StoRC
Autonomous Payload Delivery System
controls.pde
Go to the documentation of this file.
00001 /***********************************************************
00002  * StoRC - Search to Rescue Craft
00003  * MEAM Senior Design 2011-2012
00004  * 
00005  * Authors:  Michael Posner (CIS, MEAM '12)
00006  * Timothy Hennelly (ESE '12)
00007  * Jacob Orloff (MEAM '12)
00008  * 
00009  * (some code from ArduPilot Mega project, found here:
00010  * http://code.google.com/p/ardupilot-mega/ )
00011  * 
00012  * Licensing:
00013  * 
00014  * This program is free software: you can redistribute it and/or modify 
00015  * it under the terms of the GNU General Public License as published by 
00016  * the Free Software Foundation, either version 3 of the License, or 
00017  * (at your option) any later version. 
00018  * 
00019  * This program is distributed in the hope that it will be useful, 
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
00022  * GNU General Public License for more details. 
00023  * 
00024  * You should have received a copy of the GNU General Public License 
00025  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00026  * 
00027  ***********************************************************/
00028 
00029 /**
00030  *  @file controls.pde
00031  *  @brief Contains all controls functions for feedback and inner loop control
00032  *  @author Michael Posner (CIS, MEAM '12)
00033  *  @author Timothy Hennelly (ESE '12)
00034  *  @author Jacob Orloff (MEAM '12)
00035  *  
00036  */
00037 
00038 /**
00039  * PID control on roll angle
00040  * @param dt the time elapsed since the last call (for integration)
00041  */
00042 
00043 void THR_control(float dt) {
00044 
00045   //calculate gain multiplier based on rc_6 & rc_7
00046   kp_thr_gm = (float)(rc_6-1000)/1000.0f * 3.0;  // Proportional gain
00047   ki_thr_gm = (float)(rc_7-1000)/1000.0f * 3.0;  // Integral gain
00048   
00049   del_ALT = new_ALT - old_ALT;
00050 
00051   I_THR += KI_THR * ki_thr_gm * del_ALT;
00052 
00053   I_THR = constrain(I_THR,-200,200);
00054 
00055   del_THR = -(KP_THR * kp_thr_gm * (del_ALT/dt) + I_THR);
00056 
00057   //round to nearest 20 to make servos happy
00058   del_THR = (int)del_THR / 10;
00059   del_THR = (int)del_THR * 20;
00060 
00061   Serial.print(" rc_thr_trim: ");
00062   Serial.print(rc_thr_trim);
00063   Serial.print(" del_ALT: ");
00064   Serial.print(del_ALT);
00065   Serial.print(" I_THR: ");
00066   Serial.print(I_THR);
00067   Serial.print(" P+D: ");
00068   Serial.print(del_THR-I_THR);
00069   Serial.print(" Total: ");
00070   Serial.println(del_THR);
00071 
00072   //can't affect the throttle too much
00073   del_THR = constrain(del_THR,-400,400);
00074   
00075   old_ALT = new_ALT;
00076   
00077 } 
00078 
00079 void RUD_control(float dt) {
00080 
00081   /* Keeping GMs constant for now
00082   if(rc_4 < 1500){  // only change rudder GM's when we're not tweaking throttle GM's (levels of priority)
00083     //calculate gain multiplier based on rc_6 & rc_7
00084     kp_rud_gm = (float)(rc_6-1000)/1000.0f * 3.0;  // Proportional gain
00085     ki_rud_gm = (float)(rc_7-1000)/1000.0f * 3.0;  // Integral gain
00086   }
00087   */
00088 
00089   I_RUD += KI_RUD * ki_rud_gm * (int)(phi_c - dcm.roll_sensor/100.0) * dt;
00090 
00091   I_RUD = constrain(I_RUD,-150,150);
00092 
00093   del_RUD = KD_RUD * gyro.x + KP_RUD * kp_rud_gm * (int)(phi_c - dcm.roll_sensor/100.0) + I_RUD;
00094 
00095   //round to nearest 20 to make servos happy
00096   del_RUD = (int)del_RUD / 10;
00097   del_RUD = (int)del_RUD * 20;
00098 
00099   if(rc_4 < 1500){
00100     /*
00101     Serial.print(" rc_rud_trim: ");
00102     Serial.print(rc_rud_trim);
00103     Serial.print(" Phi_c: ");
00104     Serial.print(phi_c);
00105     Serial.print(" Phi: ");
00106     Serial.print(dcm.roll_sensor/100.0);
00107     Serial.print(" Error: ");
00108     Serial.print(phi_c-dcm.roll_sensor/100.0);
00109     Serial.print(" I_RUD: ");
00110     Serial.print(I_RUD);
00111     Serial.print(" P+D: ");
00112     Serial.print(del_RUD-I_RUD);
00113     Serial.print(" Total: ");
00114     Serial.println(del_RUD);
00115     */
00116   }
00117 
00118   //can't affect the rudder too much
00119   del_RUD = constrain(del_RUD,-400,400);
00120 }
00121 
00122 /**
00123  * Add elevator
00124  */
00125  
00126 /*
00127 void ELE_control(float dt){
00128 
00129   q = gyro.y;
00130   q_filtered = low_pass(q, alpha_q, q_filtered);
00131 
00132   kp_ele_gm = (float)(rc_6-1000)/1000.0f * 3.0;  // Proportional gain for elevator angle
00133   ki_ele_gm = (float)(rc_7-1000)/1000.0f * 3.0;
00134 
00135   I_ELE += KI_ELE * ki_ele_gm * (q_c - q_filtered)*dt;
00136 
00137   I_ELE = constrain(I_ELE,-100,100);
00138 
00139   del_ELE = KP_ELE * kp_ele_gm * (q_c - q_filtered) + I_ELE;
00140 
00141   del_ELE  = (int)del_ELE  / 10;
00142   del_ELE  = (int)del_ELE  * 20;
00143 
00144   del_ELE = constrain(del_ELE,-400,400);
00145 
00146   Serial.print(" rc_ele_trim: ");
00147   Serial.print(rc_ele_trim);
00148   Serial.print(" Pitch rate command: ");
00149   Serial.print(q_c);
00150   Serial.print(" Pitch rate: ");
00151   Serial.print(q);
00152   Serial.print(" Filtered: ");
00153   Serial.print(q_filtered);
00154   Serial.print(" Error: ");
00155   Serial.print(q_c-q_filtered);
00156   Serial.print(" I_ELE: ");
00157   Serial.print(I_ELE);
00158   Serial.print(" P+D: ");
00159   Serial.print(del_ELE - I_ELE);
00160   Serial.print(" Total: ");
00161   Serial.println(del_ELE);
00162 }
00163 */
00164 
00165 /**
00166  * Add rudder based on roll (bank) angle (phi).
00167  */
00168 
00169 /**
00170  * Add rudder based on current throttle position to offset the additional motor
00171  * torque caused by an increase in throttle.
00172  */
00173 void throttle_mixing(void) {
00174 
00175   //throttle_mix_result = (rc_throttle - 1000) / 100 * 10;
00176   //throttle_mix_result = throttle_mix_result * 2;
00177 
00178   throttle_mix_result = (int)( ((float)(rc_throttle-1000))/1000.0f * 0.1f*1000.0f );  //limit it to 10% of RC capability
00179 
00180   //round values to nearest 20 so the servos don't freak out
00181   //  because they may not be able to reach a precise value
00182   throttle_mix_result = throttle_mix_result / 10;
00183   throttle_mix_result = throttle_mix_result * 20;
00184   /*
00185   if(slide_sw == HIGH) { //only if the slide switch is high
00186    rc_rudder += throttle_mix_result;
00187    }
00188    */
00189 }
00190 
00191 
00192 /**
00193  * Perturbation routine that periodically adds step inputs to rudder,
00194  * elevator, etc.  Data collected from the results can be used to validate
00195  * the simulation model.
00196  */
00197 void perturb(void) {
00198 
00199   if(slide_sw == HIGH){  //only if the slide switch is high
00200 
00201     if( millis() - ptimer > 1*60000 ) { //if a minute has passed since the last perturbation
00202       rc_elevator += 300;
00203     }
00204     else if(millis() - ptimer > 1*60000+100) {  //add it for 100 ms, then return to normal
00205       ptimer = millis();
00206     }
00207 
00208   } 
00209 }