Group19-Biorobotics

Dependencies:   HIDScope MODSERIAL PID QEI SigInterpreternovember2 biquadFilter mbed

Fork of Robot_control_v3 by Fabian van Hummel

Committer:
AlexGroup19
Date:
Mon Nov 07 11:29:28 2016 +0000
Revision:
8:82e38f4aa690
Parent:
6:a4440eec3652
Group19-Biorobotics

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fabian101 0:d935ea6f5c25 1 #include "Controller.h"
fabian101 1:b9005f2aabf5 2
fabian101 0:d935ea6f5c25 3 int main() {
fabian101 6:a4440eec3652 4 pc.baud(115200);
fabian101 1:b9005f2aabf5 5 initMotors();
fabian101 1:b9005f2aabf5 6 initControllers();
fabian101 6:a4440eec3652 7 calibratePower(); // store max amplitude each emg signal
fabian101 6:a4440eec3652 8
fabian101 4:bfdcf3da7cff 9 while(true)
fabian101 4:bfdcf3da7cff 10 {
fabian101 6:a4440eec3652 11 calibrate(); // calibrate position
fabian101 4:bfdcf3da7cff 12 while(!button){} // button not pressed is true, this is here to make sure that the it will only go run if you have let go of the button and calibrated
fabian101 4:bfdcf3da7cff 13 run();
fabian101 4:bfdcf3da7cff 14 }
fabian101 0:d935ea6f5c25 15 }
fabian101 0:d935ea6f5c25 16
fabian101 4:bfdcf3da7cff 17 void run()
fabian101 4:bfdcf3da7cff 18 {
fabian101 4:bfdcf3da7cff 19 motorControl.attach(&setUpdate_flag, RATE); // rate =0.001
fabian101 4:bfdcf3da7cff 20 while(button) // button not presseed
fabian101 4:bfdcf3da7cff 21 {
fabian101 6:a4440eec3652 22 if(update_flag) //
fabian101 6:a4440eec3652 23 {
fabian101 2:6b913f93bc0b 24 // returns filtered value
fabian101 6:a4440eec3652 25 r = signal.readValue(1);
AlexGroup19 8:82e38f4aa690 26 l = signal.readValue(2);
AlexGroup19 8:82e38f4aa690 27 u = signal.readValue(3);
AlexGroup19 8:82e38f4aa690 28 d = signal.readValue(4);
fabian101 4:bfdcf3da7cff 29
AlexGroup19 8:82e38f4aa690 30 pc.printf("r : %f \n\r", r);
AlexGroup19 8:82e38f4aa690 31 pc.printf("l : %f \n\r", l);
fabian101 6:a4440eec3652 32 // calculate r,l,u,d relative to the max [0,1]
fabian101 6:a4440eec3652 33 percentageR = r/rMax;
fabian101 6:a4440eec3652 34 percentageL = l/lMax;
fabian101 6:a4440eec3652 35 percentageU = u/uMax;
fabian101 6:a4440eec3652 36 percentageD = d/dMax;
AlexGroup19 8:82e38f4aa690 37
fabian101 4:bfdcf3da7cff 38 // ignore the weaker signal,motorValue calculation, threshold set
fabian101 4:bfdcf3da7cff 39 if ( percentageR > percentageL)
fabian101 4:bfdcf3da7cff 40 { // horizontal speed request
fabian101 2:6b913f93bc0b 41 motorValueX = percentageR;
fabian101 4:bfdcf3da7cff 42 }
fabian101 4:bfdcf3da7cff 43 else
fabian101 4:bfdcf3da7cff 44 {
fabian101 4:bfdcf3da7cff 45 motorValueX = -percentageL;
fabian101 4:bfdcf3da7cff 46 }
AlexGroup19 8:82e38f4aa690 47
fabian101 4:bfdcf3da7cff 48 if (percentageU > percentageD) // vertical speed request
fabian101 4:bfdcf3da7cff 49 {
fabian101 2:6b913f93bc0b 50 motorValueY = percentageU;
AlexGroup19 8:82e38f4aa690 51 }
AlexGroup19 8:82e38f4aa690 52
fabian101 4:bfdcf3da7cff 53 else
fabian101 4:bfdcf3da7cff 54 {
fabian101 4:bfdcf3da7cff 55 motorValueY = -percentageD;
fabian101 4:bfdcf3da7cff 56 }
fabian101 6:a4440eec3652 57
fabian101 2:6b913f93bc0b 58 // current pulses
fabian101 4:bfdcf3da7cff 59 xPulses = X_Motor.getPulses();
fabian101 4:bfdcf3da7cff 60 yPulses = Y_Motor.getPulses();
AlexGroup19 8:82e38f4aa690 61
fabian101 1:b9005f2aabf5 62 //edge detection
fabian101 6:a4440eec3652 63 if ((xPulses > (x_max-margin)) && (motorValueX > sensitivityFactor)) // (x_max-margin
fabian101 4:bfdcf3da7cff 64 { // right should correspond to positive motorvalue
fabian101 2:6b913f93bc0b 65 motorValueX = 0;
fabian101 1:b9005f2aabf5 66 }
fabian101 6:a4440eec3652 67 if ((xPulses < margin) && (motorValueX < (-1 * sensitivityFactor)))
fabian101 4:bfdcf3da7cff 68 {
fabian101 2:6b913f93bc0b 69 motorValueX = 0;
fabian101 0:d935ea6f5c25 70 }
fabian101 6:a4440eec3652 71 if ((yPulses > (y_max-margin)) && (motorValueY > sensitivityFactor))
fabian101 4:bfdcf3da7cff 72 { // up should correspond to positive motorvalue
fabian101 2:6b913f93bc0b 73 motorValueY = 0;
fabian101 0:d935ea6f5c25 74 }
AlexGroup19 8:82e38f4aa690 75 if ((yPulses < margin) && (motorValueY < ((-1) * sensitivityFactor)))
fabian101 4:bfdcf3da7cff 76 {
AlexGroup19 8:82e38f4aa690 77 motorValueY = 0;
fabian101 1:b9005f2aabf5 78 }
fabian101 1:b9005f2aabf5 79 // Quantize the linear speed request
AlexGroup19 8:82e38f4aa690 80 // motorValue is a value [-1,1], currently only 0 or 1/-1
AlexGroup19 8:82e38f4aa690 81
AlexGroup19 8:82e38f4aa690 82 //pc.printf("X_MotorValue : %f \n\r", motorValueX);
AlexGroup19 8:82e38f4aa690 83 if (motorValueX >= maxXValue){motorValueX = maxXValue;} // boundary for the motor value
AlexGroup19 8:82e38f4aa690 84 else if (motorValueX <= -maxXValue){motorValueX = -maxXValue;}
AlexGroup19 8:82e38f4aa690 85 else if ((motorValueX >= sensitivityFactor) && (motorValueX < maxXValue)){motorValueX = maxXValue;} // if threshold is met go a fixed speed%, we could quantize here
AlexGroup19 8:82e38f4aa690 86 else if ((motorValueX <= -sensitivityFactor) && (motorValueX > -maxXValue)){motorValueX = -maxXValue;}
AlexGroup19 8:82e38f4aa690 87 else {motorValueX = 0;}
AlexGroup19 8:82e38f4aa690 88
fabian101 6:a4440eec3652 89 if (motorValueY >= maxYValue){motorValueY = maxYValue;}
AlexGroup19 8:82e38f4aa690 90 else if (motorValueY <= -maxYValue){motorValueY = -maxYValue;}
AlexGroup19 8:82e38f4aa690 91 else if ((motorValueY >= sensitivityFactor) && (motorValueY < maxYValue)){motorValueY = maxYValue;}
AlexGroup19 8:82e38f4aa690 92 else if ((motorValueY <= -sensitivityFactor) && (motorValueY > -maxYValue)){motorValueY = -maxYValue;}
AlexGroup19 8:82e38f4aa690 93 else {motorValueY = 0;}
AlexGroup19 8:82e38f4aa690 94
AlexGroup19 8:82e38f4aa690 95
AlexGroup19 8:82e38f4aa690 96
fabian101 2:6b913f93bc0b 97 // current position of pen in Meters
fabian101 6:a4440eec3652 98 float currentX = (xPulses/(8400.0f))*(2*PI)*RmX;
fabian101 6:a4440eec3652 99 float currentY = (yPulses/(8400.0f))*(2*PI)*Rpulley;
fabian101 1:b9005f2aabf5 100
fabian101 2:6b913f93bc0b 101 // upcoming position of pen in Meters
fabian101 2:6b913f93bc0b 102 //toX = currentX + motorValueX*maxSpeed*RATE; // speed is in m/s rate is in s
fabian101 2:6b913f93bc0b 103 //toY = currentY + motorValueY*maxSpeed*RATE;
fabian101 2:6b913f93bc0b 104
fabian101 2:6b913f93bc0b 105 // distance it should travel for 1 interval in Meters
fabian101 2:6b913f93bc0b 106 float deltaX = motorValueX*maxSpeed*RATE;
fabian101 2:6b913f93bc0b 107 float deltaY = motorValueY*maxSpeed*RATE;
AlexGroup19 8:82e38f4aa690 108
fabian101 2:6b913f93bc0b 109 // desired velocity in m/s for this interval
AlexGroup19 8:82e38f4aa690 110 float toVelX = deltaX/RATE;
fabian101 2:6b913f93bc0b 111 float toVelY = deltaY/RATE;
AlexGroup19 8:82e38f4aa690 112
fabian101 2:6b913f93bc0b 113 // set setpoint of PID controller, this is the thing you want
fabian101 2:6b913f93bc0b 114 X_Controller.setSetPoint(toVelX);
fabian101 2:6b913f93bc0b 115 Y_Controller.setSetPoint(toVelY);
fabian101 0:d935ea6f5c25 116
fabian101 2:6b913f93bc0b 117 // current velocity in M/s, the thing you measure
fabian101 2:6b913f93bc0b 118 // horizontal motor
fabian101 2:6b913f93bc0b 119 float currVelX = (currentX - prevX)/RATE;
fabian101 2:6b913f93bc0b 120 prevX = currentX;
fabian101 2:6b913f93bc0b 121 X_Controller.setProcessValue(currVelX);
fabian101 1:b9005f2aabf5 122
fabian101 2:6b913f93bc0b 123 //vertical motor
fabian101 2:6b913f93bc0b 124 float currVelY = (currentY - prevY)/RATE;
fabian101 2:6b913f93bc0b 125 prevY = currentY;
fabian101 2:6b913f93bc0b 126 Y_Controller.setProcessValue(currVelY);
AlexGroup19 8:82e38f4aa690 127
AlexGroup19 8:82e38f4aa690 128
AlexGroup19 8:82e38f4aa690 129
fabian101 1:b9005f2aabf5 130
fabian101 4:bfdcf3da7cff 131 // compute the output
AlexGroup19 8:82e38f4aa690 132 float X_MotorOutput = 9 * X_Controller.compute();
AlexGroup19 8:82e38f4aa690 133 //pc.printf("X_MotorOutput : %f \n\r", X_MotorOutput);
AlexGroup19 8:82e38f4aa690 134
AlexGroup19 8:82e38f4aa690 135 if (X_MotorOutput > maxSpeed) //
fabian101 4:bfdcf3da7cff 136 { // right request
fabian101 4:bfdcf3da7cff 137 X_Direction.write(CW);
AlexGroup19 8:82e38f4aa690 138 X_Magnitude.write(maxSpeed); //
fabian101 4:bfdcf3da7cff 139 }
AlexGroup19 8:82e38f4aa690 140 else if (X_MotorOutput <= -maxSpeed)
fabian101 4:bfdcf3da7cff 141 {
fabian101 4:bfdcf3da7cff 142 X_Direction.write(!CW); // left request
AlexGroup19 8:82e38f4aa690 143 X_Magnitude.write(maxSpeed); //motor output will be negative and you need to write a pos value
AlexGroup19 8:82e38f4aa690 144 }
AlexGroup19 8:82e38f4aa690 145 else if ((X_MotorOutput < maxSpeed) && (X_MotorOutput > sensitivityFactor))
AlexGroup19 8:82e38f4aa690 146 {
AlexGroup19 8:82e38f4aa690 147 X_Magnitude.write(X_MotorOutput);
AlexGroup19 8:82e38f4aa690 148 X_Direction.write(CW);
fabian101 2:6b913f93bc0b 149 }
AlexGroup19 8:82e38f4aa690 150
AlexGroup19 8:82e38f4aa690 151 else if ((X_MotorOutput > -maxSpeed) && (X_MotorOutput < -sensitivityFactor))
AlexGroup19 8:82e38f4aa690 152 {
AlexGroup19 8:82e38f4aa690 153 X_Magnitude.write(X_MotorOutput);
AlexGroup19 8:82e38f4aa690 154 X_Direction.write(!CW);
AlexGroup19 8:82e38f4aa690 155 }
AlexGroup19 8:82e38f4aa690 156 else
fabian101 6:a4440eec3652 157 {
fabian101 6:a4440eec3652 158 X_Magnitude.write(0);
AlexGroup19 8:82e38f4aa690 159 }
AlexGroup19 8:82e38f4aa690 160
AlexGroup19 8:82e38f4aa690 161
AlexGroup19 8:82e38f4aa690 162 float Y_MotorOutput = 9 * Y_Controller.compute();
AlexGroup19 8:82e38f4aa690 163 if (Y_MotorOutput > maxSpeed) //
AlexGroup19 8:82e38f4aa690 164 { // right request
AlexGroup19 8:82e38f4aa690 165 Y_Direction.write(CW);
AlexGroup19 8:82e38f4aa690 166 Y_Magnitude.write(maxSpeed); //
AlexGroup19 8:82e38f4aa690 167 }
AlexGroup19 8:82e38f4aa690 168 else if (Y_MotorOutput <= -maxSpeed)
AlexGroup19 8:82e38f4aa690 169 {
AlexGroup19 8:82e38f4aa690 170 Y_Direction.write(!CW); // left request
AlexGroup19 8:82e38f4aa690 171 Y_Magnitude.write(maxSpeed); //motor output will be negative and you need to write a pos value
AlexGroup19 8:82e38f4aa690 172 }
AlexGroup19 8:82e38f4aa690 173 else if ((Y_MotorOutput < maxSpeed) && (Y_MotorOutput > sensitivityFactor))
AlexGroup19 8:82e38f4aa690 174 {
AlexGroup19 8:82e38f4aa690 175 Y_Magnitude.write(Y_MotorOutput);
AlexGroup19 8:82e38f4aa690 176 Y_Direction.write(CW);
fabian101 6:a4440eec3652 177 }
fabian101 6:a4440eec3652 178
AlexGroup19 8:82e38f4aa690 179
AlexGroup19 8:82e38f4aa690 180 else if ((Y_MotorOutput > -maxSpeed) && (Y_MotorOutput < -sensitivityFactor))
AlexGroup19 8:82e38f4aa690 181 {
fabian101 4:bfdcf3da7cff 182 Y_Magnitude.write(Y_MotorOutput);
AlexGroup19 8:82e38f4aa690 183 Y_Direction.write(!CW);
fabian101 4:bfdcf3da7cff 184 }
AlexGroup19 8:82e38f4aa690 185
AlexGroup19 8:82e38f4aa690 186 else
fabian101 6:a4440eec3652 187 {
fabian101 6:a4440eec3652 188 Y_Magnitude.write(0);
fabian101 6:a4440eec3652 189 }
AlexGroup19 8:82e38f4aa690 190
fabian101 6:a4440eec3652 191 update_flag = false;
AlexGroup19 8:82e38f4aa690 192
fabian101 0:d935ea6f5c25 193 }
fabian101 0:d935ea6f5c25 194 }
fabian101 6:a4440eec3652 195 motorControl.detach();
fabian101 0:d935ea6f5c25 196 }
fabian101 0:d935ea6f5c25 197
fabian101 4:bfdcf3da7cff 198 void setUpdate_flag() {
fabian101 4:bfdcf3da7cff 199 update_flag = true;
fabian101 1:b9005f2aabf5 200 }
fabian101 1:b9005f2aabf5 201
fabian101 1:b9005f2aabf5 202 void calibrate() {
fabian101 6:a4440eec3652 203
fabian101 2:6b913f93bc0b 204 // GO-TO pos (0,0)
fabian101 6:a4440eec3652 205 while ((X_Motor.getPulses() > margin) || (Y_Motor.getPulses() > margin)){
fabian101 6:a4440eec3652 206 float pulses = X_Motor.getPulses();
fabian101 6:a4440eec3652 207 printf("pulsesX : %f\n\r", pulses);
AlexGroup19 8:82e38f4aa690 208
fabian101 6:a4440eec3652 209 if (X_Motor.getPulses() > margin)
fabian101 6:a4440eec3652 210 {
fabian101 1:b9005f2aabf5 211 // go direction LEFT
fabian101 6:a4440eec3652 212 X_Direction.write(!CW);
AlexGroup19 8:82e38f4aa690 213 X_Magnitude.write(calibrationSpeed); // 8 RPM with no load, maybe compensate for internal friction
fabian101 6:a4440eec3652 214 }
fabian101 6:a4440eec3652 215 else
fabian101 6:a4440eec3652 216 { //motormagX 0
fabian101 2:6b913f93bc0b 217 X_Direction.write(CW);
fabian101 2:6b913f93bc0b 218 X_Magnitude.write(0.0);
fabian101 6:a4440eec3652 219 }
fabian101 6:a4440eec3652 220 if (Y_Motor.getPulses() > margin)
fabian101 6:a4440eec3652 221 {
fabian101 1:b9005f2aabf5 222 // go direction DOWN
fabian101 6:a4440eec3652 223 Y_Direction.write(!CW);
AlexGroup19 8:82e38f4aa690 224 Y_Magnitude.write(calibrationSpeed);
fabian101 6:a4440eec3652 225 }
fabian101 6:a4440eec3652 226 else
fabian101 6:a4440eec3652 227 { //motormagY 0
fabian101 2:6b913f93bc0b 228 Y_Direction.write(CW);
fabian101 2:6b913f93bc0b 229 Y_Magnitude.write(0.0);
fabian101 6:a4440eec3652 230 }
fabian101 1:b9005f2aabf5 231 }
fabian101 4:bfdcf3da7cff 232 prevX = (X_Motor.getPulses()/(8400.0f))*(2*PI)*RmX;
fabian101 4:bfdcf3da7cff 233 prevY = (X_Motor.getPulses()/(8400.0f))*(2*PI)*Rpulley;
fabian101 1:b9005f2aabf5 234 }
fabian101 1:b9005f2aabf5 235
fabian101 6:a4440eec3652 236 void calibratePower(){
fabian101 6:a4440eec3652 237 motorControl.attach(&setUpdate_flag, RATE);
fabian101 6:a4440eec3652 238 led = false; // contract now, false = on
fabian101 6:a4440eec3652 239 while (counter < 3000) // get 3000 samples for the max
fabian101 6:a4440eec3652 240 {
fabian101 6:a4440eec3652 241 if(update_flag)
fabian101 4:bfdcf3da7cff 242 {
fabian101 6:a4440eec3652 243 float rCal = signal.readValue(1);
fabian101 6:a4440eec3652 244 if ( rCal > rMax)
fabian101 6:a4440eec3652 245 {
fabian101 6:a4440eec3652 246 rMax = rCal;
fabian101 6:a4440eec3652 247 }
fabian101 6:a4440eec3652 248
fabian101 6:a4440eec3652 249 float lCal = signal.readValue(2);
fabian101 6:a4440eec3652 250 if ( lCal > lMax)
fabian101 6:a4440eec3652 251 {
fabian101 6:a4440eec3652 252 lMax = lCal;
fabian101 6:a4440eec3652 253 }
AlexGroup19 8:82e38f4aa690 254
fabian101 6:a4440eec3652 255 float uCal = signal.readValue(3);
fabian101 6:a4440eec3652 256 if ( uCal > uMax)
fabian101 6:a4440eec3652 257 {
fabian101 6:a4440eec3652 258 uMax = uCal;
fabian101 6:a4440eec3652 259 }
fabian101 6:a4440eec3652 260 float dCal = signal.readValue(4);
fabian101 6:a4440eec3652 261 if ( dCal > dMax)
fabian101 6:a4440eec3652 262 {
fabian101 6:a4440eec3652 263 dMax = dCal;
fabian101 6:a4440eec3652 264 }
AlexGroup19 8:82e38f4aa690 265 counter++;
fabian101 6:a4440eec3652 266 update_flag = false;
fabian101 6:a4440eec3652 267 }
fabian101 1:b9005f2aabf5 268 }
fabian101 6:a4440eec3652 269 counter = 0;
fabian101 6:a4440eec3652 270 pc.printf("rMax : %f\n\r", rMax);
fabian101 6:a4440eec3652 271 pc.printf("lMax : %f\n\r", lMax);
fabian101 6:a4440eec3652 272 motorControl.detach();
fabian101 6:a4440eec3652 273 led = true;
fabian101 1:b9005f2aabf5 274 }