Group19-Biorobotics

Dependencies:   HIDScope MODSERIAL PID QEI SigInterpreternovember2 biquadFilter mbed

Fork of Robot_control_v3 by Fabian van Hummel

Revision:
2:6b913f93bc0b
Parent:
1:b9005f2aabf5
Child:
4:bfdcf3da7cff
diff -r b9005f2aabf5 -r 6b913f93bc0b Controller.cpp
--- a/Controller.cpp	Fri Oct 21 21:32:20 2016 +0000
+++ b/Controller.cpp	Wed Oct 26 12:37:37 2016 +0000
@@ -3,105 +3,137 @@
 
 int main() {
     calibrateButton.rise(&calibrate);
-    motorControl.attach(&setFlag, RATE);
+    motorControl.attach(&setFlag, RATE); // rate =0.001
     initMotors();
     initControllers();
+    calibrate(); // calibrate position
     calibratePower(); // store max amplitude each emg signal
     run();
 }
 
 void run() {
     while(true){
-        double r = signal.readValue(1); // returns filtered value
-        double l = signal.readValue(2);
-        double u = signal.readValue(3);
-        double d = signal.readValue(4);
-        
-        // calculate r,l,u,d in a % of max 
-        double percentageR = r/rMax;
-        double percentageL = l/lMax;
-        double percentageU = u/uMax;
-        double percentageD = d/dMax;
-        
+        if(flag){
+            // returns filtered value
+            r += signal.readValue(1)/SAMPLES_PER_AVERAGE;
+            l += signal.readValue(2)/SAMPLES_PER_AVERAGE;
+            u += signal.readValue(3)/SAMPLES_PER_AVERAGE;
+            d += signal.readValue(4)/SAMPLES_PER_AVERAGE;
+            }
+            if(i=10){ // the filtering works on a frequency which is 10 times higher
+                
+            // calculate r,l,u,d in a % of max 
+            double percentageR = r/rMax;
+            double percentageL = l/lMax;
+            double percentageU = u/uMax;
+            double percentageD = d/dMax;
+            
+            double minXThreshold;
+            double minYThreshold;
+            
+            r=0; l=0; u=0; d=0;
+                // setting the flag here will cause the edge detection to be ignored if the flag is false for some reason
+                // ignore the weaker signal,motorValue calculation, threshold set
+        } 
         
-        if (flag) { // setting the flag here will cause the edge detection to be ignored if the flag is false for some reason
-            // ignore the weaker signal,motorValue calculation, threshold set
-            if ( percentageR > percentageL){ // horizontal speed request
-                motorValueHor = percentageR;
-                minHorThreshold = 0.2*rMax; // set the threshold
-            } else {motorValueHor = -percentageL;
-                  minHorThreshold = 0.2*lMax;
-              }
+        if ( percentageR > percentageL){ // horizontal speed request
+                motorValueX = percentageR;
+                minXThreshold = 0.2f*rMax; // set the threshold
+            }   else {motorValueX = -percentageL;
+                    minXThreshold = 0.2f*lMax;
+                }
             if (percentageU > percentageD) { // vertical speed request
-                motorValueVer = percentageU;
-                minVerThreshold = 0.2*uMax;
-            } else {motorValueVer = -percentageD;
-                  minVerThreshold = 0.2*uMax;
-              }
-            // current pulses and prevpulses calculated
-            x += (pulses.getDistanceHor() - prevX); // in pulses
-            prevX = x;
-            y += (pulses.getDistanceVer() - prevY);
-            prevY = y;
+                motorValueY = percentageU;
+                minYThreshold = 0.2f*uMax;
+            }   else {motorValueY = -percentageD;
+                    minYThreshold = 0.2f*dMax;
+                }
+            // current pulses
+            xPulses = pulses.getDistanceX(); // in pulses
+            yPulses = pulses.getDistanceY();
             
             //edge detection
-            if (x > x_max && motorValueHor > 0) { // right should correspond to positive motorvalue
-                motorValueHor = 0;
+            if (xPulses > (x_max-margin) && motorValueX > 0) { // right should correspond to positive motorvalue
+                motorValueX = 0;
             }
-            if (x < 0 && motorValueHor < 0) { // carefulwith 0 pulses, maybe implement margin
-                motorValueHor = 0;
+            if (xPulses < margin && motorValueX < 0) { 
+                motorValueX = 0;
             }
-            if (y > y_max && motorValueVer > 0) { // up should correspond to positive motorvalue
-                motorValueVer = 0;
+            if (yPulses > (y_max-margin) && motorValueY > 0) { // up should correspond to positive motorvalue
+                motorValueY = 0;
             }
-            if (y < 0 && motorValueVer < 0) {
-                motorValueVer =0;
+            if (yPulses < margin && motorValueY < 0) {
+                motorValueY =0;
             } 
             
             // Quantize the linear speed request
             // motorValue is a value [-1,1], currently only 0 or 1/-1
-            if (motorValueHor > maxHorValue){motorValueHor = maxHorValue;} // safety
-            if (motorValueHor < -maxHorValue){motorValueHor = -maxHorValue;}
-            if (motorValueHor > minHorThreshold && motorValueHor < maxHorValue){motorValueHor = maxHorValue;} // if threshold is met pwm is 100%, maybe quantize here
-            if (motorValueHor < -minHorThreshold && motorValueHor > -maxHorValue){motorValueHor = -maxHorValue;}
+            if (motorValueX > maxXValue){motorValueX = maxXValue;} // safety
+            if (motorValueX < -maxXValue){motorValueX = -maxXValue;}
+            if (motorValueX > minXThreshold && motorValueX < maxXValue){motorValueX = maxXValue;} // if threshold is met pwm is 100%, maybe quantize here
+            if (motorValueX < -minXThreshold && motorValueX > -maxXValue){motorValueX = -maxXValue;}
                 
-            if (motorValueVer > maxVerValue){motorValueVer = maxVerValue;}
-            if (motorValueVer < -maxVerValue){motorValueVer = -maxVerValue;}
-            if (motorValueVer > minVerThreshold && motorValueVer < maxVerValue){motorValueVer = maxVerValue;}
-            if (motorValueVer < -minVerThreshold && motorValueVer > -maxVerValue){motorValueVer = -maxVerValue;}
+            if (motorValueY > maxYValue){motorValueY = maxYValue;}
+            if (motorValueY < -maxYValue){motorValueY = -maxYValue;}
+            if (motorValueY > minYThreshold && motorValueY < maxYValue){motorValueY = maxYValue;}
+            if (motorValueY < -minYThreshold && motorValueY > -maxYValue){motorValueY = -maxYValue;}
+            
+
+            // current position of pen in Meters
+            float currentX = (pulses.getDistanceX()/(8400.0f))*(2*PI)*RmX;
+            float currentY = (pulses.getDistanceY()/(8400.0f))*(2*PI)*Rpulley; 
             
-            //current position of pen in degrees
-            currentXangle = 360.0f*(pulses.getDistanceHor()/8400);
-            currentYangle = 360.0f*(pulses.getDistanceVer()/8400); 
+            // upcoming position of pen in Meters
+            //toX = currentX + motorValueX*maxSpeed*RATE; // speed is in m/s rate is in s
+            //toY = currentY + motorValueY*maxSpeed*RATE; 
+            
+            // distance it should travel for 1 interval in Meters 
+            float deltaX = motorValueX*maxSpeed*RATE;
+            float deltaY = motorValueY*maxSpeed*RATE;
             
-            // current position of pen in cm
-            currentX = (360.0f/(2*PI))*(pulses.getDistanceHor()/8400)*(RmHor/R1); // radiants*revolutions*gearratio is x pos in rad IS RAD EQUAL TO CM?????????
-            currentY= (360.0f/(2*PI))*(pulses.getDistanceVer()/8400); // radiants*revolutions 1:1 ratio??
+            // desired velocity in m/s for this interval
+            float toVelX = deltaX/RATE; 
+            float toVelY = deltaY/RATE;
+            
+            // set setpoint of PID controller, this is the thing you want
+            X_Controller.setSetPoint(toVelX);
+            Y_Controller.setSetPoint(toVelY);
             
-            // desired position of pen in cm
-            toX = currentX + motorValueHor*maxSpeed*RATE;
-            toY = currentY + motorValueVer*maxSpeed*RATE; 
+            // current velocity in M/s, the thing you measure
+            // horizontal motor
+            float currVelX = (currentX - prevX)/RATE;
+            prevX = currentX;
+            X_Controller.setProcessValue(currVelX);
             
-            // desired angle of pen in degrees
-            toangleX = ((toX-currentX)*(R1/RmHor))*(360.0f/(2*PI)); 
-            toangleY = (toX-currentX)*(360.0f/(2*PI)); 
+            //vertical motor
+            float currVelY = (currentY - prevY)/RATE;
+            prevY = currentY;
+            Y_Controller.setProcessValue(currVelY);
             
-            //requested velocities in degrees/sec
-            Xvelrequest = (toangleX - currentXangle) / RATE; 
-            Yvelrequest = (toangleY - currentYangle) / RATE;
-            
-            // set setpoint of PID controller here with velrequest, what are the input limits???
-            
-            // Calculate current rotational velocity
-            
-            // give the PID controller the processvariable
-            
-            // compute PID
-            
-            // output to motor
+                // compute the output FIXME[calibratebutton might break the program]
+                float X_MotorOutput = X_Controller.compute();
+                if (X_MotorOutput > 0){ // right request
+                    X_Direction.write(CW);
+                    X_Magnitude.write(X_MotorOutput); // must be value between 0 and 1
+                }   else {
+                        X_Direction.write(!CW); // left request
+                        X_Magnitude.write(-X_MotorOutput);
+                    }
+                        
+                float Y_MotorOutput = Y_Controller.compute();
+                if (Y_MotorOutput > 0){ // up request
+                    Y_Direction.write(CW);
+                    Y_Magnitude.write(Y_MotorOutput);
+                }   else {
+                        Y_Direction.write(!CW); // down request
+                        Y_Magnitude.write(-Y_MotorOutput);
+                    }
+            }
            
            // output to hidscope
+           
             flag = false; // only output to motor with RATE
+            i = 1;
         }
         
     }
@@ -109,30 +141,39 @@
 
 void setFlag() {
     flag = true;
-}
-
-void emergencyExit() {
-    calibrate();
-    run();
+    i++;
 }
 
 void calibrate() {
-    while ((pulses.getDistanceHor() > margin) && (pulses.getDistanceVer() > margin)){
-        if (pulses.getDistanceHor() > margin){
+    motorControl.detach();
+    calibrateFlag = false;
+    // GO-TO pos (0,0)
+    while ((pulses.getDistanceX() > margin) && (pulses.getDistanceY() > margin)){
+        if (pulses.getDistanceX() > margin){
         // go direction LEFT
-        }
-        else { //motormaghor 0    
-        }
-        if (pulses.getDistanceVer() > margin){
+        X_Direction.write(!CW);
+        X_Magnitude.write(1.0);
+        }   else { //motormagX 0 
+            X_Direction.write(CW);
+            X_Magnitude.write(0.0);   
+            }
+        if (pulses.getDistanceY() > margin){
         // go direction DOWN
-        }
-        else { //motormagver 0}     
-        }
-        // GO-TO pos (0,0)
-        // pulses can only be 0 or positive so reverse the direction until 0 pulses is reached
+        Y_Direction.write(!CW);
+        Y_Magnitude.write(1.0);
+        }   else { //motormagY 0  
+            Y_Direction.write(CW);
+            Y_Magnitude.write(0.0);   
+            }
         // problem with the interrupt button, after calibration the program should re-start the run function instead of going further at the point it left
         // this will cause 1 iteration to be absolutely wrong -> consequences?
+
     }
+    prevX = getDistanceX();
+    prevY = getDistanceY();
+    r=0; l=0; u=0; d=0;
+    i=0;
+    motorControl.attach(&setFlag, RATE); 
 }   
  
 void calibratePower(){