feedback_motor.cpp

00001 #include "feedback_motor.h"
00002 
00003 extern Serial pc;
00004 
00005 FeedbackMotor::FeedbackMotor(bool internal_pwm, uint8_t external_speed_pin, 
00006                              PinName internal_speed_pin, PinName microswitch_pin,
00007                              PinMode microswitch_mode) :
00008   Motor(internal_pwm, external_speed_pin, internal_speed_pin, microswitch_pin, microswitch_mode)
00009 {
00010   dt_ = 0;
00011   position_error_ = 0;
00012   target_position_ = 0;
00013   target_velocity_ = 0;
00014   integral_error_ = 0;
00015   control_enabled_ = false;
00016   p_gain_ = 0;
00017   i_gain_ = 0;
00018   d_gain_ = 0;
00019   i_saturation_ = 0;
00020   max_pwm_ = 0;
00021   velocity_threshold_ = 0;
00022   pwm_ = 0;
00023 }
00024 
00025 FeedbackMotor::~FeedbackMotor() {}
00026 
00027 void FeedbackMotor::updateMotor()
00028 {
00029   if (control_enabled_ && !update_in_progress_ && desired_move_duration_ > 0)
00030   {
00031     dt_ = move_duration_.read();
00032     if(dt_ > desired_move_duration_)
00033         dt_ = desired_move_duration_;
00034     
00035     //find the base trajectory term
00036     float base_term = (dt_ * desired_distance_) / (desired_move_duration_ * desired_move_duration_);
00037     //find the position trajectory
00038     target_position_ = (desired_encoder_ - desired_distance_) +
00039                        (3.0) * (dt_ * base_term) -
00040                        (2.0) * (dt_ * dt_ * base_term) / (desired_move_duration_);
00041     //find the velocity trajectory
00042     target_velocity_ = (6.0) * (base_term) -
00043                        (6.0) * (dt_ * base_term) / (desired_move_duration_);
00044 
00045     //find position error
00046     position_error_ = target_position_ - encoder_;
00047 
00048     //find integral error                       
00049     integral_error_ = integral_error_ + position_error_;
00050     if (integral_error_ > i_saturation_)
00051       integral_error_ = i_saturation_;
00052     else if (integral_error_ < - i_saturation_)
00053       integral_error_ = - i_saturation_;   
00054 
00055     //compute pwm                       
00056     pwm_ = p_gain_*position_error_ + i_gain_*integral_error_ + d_gain_*target_velocity_;
00057     //add a constant velocity offset if required by static friction
00058     if (velocity_threshold_ > 0)
00059     {
00060       if (pwm_ > 0)
00061         pwm_ += velocity_threshold_;
00062       else if (pwm_ < 0)
00063         pwm_ -= velocity_threshold_;
00064     }
00065     
00066     //limit the maximum and minimum pwm
00067     if (pwm_ > max_pwm_)
00068       pwm_ = max_pwm_;
00069     else if (pwm_ < - max_pwm_)
00070       pwm_ = - max_pwm_;
00071     
00072     setPWMDuty(pwm_);
00073   }
00074 }
00075 
00076 bool FeedbackMotor::setControlParameters(uint8_t length, uint8_t *data)
00077 {
00078   bool success = false;
00079   if (length == PARAMETER_MESSAGE_LENGTH)
00080   {
00081     control_enabled_ = true;
00082     update_in_progress_ = true;
00083     success = true;
00084     
00085     p_gain_             = ((float) ((data[0]  << 24) | (data[1]  << 16) | (data[2]  << 8) | data[3] )) / 100000.0;
00086     i_gain_             = ((float) ((data[4]  << 24) | (data[5]  << 16) | (data[6]  << 8) | data[7] )) / 100000.0;
00087     d_gain_             = ((float) ((data[8]  << 24) | (data[9]  << 16) | (data[10] << 8) | data[11])) / 100000.0;
00088     i_saturation_       = ((float) ((data[12] << 24) | (data[13] << 16) | (data[14] << 8) | data[15])) / 100000.0;
00089     max_pwm_            = ((float) ((data[16] << 24) | (data[17] << 16) | (data[18] << 8) | data[19])) / 100000.0;
00090     velocity_threshold_ = ((float) ((data[20] << 24) | (data[21] << 16) | (data[22] << 8) | data[23])) / 100000.0;
00091     
00092     update_in_progress_ = false;
00093   }
00094   delete[] data;
00095   return success;
00096 }
00097 
00098 uint8_t * FeedbackMotor::readControlParameters(uint8_t & length)
00099 {
00100   length = PARAMETER_MESSAGE_LENGTH;
00101   uint8_t * data = new uint8_t[PARAMETER_MESSAGE_LENGTH];
00102   int index = 0;
00103   long parameter = 0;
00104   
00105   //p_gain_
00106   parameter = (long) (p_gain_*100000.0);
00107   data[index++] = (parameter >> 24) & 0xFF;
00108   data[index++] = (parameter >> 16) & 0xFF;
00109   data[index++] = (parameter >>  8) & 0xFF;
00110   data[index++] = (parameter      ) & 0xFF;
00111   //i_gain_
00112   parameter = (long) (i_gain_*100000.0);
00113   data[index++] = (parameter >> 24) & 0xFF;
00114   data[index++] = (parameter >> 16) & 0xFF;
00115   data[index++] = (parameter >>  8) & 0xFF;
00116   data[index++] = (parameter      ) & 0xFF;
00117   //d_gain_
00118   parameter = (long) (d_gain_*100000.0);
00119   data[index++] = (parameter >> 24) & 0xFF;
00120   data[index++] = (parameter >> 16) & 0xFF;
00121   data[index++] = (parameter >>  8) & 0xFF;
00122   data[index++] = (parameter      ) & 0xFF;
00123   //i_saturation_
00124   parameter = (long) (i_saturation_*100000.0);
00125   data[index++] = (parameter >> 24) & 0xFF;
00126   data[index++] = (parameter >> 16) & 0xFF;
00127   data[index++] = (parameter >>  8) & 0xFF;
00128   data[index++] = (parameter      ) & 0xFF;
00129   //max_pwm_
00130   parameter = (long) (max_pwm_*100000.0);
00131   data[index++] = (parameter >> 24) & 0xFF;
00132   data[index++] = (parameter >> 16) & 0xFF;
00133   data[index++] = (parameter >>  8) & 0xFF;
00134   data[index++] = (parameter      ) & 0xFF;
00135   //velocity_threshold_
00136   parameter = (long) (velocity_threshold_*100000.0);
00137   data[index++] = (parameter >> 24) & 0xFF;
00138   data[index++] = (parameter >> 16) & 0xFF;
00139   data[index++] = (parameter >>  8) & 0xFF;
00140   data[index++] = (parameter      ) & 0xFF;
00141 
00142   return data;
00143 }
00144 
00145 long FeedbackMotor::readTargetPosition()
00146 {
00147   return target_position_;
00148 }
00149 
00150 long FeedbackMotor::readTargetVelocity()
00151 {
00152   return target_velocity_;
00153 }  
00154 
00155 void FeedbackMotor::setDestination(long encoderPosition, long duration)
00156 {
00157   integral_error_ = 0;
00158   Motor::setDestination(encoderPosition, duration);
00159 }
Generated on Sun May 8 08:05:56 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3