control for robotic arm that can play chess using a granular gripper

Dependencies:   Encoder mbed HIDScope Servo MODSERIAL

Fork of chessRobot by a steenbeek

Files at this revision

API Documentation at this revision

Comitter:
annesteenbeek
Date:
Wed Oct 28 11:48:07 2015 +0100
Parent:
115:d8d2968981f3
Child:
117:b1667291748d
Commit message:
calibration and kinematics

Changed in this revision

actuators.cpp Show annotated file Show diff for this revision Revisions of this file
actuators.h 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
--- a/actuators.cpp	Tue Oct 27 16:21:20 2015 +0100
+++ b/actuators.cpp	Wed Oct 28 11:48:07 2015 +0100
@@ -54,12 +54,13 @@
 const int servoStartPos = 1300; // Servo ranges from 600ms(-90) to 2000ms(90), 1300 is 0 deg
 
 // Set calibration values
-double motorCalSpeed = 5; // deg/sec
-double returnSpeed = -5;
+double motor1CalSpeed = -5; // deg/sec
+double motor2CalSpeed = 5;
 bool springHit = false;
 float lastCall = 0;
 bool calibrating1 = true;
 bool calibrating2 = false;
+double looseTime = 0;
 
 // Create object instances
 // Safety Pin
@@ -116,10 +117,10 @@
 
 void motorControl(){
         // EMG signals to motor speeds
-//        const double scaleVel = 20;
-//        motor1SetSpeed = x_velocity*scaleVel;
-//        motor2SetSpeed = y_velocity*scaleVel;
-//        servoSpeed = z_velocity*scaleVel;
+    //  const double scaleVel = 20;
+    //  motor1SetSpeed = x_velocity*scaleVel;
+    //  motor2SetSpeed = y_velocity*scaleVel;
+    //  servoSpeed = z_velocity*scaleVel;
     // get encoder positions in degrees
         // 131.25:1 gear ratio
         // getPosition uses X2 configuration, so 32 counts per revolution
@@ -129,22 +130,26 @@
         encoder2Counts = encoder2.getPosition();
 
 
-        motor1Pos = -((encoder1Counts/32)/131.25)*360;
-        motor2Pos = -((encoder2Counts/32)/131.25)*360;
+        motor1Pos = ((encoder1Counts/32)/131.25)*360;
+        motor2Pos = ((encoder2Counts/32)/131.25)*360;
 
         // check if motor's are within rotational boundarys
     // get  encoder speeds in deg/sec
         now = t.read(); 
         timechange = (now - prevTime);
-        motor1Speed = -((((encoder1Counts - motor1PrevCounts)/32)/131.25)*360)/timechange;
-        motor2Speed = -((((encoder2Counts - motor2PrevCounts)/32)/131.25)*360)/timechange;
+        motor1Speed = ((((encoder1Counts - motor1PrevCounts)/32)/131.25)*360)/timechange;
+        motor2Speed = ((((encoder2Counts - motor2PrevCounts)/32)/131.25)*360)/timechange;
         prevTime = now;
         motor1PrevCounts = encoder1Counts;
         motor2PrevCounts = encoder2Counts;
         
     // calculate motor setpoint speed in deg/sec from setpoint x/y speed
 
-        
+    // exclude kinematics when still calibrating
+    if (calReady){
+      kinematics();
+    }
+
     if(motorsEnable){  // only run motors if switch is enabled
     // compute new PID parameters using setpoint angle speeds and encoder speed
         writeMotors();
@@ -161,17 +166,17 @@
     motor2PID.Compute();
 // write new values to motor's
     if (motor1SetSpeed > 0 ){ // CCW rotation 
-        direction1 = false;
+        direction1 = true;
         motor1PID.SetOutputLimits(0,1); // change pid output direction
     }else{
-        direction1 = true; // CW rotation
+        direction1 = false; // CW rotation
         motor1PID.SetOutputLimits(-1,0);
     }
     if (motor2SetSpeed > 0 ){ // CCW rotation 
-        direction2 = false;
+        direction2 = true;
         motor2PID.SetOutputLimits(0,1);
     }else{
-        direction2 = true; // CW rotation
+        direction2 = false; // CW rotation
         motor2PID.SetOutputLimits(-1,0);
     }
     motor1Dir.write(direction1);
@@ -185,21 +190,25 @@
     servo.SetPosition(1300 + 700*servoSpeed);
 }
 
+const double motor1StartPos = (-10*32*131.25)/360; // angle to encoder counts
+const double motor2StartPos = (114*32*131.25)/360; 
+
 bool calibrateMotors(){
    safetyOn = false; // safety springs off
    motorsEnable = true; // motors on
-   redLed.write(0); greenLed.write(1); blueLed.write(1);
-   if (calibrating1 || calibrating2){
+   while (calibrating1 || calibrating2){
        if (calibrating1){
-            motor1SetSpeed = motorCalSpeed;
+            motor1SetSpeed = motor1CalSpeed;
             redLed.write(1); greenLed.write(0); blueLed.write(1);
-           if(safetyIn.read() !=1){ // check if arm reached safety position
-               encoder1.setPosition(0); // set motor 1 cal angle
-               motor1PrevCounts = 0; // set previous count to prevent speed spike
-               motor1SetSpeed = returnSpeed; // move away
+           if(safetyIn.read() !=1 && !springHit){ // check if arm reached safety position
+               encoder1.setPosition(motor1StartPos); // set motor 1 cal angle
+               motor1PrevCounts = motor1StartPos; // set previous count to prevent speed spike
+               motor1CalSpeed = -motor1CalSpeed; // move away
                springHit = true;
+               looseTime = t.read(); // timer to compensate spring movement
            }else{ 
-               if(springHit){ // if hit and after is no longer touching spring
+              // if hit and after is no longer touching spring and 0.5seconds passed
+               if(springHit && ((t.read() - looseTime) > 2)){ 
                 motor1SetSpeed = 0;
                 springHit = false;
                 calibrating2 = true; // start calibrating 2
@@ -208,29 +217,31 @@
            }
        }
        if (calibrating2){
-            motor2SetSpeed = motorCalSpeed; 
+            motor2SetSpeed = motor2CalSpeed; 
             redLed.write(1); greenLed.write(1); blueLed.write(0);
-           if(safetyIn.read() !=1){ // check if arm reached safety position
-               encoder2.setPosition(0); // set motor 2 cal angle
-               motor2PrevCounts = 0; // set previous cunt to prevent speed spike
-               motor2SetSpeed = returnSpeed; // move away
+           if(safetyIn.read() !=1 && !springHit){ // check if arm reached safety position
+               encoder2.setPosition(motor2StartPos); // set motor 2 cal angle
+               motor2PrevCounts = motor2StartPos; // set previous cunt to prevent speed spike
+               motor2CalSpeed = -motor2CalSpeed; // move away
                springHit = true;
+               looseTime = t.read();
            }else{ 
-               if(springHit){ // if hit and after is no longer touching spring
+               if(springHit && ((t.read() - looseTime) > 2)){ 
                 motor2SetSpeed = 0;
                 springHit = false;
                 calibrating2 = false; // stop calibrating 2
                }
            }
        }
-       now = t.read(); // call motor using timer instead of wait
+       // now = t.read(); // call motor using timer instead of wait
        // if(now - lastCall > motorCall){
            motorControl();
-           wait(motorCall);
+           wait(motorCall); // keep calling PID's with motorCall frequency
            // lastCall = now;
        // }
 
    }
+    redLed.write(0); greenLed.write(1); blueLed.write(1);
     motorsEnable = false; // turn motor's off again
     safetyOn = true; // turn safety on after callibration
     return true; // return true when finished
@@ -245,31 +256,40 @@
     }
 }
 
+const double L1 = 0.436; // first arm in m
+const double L2 = 0.120; // first arm in m
+const double L3 = 0.255; // servo arm in m
+const double Xmax = 0.3;
+const double Xmin; = -0.3;
+const double Ymax = 0.645;
+const double Ymin = 0.33;
 
-//bool kinematics(){
-//     // calculate current x and Y
-//     X = L2*cos((motor1Pos + motor2Pos)*PI/180) + L1*cos(motor1Pos*PI/180);
-//     Y = L2*sin((motor1Pos + motor2Pos)*PI/180) + L1*sin(motor1Pos*PI/180);
-//     // check if x and y are within limits
-//     //  else  Store the constraint line
-//     //      check if movement is in direction of constraint
-//     //      else return false no movement (anglespeed = 0)
-//     // calculate required angle speeds
-//     if( (X>Xmax && setXSpeed > 0 )|| \
-//         (X<Xmin && setXSpeed < 0 )|| \
-//         (Y>Ymax && setYSpeed > 0 )|| \
-//         (Y<Ymin && setYSpeed < 0 )   \
-//     ){
-//         motor1SetSpeed = 0;
-//         motor2SetSpeed = 0;
-//         return false;
-//         break;
-//     }
-// motor1SetSpeed = (setXSpeed*cos((motor1Pos + motor2Pos)*PI/180) + \
-//     setYSpeed*sin((motor1Pos + motor2Pos)*PI/180))/(L1*sin(motor2Pos*PI/180));
-// motor2SetSpeed = -(setXSpeed*L2*cos((motor1Pos + motor2Pos)*PI/180) + \
-//     setYSpeed*L2*sin((motor1Pos + motor2Pos)*PI/180) + \
-//     setXSpeed*L1*cos(motor1Pos*PI/180) + \
-//     setYSpeed*L1*sin(motor1Pos*PI/180))/(L1*L2*sin(motor2Pos*PI/180));
+
 
-//}
\ No newline at end of file
+bool kinematics(){
+    // calculate current x and Y
+    double X = (L2+L3)*cos((motor1Pos + motor2Pos)*PI/180) + L1*cos(motor1Pos*PI/180);
+    double Y = (L2+L3)*sin((motor1Pos + motor2Pos)*PI/180) + L1*sin(motor1Pos*PI/180);
+    // check if x and y are within limits
+    //  else  Store the constraint line
+    //      check if movement is in direction of constraint
+    //      else return false no movement (anglespeed = 0)
+    // calculate required angle speeds
+    if( (X>Xmax && setXSpeed > 0 )|| \
+        (X<Xmin && setXSpeed < 0 )|| \
+        (Y>Ymax && setYSpeed > 0 )|| \
+        (Y<Ymin && setYSpeed < 0 )   \
+    ){
+        motor1SetSpeed = 0;
+        motor2SetSpeed = 0;
+        return false;
+        break;
+    }
+motor1SetSpeed = (setXSpeed*cos((motor1Pos + motor2Pos)*PI/180) + \
+    setYSpeed*sin((motor1Pos + motor2Pos)*PI/180))/(L1*sin(motor2Pos*PI/180));
+motor2SetSpeed = -(setXSpeed*(L2+L3)*cos((motor1Pos + motor2Pos)*PI/180) + \
+    setYSpeed*(L2+L3)*sin((motor1Pos + motor2Pos)*PI/180) + \
+    setXSpeed*L1*cos(motor1Pos*PI/180) + \
+    setYSpeed*L1*sin(motor1Pos*PI/180))/(L1*(L2+L3)*sin(motor2Pos*PI/180));
+
+}
\ No newline at end of file
--- a/actuators.h	Tue Oct 27 16:21:20 2015 +0100
+++ b/actuators.h	Wed Oct 28 11:48:07 2015 +0100
@@ -30,6 +30,8 @@
 extern double servoSpeed;
 extern double motorCall;
 
+extern bool calReady;
+
 // Set PID values
 extern PID motor2PID;
 
@@ -39,5 +41,6 @@
 bool calibrateMotors();
 void writeMotors();
 void safety();
+void kinematics();
 
 #endif 
\ No newline at end of file
--- a/main.cpp	Tue Oct 27 16:21:20 2015 +0100
+++ b/main.cpp	Wed Oct 28 11:48:07 2015 +0100
@@ -14,20 +14,16 @@
 #include "debug.h"
 #include "emg.h"
 
-int a =4;
-
-Ticker switchesTick, debugTick, motorTick, EMGTick, safetyTick calibrateTick;
-volatile bool switches_go=false, debug_go=false, motor_go=false, emg_go=false, safety_go=false, cal_go=false;
+Ticker switchesTick, debugTick, motorTick, EMGTick, safetyTick;
+volatile bool switches_go=false, debug_go=false, motor_go=false, emg_go=false, safety_go=false;
 
 void switches_activate(){switches_go=true;};
 void debug_activate(){debug_go=true;};
 void motor_activate(){motor_go=true;};
 void emg_activate(){emg_go=true;};
 void safety_activate(){safety_go=true;};
-void calibration_activate(){cal_go=true;};
 
 void tickerAttach(){
-    calibrateTick.detach(&calibration_activate);  // stop calibration ticker
     EMGTick.attach(&emg_activate, 0.005f);
     switchesTick.attach(&switches_activate, 0.02f);
     debugTick.attach(&debug_activate, 0.03f);
@@ -39,17 +35,14 @@
 const int sample = 0;  // Constant for mode switching for program readability
 const int normalize = 1; // Constant for mode switching for program readability
 bool mode = normalize; // Set program mode
+bool tickersActivated = false;
 bool calReady = false; // flag for calibration ready
 
 int main(){
     motorInit();
-    calibrateTick.attach(&calibration_activate, motorCall);    
+    calReady = calibrateMotors();
 
     while (true) {
-        if(cal_go){
-            cal_go=false;
-            calReady = calibrateMotors();
-        }
 
         if(calReady && !tickersActivated){ // when done with calibration, start tickers
             tickerAttach();