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 21 12:03:43 2015 +0000
Parent:
93:a8898eb80edc
Parent:
92:12e2e57e900a
Child:
95:94f02d01ebdf
Commit message:
attempted merge

Changed in this revision

actuators.cpp Show annotated file Show diff for this revision Revisions of this file
actuators.cpp.orig Show annotated file Show diff for this revision Revisions of this file
config.h Show annotated file Show diff for this revision Revisions of this file
config.h.orig Show annotated file Show diff for this revision Revisions of this file
--- a/actuators.cpp	Wed Oct 21 13:16:24 2015 +0200
+++ b/actuators.cpp	Wed Oct 21 12:03:43 2015 +0000
@@ -8,7 +8,7 @@
 #include "buttons.h"
     // functions for controlling the motors
     bool motorsEnable = false;
-    bool safetyOn = false; // start with safety off for calibration
+    bool safetyOn = true; // start with safety off for calibration
 
 
     double encoder1Counts = 0;
@@ -177,11 +177,21 @@
 }
 
 void calibrateMotors(){
+<<<<<<< local
    safetyOn = false;
    redLed.write(0); greenLed.write(1); blueLed.write(1);
    while (calibrating1 || calibrating2){
        if (calibrating1){
+=======
+    safetyOn = false;
+    bool calibrating1 = true;
+    bool calibrating2 = true;
+    double motorCalSpeed = 10; // deg/sec
+    while (calibrating1 || calibrating2){
+        if (calibrating1){
+>>>>>>> other
             motor1SetSpeed = motorCalSpeed; // deg/sec 
+<<<<<<< local
             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
@@ -218,6 +228,27 @@
        }
 
    }
+=======
+            if(safetyIn.read() !=1){ // check if arm reached safety position
+                calibrating1 = false; // done 
+                motor1SetSpeed = 0; // brake motor
+                encoder1.setPosition(0); // set motor 1 cal angle
+                // move away
+            }
+        }
+        if (calibrating1){
+            motor2SetSpeed = motorCalSpeed; // deg/sec 
+            if(safetyIn.read() !=1){ // check if arm reached safety position
+                calibrating2 = false; // done 
+                motor2SetSpeed = 0; // brake motor
+                encoder2.setPosition(0); // set motor 2 cal angle
+                // move away
+            }
+        }
+        writeMotors();
+        wait(0.01f);
+    }
+>>>>>>> other
     safetyOn = true; // turn safety on after callibration
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/actuators.cpp.orig	Wed Oct 21 12:03:43 2015 +0000
@@ -0,0 +1,231 @@
+#include "actuators.h"
+#include "PID.h"
+#include "mbed.h"
+#include "config.h"
+#include "encoder.h"
+#include "HIDScope.h"
+#include "Servo.h"
+#include "buttons.h"
+    // functions for controlling the motors
+    bool motorsEnable = false;
+    bool safetyOn = false; // start with safety off for calibration
+
+
+    double encoder1Counts = 0;
+    double encoder2Counts = 0;
+
+    bool direction1 = false; // CCW is false(positive rotation), CW is true (neg rotation)
+    bool direction2 = false;
+
+    double motor1Pos = 0;
+    double motor2Pos = 0;
+
+    double motor1Speed = 0;
+    double motor2Speed = 0;
+
+    double motor1SetSpeed = 0;
+    double motor2SetSpeed = 0;
+
+    double servoPos = 0;
+
+    double motor1PWM = 0;
+    double motor2PWM = 0;
+
+    // Set PID values
+    double Kp1 = 1; 
+    double Ki1 = 0; 
+    double Kd1 = 0;
+
+    double Kp2 = 0.008; 
+    double Ki2 = 0.08; 
+    double Kd2 = 0;
+
+    double motor1PrevCounts = 0;
+    double motor2PrevCounts = 0;
+    double prevTime = 0;
+    double now = 0;
+    double timechange;
+    bool pidOut = 0;
+
+    // for Calibration:
+    bool calibrating1 = true;
+    bool calibrating2 = false;
+    double motorCalSpeed = 10; // deg/sec
+    double returnSpeed = -10;
+    bool springHit = false;
+    float lastCall = 0;
+
+
+    // Create object instances
+    // Safety Pin
+    DigitalIn safetyIn(safetyPin);
+    
+    // Initialze motors
+    PwmOut motor1(motor1PWMPin);
+    PwmOut motor2(motor2PWMPin);
+
+    // Initialize encoders
+    Encoder encoder1(enc1A, enc1B);
+    Encoder encoder2(enc2A, enc2B);
+
+    // Set direction pins     
+    DigitalOut motor1Dir(motor1DirPin);
+    DigitalOut motor2Dir(motor2DirPin);  
+
+    // create PID instances
+    PID motor1PID(&motor1Speed, &motor1PWM, &motor1SetSpeed, Kp1, Ki1, Kd1);
+    PID motor2PID(&motor2Speed, &motor2PWM, &motor2SetSpeed, Kp2, Ki2, Kd2);
+
+    Servo servo(servoPin);
+    Timer t;  
+    
+void motorInit(){
+    
+    motor1Dir.write(direction1);
+    motor2Dir.write(direction2);
+
+    // Set motor PWM period
+    motor1.period(1/pwm_frequency);
+    motor2.period(1/pwm_frequency);
+    
+    motor1PID.SetSampleTime(motorCall);
+    motor2PID.SetSampleTime(motorCall);
+    
+    motor1PID.SetOutputLimits(0,1);
+    motor2PID.SetOutputLimits(0,1);
+    
+    // Turn PID on
+    motor1PID.SetMode(AUTOMATIC);
+    motor2PID.SetMode(AUTOMATIC);
+    
+    // start the timer
+    t.start();
+}
+
+
+void motorControl(){
+    // get encoder positions in degrees
+        // 131.25:1 gear ratio
+        // getPosition uses X2 configuration, so 32 counts per revolution
+        // encoder reads CCW negative, and CW positive, so multiply by -1 to make CCW positive
+
+        encoder1Counts = encoder1.getPosition();
+        encoder2Counts = encoder2.getPosition();
+
+
+        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;
+        prevTime = now;
+        motor1PrevCounts = encoder1Counts;
+        motor2PrevCounts = encoder2Counts;
+        
+    // calculate motor setpoint speed in deg/sec from setpoint x/y speed
+
+        
+    if(motorsEnable){  // only run motors if switch is enabled
+    // compute new PID parameters using setpoint angle speeds and encoder speed
+        writeMotors();
+    }else{
+        // write 0 to motors
+        motor1.write(0);
+        motor2.write(0);
+    }
+}
+
+void writeMotors(){
+    motor1PID.Compute(); // calculate PID outputs, output changes automatically
+    motor2PID.Compute();
+// write new values to motor's
+    if (motor1SetSpeed > 0 ){ // CCW rotation 
+        direction1 = false;
+        motor1PID.SetOutputLimits(0,1); // change pid output direction
+    }else{
+        direction1 = true; // CW rotation
+        motor1PID.SetOutputLimits(-1,0);
+    }
+    if (motor2SetSpeed > 0 ){ // CCW rotation 
+        direction2 = false;
+        motor2PID.SetOutputLimits(0,1);
+    }else{
+        direction2 = true; // CW rotation
+        motor2PID.SetOutputLimits(-1,0);
+    }
+    motor1Dir.write(direction1);
+    motor2Dir.write(direction2);
+
+    motor1.write(abs(motor1PWM));
+    motor2.write(abs(motor2PWM));
+}
+
+void servoControl(){
+    // use potMeter Value to set servo angle
+    if (motorsEnable){
+        servo.write(servoPos);
+    }
+    // (optionaly calculate xy position to keep balloon in position)
+        // calculate z position using angle
+        // calculate x y translation of endpoint
+        // find new x and y speed.
+    
+}
+
+void calibrateMotors(){
+   safetyOn = false;
+   redLed.write(0); greenLed.write(1); blueLed.write(1);
+   while (calibrating1 || calibrating2){
+       if (calibrating1){
+            motor1SetSpeed = motorCalSpeed; // deg/sec 
+            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
+               motor1SetSpeed = returnSpeed; // move away
+               springHit = true;
+           }else{ 
+               if(springHit){ // if hit and after is no longer touching spring
+                motor1SetSpeed = 0;
+                springHit = false;
+                calibrating1 = false;
+                calibrating2 = true; // start calibrating 2
+               }
+           }
+       }
+       if (calibrating2){
+            motor2SetSpeed = motorCalSpeed; 
+            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
+               motor2SetSpeed = returnSpeed; // move away
+               springHit = true;
+           }else{ 
+               if(springHit){ // if hit and after is no longer touching spring
+                motor2SetSpeed = 0;
+                springHit = false;
+                calibrating2 = false; // stop calibrating 2
+               }
+           }
+       }
+       now = t.read(); // call motor using timer instead of wait
+       if(now - lastCall > motorCall){
+           writeMotors();
+           lastCall = now;
+       }
+
+   }
+    safetyOn = true; // turn safety on after callibration
+}
+
+
+void safety(){
+    if (safetyOn){
+        if (safetyIn.read() != 1){
+            motorsEnable = false;
+        }
+    }
+}
--- a/config.h	Wed Oct 21 13:16:24 2015 +0200
+++ b/config.h	Wed Oct 21 12:03:43 2015 +0000
@@ -1,11 +1,17 @@
 // All the definitions and variables
