Dependencies: FastPWM MODSERIAL QEI biquadFilter mbed
Fork of state_program by
main.cpp@6:e67250b8b100, 2018-11-01 (annotated)
- Committer:
- KingMufasa
- Date:
- Thu Nov 01 19:35:15 2018 +0000
- Revision:
- 6:e67250b8b100
- Parent:
- 5:a1843b698d0d
- Child:
- 7:1906d404cd1e
it works yay;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
JesseLohman | 0:2a5dd6cc0008 | 1 | #include "mbed.h" |
JesseLohman | 0:2a5dd6cc0008 | 2 | #include "FastPWM.h" |
JesseLohman | 0:2a5dd6cc0008 | 3 | #include "QEI.h" |
JesseLohman | 0:2a5dd6cc0008 | 4 | #include "BiQuad.h" |
JesseLohman | 3:be922ea2415f | 5 | #include <iostream> |
JesseLohman | 3:be922ea2415f | 6 | #include <string> |
JesseLohman | 0:2a5dd6cc0008 | 7 | |
JesseLohman | 0:2a5dd6cc0008 | 8 | enum States {WaitState, MotorCalState, EMGCalState, HomingState, MovingState, GrippingState, ScrewingState, FailureState}; |
JesseLohman | 0:2a5dd6cc0008 | 9 | States currentState = WaitState; |
JesseLohman | 0:2a5dd6cc0008 | 10 | |
JesseLohman | 0:2a5dd6cc0008 | 11 | DigitalIn startButton(D0); |
JesseLohman | 0:2a5dd6cc0008 | 12 | InterruptIn failureButton(D1); |
JesseLohman | 1:4cb9af313c26 | 13 | DigitalIn grippingSwitch(SW2); |
JesseLohman | 1:4cb9af313c26 | 14 | DigitalIn screwingSwitch(SW3); |
JesseLohman | 1:4cb9af313c26 | 15 | DigitalIn gripDirection(D2); |
JesseLohman | 1:4cb9af313c26 | 16 | DigitalIn screwDirection(D3); |
KingMufasa | 5:a1843b698d0d | 17 | |
KingMufasa | 5:a1843b698d0d | 18 | Serial pc(USBTX, USBRX); |
KingMufasa | 5:a1843b698d0d | 19 | |
JesseLohman | 1:4cb9af313c26 | 20 | DigitalOut led1(LED1); // Red led |
JesseLohman | 1:4cb9af313c26 | 21 | DigitalOut led2(LED2); // Green led |
JesseLohman | 1:4cb9af313c26 | 22 | DigitalOut led3(LED3); // Blue led |
KingMufasa | 6:e67250b8b100 | 23 | QEI encoder1(D10, D11, NC, 8400, QEI::X4_ENCODING); |
JesseLohman | 3:be922ea2415f | 24 | QEI encoder2(D12, D13, NC, 8400, QEI::X4_ENCODING); |
JesseLohman | 2:5cace74299e7 | 25 | //QEI encoder3(A4, A5), NC, 4200); |
KingMufasa | 5:a1843b698d0d | 26 | AnalogIn pot(A4); // Speed knob |
KingMufasa | 5:a1843b698d0d | 27 | AnalogIn pot2(A5); |
KingMufasa | 5:a1843b698d0d | 28 | |
KingMufasa | 5:a1843b698d0d | 29 | AnalogIn emg0(A0); |
KingMufasa | 5:a1843b698d0d | 30 | AnalogIn emg1(A1); |
KingMufasa | 5:a1843b698d0d | 31 | AnalogIn emg2(A2); |
KingMufasa | 5:a1843b698d0d | 32 | AnalogIn emg3(A3); |
JesseLohman | 0:2a5dd6cc0008 | 33 | |
JesseLohman | 0:2a5dd6cc0008 | 34 | bool stateChanged = true; |
JesseLohman | 0:2a5dd6cc0008 | 35 | |
JesseLohman | 0:2a5dd6cc0008 | 36 | Ticker mainTicker; |
JesseLohman | 0:2a5dd6cc0008 | 37 | Timer stateTimer; |
JesseLohman | 2:5cace74299e7 | 38 | |
JesseLohman | 2:5cace74299e7 | 39 | const double sampleTime = 0.001; |
JesseLohman | 2:5cace74299e7 | 40 | const float maxVelocity=8.4; // in rad/s |
JesseLohman | 2:5cace74299e7 | 41 | const double PI = 3.141592653589793238463; |
JesseLohman | 3:be922ea2415f | 42 | const double L1 = 0.328; |
JesseLohman | 3:be922ea2415f | 43 | const double L2 = 0.218; |
JesseLohman | 3:be922ea2415f | 44 | double T1[3][3] { |
JesseLohman | 3:be922ea2415f | 45 | {0, -1, 0}, |
JesseLohman | 3:be922ea2415f | 46 | {1, 0, 0,}, |
JesseLohman | 3:be922ea2415f | 47 | {0, 0, 0,} |
JesseLohman | 3:be922ea2415f | 48 | }; |
JesseLohman | 3:be922ea2415f | 49 | double T20[3][3] { |
JesseLohman | 3:be922ea2415f | 50 | {0, -1, 0}, |
JesseLohman | 3:be922ea2415f | 51 | {1, 0, -L1,}, |
JesseLohman | 3:be922ea2415f | 52 | {0, 0, 0,} |
JesseLohman | 3:be922ea2415f | 53 | }; |
JesseLohman | 3:be922ea2415f | 54 | double H200[3][3] { |
JesseLohman | 3:be922ea2415f | 55 | {1, 0, L1+L2}, |
JesseLohman | 3:be922ea2415f | 56 | {0, 1, 0,}, |
JesseLohman | 3:be922ea2415f | 57 | {0, 0, 1,} |
JesseLohman | 3:be922ea2415f | 58 | }; |
JesseLohman | 3:be922ea2415f | 59 | double Pe2 [3][1] { |
JesseLohman | 3:be922ea2415f | 60 | {0}, |
JesseLohman | 3:be922ea2415f | 61 | {0}, |
JesseLohman | 3:be922ea2415f | 62 | {1} |
JesseLohman | 3:be922ea2415f | 63 | }; |
JesseLohman | 3:be922ea2415f | 64 | |
JesseLohman | 3:be922ea2415f | 65 | double u1; |
JesseLohman | 3:be922ea2415f | 66 | double u2; // u1 is motor output of the long link, u2 is motor of the short link, u3 is motor of gripper, u4 is motor of screwer |
JesseLohman | 3:be922ea2415f | 67 | double u3; |
JesseLohman | 3:be922ea2415f | 68 | double u4; |
JesseLohman | 2:5cace74299e7 | 69 | FastPWM pwmpin1(D5); //motor pwm |
JesseLohman | 2:5cace74299e7 | 70 | DigitalOut directionpin1(D4); // motor direction |
JesseLohman | 3:be922ea2415f | 71 | FastPWM pwmpin2 (D6); |
JesseLohman | 3:be922ea2415f | 72 | DigitalOut directionpin2 (D7); |
KingMufasa | 5:a1843b698d0d | 73 | double setPointX = 0.218; |
KingMufasa | 5:a1843b698d0d | 74 | double setPointY = 0.328; |
JesseLohman | 3:be922ea2415f | 75 | double qRef1; |
JesseLohman | 3:be922ea2415f | 76 | double qRef2; |
JesseLohman | 3:be922ea2415f | 77 | double qMeas1; |
JesseLohman | 3:be922ea2415f | 78 | double qMeas2; |
JesseLohman | 2:5cace74299e7 | 79 | |
JesseLohman | 3:be922ea2415f | 80 | double v; // Global variable for printf |
JesseLohman | 3:be922ea2415f | 81 | double Dpulses; // Global variable for printf |
KingMufasa | 4:8f25ecb74221 | 82 | double error1; // Global variable for printf |
KingMufasa | 5:a1843b698d0d | 83 | double error2; // Global variable for printf |
KingMufasa | 6:e67250b8b100 | 84 | double pulses1; // Global varaible for printf |
KingMufasa | 6:e67250b8b100 | 85 | double pulses2; // Global varaible for printf |
JesseLohman | 3:be922ea2415f | 86 | |
JesseLohman | 3:be922ea2415f | 87 | double C[5][5]; |
JesseLohman | 3:be922ea2415f | 88 | |
KingMufasa | 6:e67250b8b100 | 89 | double Kp1 = 150; |
KingMufasa | 6:e67250b8b100 | 90 | double Ki1 = 1; |
KingMufasa | 6:e67250b8b100 | 91 | double Kd1 = 10; |
KingMufasa | 6:e67250b8b100 | 92 | double Kp2 = 50; |
KingMufasa | 6:e67250b8b100 | 93 | double Ki2 = 0.1; |
KingMufasa | 6:e67250b8b100 | 94 | double Kd2 = 10; |
KingMufasa | 5:a1843b698d0d | 95 | |
KingMufasa | 5:a1843b698d0d | 96 | const int samplepack = 250; //Amount of data points before one cycle completes |
KingMufasa | 5:a1843b698d0d | 97 | volatile int counter = 0; //Counts the amount of readings this cycle |
KingMufasa | 5:a1843b698d0d | 98 | volatile double total[4] = {0,0,0,0}; //Total difference between data points and the calibration value this cycle (x+, x-, y+, y-) |
KingMufasa | 5:a1843b698d0d | 99 | double refvaluebic = 10; //Minimum total value for the motor to move (biceps) |
KingMufasa | 5:a1843b698d0d | 100 | double refvaluecalf = 50; //Minimum total value for the motor to move (calfs) |
KingMufasa | 5:a1843b698d0d | 101 | double incr = 0.00005; //increment |
KingMufasa | 5:a1843b698d0d | 102 | bool moving[4] = {0,0,0,0}; //x+, x-, y+, y- |
KingMufasa | 5:a1843b698d0d | 103 | |
KingMufasa | 5:a1843b698d0d | 104 | BiQuad hpf(0.8635,-1.7269,0.8635,-1.9359,0.9394); //5Hz High pass filter |
KingMufasa | 5:a1843b698d0d | 105 | BiQuad notch(0.9922,-1.6054,0.9922,-1.6054,0.9844); //50 Hz Notch filter |
KingMufasa | 5:a1843b698d0d | 106 | BiQuad lpf(0.9780,1.9561,0.9780,1.9556,0.9565); //250Hz Low pass filter |
KingMufasa | 5:a1843b698d0d | 107 | BiQuadChain bqc; |
JesseLohman | 0:2a5dd6cc0008 | 108 | |
JesseLohman | 0:2a5dd6cc0008 | 109 | void switchToFailureState () |
JesseLohman | 0:2a5dd6cc0008 | 110 | { |
JesseLohman | 0:2a5dd6cc0008 | 111 | failureButton.fall(NULL); // Detaches button, so it can only be activated once |
JesseLohman | 1:4cb9af313c26 | 112 | led1 = 0; |
JesseLohman | 1:4cb9af313c26 | 113 | led2 = 1; |
JesseLohman | 1:4cb9af313c26 | 114 | led3 = 1; |
JesseLohman | 1:4cb9af313c26 | 115 | pc.printf("SYSTEM FAILED\n"); |
JesseLohman | 0:2a5dd6cc0008 | 116 | currentState = FailureState; |
JesseLohman | 0:2a5dd6cc0008 | 117 | stateChanged = true; |
JesseLohman | 0:2a5dd6cc0008 | 118 | } |
JesseLohman | 0:2a5dd6cc0008 | 119 | |
KingMufasa | 5:a1843b698d0d | 120 | void measureEMG () |
KingMufasa | 5:a1843b698d0d | 121 | { |
KingMufasa | 5:a1843b698d0d | 122 | total[0] += abs(bqc.step(emg0.read())); |
KingMufasa | 5:a1843b698d0d | 123 | total[1] += abs(bqc.step(emg1.read())); |
KingMufasa | 5:a1843b698d0d | 124 | total[2] += abs(bqc.step(emg2.read())); |
KingMufasa | 5:a1843b698d0d | 125 | total[3] += abs(bqc.step(emg3.read())); |
KingMufasa | 5:a1843b698d0d | 126 | counter++; |
KingMufasa | 5:a1843b698d0d | 127 | if (counter >= samplepack){ |
KingMufasa | 5:a1843b698d0d | 128 | moving[0] = 0; |
KingMufasa | 5:a1843b698d0d | 129 | moving[1] = 0; |
KingMufasa | 5:a1843b698d0d | 130 | moving[2] = 0; |
KingMufasa | 5:a1843b698d0d | 131 | moving[3] = 0; |
KingMufasa | 5:a1843b698d0d | 132 | if (total[0] >= refvaluebic){ |
KingMufasa | 5:a1843b698d0d | 133 | moving[0] = 1; |
KingMufasa | 5:a1843b698d0d | 134 | } |
KingMufasa | 5:a1843b698d0d | 135 | if (total[1] >= refvaluebic){ |
KingMufasa | 5:a1843b698d0d | 136 | moving[1] = 1; |
KingMufasa | 5:a1843b698d0d | 137 | } |
KingMufasa | 5:a1843b698d0d | 138 | if (total[2] >= refvaluecalf){ |
KingMufasa | 5:a1843b698d0d | 139 | moving[2] = 1; |
KingMufasa | 5:a1843b698d0d | 140 | } |
KingMufasa | 5:a1843b698d0d | 141 | if (total[3] >= refvaluecalf){ |
KingMufasa | 5:a1843b698d0d | 142 | moving[3] = 1; |
KingMufasa | 5:a1843b698d0d | 143 | } |
KingMufasa | 6:e67250b8b100 | 144 | //pc.printf("Totals of {x+,x-,y+,y-} are %f, %f, %f, %f \r\n",total[0],total[1],total[2],total[3]); |
KingMufasa | 6:e67250b8b100 | 145 | pc.printf("Coordinates: (%f,%f)\r\n", setPointX, setPointY); |
KingMufasa | 5:a1843b698d0d | 146 | counter = 0; //Reset for next cycle |
KingMufasa | 5:a1843b698d0d | 147 | for (int i=0;i<4;i++){ //clear 'total' array |
KingMufasa | 5:a1843b698d0d | 148 | total[i] = 0; |
KingMufasa | 5:a1843b698d0d | 149 | } |
KingMufasa | 5:a1843b698d0d | 150 | } |
KingMufasa | 6:e67250b8b100 | 151 | |
KingMufasa | 5:a1843b698d0d | 152 | if(moving[0]){ |
KingMufasa | 5:a1843b698d0d | 153 | setPointX += incr; |
KingMufasa | 5:a1843b698d0d | 154 | } |
KingMufasa | 5:a1843b698d0d | 155 | if (moving[1]){ |
KingMufasa | 5:a1843b698d0d | 156 | setPointX -= incr; |
KingMufasa | 5:a1843b698d0d | 157 | } |
KingMufasa | 5:a1843b698d0d | 158 | if (moving[2]){ |
KingMufasa | 5:a1843b698d0d | 159 | setPointY += incr; |
KingMufasa | 5:a1843b698d0d | 160 | } |
KingMufasa | 5:a1843b698d0d | 161 | if (moving[3]){ |
KingMufasa | 5:a1843b698d0d | 162 | setPointY -= incr; |
KingMufasa | 5:a1843b698d0d | 163 | } |
KingMufasa | 6:e67250b8b100 | 164 | |
KingMufasa | 5:a1843b698d0d | 165 | } |
KingMufasa | 5:a1843b698d0d | 166 | |
JesseLohman | 2:5cace74299e7 | 167 | double measureVelocity (int motor) |
JesseLohman | 2:5cace74299e7 | 168 | { |
JesseLohman | 2:5cace74299e7 | 169 | static double lastPulses = 0; |
JesseLohman | 2:5cace74299e7 | 170 | double currentPulses; |
JesseLohman | 2:5cace74299e7 | 171 | static double velocity = 0; |
JesseLohman | 3:be922ea2415f | 172 | |
JesseLohman | 2:5cace74299e7 | 173 | static int i = 0; |
JesseLohman | 2:5cace74299e7 | 174 | if (i == 10) { // Encoder is not accurate enough, so with 1000 Hz the velocity can only be 0, 1000, 2000 or 3000 pulses/s |
JesseLohman | 3:be922ea2415f | 175 | switch (motor) { // Check which motor to measure |
JesseLohman | 3:be922ea2415f | 176 | case 1: |
JesseLohman | 3:be922ea2415f | 177 | currentPulses = encoder1.getPulses(); |
JesseLohman | 3:be922ea2415f | 178 | break; |
JesseLohman | 3:be922ea2415f | 179 | case 2: |
JesseLohman | 3:be922ea2415f | 180 | //currentPulses = encoder2.getPulses(); |
JesseLohman | 3:be922ea2415f | 181 | break; |
JesseLohman | 3:be922ea2415f | 182 | case 3: |
JesseLohman | 3:be922ea2415f | 183 | //currentPulses = encoder3.getPulses(); |
JesseLohman | 3:be922ea2415f | 184 | break; |
JesseLohman | 3:be922ea2415f | 185 | } |
JesseLohman | 2:5cace74299e7 | 186 | |
JesseLohman | 3:be922ea2415f | 187 | double deltaPulses = currentPulses - lastPulses; |
JesseLohman | 3:be922ea2415f | 188 | Dpulses = deltaPulses; |
JesseLohman | 3:be922ea2415f | 189 | velocity = deltaPulses / (sampleTime * 10); // Velocity in pulses/s |
JesseLohman | 3:be922ea2415f | 190 | lastPulses = currentPulses; |
JesseLohman | 3:be922ea2415f | 191 | i = 0; |
JesseLohman | 2:5cace74299e7 | 192 | } else { |
JesseLohman | 2:5cace74299e7 | 193 | i += 1; |
JesseLohman | 2:5cace74299e7 | 194 | } |
JesseLohman | 2:5cace74299e7 | 195 | v = velocity; |
JesseLohman | 2:5cace74299e7 | 196 | return velocity; |
JesseLohman | 2:5cace74299e7 | 197 | } |
JesseLohman | 2:5cace74299e7 | 198 | |
JesseLohman | 3:be922ea2415f | 199 | void measurePosition() // Measure actual angle position with the encoder |
JesseLohman | 2:5cace74299e7 | 200 | { |
KingMufasa | 6:e67250b8b100 | 201 | pulses1 = encoder2.getPulses(); // motor 1 is on M2 and ENC2 of biorobotics shield |
KingMufasa | 6:e67250b8b100 | 202 | pulses2 = encoder1.getPulses(); // motor 2 is on M1 and ENC1 of biorobotics shield |
KingMufasa | 6:e67250b8b100 | 203 | qMeas1 = (pulses1) * 2 * PI / 8400 +140.7*PI/180 ; // Calculate the angle relative to the starting point (8400 pulses per revolution) + offset |
KingMufasa | 6:e67250b8b100 | 204 | qMeas2 = (pulses2) * 2 * PI / 8400 - 93*PI/180 ; |
JesseLohman | 2:5cace74299e7 | 205 | |
JesseLohman | 2:5cace74299e7 | 206 | } |
JesseLohman | 2:5cace74299e7 | 207 | |
JesseLohman | 2:5cace74299e7 | 208 | void getMotorControlSignal () // Milestone 1 code, not relevant anymore |
JesseLohman | 2:5cace74299e7 | 209 | { |
JesseLohman | 3:be922ea2415f | 210 | double potSignal = pot.read() * 2 - 1; // read pot and scale to motor control signal |
JesseLohman | 3:be922ea2415f | 211 | //pc.printf("motor control signal = %f\n", posampleTimeignal); |
JesseLohman | 2:5cace74299e7 | 212 | u1 = potSignal; |
JesseLohman | 3:be922ea2415f | 213 | u2 = potSignal; |
JesseLohman | 3:be922ea2415f | 214 | } |
JesseLohman | 3:be922ea2415f | 215 | |
JesseLohman | 3:be922ea2415f | 216 | template<std::size_t N, std::size_t M, std::size_t P> |
JesseLohman | 3:be922ea2415f | 217 | void mult(double A[N][M], double B[M][P]) |
JesseLohman | 3:be922ea2415f | 218 | { |
JesseLohman | 3:be922ea2415f | 219 | |
JesseLohman | 3:be922ea2415f | 220 | for( int n =0; n < 5; n++) { |
JesseLohman | 3:be922ea2415f | 221 | for(int p =0; p < 5; p++) { |
JesseLohman | 3:be922ea2415f | 222 | C[n][p] =0; |
JesseLohman | 3:be922ea2415f | 223 | } |
JesseLohman | 3:be922ea2415f | 224 | } |
JesseLohman | 3:be922ea2415f | 225 | for (int n = 0; n < N; n++) { |
JesseLohman | 3:be922ea2415f | 226 | for (int p = 0; p < P; p++) { |
JesseLohman | 3:be922ea2415f | 227 | double num = 0; |
JesseLohman | 3:be922ea2415f | 228 | for (int m = 0; m < M; m++) { |
JesseLohman | 3:be922ea2415f | 229 | num += A[n][m] * B[m][p]; |
JesseLohman | 3:be922ea2415f | 230 | |
JesseLohman | 3:be922ea2415f | 231 | } |
JesseLohman | 3:be922ea2415f | 232 | |
JesseLohman | 3:be922ea2415f | 233 | C[n][p] = num; |
JesseLohman | 3:be922ea2415f | 234 | |
JesseLohman | 3:be922ea2415f | 235 | } |
JesseLohman | 3:be922ea2415f | 236 | } |
JesseLohman | 3:be922ea2415f | 237 | |
JesseLohman | 3:be922ea2415f | 238 | } |
JesseLohman | 3:be922ea2415f | 239 | |
JesseLohman | 3:be922ea2415f | 240 | void inverseKinematics () |
JesseLohman | 3:be922ea2415f | 241 | { |
JesseLohman | 3:be922ea2415f | 242 | if (currentState == MovingState) { // Only in the HomingState should the qRef1, qRef2 consistently change |
KingMufasa | 6:e67250b8b100 | 243 | |
JesseLohman | 3:be922ea2415f | 244 | double Pe_set[3][1] { // defining setpoint location of end effector |
KingMufasa | 6:e67250b8b100 | 245 | {setPointX}, //setting xcoord to pot 1 |
KingMufasa | 6:e67250b8b100 | 246 | {setPointY}, // setting ycoord to pot 2 |
JesseLohman | 3:be922ea2415f | 247 | {1} |
JesseLohman | 3:be922ea2415f | 248 | }; |
JesseLohman | 3:be922ea2415f | 249 | |
JesseLohman | 3:be922ea2415f | 250 | //Calculating new H matrix |
JesseLohman | 3:be922ea2415f | 251 | double T1e[3][3] { |
JesseLohman | 3:be922ea2415f | 252 | {cos(qRef1), -sin(qRef1), 0}, |
JesseLohman | 3:be922ea2415f | 253 | {sin(qRef1), cos(qRef1), 0}, |
JesseLohman | 3:be922ea2415f | 254 | {0, 0, 1} |
JesseLohman | 3:be922ea2415f | 255 | }; |
JesseLohman | 3:be922ea2415f | 256 | double T20e[3][3] { |
JesseLohman | 3:be922ea2415f | 257 | {cos(qRef2), -sin(qRef2), L1-L1*cos(qRef2)}, |
JesseLohman | 3:be922ea2415f | 258 | {sin(qRef2), cos(qRef2), -L1*sin(qRef2)}, |
JesseLohman | 3:be922ea2415f | 259 | {0, 0, 1} |
JesseLohman | 3:be922ea2415f | 260 | }; |
JesseLohman | 3:be922ea2415f | 261 | |
JesseLohman | 3:be922ea2415f | 262 | |
JesseLohman | 3:be922ea2415f | 263 | mult<3,3,3>(T1e,T20e); // matrix multiplication |
JesseLohman | 3:be922ea2415f | 264 | double H201[3][3] { |
JesseLohman | 3:be922ea2415f | 265 | {C[0][0],C[0][1],C[0][2]}, |
JesseLohman | 3:be922ea2415f | 266 | {C[1][0],C[1][1],C[1][2]}, |
JesseLohman | 3:be922ea2415f | 267 | {C[2][0],C[2][1],C[2][2]} |
JesseLohman | 3:be922ea2415f | 268 | }; |
JesseLohman | 3:be922ea2415f | 269 | |
JesseLohman | 3:be922ea2415f | 270 | mult<3,3,3>(H201,H200); // matrix multiplication |
JesseLohman | 3:be922ea2415f | 271 | double H20 [3][3] { |
JesseLohman | 3:be922ea2415f | 272 | {C[0][0],C[0][1],C[0][2]}, |
JesseLohman | 3:be922ea2415f | 273 | {C[1][0],C[1][1],C[1][2]}, |
JesseLohman | 3:be922ea2415f | 274 | {C[2][0],C[2][1],C[2][2]} |
JesseLohman | 3:be922ea2415f | 275 | }; |
JesseLohman | 3:be922ea2415f | 276 | |
JesseLohman | 3:be922ea2415f | 277 | mult<3,3,1>(H20,Pe2); // matrix multiplication |
JesseLohman | 3:be922ea2415f | 278 | double Pe0[3][1] { |
JesseLohman | 3:be922ea2415f | 279 | {C[0][0]}, |
JesseLohman | 3:be922ea2415f | 280 | {C[1][0]}, |
JesseLohman | 3:be922ea2415f | 281 | {C[2][0]} |
JesseLohman | 3:be922ea2415f | 282 | }; |
JesseLohman | 3:be922ea2415f | 283 | |
JesseLohman | 3:be922ea2415f | 284 | double pe0x = Pe0[0][0]; // seperating coordinates of end effector location |
JesseLohman | 3:be922ea2415f | 285 | double pe0y = Pe0[1][0]; |
JesseLohman | 3:be922ea2415f | 286 | |
JesseLohman | 3:be922ea2415f | 287 | // Determing the jacobian |
JesseLohman | 3:be922ea2415f | 288 | |
JesseLohman | 3:be922ea2415f | 289 | double T_1[3][1] { |
JesseLohman | 3:be922ea2415f | 290 | {1}, |
JesseLohman | 3:be922ea2415f | 291 | {T1[0][2]}, |
JesseLohman | 3:be922ea2415f | 292 | {T1[1][2]} |
JesseLohman | 3:be922ea2415f | 293 | }; |
JesseLohman | 3:be922ea2415f | 294 | |
JesseLohman | 3:be922ea2415f | 295 | double T_2[3][1] { |
JesseLohman | 3:be922ea2415f | 296 | {1}, |
JesseLohman | 3:be922ea2415f | 297 | {L1*sin(qRef1)}, |
JesseLohman | 3:be922ea2415f | 298 | {-L1*cos(qRef1)} |
JesseLohman | 3:be922ea2415f | 299 | }; |
JesseLohman | 3:be922ea2415f | 300 | |
JesseLohman | 3:be922ea2415f | 301 | double J[3][2] { |
JesseLohman | 3:be922ea2415f | 302 | {T_1[0][0], T_2[0][0]}, |
JesseLohman | 3:be922ea2415f | 303 | {T_1[1][0], T_2[1][0]}, |
JesseLohman | 3:be922ea2415f | 304 | {T_1[2][0], T_2[2][0]} |
JesseLohman | 3:be922ea2415f | 305 | }; |
JesseLohman | 3:be922ea2415f | 306 | |
JesseLohman | 3:be922ea2415f | 307 | //Determing 'Pulling" force to setpoint |
JesseLohman | 3:be922ea2415f | 308 | |
KingMufasa | 6:e67250b8b100 | 309 | double kspring= 1; //virtual stifness of the force |
JesseLohman | 3:be922ea2415f | 310 | double Fs[3][1] { //force vector from end effector to setpoint |
KingMufasa | 6:e67250b8b100 | 311 | {kspring*Pe_set[0][0] - kspring*Pe0[0][0]}, |
KingMufasa | 6:e67250b8b100 | 312 | {kspring*Pe_set[1][0] - kspring*Pe0[1][0]}, |
KingMufasa | 6:e67250b8b100 | 313 | {kspring*Pe_set[2][0] - kspring*Pe0[2][0]} |
JesseLohman | 3:be922ea2415f | 314 | }; |
KingMufasa | 6:e67250b8b100 | 315 | double Fx = kspring*setPointX - kspring*pe0x; |
KingMufasa | 6:e67250b8b100 | 316 | double Fy = kspring*setPointY - kspring*pe0y; |
JesseLohman | 3:be922ea2415f | 317 | double W0t[3][1] { |
JesseLohman | 3:be922ea2415f | 318 | {pe0x*Fy - pe0y*Fx}, |
JesseLohman | 3:be922ea2415f | 319 | {Fx}, |
JesseLohman | 3:be922ea2415f | 320 | {Fy} |
JesseLohman | 3:be922ea2415f | 321 | }; |
JesseLohman | 3:be922ea2415f | 322 | |
JesseLohman | 3:be922ea2415f | 323 | double Jt[2][3] { // transposing jacobian matrix |
JesseLohman | 3:be922ea2415f | 324 | {J[0][0], J[1][0], J[2][0]}, |
JesseLohman | 3:be922ea2415f | 325 | {T_2[0][0], T_2[1][0], T_2[2][0]} |
JesseLohman | 3:be922ea2415f | 326 | }; |
JesseLohman | 3:be922ea2415f | 327 | |
JesseLohman | 3:be922ea2415f | 328 | mult<2,3,1>(Jt,W0t); |
JesseLohman | 3:be922ea2415f | 329 | double tau_st1 = C[0][0]; |
JesseLohman | 3:be922ea2415f | 330 | double tau_st2 = C[1][0]; |
JesseLohman | 3:be922ea2415f | 331 | |
JesseLohman | 3:be922ea2415f | 332 | //Calculating joint behaviour |
JesseLohman | 3:be922ea2415f | 333 | |
KingMufasa | 6:e67250b8b100 | 334 | double b1 =10; |
KingMufasa | 5:a1843b698d0d | 335 | double b2 =1; |
JesseLohman | 3:be922ea2415f | 336 | //joint friction coefficent |
JesseLohman | 3:be922ea2415f | 337 | //double sampleTime = 1/1000; //Time step to reach the new angle |
KingMufasa | 4:8f25ecb74221 | 338 | double w_s1 = tau_st1/b1; // angular velocity |
KingMufasa | 4:8f25ecb74221 | 339 | double w_s2 = tau_st2/b2; // angular velocity |
JesseLohman | 3:be922ea2415f | 340 | //checking angle boundaries |
KingMufasa | 5:a1843b698d0d | 341 | qRef1 = qRef1 +w_s1*1; // calculating new angle of qRef1 in time step sampleTime |
JesseLohman | 3:be922ea2415f | 342 | if (qRef1 > 2*PI/3) { |
JesseLohman | 3:be922ea2415f | 343 | qRef1 = 2*PI/3; |
JesseLohman | 3:be922ea2415f | 344 | } else if (qRef1 < PI/6) { |
JesseLohman | 3:be922ea2415f | 345 | qRef1= PI/6; |
JesseLohman | 3:be922ea2415f | 346 | } |
JesseLohman | 3:be922ea2415f | 347 | |
KingMufasa | 5:a1843b698d0d | 348 | qRef2 = qRef2 + w_s2*1; // calculating new angle of qRef2 in time step sampleTime |
JesseLohman | 3:be922ea2415f | 349 | if (qRef2 > -PI/4) { |
JesseLohman | 3:be922ea2415f | 350 | qRef2 = -PI/4; |
JesseLohman | 3:be922ea2415f | 351 | } else if (qRef2 < -PI/2) { |
JesseLohman | 3:be922ea2415f | 352 | qRef2= -PI/2; |
JesseLohman | 3:be922ea2415f | 353 | } |
JesseLohman | 3:be922ea2415f | 354 | } |
JesseLohman | 3:be922ea2415f | 355 | } |
JesseLohman | 3:be922ea2415f | 356 | void PID_controller() // Put the error trough PID control to make output 'u' |
KingMufasa | 5:a1843b698d0d | 357 | |
JesseLohman | 3:be922ea2415f | 358 | { |
KingMufasa | 5:a1843b698d0d | 359 | if (currentState >= HomingState && currentState < FailureState){ |
KingMufasa | 4:8f25ecb74221 | 360 | // Should only work when we move the robot to a defined position |
KingMufasa | 5:a1843b698d0d | 361 | error1 = qRef1 - qMeas1; |
KingMufasa | 5:a1843b698d0d | 362 | error2 = qRef2 - qMeas2; |
JesseLohman | 3:be922ea2415f | 363 | |
JesseLohman | 3:be922ea2415f | 364 | static double errorIntegral1 = 0; |
JesseLohman | 3:be922ea2415f | 365 | static double errorIntegral2 = 0; |
JesseLohman | 3:be922ea2415f | 366 | static double errorPrev1 = error1; |
JesseLohman | 3:be922ea2415f | 367 | static double errorPrev2 = error2; |
JesseLohman | 3:be922ea2415f | 368 | static BiQuad LowPassFilter(0.0640, 0.1279, 0.0640, -1.1683, 0.4241); |
JesseLohman | 3:be922ea2415f | 369 | //Ki = pot2.read() * 0.5; //Only Kd is controlled by a pot, Kp and Ki are constant |
JesseLohman | 3:be922ea2415f | 370 | |
KingMufasa | 4:8f25ecb74221 | 371 | // Proportional part: |
KingMufasa | 4:8f25ecb74221 | 372 | double Kp = pot2.read() * 0.001; |
KingMufasa | 4:8f25ecb74221 | 373 | double u_k1 = Kp1 * error1; |
KingMufasa | 4:8f25ecb74221 | 374 | double u_k2 = Kp2 * error2; |
JesseLohman | 3:be922ea2415f | 375 | |
JesseLohman | 3:be922ea2415f | 376 | //Integral part: |
JesseLohman | 3:be922ea2415f | 377 | errorIntegral1 = errorIntegral1 + error1 * sampleTime; |
KingMufasa | 4:8f25ecb74221 | 378 | double u_i1 = Ki1 * errorIntegral1; |
JesseLohman | 3:be922ea2415f | 379 | errorIntegral2 = errorIntegral2 + error2 * sampleTime; |
KingMufasa | 4:8f25ecb74221 | 380 | double u_i2 = Ki2 * errorIntegral2; |
JesseLohman | 3:be922ea2415f | 381 | |
JesseLohman | 3:be922ea2415f | 382 | // Derivative part |
JesseLohman | 3:be922ea2415f | 383 | double errorDerivative1 = (error1 - errorPrev1)/sampleTime; |
JesseLohman | 3:be922ea2415f | 384 | double filteredErrorDerivative1 = LowPassFilter.step(errorDerivative1); |
KingMufasa | 4:8f25ecb74221 | 385 | double u_d1 = Kd1 * filteredErrorDerivative1; |
JesseLohman | 3:be922ea2415f | 386 | errorPrev1 = error1; |
JesseLohman | 3:be922ea2415f | 387 | double errorDerivative2 = (error2 - errorPrev2)/sampleTime; |
JesseLohman | 3:be922ea2415f | 388 | double filteredErrorDerivative2 = LowPassFilter.step(errorDerivative2); |
KingMufasa | 4:8f25ecb74221 | 389 | double u_d2 = Kd2 * filteredErrorDerivative2; |
JesseLohman | 3:be922ea2415f | 390 | errorPrev2 = error2; |
JesseLohman | 3:be922ea2415f | 391 | |
JesseLohman | 3:be922ea2415f | 392 | // Sum all parsampleTime |
JesseLohman | 3:be922ea2415f | 393 | u1 = u_k1 + u_i1 + u_d1; |
JesseLohman | 3:be922ea2415f | 394 | u2 = u_k2 + u_i2 + u_d2; |
KingMufasa | 5:a1843b698d0d | 395 | |
KingMufasa | 4:8f25ecb74221 | 396 | |
KingMufasa | 5:a1843b698d0d | 397 | } |
JesseLohman | 2:5cace74299e7 | 398 | } |
JesseLohman | 2:5cace74299e7 | 399 | |
JesseLohman | 2:5cace74299e7 | 400 | void controlMotor () // Control direction and speed |
JesseLohman | 2:5cace74299e7 | 401 | { |
JesseLohman | 2:5cace74299e7 | 402 | directionpin1 = u1 > 0.0f; // Either true or false |
JesseLohman | 2:5cace74299e7 | 403 | pwmpin1 = fabs(u1); |
JesseLohman | 3:be922ea2415f | 404 | directionpin2 = u2 > 0.0f; // Either true or false |
JesseLohman | 3:be922ea2415f | 405 | pwmpin2 = fabs(u2); |
JesseLohman | 2:5cace74299e7 | 406 | } |
JesseLohman | 2:5cace74299e7 | 407 | |
JesseLohman | 0:2a5dd6cc0008 | 408 | void stateMachine () |
JesseLohman | 0:2a5dd6cc0008 | 409 | { |
JesseLohman | 0:2a5dd6cc0008 | 410 | switch (currentState) { |
JesseLohman | 0:2a5dd6cc0008 | 411 | case WaitState: |
JesseLohman | 0:2a5dd6cc0008 | 412 | if (stateChanged == true) { |
JesseLohman | 1:4cb9af313c26 | 413 | led1 = 0; |
JesseLohman | 1:4cb9af313c26 | 414 | led2 = 1; |
JesseLohman | 1:4cb9af313c26 | 415 | led3 = 1; |
JesseLohman | 0:2a5dd6cc0008 | 416 | // Entry action: all the things you do once in this state |
JesseLohman | 2:5cace74299e7 | 417 | u1 = 0; // Turn off all motors |
JesseLohman | 2:5cace74299e7 | 418 | u2 = 0; |
JesseLohman | 2:5cace74299e7 | 419 | u3 = 0; |
JesseLohman | 2:5cace74299e7 | 420 | u4 = 0; |
JesseLohman | 0:2a5dd6cc0008 | 421 | stateChanged = false; |
JesseLohman | 0:2a5dd6cc0008 | 422 | } |
JesseLohman | 0:2a5dd6cc0008 | 423 | |
JesseLohman | 2:5cace74299e7 | 424 | if (startButton.read() == false) { // When button is pressed, value is false |
JesseLohman | 1:4cb9af313c26 | 425 | //pc.printf("Switching to motor calibration"); |
JesseLohman | 1:4cb9af313c26 | 426 | led1 = 1; |
JesseLohman | 0:2a5dd6cc0008 | 427 | currentState = MotorCalState; |
JesseLohman | 0:2a5dd6cc0008 | 428 | stateChanged = true; |
JesseLohman | 0:2a5dd6cc0008 | 429 | } |
JesseLohman | 0:2a5dd6cc0008 | 430 | |
JesseLohman | 0:2a5dd6cc0008 | 431 | break; |
JesseLohman | 0:2a5dd6cc0008 | 432 | case MotorCalState: |
JesseLohman | 0:2a5dd6cc0008 | 433 | if (stateChanged == true) { |
JesseLohman | 0:2a5dd6cc0008 | 434 | // Entry action: all the things you do once in this state |
JesseLohman | 1:4cb9af313c26 | 435 | led2 = 0; |
JesseLohman | 0:2a5dd6cc0008 | 436 | // Set motorpwm to 'low' value |
JesseLohman | 3:be922ea2415f | 437 | //u1 = 0.6; //TODO: Check if direction is right |
JesseLohman | 3:be922ea2415f | 438 | //u2 = 0.6; |
JesseLohman | 0:2a5dd6cc0008 | 439 | stateTimer.reset(); |
JesseLohman | 0:2a5dd6cc0008 | 440 | stateTimer.start(); |
JesseLohman | 0:2a5dd6cc0008 | 441 | stateChanged = false; |
JesseLohman | 0:2a5dd6cc0008 | 442 | } |
JesseLohman | 0:2a5dd6cc0008 | 443 | |
JesseLohman | 0:2a5dd6cc0008 | 444 | // Add stuff you do every loop |
JesseLohman | 2:5cace74299e7 | 445 | getMotorControlSignal(); |
JesseLohman | 0:2a5dd6cc0008 | 446 | |
JesseLohman | 3:be922ea2415f | 447 | if (stateTimer >= 3.0f && fabs(measureVelocity(1)) < 100 && screwingSwitch.read() == false) { //TODO: add && fabs(measureVelocity(2)) < 0.1f |
JesseLohman | 2:5cace74299e7 | 448 | //TODO: Add reset of encoder2 |
JesseLohman | 1:4cb9af313c26 | 449 | led2 = 1; |
JesseLohman | 2:5cace74299e7 | 450 | encoder1.reset(); // Reset encoder for the 0 position |
JesseLohman | 0:2a5dd6cc0008 | 451 | currentState = EMGCalState; |
JesseLohman | 0:2a5dd6cc0008 | 452 | stateChanged = true; |
JesseLohman | 2:5cace74299e7 | 453 | u1 = 0; // Turn off motors |
JesseLohman | 2:5cace74299e7 | 454 | u2 = 0; |
JesseLohman | 0:2a5dd6cc0008 | 455 | } |
JesseLohman | 0:2a5dd6cc0008 | 456 | break; |
JesseLohman | 0:2a5dd6cc0008 | 457 | case EMGCalState: |
JesseLohman | 0:2a5dd6cc0008 | 458 | if (stateChanged == true) { |
JesseLohman | 0:2a5dd6cc0008 | 459 | // Entry action: all the things you do once in this state; |
JesseLohman | 1:4cb9af313c26 | 460 | led3 = 0; |
JesseLohman | 0:2a5dd6cc0008 | 461 | stateTimer.reset(); |
JesseLohman | 0:2a5dd6cc0008 | 462 | stateTimer.start(); |
JesseLohman | 0:2a5dd6cc0008 | 463 | stateChanged = false; |
JesseLohman | 0:2a5dd6cc0008 | 464 | } |
JesseLohman | 0:2a5dd6cc0008 | 465 | |
JesseLohman | 0:2a5dd6cc0008 | 466 | // Add stuff you do every loop |
JesseLohman | 0:2a5dd6cc0008 | 467 | |
JesseLohman | 0:2a5dd6cc0008 | 468 | if (stateTimer >= 3.0f) { |
JesseLohman | 1:4cb9af313c26 | 469 | //pc.printf("Starting homing...\n"); |
JesseLohman | 1:4cb9af313c26 | 470 | led3 = 1; |
JesseLohman | 0:2a5dd6cc0008 | 471 | currentState = HomingState; |
JesseLohman | 0:2a5dd6cc0008 | 472 | stateChanged = true; |
JesseLohman | 0:2a5dd6cc0008 | 473 | } |
JesseLohman | 0:2a5dd6cc0008 | 474 | break; |
JesseLohman | 0:2a5dd6cc0008 | 475 | case HomingState: |
JesseLohman | 0:2a5dd6cc0008 | 476 | if (stateChanged == true) { |
JesseLohman | 0:2a5dd6cc0008 | 477 | // Entry action: all the things you do once in this state; |
JesseLohman | 1:4cb9af313c26 | 478 | led1 = 0; |
JesseLohman | 3:be922ea2415f | 479 | led2 = 0; // EmisampleTime yellow together |
JesseLohman | 3:be922ea2415f | 480 | //TODO: Set qRef1 and qRef2 |
KingMufasa | 5:a1843b698d0d | 481 | qRef1 = 90 * PI / 180; |
KingMufasa | 6:e67250b8b100 | 482 | qRef2 = -qRef1 + 0 *PI/180; |
JesseLohman | 0:2a5dd6cc0008 | 483 | stateChanged = false; |
JesseLohman | 0:2a5dd6cc0008 | 484 | } |
JesseLohman | 0:2a5dd6cc0008 | 485 | |
JesseLohman | 0:2a5dd6cc0008 | 486 | // Nothing extra happens till robot reaches starting position and button is pressed |
JesseLohman | 0:2a5dd6cc0008 | 487 | |
JesseLohman | 1:4cb9af313c26 | 488 | if (startButton.read() == false) { //TODO: Also add position condition |
JesseLohman | 1:4cb9af313c26 | 489 | led1 = 1; |
JesseLohman | 1:4cb9af313c26 | 490 | led2 = 1; |
JesseLohman | 0:2a5dd6cc0008 | 491 | currentState = MovingState; |
JesseLohman | 0:2a5dd6cc0008 | 492 | stateChanged = true; |
JesseLohman | 0:2a5dd6cc0008 | 493 | } |
JesseLohman | 0:2a5dd6cc0008 | 494 | break; |
JesseLohman | 0:2a5dd6cc0008 | 495 | case MovingState: |
JesseLohman | 1:4cb9af313c26 | 496 | if (stateChanged == true) { |
JesseLohman | 0:2a5dd6cc0008 | 497 | // Entry action: all the things you do once in this state; |
JesseLohman | 1:4cb9af313c26 | 498 | led1 = 0; |
JesseLohman | 1:4cb9af313c26 | 499 | led2 = 0; |
JesseLohman | 3:be922ea2415f | 500 | led3 = 0; // EmisampleTime white together |
JesseLohman | 1:4cb9af313c26 | 501 | stateChanged = false; |
JesseLohman | 1:4cb9af313c26 | 502 | } |
JesseLohman | 1:4cb9af313c26 | 503 | |
JesseLohman | 1:4cb9af313c26 | 504 | if (grippingSwitch.read() == false) { |
JesseLohman | 0:2a5dd6cc0008 | 505 | led1 = 1; |
JesseLohman | 0:2a5dd6cc0008 | 506 | led2 = 1; |
JesseLohman | 0:2a5dd6cc0008 | 507 | led3 = 1; |
JesseLohman | 1:4cb9af313c26 | 508 | currentState = GrippingState; |
JesseLohman | 1:4cb9af313c26 | 509 | stateChanged = true; |
JesseLohman | 1:4cb9af313c26 | 510 | } |
JesseLohman | 1:4cb9af313c26 | 511 | |
JesseLohman | 1:4cb9af313c26 | 512 | break; |
JesseLohman | 1:4cb9af313c26 | 513 | case GrippingState: |
JesseLohman | 1:4cb9af313c26 | 514 | if (stateChanged == true) { |
JesseLohman | 1:4cb9af313c26 | 515 | // Entry action: all the things you do once in this state; |
JesseLohman | 1:4cb9af313c26 | 516 | led2 = 0; |
JesseLohman | 3:be922ea2415f | 517 | led3 = 0; // EmisampleTime light blue together |
JesseLohman | 0:2a5dd6cc0008 | 518 | stateChanged = false; |
JesseLohman | 0:2a5dd6cc0008 | 519 | } |
JesseLohman | 1:4cb9af313c26 | 520 | |
JesseLohman | 1:4cb9af313c26 | 521 | if (gripDirection == true) { |
JesseLohman | 1:4cb9af313c26 | 522 | // Close gripper |
JesseLohman | 1:4cb9af313c26 | 523 | } else { |
JesseLohman | 1:4cb9af313c26 | 524 | // Open gripper |
JesseLohman | 1:4cb9af313c26 | 525 | } |
JesseLohman | 1:4cb9af313c26 | 526 | |
JesseLohman | 1:4cb9af313c26 | 527 | if (screwingSwitch.read() == false) { |
JesseLohman | 1:4cb9af313c26 | 528 | led2 = 1; |
JesseLohman | 1:4cb9af313c26 | 529 | led3 = 1; |
JesseLohman | 1:4cb9af313c26 | 530 | currentState = ScrewingState; |
JesseLohman | 1:4cb9af313c26 | 531 | stateChanged = true; |
JesseLohman | 1:4cb9af313c26 | 532 | } |
JesseLohman | 1:4cb9af313c26 | 533 | if (startButton.read() == false) { |
JesseLohman | 1:4cb9af313c26 | 534 | led2 = 1; |
JesseLohman | 1:4cb9af313c26 | 535 | led3 = 1; |
JesseLohman | 1:4cb9af313c26 | 536 | currentState = MovingState; |
JesseLohman | 1:4cb9af313c26 | 537 | stateChanged = true; |
JesseLohman | 1:4cb9af313c26 | 538 | } |
JesseLohman | 0:2a5dd6cc0008 | 539 | break; |
JesseLohman | 0:2a5dd6cc0008 | 540 | case ScrewingState: |
JesseLohman | 1:4cb9af313c26 | 541 | if (stateChanged == true) { |
JesseLohman | 1:4cb9af313c26 | 542 | // Entry action: all the things you do once in this state; |
JesseLohman | 1:4cb9af313c26 | 543 | led1 = 0; |
JesseLohman | 3:be922ea2415f | 544 | led3 = 0; // EmisampleTime pink together |
JesseLohman | 1:4cb9af313c26 | 545 | stateChanged = false; |
JesseLohman | 1:4cb9af313c26 | 546 | } |
JesseLohman | 2:5cace74299e7 | 547 | |
JesseLohman | 1:4cb9af313c26 | 548 | if (screwDirection == true) { |
JesseLohman | 1:4cb9af313c26 | 549 | // Screw |
JesseLohman | 1:4cb9af313c26 | 550 | } else { |
JesseLohman | 1:4cb9af313c26 | 551 | // Unscrew |
JesseLohman | 1:4cb9af313c26 | 552 | } |
JesseLohman | 2:5cace74299e7 | 553 | |
JesseLohman | 1:4cb9af313c26 | 554 | if (startButton.read() == false) { |
JesseLohman | 1:4cb9af313c26 | 555 | led1 = 1; |
JesseLohman | 1:4cb9af313c26 | 556 | led3 = 1; |
JesseLohman | 1:4cb9af313c26 | 557 | currentState = MovingState; |
JesseLohman | 1:4cb9af313c26 | 558 | stateChanged = true; |
JesseLohman | 1:4cb9af313c26 | 559 | } |
JesseLohman | 0:2a5dd6cc0008 | 560 | break; |
JesseLohman | 0:2a5dd6cc0008 | 561 | case FailureState: |
JesseLohman | 0:2a5dd6cc0008 | 562 | if (stateChanged == true) { |
JesseLohman | 0:2a5dd6cc0008 | 563 | // Entry action: all the things you do once in this state |
JesseLohman | 2:5cace74299e7 | 564 | u1 = 0; // Turn off all motors |
JesseLohman | 2:5cace74299e7 | 565 | u2 = 0; |
JesseLohman | 2:5cace74299e7 | 566 | u3 = 0; |
JesseLohman | 2:5cace74299e7 | 567 | u4 = 0; |
JesseLohman | 0:2a5dd6cc0008 | 568 | stateChanged = false; |
JesseLohman | 0:2a5dd6cc0008 | 569 | } |
JesseLohman | 1:4cb9af313c26 | 570 | |
JesseLohman | 1:4cb9af313c26 | 571 | static double blinkTimer = 0; |
JesseLohman | 1:4cb9af313c26 | 572 | if (blinkTimer >= 0.5) { |
JesseLohman | 1:4cb9af313c26 | 573 | led1 = !led1; |
JesseLohman | 1:4cb9af313c26 | 574 | blinkTimer = 0; |
JesseLohman | 1:4cb9af313c26 | 575 | } |
JesseLohman | 1:4cb9af313c26 | 576 | blinkTimer += sampleTime; |
JesseLohman | 1:4cb9af313c26 | 577 | |
JesseLohman | 1:4cb9af313c26 | 578 | break; |
JesseLohman | 0:2a5dd6cc0008 | 579 | } |
JesseLohman | 0:2a5dd6cc0008 | 580 | } |
JesseLohman | 0:2a5dd6cc0008 | 581 | |
JesseLohman | 3:be922ea2415f | 582 | void measureAll () |
JesseLohman | 3:be922ea2415f | 583 | { |
JesseLohman | 3:be922ea2415f | 584 | measurePosition(); |
KingMufasa | 5:a1843b698d0d | 585 | measureEMG(); |
JesseLohman | 3:be922ea2415f | 586 | inverseKinematics(); |
JesseLohman | 3:be922ea2415f | 587 | } |
JesseLohman | 3:be922ea2415f | 588 | |
JesseLohman | 0:2a5dd6cc0008 | 589 | void mainLoop () |
JesseLohman | 0:2a5dd6cc0008 | 590 | { |
KingMufasa | 4:8f25ecb74221 | 591 | // Add measure, motor controller and output function |
JesseLohman | 2:5cace74299e7 | 592 | measureAll(); |
JesseLohman | 0:2a5dd6cc0008 | 593 | stateMachine(); |
JesseLohman | 3:be922ea2415f | 594 | PID_controller(); |
JesseLohman | 2:5cace74299e7 | 595 | controlMotor(); |
JesseLohman | 0:2a5dd6cc0008 | 596 | } |
JesseLohman | 0:2a5dd6cc0008 | 597 | |
JesseLohman | 0:2a5dd6cc0008 | 598 | int main() |
JesseLohman | 0:2a5dd6cc0008 | 599 | { |
KingMufasa | 5:a1843b698d0d | 600 | pc.baud(115200); |
JesseLohman | 2:5cace74299e7 | 601 | pc.printf("checkpoint 1\n"); |
KingMufasa | 5:a1843b698d0d | 602 | bqc.add(&hpf).add(¬ch).add(&lpf); //Add bqfilters to bqc |
JesseLohman | 0:2a5dd6cc0008 | 603 | mainTicker.attach(mainLoop, sampleTime); |
JesseLohman | 0:2a5dd6cc0008 | 604 | failureButton.fall(&switchToFailureState); // When button is pressed FailureState is activated |
JesseLohman | 0:2a5dd6cc0008 | 605 | |
JesseLohman | 0:2a5dd6cc0008 | 606 | while (true) { |
JesseLohman | 2:5cace74299e7 | 607 | //pc.printf("State = %i\n", currentState); |
JesseLohman | 2:5cace74299e7 | 608 | //int pulses = encoder1.getPulses(); |
JesseLohman | 2:5cace74299e7 | 609 | //pc.printf("pulses = %i\n", pulses); |
KingMufasa | 5:a1843b698d0d | 610 | // pc.printf("v = %f\n", v); |
KingMufasa | 6:e67250b8b100 | 611 | pc.printf("Error1 = %f Error2 = %f \n qRef1 = %f rQref2 = %f \r\n qMeas1 = %f qMeas2 = %f \n, Pulses1 = %f Pulses2 = %f \n", error1,error2,qRef1,qRef2,qMeas1,qMeas2, pulses1, pulses2); |
KingMufasa | 5:a1843b698d0d | 612 | wait(2); |
JesseLohman | 0:2a5dd6cc0008 | 613 | } |
JesseLohman | 0:2a5dd6cc0008 | 614 | } |