Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed Servo LSM9DS1 mbed-rtos Clock3 PidCombine
Diff: main.cpp
- Revision:
- 0:4cf11edf30cf
- Child:
- 1:57378b3160b9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Thu Apr 11 22:24:36 2019 +0000
@@ -0,0 +1,213 @@
+#include "mbed.h"
+#include "LSM9DS1.h"
+#include "Servo.h"
+#include "clock.h"
+
+#define PI 3.14159
+#define DECLINATION -2.44
+#define deltat_ 0.004f //250Hz
+
+//Setup Patameters
+Servo servo_1(p24); //left servo
+Servo servo_2(p25); //right servo
+DigitalOut myled(LED1);
+Serial pc(USBTX, USBRX);
+
+AnalogIn ain(A0);
+AnalogIn ain1(A1);
+
+void Setup()
+{
+ set_tick_(deltat_);
+}
+
+int main()
+{
+ Setup();
+ //Display Setup
+ Timer timer;
+ Timer timer2;
+ // int timee =0;
+ int i=50;
+ int j =0;
+ // int begin, end;
+ // PID config Roll
+ float error=0.0;
+ float P =0.0; //Proportional term
+ float I =0.0; //Intergral term
+ float prevD =0.0;
+ //float prevDy=0.0l;
+ float D =0.0; //Derivative term
+ float k1 = -0.9776; //Proportaional PID weight
+ float k2 = -0.5656; //Integral PID
+ float k3 = -4.2247; //Derivative PID
+ float PV=0.0; //Process variable
+ float SP=0; //Set Point (Desired Roll in degerees)
+ // PID config Pitch
+ float errorp =0.0; //Proportional term
+ float Pp =0.0; //Proportional term
+ float Ip =0.0; //Intergral term
+ float prevDp =0.0;
+ float Dp =0.0; //Derivative term
+ float k1p = -1; //PID weights
+ float k2p = 0.5;
+ float k3p = 10;
+ float PVp=0.0; //Process variable
+ float SPp=0; //Set Point
+ //PID combine setup
+ float rollc;
+ float pitchc;
+ float top;
+ float bot;
+ float centre;
+ float diff;
+ //Servo initial conditions
+ float range = 0.0005;
+ float roll_correct = 0;
+ float pitch_correct= 0; //Range 0-1
+ float left_servo=0;
+ float right_servo=0;
+ servo_1.calibrate(range, 45.0);
+ servo_2.calibrate(range, 45.0);
+ //PWM conversion
+ float left_scale = 0.01778; //convert degrees to PWM. Assumes linear realtionship (is not). optimised for linearity around neutral.
+ float right_scale = -0.01778;
+ float left_neutral = 0.39; //neutral position PWM
+ float right_neutral = 0.61;
+ //IMU
+ LSM9DS1 IMU(p9, p10, 0xD6, 0x3C);//SDA, SDL
+ IMU.begin();
+ if (!IMU.begin()) {
+ pc.printf("Failed to communicate with LSM9DS1.\n");
+ }
+ IMU.calibrate(0); //If this is set to 1 the Glider will assume it starts level
+
+ printf("Start");
+ while(1)
+ {
+ if(tock())
+ {
+
+ //Attitude
+ while(!IMU.accelAvailable());
+ IMU.readAccel();
+ float roll = atan2((double)IMU.ax, (double)IMU.az); //swtiched the roll and pitch eqautions round
+ float pitch = atan2(-(double)IMU.ay, sqrt((double)IMU.ax * (double)IMU.ax + (double)IMU.az * (double)IMU.az));
+ pitch *= 180.0 / PI;
+ roll *= 180.0 / PI;
+ // printf("%f %f\n", roll, pitch);
+
+ //If moving up or down adjust the SPp for pitch. Tether should deal with this
+ //shift_SPp=IMU.az;//scale with time and shift by 9.81.
+ //SPp+=shift_SPp ; Adjusting the setpoint would require new PID values.
+
+ //PID for Roll
+ PV =roll;
+ error= PV-SP; //in degrees
+ P = k1*error;
+ I += k2*error;
+ D = k3*error - prevD; //change in glider's roll in degrees since last sample
+ //float N=5.3;
+ //D = (k3*error -prevD)*N -(N-1)*prevDy;
+ prevD =k3*error;
+ //prevDy = D;
+ roll_correct = P + I + D ; //Try PID
+ //Clamp if PID has saturated integral.
+ if(roll_correct<-18 || roll_correct>48) { //Is the PID saturated?
+ if(!((k2*error>0)^(roll_correct>0))) //Is the new intergral contributing to saturation?
+ {
+ I -=k2*error; //Don let accError increase, its saturated
+ roll_correct = P + I + D ; //Update PID
+ }
+ }
+
+ //PID for pitch
+ PVp =pitch;
+ errorp= PVp-SPp; //in degrees
+ Pp = k1p*errorp;
+ Ip += k2p*errorp;
+ Dp = k3p*errorp - prevDp; //change in glider's roll in degrees since last sample
+ prevDp =k3p*errorp;
+ pitch_correct = Pp + Ip + Dp ; //Try PID
+ //Clamp if PID has saturated integral.
+ if(pitch_correct<-18 || pitch_correct>48) { //Is the PID saturated?
+ if(!((k2p*errorp>0)^(pitch_correct>0))) //Is the new intergral contributing to saturation?
+ {
+ Ip -=k2p*errorp; //Don let accError increase, its saturated
+ pitch_correct = Pp + Ip + Dp ; //Update PID
+ }
+ }
+
+ //Update Servos, left and right
+ //left_servo = pitch_correct + roll_correct; //Angle deg from -18 to (18)
+ //right_servo = pitch_correct +(1 - roll_correct); //Angle deg from -18 to (18)
+
+ //Take in the corrects and combine them for Left and Right elevator
+ rollc = (roll_correct/2);
+ pitchc = (-pitch_correct-15);
+ top = rollc+15;
+ bot = 15-rollc;
+ centre = 15;
+
+ while (pitchc != 0)
+ {
+ if (pitchc > 0)
+ {
+ if (top<48)
+ {
+ centre = centre+1;
+ pitchc = pitchc-1;
+ top=top+1;
+ }else{
+ pitchc=0;
+ }
+ }else{
+ if (bot>-18)
+ {
+ centre=centre-1;
+ pitchc=pitchc+1;
+ bot=bot-1;
+ }else{
+ pitchc=0;
+ }
+ }
+ }
+
+ diff=rollc*2;
+ centre=centre;
+
+ //Convert to PWM
+ left_servo = left_neutral + (centre + diff) * left_scale;
+ right_servo = right_neutral + (centre - diff) * right_scale;
+
+ //Saturate outputs(For Safety) -18 to 48deg
+ if(left_servo>0.94){left_servo=0.94;}//0.54
+ if(left_servo<0.07){left_servo=0.07;}
+ if(right_servo>0.93){right_servo=0.93;}
+ if(right_servo<0.06){right_servo=0.06;}//0.41
+
+ //Output to Servos
+ servo_1 = left_servo; //0.07 - 0.59
+ servo_2 = right_servo;//0.93 - 0.41
+
+ //timer.reset();
+ //timer.start();
+ // begin = timer.read_us();
+ //Display
+ if (i>0) //5 every second at 250Hz =5Hz (50)
+ {
+ //pc.printf("(Roll %f) (Pitch %f) \r",roll,pitch);
+ //pc.printf("%f %f \r",roll,pitch);
+ pc.printf("%d %d %d %f %f %f %f %f %f %f %f \r",IMU.ax,IMU.ay,IMU.az,roll, pitch,roll_correct,pitch_correct,left_servo, right_servo, (float)ain.read(), (float)ain1.read());
+ //pc.printf("%f %f %f\r",P,I,D);
+ //pc.printf("%f %f %f %f %f %f\r",P,I,D,Pp,Ip,Dp);
+ i=0;
+ }
+ i++;
+ j++;
+ //end = timer.read_us();
+ //timee=end-begin;
+
+ }
+ }
+}