first commit

Dependencies:   mbed MMA8451Q

Committer:
aalawfi
Date:
Sat Nov 06 16:31:02 2021 +0000
Revision:
25:8bd029d58251
Parent:
24:7bf492bf50f4
Child:
26:54ce9f642477
-

Who changed what in which revision?

UserRevisionLine numberNew contents of line
aalawfi 2:c857935f928e 1 //#include "steering_header.h"
aalawfi 2:c857935f928e 2 /*
aalawfi 2:c857935f928e 3 Include methods and functions
aalawfi 2:c857935f928e 4 */
aalawfi 2:c857935f928e 5
aalawfi 2:c857935f928e 6 // --------- LANDMARK COUNTER --------
aalawfi 2:c857935f928e 7 static int decimal_to_bin[16][BITS] = {
aalawfi 2:c857935f928e 8 {0,0,0,0}, // zero
aalawfi 2:c857935f928e 9 {0,0,0,1}, // one
aalawfi 2:c857935f928e 10 {0,0,1,0}, //two
aalawfi 2:c857935f928e 11 {0,0,1,1}, //three
aalawfi 2:c857935f928e 12 {0,1,0,0}, // four
aalawfi 2:c857935f928e 13 {0,1,0,1}, //five
aalawfi 2:c857935f928e 14 {0,1,1,0}, // six
aalawfi 2:c857935f928e 15 {0,1,1,1}, //seven
aalawfi 2:c857935f928e 16 {1,0,0,0}, //eight
aalawfi 2:c857935f928e 17 {1,0,0,1}, //nine
aalawfi 2:c857935f928e 18 {1,0,1,0}, //ten
aalawfi 2:c857935f928e 19 {1,0,1,1}, //11
aalawfi 2:c857935f928e 20 {1,1,0,0}, //12
aalawfi 2:c857935f928e 21 {1,1,0,1}, //13
aalawfi 2:c857935f928e 22 {1,1,1,0}, //14
aalawfi 2:c857935f928e 23 {1,1,1,1}, //15
aalawfi 2:c857935f928e 24 } ;
aalawfi 2:c857935f928e 25 void turn_seg_off(DigitalOut segment[]){
aalawfi 2:c857935f928e 26 for(int i =0; i<BITS; i++){
aalawfi 2:c857935f928e 27 segment[i] = 0;
aalawfi 2:c857935f928e 28 }
aalawfi 2:c857935f928e 29 }
aalawfi 2:c857935f928e 30 void show_decimal(int number, DigitalOut segment[]) {
aalawfi 2:c857935f928e 31 turn_seg_off(segment);
aalawfi 2:c857935f928e 32 for(int i =0; i < BITS; i++){
aalawfi 2:c857935f928e 33 segment[i] = decimal_to_bin[number][i];
aalawfi 2:c857935f928e 34 };
aalawfi 2:c857935f928e 35 }
aalawfi 2:c857935f928e 36 // ------------ LANDMARK DETECTION ------------
aalawfi 23:4c743746533c 37 Timer land;
aalawfi 25:8bd029d58251 38
quarren42 19:65fecaa2a387 39 volatile bool landmark_triggered=false; // Debugging purposes only
quarren42 19:65fecaa2a387 40 volatile bool restarted = false; // Debugging purposes only
aalawfi 23:4c743746533c 41
aalawfi 2:c857935f928e 42 void landmark_counter(void){
aalawfi 23:4c743746533c 43 land.start();
quarren42 19:65fecaa2a387 44 landmark_triggered=false; // Debugging purposes only
quarren42 19:65fecaa2a387 45 restarted = false; // Debugging purposes only
aalawfi 2:c857935f928e 46 if(counter >= 15)
aalawfi 2:c857935f928e 47 counter =0;
aalawfi 2:c857935f928e 48 turn_seg_off(seg1);
aalawfi 25:8bd029d58251 49 if((right_landmark_sensor.read() == 1 || left_landmark_sensor.read() == 1) && land.read_us() > 10 )
aalawfi 25:8bd029d58251 50 {
aalawfi 23:4c743746533c 51 landmark_triggered =true; // Debugging purpose only
aalawfi 25:8bd029d58251 52 (counter > 6 ? counter = 7 : counter++);
aalawfi 23:4c743746533c 53 land.stop();
aalawfi 23:4c743746533c 54 }
aalawfi 23:4c743746533c 55
aalawfi 23:4c743746533c 56 // }
aalawfi 25:8bd029d58251 57 if(right_landmark_sensor.read() == 1 && left_landmark_sensor.read() == 1&& land.read_us() > 4)
quarren42 19:65fecaa2a387 58 {
aalawfi 25:8bd029d58251 59 lap++;
aalawfi 23:4c743746533c 60 counter = 0;
aalawfi 23:4c743746533c 61 restarted=true;
aalawfi 25:8bd029d58251 62 // Debugging purposes only
quarren42 19:65fecaa2a387 63 }
aalawfi 23:4c743746533c 64 land.stop();
aalawfi 2:c857935f928e 65 show_decimal(counter, seg1);
aalawfi 2:c857935f928e 66 }
aalawfi 2:c857935f928e 67
aalawfi 2:c857935f928e 68
aalawfi 2:c857935f928e 69 float rad2dc (float angle){
aalawfi 2:c857935f928e 70 angle = std::max(MIN_TURN_ANGLE, std::min(angle, MAX_TURN_ANGLE));
aalawfi 2:c857935f928e 71 float x = (angle - MIN_TURN_ANGLE)/(MAX_TURN_ANGLE - MIN_TURN_ANGLE);
aalawfi 2:c857935f928e 72 float dutyCycle = 0.05*x+0.05;
aalawfi 2:c857935f928e 73 return dutyCycle;
aalawfi 2:c857935f928e 74 }
aalawfi 2:c857935f928e 75
aalawfi 2:c857935f928e 76 float current_duty_cycle=0.075;
aalawfi 2:c857935f928e 77 // -------------- PD CONTROLLER --------------
aalawfi 2:c857935f928e 78 // Global declearation
aalawfi 2:c857935f928e 79 float err_prev = 0;
quarren42 6:d2bd68ba99c9 80 float prev_duty = 0;
aalawfi 22:08d30ea47111 81 float errorArea;
aalawfi 22:08d30ea47111 82 float errorAreaPrev =0.0;
aalawfi 25:8bd029d58251 83 float feedback;
aalawfi 25:8bd029d58251 84 float err;
aalawfi 25:8bd029d58251 85 float left_sens; float right_sens;
aalawfi 25:8bd029d58251 86 volatile bool clamp;
aalawfi 2:c857935f928e 87 void steering_control(void)
aalawfi 2:c857935f928e 88 {
aalawfi 2:c857935f928e 89
aalawfi 25:8bd029d58251 90
aalawfi 2:c857935f928e 91 if(steering_enabled == true ){
aalawfi 2:c857935f928e 92 //Read each sensor and calculate the sensor difference
quarren42 19:65fecaa2a387 93 float sensor_difference = left_distance_sensor.read() -
aalawfi 22:08d30ea47111 94 right_distance_sensor.read();
aalawfi 25:8bd029d58251 95 left_sens = left_distance_sensor.read();
aalawfi 25:8bd029d58251 96 right_sens = right_distance_sensor.read()*1.065;
aalawfi 2:c857935f928e 97 //calculate the feedback term for the controller. distance (meters) from
aalawfi 2:c857935f928e 98 //track to sensor
aalawfi 25:8bd029d58251 99 feedback = (sensor_difference/SEN_DIFF_TO_DIST); //
aalawfi 25:8bd029d58251 100 if(abs(feedback) < 0.035 && counter ==0)
aalawfi 25:8bd029d58251 101 {
aalawfi 25:8bd029d58251 102 KP = 1.3;
aalawfi 25:8bd029d58251 103 KD = 0.0856;
aalawfi 25:8bd029d58251 104 }
aalawfi 25:8bd029d58251 105 else if (abs(feedback) > 0.035 && counter ==0)
aalawfi 25:8bd029d58251 106 {
aalawfi 25:8bd029d58251 107 KP = 2;
aalawfi 25:8bd029d58251 108
aalawfi 25:8bd029d58251 109 }
aalawfi 25:8bd029d58251 110 else if (counter == 0 && lap ==2 )
aalawfi 25:8bd029d58251 111 {
aalawfi 25:8bd029d58251 112 KP=3.3;
aalawfi 25:8bd029d58251 113 KD=0.35;
aalawfi 25:8bd029d58251 114 }
aalawfi 25:8bd029d58251 115 else
aalawfi 25:8bd029d58251 116 {
aalawfi 25:8bd029d58251 117 KP = 5.5;
aalawfi 25:8bd029d58251 118 KD = 0.6;
aalawfi 25:8bd029d58251 119 }
aalawfi 25:8bd029d58251 120
aalawfi 2:c857935f928e 121 //calculate the error term for the controller. distance (meters) from
aalawfi 2:c857935f928e 122 //desired position to sensor
aalawfi 2:c857935f928e 123 err = REF - feedback; //
aalawfi 22:08d30ea47111 124
aalawfi 22:08d30ea47111 125 //Area of the error: TimeStep*err (width*length of a rectangle)
aalawfi 25:8bd029d58251 126 if(clamp == false)
aalawfi 22:08d30ea47111 127 errorArea= TI_STEERING*err + errorAreaPrev;
aalawfi 25:8bd029d58251 128
aalawfi 2:c857935f928e 129 //Calculate the derivative of the error term for the controller.
aalawfi 2:c857935f928e 130 // e'(t) = (error(t) - error(t-1))/dt
aalawfi 22:08d30ea47111 131 float errChange = (err - err_prev)/(TI_STEERING);
aalawfi 2:c857935f928e 132
aalawfi 2:c857935f928e 133 //Calculate the controller output
aalawfi 2:c857935f928e 134 //Angle in radians
aalawfi 25:8bd029d58251 135 float servo_angle = (0.15+KP*err + KD*errChange*TIME_DERIVATIVE + KI_STEERING*errorArea*TIME_INTEGRAL);
aalawfi 2:c857935f928e 136 //Calculate the duty cycle for the servo motor
aalawfi 2:c857935f928e 137 current_duty_cycle = rad2dc(servo_angle);
aalawfi 24:7bf492bf50f4 138
aalawfi 25:8bd029d58251 139
aalawfi 25:8bd029d58251 140 //--- integral anti-windup ---
aalawfi 25:8bd029d58251 141 if (servo_angle > 0.1 || servo_angle < 0.05){
aalawfi 25:8bd029d58251 142 if (errorArea > 0.0){
aalawfi 25:8bd029d58251 143 clamp = true;
aalawfi 25:8bd029d58251 144 }
aalawfi 25:8bd029d58251 145 } else {
aalawfi 25:8bd029d58251 146 clamp = false;
aalawfi 25:8bd029d58251 147 }
aalawfi 25:8bd029d58251 148
aalawfi 22:08d30ea47111 149 servo_motor_pwm.write(current_duty_cycle);
aalawfi 22:08d30ea47111 150
aalawfi 2:c857935f928e 151 }
aalawfi 9:5320c2dfb913 152 else {
aalawfi 2:c857935f928e 153 current_duty_cycle = rad2dc(M_PI/4);
aalawfi 25:8bd029d58251 154
aalawfi 2:c857935f928e 155 servo_motor_pwm.write(current_duty_cycle);
aalawfi 9:5320c2dfb913 156 };
aalawfi 2:c857935f928e 157 //Save the error for the next calculation.
aalawfi 2:c857935f928e 158 prev_duty = current_duty_cycle;
aalawfi 2:c857935f928e 159 err_prev = err;
aalawfi 22:08d30ea47111 160 errorAreaPrev = errorArea;
aalawfi 2:c857935f928e 161 }
aalawfi 2:c857935f928e 162
aalawfi 2:c857935f928e 163
aalawfi 2:c857935f928e 164