StoRC
Autonomous Payload Delivery System
|
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 }