Magnetic Whiteboard Robot Eraser

Dependencies:   Motordriver mbed

Fork of LSM9DS0 by Taylor Andrews

Files at this revision

API Documentation at this revision

Comitter:
alexcrepory
Date:
Fri May 01 04:59:07 2015 +0000
Parent:
5:e6a15dcba942
Commit message:
1.0

Changed in this revision

Motordriver.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
diff -r e6a15dcba942 -r a37a49d2793c Motordriver.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Motordriver.lib	Fri May 01 04:59:07 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/littlexc/code/Motordriver/#3110b9209d3c
diff -r e6a15dcba942 -r a37a49d2793c main.cpp
--- a/main.cpp	Sun Jan 11 14:44:43 2015 +0000
+++ b/main.cpp	Fri May 01 04:59:07 2015 +0000
@@ -1,166 +1,131 @@
-//Most of the Credit goes to jimblom and Judah Okeleye
 #include "LSM9DS0.h"
 #include "mbed.h"
+#include "motordriver.h"
+
+#define pi 3.14159265359
 
 // SDO_XM and SDO_G are both grounded, so our addresses are:
 #define LSM9DS0_XM  0x1D // Would be 0x1E if SDO_XM is LOW
 #define LSM9DS0_G   0x6B // Would be 0x6A if SDO_G is LOW
 
-
+Ticker tmr;
 LSM9DS0 dof(p9, p10,LSM9DS0_G, LSM9DS0_XM);
 Serial pc(USBTX, USBRX); // tx, rx
+Motor left(p21, p22, p23, 1); // pwm, fwd, rev, has brake feature
+Motor right(p26, p25, p24, 1);
+InterruptIn button(p7);
 
-//Uncomment If you want to use interrupts
-/*DigitalIn pinDRDYG(p14);
-DigitalIn pinINTG(p13);
-DigitalIn pinINT1_XM(p14);
-DigitalIn pinINT2_XM(p15);*/
+DigitalOut timer_on(LED1);
+DigitalOut pb(LED2);
+DigitalOut ld3(LED3);
+DigitalOut ld4(LED4);
 
-#define PRINT_CALCULATED
-#define PRINT_SPEED 500 // 500 ms between prints
+#define R 0.06 //distance from the center of the robot to the wheel (radius)
+#define lambda_r 22 // eigenvalue fo the regulator, chosen through tests
+
+float umax=1; //maximum system input (motor speed)
 
-//Init Serial port and LSM9DS0 chip
-void setup()
-{
-    pc.baud(115200); // Start serial at 115200 bps
-    // Use the begin() function to initialize the LSM9DS0 library.
-    // You can either call it with no parameters (the easy way):
-    uint16_t status = dof.begin();
-    
-   
-   //Make sure communication is working
-    pc.printf("LSM9DS0 WHO_AM_I's returned: 0x");
-    pc.printf("%x\n",status);
-    pc.printf("Should be 0x49D4\n");
-    pc.printf("\n");
-}
+float K=lambda_r*R; //control gain
+float T=0.01; //in milliseconds
 
+float w=0; //angular velocity
+float r=0; //reference for orientation
+float y=0; //current orientation
+float u=0; //difference between right and left motor speeds
+float u_star=0;
+
+float vr=umax/2; //right motor speed
+float vl=umax/2; //left motor speed
+
+int c=0; //counter for measuring time
+bool back=0; //180 degrees turn flag
+int bumps=0; //bumps counter
+int cw=-1; //turn direction flag
 
