branch for tests with T265

Dependencies:   Lib_Cntrl AHRS Lib_Misc

Committer:
altb2
Date:
Wed Oct 02 15:31:12 2019 +0000
Revision:
0:a479dc61e931
Child:
1:d8c9f6b16279
first setup, not running!!!!

Who changed what in which revision?

UserRevisionLine numberNew contents of line
altb2 0:a479dc61e931 1 #define PI 3.141592653589793
altb2 0:a479dc61e931 2 #include "mbed.h"
altb2 0:a479dc61e931 3 #define _MBED_
altb2 0:a479dc61e931 4 #include "LinearCharacteristics.h"
altb2 0:a479dc61e931 5 #include "UAV.h"
altb2 0:a479dc61e931 6 #include "RCin.h"
altb2 0:a479dc61e931 7 #include "define_constants.h"
altb2 0:a479dc61e931 8 #include "PID_Cntrl.h"
altb2 0:a479dc61e931 9 #include "IIR_filter.h"
altb2 0:a479dc61e931 10 #include "data_structs.h"
altb2 0:a479dc61e931 11 #include "Signal.h"
altb2 0:a479dc61e931 12 #include "data_logger.h"
altb2 0:a479dc61e931 13 #include "RangeFinder.h"
altb2 0:a479dc61e931 14 #include "AHRS.h"
altb2 0:a479dc61e931 15 #include "PX4Flow.h"
altb2 0:a479dc61e931 16 #include "TFmini.h"
altb2 0:a479dc61e931 17
altb2 0:a479dc61e931 18 // ----------------------------------------------------------------------------
altb2 0:a479dc61e931 19 // ----------------------------------------------------------------------------
altb2 0:a479dc61e931 20 // define IOs
altb2 0:a479dc61e931 21 Serial pc(SERIAL_TX, SERIAL_RX,115200); // serial connection via USB - programmer
altb2 0:a479dc61e931 22 RawSerial uart4lidar(PA_0, PA_1);
altb2 0:a479dc61e931 23 PwmOut motor_pwms[4];
altb2 0:a479dc61e931 24 motor_pwms[0] = new PwmOut(PC_6);
altb2 0:a479dc61e931 25 motor_pwms[1] = new PwmOut(PC_8);
altb2 0:a479dc61e931 26 motor_pwms[2] = new PwmOut(PB_14);
altb2 0:a479dc61e931 27 motor_pwms[3] = new PwmOut(PB_9);
altb2 0:a479dc61e931 28 // ----------------------------------------------------------------------------
altb2 0:a479dc61e931 29 RCin myRC(PB_6); // read PWM of RC (Graupner Hott)
altb2 0:a479dc61e931 30 // ----------------------------------------------------------------------------
altb2 0:a479dc61e931 31 // Ultrasonic Range finder (US), read up to 4 signals
altb2 0:a479dc61e931 32 RangeFinder rf(PA_10, PB_3, PB_5, PB_4 , 10, 5782.0, 0.02, 12000); // 20 Hz parametrization
altb2 0:a479dc61e931 33 TFmini tfmini(uart4lidar);
altb2 0:a479dc61e931 34 // ----------------------------------------------------------------------------
altb2 0:a479dc61e931 35 // PX4 Optical flow (OF), use same i2c like imu
altb2 0:a479dc61e931 36 I2C i2c(PC_9, PA_8);
altb2 0:a479dc61e931 37 PX4Flow optical_flow(i2c);
altb2 0:a479dc61e931 38 // -----------------------------------------------------------------------------
altb2 0:a479dc61e931 39 // Timers
altb2 0:a479dc61e931 40 Timer global_timer; // in main loop
altb2 0:a479dc61e931 41 // -----------------------------------------------------------------------------
altb2 0:a479dc61e931 42 // The copter!
altb2 0:a479dc61e931 43 UAV copter(QUAD2,AIRGEAR350);
altb2 0:a479dc61e931 44
altb2 0:a479dc61e931 45 // -----------------------------------------------------------------------------
altb2 0:a479dc61e931 46 // Characteristic for thrust,
altb2 0:a479dc61e931 47 //LinearCharacteristics PM1_2_F_Thrust; // map +-1 to Thrust
altb2 0:a479dc61e931 48 float PM1_2_F_Thrust(float); // replace linear char. with nonlinear below
altb2 0:a479dc61e931 49
altb2 0:a479dc61e931 50 // -----------------------------------------------------------------------------
altb2 0:a479dc61e931 51 // States and communication
altb2 0:a479dc61e931 52 char Message[150];
altb2 0:a479dc61e931 53
altb2 0:a479dc61e931 54 // -----------------------------------------------------------------------------
altb2 0:a479dc61e931 55 // sample rates
altb2 0:a479dc61e931 56 float Ts200 = 0.005f;
altb2 0:a479dc61e931 57 float Ts100 = 0.01f;
altb2 0:a479dc61e931 58 float Ts50 = 0.02f;
altb2 0:a479dc61e931 59 float Ts25 = 0.04f;
altb2 0:a479dc61e931 60 float Ts10 = 0.1f;
altb2 0:a479dc61e931 61 float Ts4 = 0.25f;
altb2 0:a479dc61e931 62 // -----------------------------------
altb2 0:a479dc61e931 63 float TsCntrl = Ts200;
altb2 0:a479dc61e931 64 float TsSDLog = Ts50;
altb2 0:a479dc61e931 65 // -----------------------------------
altb2 0:a479dc61e931 66 // some stuff
altb2 0:a479dc61e931 67 float Mxy_limit = 0.0f;
altb2 0:a479dc61e931 68 uint8_t CS=INIT; // for main state machine
altb2 0:a479dc61e931 69 float motorspeed[8]; // motor speeds in rad/sec
altb2 0:a479dc61e931 70 AHRS ahrs(1,Ts100,true); // ahrs filter, 1=EKF,,true=do recalibration of imu
altb2 0:a479dc61e931 71
altb2 0:a479dc61e931 72 float Kv = 4.0;
altb2 0:a479dc61e931 73 // -----------------------------------------------------------------------------
altb2 0:a479dc61e931 74 // use pottis for scaling (temporarily)
altb2 0:a479dc61e931 75 LinearCharacteristics map_pwm_2_P(864,1600,0.35,1.5);
altb2 0:a479dc61e931 76 LinearCharacteristics map_pwm_2_I(864,1600,2.0, 8.0);
altb2 0:a479dc61e931 77 LinearCharacteristics map_pwm_2_PX(864,1600,1.0, 4.0); // RP-Winkelregler
altb2 0:a479dc61e931 78 LinearCharacteristics map_pwm_2_scale(864,1600,1.0,2.0);
altb2 0:a479dc61e931 79
altb2 0:a479dc61e931 80 // -----------------------------------------------------------------------------
altb2 0:a479dc61e931 81 // my functions (below)
altb2 0:a479dc61e931 82 void updateLoop(void); // THE MAIN LOOP!!!!
altb2 0:a479dc61e931 83 void motor_mix(float *,float ,float *); // map torques Mx,My,Mz and thrust to motor speeds
altb2 0:a479dc61e931 84 void read_US_OF_sensors(void); // read extra sensors (low frequency)
altb2 0:a479dc61e931 85 //
altb2 0:a479dc61e931 86 void RPY_controller(float *, uint8_t , uint8_t, float *); // the main controller for Stabilized and Acro mode
altb2 0:a479dc61e931 87 // -----------------------------------------------------------------------------
altb2 0:a479dc61e931 88 // - some extra functions
altb2 0:a479dc61e931 89 float limit_minmax(float ,float ,float );
altb2 0:a479dc61e931 90 float deadzone(float,float,float);
altb2 0:a479dc61e931 91 void sendSignal_mainLoop(void);
altb2 0:a479dc61e931 92 void sendSignal_read_US_OF_sensors(void);
altb2 0:a479dc61e931 93 void sendSignal_Output(void);
altb2 0:a479dc61e931 94 // -----------------------------------------------------------------------------
altb2 0:a479dc61e931 95 // some values needed
altb2 0:a479dc61e931 96 float dt; // time elapsed in current state
altb2 0:a479dc61e931 97 float Mxyz[3]; // torques
altb2 0:a479dc61e931 98 float cur_pos[3];
altb2 0:a479dc61e931 99 bool disarm_flag=false;
altb2 0:a479dc61e931 100 bool flipm = false; // used while arming motors
altb2 0:a479dc61e931 101 float F_thrust; // Thrust of motors
altb2 0:a479dc61e931 102 float z_des = 0.0;
altb2 0:a479dc61e931 103 // -----------------------------------------------------------------------------
altb2 0:a479dc61e931 104 // ----------- MBED OS ----------------------------
altb2 0:a479dc61e931 105 Thread thread_mainLoop(osPriorityNormal, 4096);
altb2 0:a479dc61e931 106 Thread thread_read_US_OF_sensors(osPriorityBelowNormal, 4096);
altb2 0:a479dc61e931 107 Thread thread_UAV_state(osPriorityLow, 4096);
altb2 0:a479dc61e931 108 Thread thread_Output(osPriorityIdle, 4096);
altb2 0:a479dc61e931 109 // Signals
altb2 0:a479dc61e931 110 Signal signal_mainLoop;
altb2 0:a479dc61e931 111 Signal signal_read_US_OF_sensors;
altb2 0:a479dc61e931 112 Signal signal_read_OF_sensors;
altb2 0:a479dc61e931 113 Signal signal_UAV_state;
altb2 0:a479dc61e931 114 Signal signal_Output;
altb2 0:a479dc61e931 115 // tickers
altb2 0:a479dc61e931 116 Ticker mainLoop; // Main loop at 100Hz
altb2 0:a479dc61e931 117 Ticker US_OF_sensors_loop;
altb2 0:a479dc61e931 118 Ticker UAV_state; // check if UAV crashed / flying / landed etc.
altb2 0:a479dc61e931 119 Ticker Output; // Output loop at 4Hz (Writing and saving)
altb2 0:a479dc61e931 120
altb2 0:a479dc61e931 121 // -----------------------------------------------------------------------------
altb2 0:a479dc61e931 122 // data logger:
altb2 0:a479dc61e931 123 data_logger my_logger(35); // number shows # of logged data columns
altb2 0:a479dc61e931 124 // -----------------------------------------------------------------------------
altb2 0:a479dc61e931 125 // MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN
altb2 0:a479dc61e931 126 // -----------------------------------------------------------------------------
altb2 0:a479dc61e931 127 int main() {
altb2 0:a479dc61e931 128 i2c.frequency(400000);
altb2 0:a479dc61e931 129 att_cntrl.P_Roll = Kv; // was 8 // p-controller different attitudes
altb2 0:a479dc61e931 130 att_cntrl.P_Pitch = Kv;
altb2 0:a479dc61e931 131 // --- initialize PWMS
altb2 0:a479dc61e931 132 wait(1);
altb2 0:a479dc61e931 133 uint32_t pwm_init_us = 500;
altb2 0:a479dc61e931 134 PWMOut1.period_ms(5);
altb2 0:a479dc61e931 135 PWMOut1.pulsewidth_us(pwm_init_us);
altb2 0:a479dc61e931 136 PWMOut2.period_ms(5);
altb2 0:a479dc61e931 137 PWMOut2.pulsewidth_us(pwm_init_us);
altb2 0:a479dc61e931 138 PWMOut3.period_ms(5);
altb2 0:a479dc61e931 139 PWMOut3.pulsewidth_us(pwm_init_us);
altb2 0:a479dc61e931 140 PWMOut4.period_ms(5);
altb2 0:a479dc61e931 141 PWMOut4.pulsewidth_us(pwm_init_us);
altb2 0:a479dc61e931 142 copter.calc_copter(myMotor);
altb2 0:a479dc61e931 143 myRC.map_Channels();
altb2 0:a479dc61e931 144 myRC.cou=0;
altb2 0:a479dc61e931 145 myMotor.calc_n2pwm_9k5();
altb2 0:a479dc61e931 146 //myMotor.calc_n2pwm_8k4();
altb2 0:a479dc61e931 147 global_timer.reset();
altb2 0:a479dc61e931 148 global_timer.start();
altb2 0:a479dc61e931 149 wait(1);
altb2 0:a479dc61e931 150 while(!myRC.isAlive)
altb2 0:a479dc61e931 151 {
altb2 0:a479dc61e931 152 wait(.5);
altb2 0:a479dc61e931 153 pc.printf("Failed to receive RC - signal!\r\n");
altb2 0:a479dc61e931 154 }
altb2 0:a479dc61e931 155 pc.printf("RC - signal on!\r\n");
altb2 0:a479dc61e931 156 wait(.5);
altb2 0:a479dc61e931 157 if(1){
altb2 0:a479dc61e931 158 // start main threads:
altb2 0:a479dc61e931 159 thread_mainLoop.start(&updateLoop);
altb2 0:a479dc61e931 160 mainLoop.attach(&sendSignal_mainLoop, TsCntrl);
altb2 0:a479dc61e931 161 thread_read_US_OF_sensors.start(&read_US_OF_sensors);
altb2 0:a479dc61e931 162 US_OF_sensors_loop.attach(&sendSignal_read_US_OF_sensors,Ts50);
altb2 0:a479dc61e931 163 my_logger.start_logging(TsSDLog);
altb2 0:a479dc61e931 164 my_logger.pause_logging();
altb2 0:a479dc61e931 165 }
altb2 0:a479dc61e931 166 }
altb2 0:a479dc61e931 167 // -----------------------------------------------------------------------------
altb2 0:a479dc61e931 168 // main loop with state handling and controllers
altb2 0:a479dc61e931 169 // -----------------------------------------------------------------------------
altb2 0:a479dc61e931 170 void updateLoop(void){
altb2 0:a479dc61e931 171 pc.printf("Start Main loop...\r\n");
altb2 0:a479dc61e931 172 bool flightmode_changed = false;
altb2 0:a479dc61e931 173 float old_dt=0;
altb2 0:a479dc61e931 174 uint8_t flm_temp = 1;
altb2 0:a479dc61e931 175 uint8_t flm_loc = 1;
altb2 0:a479dc61e931 176 float des_values[3]; // temporary variable for desired values
altb2 0:a479dc61e931 177 des_values[0]=0.0; // temporary variable for desired values
altb2 0:a479dc61e931 178 des_values[1]=0.0; // temporary variable for desired values
altb2 0:a479dc61e931 179 des_values[2]=0.0; // temporary variable for desired values
altb2 0:a479dc61e931 180 while(1){
altb2 0:a479dc61e931 181 thread_mainLoop.signal_wait(signal_mainLoop);
altb2 0:a479dc61e931 182 old_dt = dt;
altb2 0:a479dc61e931 183 dt = global_timer.read(); // time elapsed in current state
altb2 0:a479dc61e931 184 my_logger.data_vector[24] = dt - old_dt; // time delta for analyses
altb2 0:a479dc61e931 185 if(myRC.flightmode_changed){ // This is triggered bei RC-PWM readout
altb2 0:a479dc61e931 186 flm_temp = myRC.get_flightmode();
altb2 0:a479dc61e931 187 if(flm_temp == VEL_OF_Z_POS & optical_flow.avg_scaled_quality() <150) // do not change to that flightmode, if OF quality ist too low
altb2 0:a479dc61e931 188 {
altb2 0:a479dc61e931 189 myRC.flightmode_changed = false; // set flag back, but do nothing else!
altb2 0:a479dc61e931 190 }
altb2 0:a479dc61e931 191 else{
altb2 0:a479dc61e931 192 flm_loc = flm_temp;
altb2 0:a479dc61e931 193 pc.printf("Changed FM to %d \r\n",flm_loc);
altb2 0:a479dc61e931 194 my_logger.data_vector[23]=(float)flm_loc;
altb2 0:a479dc61e931 195 myRC.flightmode_changed = false;
altb2 0:a479dc61e931 196 flightmode_changed = true;
altb2 0:a479dc61e931 197 }
altb2 0:a479dc61e931 198 }
altb2 0:a479dc61e931 199 switch(CS) {
altb2 0:a479dc61e931 200 case INIT: // at very beginning
altb2 0:a479dc61e931 201 if (dt > 5.0f && (myRC.PM1[1]<-0.9f) && (myRC.PM1[4]>0.9f)){
altb2 0:a479dc61e931 202 CS = INIT_MOTORS; // switch to FLAT state
altb2 0:a479dc61e931 203 global_timer.reset();
altb2 0:a479dc61e931 204 printf("INIT_MOTORS\r\n");
altb2 0:a479dc61e931 205 }
altb2 0:a479dc61e931 206 break; // CS: INIT
altb2 0:a479dc61e931 207 case INIT_MOTORS: //
altb2 0:a479dc61e931 208 if(dt < 2.0f && flipm){ // after 2 sec armed
altb2 0:a479dc61e931 209 for(uint8_t m=1;m <= copter.nb_motors;m++)
altb2 0:a479dc61e931 210 motorspeed[m]=100.0;
altb2 0:a479dc61e931 211 flipm = false;
altb2 0:a479dc61e931 212 }
altb2 0:a479dc61e931 213 else if(dt < 2.0f){ // after 2 sec armed
altb2 0:a479dc61e931 214 for(uint8_t m=1;m <= copter.nb_motors;m++)
altb2 0:a479dc61e931 215 motorspeed[m]=0.0f;
altb2 0:a479dc61e931 216 flipm = true;
altb2 0:a479dc61e931 217 }
altb2 0:a479dc61e931 218 else{
altb2 0:a479dc61e931 219 CS = WAIT_ARMING;
altb2 0:a479dc61e931 220 global_timer.reset();
altb2 0:a479dc61e931 221 pc.printf("Motors initialized\r\n");
altb2 0:a479dc61e931 222 }
altb2 0:a479dc61e931 223 break; // CS: INIT_MOTORS
altb2 0:a479dc61e931 224 case WAIT_ARMING: //
altb2 0:a479dc61e931 225 if(flm_loc == RTL) // HACK!: update scaled Parameters
altb2 0:a479dc61e931 226 {
altb2 0:a479dc61e931 227 /*rate_cntrl_Roll.scale_PID_param(map_pwm_2_scale(myRC.pwms[10]));
altb2 0:a479dc61e931 228 rate_cntrl_Pitch.scale_PID_param(map_pwm_2_scale(myRC.pwms[10]));
altb2 0:a479dc61e931 229 att_cntrl.P_Roll = map_pwm_2_scale(myRC.pwms[11]) * Kv;
altb2 0:a479dc61e931 230 att_cntrl.P_Pitch = map_pwm_2_scale(myRC.pwms[11]) * Kv;*/
altb2 0:a479dc61e931 231 my_logger.continue_logging();
altb2 0:a479dc61e931 232 }
altb2 0:a479dc61e931 233 if((myRC.PM1[1] < -.9) && (myRC.PM1[4]>0.9f) ){ // use CH1 (Roll) and CH4 (Yaw) to arm (stick to middle)
altb2 0:a479dc61e931 234 CS = ARMING;
altb2 0:a479dc61e931 235 my_logger.continue_logging();
altb2 0:a479dc61e931 236 pc.printf("Rate Cntrl P: %2.3f\r\n",rate_cntrl_Roll.get_P_gain());
altb2 0:a479dc61e931 237 pc.printf("Att Cntrl P: %2.3f\r\n",att_cntrl.P_Roll);
altb2 0:a479dc61e931 238 global_timer.reset();
altb2 0:a479dc61e931 239 }
altb2 0:a479dc61e931 240 break; // CS: WAIT_ARMING
altb2 0:a479dc61e931 241 case ARMING: //
altb2 0:a479dc61e931 242 if((myRC.PM1[1] >= -.9) || (myRC.PM1[4]<.9f)){
altb2 0:a479dc61e931 243 CS = WAIT_ARMING;
altb2 0:a479dc61e931 244 global_timer.reset();
altb2 0:a479dc61e931 245 }
altb2 0:a479dc61e931 246 else if(dt > 1.0f){ // after 1 sec armed
altb2 0:a479dc61e931 247 CS = START_MOTORS;
altb2 0:a479dc61e931 248 global_timer.reset();
altb2 0:a479dc61e931 249 pc.printf("Armed, start motors at %3.0f rad/s \r\n",copter.static_thrust_n*0.1f);
altb2 0:a479dc61e931 250 }
altb2 0:a479dc61e931 251 break; // CS: ARMING
altb2 0:a479dc61e931 252 case START_MOTORS: //
altb2 0:a479dc61e931 253 for(uint8_t m=1;m <= copter.nb_motors;m++)
altb2 0:a479dc61e931 254 motorspeed[m]=copter.static_thrust_n*0.1f;
altb2 0:a479dc61e931 255 if (dt > 1.5f){
altb2 0:a479dc61e931 256 CS = FLIGHT;
altb2 0:a479dc61e931 257 global_timer.reset();
altb2 0:a479dc61e931 258 Mxy_limit = copter.max_Mxy;
altb2 0:a479dc61e931 259 rate_cntrl_Roll.reset(0.0);
altb2 0:a479dc61e931 260 rate_cntrl_Roll.set_limits(-Mxy_limit,Mxy_limit);
altb2 0:a479dc61e931 261 rate_cntrl_Pitch.reset(0.0);
altb2 0:a479dc61e931 262 rate_cntrl_Pitch.set_limits(-Mxy_limit,Mxy_limit);
altb2 0:a479dc61e931 263 // rate_cntrl_Roll_rolloff.reset(0.0);
altb2 0:a479dc61e931 264 // rate_cntrl_Pitch_rolloff.reset(0.0);
altb2 0:a479dc61e931 265 rate_cntrl_Yaw.reset(0.0);
altb2 0:a479dc61e931 266 rate_cntrl_Yaw.set_limits(-copter.max_Mz,copter.max_Mz);
altb2 0:a479dc61e931 267 pos_cntrl_z.reset(0.0);
altb2 0:a479dc61e931 268 z_des = 0.0;
altb2 0:a479dc61e931 269 }
altb2 0:a479dc61e931 270 break; // CS: START_MOTORS
altb2 0:a479dc61e931 271 case FLIGHT:
altb2 0:a479dc61e931 272 // 2nd SWITCH-CASE
altb2 0:a479dc61e931 273 switch(flm_loc){
altb2 0:a479dc61e931 274 case STABILIZED: // STABILIZED: Control RP-Angles with Sticks, Yaw-Rate with Sticks, Thrust with Sticks
altb2 0:a479dc61e931 275 des_values[0] = myRC.PM1[1] * 0.5f; // +- 1 correspond to +-0.5 rad desired angle
altb2 0:a479dc61e931 276 des_values[1] = myRC.PM1[2] * 0.5f; // +- 1 correspond to +-0.5 rad desired angle
altb2 0:a479dc61e931 277 des_values[2] = -myRC.PM1[4]* 0.8f;//integrate_CH4_2_yaw_angle(myRC.PM1[4]);; // integrate +- 1 to yaw angle
altb2 0:a479dc61e931 278 F_thrust = PM1_2_F_Thrust(myRC.PM1[3]); // desired thrust
altb2 0:a479dc61e931 279 RPY_controller(des_values, 1,1,Mxyz);
altb2 0:a479dc61e931 280 break; // flm_loc: STABILIZED
altb2 0:a479dc61e931 281 case ACRO: // ACRO: Control Rates with sticks, Thrust with Sticks
altb2 0:a479dc61e931 282 des_values[0] = myRC.PM1[1]*2.5f; // +- 1 correspond to +-1 rad/s desired rate
altb2 0:a479dc61e931 283 des_values[1] = myRC.PM1[2]*2.5f; // +- 1 correspond to +-1 rad/s desired rate
altb2 0:a479dc61e931 284 des_values[2] = -myRC.PM1[4]*1.5f; // +- 1 correspond to +-1 rad/s desired rate
altb2 0:a479dc61e931 285 F_thrust = PM1_2_F_Thrust(myRC.PM1[3]); // desired thrust
altb2 0:a479dc61e931 286 RPY_controller(des_values, 0,1,Mxyz);
altb2 0:a479dc61e931 287 break; // flm_loc: ACRO
altb2 0:a479dc61e931 288 case ALT_HOLD: // Altitde Hold (with US Sensor)
altb2 0:a479dc61e931 289 if(flightmode_changed){
altb2 0:a479dc61e931 290 cur_pos[2] = ahrs.xyzUS[2];
altb2 0:a479dc61e931 291 pos_cntrl_z.reset(F_thrust);
altb2 0:a479dc61e931 292 flightmode_changed = false;
altb2 0:a479dc61e931 293 // pc.printf("Initialized z:%1.3f\r\n",cur_pos[2]);
altb2 0:a479dc61e931 294 }
altb2 0:a479dc61e931 295 des_values[0] = myRC.PM1[1] * 0.5f; // +- 1 correspond to +-0.5 rad desired angle
altb2 0:a479dc61e931 296 des_values[1] = myRC.PM1[2] * 0.5f; // +- 1 correspond to +-0.5 rad desired angle
altb2 0:a479dc61e931 297 des_values[2] = -myRC.PM1[4]* 0.8f; //integrate_CH4_2_yaw_angle(myRC.PM1[4]);; // integrate +- 1 to yaw angle
altb2 0:a479dc61e931 298 // cur_pos[2] += 0.8 * TsCntrl * deadzone(myRC.PM1[3],-0.15,0.15);
altb2 0:a479dc61e931 299 // cur_pos[2] = limit_minmax(cur_pos[2],-1.0,0.8);
altb2 0:a479dc61e931 300 //F_thrust = pos_cntrl_z(cur_pos[2] - ahrs.xyzUS[2]);
altb2 0:a479dc61e931 301 F_thrust = pos_cntrl_z(0.8f - ahrs.xyzLIDAR[2]); // use fixed value here and use analog Sensor
altb2 0:a479dc61e931 302 RPY_controller(des_values, 1,1,Mxyz);
altb2 0:a479dc61e931 303 break; // flm_loc: ALT_HOLD
altb2 0:a479dc61e931 304 case VEL_OF_Z_POS: // This is the velocity mode with optical flow sensor
altb2 0:a479dc61e931 305 if(flightmode_changed){
altb2 0:a479dc61e931 306 vel_cntrl_x.reset(0.0);
altb2 0:a479dc61e931 307 vel_cntrl_y.reset(0.0);
altb2 0:a479dc61e931 308 // pos_cntrl_z.reset(F_thrust); // carfull!!! only valid if this state comes from ALT_HOLD
altb2 0:a479dc61e931 309 flightmode_changed = false;
altb2 0:a479dc61e931 310 }
altb2 0:a479dc61e931 311 des_values[1] = vel_cntrl_x(1.5f * myRC.PM1[2] - ahrs.v_xyzOF[0]); // Pitchachse: korrekt: positices pitchen führt zu Bewegung in +x
altb2 0:a479dc61e931 312 des_values[0] = -vel_cntrl_y(-1.5f * myRC.PM1[1] - ahrs.v_xyzOF[1]);; // Rollachse: Diese ist gedreht: Positives Rollen fuehrt zu Bewegung -y, Hebel nach recht ebenfalls!!!
altb2 0:a479dc61e931 313 des_values[2] = -myRC.PM1[4]* 0.8f;
altb2 0:a479dc61e931 314 F_thrust = pos_cntrl_z(0.8f - ahrs.xyzLIDAR[2]); // use fixed value here and use analog Sensor
altb2 0:a479dc61e931 315 RPY_controller(des_values, 1,1,Mxyz);
altb2 0:a479dc61e931 316 break; // flm_loc: VEL_OF_Z_POS
altb2 0:a479dc61e931 317 default: break;
altb2 0:a479dc61e931 318 } // end of switch(flm_loc)
altb2 0:a479dc61e931 319 // ... continue FLIGHT case
altb2 0:a479dc61e931 320 motor_mix(Mxyz,F_thrust,motorspeed); // MAp TOrques to Motor speeds
altb2 0:a479dc61e931 321 if((myRC.PM1[1] > 0.8f) && (myRC.PM1[4]<-0.8f) && (myRC.PM1[3]<-0.8f) && disarm_flag == false){ // use CH1 (Roll) and CH4 (Yaw) to disarm (stick to leftright)
altb2 0:a479dc61e931 322 disarm_flag=true;
altb2 0:a479dc61e931 323 global_timer.reset();
altb2 0:a479dc61e931 324 }
altb2 0:a479dc61e931 325 if(disarm_flag == true && dt > 0.8f){
altb2 0:a479dc61e931 326 disarm_flag=false;
altb2 0:a479dc61e931 327 global_timer.reset();
altb2 0:a479dc61e931 328 CS = MOTOR_STOPPED;
altb2 0:a479dc61e931 329 my_logger.pause_logging();
altb2 0:a479dc61e931 330 pc.printf("UAV disarmed\r\n");
altb2 0:a479dc61e931 331 }
altb2 0:a479dc61e931 332 break; // case FLIGHT
altb2 0:a479dc61e931 333 case MOTOR_STOPPED:
altb2 0:a479dc61e931 334 for(uint8_t m=1;m <= copter.nb_motors;m++)
altb2 0:a479dc61e931 335 motorspeed[m]=0.0f;
altb2 0:a479dc61e931 336 if(dt>1){
altb2 0:a479dc61e931 337 global_timer.reset();
altb2 0:a479dc61e931 338 CS = WAIT_ARMING;
altb2 0:a479dc61e931 339 } // case MOTOR_STOPPED
altb2 0:a479dc61e931 340 break;
altb2 0:a479dc61e931 341 default: break;
altb2 0:a479dc61e931 342 } // end of switch(CS)
altb2 0:a479dc61e931 343 // ------- Datalogger
altb2 0:a479dc61e931 344 my_logger.data_vector[15] = Mxyz[0];
altb2 0:a479dc61e931 345 my_logger.data_vector[16] = Mxyz[1];
altb2 0:a479dc61e931 346 my_logger.data_vector[17] = Mxyz[2];
altb2 0:a479dc61e931 347 my_logger.data_vector[18]=F_thrust;
altb2 0:a479dc61e931 348 my_logger.data_vector[19]=motorspeed[1];
altb2 0:a479dc61e931 349 my_logger.data_vector[20]=motorspeed[2];
altb2 0:a479dc61e931 350 my_logger.data_vector[21]=motorspeed[3];
altb2 0:a479dc61e931 351 my_logger.data_vector[22]=motorspeed[4];
altb2 0:a479dc61e931 352 my_logger.data_vector[25]=des_values[0];
altb2 0:a479dc61e931 353 my_logger.data_vector[26]=des_values[1];
altb2 0:a479dc61e931 354 my_logger.data_vector[27]=des_values[2];
altb2 0:a479dc61e931 355 // pc.printf("%3.3f %3.3f %3.3f \r\n",des_values[0],des_values[1],des_values[2]);
altb2 0:a479dc61e931 356 } // of while(1) (the thread)
altb2 0:a479dc61e931 357 }
altb2 0:a479dc61e931 358 //-----------------------------------------------------------------------------
altb2 0:a479dc61e931 359 // Read Ultrasonic range finder Sensors (via PWM) and Optcal Flow Sensors
altb2 0:a479dc61e931 360 // WARNING: US-Sensors interfere each other, thus the sensorw are read sequentially
altb2 0:a479dc61e931 361 void read_US_OF_sensors(void){
altb2 0:a479dc61e931 362 while(1)
altb2 0:a479dc61e931 363 {
altb2 0:a479dc61e931 364 thread_read_US_OF_sensors.signal_wait(signal_read_US_OF_sensors);
altb2 0:a479dc61e931 365 /*
altb2 0:a479dc61e931 366 rf.read_and_filter(rf.current_sensor++);
altb2 0:a479dc61e931 367 if(rf.current_sensor >= rf.n_sensors) // loop over 4 Sensors from step to step.(only 1/4 sampling rate)
altb2 0:a479dc61e931 368 rf.current_sensor = 0;
altb2 0:a479dc61e931 369 //for(uint8_t k=0;k<rf.n_sensors;k++)printf("S%d: %1.3f ",k,rf.val[k]);printf("\r\n");
altb2 0:a479dc61e931 370 ahrs.xyzUS[0] = 1.0f-(rf.val[2]+rf.val[3])/2; // mind x positive! If Sensors measure larger distance, it is towards -x !!!
altb2 0:a479dc61e931 371 // distance 1m is the origin!
altb2 0:a479dc61e931 372 ahrs.xyzUS[1] = rf.val[1]; // larger position of sensor 1 means +y (correct direction)
altb2 0:a479dc61e931 373 ahrs.xyzUS[2] = rf.val[0]; // z-sensor
altb2 0:a479dc61e931 374 ahrs.rxryrzUS[2] = (rf.val[3]-rf.val[2])/0.4; // Yaw axis
altb2 0:a479dc61e931 375 my_logger.data_vector[18]=rf.val[0];
altb2 0:a479dc61e931 376 */
altb2 0:a479dc61e931 377 ahrs.xyzAS[2] = 2.311f *exp(-6.5514f*ai1.read())+0.2017f;
altb2 0:a479dc61e931 378 ahrs.xyzLIDAR[2] = tfmini()*0.001f;
altb2 0:a479dc61e931 379 my_logger.data_vector[14]=ahrs.xyzLIDAR[2];
altb2 0:a479dc61e931 380 //my_logger.data_vector[22]=ahrs.xyzAS[2];
altb2 0:a479dc61e931 381 if(optical_flow.update_integral()) {
altb2 0:a479dc61e931 382 ahrs.v_xyzOF[0]= vel_cntrl_x_rolloff(-optical_flow.avg_flowx()*0.001f + ahrs.raw_gy2gy(ahrs.imu.gyroY) * ahrs.xyzLIDAR[2]);
altb2 0:a479dc61e931 383 ahrs.v_xyzOF[1]= vel_cntrl_y_rolloff( optical_flow.avg_flowy()*0.001f - ahrs.raw_gx2gx(ahrs.imu.gyroX) * ahrs.xyzLIDAR[2]);
altb2 0:a479dc61e931 384 ahrs.xyzOF[2]= 0.0f;//((float)optical_flow.ground_distance())*0.001f;
altb2 0:a479dc61e931 385 my_logger.data_vector[10]=ahrs.v_xyzOF[0];
altb2 0:a479dc61e931 386 my_logger.data_vector[11]=ahrs.v_xyzOF[1];
altb2 0:a479dc61e931 387 my_logger.data_vector[13]=(float)optical_flow.avg_scaled_quality();
altb2 0:a479dc61e931 388 my_logger.data_vector[28]=optical_flow.gyro_x_rate();
altb2 0:a479dc61e931 389 my_logger.data_vector[29]=optical_flow.gyro_y_rate();
altb2 0:a479dc61e931 390 my_logger.data_vector[30]=optical_flow.gyro_z_rate();
altb2 0:a479dc61e931 391 }
altb2 0:a479dc61e931 392 }
altb2 0:a479dc61e931 393 }
altb2 0:a479dc61e931 394
altb2 0:a479dc61e931 395
altb2 0:a479dc61e931 396 /* ****************************************************************************
altb2 0:a479dc61e931 397 void RPY_controller(float *des_values, uint8_t rate_and_att,float* Mxyz){
altb2 0:a479dc61e931 398 Roll/Pitch/Yaw Controller,
altb2 0:a479dc61e931 399 INPUT:
altb2 0:a479dc61e931 400 des_values desired angle ( mode stabilized aso), rotation rates (acro)
altb2 0:a479dc61e931 401 rate_and_att logic for flight mode (1 = cascade control)
altb2 0:a479dc61e931 402 *Mxyz resulting values
altb2 0:a479dc61e931 403 ***************************************************************************** */
altb2 0:a479dc61e931 404 void RPY_controller(float *des_values, uint8_t rate_and_att,uint8_t filtertype,float* Mxyz){
altb2 0:a479dc61e931 405 float rate_des[4];
altb2 0:a479dc61e931 406 //--------------------------------
altb2 0:a479dc61e931 407 if(rate_and_att ==1){ // this is for Mode STABILIZED (and Loiter aso)
altb2 0:a479dc61e931 408 rate_des[1] = att_cntrl.P_Roll * (des_values[0] - ahrs.getRoll(filtertype));
altb2 0:a479dc61e931 409 rate_des[2] = att_cntrl.P_Pitch * (des_values[1] - ahrs.getPitch(filtertype));
altb2 0:a479dc61e931 410 rate_des[3] = des_values[2];//att_cntrl.P_Yaw * (des_values[2] - ahrs.getYawRadians());
altb2 0:a479dc61e931 411 }
altb2 0:a479dc61e931 412 else{ // this is for Mode ACRO
altb2 0:a479dc61e931 413 rate_des[1] = des_values[0];
altb2 0:a479dc61e931 414 rate_des[2] = des_values[1];
altb2 0:a479dc61e931 415 rate_des[3] = des_values[2];
altb2 0:a479dc61e931 416 }
altb2 0:a479dc61e931 417 // Mxyz[0]= rate_cntrl_Roll_rolloff( rate_cntrl_Roll(rate_des[1] - ahrs.raw_gx2gx(ahrs.imu.gyroX)) );
altb2 0:a479dc61e931 418 // Mxyz[1]= rate_cntrl_Pitch_rolloff( rate_cntrl_Pitch(rate_des[2] - ahrs.raw_gy2gy(ahrs.imu.gyroY)) );
altb2 0:a479dc61e931 419 float gx = ahrs.raw_gx2gx(ahrs.imu.gyroX);
altb2 0:a479dc61e931 420 float gy = ahrs.raw_gy2gy(ahrs.imu.gyroY);
altb2 0:a479dc61e931 421 Mxyz[0]= rate_cntrl_Roll(rate_des[1] - gx, gx);
altb2 0:a479dc61e931 422 Mxyz[1]= rate_cntrl_Pitch(rate_des[2] - gy, gy);
altb2 0:a479dc61e931 423 Mxyz[2]= rate_cntrl_Yaw(rate_des[3] - ahrs.raw_gz2gz(ahrs.imu.gyroZ));
altb2 0:a479dc61e931 424 }
altb2 0:a479dc61e931 425 // *****************************************************************************
altb2 0:a479dc61e931 426 // *****************************************************************************
altb2 0:a479dc61e931 427 float limit_minmax(float val,float mi,float ma){
altb2 0:a479dc61e931 428 if(val < mi)
altb2 0:a479dc61e931 429 val = mi;
altb2 0:a479dc61e931 430 if(val > ma)
altb2 0:a479dc61e931 431 val = ma;
altb2 0:a479dc61e931 432 return val;
altb2 0:a479dc61e931 433 }
altb2 0:a479dc61e931 434
altb2 0:a479dc61e931 435 // *****************************************************************************
altb2 0:a479dc61e931 436 // Dead zone, from lo ... hi
altb2 0:a479dc61e931 437 float deadzone(float x,float lo,float hi){
altb2 0:a479dc61e931 438 return (x>hi)*(x-hi)+(x<lo)*(x-lo);
altb2 0:a479dc61e931 439 }
altb2 0:a479dc61e931 440
altb2 0:a479dc61e931 441 // *****************************************************************************
altb2 0:a479dc61e931 442 // nonlinear characteristics for thrust
altb2 0:a479dc61e931 443 float PM1_2_F_Thrust(float x)
altb2 0:a479dc61e931 444 {
altb2 0:a479dc61e931 445 return 9.81f*copter.weight*(0.5f*x+1.1f - 0.06f/(x+1.1f)); // y=0.5*x+1.1-0.06./(x+1.1);
altb2 0:a479dc61e931 446 }
altb2 0:a479dc61e931 447
altb2 0:a479dc61e931 448
altb2 0:a479dc61e931 449 void sendSignal_mainLoop(void){
altb2 0:a479dc61e931 450 thread_mainLoop.signal_set(signal_mainLoop);
altb2 0:a479dc61e931 451 }
altb2 0:a479dc61e931 452 void sendSignal_read_US_OF_sensors(void){
altb2 0:a479dc61e931 453 thread_read_US_OF_sensors.signal_set(signal_read_US_OF_sensors);
altb2 0:a479dc61e931 454 }
altb2 0:a479dc61e931 455
altb2 0:a479dc61e931 456 void sendSignal_UAV_state(void){
altb2 0:a479dc61e931 457 thread_UAV_state.signal_set(signal_UAV_state);
altb2 0:a479dc61e931 458 }
altb2 0:a479dc61e931 459 void sendSignal_Output(void){
altb2 0:a479dc61e931 460 thread_Output.signal_set(signal_Output);
altb2 0:a479dc61e931 461 }
altb2 0:a479dc61e931 462
altb2 0:a479dc61e931 463 /*
altb2 0:a479dc61e931 464 Thread thread_mainLoop(osPriorityNormal, 4096);
altb2 0:a479dc61e931 465 Thread thread_AHRS(osPriorityBelowNormal, 4096);
altb2 0:a479dc61e931 466 Thread thread_UAV_state(osPriorityLow, 4096);
altb2 0:a479dc61e931 467 Thread thread_Output(osPriorityIdle, 4096);
altb2 0:a479dc61e931 468
altb2 0:a479dc61e931 469 Signal signal_mainLoop;
altb2 0:a479dc61e931 470 Signal signal_AHRS;
altb2 0:a479dc61e931 471 Signal signal_UAV_state;
altb2 0:a479dc61e931 472 Signal signal_Output;
altb2 0:a479dc61e931 473
altb2 0:a479dc61e931 474 Ticker AHRS; // Madgwick filter for AHRS
altb2 0:a479dc61e931 475 Ticker mainLoop; // Main loop at 200Hz
altb2 0:a479dc61e931 476 Ticker UAV_state; // check if UAV crashed / flying / landed etc.
altb2 0:a479dc61e931 477 Ticker Output; // Output loop at 10Hz (Writing and saving
altb2 0:a479dc61e931 478 */