+<<<<<<< local
 // #define TUNEPID  // set to switch between normal opperation or tuning PID
 // #define TUNEEMG // set hdiscope for EMG
 #define TUNEPWM // set hidscope for rest
+=======
+
+>>>>>>> other
 // Analog inputs for EMG
 #define EMG1in          A0
 #define EMG2in          A1
 
+#define startPin		PTC6
+
 // Analog inputs for potmeters
 #define pot1Pin         A2
 #define pot2Pin         A3
@@ -14,6 +20,10 @@
 
 #define button1Pin      D0
 #define button2Pin      D1
+<<<<<<< local
+=======
+#define button3Pin      PTC6
+>>>>>>> other
 
 // Servo
 #define servoPin        D9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config.h.orig	Wed Oct 21 12:03:43 2015 +0000
@@ -0,0 +1,34 @@
+// All the definitions and variables
+// #define TUNEPID  // set to switch between normal opperation or tuning PID
+// #define TUNEEMG // set hdiscope for EMG
+#define TUNEPWM // set hidscope for rest
+// Analog inputs for EMG
+#define EMG1in          A0
+#define EMG2in          A1
+
+// Analog inputs for potmeters
+#define pot1Pin         A2
+#define pot2Pin         A3
+
+#define safetyPin		D2
+
+#define button1Pin      D0
+#define button2Pin      D1
+
+// Servo
+#define servoPin        D9
+
+// MOTORS
+#define motor2DirPin    D4
+#define motor2PWMPin    D5
+
+#define motor1DirPin    D7
+#define motor1PWMPin    D6
+
+#define enc1A           D11
+#define enc1B           D10
+#define enc2A           D13
+#define enc2B           D12
+
+// Motor control constants
+#define pwm_frequency 50000
--- a/debug.cpp	Wed Oct 21 13:16:24 2015 +0200
+++ b/debug.cpp	Wed Oct 21 12:03:43 2015 +0000
@@ -6,6 +6,9 @@
 #include "config.h"
 // all the debugging functions
 
