The servo version of SCRIBE

Dependencies:   BLE_nRF8001 BNO055 HC_SR04_Ultrasonic_Library mbed-rtos mbed

Fork of SCRIBE_stepper by SCRIBE

Files at this revision

API Documentation at this revision

Comitter:
manz
Date:
Thu May 12 06:17:49 2016 +0000
Parent:
13:d49cb8b52a1e
Commit message:
latest version;

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
servo.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r d49cb8b52a1e -r 82248fb06e53 main.cpp
--- a/main.cpp	Fri May 06 00:18:02 2016 +0000
+++ b/main.cpp	Thu May 12 06:17:49 2016 +0000
@@ -25,6 +25,14 @@
 DigitalInOut BLE_RDY(p21);  
 DigitalInOut BLE_REQ(p22);   
 DigitalInOut BLE_RESET(p23); 
+
+
+// pins for IR localization
+I2C i2c(p9, p10);        // sda, scl
+const int addr = 0xB0;   // define the I2C Address of camera
+int ir_finish = 0;
+
+void back_to_zero();
  
 unsigned char txbuf[16] = {0};
 unsigned char txlen = 0;
@@ -65,6 +73,8 @@
 double y_pen = 0;
 double x_cent = 0;
 double y_cent = -1;
+double x_taro = 0;
+double y_taro = 0;
 
 //speed of SCRIBE
 float speed = 0.3;
@@ -75,7 +85,7 @@
 
 localization L;
 
-osThreadId bluetooth_id, mover_id;
+osThreadId bluetooth_id, mover_id,ir_id;
 
 void bluetooth_thread(void const *args){
     bluetooth_id = Thread::gettid();
@@ -138,8 +148,8 @@
                         // inputs blocked until shape finished
                         if (mode != 13){
                             mode = (int) val[0];
+                            serial.printf("Mode 1-val: %i\r\n",mode);
                             if(mode != 4 && mode !=6){
-                                serial.printf("Mode 1-val: %i\r\n",mode);
                                 osSignalClear(bluetooth_id,0x1);
                                 which_thread = 1;
                             }
@@ -232,16 +242,219 @@
     }
 }
 
