#include <iostream>
#include "motor.h"
#include <stdio.h>
#include <time.h>
#include <string>
#include <stdlib.h>
#include "error.h"
using namespace std;
Motor::Motor(Motor_port port, Connection *connection){
this->port=port;
this->connection = connection;
//mode = BREAK | REGULATED;
//reg_mode = MOTOR_SPEED;
//run_state = RUN_IDLE;
//turnratio = 100;
}
void Motor::get_output_state(){
unsigned char answer[NXT_BUFFER_SIZE];
unsigned char command[5];
command[0]=0x03; //command length
command[1]=0x00;
//start of message
command[2]=0x00;
command[3]=0x06;
command[4]=port;
connection->send(&command[0],5);
connection->receive(&answer[0],27);
if(answer[4]){
throw Nxt_exception::Nxt_exception("get_output_state","Motor", answer[4]);
}
//mode=answer[7];
//reg_mode=answer[8];
//turnratio=answer[9];
run_state=answer[10];
tacho_limit = (0xFF & answer[11]) | ((0xFF & answer[12]) << 8)| ((0xFF & answer[13]) << 16)| ((0xFF & answer[14]) << 24);
tacho_count = (0xFF & answer[15]) | ((0xFF & answer[16]) << 8)| ((0xFF & answer[17]) << 16)| ((0xFF & answer[18]) << 24);
block_count = (0xFF & answer[19]) | ((0xFF & answer[20]) << 8)| ((0xFF & answer[21]) << 16)| ((0xFF & answer[22]) << 24);
rotation_count = (0xFF & answer[19]) | ((0xFF & answer[20]) << 8)| ((0xFF & answer[21]) << 16)| ((0xFF & answer[22]) << 24);
//printf("Run state: %d\n", run_state);
//printf("Tacho limit: %d\n", tacho_limit);
//printf("Tacho count: %d\n", tacho_count);
//printf("Block tacho count: %d\n", block_count);
//printf("Rotation count: %d\n", rotation_count);
//printf("\n");
return;
}
void Motor::set_output_state(char set_speed, unsigned char set_mode, unsigned char set_regulation, char set_turn_ratio, unsigned char set_run_state, unsigned int set_tacho_limit, bool reply){
unsigned char answer[NXT_BUFFER_SIZE];
unsigned char command[15];
command[0]=13; //command length
command[1]=0x00;
//start of message
if(reply){
command[2]=0x00;
}
else{
command[2]=0x80;
}
command[3]=0x04;//Turn on motor
command[4]=port;//Output port
command[5]=set_speed;//power set point
command[6]=set_mode;//Mode
command[7]=set_regulation;//Regulation
command[8]=set_turn_ratio;//Turn ratio
command[9]=set_run_state;//Run stat
command[10]=set_tacho_limit;//TachoLimit
command[11]=set_tacho_limit >> 8;//TachoLimit
command[12]=set_tacho_limit >> 16;//TachoLimit
command[13]=set_tacho_limit >> 24;//TachoLimit
command[14]=0; // why a 5th byte?????
connection->send(&command[0],15);
//connection->send(&command[0],8);
if(reply){
connection->receive(&answer[0],5);
if(answer[4]){
throw Nxt_exception::Nxt_exception("set_output_state","Motor", 0x00FF & answer[4]);
}
}
return;
}
void Motor::reset(bool relative, bool reply){
unsigned char answer[NXT_BUFFER_SIZE];
unsigned char command[6];
command[0]=0x04; //command length
command[1]=0x00;
//start of message
if(reply){
command[2]=0x00;
}
else{
command[2]=0x80;
}
command[3]=0x0A;
command[4]=port;
command[5]=relative;
connection->send(&command[0],6);
if(reply){
connection->receive(&answer[0],5);
if(answer[4]){
throw Nxt_exception::Nxt_exception("reset","Motor", 0x00FF & answer[4]);
}
}
return;
}
void Motor::on(char speed, unsigned int degrees, bool reply){
return set_output_state(speed, BREAK | MOTOR_ON | REGULATED, MOTOR_SPEED, DEFAULT_TURN_RATIO, RUNNING, degrees, reply);
}
void Motor::stop(bool reply){
return set_output_state(0, BREAK | MOTOR_ON | REGULATED, MOTOR_SPEED, DEFAULT_TURN_RATIO, RUNNING, 0, reply);
}
void Motor::off(bool reply){
return set_output_state(0, REGULATED, MOTOR_SPEED, DEFAULT_TURN_RATIO, RUN_IDLE, 0, reply);
}
void Motor::reset_rotation(bool reply){
return reset(true, reply);
}
bool Motor::is_running(){
get_output_state();
if(run_state){
return true;
}
else
return false;
}
long int Motor::get_rotation(){
get_output_state();
return rotation_count;
}
void Motor::move_to(char speed, long int target){
return move_to(speed,target,4);
}
void Motor::move_to(char speed, long int target, int tol){
speed=abs(speed);
long int current_pos= get_rotation();
if(target>current_pos){
on(speed);
while(get_rotation()<=target){
//wait
}
stop();
}
else{
on(-speed);
while(get_rotation()>=target){
//wait
}
stop();
}
if( abs(target-get_rotation()) >tol ){
move_to(5,target);
}
return;
}
Motor_port Motor::get_port(){
return this->port;
}
/********* Work in progress******/
/* int Motor::move_to(int speed, long int target){
speed=abs(speed);
int dir=1;
long int slow_down=720;
long int current_pos=get_rotation();
if(target<current_pos){
dir=-1;
}
printf("target:%d\n",target);
on(speed * dir);
do{
current_pos=get_rotation();
printf("Pos1 %d\n", current_pos);
}while(target-slow_down > current_pos);
set_output_state(0, BREAK | MOTOR_ON | REGULATED, reg_mode, turnratio, RAMP_DOWN, slow_down );
do{
current_pos=get_rotation();
}while(target-15>current_pos);
set_output_state(0, BREAK | MOTOR_ON| REGULATED, reg_mode, turnratio, RUNNING, 0);
if(target<current_pos){
dir=-1;
}
else{
dir=1;
}
on(10*dir);
do{
current_pos=get_rotation();
}while(target>current_pos);
}*/