+// #define TUNEPID  // set to switch between normal opperation or tuning PID
+// #define TUNEEMG // set hdiscope for EMG
+#define TUNEPWM // set hidscope for rest
 
 #ifdef TUNEPID
 HIDScope scope(5);
--- a/emg.cpp	Wed Oct 21 13:16:24 2015 +0200
+++ b/emg.cpp	Wed Oct 21 12:03:43 2015 +0000
@@ -14,13 +14,7 @@
 // Define program constants
 const int     on = 0;                   // On-constant for LEDs for program readability
 const int     off = 1;                  // Off-constant for LEDs for program readability
-const int     sample = 0;               // Constant for mode switching for program readability
-const int     normalize = 1;            // Constant for mode switching for program readability
-
 bool ledsEnable = false;
-//**********************************************************************************************
-bool mode               = normalize;         // Set program mode
-//**********************************************************************************************
 
 // Initialize sampling constants
 double emg_val1 = 0, emg_val2 = 0, emg_filt_val1 = 0, emg_filt_val2 = 0;
@@ -214,13 +208,14 @@
 }
 
 
-void readEMG(){
-    if(mode==normalize && normalizing_timer.read_ms() == 0) {   // Start normalizing timer
+void readEMG()
+{
+    if(emg_mode==normalize && normalizing_timer.read_ms() == 0) {   // Start normalizing timer
         normalizing_timer.reset();
         normalizing_timer.start();
     }
 
-    if(mode ==normalize) {
+    if(emg_mode ==normalize) {
         emg_val1 = emg1.read();               // Sample EMG value 1 from AnalogIn
         emg_val2 = emg2.read();               // Sample EMG value 2 from AnalogIn
 
@@ -239,7 +234,7 @@
 
         // First normalizing step: channel 1
         if (normalizing_timer.read_ms() <= normalize_time && channel == 1) {
-            if (ledsEnable){
+            if (ledsEnable) {
                 redLed.write(off);
                 greenLed.write(on);
             }
@@ -249,13 +244,13 @@
             // Second normalizing step: wait time, switch channel
         } else if (normalizing_timer.read_ms() > normalize_time && channel == 1) {
             channel = 2;
-            if (ledsEnable){
+            if (ledsEnable) {
                 greenLed.write(off);
                 redLed.write(on);
             }
             // Third normalizing step: channel 2
         } else if (normalizing_timer.read_ms() >= (normalize_time + normalize_wait) && normalizing_timer.read_ms() <= (2*normalize_time + normalize_wait) && channel == 2) {
-            if (ledsEnable){
+            if (ledsEnable) {
                 redLed.write(off);
                 greenLed.write(on);
             }
@@ -266,17 +261,17 @@
         } else if (normalizing_timer.read_ms() > (2*normalize_time + normalize_wait)) {
             normalizing_timer.stop();
             normalizing_timer.reset();
-            if (ledsEnable){
+            if (ledsEnable) {
                 greenLed.write(off);
                 redLed.write(off);
                 blueLed.write(on);
             }
-            mode = sample;
+            emg_mode = sample;
         }
     }
 
 
-    if(mode ==sample) {
+    if(emg_mode ==sample) {
         emg_val1 = emg1.read();                             // Sample EMG value 1 from AnalogIn
         emg_val2 = emg2.read();                             // Sample EMG value 2 from AnalogIn
 
@@ -303,7 +298,7 @@
             EMG_check(thr_pass1, thr_pass2, x_velocity, y_velocity, z_velocity, emg_filt_val1, emg_filt_val2, EMG_timer.read_ms());
 
         } else {
-            if (ledsEnable){
+            if (ledsEnable) {
                 greenLed.write(off);
                 redLed.write(on);
                 blueLed.write(off);
@@ -312,8 +307,5 @@
     }
 
     // Graphical output to HIDScope for debugging/ program check
-
-
-
 }
 
--- a/emg.h	Wed Oct 21 13:16:24 2015 +0200
+++ b/emg.h	Wed Oct 21 12:03:43 2015 +0000
@@ -10,6 +10,10 @@
 extern DigitalOut  greenLed;
 extern DigitalOut  blueLed;
 
+extern const int normalize;
+extern const int sample;
+extern bool emg_mode;
+
 extern const double sample_frequency; 
 
 extern const int     normalize_time;
@@ -44,5 +48,6 @@
 extern const double a12_gain, a12_a1, a12_a2, a12_b0, a12_b1, a12_b2; 
 extern const double a13_gain, a13_a1,  a13_a2, a13_b0, a13_b1, a13_b2;
 
+
 void readEMG();
 #endif
--- a/main.cpp	Wed Oct 21 13:16:24 2015 +0200
+++ b/main.cpp	Wed Oct 21 12:03:43 2015 +0000
@@ -1,10 +1,10 @@
 /*
-   ________                      ____        __          __ 
+   ________                      ____        __          __
   / ____/ /_  ___  __________   / __ \____  / /_  ____  / /_
  / /   / __ \/ _ \/ ___/ ___/  / /_/ / __ \/ __ \/ __ \/ __/
-/ /___/ / / /  __(__  |__  )  / _, _/ /_/ / /_/ / /_/ / /_  
-\____/_/ /_/\___/____/____/  /_/ |_|\____/_.___/\____/\__/  
-                                                            
+/ /___/ / / /  __(__  |__  )  / _, _/ /_/ / /_/ / /_/ / /_
+\____/_/ /_/\___/____/____/  /_/ |_|\____/_.___/\____/\__/
+
 */
 
 #include "mbed.h"
@@ -14,48 +14,85 @@
 #include "debug.h"
 #include "emg.h"
 
+const int     sample = 0;               // Constant for EMG mode switching for program readability
+const int     normalize = 1;            // Constant for EMG mode switching for program readability
+
+bool start=false;
+bool emg_mode = normalize;              // Set EMG mode
+
 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 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;
+};
 
-double motorCall = 0.01; // set motor frequency global so it can be used for speed.
-int main(){
-motorInit();    
-calibrateMotors(); // start calibration procedure
-
-switchesTick.attach(&switches_activate, 0.02f);
-debugTick.attach(&debug_activate, 0.03f);
-motorTick.attach(&motor_activate, motorCall);
-EMGTick.attach(&emg_activate, 0.005f);
-safetyTick.attach(&safety_activate, 0.001f);
-
+double motorCall = 0.005; // set motor frequency global so it can be used for speed.
+int main()
+{
+    DigitalIn startButton(startPin);
+    while(start == false) {
+        if(startButton.read()==0) {
+            start=true;
+        }
+    }
+    while (start == true) {
+        motorInit();
 
-    while (true) {
-        if(safety_go){
-            safety_go=false;
-            safety();
-        }
-        if(emg_go){
-            emg_go=false;
-            readEMG();
+        EMGTick.attach(&emg_activate, 0.005f);
+        switchesTick.attach(&switches_activate, 0.02f);
+        debugTick.attach(&debug_activate, 0.03f);
+        motorTick.attach(&motor_activate, motorCall);
+        safetyTick.attach(&safety_activate, 0.001f);
+
+        while (emg_mode == normalize) {
+            if(emg_go) {
+                emg_go=false;
+                readEMG();
+            }
         }
-        if(switches_go){
-            switches_go=false;
-            checkSwitches();
-        }
-        if(debug_go){
-            debug_go=false;
-            debugProcess();
-        }
-        if(motor_go){
-            motor_go=false;
-            motorControl();
-        // servoControl();
+
+        calibrateMotors();              // start calibration procedure
+
+        while (true) {
+            if(safety_go) {
+                safety_go=false;
+                safety();
+            }
+            if(emg_go) {
+                emg_go=false;
+                readEMG();
+            }
+            if(switches_go) {
+                switches_go=false;
+                checkSwitches();
+            }
+            if(debug_go) {
+                debug_go=false;
+                debugProcess();
+            }
+            if(motor_go) {
+                motor_go=false;
+                motorControl();
+                // servoControl();
+            }
         }
     }
 }
\ No newline at end of file