00001 #include "scorbot.h" 00002 #include "feedback_motor.h" 00003 00004 //I2C Scorbot::g_i2c_to_pwm_driver_(I2C_SDA, I2C_SCL); 00005 00006 Scorbot::Scorbot() : 00007 propeller_(PROPELLER_RX, PROPELLER_TX, PROPELLER_DATA_SIZE) 00008 { 00009 // Instantiate motors 00010 // Interna PWM, Ext Spd Pin, Int Spd Pin, Microswitch Pin, Microswitch Mode 00011 motor_[0] = new FeedbackMotor(true, 0, PWM_1_PIN, MS_1_PIN, PullUp); 00012 motor_[1] = new FeedbackMotor(true, 0, PWM_2_PIN, MS_2_PIN, PullUp); 00013 motor_[2] = new FeedbackMotor(true, 0, PWM_3_PIN, MS_3_PIN, PullUp); 00014 motor_[3] = new FeedbackMotor(true, 0, PWM_4_PIN, MS_4_PIN, PullUp); 00015 motor_[4] = new FeedbackMotor(true, 0, PWM_5_PIN, MS_5_PIN, PullUp); 00016 motor_[5] = new FeedbackMotor(false, 11, PWM_6_PIN, MS_6_PIN, PullUp); 00017 motor_[6] = new FeedbackMotor(true, 0, PWM_7_PIN, MS_7_PIN); 00018 00019 //Set all PWMs to 0 00020 for (int i = 0; i < NUM_MOTORS; i++) 00021 motor_[i]->setPWMDuty(0); 00022 00023 //Setup serial communication with Propeller 00024 propeller_.baud(115200); 00025 controller_status_ = 0; 00026 00027 //ensure the motors are off 00028 propeller_.putc(PROPELLER_STOP_MOTORS); 00029 00030 //Set the update step to occur at 100Hz (UPDATE_PERIOD = 10000us, defined in motor.h) 00031 propeller_.setFullCallback(this, &Scorbot::updateStep); 00032 request_update_.attach_us(this, &Scorbot::requestUpdate, UPDATE_PERIOD); 00033 } 00034 00035 Scorbot::~Scorbot() 00036 { 00037 for (int index = 0; index < NUM_MOTORS; index++) 00038 delete motor_[index]; 00039 } 00040 00041 uint8_t Scorbot::readMicroswitches() 00042 { 00043 uint8_t switches = 0; 00044 for (int index = 0; index < 7; index++) 00045 switches |= (motor_[index]->readMicroswitch() << index); 00046 00047 return switches; 00048 } 00049 00050 uint8_t Scorbot::readMicroswitch(uint8_t motor_index) 00051 { 00052 return motor_[motor_index]->readMicroswitch(); 00053 } 00054 00055 long Scorbot::readEncoder(uint8_t motor_index) 00056 { 00057 return motor_[motor_index]->readEncoder(); 00058 } 00059 00060 float Scorbot::readPWMDuty(uint8_t motor_index) 00061 { 00062 return motor_[motor_index]->readPWMDuty(); 00063 } 00064 00065 uint8_t Scorbot::readControllerStatus() 00066 { 00067 return controller_status_; 00068 } 00069 00070 uint8_t * Scorbot::readControlParameters(uint8_t motor_index, uint8_t & length) 00071 { 00072 return motor_[motor_index]->readControlParameters(length); 00073 } 00074 00075 long Scorbot::readTargetPosition(uint8_t motor_index) 00076 { 00077 return motor_[motor_index]->readTargetPosition(); 00078 } 00079 00080 long Scorbot::readTargetVelocity(uint8_t motor_index) 00081 { 00082 return motor_[motor_index]->readTargetVelocity(); 00083 } 00084 00085 void Scorbot::resetEncoders() 00086 { 00087 propeller_.putc(PROPELLER_RESET_ENCODERS); 00088 } 00089 00090 void Scorbot::setDestination(uint8_t motor_index, long position, long duration) 00091 { 00092 motor_[motor_index]->setDestination(position, duration); 00093 } 00094 00095 bool Scorbot::setControlParameters(uint8_t motor_index, uint8_t length, uint8_t *params) 00096 { 00097 return motor_[motor_index]->setControlParameters(length, params); 00098 } 00099 00100 void Scorbot::enableMotors() 00101 { 00102 propeller_.putc(PROPELLER_START_MOTORS); 00103 } 00104 00105 void Scorbot::disableMotors() 00106 { 00107 propeller_.putc(PROPELLER_STOP_MOTORS); 00108 } 00109 00110 void Scorbot::requestUpdate() 00111 { 00112 //get rid of any lingering data 00113 propeller_.flushBuffer(); 00114 //request an update 00115 propeller_.putc(PROPELLER_GET_VALUES); 00116 } 00117 00118 void Scorbot::updateStep() 00119 { 00120 //if the message is the correct length, and the sentinel character 00121 //is correct, then we may proceed to process the data 00122 if (propeller_.getc() == PROPELLER_SENTINEL_CHARACTER) 00123 { 00124 /******************************************** 00125 * Parse the Propeller Message * 00126 ********************************************/ 00127 //parse the encoder values 00128 for (int index = 0; index < 7; index++) 00129 motor_[index]->setEncoder(propeller_.readLong()); 00130 //parse the controller status 00131 controller_status_ = propeller_.getc(); 00132 00133 /******************************************** 00134 * Perform Control Update * 00135 ********************************************/ 00136 for (int index = 0; index < 7; index++) 00137 motor_[index]->updateMotor(); 00138 } 00139 } 00140 00141 /*void Scorbot::setExternalPWMDuty(uint8_t external_pwm_address, uint8_t pwm_duty) 00142 { 00143 char i2c_message[2]; 00144 i2c_message[0] = external_pwm_address; 00145 i2c_message[1] = pwm_duty; 00146 g_i2c_to_pwm_driver_.write(I2C_TO_PWM_DRIVER_ADDRESS, i2c_message, 2); 00147 }*/