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
00053
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
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
00071
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
00136 TooN::Vector<4> d_term = d_error;
00137 TooN::Vector<4> p_term = new_err;
00138
00139
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
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
00155
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
00167 lastSentControl.yaw = Kp_yaw * p_term[3] + Kd_yaw * d_term[3];
00168 lastSentControl.yaw = std::min(max_yaw,std::max(-max_yaw,(double)(lastSentControl.yaw*agr)));
00169
00170
00171
00172
00173
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
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 lastSentControl.roll = cX_p + cX_d + cX_i;
00213 lastSentControl.pitch = cY_p + cY_d + cY_i;
00214
00215
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
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 }