DroneController.cpp
Go to the documentation of this file.
00001 
00023 #include "DroneController.h"
00024 #include "gvars3/instances.h"
00025 #include "../HelperFunctions.h"
00026 #include "ControlNode.h"
00027 
00028 DroneController::DroneController(void)
00029 {
00030         target = DronePosition(TooN::makeVector(0.0,0.0,0.0),0.0);
00031         targetValid = false;
00032         last_err[2] = 0;
00033         lastTimeStamp = 0;
00034 
00035         hoverCommand.gaz = hoverCommand.pitch = hoverCommand.roll = hoverCommand.yaw = 0;
00036 
00037         node = NULL;
00038 }
00039 
00040 
00041 DroneController::~DroneController(void)
00042 {
00043 }
00044 
00045 double angleFromTo2(double angle, double min, double sup)
00046 {
00047         while(angle < min) angle += 360;
00048         while(angle >=  sup) angle -= 360;
00049         return angle;
00050 }
00051 
00052 // generates and sends a new control command to the drone, 
00053 // based on the currently active command ant the drone's position.
00054 ControlCommand DroneController::update(tum_ardrone::filter_stateConstPtr state)
00055 {
00056         TooN::Vector<3> pose = TooN::makeVector(state->x, state->y, state->z);
00057         double yaw = state->yaw;
00058         TooN::Vector<4> speeds = TooN::makeVector(state->dx, state->dy, state->dz, state->dyaw);
00059         ptamIsGood = state->ptamState == state->PTAM_BEST || state->ptamState == state->PTAM_GOOD || state->ptamState == state->PTAM_TOOKKF;
00060         scaleAccuracy = state->scaleAccuracy;
00061 
00062         // calculate (new) errors.
00063         TooN::Vector<4> new_err = TooN::makeVector(
00064                 target.pos[0] - pose[0],
00065                 target.pos[1] - pose[1],
00066                 target.pos[2] - pose[2],
00067                 target.yaw - yaw
00068                 );
00069 
00070         // yaw error needs special attention, it can always be pushed in between 180 and -180.
00071         // this does not affect speeds and makes the drone always take the quickest rotation side.
00072         new_err[3] = angleFromTo2(new_err[3],-180,180); 
00073         TooN::Vector<4> d_err = TooN::makeVector(-speeds[0], -speeds[1], -speeds[2], -speeds[3]);
00074 
00075         if(targetValid)
00076                 calcControl(new_err, d_err, yaw);
00077         else
00078         {
00079                 lastSentControl = hoverCommand;
00080                 ROS_WARN("Warning: no valid target, sending hover.");
00081         }
00082 
00083         last_err = new_err;
00084         return lastSentControl;
00085 }
00086 
00087 
00088 void DroneController::setTarget(DronePosition newTarget)
00089 {
00090         target = newTarget;
00091         target.yaw = angleFromTo2(target.yaw,-180,180);
00092         targetSetAtClock = getMS()/1000.0;
00093         targetNew = TooN::makeVector(1.0,1.0,1.0,1.0);
00094         targetValid = true;
00095         last_err = i_term = TooN::makeVector(0,0,0,0);
00096 
00097         char buf[200];
00098         snprintf(buf,200,"New Target: xyz = %.3f, %.3f, %.3f,  yaw=%.3f", target.pos[0],target.pos[1],target.pos[2],target.yaw);
00099         ROS_INFO(buf);
00100 
00101         if(node != NULL)
00102                 node->publishCommand(std::string("u l ") + buf);
00103 }
00104 
00105 
00106 DronePosition DroneController::getCurrentTarget()
00107 {
00108         return target;
00109 }
00110 
00111 void DroneController::clearTarget()
00112 {
00113         targetValid = false;
00114 }
00115 
00116 void i_term_increase(double& i_term, double new_err, double cap)
00117 {
00118         if(new_err < 0 && i_term > 0)
00119                 i_term = std::max(0.0, i_term + 2.5 * new_err);
00120         else if(new_err > 0 && i_term < 0)
00121                 i_term = std::min(0.0, i_term + 2.5 * new_err);
00122         else
00123                 i_term += new_err;
00124 
00125         if(i_term > cap) i_term =  cap;
00126         if(i_term < -cap) i_term =  -cap;
00127 }
00128 
00129 void DroneController::calcControl(TooN::Vector<4> new_err, TooN::Vector<4> d_error, double yaw)
00130 {
00131         float agr = agressiveness;
00132         if(!ptamIsGood) agr *= 0.75;
00133         agr *= scaleAccuracy;
00134 
00135         //TooN::Vector<4> d_term = new_err - last_err;  // d-term:just differentiate
00136         TooN::Vector<4> d_term = d_error;
00137         TooN::Vector<4> p_term = new_err;       // p-term is error.
00138 
00139         // rotate error to drone CS, invert pitch
00140         double yawRad = yaw * 2 * 3.141592 / 360;       
00141         d_term[0] = cos(yawRad)*d_error[0] - sin(yawRad)*d_error[1];
00142         d_term[1] = - sin(yawRad)*d_error[0] - cos(yawRad)*d_error[1];
00143 
00144         p_term[0] = cos(yawRad)*new_err[0] - sin(yawRad)*new_err[1];
00145         p_term[1] = - sin(yawRad)*new_err[0] - cos(yawRad)*new_err[1];
00146 
00147 
00148         // integrate & cap
00149         double sec = getMS()/1000.0 - lastTimeStamp; lastTimeStamp = getMS()/1000.0;
00150         i_term_increase(i_term[2],new_err[2] * sec, 0.2f / Ki_gaz);
00151         i_term_increase(i_term[1],new_err[1] * sec, 0.1f / Ki_rp+(1e-10));
00152         i_term_increase(i_term[0],new_err[0] * sec, 0.1f / Ki_rp+(1e-10));
00153 
00154         // kill integral term when first crossing target
00155         // that is, thargetNew is set, it was set at least 100ms ago, and err changed sign.
00156         for(int i=0;i<4;i++)
00157                 if(targetNew[i] > 0.5 && getMS()/1000.0 - targetSetAtClock > 0.1 && last_err[i] * new_err[i] < 0)
00158                 {
00159                         i_term[i] = 0; targetNew[i] = 0;
00160                 }
00161 
00162 
00163 
00164 
00165 
00166         // YAW
00167         lastSentControl.yaw = Kp_yaw * p_term[3] + Kd_yaw * d_term[3];  // yaw can be translated directly
00168         lastSentControl.yaw = std::min(max_yaw,std::max(-max_yaw,(double)(lastSentControl.yaw*agr)));
00169 
00170 
00171 
00172         // RP
00173         // calculate signals only based on d and p:
00174         double cX_p = Kp_rp * p_term[0];
00175         double cY_p = Kp_rp * p_term[1];
00176 
00177         double cX_d = Kd_rp * d_term[0];
00178         double cY_d = Kd_rp * d_term[1];
00179 
00180         double cX_i = Ki_rp * i_term[0];
00181         double cY_i = Ki_rp * i_term[1];
00182 
00183 
00184         /*
00185         // modulate non-linearely
00186         float rp_mod_cut1 = 0.0; 
00187         float rp_mod_cut2 = 0.0; 
00188         float rp_mod_exp = 2;
00189 
00190         if(cX_p <  rp_mod_cut1 && cX_p > 0) 
00191                 cX_p = pow((float)cX_p,rp_mod_exp) / pow(rp_mod_cut1,rp_mod_exp-1);
00192         else if(cX_p <  rp_mod_cut2 && cX_p > 0) 
00193                 cX_p = rp_mod_cut1 + pow((float)cX_p-rp_mod_cut1,1/rp_mod_exp) / pow(rp_mod_cut2-rp_mod_cut1,1/rp_mod_exp-1);
00194 
00195         if(cX_p > - rp_mod_cut1 && cX_p < 0) 
00196                 cX_p = - pow(-(float)cX_p,rp_mod_exp) / pow(rp_mod_cut1,rp_mod_exp-1);
00197         else if(cX_p >  - rp_mod_cut2 && cX_p < 0) 
00198                 cX_p = - (rp_mod_cut1 + pow(-(float)cX_p-rp_mod_cut1,1/rp_mod_exp) / pow(rp_mod_cut2-rp_mod_cut1,1/rp_mod_exp-1));
00199 
00200         if(cY_p <  rp_mod_cut1 && cY_p > 0) 
00201                 cY_p = pow((float)cY_p,rp_mod_exp) / pow(rp_mod_cut1,rp_mod_exp-1);
00202         else if(cY_p <  rp_mod_cut2 && cY_p > 0) 
00203                 cY_p = rp_mod_cut1 + pow((float)cY_p-rp_mod_cut1,1/rp_mod_exp) / pow(rp_mod_cut2-rp_mod_cut1,1/rp_mod_exp-1);
00204 
00205         if(cY_p > - rp_mod_cut1 && cY_p < 0) 
00206                 cY_p = - pow(-(float)cY_p,rp_mod_exp) / pow(rp_mod_cut1,rp_mod_exp-1);
00207         else if(cY_p >  - rp_mod_cut2 && cY_p < 0) 
00208                 cY_p = - (rp_mod_cut1 + pow(-(float)cY_p-rp_mod_cut1,1/rp_mod_exp) / pow(rp_mod_cut2-rp_mod_cut1,1/rp_mod_exp-1));
00209         */
00210 
00211 
00212         lastSentControl.roll = cX_p + cX_d + cX_i;
00213         lastSentControl.pitch = cY_p + cY_d + cY_i;
00214 
00215         // clip
00216         lastSentControl.roll = std::min(max_rp,std::max(-max_rp,(double)(lastSentControl.roll*agr)));
00217         lastSentControl.pitch = std::min(max_rp,std::max(-max_rp,(double)(lastSentControl.pitch*agr)));
00218 
00219         // GAZ
00220         double gazP = Kp_gaz * p_term[2];
00221         double gazD = Kd_gaz * d_term[2];
00222         double gazI = Ki_gaz * i_term[2];
00223 
00224 
00225         lastSentControl.gaz = std::min(max_gaz_rise/rise_fac,std::max(max_gaz_drop, gazP + gazD + gazI));
00226         if(lastSentControl.gaz > 0) lastSentControl.gaz *= rise_fac;
00227 
00228         logInfo = TooN::makeVector(
00229                 Kp_rp * p_term[0], Kp_rp * p_term[1], gazP, Kp_yaw * p_term[3],
00230                 Kd_rp * d_term[0], Kd_rp * d_term[1], gazD, Kd_yaw * d_term[3],
00231                 Ki_rp * i_term[0], Ki_rp * i_term[1], gazI, Ki_yaw * i_term[3],
00232                 lastSentControl.roll, lastSentControl.pitch, lastSentControl.gaz, lastSentControl.yaw,
00233                 lastSentControl.roll, lastSentControl.pitch, lastSentControl.gaz, lastSentControl.yaw,
00234                 new_err[0],new_err[1],new_err[2],new_err[3],
00235                 target.pos[0],target.pos[1],target.pos[2],target.yaw
00236                 );
00237 }
00238 
00239 TooN::Vector<4> DroneController::getLastErr()
00240 {
00241         return last_err;
00242 }
00243 ControlCommand DroneController::getLastControl()
00244 {
00245         return lastSentControl;
00246 }


tum_ardrone
Author(s):
autogenerated on Sat Jun 8 2019 20:27:22