-void printGyro()
-{
-    // To read from the gyroscope, you must first call the
-    // readGyro() function. When this exits, it'll update the
-    // gx, gy, and gz variables with the most current data.
-    
-    //Uncomment code if you plan on using interrupts
-    /*while(pinDRDYG == 0)
-    {
-        ;
-    }*/
-    
-    
+//Timer ISR, called with 100Hz frequency
+void timer() {
+    //sensor input
     dof.readGyro();
-
-    // Now we can use the gx, gy, and gz variables as we please.
-    // Either print them as raw ADC values, or calculated in DPS.
-    pc.printf("G: ");
-#ifdef PRINT_CALCULATED
-    // If you want to print calculated values, you can use the
-    // calcGyro helper function to convert a raw ADC value to
-    // DPS. Give the function the value that you want to convert.
-    //pc.printf("The bias: %2f, %2f, %2f \n", dof.gbias[0], dof.gbias[1], dof.gbias[2]);
-    pc.printf("%2f",dof.calcGyro(dof.gx) - dof.gbias[0]);
-    pc.printf(", ");
-    pc.printf("%2f",dof.calcGyro(dof.gy) - dof.gbias[1]);
-    pc.printf(", ");
-    pc.printf("%2f\n",dof.calcGyro(dof.gz) - dof.gbias[2]);
-#elif defined PRINT_RAW
-    pc.printf("%d", dof.gx);
-    pc.printf(", ");
-    pc.printf("%d",dof.gy);
-    pc.printf(", ");
-    pc.printf("%d\n",dof.gz);
-#endif
+    w=(pi/15)*(dof.calcGyro(dof.gz)-dof.gbias[2]); //measure angular velocity
+    y=y+T*(w-0.0000001); //integrate to obtain orientation
+    
+    //input calculation
+    u_star=-K*(y-r);
+  
+    //limiting motor speed
+    if (u_star<-umax){
+      u=-umax;
+    } else if (u_star>umax){
+      u=umax;
+    } else{
+      u=u_star;
+    }
+    
+    //actuator output
+    vr=(umax+u)/2.0;
+    vl=(umax-u)/2.0;
+    left.speed(vr);
+    right.speed(vl);
+    
+    //one second after it bumps, reference changes to -pi or zero
+    if (c==100 && back){
+        r=r+cw*pi/2;
+        c=0;
+        back=0;
+        cw=-cw; //changes direction of 180 turn when bumps
+        pb=0;
+    }  
+    
+    c++;
 }
 
-void printAccel()
-{
-    //Uncomment code if you plan on using interrupts
-    /*while(pinINT1_XM == 0)
-    {
-        ;
-    }*/
+void bump() {
+    bumps++; //counts bumps
+    tmr.detach(); //turn off timer
+    ld4=1;
     
-
-    dof.readAccel();
+    //avoid abrupt speed changes
+    left.speed(0);
+    right.speed(0);
+    wait(0.5);
+    
+    //goes backwards for 0.5s
+    left.speed(-0.8);
+    right.speed(-0.8);
+    wait(0.5);
     
-    // Now we can use the ax, ay, and az variables as we please.
-    // Either print them as raw ADC values, or calculated in g's.
-    pc.printf("A: ");
-#ifdef PRINT_CALCULATED
-    // If you want to print calculated values, you can use the
-    // calcAccel helper function to convert a raw ADC value to
-    // g's. Give the function the value that you want to convert.
-    //pc.printf("The bias: %2f, %2f, %2f \n", dof.abias[0], dof.abias[1], dof.abias[2]);
-    pc.printf("%2f",dof.calcAccel(dof.ax) - dof.abias[0]);
-    pc.printf(", ");
-    pc.printf("%2f",dof.calcAccel(dof.ay) - dof.abias[1]);
-    pc.printf(", ");
-    pc.printf("%2f\n",dof.calcAccel(dof.az) - dof.abias[2]);
-#elif defined PRINT_RAW
-    pc.printf("%d",dof.ax);
-    pc.printf(", ");
-    pc.printf("%d",dof.ay);
-    pc.printf(", ");
-    pc.printf("%d\n",dof.az);
-#endif
+    ld4=0;  
+    pb=1;
+    c=0;
+    
+    //change reference to plus or minus pi/2
+    r=r+cw*pi/2;
     
+    //implementation of finding initial position
+    if (bumps>2){
+        ld3=1;
+        back=1;
+    }
+    
+    LPC_TIM3->TC = 0;
+    tmr.attach(&timer, T); //turn timer back on
 }
 
-void printMag()
-{
-     //Uncomment code if you plan on using interrupts
-    /*while(pinINT2_XM == 0)
-    {
-        ;
-    }*/
-    
-    // To read from the magnetometer, you must first call the
-    // readMag() function. When this exits, it'll update the
-    // mx, my, and mz variables with the most current data.
-    dof.readMag();
-    
-    // Now we can use the mx, my, and mz variables as we please.
-    // Either print them as raw ADC values, or calculated in Gauss.
-    pc.printf("M: ");
-#ifdef PRINT_CALCULATED
-    // If you want to print calculated values, you can use the
-    // calcMag helper function to convert a raw ADC value to
-    // Gauss. Give the function the value that you want to convert.
-    pc.printf("%2f",dof.calcMag(dof.mx));
-    pc.printf(", ");
-    pc.printf("%2f",dof.calcMag(dof.my));
-    pc.printf(", ");
-    pc.printf("%2f\n",dof.calcMag(dof.mz));
-#elif defined PRINT_RAW
-    pc.printf("%d", dof.mx);
-    pc.printf(", ");
-    pc.printf("%d", dof.my);
-    pc.printf(", ");
-    pc.printf("%d\n", dof.mz);
-#endif
-}
-
-void loop()
-{
-    printGyro();  // Print "G: gx, gy, gz" 
-    printAccel(); // Print "A: ax, ay, az"
-    printMag();   // Print "M: mx, my, mz"    
-    wait_ms(PRINT_SPEED);
-}
-
-
 int main()
 {
-    setup();  //Setup sensor and Serial
-    pc.printf("Hello World\n");
+    uint16_t status = dof.begin(); //start and setup gyroscope
+    dof.calLSM9DS0(dof.gbias, dof.abias); //Calculate bias
+    
+    wait(3);
+    //starts going forward with 0.5 speed in both motors
+    left.speed(vl);
+    right.speed(vr);
+    
+    button.rise(&bump); //atach bump external interrupt
+    
+    //start timer with 0.01 period
+    timer_on=1;
+    tmr.attach(&timer, T);
 
-    while (true)
-    {
-         //Calculate bias
-         dof.calLSM9DS0(dof.gbias, dof.abias);
-         //pc.printf("Setup Done\n");
-         loop(); //Get sensor values
-   }
-}
-
+    while (true){} //infinite loop
+}
\ No newline at end of file