balance

Dependencies:   mbed LSM9DS0

Files at this revision

API Documentation at this revision

Comitter:
omidece2035
Date:
Tue Oct 20 04:32:01 2015 +0000
Commit message:
V1 for ECE 4180 LAB4

Changed in this revision

LSM9DS0.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 9d2ceb7b8ec9 LSM9DS0.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LSM9DS0.lib	Tue Oct 20 04:32:01 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/aswild/code/LSM9DS0/#5556e6fb99f5
diff -r 000000000000 -r 9d2ceb7b8ec9 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Oct 20 04:32:01 2015 +0000
@@ -0,0 +1,192 @@
+#include "mbed.h"                                              
+#include "LSM9DS0.h"                                          
+#include "math.h"                                               
+
+LSM9DS0 imu(p9, p10, 0x6B, 0x1D); 
+Serial pc(USBTX, USBRX);
+Ticker control;  // create Ticker for control algorithm
+Ticker db;
+
+//debugging
+int debug=0;
+int wt = 500;
+DigitalOut led1(LED1);
+
+//motor variables
+PwmOut left_motor_speed(p21); //left motor pwm A
+PwmOut right_motor_speed(p22); //right motor pwm B
+DigitalOut left_fwd_enable(p23); //fwd enable of left/A motor
+DigitalOut left_rev_enable(p24); //rev enable of left/A motor
+DigitalOut right_fwd_enable(p26); //fwd enable or right/B motor
+DigitalOut right_rev_enable(p25); //rev enable of right/B motor
+
+//angle variables
+float accelerometer_angle =0;
+float gyro_data =0;
+float gyro_angle=0;
+float current_angle =0;
+float angle_offset = 0;
+int i=0;
+
+//control variables
+float Error=0; // I had to capitalize this for some reason unlike the other vars
+float kp=.5;
+float ki=.01;
+float kd= 0;
+float setpoint=0; //reference angle
+float angle=0;
+float integral=0;
+float derivative = 0;
+float dt= 0.01; //time period 1/100 (s)
+float previous_error =0;
+float actuator_input =0;
+int ready = 0;
+float maximum_angle=15;
+float SCALAR = 0;
+
+void initialiation (void)
+{
+    //with the "initialization" in the control loop, we may not use this
+    //this is where offsets and sensors are set up
+    //need to hold robot balanced at this point
+    imu.readGyro();
+    angle_offset= float(imu.gy); //maybe take avg. like the other team did in a for loop   
+}
+
+void MotorDriver (float speed)
+{
+// if speed > 0 then move robot left
+// if speed < 0 then move robot right
+    if ( speed>0 )
+    {
+    //move both motors in same direction
+    right_rev_enable = 0;
+    right_fwd_enable = 1;
+    left_fwd_enable = 0;
+    left_rev_enable = 1;
+    right_motor_speed = speed;
+    left_motor_speed = speed;
+    //pc.printf("moving f\n");
+    }
+    else if ( speed <0 )
+    {
+    //move both motors in same direction
+    right_fwd_enable = 0;
+    right_rev_enable = 1;
+    left_rev_enable = 0;
+    left_fwd_enable = 1;
+    right_motor_speed = -speed;
+    left_motor_speed= -speed;
+    //pc.printf("moving r\n");
+    }
+    else 
+    {
+    right_fwd_enable = 0;
+    right_rev_enable = 0;
+    left_rev_enable = 0;
+    left_fwd_enable = 0;
+    right_motor_speed = speed;
+    left_motor_speed = speed;
+    //pc.printf("not moving\n");
+    }
+}
+
+float calcSCALAR(float degrees)
+{
+    //give it a degree such as 10 degrees, anything past that is the same as 10 degrees
+    Error = 0 - degrees; //this is the maximum error
+    integral = integral + (Error*dt); //Forward Euler approximation
+    derivative = (Error - previous_error) / dt; //change wrt time
+    previous_error = Error; 
+    SCALAR = ( (Error*kp) + (integral*ki) + (derivative*kd) );
+    pc.printf("here in scalar calc and error is %f and integral is %f and derivative is %f \n", Error, integral, derivative);
+    Error=0;
+    integral=0;
+    derivative=0;
+    previous_error=0;    
+    return 1;
+}
+
+void controlalgorithm (void)
+{
+    if (i< wt) //gives you time to balance it upon reset; this is like an initialization code for the imu;
+    {
+        //determine current angle using a complementary filter found online http://www.pieter-jan.com/node/11
+        //place +z-axis up, + x-axis right, and +y-axis away from the back of the robot when robot can move left to right 
+        imu.readGyro();
+        gyro_data= imu.gy;
+        imu.readAccel(); 
+        accelerometer_angle = atan2(imu.ax, imu.az) * 180 / 3.14159; //angle in degrees; positive angle is CCW, negative angle is CW; this gives the angle as determined by the accelerometer
+        current_angle = 0.98 * (current_angle + gyro_data * dt) + 0.02 * (accelerometer_angle);
+        i=i+1;      
+    }
+    
+    //if the SCALAR has been calculated and the initilization complete, start controlling
+    if ( ready ==1 )
+    {
+        imu.readGyro();
+        gyro_data= imu.gy; //maybe negative?? I don't think so
+        imu.readAccel(); 
+        accelerometer_angle = atan2(imu.ax, imu.az) * 180 / 3.14159; //angle in degrees; positive angle is CCW, negative angle is CW
+        current_angle = 0.98 * (current_angle + gyro_data * dt) + 0.02 * (accelerometer_angle);    
+            
+        //maybe take into account integral windup
+        Error = setpoint - current_angle; //determine the difference in angle
+        integral = integral + (Error*dt); //Forward Euler approximation
+        derivative = (Error - previous_error) / dt; //change wrt time
+        previous_error = Error; 
+        actuator_input = ( (Error*kp) + (integral*ki) + (derivative*kd) ) / SCALAR; //we should scale this???? and write in terms of a PWM value [-1,1]; be careful, SCALAR is negative
+        MotorDriver(actuator_input);
+    }
+    
+}
+
+void debugout (void)
+{
+    //pc.printf ("setpoint is %f\n", setpoint);
+    pc.printf ("actuator_input is %f\n", actuator_input);
+    //pc.printf("Speed is: %f, angle is: %f\n\n",speed,current_angle);
+}
+
+main()
+{
+    pc.printf("starting...\n");
+    uint16_t status = imu.begin();
+    pc.printf("LSM9DS0 WHO_AM_I's returned: 0x%X\n", status);
+    pc.printf("Should be 0x49D4\n\n");
+    
+    SCALAR= calcSCALAR(maximum_angle); //scale the actuator inputl depends on lp, kd, and ki, and maximum angle allowed
+    control.attach(&controlalgorithm, dt); //check frequency, 100 Hz
+    if (debug==1)
+    {
+        db.attach(&debugout, 0.1);
+    }
+    
+    while(1)
+    {
+        //put some calcs here if needed; need 0.01 seconds at least
+        if (i==wt)
+        {
+           // setpoint=current_angle / 1000; //take first 1000 samples for current angle then avg. it
+            setpoint=current_angle; 
+            ready=1;
+            i=i+1;
+            pc.printf ("i is %d in top if statement\n\n\n\n", i);
+        }
+        
+        //if (debug == 1 && i>20 )
+//        {
+//            //probably need some kind of wait statement; will a wait statement affect the timer interrupt? no, i checked
+//            pc.printf("accel: x: %f y: %f z: %f\n",imu.ax,imu.ay,imu.az);
+//            pc.printf("gyro: x: %f y: %f z: %f\n",imu.gx,imu.gy,imu.gz);
+//            pc.printf ("current_angle is %f\n", current_angle);
+//            pc.printf ("setpoint is %f\n", setpoint);
+//            pc.printf ("accelerometer_angle is %f\n", accelerometer_angle);
+//            pc.printf ("gyro_angle is %f\n", gyro_angle);
+//            pc.printf ("actuator_input is %f\n", actuator_input);
+//            pc.printf ("SCALAR is %f \n", SCALAR);
+//            pc.printf ("i is %d\n\n\n\n", i);
+//            wait(2);
+//        }
+    }
+}
diff -r 000000000000 -r 9d2ceb7b8ec9 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Oct 20 04:32:01 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/34e6b704fe68
\ No newline at end of file