-
-// incomplete
-int draw_circle(double radius){
-    float currAngle = L.getAngle();
-    if(radius >= 5){ 
-        int outer = (int) radius*0.6;
-        int inner = (int) radius*0.2;
+void i2c_write2(int addr, char a, char b)
+{
+    char cmd[2];
+    
+    cmd[0] = a;
+    cmd[1] = b;
+    i2c.write(addr, cmd, 2);
+    wait(0.07); // delay 70ms    
+}
+ 
+void clock_init()
+{
+    // set up ~20-25MHz clock on p21
+    LPC_PWM1->TCR = (1 << 1);               // Reset counter, disable PWM
+    LPC_SC->PCLKSEL0 &= ~(0x3 << 12);  
+    LPC_SC->PCLKSEL0 |= (1 << 12);          // Set peripheral clock divider to /1, i.e. system clock
+    LPC_PWM1->MR0 = 4;                     // Match Register 0 is shared period counter for all PWM1
+    LPC_PWM1->MR6 = 2;                      // Pin 21 is PWM output 6, so Match Register 6
+    LPC_PWM1->LER |= 1;                     // Start updating at next period start
+    LPC_PWM1->TCR = (1 << 0) || (1 << 3);   // Enable counter and PWM
+}
+ 
+void cam_init()
+{
+    // Init IR Camera sensor
+    i2c_write2(addr, 0x30, 0x01);
+    i2c_write2(addr, 0x30, 0x08);    
+    i2c_write2(addr, 0x06, 0x90);
+    i2c_write2(addr, 0x08, 0xC0);
+    i2c_write2(addr, 0x1A, 0x40);
+    i2c_write2(addr, 0x33, 0x33);
+    wait(0.1);
+}
+ 
+void ir_localization(void const *args) {
+    ir_id = Thread::gettid();
+    char cmd[8];
+    char buf[16];
+    int Ix1,Iy1,Ix2,Iy2;
+    int Ix3,Iy3,Ix4,Iy4;
+    double angle1,angle2,angle3,angle4;
+    double angle_init, sum_x;
+    int s;
+    
+    // variables for localization
+    int m_count = 0;
+    double alpha1,alpha2,phi1,phi2,phiIMU1,phiIMU2,beta;
+    double x,y,z;
+    
+    // height is given
+    double h = 97;
+    
+    //clock_init();
+    
+    // PC serial output    
+    serial.printf("Initializing camera...");
+ 
+    cam_init();
+  
+    serial.printf("complete\n");
+    
+    float testAngle = L.getAngle();
+    angle_init = L.getAngle();
+    
+    serial.printf("Initial IMU-Angle is: %f\r\n",angle_init);
+    servo_slowleft();
+    // read I2C stuff
+    while(m_count !=2){
+        // IR Sensor read
+        cmd[0] = 0x36;
+        i2c.write(addr, cmd, 1);
+        i2c.read(addr, buf, 16); // read the 16-byte result
+        
+        Ix1 = buf[1];
+        Iy1 = buf[2];
+        s   = buf[3];
+        Ix1 += (s & 0x30) <<4;
+        Iy1 += (s & 0xC0) <<2;
+        
+        Ix2 = buf[4];
+        Iy2 = buf[5];
+        s   = buf[6];
+        Ix2 += (s & 0x30) <<4;
+        Iy2 += (s & 0xC0) <<2;
+        
+        Ix3 = buf[7];
+        Iy3 = buf[8];
+        s   = buf[9];
+        Ix3 += (s & 0x30) <<4;
+        Iy3 += (s & 0xC0) <<2;
+        
+        Ix4 = buf[10];
+        Iy4 = buf[11];
+        s   = buf[12];
+        Ix4 += (s & 0x30) <<4;
+        Iy4 += (s & 0xC0) <<2;
+        
+        angle1 = 45*((double)Ix1 / 1023 - 0.5);
+        angle2 = 45*((double)Ix2 / 1023 - 0.5);
+        angle3 = 45*(double)Ix3 / 1023;
+        angle4 = 45*(double)Ix4 / 1023;
+        
+        // print the coordinate data
+        serial.printf("Ix1: %4d, Iy1: %4d\n", Ix1, Iy1 );
+        //serial.printf("Ix2: %4d, Iy2: %4d\n", Ix2, Iy2 );
+        //serial.printf("Current IMU-Angle is: %f\r\n",L.getAngle());
+        //print when more than one LED present
+        
+        if(Ix1 < 1023){
+            //serial.printf("%d, %d: %f; %d, %d : %f\r\n", Ix1, Iy1, angle1, Ix2, Iy2, angle2);
+/*            if(angle1 <= -2){
+                //serial.printf("Turn left! \r\n");
+            }
+            else if (angle1 >= 2 && (abs(360 - L.getAngle()) > 90)){
+                serial.printf("Turn right! \r\n");
+            }*/
+            if(abs(angle1) < 2) {
+                if(m_count == 0 && abs(360 - L.getAngle()) < 90){
+                    sum_x = 0;
+                    // get ten pictures
+                    for(int i = 0; i < 10; i++){
+                        cmd[0] = 0x36;
+                        i2c.write(addr, cmd, 1);
+                        i2c.read(addr, buf, 16);
+                        
+                        Ix1 = buf[1];
+                        Iy1 = buf[2];
+                        s   = buf[3];
+                        Ix1 += (s & 0x30) <<4;
+                        Iy1 += (s & 0xC0) <<2;
+                        angle1 = 45*((double)Ix1 / 1023 - 0.5);  
+                        sum_x = sum_x + angle1;  
+                    }
+                    serial.printf("*** Got average angle1: %f\r\n",sum_x/10);
+                    phiIMU1 = L.getAngle();
+                    phi1 = 360 - (phiIMU1 + sum_x/10);
+                    serial.printf("*** Got phi1: %f, got phi_IMU1: %f\r\n", phi1,phiIMU1);
+                    m_count = 1;
+                }
+                else if (m_count == 1 && abs(360 - L.getAngle()) > 90){
+                    servo_stop();
+                    phiIMU2 = L.getAngle();
+                    
+                    sum_x = 0;
+                    // get ten pictures
+                    for(int i = 0; i < 10; i++){
+                        cmd[0] = 0x36;
+                        i2c.write(addr, cmd, 1);
+                        i2c.read(addr, buf, 16);
+                        
+                        Ix1 = buf[1];
+                        Iy1 = buf[2];
+                        s   = buf[3];
+                        Ix1 += (s & 0x30) <<4;
+                        Iy1 += (s & 0xC0) <<2;
+                        angle2 = 45*((double)Ix1 / 1023 - 0.5);
+                        
+                        sum_x = sum_x + angle2;  
+                    }
+                    serial.printf("*** Got average angle2: %f\r\n",sum_x/10);
+                    
+                    phi2 = 360 - (phiIMU2 + sum_x/10);
+                    serial.printf("*** Got phi2: %f, got phi_IMU2: %f\r\n", phi2,phiIMU2);
+                    alpha1 = 90 - phi1;
+                    alpha2 = 90 - alpha1;
+                    beta = 180 - (phi2 - phi1) - alpha2;
+                    z = h*sin(beta/180*3.1415)/sin((phi2 - phi1)/180*3.1415);
+                    x = z*sin(phi1/180*3.1415);
+                    y = z*sin(alpha1/180*3.1415);
+                    
+                    serial.printf("Angles are: phi1 = %f, phi2 = %f:\r\n",phi1, phi2);
+                    serial.printf("Angles are: alpha1 = %f, alpha2 = %f:\r\n",alpha1, alpha2);
+                    
+                    //reset after print out and set coordinates
+                    m_count = 2;
+                    x_pen = rint(x/4.5);
+                    y_pen = rint((h-y)/4.5);
+                    
+                    //correction for translation
+                    x_pen = x_pen + 2;
+                    y_pen = y_pen - 2;
+                    x_cent = x_pen;
+                    y_cent = y_pen - 1;
+                    x_taro = x_pen;
+                    y_taro = y_pen;  
+                    serial.printf("Current location: x = %f, y = %f \r\n",x,h-y);
+                    serial.printf("Current coordinates Pen: x = %f, y = %f \r\n",x_pen,y_pen);
+                    serial.printf("Current coordinates Center: x = %f, y = %f \r\n",x_cent,y_cent);
+                }
+            }
+            
+        }
+        wait(0.2);
     }
+    
+    //turn upside again
+    back_to_zero();
+    ir_finish = 1;
 }
 
+void back_to_zero(){
+    float testAngle = L.getAngle();
+    serial.printf("Current Angle BTZ: %f",L.getAngle());
+    while(L.getAngle()> 1){
+        if(L.getAngle() > 180){
+            servo_slowright();        
+        }
+        else{
+            servo_slowleft();
+        }
+    }
+    servo_stop();
+}
  
 void move_thread(void const *args){
 
@@ -252,8 +465,6 @@
 
     Timer t;
     //initally put pen down
-    servo_reset();
-    servo_stop();
     
     float currentAngle;
     float targetAngle;
@@ -275,8 +486,6 @@
     double x_tar,y_tar;
     double x_pen_pr, y_pen_pr, x_cent_pr, y_cent_pr, x_taro_pr, y_taro_pr;
     double cosg,gamma,distance,wait_t;
-    double x_taro = 0;
-    double y_taro = 0;
     serial.printf("Started move thread\r\n");
     int newval = 0;
     
@@ -340,7 +549,7 @@
         else if(mode == 1){
             serial.printf("Draw circle \r\n");
             //call circle function
-            control = draw_circle(radius);
+            //control = draw_circle(radius);
             
             mode = -1;
         }     
@@ -393,7 +602,7 @@
         else if (mode == 7){
             if (first == 0){
                 serial.printf("Draw freely \r\n");
-                draw_corr = 1;
+                draw_corr = 0.08;
             }
             first = 1;
         }
@@ -410,8 +619,12 @@
                 if (start == size){
                     start = 0;
                 }
-                x_tar = (double) path_x[start]*draw_corr;
-                y_tar = (double) path_y[start]*draw_corr;
+                x_tar = (double) path_x[start];
+                y_tar = (double) path_y[start];
+                serial.printf("Got data: x = %f, y = %f \r\n",x_tar,y_tar);
+                x_tar = x_tar*draw_corr;
+                y_tar = y_tar*draw_corr;
+                serial.printf("Scaled data: x = %f, y = %f \r\n",x_tar,y_tar);
                 p_mode = path_p[start];
                 start++;
                 if(start == counter){
@@ -486,11 +699,18 @@
                 //compute length of path til target
                 distance = sqrt((x_tar - x_pen)*(x_tar - x_pen) + (y_tar - y_pen)*(y_tar - y_pen));
                 
-                //forward SCRIBE til target
-                serial.printf("Distance to be taken: %f\r\n",distance);
-                
+                //forward SCRIBE til target                
                 int counter_m = (int) rint(distance);
                 
+                // do adjustment when going down
+                if (L.getAngle() > 330 || L.getAngle() < 30){
+                    counter_m = counter_m + 2;    
+                }
+                if (L.getAngle() > 130 || L.getAngle() < 230){
+                    counter_m = counter_m - 2;    
+                }
+                serial.printf("*** Distance to be taken: %d\r\n",counter_m);
+
                 // find position of wheels
                 for (int i = 0; i < 100; i++){
                         sum_r += ain1.read();
@@ -505,7 +725,7 @@
                 else{
                     on_r = 1;
                 }
-                if(value_l < 0.93){
+                if(value_l < 0.925){
                     on_l = 0;
                 }
                 else{
@@ -521,32 +741,33 @@
                 while (counter_m > 0){
                     sum_r = 0;
                     sum_l = 0;
-                    for (int i = 0; i < 100; i++){
+                    for (int i = 0; i < 5; i++){
                         sum_r += ain1.read();  
                         sum_l += ain2.read(); 
                     }
-                    value_r = sum_r/100;
-                    value_l = sum_l/100;
-                    //printf("Value: %f\r\n",value);
-                    if(value_r < 0.93 && on_r == 1){
+                    value_r = sum_r/5;
+                    value_l = sum_l/5;
+                    printf("Left Value: %f\r\n",value_l);
+                    printf("Right Value: %f\r\n",value_r);
+                    if(value_r < 0.84 && on_r == 1){
                         //printf("Value right: %f\r\n",value_r);
                         on_r = 0;
                     }
-                    else if (value_r > 0.95 && on_r == 0){
+                    else if (value_r > 0.88 && on_r == 0){
                         //printf("Value right: %f\r\n",value_r);
                         on_r = 1;
                         counter_r--;
-                        //printf("*** Right Counter is: %d\r\n",counter_r);
+                        printf("*** Right Counter is: %d\r\n",counter_r);
                     }
-                    if(value_l < 0.93 && on_l == 1){
+                    if(value_l < 0.9 && on_l == 1){
                         //printf("Value left: %f\r\n",value_l);
                         on_l = 0;
                     }
-                    else if (value_l > 0.95 && on_l == 0){
+                    else if (value_l > 0.92 && on_l == 0){
                         //printf("Value left: %f\r\n",value_l);
                         on_l = 1;
                         counter_l--;
-                        //printf("*** Left Counter is: %d\r\n",counter_l);
+                        printf("*** Left Counter is: %d\r\n",counter_l);
                     }
                     
                     if(counter_l >= counter_r){
@@ -556,17 +777,20 @@
                         counter_m = counter_l;    
                     }
                     //deviation left from path
-                    if(L.getAngle() - angle_init > 2 || (angle_init > 358 &&  L.getAngle() < 5 && (L.getAngle() + 360 - angle_init) > 2)){
-                        servo_slowleft();
-                        serial.printf("Angle Difference: %f\r\n",L.getAngle() - angle_init);
-                        while(fmod(abs(L.getAngle() - angle_init),360)> 1);
-                        servo_f();                        
-                    }
-                    //deviation right from path
-                    if(angle_init - L.getAngle() > 2 ){
-                        servo_slowright();
-                        while(fmod(abs(L.getAngle() - angle_init),360)> 1);
-                        servo_f();                        
+                    if(angle_init > 270 || angle_init < 90){
+                        if((L.getAngle() - angle_init > 2 && L.getAngle() - angle_init < 10) || (angle_init > 358 &&  L.getAngle() < 5 && (L.getAngle() + 360 - angle_init) > 2)){
+                            servo_slowleft();
+                            serial.printf("Left: Angle Difference: %f\r\n",L.getAngle() - angle_init);
+                            serial.printf("Left: Init: %f, Current: %f\r\n",angle_init,L.getAngle());
+                            while(fmod(abs(L.getAngle() - angle_init),360)> 1);
+                            servo_f();                        
+                        }
+                        //deviation right from path
+                        if(angle_init - L.getAngle() > 2 || (L.getAngle() > 358 &&  angle_init < 5 && (angle_init + 360 - L.getAngle()) > 2)){
+                            servo_slowright();
+                            while(fmod(abs(L.getAngle() - angle_init),360)> 1);
+                            servo_f();                        
+                        }
                     }
                     //printf("*** Distance to take is: %d\r\n",counter_m);
                 }
@@ -605,10 +829,19 @@
 int main()
 {   
     L.reset();
-    //L.servo(90);
-    wait(1);
-    serial.printf("Starting Dead-Reckoning\r\n");
-    //deadreckoning(); 
+    servo_reset();
+    servo_stop();
+    serial.printf("Starting Calibration\r\n");
+    back_to_zero();
+
+    serial.printf("Starting IR-Localization\r\n");
+    //ir_localization(); 
+    Thread ir(ir_localization);
+    ir_id = ir.gettid();
+    
+    while(ir_finish == 0){
+        Thread::wait(10);
+    }
     serial.printf("Starting the threads\r\n");
     
     Thread bluetooth(bluetooth_thread);
diff -r d49cb8b52a1e -r 82248fb06e53 servo.cpp
--- a/servo.cpp	Fri May 06 00:18:02 2016 +0000
+++ b/servo.cpp	Thu May 12 06:17:49 2016 +0000
@@ -9,8 +9,10 @@
 }
 
 void servo_f(){
-    pin25.pulsewidth_us(1300);
-    pin26.pulsewidth_us(1700);
+    //pin25.pulsewidth_us(1300);
+    //pin26.pulsewidth_us(1700);
+    pin25.pulsewidth_us(1350);
+    pin26.pulsewidth_us(1650);
 }
 
 void servo_b(){
@@ -30,7 +32,7 @@
 
 void servo_stop(){
     pin25.pulsewidth_us(1500);
-    pin26.pulsewidth_us(1510);                                      
+    pin26.pulsewidth_us(1515);                                      
 }
 
 void servo_slowright(){