Version for EMG Threshold finding

Dependencies:   HIDScope MODSERIAL QEI biquadFilter mbed

Fork of prog_BioRobotics_Group9_StampRobot by Gerhard Berman

Committer:
GerhardBerman
Date:
Thu Nov 03 18:56:09 2016 +0000
Revision:
41:68b170829965
Parent:
40:9ecaab27acde
Child:
42:a080925eabf8
Child:
43:2b2e0bff0b39
ROBOT WORKING GOOD, only a little slow movements ;)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
GerhardBerman 0:43160ef59f9f 1 #include "mbed.h"
GerhardBerman 0:43160ef59f9f 2 #include <math.h>
GerhardBerman 0:43160ef59f9f 3 #include "MODSERIAL.h"
GerhardBerman 0:43160ef59f9f 4 #include "QEI.h"
GerhardBerman 0:43160ef59f9f 5 #include "HIDScope.h"
GerhardBerman 0:43160ef59f9f 6 #include "BiQuad.h"
GerhardBerman 0:43160ef59f9f 7
GerhardBerman 17:91d20d362e72 8 /*
GerhardBerman 17:91d20d362e72 9 THINGS TO CONSIDER
GerhardBerman 17:91d20d362e72 10 - Line 234, 239: motor action of motor 1 is inverted because it is mounted
GerhardBerman 17:91d20d362e72 11 opposite to motor 2 in the tower. Check if the clockwise directions of the
GerhardBerman 17:91d20d362e72 12 motors correspond to the positive q1, q2-directions (both counterclockwise)
GerhardBerman 17:91d20d362e72 13 in the original IK-sketch.
GerhardBerman 17:91d20d362e72 14 - Line 244,257: motor values have been scaled down for safety at first test, restore
GerhardBerman 17:91d20d362e72 15 after testing to get proper action.
GerhardBerman 19:cba54636bd62 16 - Set angle and length boundaries!!
GerhardBerman 17:91d20d362e72 17 - Set robot constants (lengths etc.)
GerhardBerman 18:d2cfd07ae88a 18 - Set EMGgain and thresholds
GerhardBerman 23:3a4d5e19c20d 19 - Add tower height to ReferencePosition_y and Position_y AND inverse kinematics calculation!
GerhardBerman 22:c679f753a8bd 20 - Add (lower) boundaries to TotalErrors
GerhardBerman 22:c679f753a8bd 21 - MotorGain could change due to arm weight!!
GerhardBerman 22:c679f753a8bd 22 - Arms should be placed manually into reference position.
GerhardBerman 17:91d20d362e72 23 */
GerhardBerman 17:91d20d362e72 24
GerhardBerman 0:43160ef59f9f 25 //set pins
GerhardBerman 0:43160ef59f9f 26 DigitalIn encoder1A (D13); //Channel A van Encoder 1
GerhardBerman 0:43160ef59f9f 27 DigitalIn encoder1B (D12); //Channel B van Encoder 1
GerhardBerman 14:725a608b6709 28 DigitalIn encoder2A (D11); //Channel A van Encoder 2, kan niet op D15
GerhardBerman 14:725a608b6709 29 DigitalIn encoder2B (D10); //Channel B van Encoder 2, kan niet op D14
GerhardBerman 14:725a608b6709 30 //DigitalOut led1 (D11);
GerhardBerman 14:725a608b6709 31 //DigitalOut led2 (D10);
GerhardBerman 19:cba54636bd62 32 //AnalogIn potMeter1(A2);
GerhardBerman 19:cba54636bd62 33 //AnalogIn potMeter2(A1);
GerhardBerman 0:43160ef59f9f 34 DigitalOut motor1DirectionPin(D7);
GerhardBerman 0:43160ef59f9f 35 PwmOut motor1MagnitudePin(D6);
GerhardBerman 7:2f74dfd1d411 36 DigitalOut motor2DirectionPin(D4);
GerhardBerman 7:2f74dfd1d411 37 PwmOut motor2MagnitudePin(D5);
GerhardBerman 9:e4c34f5665a0 38 DigitalIn button1(D3);
GerhardBerman 7:2f74dfd1d411 39 DigitalIn button2(D9);
GerhardBerman 41:68b170829965 40 AnalogIn emg0( A0 );
GerhardBerman 41:68b170829965 41 AnalogIn emg1( A1 );
GerhardBerman 0:43160ef59f9f 42
GerhardBerman 41:68b170829965 43 DigitalOut ledGrn(LED_GREEN);
GerhardBerman 41:68b170829965 44 DigitalOut ledRed(LED_RED);
GerhardBerman 41:68b170829965 45 DigitalOut ledBlue(LED_BLUE);
GerhardBerman 33:b09608fa69e9 46
GerhardBerman 7:2f74dfd1d411 47 //library settings
GerhardBerman 0:43160ef59f9f 48 Serial pc(USBTX,USBRX);
GerhardBerman 3:8caef4872b0c 49 Ticker MeasureTicker, BiQuadTicker; //, TimeTracker; // sampleT;
GerhardBerman 41:68b170829965 50 HIDScope scope(6);
GerhardBerman 0:43160ef59f9f 51
GerhardBerman 26:bb7e14f59ddd 52 //initial values
GerhardBerman 7:2f74dfd1d411 53 float dx;
GerhardBerman 7:2f74dfd1d411 54 float dy;
GerhardBerman 23:3a4d5e19c20d 55 double DerivativeCounts;
GerhardBerman 19:cba54636bd62 56 //float referenceVelocity = 0;
GerhardBerman 19:cba54636bd62 57 //float bqcDerivativeCounts = 0;
GerhardBerman 3:8caef4872b0c 58 const float PI = 3.141592653589793;
GerhardBerman 3:8caef4872b0c 59 const int cw = 0; //values for cw and ccw are inverted!! cw=0 and ccw=1
GerhardBerman 3:8caef4872b0c 60 const int ccw = 1;
GerhardBerman 0:43160ef59f9f 61
GerhardBerman 26:bb7e14f59ddd 62 //set lengths (VALUES HAVE TO BE CHANGED)
GerhardBerman 36:72f0913c5460 63 //float x0 = 1.0;
GerhardBerman 36:72f0913c5460 64 float L0 = 0.232;
GerhardBerman 36:72f0913c5460 65 float L1 = 0.45;
GerhardBerman 36:72f0913c5460 66 float L2 = 0.35;
GerhardBerman 36:72f0913c5460 67 float TowerHeight = 0.232; //height of motor axes above table surface!
GerhardBerman 39:cc7754330c26 68 float StampHeight = 0.056; // height of end effector
GerhardBerman 34:96bcbddc7d2d 69 float y_stampup = 0.1; //height stamp while not stamping: 10cm above table surface
GerhardBerman 41:68b170829965 70 float y_stampdown = -0.04; //height stamp while stamping: at table surface
GerhardBerman 34:96bcbddc7d2d 71
GerhardBerman 26:bb7e14f59ddd 72
GerhardBerman 19:cba54636bd62 73 //set initial conditions
GerhardBerman 19:cba54636bd62 74 float biceps_l = 0;
GerhardBerman 19:cba54636bd62 75 float biceps_r = 0;
GerhardBerman 39:cc7754330c26 76 float ReferencePosition_x = 0.4; //L2;
GerhardBerman 28:6d8c6fe79394 77 float ReferencePosition_y = L1 + TowerHeight - StampHeight;
GerhardBerman 39:cc7754330c26 78 float ReferencePosition_xnew = 0.4; //L2;
GerhardBerman 39:cc7754330c26 79 float ReferencePosition_ynew = L1 + TowerHeight - StampHeight;
GerhardBerman 19:cba54636bd62 80 float Position_x = 0.0;
GerhardBerman 19:cba54636bd62 81 float Position_y = 0.0;
GerhardBerman 19:cba54636bd62 82 float q1 = 0;
GerhardBerman 39:cc7754330c26 83 float q2 = PI/2;
GerhardBerman 19:cba54636bd62 84 float q1_ref = 0;
GerhardBerman 19:cba54636bd62 85 float q2_ref = 0;
GerhardBerman 19:cba54636bd62 86 float q1start = 0;
GerhardBerman 39:cc7754330c26 87 float q12start = PI/2;
GerhardBerman 39:cc7754330c26 88 float q1Encoder = 0;
GerhardBerman 39:cc7754330c26 89 float q12Encoder = 0;
GerhardBerman 39:cc7754330c26 90 float q12Out = 0;
GerhardBerman 19:cba54636bd62 91
GerhardBerman 19:cba54636bd62 92 float q1_error_prev = 0;
GerhardBerman 19:cba54636bd62 93 float q2_error_prev = 0;
GerhardBerman 25:596255732b65 94 float DerTotalError1 = 0;
GerhardBerman 25:596255732b65 95 float DerTotalError2 = 0;
GerhardBerman 19:cba54636bd62 96 float q1IntError = 0;
GerhardBerman 19:cba54636bd62 97 float q2IntError = 0;
GerhardBerman 29:caf3dd699617 98 float TotalError1_prev = 0;
GerhardBerman 29:caf3dd699617 99 float TotalError2_prev = 0;
GerhardBerman 19:cba54636bd62 100
GerhardBerman 19:cba54636bd62 101 float motorValue1 = 0.0;
GerhardBerman 19:cba54636bd62 102 float motorValue2 = 0.0;
GerhardBerman 19:cba54636bd62 103 int counts1 = 0;
GerhardBerman 19:cba54636bd62 104 int counts2 = 0;
GerhardBerman 19:cba54636bd62 105 int counts1Prev = 0;
GerhardBerman 19:cba54636bd62 106 int counts2Prev = 0;
GerhardBerman 41:68b170829965 107 double envelopeL = 0;
GerhardBerman 41:68b170829965 108 double envelopeR = 0;
GerhardBerman 26:bb7e14f59ddd 109
GerhardBerman 26:bb7e14f59ddd 110 //set constant or variable values (VALUES HAVE TO BE EDITED)
GerhardBerman 41:68b170829965 111 int T=0; //EMG 'switch' variable
GerhardBerman 41:68b170829965 112 double threshold_l=0.1; //left arm EMG threshold
GerhardBerman 41:68b170829965 113 double threshold_r = 0.08; //right arm EMG threshold
GerhardBerman 26:bb7e14f59ddd 114 float EMGgain = 1.0;
GerhardBerman 41:68b170829965 115
GerhardBerman 26:bb7e14f59ddd 116 float dy_stampdown = 2.0; //0.05; //5 cm movement downward to stamp
GerhardBerman 26:bb7e14f59ddd 117 float MotorGain = 8.4; // rad/s for PWM, is max motor speed (motor value of 1)
GerhardBerman 39:cc7754330c26 118 float Motor1ExtraGain = 1.0;
GerhardBerman 41:68b170829965 119 float MotorMaxSpeed = 0.1; //define a maximum PWM speed for the motor
GerhardBerman 39:cc7754330c26 120 float t_sample = 0.01; //seconds
GerhardBerman 41:68b170829965 121 const float maxStampDistance = 0.7; //0.66;
GerhardBerman 41:68b170829965 122 const float minStampDistance = 0.35;
GerhardBerman 41:68b170829965 123 float Kp = 4.0;//potMeter2.read();
GerhardBerman 41:68b170829965 124 float Ki = 0.02; //0.01*Kp; //potMeter2.read();
GerhardBerman 41:68b170829965 125 float Kd = 0.02; //0.1;(unstable!) //0.05; //0.02; //0.04*Kp; //potMeter2.read();
GerhardBerman 41:68b170829965 126 float N = 25; //N=1/Tf, Higher N is faster derivative action but more sensitive to noise.
GerhardBerman 26:bb7e14f59ddd 127
GerhardBerman 26:bb7e14f59ddd 128 float q1_refOutNew = 0;
GerhardBerman 39:cc7754330c26 129 float q1_refOutMin = 0; //Physical min angle 0.00 radians + 0.1 rad
GerhardBerman 39:cc7754330c26 130 float q1_refOutMax = 1.37; //Physical max angle 1.47 radians - 0.1 rad
GerhardBerman 26:bb7e14f59ddd 131 float q2_refOutNew = 0;
GerhardBerman 39:cc7754330c26 132 float q2_refOutMin = 0.91; //Physical min angle 0.81 radians + 0.1 rad
GerhardBerman 39:cc7754330c26 133 float q2_refOutMax = 2.07; //Physical max angle 2.17 radians - 0.1 rad
GerhardBerman 26:bb7e14f59ddd 134 float TotalError1= 0;
GerhardBerman 26:bb7e14f59ddd 135 float TotalError2= 0;
GerhardBerman 26:bb7e14f59ddd 136 float TotalErrorMin= 0;
GerhardBerman 19:cba54636bd62 137
GerhardBerman 0:43160ef59f9f 138 //set BiQuad
GerhardBerman 0:43160ef59f9f 139 BiQuadChain bqc;
GerhardBerman 0:43160ef59f9f 140 BiQuad bq1(0.0186, 0.0743, 0.1114, 0.0743, 0.0186); //get numbers from butter filter MATLAB
GerhardBerman 0:43160ef59f9f 141 BiQuad bq2(1.0000, -1.5704, 1.2756, -0.4844, 0.0762);
GerhardBerman 0:43160ef59f9f 142
GerhardBerman 40:9ecaab27acde 143 BiQuad pidf;
GerhardBerman 40:9ecaab27acde 144
GerhardBerman 41:68b170829965 145 BiQuadChain bcq1R;
GerhardBerman 41:68b170829965 146 BiQuadChain bcq2R;
GerhardBerman 41:68b170829965 147 // Notch filter wo=50; bw=wo/35
GerhardBerman 41:68b170829965 148 BiQuad bq1R(9.9110e-01,-1.6036e+00,9.9110e-01,-1.6036e+00,9.8221e-01);
GerhardBerman 41:68b170829965 149 // High pass Butterworth filter 2nd order, Fc=10;
GerhardBerman 41:68b170829965 150 BiQuad bq2R(9.1497e-01,-1.8299e+00,9.1497e-01,-1.8227e+00,8.3718e-01);
GerhardBerman 41:68b170829965 151 // Low pass Butterworth filter 2nd order, Fc = 8;
GerhardBerman 41:68b170829965 152 BiQuad bq3R(1.3487e-03,2.6974e-03,1.3487e-03,-1.8935e+00,8.9886e-01);
GerhardBerman 41:68b170829965 153
GerhardBerman 41:68b170829965 154 BiQuadChain bcq1L;
GerhardBerman 41:68b170829965 155 BiQuadChain bcq2L;
GerhardBerman 41:68b170829965 156 // Notch filter wo=50; bw=wo/35
GerhardBerman 41:68b170829965 157 BiQuad bq1L(9.9110e-01,-1.6036e+00,9.9110e-01,-1.6036e+00,9.8221e-01);
GerhardBerman 41:68b170829965 158 // High pass Butterworth filter 2nd order, Fc=10;
GerhardBerman 41:68b170829965 159 BiQuad bq2L(9.1497e-01,-1.8299e+00,9.1497e-01,-1.8227e+00,8.3718e-01);
GerhardBerman 41:68b170829965 160 // Low pass Butterworth filter 2nd order, Fc = 8;
GerhardBerman 41:68b170829965 161 BiQuad bq3L(1.3487e-03,2.6974e-03,1.3487e-03,-1.8935e+00,8.9886e-01);
GerhardBerman 41:68b170829965 162 // In the following: R is used for right arm, L is used for left arm!
GerhardBerman 41:68b170829965 163
GerhardBerman 0:43160ef59f9f 164 //set go-Ticker settings
GerhardBerman 3:8caef4872b0c 165 volatile bool MeasureTicker_go=false, BiQuadTicker_go=false, FeedbackTicker_go=false, TimeTracker_go=false; // sampleT_go=false;
GerhardBerman 3:8caef4872b0c 166 void MeasureTicker_act(){MeasureTicker_go=true;}; // Activates go-flags
GerhardBerman 3:8caef4872b0c 167 void BiQuadTicker_act(){BiQuadTicker_go=true;};
GerhardBerman 3:8caef4872b0c 168 void FeedbackTicker_act(){FeedbackTicker_go=true;};
GerhardBerman 3:8caef4872b0c 169 void TimeTracker_act(){TimeTracker_go=true;};
GerhardBerman 3:8caef4872b0c 170 //void sampleT_act(){sampleT_go=true;};
GerhardBerman 3:8caef4872b0c 171
GerhardBerman 3:8caef4872b0c 172 //define encoder counts and degrees
GerhardBerman 7:2f74dfd1d411 173 QEI Encoder1(D12, D13, NC, 32); // turns on encoder
GerhardBerman 15:9061cf7db23e 174 QEI Encoder2(D10, D11, NC, 32); // turns on encoder
GerhardBerman 14:725a608b6709 175
GerhardBerman 4:19e376d31380 176 const int counts_per_revolution = 4200; //counts per motor axis revolution
GerhardBerman 4:19e376d31380 177 const int inverse_gear_ratio = 131;
GerhardBerman 4:19e376d31380 178 const float resolution = counts_per_revolution/(2*PI/inverse_gear_ratio); //87567.0496892 counts per radian, encoder axis
GerhardBerman 3:8caef4872b0c 179
GerhardBerman 41:68b170829965 180 void FilteredSample(int &Tout, double &envelopeLout, double &envelopeRout)
GerhardBerman 41:68b170829965 181 {
GerhardBerman 41:68b170829965 182 double inLout = emg0.read();
GerhardBerman 41:68b170829965 183 double inRout = emg1.read();
GerhardBerman 41:68b170829965 184
GerhardBerman 41:68b170829965 185 double outRfilter1 = bcq1R.step(inRout);
GerhardBerman 41:68b170829965 186 double outRrect= fabs(outRfilter1);
GerhardBerman 41:68b170829965 187 envelopeRout = bcq2R.step(outRrect);
GerhardBerman 41:68b170829965 188
GerhardBerman 41:68b170829965 189 double outLfilter1 = bcq1L.step(inLout);
GerhardBerman 41:68b170829965 190 double outLrect = fabs(outLfilter1);
GerhardBerman 41:68b170829965 191 envelopeLout = bcq2L.step(outLrect);
GerhardBerman 41:68b170829965 192
GerhardBerman 41:68b170829965 193 double biceps_l = (double) envelopeLout * EMGgain; //emg0.read(); //velocity or reference position change, EMG with a gain
GerhardBerman 41:68b170829965 194 double biceps_r = (double) envelopeRout * EMGgain; //emg1.read();
GerhardBerman 41:68b170829965 195 if (biceps_l > threshold_l && biceps_r > threshold_r){
GerhardBerman 41:68b170829965 196 //both arms activated: stamp moves down
GerhardBerman 41:68b170829965 197 Tout = -2;
GerhardBerman 41:68b170829965 198 }
GerhardBerman 41:68b170829965 199 else if (biceps_l > threshold_l && biceps_r <= threshold_r){
GerhardBerman 41:68b170829965 200 //arm 1 activated, move left
GerhardBerman 41:68b170829965 201 Tout = -1;
GerhardBerman 41:68b170829965 202 }
GerhardBerman 41:68b170829965 203 else if (biceps_l <= threshold_l && biceps_r > threshold_r){
GerhardBerman 41:68b170829965 204 //arm 1 activated, move right
GerhardBerman 41:68b170829965 205 Tout = 1;
GerhardBerman 41:68b170829965 206 }
GerhardBerman 41:68b170829965 207 else{
GerhardBerman 41:68b170829965 208 //wait(0.2);
GerhardBerman 41:68b170829965 209 Tout = 0;
GerhardBerman 41:68b170829965 210 }
GerhardBerman 41:68b170829965 211
GerhardBerman 41:68b170829965 212 // scope.set(0, inLout);
GerhardBerman 41:68b170829965 213 // scope.set(1, inRout);
GerhardBerman 41:68b170829965 214
GerhardBerman 41:68b170829965 215 }
GerhardBerman 41:68b170829965 216
GerhardBerman 19:cba54636bd62 217 void GetReferenceKinematics1(float &q1Out, float &q2Out, float &q1_refOut, float &q2_refOut){
GerhardBerman 7:2f74dfd1d411 218
GerhardBerman 19:cba54636bd62 219 //get joint positions q feedback from encoder
GerhardBerman 19:cba54636bd62 220 float Encoder1Position = counts1/resolution; //angular position in radians, encoder axis
GerhardBerman 39:cc7754330c26 221 float Encoder2Position = -1*counts2/resolution; //NEGATIVE!
GerhardBerman 39:cc7754330c26 222
GerhardBerman 39:cc7754330c26 223 q1Encoder = Encoder1Position*inverse_gear_ratio;
GerhardBerman 39:cc7754330c26 224 q12Encoder = Encoder2Position*inverse_gear_ratio;
GerhardBerman 39:cc7754330c26 225 q1Out = q1start + q1Encoder; //angular position in radians, motor axis
GerhardBerman 39:cc7754330c26 226 q12Out = q12start + q12Encoder; //encoder 2 gives sum of both angles!
GerhardBerman 39:cc7754330c26 227 q2Out = q12Out - q1Out;
GerhardBerman 39:cc7754330c26 228 float q1deg = q1Out*360/2/PI;
GerhardBerman 39:cc7754330c26 229 float q2deg = q2Out*360/2/PI;
GerhardBerman 7:2f74dfd1d411 230
GerhardBerman 19:cba54636bd62 231 /*
GerhardBerman 19:cba54636bd62 232 //get end effector position feedback with Brockett
GerhardBerman 18:d2cfd07ae88a 233 float Position_x = ((L2 + x0)*(cos(q1)*cos(q2) - sin(q1)*sin(q2)) - L0*sin(q1) + (cos(q1)*sin(q2) + cos(q2)*sin(q1))*(L0 + L1) - cos(q1)*(L1*sin(q1) + L1*cos(q1)*sin(q2) - L1*cos(q2)*sin(q1)) - sin(q1)*(L1*cos(q1)*cos(q2) - L1*cos(q1) + L1*sin(q1)*sin(q2))); //calculate end effector x-position from motor angles with Brockett, rx
GerhardBerman 18:d2cfd07ae88a 234 float Position_y = (L0 - (L2 + x0)*(cos(q1)*sin(q2) + cos(q2)*sin(q1)) - L0*cos(q1) - cos(q1)*(L1*cos(q1)*cos(q2) - L1*cos(q1) + L1*sin(q1)*sin(q2)) + (cos(q1)*cos(q2) - sin(q1)*sin(q2))*(L0 + L1) + sin(q1)*(L1*sin(q1) + L1*cos(q1)*sin(q2) - L1*cos(q2)*sin(q1))); //calculate end effector y-position from motor angles with Brockett, ry
GerhardBerman 19:cba54636bd62 235 */
GerhardBerman 19:cba54636bd62 236 //get end effector position feedback with trigonometry
GerhardBerman 19:cba54636bd62 237 Position_x = (L1*sin(q1) + L2*sin(q1+q2));
GerhardBerman 28:6d8c6fe79394 238 Position_y = (L1*cos(q1) + L2*cos(q1+q2)) + TowerHeight - StampHeight;
GerhardBerman 19:cba54636bd62 239 //float PositionVector = sqrt(pow(Position_x,2)+pow(Position_y,2));
GerhardBerman 29:caf3dd699617 240
GerhardBerman 33:b09608fa69e9 241 /*
GerhardBerman 29:caf3dd699617 242 if (Position_y < (0.5*TowerHeight)){
GerhardBerman 29:caf3dd699617 243 wait(1.0);
GerhardBerman 29:caf3dd699617 244 ReferencePosition_ynew = L1 + TowerHeight - StampHeight; //Reset vertical position after stamping
GerhardBerman 29:caf3dd699617 245 }
GerhardBerman 29:caf3dd699617 246 else{
GerhardBerman 33:b09608fa69e9 247 */
GerhardBerman 7:2f74dfd1d411 248 //get velocity vector v = (Pe*- Pe) = [0; dx; dy] from EMG
GerhardBerman 19:cba54636bd62 249 biceps_l = !button1.read() * EMGgain; //emg0.read(); //velocity or reference position change, EMG with a gain
GerhardBerman 19:cba54636bd62 250 biceps_r = !button2.read() * EMGgain; //emg1.read();
GerhardBerman 41:68b170829965 251 if (T == -2){
GerhardBerman 8:935abf8ecc27 252 //both arms activated: stamp moves down
GerhardBerman 15:9061cf7db23e 253 //led1 = 1;
GerhardBerman 15:9061cf7db23e 254 //led2 = 1;
GerhardBerman 19:cba54636bd62 255 ReferencePosition_xnew = ReferencePosition_x;
GerhardBerman 41:68b170829965 256 ReferencePosition_ynew = ReferencePosition_y - 0.015; //ReferencePosition_y - dy_stampdown; //into stamping vertical position ~the stamp down action
GerhardBerman 18:d2cfd07ae88a 257
GerhardBerman 18:d2cfd07ae88a 258 }
GerhardBerman 41:68b170829965 259 else if (T==-1){
GerhardBerman 18:d2cfd07ae88a 260 //arm 1 activated, move left
GerhardBerman 18:d2cfd07ae88a 261 //led1 = 1;
GerhardBerman 18:d2cfd07ae88a 262 //led2 = 0;
GerhardBerman 41:68b170829965 263 ReferencePosition_xnew = ReferencePosition_x - 0.0009; //biceps_l;
GerhardBerman 34:96bcbddc7d2d 264 ReferencePosition_ynew = y_stampup; //ReferencePosition_y;
GerhardBerman 12:05e5964b69a4 265 /*
GerhardBerman 18:d2cfd07ae88a 266 PositionError_x = ReferencePosition_x - Position_x; //Position error in dx,dy
GerhardBerman 18:d2cfd07ae88a 267 PositionError_y = ReferencePosition_y - Position_y; //Position error in dx,dy
GerhardBerman 18:d2cfd07ae88a 268
GerhardBerman 18:d2cfd07ae88a 269 dx = PositionError_x;
GerhardBerman 18:d2cfd07ae88a 270 dy = PositionError_y;
GerhardBerman 12:05e5964b69a4 271 q1_dotOut = dy*(((x0 + L1*cos(q1))*(L0*L0 + L1*sin(q1)*L0 + x0*x0 + L1*cos(q1)*x0 + 1))/(pow(L1*cos(q1),2) + pow(L1*sin(q1),2) + pow(L1*x0*sin(q1),2) + pow(L0*L1*cos(q1),2) - 2*L0*L1*L1*x0*cos(q1)*sin(q1)) - (x0*(pow(L1*cos(q1),2) + pow(L1*sin(q1),2) + L0*L0 + x0*x0 + 2*L0*L1*sin(q1) + 2*L1*x0*cos(q1) + 1))/(pow(L1*cos(q1),2) + pow(L1*sin(q1),2) + pow(L1*x0*sin(q1),2) + pow(L0*L1*cos(q1),2) - 2*L0*L1*L1*x0*cos(q1)*sin(q1))) - dx*(((L0 + L1*sin(q1))*(L0*L0 + L1*sin(q1)*L0 + x0*x0 + L1*cos(q1)*x0 + 1))/(pow(L1*cos(q1),2) + pow(L1*sin(q1),2) + pow(L1*x0*sin(q1),2) + pow(L0*L1*cos(q1),2) - 2*L0*L1*L1*x0*cos(q1)*sin(q1)) - (L0*(pow(L1*cos(q1),2) + pow(L1*sin(q1),2) + L0*L0 + x0*x0 + 2*L0*L1*sin(q1) + 2*L1*x0*cos(q1) + 1))/(pow(L1*cos(q1),2) + pow(L1*sin(q1),2) + pow(L1*x0*sin(q1),2) + pow(L0*L1*cos(q1),2) - 2*L0*L1*L1*x0*cos(q1)*sin(q1)));
GerhardBerman 12:05e5964b69a4 272 q2_dotOut = dy*((x0*(L0*L0 + L1*sin(q1)*L0 + x0*x0 + L1*cos(q1)*x0 + 1))/(L1*L1*pow(cos(q1),2) + pow(L1*sin(q1),2) + pow(L1*x0*sin(q1),2) + pow(L0*L1*cos(q1),2) - 2*L0*pow(L1,2)*x0*cos(q1)*sin(q1)) - ((x0 + L1*cos(q1))*(pow(L0,2) + pow(x0,2) + 1))/(pow(L1*cos(q1),2)) + pow(L1*sin(q1),2) + pow(L1*x0*sin(q1),2) + pow(L0*L1*cos(q1),2) - 2*L0*pow(L1,2)*x0*cos(q1)*sin(q1)) - dx*((L0*(L0*L0+L1*sin(q1)*L0+x0*x0+L1*cos(q1)*x0+1))/(pow(L1*cos(q1),2)+pow(L1*sin(q1),2)+pow(L1*x0*sin(q1),2)+pow(L0*L1*cos(q1),2)-2*L0*L1*L1*x0*cos(q1)*sin(q1))-((L0 + L1*sin(q1))*(L0*L0 + x0*x0 + 1))/(pow(L1*cos(q1),2)+pow(L1*sin(q1),2)+pow(L1*x0*sin(q1),2)+pow(L0*L1*cos(q1),2)-2*L0*L1*L1*x0*cos(q1)*sin(q1)));
GerhardBerman 12:05e5964b69a4 273 */
GerhardBerman 8:935abf8ecc27 274 }
GerhardBerman 41:68b170829965 275 else if (T==1){
GerhardBerman 18:d2cfd07ae88a 276 //arm 1 activated, move right
GerhardBerman 18:d2cfd07ae88a 277 //led1 = 0;
GerhardBerman 18:d2cfd07ae88a 278 //led2 = 1;
GerhardBerman 41:68b170829965 279 ReferencePosition_xnew = ReferencePosition_x + 0.0009; //biceps_r;
GerhardBerman 34:96bcbddc7d2d 280 ReferencePosition_ynew = y_stampup; //ReferencePosition_y;
GerhardBerman 18:d2cfd07ae88a 281 /*PositionError_x = ReferencePosition_x - Position_x; //Position error in dx,dy
GerhardBerman 18:d2cfd07ae88a 282 PositionError_y = ReferencePosition_y - Position_y; //Position error in dx,dy
GerhardBerman 18:d2cfd07ae88a 283
GerhardBerman 18:d2cfd07ae88a 284 dx = PositionError_x;
GerhardBerman 18:d2cfd07ae88a 285 dy = PositionError_y;
GerhardBerman 12:05e5964b69a4 286 q1_dotOut = dy*(((x0 + L1*cos(q1))*(L0*L0 + L1*sin(q1)*L0 + x0*x0 + L1*cos(q1)*x0 + 1))/(pow(L1*cos(q1),2) + pow(L1*sin(q1),2) + pow(L1*x0*sin(q1),2) + pow(L0*L1*cos(q1),2) - 2*L0*L1*L1*x0*cos(q1)*sin(q1)) - (x0*(pow(L1*cos(q1),2) + pow(L1*sin(q1),2) + L0*L0 + x0*x0 + 2*L0*L1*sin(q1) + 2*L1*x0*cos(q1) + 1))/(pow(L1*cos(q1),2) + pow(L1*sin(q1),2) + pow(L1*x0*sin(q1),2) + pow(L0*L1*cos(q1),2) - 2*L0*L1*L1*x0*cos(q1)*sin(q1))) - dx*(((L0 + L1*sin(q1))*(L0*L0 + L1*sin(q1)*L0 + x0*x0 + L1*cos(q1)*x0 + 1))/(pow(L1*cos(q1),2) + pow(L1*sin(q1),2) + pow(L1*x0*sin(q1),2) + pow(L0*L1*cos(q1),2) - 2*L0*L1*L1*x0*cos(q1)*sin(q1)) - (L0*(pow(L1*cos(q1),2) + pow(L1*sin(q1),2) + L0*L0 + x0*x0 + 2*L0*L1*sin(q1) + 2*L1*x0*cos(q1) + 1))/(pow(L1*cos(q1),2) + pow(L1*sin(q1),2) + pow(L1*x0*sin(q1),2) + pow(L0*L1*cos(q1),2) - 2*L0*L1*L1*x0*cos(q1)*sin(q1)));
GerhardBerman 12:05e5964b69a4 287 q2_dotOut = dy*((x0*(L0*L0 + L1*sin(q1)*L0 + x0*x0 + L1*cos(q1)*x0 + 1))/(L1*L1*pow(cos(q1),2) + pow(L1*sin(q1),2) + pow(L1*x0*sin(q1),2) + pow(L0*L1*cos(q1),2) - 2*L0*pow(L1,2)*x0*cos(q1)*sin(q1)) - ((x0 + L1*cos(q1))*(pow(L0,2) + pow(x0,2) + 1))/(pow(L1*cos(q1),2)) + pow(L1*sin(q1),2) + pow(L1*x0*sin(q1),2) + pow(L0*L1*cos(q1),2) - 2*L0*pow(L1,2)*x0*cos(q1)*sin(q1)) - dx*((L0*(L0*L0+L1*sin(q1)*L0+x0*x0+L1*cos(q1)*x0+1))/(pow(L1*cos(q1),2)+pow(L1*sin(q1),2)+pow(L1*x0*sin(q1),2)+pow(L0*L1*cos(q1),2)-2*L0*L1*L1*x0*cos(q1)*sin(q1))-((L0 + L1*sin(q1))*(L0*L0 + x0*x0 + 1))/(pow(L1*cos(q1),2)+pow(L1*sin(q1),2)+pow(L1*x0*sin(q1),2)+pow(L0*L1*cos(q1),2)-2*L0*L1*L1*x0*cos(q1)*sin(q1)));
GerhardBerman 18:d2cfd07ae88a 288 */
GerhardBerman 8:935abf8ecc27 289 }
GerhardBerman 41:68b170829965 290 else{ //T==0
GerhardBerman 15:9061cf7db23e 291 //led1 = 0;
GerhardBerman 15:9061cf7db23e 292 //led2 = 0;
GerhardBerman 39:cc7754330c26 293 //ReferencePosition_xnew = ReferencePosition_x;
GerhardBerman 36:72f0913c5460 294 ReferencePosition_ynew = y_stampup; //ReferencePosition_y; //
GerhardBerman 19:cba54636bd62 295 }
GerhardBerman 33:b09608fa69e9 296 // }
GerhardBerman 19:cba54636bd62 297
GerhardBerman 39:cc7754330c26 298 //check position boundaries
GerhardBerman 39:cc7754330c26 299 if (ReferencePosition_xnew > maxStampDistance){
GerhardBerman 39:cc7754330c26 300 ReferencePosition_x = maxStampDistance; // - 0.1;
GerhardBerman 39:cc7754330c26 301 ReferencePosition_y = y_stampup;
GerhardBerman 39:cc7754330c26 302 pc.printf("Target too far! \r\n");
GerhardBerman 39:cc7754330c26 303 }
GerhardBerman 39:cc7754330c26 304 else if (ReferencePosition_xnew < minStampDistance){
GerhardBerman 39:cc7754330c26 305 ReferencePosition_x = minStampDistance; // + 0.1;
GerhardBerman 39:cc7754330c26 306 ReferencePosition_y = y_stampup;
GerhardBerman 39:cc7754330c26 307 pc.printf("Target too close! \r\n");
GerhardBerman 39:cc7754330c26 308 }
GerhardBerman 41:68b170829965 309 else if (ReferencePosition_ynew < y_stampdown){
GerhardBerman 41:68b170829965 310 ReferencePosition_x = ReferencePosition_xnew; // + 0.1;
GerhardBerman 41:68b170829965 311 ReferencePosition_y = y_stampdown;
GerhardBerman 41:68b170829965 312 pc.printf("Target too close! \r\n");
GerhardBerman 41:68b170829965 313 }
GerhardBerman 39:cc7754330c26 314 else {
GerhardBerman 39:cc7754330c26 315 ReferencePosition_x = ReferencePosition_xnew;
GerhardBerman 39:cc7754330c26 316 ReferencePosition_y = ReferencePosition_ynew;
GerhardBerman 39:cc7754330c26 317 }
GerhardBerman 39:cc7754330c26 318
GerhardBerman 28:6d8c6fe79394 319 float PointPositionArm2_x = ReferencePosition_x;
GerhardBerman 28:6d8c6fe79394 320 float PointPositionArm2_y = ReferencePosition_y - TowerHeight + StampHeight;
GerhardBerman 28:6d8c6fe79394 321 float PointVectorArm2 = sqrt(pow(PointPositionArm2_x,2)+pow(PointPositionArm2_y,2));
GerhardBerman 19:cba54636bd62 322
GerhardBerman 19:cba54636bd62 323 //calculate reference joint angles for the new reference position
GerhardBerman 28:6d8c6fe79394 324 float alpha = atan(PointPositionArm2_y/PointPositionArm2_x);
GerhardBerman 28:6d8c6fe79394 325 float beta = acos((L2*L2-L1*L1-pow(PointVectorArm2,2))/(-2*L1*PointVectorArm2));
GerhardBerman 19:cba54636bd62 326 q1_refOutNew = PI/2 - (alpha+beta);
GerhardBerman 28:6d8c6fe79394 327 q2_refOutNew = PI - asin(PointVectorArm2*sin(beta)/L2);
GerhardBerman 19:cba54636bd62 328
GerhardBerman 19:cba54636bd62 329 //check angle boundaries
GerhardBerman 39:cc7754330c26 330 if (q1_refOutNew < q1_refOutMin){
GerhardBerman 39:cc7754330c26 331 q1_refOut = q1_refOutMin;
GerhardBerman 39:cc7754330c26 332 pc.printf("\r\n Under q1 angle boundaries\r\n");
GerhardBerman 39:cc7754330c26 333 }
GerhardBerman 39:cc7754330c26 334 else if (q1_refOutNew > q1_refOutMax){
GerhardBerman 39:cc7754330c26 335 q1_refOut = q1_refOutMax;
GerhardBerman 39:cc7754330c26 336 pc.printf("\r\n Above q1 angle boundaries\r\n");
GerhardBerman 19:cba54636bd62 337 }
GerhardBerman 19:cba54636bd62 338 else {
GerhardBerman 39:cc7754330c26 339 q1_refOut = q1_refOutNew;
GerhardBerman 19:cba54636bd62 340 }
GerhardBerman 39:cc7754330c26 341
GerhardBerman 39:cc7754330c26 342 if (q2_refOutNew < q2_refOutMin){
GerhardBerman 39:cc7754330c26 343 q2_refOut = q2_refOutMin;
GerhardBerman 39:cc7754330c26 344 pc.printf("\r\n Under q2 angle boundaries");
GerhardBerman 39:cc7754330c26 345 }
GerhardBerman 39:cc7754330c26 346 else if (q2_refOutNew > q2_refOutMax){
GerhardBerman 39:cc7754330c26 347 q2_refOut = q2_refOutMax;
GerhardBerman 39:cc7754330c26 348 pc.printf("\r\n Above q2 angle boundaries");
GerhardBerman 19:cba54636bd62 349 }
GerhardBerman 19:cba54636bd62 350 else {
GerhardBerman 39:cc7754330c26 351 q2_refOut = q2_refOutNew;
GerhardBerman 39:cc7754330c26 352 }
GerhardBerman 7:2f74dfd1d411 353 //update joint angles
GerhardBerman 18:d2cfd07ae88a 354 //q1Out = q1Out + q1_dotOut; //in radians
GerhardBerman 18:d2cfd07ae88a 355 //q2Out = q2Out + q2_dotOut;
GerhardBerman 12:05e5964b69a4 356
GerhardBerman 34:96bcbddc7d2d 357 pc.baud(115200);
GerhardBerman 36:72f0913c5460 358 pc.printf("posX: %f ",Position_x);
GerhardBerman 36:72f0913c5460 359 pc.printf("posY: %f ",Position_y);
GerhardBerman 34:96bcbddc7d2d 360 pc.printf("refX: %f ",ReferencePosition_xnew);
GerhardBerman 34:96bcbddc7d2d 361 pc.printf("refY: %f ",ReferencePosition_ynew);
GerhardBerman 34:96bcbddc7d2d 362 pc.printf("q1: %f ", q1Out);
GerhardBerman 34:96bcbddc7d2d 363 pc.printf("q1ref: %f ", q1_refOut);
GerhardBerman 34:96bcbddc7d2d 364 pc.printf("q2: %f ", q2Out);
GerhardBerman 34:96bcbddc7d2d 365 pc.printf("q2ref: %f ", q2_refOut);
GerhardBerman 39:cc7754330c26 366 pc.printf("q1deg: %f ", q1deg);
GerhardBerman 39:cc7754330c26 367 pc.printf("q2deg: %f \r\n", q2deg);
GerhardBerman 41:68b170829965 368
GerhardBerman 41:68b170829965 369 scope.set(0, ReferencePosition_xnew);
GerhardBerman 41:68b170829965 370 scope.set(1, ReferencePosition_ynew);
GerhardBerman 41:68b170829965 371 scope.set(2, envelopeL);
GerhardBerman 41:68b170829965 372 scope.set(3, envelopeR);
GerhardBerman 41:68b170829965 373 scope.set(4, T);
GerhardBerman 41:68b170829965 374 scope.send();
GerhardBerman 18:d2cfd07ae88a 375 /*
GerhardBerman 12:05e5964b69a4 376 pc.printf("dx: %f \r\n", dx);
GerhardBerman 12:05e5964b69a4 377 pc.printf("dy: %f \r\n", dy);
GerhardBerman 12:05e5964b69a4 378 pc.printf("q1: %f \r\n", q1Out);
GerhardBerman 12:05e5964b69a4 379 pc.printf("q1_dot: %f \r\n", q1_dotOut);
GerhardBerman 12:05e5964b69a4 380 pc.printf("q2: %f \r\n", q2Out);
GerhardBerman 12:05e5964b69a4 381 pc.printf("q2_dot: %f \r\n", q2_dotOut);
GerhardBerman 12:05e5964b69a4 382
GerhardBerman 14:725a608b6709 383 pc.printf("Counts1: %f \r\n", counts1);
GerhardBerman 14:725a608b6709 384 pc.printf("Encoder1: %f \r\n", Encoder1Position);
GerhardBerman 18:d2cfd07ae88a 385 pc.printf("Motor1: %f \r\n", q1Out);
GerhardBerman 14:725a608b6709 386 pc.printf("Counts2: %f \r\n", counts2);
GerhardBerman 14:725a608b6709 387 pc.printf("Encoder2: %f \r\n", Encoder2Position);
GerhardBerman 18:d2cfd07ae88a 388 pc.printf("Motor2: %f \r\n", q2Out);
GerhardBerman 18:d2cfd07ae88a 389 */
GerhardBerman 29:caf3dd699617 390
GerhardBerman 7:2f74dfd1d411 391 }
GerhardBerman 18:d2cfd07ae88a 392
GerhardBerman 7:2f74dfd1d411 393
GerhardBerman 24:393da1cc1fa8 394 void FeedbackControl1(float q1_ref, float q2_ref, float q1, float q2, float &motorValue1Out, float &motorValue2Out){
GerhardBerman 7:2f74dfd1d411 395
GerhardBerman 7:2f74dfd1d411 396 // linear feedback control
GerhardBerman 19:cba54636bd62 397 float q1_error = q1_ref - q1; //referencePosition1 - Position1; // proportional angular error in radians
GerhardBerman 19:cba54636bd62 398 float q2_error = q2_ref - q2; //referencePosition1 - Position1; // proportional angular error in radians
GerhardBerman 7:2f74dfd1d411 399
GerhardBerman 40:9ecaab27acde 400 float TotalError1 = pidf.step(q1_error);
GerhardBerman 40:9ecaab27acde 401 float TotalError2 = pidf.step(q2_error);
GerhardBerman 40:9ecaab27acde 402
GerhardBerman 40:9ecaab27acde 403 /*
GerhardBerman 19:cba54636bd62 404 float q1IntError = q1IntError + q1_error*t_sample; // integrated error in radians
GerhardBerman 19:cba54636bd62 405 float q2IntError = q2IntError + q2_error*t_sample; // integrated error in radians
GerhardBerman 7:2f74dfd1d411 406 //float maxKi = 0.2;
GerhardBerman 34:96bcbddc7d2d 407 float Ki = 0.04*Kp; //0.01*Kp; //potMeter2.read();
GerhardBerman 7:2f74dfd1d411 408
GerhardBerman 27:456e8a47f815 409 float q1DerivativeError = (q1_error - q1_error_prev)/t_sample; // derivative of error in radians
GerhardBerman 19:cba54636bd62 410 float q2DerivativeError = (q2_error_prev + q2_error)/t_sample; // derivative of error in radians
GerhardBerman 7:2f74dfd1d411 411 //float maxKd = 0.2;
GerhardBerman 33:b09608fa69e9 412 float Kd = 0.0; //0.04*Kp; //potMeter2.read();
GerhardBerman 7:2f74dfd1d411 413
GerhardBerman 7:2f74dfd1d411 414 //scope.set(0,referencePosition1);
GerhardBerman 7:2f74dfd1d411 415 //scope.set(1,Position1);
GerhardBerman 7:2f74dfd1d411 416 //scope.set(2,Ki);
GerhardBerman 7:2f74dfd1d411 417 //scope.send();
GerhardBerman 7:2f74dfd1d411 418
GerhardBerman 23:3a4d5e19c20d 419 TotalError1 = q1_error * Kp + q1IntError * Ki + q1DerivativeError * Kd; //total controller output in radians = motor input
GerhardBerman 23:3a4d5e19c20d 420 TotalError2 = q2_error * Kp + q2IntError * Ki + q2DerivativeError * Kd; //total controller output in radians = motor input
GerhardBerman 40:9ecaab27acde 421 */
GerhardBerman 33:b09608fa69e9 422 /*
GerhardBerman 33:b09608fa69e9 423 if (fabs(TotalError1) < TotalErrorMin) {
11i 21:dd51d78c0732 424 TotalError1=0;
11i 21:dd51d78c0732 425 }
11i 21:dd51d78c0732 426 else {
11i 21:dd51d78c0732 427 TotalError1=TotalError1;
11i 21:dd51d78c0732 428 }
GerhardBerman 33:b09608fa69e9 429 if (fabs(TotalError2) < TotalErrorMin) {
11i 21:dd51d78c0732 430 TotalError2=0;
11i 21:dd51d78c0732 431 }
11i 21:dd51d78c0732 432 else {
11i 21:dd51d78c0732 433 TotalError2=TotalError2;
11i 21:dd51d78c0732 434 }
GerhardBerman 33:b09608fa69e9 435 */
GerhardBerman 25:596255732b65 436 /*
GerhardBerman 25:596255732b65 437 DerTotalError1 = (TotalError1 - TotalError1_prev)/t_sample;
GerhardBerman 25:596255732b65 438 DerTotalError1 = (TotalError1 - TotalError1_prev)/t_sample;
GerhardBerman 25:596255732b65 439 motorValue1Out = DerTotalError1/MotorGain;
GerhardBerman 25:596255732b65 440 motorValue2Out = DerTotalError2/MotorGain;
GerhardBerman 25:596255732b65 441 */
GerhardBerman 25:596255732b65 442
GerhardBerman 39:cc7754330c26 443 motorValue1Out = Motor1ExtraGain*(TotalError1/MotorGain);
11i 21:dd51d78c0732 444 motorValue2Out = TotalError2/MotorGain;
11i 21:dd51d78c0732 445
GerhardBerman 33:b09608fa69e9 446 /*
GerhardBerman 29:caf3dd699617 447 scope.set(0,q1_ref);
GerhardBerman 29:caf3dd699617 448 scope.set(1,q1);
GerhardBerman 29:caf3dd699617 449 scope.set(2,q2_ref);
GerhardBerman 29:caf3dd699617 450 scope.set(3,q2);
GerhardBerman 29:caf3dd699617 451 scope.set(4,motorValue1Out);
GerhardBerman 29:caf3dd699617 452 scope.set(5,motorValue2Out);
GerhardBerman 29:caf3dd699617 453 scope.send();
GerhardBerman 33:b09608fa69e9 454 */
GerhardBerman 33:b09608fa69e9 455 /*
GerhardBerman 33:b09608fa69e9 456 pc.printf("E1: %f ", q1_error);
GerhardBerman 33:b09608fa69e9 457 pc.printf("IE1: %f ", q1IntError);
GerhardBerman 33:b09608fa69e9 458 pc.printf("DE1: %f ", q2DerivativeError);
GerhardBerman 33:b09608fa69e9 459 pc.printf("E2: %f ", q2_error);
GerhardBerman 33:b09608fa69e9 460 pc.printf("IE2: %f ", q2IntError);
GerhardBerman 33:b09608fa69e9 461 pc.printf("DE2: %f ", q2DerivativeError);
GerhardBerman 34:96bcbddc7d2d 462 */
GerhardBerman 39:cc7754330c26 463 //pc.printf("TE1: %f ", TotalError1);
GerhardBerman 39:cc7754330c26 464 //pc.printf("TE2: %f ", TotalError2);
GerhardBerman 39:cc7754330c26 465 pc.printf("M1: %f \r\n", motorValue1Out);
GerhardBerman 33:b09608fa69e9 466 pc.printf("M2: %f \r\n", motorValue2Out);
GerhardBerman 34:96bcbddc7d2d 467
GerhardBerman 19:cba54636bd62 468 q1_error_prev = q1_error;
GerhardBerman 19:cba54636bd62 469 q2_error_prev = q2_error;
GerhardBerman 25:596255732b65 470 TotalError1_prev = TotalError1;
GerhardBerman 33:b09608fa69e9 471 TotalError2_prev = TotalError2;
GerhardBerman 3:8caef4872b0c 472 }
GerhardBerman 3:8caef4872b0c 473
GerhardBerman 9:e4c34f5665a0 474 void SetMotor1(float motorValue1, float motorValue2)
GerhardBerman 3:8caef4872b0c 475 {
GerhardBerman 3:8caef4872b0c 476 // Given -1<=motorValue<=1, this sets the PWM and direction
GerhardBerman 3:8caef4872b0c 477 // bits for motor 1. Positive value makes motor rotating
GerhardBerman 3:8caef4872b0c 478 // clockwise. motorValues outside range are truncated to
GerhardBerman 3:8caef4872b0c 479 // within range
GerhardBerman 9:e4c34f5665a0 480 //control motor 1
GerhardBerman 15:9061cf7db23e 481 if (motorValue1 >=0) //clockwise rotation
GerhardBerman 19:cba54636bd62 482 {motor1DirectionPin=cw; //inverted due to opposite (to other motor) build-up in tower
GerhardBerman 9:e4c34f5665a0 483 //led1=1;
GerhardBerman 9:e4c34f5665a0 484 //led2=0;
GerhardBerman 3:8caef4872b0c 485 }
GerhardBerman 15:9061cf7db23e 486 else //counterclockwise rotation
GerhardBerman 19:cba54636bd62 487 {motor1DirectionPin=ccw; //inverted due to opposite (to other motor) build-up in tower
GerhardBerman 9:e4c34f5665a0 488 //led1=0;
GerhardBerman 9:e4c34f5665a0 489 //led2=1;
GerhardBerman 3:8caef4872b0c 490 }
GerhardBerman 39:cc7754330c26 491 if (fabs(motorValue1)>MotorMaxSpeed){
GerhardBerman 39:cc7754330c26 492 motor1MagnitudePin = MotorMaxSpeed;
GerhardBerman 29:caf3dd699617 493 }
GerhardBerman 29:caf3dd699617 494 else{
GerhardBerman 29:caf3dd699617 495 motor1MagnitudePin = fabs(motorValue1); //fabs(motorValue1);
GerhardBerman 29:caf3dd699617 496 }
GerhardBerman 29:caf3dd699617 497
GerhardBerman 9:e4c34f5665a0 498 //control motor 2
GerhardBerman 15:9061cf7db23e 499 if (motorValue2 >=0) //clockwise rotation
GerhardBerman 39:cc7754330c26 500 {motor2DirectionPin=cw; //action is ccw, due to faulty motor2DirectionPin (inverted)
GerhardBerman 10:45473f650198 501 //led1=1;
GerhardBerman 10:45473f650198 502 //led2=0;
GerhardBerman 7:2f74dfd1d411 503 }
GerhardBerman 15:9061cf7db23e 504 else //counterclockwise rotation
GerhardBerman 39:cc7754330c26 505 {motor2DirectionPin=ccw; //action is cw, due to faulty motor2DirectionPin (inverted)
GerhardBerman 10:45473f650198 506 //led1=0;
GerhardBerman 10:45473f650198 507 //led2=1;
GerhardBerman 7:2f74dfd1d411 508 }
GerhardBerman 39:cc7754330c26 509 if (fabs(motorValue2)>MotorMaxSpeed){
GerhardBerman 39:cc7754330c26 510 motor2MagnitudePin = MotorMaxSpeed;
GerhardBerman 29:caf3dd699617 511 }
GerhardBerman 29:caf3dd699617 512 else{
GerhardBerman 29:caf3dd699617 513 motor2MagnitudePin = fabs(motorValue2);
GerhardBerman 29:caf3dd699617 514 }
GerhardBerman 39:cc7754330c26 515 float ReadDir1 = motor1DirectionPin.read();
GerhardBerman 39:cc7754330c26 516 float ReadDir2 = motor2DirectionPin.read();
GerhardBerman 39:cc7754330c26 517 pc.printf("M1 dir: %f \r\n", ReadDir1);
GerhardBerman 39:cc7754330c26 518 pc.printf("M2 dir: %f \r\n", ReadDir2);
GerhardBerman 3:8caef4872b0c 519 }
GerhardBerman 3:8caef4872b0c 520
GerhardBerman 3:8caef4872b0c 521 void MeasureAndControl()
GerhardBerman 3:8caef4872b0c 522 {
GerhardBerman 9:e4c34f5665a0 523 // This function measures the EMG of both arms, calculates via IK what
GerhardBerman 24:393da1cc1fa8 524 // the joint positions should be, and controls the motor with
GerhardBerman 24:393da1cc1fa8 525 // a Feedback controller. This is called from a Ticker.
GerhardBerman 41:68b170829965 526 FilteredSample(T, envelopeL, envelopeR);
GerhardBerman 19:cba54636bd62 527 GetReferenceKinematics1(q1, q2, q1_ref, q2_ref);
GerhardBerman 24:393da1cc1fa8 528 FeedbackControl1( q1_ref, q2_ref, q1, q2, motorValue1, motorValue2);
GerhardBerman 9:e4c34f5665a0 529 SetMotor1(motorValue1, motorValue2);
GerhardBerman 3:8caef4872b0c 530 }
GerhardBerman 3:8caef4872b0c 531
GerhardBerman 3:8caef4872b0c 532 void TimeTrackerF(){
GerhardBerman 3:8caef4872b0c 533 //wait(1);
GerhardBerman 3:8caef4872b0c 534 //float Potmeter1 = potMeter1.read();
GerhardBerman 7:2f74dfd1d411 535 //float referencePosition1 = GetReferencePosition();
GerhardBerman 7:2f74dfd1d411 536 //pc.printf("TTReference Position: %d rad \r\n", referencePosition1);
GerhardBerman 3:8caef4872b0c 537 //pc.printf("TTPotmeter1, for refpos: %f \r\n", Potmeter1);
GerhardBerman 3:8caef4872b0c 538 //pc.printf("TTPotmeter2, Kp: %f \r\n", Potmeter2);
GerhardBerman 7:2f74dfd1d411 539 //pc.printf("TTCounts: %i \r\n", counts1);
GerhardBerman 3:8caef4872b0c 540 }
GerhardBerman 7:2f74dfd1d411 541
GerhardBerman 3:8caef4872b0c 542 /*
GerhardBerman 3:8caef4872b0c 543 void BiQuadFilter(){ //this function creates a BiQuad filter for the DerivativeCounts
GerhardBerman 3:8caef4872b0c 544 //double in=DerivativeCounts();
GerhardBerman 3:8caef4872b0c 545 bqcDerivativeCounts=bqc.step(DerivativeCounts);
GerhardBerman 3:8caef4872b0c 546 //return(bqcDerivativeCounts);
GerhardBerman 3:8caef4872b0c 547 }
GerhardBerman 9:e4c34f5665a0 548 */
GerhardBerman 6:3c4f3f2ce54f 549
GerhardBerman 0:43160ef59f9f 550 int main()
GerhardBerman 0:43160ef59f9f 551 {
GerhardBerman 0:43160ef59f9f 552 //Initialize
GerhardBerman 15:9061cf7db23e 553 //int led1val = led1.read();
GerhardBerman 15:9061cf7db23e 554 //int led2val = led2.read();
GerhardBerman 34:96bcbddc7d2d 555 pc.baud(115200);
GerhardBerman 34:96bcbddc7d2d 556 pc.printf("Test putty IK");
GerhardBerman 41:68b170829965 557 ledRed=1;
GerhardBerman 41:68b170829965 558 ledBlue=1;
GerhardBerman 41:68b170829965 559 ledRed=0; //red
GerhardBerman 41:68b170829965 560
GerhardBerman 41:68b170829965 561 bcq1R.add(&bq1R).add(&bq2R); //set BiQuad chains
GerhardBerman 41:68b170829965 562 bcq2R.add(&bq3R);
GerhardBerman 41:68b170829965 563
GerhardBerman 41:68b170829965 564 bcq1L.add(&bq1L).add(&bq2L);
GerhardBerman 41:68b170829965 565 bcq2L.add(&bq3L);
GerhardBerman 41:68b170829965 566
GerhardBerman 36:72f0913c5460 567 counts1 = Encoder1.getPulses(); // gives position of encoder
GerhardBerman 36:72f0913c5460 568 counts2 = Encoder2.getPulses(); // gives position of encoder
GerhardBerman 41:68b170829965 569 wait(20.0);
GerhardBerman 41:68b170829965 570 MeasureTicker.attach(&MeasureTicker_act, 0.002); //0.1f);
GerhardBerman 41:68b170829965 571 //bqc.add(&bq1).add(&bq2); //set BiQuad chain
GerhardBerman 40:9ecaab27acde 572 pidf.PIDF( Kp, Ki, Kd, N, t_sample ); //set PID filter
GerhardBerman 0:43160ef59f9f 573 while(1)
GerhardBerman 0:43160ef59f9f 574 {
GerhardBerman 3:8caef4872b0c 575 if (MeasureTicker_go){
GerhardBerman 3:8caef4872b0c 576 MeasureTicker_go=false;
GerhardBerman 41:68b170829965 577 ledGrn = 1;
GerhardBerman 41:68b170829965 578 ledBlue = 0;
GerhardBerman 3:8caef4872b0c 579 MeasureAndControl();
GerhardBerman 15:9061cf7db23e 580 counts1 = Encoder1.getPulses(); // gives position of encoder
GerhardBerman 15:9061cf7db23e 581 counts2 = Encoder2.getPulses(); // gives position of encoder
GerhardBerman 33:b09608fa69e9 582 //pc.printf("counts1: %i ", counts1);
GerhardBerman 33:b09608fa69e9 583 //pc.printf("counts2: %i \r\n", counts2);
GerhardBerman 41:68b170829965 584 ledBlue = 1;
GerhardBerman 41:68b170829965 585 ledGrn = 0;
GerhardBerman 3:8caef4872b0c 586 }
GerhardBerman 10:45473f650198 587 /*
GerhardBerman 3:8caef4872b0c 588 if (BiQuadTicker_go){
GerhardBerman 3:8caef4872b0c 589 BiQuadTicker_go=false;
GerhardBerman 3:8caef4872b0c 590 BiQuadFilter();
GerhardBerman 3:8caef4872b0c 591 }
GerhardBerman 10:45473f650198 592 */
GerhardBerman 0:43160ef59f9f 593 }
GerhardBerman 0:43160ef59f9f 594 }