Work in progress...
Dependencies: ESC FreeIMU mbed-rtos mbed
Experiment - work in progress...
Diff: main.cpp
- Revision:
- 5:33abcc31b0aa
- Parent:
- 4:46f3c3dd5977
- Child:
- 6:4ddd68260f76
--- a/main.cpp Sat May 03 13:22:30 2014 +0000 +++ b/main.cpp Mon May 12 22:58:06 2014 +0000 @@ -1,22 +1,18 @@ #include "math.h" #include "mbed.h" #include "rtos.h" -#include "EthernetInterface.h" #include "esc.h" -#include "PID.h" -#include "MPU6050.h" -#include "IMUfilter.h" +#include "FreeIMU.h" #include <string> //Author: Matteo Terruzzi //Target differential of time in seconds, for the various program cycles: - //timings as for main cycle: -#define TARGET_IMU_DT 0.002 //every 1 step: 100% -#define TARGET_MAIN_DT 0.016 //every 8 steps: 12.5% + 2 step start delay -#define TARGET_TX_DT 0.040 //every 20 steps: 5% + 1 step start delay -#define TARGET_RX_DT 0.040 //with previous +#define TARGET_IMU_DT 0.002 //500Hz on main thread, every step of the cycle. +#define TARGET_MAIN_DT 0.016 //62.5Hz on main thread, every 8 steps + 7 step delay. +#define TARGET_TX_DT 0.050 //20Hz on other thread. Exchanged with main every 24 steps + 21 step delay (dt=48ms, 20.8333Hz) +#define TARGET_RX_DT 0.050 //waited with previous: this dt is only measured, not waited. //For the various dt, "average" is computed using a sort of low-pass filter of the actual value. //The formula (recurrence equation) is: @@ -34,58 +30,57 @@ #define AVERAGE_DT_K_GAIN 0.0125 //Blinking status leds -#define LED_ESC LED1 -#define LED_IMU LED2 +#define LED_IMU LED1 +#define LED_ESC LED2 #define LED_TXRX LED3 -#define LED_RX LED4 +#define LED_RX LED4 +#define FAST_FLASH_ON(led,times) for(int i=0;i<times;++i){Thread::wait(25); led = 0; Thread::wait(50); led = 1; Thread::wait(25); } +#define FAST_FLASH_OFF(led,times) for(int i=0;i<times;++i){Thread::wait(25); led = 1; Thread::wait(50); led = 0; Thread::wait(25); } +#define SLOW_FLASH_ON(led,times) for(int i=0;i<times;++i){Thread::wait(250); led = 0; Thread::wait(500); led = 1; Thread::wait(250);} #include "state.h" -#include "IMU.h" -#include "TXRX.h" +#include "TXRX_nomagic.h" +FreeIMU IMU_imu; + int main() { - - Serial pc(USBTX,USBRX); //INITIALIZATION //------------------------------------------------------------------------------- //Setup ESCs - ESC esc1(p23); - ESC esc2(p24); - ESC esc3(p25); - ESC esc4(p26); + ESC esc1(p23); esc1=0; + ESC esc2(p24); esc1=0; + ESC esc3(p25); esc1=0; + ESC esc4(p26); esc1=0; //Setup status leds - DigitalOut led_esc(LED_ESC); led_esc = 1; //flip at esc update (fixed 0 means that the ESCs was not been initiated--the program is stucked before this point) - DigitalOut led_imu(LED_IMU); led_imu = 0; //flip at imu computations done (fixed 0 means that the imu sensors don't respond) - DigitalOut led_txrx(LED_TXRX); led_txrx = 0; //flip at remote signal exchange done (fixed 0 means that the TXRX_thread has not been started) - - //Setup Ethernet - EthernetInterface interface; - interface.init("192.168.2.16","255.255.255.0","192.168.2.1"); - interface.connect(); + DigitalOut led_imu(LED_IMU); led_imu = 0; + DigitalOut led_esc(LED_ESC); led_esc = 0; + DigitalOut led_txrx(LED_TXRX); led_txrx = 0; + FAST_FLASH_ON(led_esc,5); //Setup remote control - Thread TXRX_thread (TXRX_thread_routine); - led_txrx = 1; + FAST_FLASH_OFF(led_txrx,2); + Thread TXRX_thread(TXRX_thread_routine); + Thread::wait(8000); + FAST_FLASH_ON(led_txrx,5); + + //Setup IMU + Thread::wait(2000); + FAST_FLASH_OFF(led_imu,2); + IMU_imu.init(true); + Thread::wait(8000); + FAST_FLASH_ON(led_imu,5); //Setup state QuadState mainQuadState; mainQuadState.reset(); QuadState rxQuadState; rxQuadState.reset(); QuadState txQuadState; txQuadState.reset(); - //Setup FreeIMU - IMUfilter IMU_filter(TARGET_IMU_DT,40); - MPU6050 IMU_sensor(p28, p27); - IMU_sensor.setGyroRange(MPU6050_GYRO_RANGE_250); - IMU_sensor.setAcceleroRange(MPU6050_ACCELERO_RANGE_4G); - led_imu = 1; - - //MAIN CONTROL CYCLE PREPARATION @@ -94,128 +89,80 @@ unsigned short int step = 0; //Just a moment... Let the other threads begin! - Thread::wait(2000 /*ms*/); Thread::yield(); + Thread::wait(1000.0 * (TARGET_MAIN_DT + TARGET_IMU_DT + TARGET_TX_DT + TARGET_RX_DT) * 10.0); //just made sure the other threads had time to begin. //Setup timers - Timer IMU_dt_timer; IMU_dt_timer.reset(); IMU_dt_timer.start(); Timer dt_timer; dt_timer.reset(); dt_timer.start(); - Thread::wait(1000.0 * min(mainQuadState.target_imu_dt,mainQuadState.target_main_dt)); + Timer IMU_dt_timer; IMU_dt_timer.reset(); IMU_dt_timer.start(); + Thread::wait(1000.0 * TARGET_IMU_DT); + - //pid - /*PID targetRoll_pid(0.1,0.0001,0.5, 0.020); - targetRoll_pid.setInputLimits(-3.15/4,3.15/4); - targetRoll_pid.setOutputLimits(0,0.5);*/ - + //Some flashing animation + for(int i=100;i>10;i=(75*i)/100){ + led_txrx = 0;led_esc = 0;led_imu = 0; Thread::wait(i); + led_txrx = 1;led_esc = 1;led_imu = 1; Thread::wait(i); + } + + //MAIN CONTROL CYCLE //=================================================================================== while(1) { - - - //IMU INPUT - //------------------------------------------------------------------------------- - - //Measure the time and sleep to correct the interval + + + //measure the time for IMU cycle QUAD_STATE_READ_ACTUAL_DT(mainQuadState,imu,IMU_dt_timer) QUAD_STATE_WAIT_DT_TARGET(mainQuadState.actual_imu_dt,mainQuadState.target_imu_dt) QUAD_STATE_UPDATE_DT(mainQuadState,imu,IMU_dt_timer) + wait_us(1000); + + +if(step % 8 != 7){//see step%8==7; prevent double sensor refresh + + + //IMU INPUT + //------------------------------------------------------------------------------- + + led_imu = 1; + IMU_imu.getQ(NULL); + led_imu = 0; - led_imu = 1; +}//end of 7/8 steps +if(step % 8 == 7){ + - //Retrieve inertial values from sensors + //IMU INPUT AND ANGLES COMPUTATION + //------------------------------------------------------------------------------- + { - float a[3], g[3]; - IMU_sensor.getAccelero(a); - IMU_sensor.getGyro(g); - - mainQuadState.sensor_accel_x += a[0]/4 - mainQuadState.sensor_accel_x/4; - mainQuadState.sensor_accel_y += a[1]/4 - mainQuadState.sensor_accel_y/4; - mainQuadState.sensor_accel_z += a[2]/4 - mainQuadState.sensor_accel_z/4; - mainQuadState.sensor_gyro_r = g[0]; - mainQuadState.sensor_gyro_p = g[1]; - mainQuadState.sensor_gyro_y = g[2]; - - //Compute IMU filters - IMU_filter.updateFilter(g[0], g[1], g[2], a[0], a[1], a[2]); + float ypr[3]; + led_imu = 1; + IMU_imu.getYawPitchRoll(ypr); + mainQuadState.estimated_position_z = IMU_imu.getBaroAlt(); + IMU_imu.baro->getTemperature(); + mainQuadState.estimated_rotation_y = ypr[0]; + mainQuadState.estimated_rotation_p = ypr[1]; + mainQuadState.estimated_rotation_r = ypr[2]; + led_imu = 0; } if(mainQuadState.actual_imu_dt >= 100.0 * mainQuadState.target_imu_dt) mainQuadState.ZERO_MEANS_ZERO_ALL_MOTORS_NOW__DANGER = 0; //experiments only ////NOTE: FIXME: THAT'S ABSOLUTELY UNSAFE WHILE FLYING!!! - - led_imu = 0; - - - - -if(step % 20 == 2){ -//5% frequency; step%20==2 - - - - //REMOTE INPUT - //------------------------------------------------------------------------------- - led_txrx = 1; - - //Remote signal exchange - txQuadState = mainQuadState; //send info back - txQuadState.timestamp = time(NULL); - if(TXRX_stateExchange(txQuadState,rxQuadState)){ - mainQuadState.average_rx_dt = rxQuadState.average_rx_dt; - mainQuadState.actual_rx_dt = rxQuadState.actual_rx_dt; - mainQuadState.ZERO_MEANS_ZERO_ALL_MOTORS_NOW__DANGER = rxQuadState.ZERO_MEANS_ZERO_ALL_MOTORS_NOW__DANGER; - if(mainQuadState.actual_rx_dt >= 100.0 * mainQuadState.target_rx_dt) - mainQuadState.ZERO_MEANS_ZERO_ALL_MOTORS_NOW__DANGER = 0; //experiments only ////NOTE: FIXME: THAT'S ABSOLUTELY UNSAFE WHILE FLYING!!! - } - - - /*if(step % 640 == 2){ - - //Other tasks - - if(pc.writeable()){ - pc.printf("%s \r\n", mainQuadState.getJSON().c_str()); //the message is long => it slows down a lot! - } - }*/ - - led_txrx = 0; - - - -//end of 5% frequency; step%20==2 -} -if(step % 8 == 3){ -//12.5% frequency; step%8==3 - - - led_esc = 1; //ELABORATION //------------------------------------------------------------------------------- - - //Measure the time + + //Measure the time for main control cycle QUAD_STATE_UPDATE_DT(mainQuadState,main,dt_timer) - //Get estimated rotation - //IMU_filter.computeEuler(); - //mainQuadState.estimated_rotation_y = IMU_filter.getYaw(); - //mainQuadState.estimated_rotation_p = IMU_filter.getPitch(); - //mainQuadState.estimated_rotation_r = IMU_filter.getRoll(); - IMU_filter.getCorrectedEuler( - mainQuadState.estimated_rotation_r, - mainQuadState.estimated_rotation_p, - mainQuadState.estimated_rotation_y ); - IMU_filter.getQuaternion( - mainQuadState.estimated_rotation_q1, - mainQuadState.estimated_rotation_q2, - mainQuadState.estimated_rotation_q3, - mainQuadState.estimated_rotation_q4); + //Elaborate inputs to determinate outputs + led_esc = 1; - //Elaborate inputs to determinate outputs {//Roll PID float previous = mainQuadState.pid_rotation_r_error; mainQuadState.pid_rotation_r_error = mainQuadState.target_rotation_r - mainQuadState.estimated_rotation_r; @@ -225,7 +172,7 @@ + mainQuadState.pid_rotation_r_kI * mainQuadState.pid_rotation_r_error_integrative + mainQuadState.pid_rotation_r_kD * mainQuadState.pid_rotation_r_error_derivative; if(mainQuadState.pid_rotation_r_error_integrative > 100) mainQuadState.pid_rotation_r_error_integrative = 100; - else if(mainQuadState.pid_rotation_r_error_integrative > -100) mainQuadState.pid_rotation_r_error_integrative = -100; + else if(mainQuadState.pid_rotation_r_error_integrative < -100) mainQuadState.pid_rotation_r_error_integrative = -100; }{//Pitch PID float previous = mainQuadState.pid_rotation_p_error; mainQuadState.pid_rotation_p_error = mainQuadState.target_rotation_p - mainQuadState.estimated_rotation_p; @@ -235,7 +182,7 @@ + mainQuadState.pid_rotation_p_kI * mainQuadState.pid_rotation_p_error_integrative + mainQuadState.pid_rotation_p_kD * mainQuadState.pid_rotation_p_error_derivative; if(mainQuadState.pid_rotation_p_error_integrative > 100) mainQuadState.pid_rotation_p_error_integrative = 100; - else if(mainQuadState.pid_rotation_p_error_integrative > -100) mainQuadState.pid_rotation_p_error_integrative = -100; + else if(mainQuadState.pid_rotation_p_error_integrative < -100) mainQuadState.pid_rotation_p_error_integrative = -100; }{//Yaw PID float previous = mainQuadState.pid_rotation_y_error; mainQuadState.pid_rotation_y_error = mainQuadState.target_rotation_y - mainQuadState.estimated_rotation_y; @@ -245,7 +192,7 @@ + mainQuadState.pid_rotation_y_kI * mainQuadState.pid_rotation_y_error_integrative + mainQuadState.pid_rotation_y_kD * mainQuadState.pid_rotation_y_error_derivative; if(mainQuadState.pid_rotation_y_error_integrative > 100) mainQuadState.pid_rotation_y_error_integrative = 100; - else if(mainQuadState.pid_rotation_y_error_integrative > -100) mainQuadState.pid_rotation_y_error_integrative = -100; + else if(mainQuadState.pid_rotation_y_error_integrative < -100) mainQuadState.pid_rotation_y_error_integrative = -100; } //Compute actual throttle values if(mainQuadState.ZERO_MEANS_ZERO_ALL_MOTORS_NOW__DANGER == 0 @@ -264,16 +211,6 @@ mainQuadState.reference_throttle_2 = rxQuadState.reference_throttle_2; mainQuadState.reference_throttle_3 = rxQuadState.reference_throttle_3; mainQuadState.reference_throttle_4 = rxQuadState.reference_throttle_4; - - /*float roll = 0; - if(mainQuadState.target_rotation_r_isRequired){ - targetRoll_pid.setSetPoint(mainQuadState.target_rotation_r); - targetRoll_pid.setInterval(mainQuadState.average_main_dt); - targetRoll_pid.setProcessValue(mainQuadState.estimated_rotation_r); - roll = targetRoll_pid.compute(); - }else{ - targetRoll_pid.setSetPoint(mainQuadState.estimated_rotation_r); - }*/ if(mainQuadState.reference_throttle_1 <= -1000) mainQuadState.actual_throttle_1 = 0; @@ -307,7 +244,6 @@ } - //OUTPUT //------------------------------------------------------------------------------- @@ -322,19 +258,35 @@ esc2(); esc3(); esc4(); - - - led_esc = 0; -//end of 12.5% frequency; step%8==3 -} + +} //end of 1/8 steps +if(step % 24 == 21){ + //REMOTE INPUT/OUTPUT EXCHANGE + //------------------------------------------------------------------------------- + led_txrx = 1; + txQuadState = mainQuadState; //send info back + txQuadState.timestamp = time(NULL); + if(TXRX_stateExchange(txQuadState,rxQuadState)){ + mainQuadState.average_rx_dt = rxQuadState.average_rx_dt; + mainQuadState.actual_rx_dt = rxQuadState.actual_rx_dt; + mainQuadState.ZERO_MEANS_ZERO_ALL_MOTORS_NOW__DANGER = rxQuadState.ZERO_MEANS_ZERO_ALL_MOTORS_NOW__DANGER; + if(mainQuadState.actual_rx_dt >= 100.0 * mainQuadState.target_rx_dt) + mainQuadState.ZERO_MEANS_ZERO_ALL_MOTORS_NOW__DANGER = 0; //experiments only ////NOTE: FIXME: THAT'S ABSOLUTELY UNSAFE WHILE FLYING!!! + } + led_txrx = 0; + + +}//end of 1/24 steps + ++step; }//End of main control loop + //It must not get here. return 0; }