James Bartholomew / Mbed 2 deprecated mbed_IMU_Servo_matlab

Dependencies:   mbed Servo LSM9DS1 mbed-rtos Clock3 PidCombine

Committer:
JamB
Date:
Mon Apr 15 14:50:49 2019 +0000
Revision:
1:57378b3160b9
Parent:
0:4cf11edf30cf
hello

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JamB 0:4cf11edf30cf 1 #include "mbed.h"
JamB 1:57378b3160b9 2 #include "rtos.h" //for threads
JamB 0:4cf11edf30cf 3 #include "LSM9DS1.h"
JamB 0:4cf11edf30cf 4 #include "Servo.h"
JamB 0:4cf11edf30cf 5 #include "clock.h"
JamB 0:4cf11edf30cf 6
JamB 0:4cf11edf30cf 7 #define PI 3.14159
JamB 0:4cf11edf30cf 8 #define DECLINATION -2.44
JamB 0:4cf11edf30cf 9 #define deltat_ 0.004f //250Hz
JamB 1:57378b3160b9 10 #define deltat_disp 0.164f //~6Hz
JamB 0:4cf11edf30cf 11
JamB 0:4cf11edf30cf 12 //Setup Patameters
JamB 1:57378b3160b9 13 Servo servo_1(p25); //left servo
JamB 1:57378b3160b9 14 Servo servo_2(p24); //right servo
JamB 0:4cf11edf30cf 15 DigitalOut myled(LED1);
JamB 0:4cf11edf30cf 16 Serial pc(USBTX, USBRX);
JamB 0:4cf11edf30cf 17
JamB 0:4cf11edf30cf 18 AnalogIn ain(A0);
JamB 0:4cf11edf30cf 19 AnalogIn ain1(A1);
JamB 1:57378b3160b9 20 LSM9DS1 IMU(p9, p10, 0xD6, 0x3C);//SDA, SDL
JamB 1:57378b3160b9 21 //ports for switching circuit
JamB 1:57378b3160b9 22 Thread thread;
JamB 1:57378b3160b9 23
JamB 1:57378b3160b9 24 float roll;
JamB 1:57378b3160b9 25 float pitch;
JamB 1:57378b3160b9 26 float yaw;
JamB 1:57378b3160b9 27 float left_servo;
JamB 1:57378b3160b9 28 float right_servo;
JamB 1:57378b3160b9 29 //int i;
JamB 1:57378b3160b9 30
JamB 1:57378b3160b9 31
JamB 0:4cf11edf30cf 32
JamB 0:4cf11edf30cf 33 void Setup()
JamB 0:4cf11edf30cf 34 {
JamB 1:57378b3160b9 35 set_tick_(deltat_);
JamB 1:57378b3160b9 36 set_tick_disp(deltat_disp);
JamB 0:4cf11edf30cf 37 }
JamB 0:4cf11edf30cf 38
JamB 0:4cf11edf30cf 39 int main()
JamB 0:4cf11edf30cf 40 {
JamB 0:4cf11edf30cf 41 Setup();
JamB 0:4cf11edf30cf 42 //Display Setup
JamB 0:4cf11edf30cf 43 Timer timer;
JamB 0:4cf11edf30cf 44 Timer timer2;
JamB 1:57378b3160b9 45
JamB 0:4cf11edf30cf 46 // int timee =0;
JamB 0:4cf11edf30cf 47 int i=50;
JamB 0:4cf11edf30cf 48 int j =0;
JamB 0:4cf11edf30cf 49 // int begin, end;
JamB 0:4cf11edf30cf 50 // PID config Roll
JamB 0:4cf11edf30cf 51 float error=0.0;
JamB 0:4cf11edf30cf 52 float P =0.0; //Proportional term
JamB 0:4cf11edf30cf 53 float I =0.0; //Intergral term
JamB 0:4cf11edf30cf 54 float prevD =0.0;
JamB 0:4cf11edf30cf 55 //float prevDy=0.0l;
JamB 0:4cf11edf30cf 56 float D =0.0; //Derivative term
JamB 0:4cf11edf30cf 57 float k1 = -0.9776; //Proportaional PID weight
JamB 0:4cf11edf30cf 58 float k2 = -0.5656; //Integral PID
JamB 0:4cf11edf30cf 59 float k3 = -4.2247; //Derivative PID
JamB 0:4cf11edf30cf 60 float PV=0.0; //Process variable
JamB 0:4cf11edf30cf 61 float SP=0; //Set Point (Desired Roll in degerees)
JamB 0:4cf11edf30cf 62 // PID config Pitch
JamB 0:4cf11edf30cf 63 float errorp =0.0; //Proportional term
JamB 0:4cf11edf30cf 64 float Pp =0.0; //Proportional term
JamB 0:4cf11edf30cf 65 float Ip =0.0; //Intergral term
JamB 0:4cf11edf30cf 66 float prevDp =0.0;
JamB 0:4cf11edf30cf 67 float Dp =0.0; //Derivative term
JamB 0:4cf11edf30cf 68 float k1p = -1; //PID weights
JamB 0:4cf11edf30cf 69 float k2p = 0.5;
JamB 0:4cf11edf30cf 70 float k3p = 10;
JamB 0:4cf11edf30cf 71 float PVp=0.0; //Process variable
JamB 0:4cf11edf30cf 72 float SPp=0; //Set Point
JamB 0:4cf11edf30cf 73 //PID combine setup
JamB 0:4cf11edf30cf 74 float rollc;
JamB 0:4cf11edf30cf 75 float pitchc;
JamB 0:4cf11edf30cf 76 float top;
JamB 0:4cf11edf30cf 77 float bot;
JamB 0:4cf11edf30cf 78 float centre;
JamB 0:4cf11edf30cf 79 float diff;
JamB 0:4cf11edf30cf 80 //Servo initial conditions
JamB 0:4cf11edf30cf 81 float range = 0.0005;
JamB 0:4cf11edf30cf 82 float roll_correct = 0;
JamB 0:4cf11edf30cf 83 float pitch_correct= 0; //Range 0-1
JamB 0:4cf11edf30cf 84 servo_1.calibrate(range, 45.0);
JamB 0:4cf11edf30cf 85 servo_2.calibrate(range, 45.0);
JamB 0:4cf11edf30cf 86 //PWM conversion
JamB 0:4cf11edf30cf 87 float left_scale = 0.01778; //convert degrees to PWM. Assumes linear realtionship (is not). optimised for linearity around neutral.
JamB 0:4cf11edf30cf 88 float right_scale = -0.01778;
JamB 0:4cf11edf30cf 89 float left_neutral = 0.39; //neutral position PWM
JamB 0:4cf11edf30cf 90 float right_neutral = 0.61;
JamB 0:4cf11edf30cf 91 //IMU
JamB 0:4cf11edf30cf 92 LSM9DS1 IMU(p9, p10, 0xD6, 0x3C);//SDA, SDL
JamB 0:4cf11edf30cf 93 IMU.begin();
JamB 0:4cf11edf30cf 94 if (!IMU.begin()) {
JamB 0:4cf11edf30cf 95 pc.printf("Failed to communicate with LSM9DS1.\n");
JamB 0:4cf11edf30cf 96 }
JamB 0:4cf11edf30cf 97 IMU.calibrate(0); //If this is set to 1 the Glider will assume it starts level
JamB 1:57378b3160b9 98 double mx;
JamB 0:4cf11edf30cf 99 printf("Start");
JamB 1:57378b3160b9 100 void display_thread();
JamB 1:57378b3160b9 101 thread.start(display_thread);
JamB 0:4cf11edf30cf 102 while(1)
JamB 0:4cf11edf30cf 103 {
JamB 0:4cf11edf30cf 104 if(tock())
JamB 0:4cf11edf30cf 105 {
JamB 1:57378b3160b9 106 myled=!myled;
JamB 0:4cf11edf30cf 107 //Attitude
JamB 0:4cf11edf30cf 108 while(!IMU.accelAvailable());
JamB 0:4cf11edf30cf 109 IMU.readAccel();
JamB 1:57378b3160b9 110 roll = atan2((double)IMU.ax, (double)IMU.az); //swtiched the roll and pitch eqautions round
JamB 1:57378b3160b9 111 pitch = atan2(-(double)IMU.ay, sqrt((double)IMU.ax * (double)IMU.ax + (double)IMU.az * (double)IMU.az));
JamB 0:4cf11edf30cf 112 pitch *= 180.0 / PI;
JamB 0:4cf11edf30cf 113 roll *= 180.0 / PI;
JamB 1:57378b3160b9 114
JamB 1:57378b3160b9 115
JamB 1:57378b3160b9 116 mx = -IMU.mx;
JamB 1:57378b3160b9 117 float heading;
JamB 1:57378b3160b9 118 if (IMU.my == 0.0)
JamB 1:57378b3160b9 119 heading = (mx < 0.0) ? 180.0 : 0.0;
JamB 1:57378b3160b9 120 else
JamB 1:57378b3160b9 121 heading = atan2(mx, IMU.my)*360.0/(2.0*PI);
JamB 1:57378b3160b9 122
JamB 0:4cf11edf30cf 123
JamB 0:4cf11edf30cf 124 //If moving up or down adjust the SPp for pitch. Tether should deal with this
JamB 0:4cf11edf30cf 125 //shift_SPp=IMU.az;//scale with time and shift by 9.81.
JamB 0:4cf11edf30cf 126 //SPp+=shift_SPp ; Adjusting the setpoint would require new PID values.
JamB 0:4cf11edf30cf 127
JamB 0:4cf11edf30cf 128 //PID for Roll
JamB 0:4cf11edf30cf 129 PV =roll;
JamB 0:4cf11edf30cf 130 error= PV-SP; //in degrees
JamB 0:4cf11edf30cf 131 P = k1*error;
JamB 0:4cf11edf30cf 132 I += k2*error;
JamB 0:4cf11edf30cf 133 D = k3*error - prevD; //change in glider's roll in degrees since last sample
JamB 0:4cf11edf30cf 134 //float N=5.3;
JamB 0:4cf11edf30cf 135 //D = (k3*error -prevD)*N -(N-1)*prevDy;
JamB 0:4cf11edf30cf 136 prevD =k3*error;
JamB 0:4cf11edf30cf 137 //prevDy = D;
JamB 0:4cf11edf30cf 138 roll_correct = P + I + D ; //Try PID
JamB 0:4cf11edf30cf 139 //Clamp if PID has saturated integral.
JamB 0:4cf11edf30cf 140 if(roll_correct<-18 || roll_correct>48) { //Is the PID saturated?
JamB 0:4cf11edf30cf 141 if(!((k2*error>0)^(roll_correct>0))) //Is the new intergral contributing to saturation?
JamB 0:4cf11edf30cf 142 {
JamB 0:4cf11edf30cf 143 I -=k2*error; //Don let accError increase, its saturated
JamB 0:4cf11edf30cf 144 roll_correct = P + I + D ; //Update PID
JamB 0:4cf11edf30cf 145 }
JamB 0:4cf11edf30cf 146 }
JamB 0:4cf11edf30cf 147
JamB 0:4cf11edf30cf 148 //PID for pitch
JamB 0:4cf11edf30cf 149 PVp =pitch;
JamB 0:4cf11edf30cf 150 errorp= PVp-SPp; //in degrees
JamB 0:4cf11edf30cf 151 Pp = k1p*errorp;
JamB 0:4cf11edf30cf 152 Ip += k2p*errorp;
JamB 0:4cf11edf30cf 153 Dp = k3p*errorp - prevDp; //change in glider's roll in degrees since last sample
JamB 0:4cf11edf30cf 154 prevDp =k3p*errorp;
JamB 0:4cf11edf30cf 155 pitch_correct = Pp + Ip + Dp ; //Try PID
JamB 0:4cf11edf30cf 156 //Clamp if PID has saturated integral.
JamB 0:4cf11edf30cf 157 if(pitch_correct<-18 || pitch_correct>48) { //Is the PID saturated?
JamB 0:4cf11edf30cf 158 if(!((k2p*errorp>0)^(pitch_correct>0))) //Is the new intergral contributing to saturation?
JamB 0:4cf11edf30cf 159 {
JamB 0:4cf11edf30cf 160 Ip -=k2p*errorp; //Don let accError increase, its saturated
JamB 0:4cf11edf30cf 161 pitch_correct = Pp + Ip + Dp ; //Update PID
JamB 0:4cf11edf30cf 162 }
JamB 0:4cf11edf30cf 163 }
JamB 0:4cf11edf30cf 164
JamB 0:4cf11edf30cf 165 //Update Servos, left and right
JamB 0:4cf11edf30cf 166 //left_servo = pitch_correct + roll_correct; //Angle deg from -18 to (18)
JamB 0:4cf11edf30cf 167 //right_servo = pitch_correct +(1 - roll_correct); //Angle deg from -18 to (18)
JamB 0:4cf11edf30cf 168
JamB 0:4cf11edf30cf 169 //Take in the corrects and combine them for Left and Right elevator
JamB 0:4cf11edf30cf 170 rollc = (roll_correct/2);
JamB 0:4cf11edf30cf 171 pitchc = (-pitch_correct-15);
JamB 0:4cf11edf30cf 172 top = rollc+15;
JamB 0:4cf11edf30cf 173 bot = 15-rollc;
JamB 0:4cf11edf30cf 174 centre = 15;
JamB 0:4cf11edf30cf 175
JamB 0:4cf11edf30cf 176 while (pitchc != 0)
JamB 0:4cf11edf30cf 177 {
JamB 0:4cf11edf30cf 178 if (pitchc > 0)
JamB 0:4cf11edf30cf 179 {
JamB 0:4cf11edf30cf 180 if (top<48)
JamB 0:4cf11edf30cf 181 {
JamB 0:4cf11edf30cf 182 centre = centre+1;
JamB 0:4cf11edf30cf 183 pitchc = pitchc-1;
JamB 0:4cf11edf30cf 184 top=top+1;
JamB 0:4cf11edf30cf 185 }else{
JamB 0:4cf11edf30cf 186 pitchc=0;
JamB 0:4cf11edf30cf 187 }
JamB 0:4cf11edf30cf 188 }else{
JamB 0:4cf11edf30cf 189 if (bot>-18)
JamB 0:4cf11edf30cf 190 {
JamB 0:4cf11edf30cf 191 centre=centre-1;
JamB 0:4cf11edf30cf 192 pitchc=pitchc+1;
JamB 0:4cf11edf30cf 193 bot=bot-1;
JamB 0:4cf11edf30cf 194 }else{
JamB 0:4cf11edf30cf 195 pitchc=0;
JamB 0:4cf11edf30cf 196 }
JamB 0:4cf11edf30cf 197 }
JamB 0:4cf11edf30cf 198 }
JamB 0:4cf11edf30cf 199
JamB 0:4cf11edf30cf 200 diff=rollc*2;
JamB 0:4cf11edf30cf 201 centre=centre;
JamB 0:4cf11edf30cf 202
JamB 0:4cf11edf30cf 203 //Convert to PWM
JamB 0:4cf11edf30cf 204 left_servo = left_neutral + (centre + diff) * left_scale;
JamB 0:4cf11edf30cf 205 right_servo = right_neutral + (centre - diff) * right_scale;
JamB 0:4cf11edf30cf 206
JamB 0:4cf11edf30cf 207 //Saturate outputs(For Safety) -18 to 48deg
JamB 0:4cf11edf30cf 208 if(left_servo>0.94){left_servo=0.94;}//0.54
JamB 0:4cf11edf30cf 209 if(left_servo<0.07){left_servo=0.07;}
JamB 0:4cf11edf30cf 210 if(right_servo>0.93){right_servo=0.93;}
JamB 0:4cf11edf30cf 211 if(right_servo<0.06){right_servo=0.06;}//0.41
JamB 0:4cf11edf30cf 212
JamB 0:4cf11edf30cf 213 //Output to Servos
JamB 0:4cf11edf30cf 214 servo_1 = left_servo; //0.07 - 0.59
JamB 0:4cf11edf30cf 215 servo_2 = right_servo;//0.93 - 0.41
JamB 0:4cf11edf30cf 216
JamB 0:4cf11edf30cf 217 //timer.reset();
JamB 0:4cf11edf30cf 218 //timer.start();
JamB 0:4cf11edf30cf 219 // begin = timer.read_us();
JamB 0:4cf11edf30cf 220 //Display
JamB 1:57378b3160b9 221 /*
JamB 0:4cf11edf30cf 222 if (i>0) //5 every second at 250Hz =5Hz (50)
JamB 0:4cf11edf30cf 223 {
JamB 1:57378b3160b9 224
JamB 0:4cf11edf30cf 225 i=0;
JamB 0:4cf11edf30cf 226 }
JamB 1:57378b3160b9 227 */
JamB 0:4cf11edf30cf 228 i++;
JamB 0:4cf11edf30cf 229 j++;
JamB 0:4cf11edf30cf 230 //end = timer.read_us();
JamB 0:4cf11edf30cf 231 //timee=end-begin;
JamB 0:4cf11edf30cf 232
JamB 0:4cf11edf30cf 233 }
JamB 0:4cf11edf30cf 234 }
JamB 0:4cf11edf30cf 235 }
JamB 1:57378b3160b9 236
JamB 1:57378b3160b9 237
JamB 1:57378b3160b9 238
JamB 1:57378b3160b9 239 void display_thread(){
JamB 1:57378b3160b9 240
JamB 1:57378b3160b9 241 while(1){
JamB 1:57378b3160b9 242 if (tockdisp()){
JamB 1:57378b3160b9 243 //pc.printf("(Roll %f) (Pitch %f) \r",roll,pitch);
JamB 1:57378b3160b9 244 //pc.printf("%f %f \r",roll,pitch);
JamB 1:57378b3160b9 245 pc.printf("%f,%f,%f,%f,%f\n", roll, pitch, yaw, (float)ain.read(), (float)ain1.read()) ;
JamB 1:57378b3160b9 246 //pc.printf("%d %d %d %f %f %f %f %f %f %d\n",IMU.ax,IMU.ay,IMU.az,roll, pitch,left_servo, right_servo, (float)ain.read(), (float)ain1.read()),i;
JamB 1:57378b3160b9 247 //pc.printf("%f %f %f\r",P,I,D);
JamB 1:57378b3160b9 248 //pc.printf("%f %f %f %f %f %f\r",P,I,D,Pp,Ip,Dp);
JamB 1:57378b3160b9 249 }
JamB 1:57378b3160b9 250 //Thread::wait(164);
JamB 1:57378b3160b9 251 }
JamB 1:57378b3160b9 252 }
JamB 1:57378b3160b9 253