![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
BroBot Code for ESE350 Lab6 part 3 (Skeleton)
Dependencies: MPU6050_V3 mbed-rtos mbed
Fork of BroBot_RTOS_ESE350 by
Diff: main.cpp
- Revision:
- 10:48f640a54401
- Parent:
- 9:fb671fa0c0be
- Child:
- 11:2553f5798f84
--- a/main.cpp Mon Jan 09 17:50:35 2017 +0000 +++ b/main.cpp Tue Jan 10 21:10:39 2017 +0000 @@ -15,6 +15,13 @@ * To reset the motor positions you must press the josystick button anytime. ******************************************************************************/ +//Controller Values +float knob1, knob2, knob3, knob4; +float jstick_h, jstick_v; + +//Button +bool button; + //BroBot Begin #include "cmsis_os.h" #include "pin_assignments.h" @@ -24,10 +31,12 @@ #include "BroBot_IMU.h" #include "stepper_motors.h" #include "MRF24J40.h" +#include "communication.h" //Angle Offset is used to set the natural balance point of your robot. //You should adjust this offset so that your robots balance points is near 0 #define ANGLE_OFFSET 107 +#define MRF_CHANNEL 2 //For RF Communication #define JSTICK_H 8 @@ -62,9 +71,22 @@ #define ITERM_MAX_ERROR 25 // Iterm windup constants for PI control //40 #define ITERM_MAX 8000 // 5000 -//Controller Values -float knob1, knob2, knob3, knob4; -float jstick_h, jstick_v; +#define GPIOA p21 +#define GPIOB p22 +#define GPIOC p23 +#define GPIOD p24 + +//*********** Thread Definations BEGIN ***********// +void imu_update_thread(void const *args); +osThreadDef(imu_update_thread, osPriorityNormal, DEFAULT_STACK_SIZE); +//*********** Thread Definations END *************// + +//*********** Local Function Definations BEGIN **************// +void init_system(); +void init_imu(); +//*********** Local Function Definations END **************// + + //PID Default control values from constant definitions float Kp1 = KP; @@ -106,27 +128,34 @@ DigitalOut led3(LED3); DigitalOut led4(LED4); -//Button -bool button; -#include "communication.h" +//GPIO Pins +DigitalOut gpioMonitorA(GPIOA); +DigitalOut gpioMonitorB(GPIOB); +DigitalOut gpioMonitorC(GPIOC); +DigitalOut gpioMonitorD(GPIOD); -//Used to set angle upon startup, filter -bool FILTER_DISABLE = true; + + + +//Used to set angle upon startup +bool initilizeAngle = true; // ================================================================ -// === Threads === +// === IMU Thread === // ================================================================ -void led2_thread(void const *args) +void imu_update_thread(void const *args) { while (true) { - //if(mpuInterrupt) { + gpioMonitorA = 1; + if(mpuInterrupt){ + mpuInterrupt = false; led3 = !led3; /********************* All IMU Handling DO NOT MODIFY *****************/ //Disable IRQ //checkpin.rise(NULL); //reset interrupt flag and get INT_STATUS byte - mpuInterrupt = false; + mpuIntStatus = mpu.getIntStatus(); //get current FIFO count @@ -136,8 +165,7 @@ if ((mpuIntStatus & 0x10) || fifoCount == 1024) { // reset so we can continue cleanly mpu.resetFIFO(); - pc.printf("FIFO overflow!"); - + pc.printf("MPU FIFO overflow!"); //otherwise, check for DMP data ready interrupt (this should happen frequently) } else if (mpuIntStatus & 0x02) { //wait for correct available data length, should be a VERY short wait @@ -152,32 +180,35 @@ //Read new angle from IMU new_angle = (float)(dmpGetPhi() - ANGLE_OFFSET); + //Calculate the delta angle dAngle = new_angle - angle; //Filter out angle readings larger then MAX_ANGLE_DELTA - if( ((dAngle < 15) && (dAngle > -15)) || FILTER_DISABLE) { + if(initilizeAngle) { angle = new_angle; - FILTER_DISABLE = false; //turn of filter disabler + initilizeAngle = false; + } else if( ((dAngle < 15) && (dAngle > -15))) { + angle = new_angle; } else { - pc.printf("\t\t\t filtered angle \r\n"); + pc.printf("\t\t\t Delta Angle too Large: %d. Ignored \r\n",dAngle); } } + gpioMonitorA = 0; /********************* All IMU Handling DO NOT MODIFY *****************/ - //} + }//End of if(mpuInterrupt) loop + osThreadYield(); // Yield to a running thread + } +} - osDelay(1); - //pc.printf(" thread2 "); - } -} -osThreadDef(led2_thread, osPriorityNormal, DEFAULT_STACK_SIZE); + // ================================================================ // === INITIAL SETUP === // ================================================================ void init_imu() { - pc.printf("\r\r\n\n Start \r\n"); + pc.printf("Start IMU Initilization.. \r\n"); // Manual MPU initialization... accel=2G, gyro=2000º/s, filter=20Hz BW, output=200Hz mpu.setClockSource(MPU6050_CLOCK_PLL_ZGYRO); @@ -202,7 +233,7 @@ //Gyro Calibration wait_ms(500); - pc.printf("Gyro calibration!! Dont move the robot in 10 seconds... \r\n"); + pc.printf("Gyro calibration!! Dont move the robot in 1 second... \r\n"); wait_ms(500); // verify connection @@ -215,6 +246,42 @@ mpu.resetFIFO(); } +void init_system() +{ + initilizeAngle = true; + //Set the Channel. 0 is default, 15 is max + mrf.SetChannel(MRF_CHANNEL); + enable = DISABLE; //Disable Motors + pc.baud(115200); + pc.printf("Booting BroBot mbed RTOS..\r\n"); + + + //Initilize the IMU + init_imu(); + //Attach Interupt for IMU on rising edge of checkpin + checkpin.rise(&dmpDataReady); + pc.printf("IMU Initilized..\r\n"); + + //Init Stepper Motors + //Attach Motor Control Timer Call Back Functions + timer_M1.attach_us(&ISR1, ZERO_SPEED);//1s Period + timer_M2.attach_us(&ISR2, ZERO_SPEED);//1s Period + step_M1 = 1; + dir_M1 = 1; + pc.printf("Motors Initilized..\r\n"); + + //Timers initilized + timer.start(); + timer_value = timer.read_us(); + + //Init GPIO Monitors + gpioMonitorA = 0; + gpioMonitorB = 0; + gpioMonitorC = 0; + gpioMonitorD = 0; + +} + // ================================================================ // === MAIN PROGRAM LOOP === // ================================================================ @@ -240,38 +307,19 @@ int main() { - //Set the Channel. 0 is default, 15 is max - uint8_t channel = 2; - mrf.SetChannel(channel); - pc.baud(115200); - pc.printf("Start\r\n"); - init_imu(); - timer.start(); - //timer - timer_value = timer.read_us(); + - //Init Stepper Motors - //Attach Timer Interupts (Tiker) - timer_M1.attach_us(&ISR1, ZERO_SPEED); - timer_M2.attach_us(&ISR2, ZERO_SPEED); - step_M1 = 1; - dir_M1 = 1; - enable = DISABLE; //Disable Motors + init_system(); + enable = ENABLE; //Enable Motors - //Attach Interupt for IMU - checkpin.rise(&dmpDataReady); - - //Used to set angle upon startup, filter - //bool FILTER_DISABLE = true; - - //Enable Motors - enable = ENABLE; - - //Create Threads - osThreadCreate(osThread(led2_thread), NULL); + //Create IMU Thread + osThreadCreate(osThread(imu_update_thread), NULL); while(1) { + + //Get the time stamp as soon as it enters the loop + timer_value = timer.read_us(); //led1 = led1^1; led4 = !fallen; led2 = button; @@ -281,6 +329,7 @@ else led3 = 0; + //Button Press on the remote initilizes the robot position. if(button) { pos_M1 = 0; pos_M2 = 0; @@ -288,144 +337,141 @@ fallen = false; } - // while(!mpuInterrupt) { - timer_value = timer.read_us(); + + //Preset Knob Values for Green Balance Bot + knob1 = 42.157; + knob2 = 41.135; + knob3 = 8.82; + knob4 = 20.68; - //Preset Knob Values for Green Balance Bot - knob1 = 42.157; - knob2 = 41.135; - knob3 = 8.82; - knob4 = 20.68; - - //Set Gainz with knobs - Kp1 = ((float)knob1) / 1000.0; - Kd1 = ((float)knob2) / 1.0; - Kp2 = ((float)knob3) / 1000.0; - Kd2 = ((float)knob4) / 100.0; + //Set Gainz with knobs + Kp1 = ((float)knob1) / 1000.0; + Kd1 = ((float)knob2) / 1.0; + Kp2 = ((float)knob3) / 1000.0; + Kd2 = ((float)knob4) / 100.0; + + //Joystick control + throttle = (float)jstick_v /10.0; + steering = (float)jstick_h / 10.0; - //Joystick control - throttle = (float)jstick_v /10.0; - steering = (float)jstick_h / 10.0; + //Increment the loop counters + loop_counter++; + slow_loop_counter++; + medium_loop_counter++; - //Update Values - loop_counter++; - slow_loop_counter++; - medium_loop_counter++; - dt = (timer_value - timer_old); - timer_old = timer_value; - angle_old = angle; + //Calculate the delta time + dt = (timer_value - timer_old); + timer_old = timer_value; + angle_old = angle; - // STANDING: Motor Control Enabled - if(((angle < 45) && (angle > -45)) && (fallen == false)) { + // STANDING: Motor Control Enabled + //******************** PID Control BEGIN ********************** // + if(((angle < 45) && (angle > -45)) && (fallen == false)) { + gpioMonitorB = 1; - //CS Pd Target Angle Contoller Goes Here + //CS Pd Target Angle Contoller Goes Here - //Robot Position - robot_pos = (pos_M1 + pos_M2) / 2; - target_pos += throttle/2; + //Robot Position + robot_pos = (pos_M1 + pos_M2) / 2; + target_pos += throttle/2; - //Robot Current Velocity - velocity = motor1 + motor2 / 2; + //Robot Current Velocity + velocity = motor1 + motor2 / 2; - //CS ***************** Velocity Controller ********************* - //float target_velocity = 0; - //velocity_error = target_velocity - velocity; - //target_angle = -velocity_error * Kp2 * 100; - //CS ***************** Position Controller ********************* - pos_error = robot_pos - target_pos; //robot_pos - target_pos; + //CS ***************** Velocity Controller ********************* + //float target_velocity = 0; + //velocity_error = target_velocity - velocity; + //target_angle = -velocity_error * Kp2 * 100; + //CS ***************** Position Controller ********************* + pos_error = robot_pos - target_pos; //robot_pos - target_pos; - //KP Term - kp_pos_term = -Kp2 * pos_error; + //KP Term + kp_pos_term = -Kp2 * pos_error; - //KD Term - change_in_target_pos = target_pos - target_pos_old; - change_in_pos = robot_pos - robot_pos_old2; - //kd_pos_term = ((-Kd2 * change_in_target_pos) + (-Kd2*change_in_pos)) /dt; - kd_pos_term = ((Kd2 * change_in_target_pos) + (Kd2*velocity)); - target_angle = kp_pos_term + kd_pos_term; - target_angle = CAP(target_angle, MAX_TARGET_ANGLE); + //KD Term + change_in_target_pos = target_pos - target_pos_old; + change_in_pos = robot_pos - robot_pos_old2; + //kd_pos_term = ((-Kd2 * change_in_target_pos) + (-Kd2*change_in_pos)) /dt; + kd_pos_term = ((Kd2 * change_in_target_pos) + (Kd2*velocity)); + target_angle = kp_pos_term + kd_pos_term; + target_angle = CAP(target_angle, MAX_TARGET_ANGLE); - //Update values - target_pos_old = target_pos; - robot_pos_old2 = robot_pos_old1; - robot_pos_old1 = robot_pos; + //Update values + target_pos_old = target_pos; + robot_pos_old2 = robot_pos_old1; + robot_pos_old1 = robot_pos; - //CS ************ PD Stability CONTROLLER HERE **************** - error = target_angle - angle; - kp_term = Kp1 * error; + //CS ************ PD Stability CONTROLLER HERE **************** + error = target_angle - angle; + kp_term = Kp1 * error; - change_in_target_angle = target_angle - target_angle_old; //add - change_in_angle = angle - angle_old2; //add - kd_term = ((Kd1 * change_in_target_angle) - Kd1*(change_in_angle)) / dt; - //kd_term = ((Kd1 * change_in_target_angle) - (Kd1*velocity)); + change_in_target_angle = target_angle - target_angle_old; //add + change_in_angle = angle - angle_old2; //add + kd_term = ((Kd1 * change_in_target_angle) - (Kd1*change_in_angle)) / dt; + //kd_term = ((Kd1 * change_in_target_angle) - (Kd1*velocity)); - //pc.printf("dAngle:%f\r\n", angle-angle_old1); + //pc.printf("dAngle:%f\r\n", angle-angle_old1); - //Control Output - control_output += kp_term + kd_term; - control_output = CAP(control_output, MAX_CONTROL_OUTPUT); // Limit max output from control - motor1 = (int16_t)(control_output + (steering)); - motor2 = (int16_t)(control_output - (steering)); - motor1 = CAP(motor1, MAX_CONTROL_OUTPUT); - motor2 = CAP(motor2, MAX_CONTROL_OUTPUT); + //Control Output + control_output += kp_term + kd_term; + control_output = CAP(control_output, MAX_CONTROL_OUTPUT); // Limit max output from control + motor1 = (int16_t)(control_output + (steering)); + motor2 = (int16_t)(control_output - (steering)); + motor1 = CAP(motor1, MAX_CONTROL_OUTPUT); + motor2 = CAP(motor2, MAX_CONTROL_OUTPUT); - //Update variables - target_angle_old = target_angle; - angle_old2 = angle_old1; - angle_old1 = angle; + //Update variables + target_angle_old = target_angle; + angle_old2 = angle_old1; + angle_old1 = angle; - //Enable Motors - enable = ENABLE; - setMotor1Speed(-motor1); - setMotor2Speed(-motor2); - robot_pos += (-motor1 + -motor2) / 2; - //pc.printf("m1: %d m2: %d angle: %0.1f, controlout: %f tAngle: %f dt: %f timer: %d \r\n", motor1, motor2, angle, control_output, target_angle, dt, timer_value); - } else { //[FALLEN} - //Disable Motors - enable = DISABLE; - - //Set fallen flag - fallen = true; - } + //Enable Motors + enable = ENABLE; + setMotor1Speed(-motor1); + setMotor2Speed(-motor2); + robot_pos += (-motor1 + -motor2) / 2; + gpioMonitorB = 0; + //pc.printf("m1: %d m2: %d angle: %0.1f, controlout: %f tAngle: %f dt: %f timer: %d \r\n", motor1, motor2, angle, control_output, target_angle, dt, timer_value); + } else { //[FALLEN} + //Disable Motors + enable = DISABLE; - //Fast Loop - if(loop_counter >= 5) { - loop_counter = 0; - pc.printf("angle:%d Kp1: %0.3f Kd1: %0.2f Kp2: %0.2f Kd2: %0.3f tang: %0.2f dt:%d rob_pos: %d VE: %f\r\n", (int)angle, Kp1, Kd1, Kp2, Ki2, target_angle, dt, robot_pos, velocity_error); - //pc.printf("Jstick_h: %d Jstick_v: %d Knob1 %d Knob2 %d Knob3 %d Knob4 %d Button: %d\r\n", jstick_h, jstick_v, knob1, knob2, knob3, knob4, button); - } + //Set fallen flag + fallen = true; + } + //******************** PID Control END ********************** // - //Meduim Loop - if (medium_loop_counter >= 10) { - medium_loop_counter = 0; // Read status + //Fast Loop + if(loop_counter >= 5) { + loop_counter = 0; + pc.printf("angle:%d Kp1: %0.3f Kd1: %0.2f Kp2: %0.2f Kd2: %0.3f tang: %0.2f dt:%d rob_pos: %d VE: %f\r\n", (int)angle, Kp1, Kd1, Kp2, Ki2, target_angle, dt, robot_pos, velocity_error); + //pc.printf("Jstick_h: %d Jstick_v: %d Knob1 %d Knob2 %d Knob3 %d Knob4 %d Button: %d\r\n", jstick_h, jstick_v, knob1, knob2, knob3, knob4, button); + } - //Recieve Data - rxLen = rf_receive(rxBuffer, 128); - if(rxLen > 0) { - led1 = led1^1; - //Process data with our protocal - communication_protocal(rxLen); - } + //Meduim Loop + if (medium_loop_counter >= 10) { + medium_loop_counter = 0; // Read status - } // End of medium loop - - //Slow Loop - if(slow_loop_counter >= 99) { - slow_loop_counter = 0; - - /* Send Data To Controller goes here * - * */ + //Recieve Data + rxLen = rf_receive(rxBuffer, 128); + if(rxLen > 0) { + led1 = led1^1; + //Process data with our protocal + communication_protocal(rxLen); + } + } // End of medium loop - } //End of Slow Loop - - //Reattach interupt - //checkpin.rise(&dmpDataReady); - // } //END WHILE + //Slow Loop + if(slow_loop_counter >= 99) { + slow_loop_counter = 0; - - /********************* All IMU Handling DO NOT MODIFY *****************/ + /* Send Data To Controller goes here * + * */ + } //End of Slow Loop - /********************* All IMU Handling DO NOT MODIFY *****************/ - + //Reattach interupt + //checkpin.rise(&dmpDataReady); + + gpioMonitorB = 0; } //end main loop } //End Main() \ No newline at end of file