Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed QEI HIDScope biquadFilter MODSERIAL FastPWM
main.cpp@23:ff73ee119244, 2019-10-31 (annotated)
- Committer:
- Floris_Hoek
- Date:
- Thu Oct 31 09:48:53 2019 +0000
- Revision:
- 23:ff73ee119244
- Parent:
- 22:cce4dc5738af
- Child:
- 24:e87e4fcf6226
final V1
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| Floris_Hoek | 23:ff73ee119244 | 1 | // Ticker function.attach(nothing,1000) good solution?????? |
| Floris_Hoek | 23:ff73ee119244 | 2 | // Operating mode might not go to next state when SW2 is pressed |
| Floris_Hoek | 12:f4331640e3ad | 3 | |
| RobertoO | 0:67c50348f842 | 4 | #include "mbed.h" |
| Floris_Hoek | 8:7dab565a208e | 5 | #include "HIDScope.h" |
| Floris_Hoek | 8:7dab565a208e | 6 | #include "BiQuad.h" |
| RobertoO | 1:b862262a9d14 | 7 | #include "MODSERIAL.h" |
| paulstuiver | 2:75b2f713161c | 8 | #include "FastPWM.h" |
| paulstuiver | 5:2ae500da8fe1 | 9 | #include "QEI.h" |
| Floris_Hoek | 12:f4331640e3ad | 10 | |
| Floris_Hoek | 23:ff73ee119244 | 11 | #include <cmath> // Included to use different math operations |
| paulstuiver | 2:75b2f713161c | 12 | |
| Floris_Hoek | 23:ff73ee119244 | 13 | #include "Servo.h" // Included to control the servo motor |
| Floris_Hoek | 8:7dab565a208e | 14 | |
| Floris_Hoek | 23:ff73ee119244 | 15 | Servo myservo(D13); // To control the servo motor |
| Floris_Hoek | 23:ff73ee119244 | 16 | DigitalIn but3(SW2); // To go to the next state or to choose one of two game modes when in state START_GAME |
| Floris_Hoek | 23:ff73ee119244 | 17 | DigitalIn but4(SW3); // To choose one of two game modes when in state START_GAME or to move the gripper |
| Floris_Hoek | 9:e8cc37a94fec | 18 | |
| Floris_Hoek | 22:cce4dc5738af | 19 | AnalogIn S0(A0), S1(A1), S2(A2),S3(A3); // Input EMG Shield 0,1,2,3 |
| Floris_Hoek | 22:cce4dc5738af | 20 | DigitalOut MD0(D7), MD1(D4); // MotorDirection of motors 0,1,2 |
| Floris_Hoek | 23:ff73ee119244 | 21 | FastPWM MV0(D6), MV1(D5); // MotorVelocities of motors 0,1,2 |
| Floris_Hoek | 23:ff73ee119244 | 22 | QEI E0(D8,D9,NC,8400), E1(D11,D10,NC,8400); // Encoders of motors 0,1,2 |
| Floris_Hoek | 9:e8cc37a94fec | 23 | |
| Floris_Hoek | 23:ff73ee119244 | 24 | Ticker measurecontrol; // Ticker function for the measurements |
| Floris_Hoek | 18:4a6be1893d7f | 25 | |
| Floris_Hoek | 18:4a6be1893d7f | 26 | // Make arrays for the different variables for the motors |
| Floris_Hoek | 18:4a6be1893d7f | 27 | AnalogIn Shields[4] = {S0, S1, S2, S3}; |
| Floris_Hoek | 22:cce4dc5738af | 28 | DigitalOut MotorDirections[2] = {MD0, MD1}; |
| Floris_Hoek | 23:ff73ee119244 | 29 | FastPWM MotorVelocities[2] = {MV0, MV1}; |
| Floris_Hoek | 22:cce4dc5738af | 30 | QEI Encoders[2] = {E0, E1}; |
| Floris_Hoek | 18:4a6be1893d7f | 31 | |
| Floris_Hoek | 22:cce4dc5738af | 32 | Serial pc(USBTX, USBRX); |
| Floris_Hoek | 8:7dab565a208e | 33 | |
| Floris_Hoek | 23:ff73ee119244 | 34 | double PI = 3.14159265358;//97932384626433832795028841971693993; |
| Floris_Hoek | 23:ff73ee119244 | 35 | volatile double timeinterval = 0.001f; // Time interval of the Ticker function |
| Floris_Hoek | 23:ff73ee119244 | 36 | volatile double frequency = 17000.0; // Set motorfrequency |
| Floris_Hoek | 23:ff73ee119244 | 37 | double period_signal = 1.0/frequency; // Convert to period of the signal |
| Floris_Hoek | 23:ff73ee119244 | 38 | |
| Floris_Hoek | 23:ff73ee119244 | 39 | double yendeffector = 10.6159; |
| Floris_Hoek | 23:ff73ee119244 | 40 | double xendeffector = 0; |
| Floris_Hoek | 23:ff73ee119244 | 41 | int ingedrukt = 0; |
| Floris_Hoek | 23:ff73ee119244 | 42 | int state_int; |
| Floris_Hoek | 9:e8cc37a94fec | 43 | |
| Floris_Hoek | 9:e8cc37a94fec | 44 | // Define the different states in which the robot can be |
| Floris_Hoek | 23:ff73ee119244 | 45 | enum States {MOTORS_OFF, EMG_CALIBRATION, START_GAME, |
| Floris_Hoek | 23:ff73ee119244 | 46 | DEMO_MODE, OPERATING_MODE, END_GAME |
| Floris_Hoek | 22:cce4dc5738af | 47 | }; |
| Floris_Hoek | 19:b3e224e0cb85 | 48 | |
| Floris_Hoek | 9:e8cc37a94fec | 49 | // Default state is the state in which the motors are turned off |
| Floris_Hoek | 9:e8cc37a94fec | 50 | States MyState = MOTORS_OFF; |
| paulstuiver | 5:2ae500da8fe1 | 51 | |
| Floris_Hoek | 23:ff73ee119244 | 52 | |
| Floris_Hoek | 14:1343966a79e8 | 53 | // Initialise the functions |
| Floris_Hoek | 9:e8cc37a94fec | 54 | |
| Floris_Hoek | 14:1343966a79e8 | 55 | void motorsoff(); |
| Floris_Hoek | 14:1343966a79e8 | 56 | |
| Floris_Hoek | 23:ff73ee119244 | 57 | void measure_data(double &f_y0, double &f_y1, double &f_y2, double &f_y3); |
| Floris_Hoek | 14:1343966a79e8 | 58 | |
| Floris_Hoek | 18:4a6be1893d7f | 59 | void det_max(double y, double &max_y); |
| Floris_Hoek | 14:1343966a79e8 | 60 | |
| Floris_Hoek | 14:1343966a79e8 | 61 | void emgcalibration(); |
| Floris_Hoek | 14:1343966a79e8 | 62 | |
| Floris_Hoek | 22:cce4dc5738af | 63 | void nothing() |
| Floris_Hoek | 22:cce4dc5738af | 64 | { |
| Floris_Hoek | 14:1343966a79e8 | 65 | // Do nothing |
| Floris_Hoek | 14:1343966a79e8 | 66 | } |
| Floris_Hoek | 14:1343966a79e8 | 67 | |
| Floris_Hoek | 23:ff73ee119244 | 68 | void startgame() ; |
| Floris_Hoek | 18:4a6be1893d7f | 69 | |
| Floris_Hoek | 23:ff73ee119244 | 70 | void demo_mode(); |
| Floris_Hoek | 18:4a6be1893d7f | 71 | |
| Floris_Hoek | 18:4a6be1893d7f | 72 | void operating_mode(); |
| Floris_Hoek | 18:4a6be1893d7f | 73 | |
| Floris_Hoek | 14:1343966a79e8 | 74 | void New_State(); |
| Floris_Hoek | 14:1343966a79e8 | 75 | |
| Floris_Hoek | 19:b3e224e0cb85 | 76 | void Set_State(); |
| Floris_Hoek | 19:b3e224e0cb85 | 77 | |
| Floris_Hoek | 23:ff73ee119244 | 78 | double PID_controller1(double error1); |
| Floris_Hoek | 23:ff73ee119244 | 79 | |
| Floris_Hoek | 23:ff73ee119244 | 80 | double PID_controller2(double error2); |
| Floris_Hoek | 23:ff73ee119244 | 81 | |
| Floris_Hoek | 23:ff73ee119244 | 82 | void getmeasuredposition(double & measuredposition1, double & measuredposition2); |
| Floris_Hoek | 23:ff73ee119244 | 83 | |
| Floris_Hoek | 23:ff73ee119244 | 84 | void getreferenceposition(double & referenceposition1, double & referenceposition2); |
| Floris_Hoek | 23:ff73ee119244 | 85 | |
| Floris_Hoek | 23:ff73ee119244 | 86 | void sendtomotor(double motorvalue1, double motorvalue2); |
| Floris_Hoek | 23:ff73ee119244 | 87 | |
| Floris_Hoek | 23:ff73ee119244 | 88 | void measureandcontrol(); |
| Floris_Hoek | 14:1343966a79e8 | 89 | |
| Floris_Hoek | 14:1343966a79e8 | 90 | |
| Floris_Hoek | 23:ff73ee119244 | 91 | |
| Floris_Hoek | 14:1343966a79e8 | 92 | int main() |
| Floris_Hoek | 14:1343966a79e8 | 93 | { |
| Floris_Hoek | 22:cce4dc5738af | 94 | pc.baud(115200); |
| Floris_Hoek | 23:ff73ee119244 | 95 | pc.printf("Starting...\r\n\r\n"); |
| Floris_Hoek | 22:cce4dc5738af | 96 | |
| Floris_Hoek | 23:ff73ee119244 | 97 | for (int i = 0; i < 2; i++) { |
| Floris_Hoek | 18:4a6be1893d7f | 98 | MotorVelocities[i].period(period_signal); // Set the period of the PWMfunction |
| Floris_Hoek | 18:4a6be1893d7f | 99 | } |
| Floris_Hoek | 22:cce4dc5738af | 100 | |
| Floris_Hoek | 23:ff73ee119244 | 101 | measurecontrol.attach(nothing, timeinterval); // Ticker function to measure motor input and control the motors |
| Floris_Hoek | 22:cce4dc5738af | 102 | |
| Floris_Hoek | 14:1343966a79e8 | 103 | int previous_state_int = (int)MyState; // Save previous state to compare with current state and possibly execute New_State() |
| Floris_Hoek | 22:cce4dc5738af | 104 | // in the while loop |
| Floris_Hoek | 22:cce4dc5738af | 105 | |
| Floris_Hoek | 14:1343966a79e8 | 106 | New_State(); // Execute the functions belonging to the current state |
| Floris_Hoek | 22:cce4dc5738af | 107 | |
| Floris_Hoek | 23:ff73ee119244 | 108 | while(true) { |
| Floris_Hoek | 14:1343966a79e8 | 109 | if ( (previous_state_int - (int)MyState) != 0 ) { // If current state is not previous state execute New_State() |
| Floris_Hoek | 14:1343966a79e8 | 110 | New_State(); |
| Floris_Hoek | 14:1343966a79e8 | 111 | } |
| Floris_Hoek | 23:ff73ee119244 | 112 | |
| Floris_Hoek | 23:ff73ee119244 | 113 | previous_state_int = (int)MyState-state_int; // Change previous state to current state |
| Floris_Hoek | 23:ff73ee119244 | 114 | state_int = 0; |
| Floris_Hoek | 14:1343966a79e8 | 115 | } |
| Floris_Hoek | 23:ff73ee119244 | 116 | } |
| Floris_Hoek | 23:ff73ee119244 | 117 | |
| Floris_Hoek | 23:ff73ee119244 | 118 | |
| Floris_Hoek | 23:ff73ee119244 | 119 | |
| Floris_Hoek | 23:ff73ee119244 | 120 | double PID_controller1(double error1) |
| Floris_Hoek | 23:ff73ee119244 | 121 | { |
| Floris_Hoek | 23:ff73ee119244 | 122 | // Define errors for motor 1 and 2 |
| Floris_Hoek | 23:ff73ee119244 | 123 | static double error_integral1 = 0; |
| Floris_Hoek | 23:ff73ee119244 | 124 | static double error_prev1 = error1; |
| Floris_Hoek | 23:ff73ee119244 | 125 | |
| Floris_Hoek | 23:ff73ee119244 | 126 | // Low-pass filter |
| Floris_Hoek | 23:ff73ee119244 | 127 | static BiQuad LowPassFilter(0.0640, 0.1279, 0.0640, -1.1683, 0.4241); |
| Floris_Hoek | 23:ff73ee119244 | 128 | |
| Floris_Hoek | 23:ff73ee119244 | 129 | // PID variables: we assume them to be the same for both motors |
| Floris_Hoek | 23:ff73ee119244 | 130 | double Kp = 65; |
| Floris_Hoek | 23:ff73ee119244 | 131 | double Ki = 3.64; |
| Floris_Hoek | 23:ff73ee119244 | 132 | double Kd = 5; |
| Floris_Hoek | 23:ff73ee119244 | 133 | |
| Floris_Hoek | 23:ff73ee119244 | 134 | //Proportional part: |
| Floris_Hoek | 23:ff73ee119244 | 135 | double u_k1 = Kp * error1; |
| Floris_Hoek | 23:ff73ee119244 | 136 | |
| Floris_Hoek | 23:ff73ee119244 | 137 | // Integreal part |
| Floris_Hoek | 23:ff73ee119244 | 138 | error_integral1 = error_integral1 + error1 * timeinterval; |
| Floris_Hoek | 23:ff73ee119244 | 139 | double u_i1 = Ki*error_integral1; |
| Floris_Hoek | 23:ff73ee119244 | 140 | |
| Floris_Hoek | 23:ff73ee119244 | 141 | // Derivate part |
| Floris_Hoek | 23:ff73ee119244 | 142 | double error_derivative1 = (error1 - error_prev1)/timeinterval; |
| Floris_Hoek | 23:ff73ee119244 | 143 | double filtered_error_derivative1 = LowPassFilter.step(error_derivative1); |
| Floris_Hoek | 23:ff73ee119244 | 144 | double u_d1 = Kd * filtered_error_derivative1; |
| Floris_Hoek | 23:ff73ee119244 | 145 | error_prev1 = error1; |
| Floris_Hoek | 23:ff73ee119244 | 146 | |
| Floris_Hoek | 23:ff73ee119244 | 147 | //sum all parts and return it |
| Floris_Hoek | 23:ff73ee119244 | 148 | return u_k1 + u_i1 + u_d1; |
| Floris_Hoek | 23:ff73ee119244 | 149 | } |
| Floris_Hoek | 23:ff73ee119244 | 150 | |
| Floris_Hoek | 23:ff73ee119244 | 151 | |
| Floris_Hoek | 23:ff73ee119244 | 152 | double PID_controller2(double error2) |
| Floris_Hoek | 23:ff73ee119244 | 153 | { |
| Floris_Hoek | 23:ff73ee119244 | 154 | // Define errors for motor 1 and 2 |
| Floris_Hoek | 23:ff73ee119244 | 155 | static double error_integral2 = 0; |
| Floris_Hoek | 23:ff73ee119244 | 156 | static double error_prev2 = error2; |
| Floris_Hoek | 23:ff73ee119244 | 157 | |
| Floris_Hoek | 23:ff73ee119244 | 158 | // Low-pass filter |
| Floris_Hoek | 23:ff73ee119244 | 159 | static BiQuad LowPassFilter(0.0640, 0.1279, 0.0640, -1.1683, 0.4241); |
| Floris_Hoek | 23:ff73ee119244 | 160 | |
| Floris_Hoek | 23:ff73ee119244 | 161 | // PID variables: we assume them to be the same for both motors |
| Floris_Hoek | 23:ff73ee119244 | 162 | double Kp = 65; |
| Floris_Hoek | 23:ff73ee119244 | 163 | double Ki = 3.64; |
| Floris_Hoek | 23:ff73ee119244 | 164 | double Kd = 5; |
| Floris_Hoek | 23:ff73ee119244 | 165 | |
| Floris_Hoek | 23:ff73ee119244 | 166 | //Proportional part: |
| Floris_Hoek | 23:ff73ee119244 | 167 | double u_k2 = Kp * error2; |
| Floris_Hoek | 23:ff73ee119244 | 168 | |
| Floris_Hoek | 23:ff73ee119244 | 169 | // Integreal part |
| Floris_Hoek | 23:ff73ee119244 | 170 | error_integral2 = error_integral2 + error2 * timeinterval; |
| Floris_Hoek | 23:ff73ee119244 | 171 | double u_i2 = Ki*error_integral2; |
| Floris_Hoek | 23:ff73ee119244 | 172 | |
| Floris_Hoek | 23:ff73ee119244 | 173 | // Derivate part |
| Floris_Hoek | 23:ff73ee119244 | 174 | double error_derivative2 = (error2 - error_prev2)/timeinterval; |
| Floris_Hoek | 23:ff73ee119244 | 175 | double filtered_error_derivative2 = LowPassFilter.step(error_derivative2); |
| Floris_Hoek | 23:ff73ee119244 | 176 | double u_d2 = Kd * filtered_error_derivative2; |
| Floris_Hoek | 23:ff73ee119244 | 177 | error_prev2 = error2; |
| Floris_Hoek | 23:ff73ee119244 | 178 | |
| Floris_Hoek | 23:ff73ee119244 | 179 | //sum all parts and return it |
| Floris_Hoek | 23:ff73ee119244 | 180 | return u_k2 + u_i2 + u_d2; |
| Floris_Hoek | 23:ff73ee119244 | 181 | } |
| Floris_Hoek | 23:ff73ee119244 | 182 | |
| Floris_Hoek | 22:cce4dc5738af | 183 | |
| Floris_Hoek | 23:ff73ee119244 | 184 | //get the measured position |
| Floris_Hoek | 23:ff73ee119244 | 185 | void getmeasuredposition(double & measuredposition1, double & measuredposition2) |
| Floris_Hoek | 23:ff73ee119244 | 186 | { |
| Floris_Hoek | 23:ff73ee119244 | 187 | // Obtain the counts of motors 1 and 2 from the encoder |
| Floris_Hoek | 23:ff73ee119244 | 188 | int countsmotor1; |
| Floris_Hoek | 23:ff73ee119244 | 189 | int countsmotor2; |
| Floris_Hoek | 23:ff73ee119244 | 190 | countsmotor1 = Encoders[0].getPulses(); |
| Floris_Hoek | 23:ff73ee119244 | 191 | countsmotor2 = Encoders[1].getPulses(); |
| Floris_Hoek | 23:ff73ee119244 | 192 | |
| Floris_Hoek | 23:ff73ee119244 | 193 | // Obtain the measured position for motor 1 and 2 |
| Floris_Hoek | 23:ff73ee119244 | 194 | measuredposition1 = ((double)countsmotor1) / 8400.0f * 2.0f; |
| Floris_Hoek | 23:ff73ee119244 | 195 | measuredposition2 = ((double)countsmotor2) / 8400.0f * 2.0f; |
| Floris_Hoek | 23:ff73ee119244 | 196 | } |
| Floris_Hoek | 23:ff73ee119244 | 197 | |
| Floris_Hoek | 23:ff73ee119244 | 198 | |
| Floris_Hoek | 23:ff73ee119244 | 199 | //get the reference of the |
| Floris_Hoek | 23:ff73ee119244 | 200 | void getreferenceposition(double & referenceposition1, double & referenceposition2) |
| Floris_Hoek | 23:ff73ee119244 | 201 | { |
| Floris_Hoek | 23:ff73ee119244 | 202 | //Measurements of the arm |
| Floris_Hoek | 23:ff73ee119244 | 203 | double L0=1.95; |
| Floris_Hoek | 23:ff73ee119244 | 204 | double L1=15; |
| Floris_Hoek | 23:ff73ee119244 | 205 | double L2=20; |
| Floris_Hoek | 23:ff73ee119244 | 206 | |
| Floris_Hoek | 23:ff73ee119244 | 207 | //Inverse kinematics: given the end position, what are the desired motor angles of 1 and 2 |
| Floris_Hoek | 23:ff73ee119244 | 208 | double desiredmotorangle1, desiredmotorangle2; |
| Floris_Hoek | 23:ff73ee119244 | 209 | desiredmotorangle1 = (atan2(yendeffector,(L0+xendeffector))*180.0/PI + acos((pow(L1,2)+pow(L0+xendeffector,2)+pow(yendeffector,2)-pow(L2,2))/(2*L1*sqrt(pow(L0+xendeffector,2)+pow(yendeffector,2))))*180.0/PI)-180.0; |
| Floris_Hoek | 23:ff73ee119244 | 210 | desiredmotorangle2 = (atan2(yendeffector,(L0-xendeffector))*180.0/PI + acos((pow(L1,2)+pow(L0-xendeffector,2)+pow(yendeffector,2)-pow(L2,2))/(2*L1*sqrt(pow(L0-xendeffector,2)+pow(yendeffector,2))))*180.0/PI)-180.0; |
| Floris_Hoek | 23:ff73ee119244 | 211 | |
| Floris_Hoek | 23:ff73ee119244 | 212 | //Convert motor angles to counts |
| Floris_Hoek | 23:ff73ee119244 | 213 | double desiredmotorrounds1; |
| Floris_Hoek | 23:ff73ee119244 | 214 | double desiredmotorrounds2; |
| Floris_Hoek | 23:ff73ee119244 | 215 | desiredmotorrounds1 = (desiredmotorangle1)/360.0; |
| Floris_Hoek | 23:ff73ee119244 | 216 | desiredmotorrounds2 = (desiredmotorangle2)/360.0; |
| Floris_Hoek | 23:ff73ee119244 | 217 | |
| Floris_Hoek | 23:ff73ee119244 | 218 | //Assign this to new variables because otherwise it doesn't work |
| Floris_Hoek | 23:ff73ee119244 | 219 | referenceposition1 = desiredmotorrounds1; |
| Floris_Hoek | 23:ff73ee119244 | 220 | referenceposition2 = desiredmotorrounds2; |
| Floris_Hoek | 14:1343966a79e8 | 221 | } |
| Floris_Hoek | 23:ff73ee119244 | 222 | |
| Floris_Hoek | 23:ff73ee119244 | 223 | |
| Floris_Hoek | 23:ff73ee119244 | 224 | //send value to motor |
| Floris_Hoek | 23:ff73ee119244 | 225 | // IT WAS "void sendtomotor(float & motorvalue1, float & motorvalue2)" BUT I REMOVED THE REFERENCE, BECAUSE I THOUGHT IT WAS NOT NEEDED |
| Floris_Hoek | 23:ff73ee119244 | 226 | void sendtomotor(double motorvalue1, double motorvalue2) |
| Floris_Hoek | 23:ff73ee119244 | 227 | { |
| Floris_Hoek | 23:ff73ee119244 | 228 | // Define the absolute motor values |
| Floris_Hoek | 23:ff73ee119244 | 229 | double absolutemotorvalue1; |
| Floris_Hoek | 23:ff73ee119244 | 230 | double absolutemotorvalue2; |
| Floris_Hoek | 23:ff73ee119244 | 231 | absolutemotorvalue1 = fabs(motorvalue1); |
| Floris_Hoek | 23:ff73ee119244 | 232 | absolutemotorvalue2 = fabs(motorvalue2); |
| Floris_Hoek | 23:ff73ee119244 | 233 | |
| Floris_Hoek | 23:ff73ee119244 | 234 | // If absolutemotorvalueocity is greater than 1, reduce to 1, otherwise remain absolutemotorvalue |
| Floris_Hoek | 23:ff73ee119244 | 235 | absolutemotorvalue1 = absolutemotorvalue1 > 1.0f ? 1.0f : absolutemotorvalue1; |
| Floris_Hoek | 23:ff73ee119244 | 236 | absolutemotorvalue2 = absolutemotorvalue2 > 1.0f ? 1.0f : absolutemotorvalue2; |
| Floris_Hoek | 23:ff73ee119244 | 237 | |
| Floris_Hoek | 23:ff73ee119244 | 238 | // Send the absolutemotorvalue to the motors |
| Floris_Hoek | 23:ff73ee119244 | 239 | MotorVelocities[0] = absolutemotorvalue1; |
| Floris_Hoek | 23:ff73ee119244 | 240 | MotorVelocities[1] = absolutemotorvalue2; |
| Floris_Hoek | 23:ff73ee119244 | 241 | |
| Floris_Hoek | 23:ff73ee119244 | 242 | // Determine the motor direction. Boolean output: true gives counterclockwise direction, false gives clockwise direction |
| Floris_Hoek | 23:ff73ee119244 | 243 | MotorDirections[0] = (motorvalue1 > 0.0f); |
| Floris_Hoek | 23:ff73ee119244 | 244 | MotorDirections[1] = (motorvalue2 > 0.0f); |
| Floris_Hoek | 23:ff73ee119244 | 245 | } |
| Floris_Hoek | 23:ff73ee119244 | 246 | |
| Floris_Hoek | 23:ff73ee119244 | 247 | // function to call reference absolutemotorvalueocity, measured absolutemotorvalueocity and controls motor with feedback |
| Floris_Hoek | 23:ff73ee119244 | 248 | void measureandcontrol() |
| Floris_Hoek | 23:ff73ee119244 | 249 | { |
| Floris_Hoek | 23:ff73ee119244 | 250 | // Get the reference positions of motor 1 and 2 |
| Floris_Hoek | 23:ff73ee119244 | 251 | double reference1, reference2; |
| Floris_Hoek | 23:ff73ee119244 | 252 | getreferenceposition(reference1, reference2); |
| Floris_Hoek | 23:ff73ee119244 | 253 | |
| Floris_Hoek | 23:ff73ee119244 | 254 | // Get the measured positions of motor 1 and 2 |
| Floris_Hoek | 23:ff73ee119244 | 255 | double measured1, measured2; |
| Floris_Hoek | 23:ff73ee119244 | 256 | getmeasuredposition(measured1, measured2); |
| Floris_Hoek | 23:ff73ee119244 | 257 | |
| Floris_Hoek | 23:ff73ee119244 | 258 | // Calculate the motor values |
| Floris_Hoek | 23:ff73ee119244 | 259 | double motorvalue1, motorvalue2; |
| Floris_Hoek | 23:ff73ee119244 | 260 | motorvalue1 = PID_controller1(reference1 - measured1); |
| Floris_Hoek | 23:ff73ee119244 | 261 | motorvalue2 = PID_controller2(reference2 - measured2); |
| Floris_Hoek | 23:ff73ee119244 | 262 | sendtomotor(motorvalue1, motorvalue2); |
| Floris_Hoek | 23:ff73ee119244 | 263 | } |
| Floris_Hoek | 23:ff73ee119244 | 264 | |
| Floris_Hoek | 9:e8cc37a94fec | 265 | |
| Floris_Hoek | 22:cce4dc5738af | 266 | void motorsoff() |
| Floris_Hoek | 22:cce4dc5738af | 267 | { |
| Floris_Hoek | 23:ff73ee119244 | 268 | // Function to turn the motors off. First state that the robot has. Robot will stay in this state untill button SW2 is pressed. |
| Floris_Hoek | 12:f4331640e3ad | 269 | // Robot will not return to this state anymore unless the user sets it back to this state with the keyboard input. |
| Floris_Hoek | 23:ff73ee119244 | 270 | sendtomotor(0.0,0.0); // Set motor velocity to 0 |
| Floris_Hoek | 23:ff73ee119244 | 271 | |
| Floris_Hoek | 23:ff73ee119244 | 272 | state_int = 10; |
| Floris_Hoek | 22:cce4dc5738af | 273 | |
| Floris_Hoek | 12:f4331640e3ad | 274 | bool whileloop_boolean = true; // Boolean for the while loop |
| Floris_Hoek | 22:cce4dc5738af | 275 | |
| Floris_Hoek | 12:f4331640e3ad | 276 | while (whileloop_boolean) { |
| Floris_Hoek | 23:ff73ee119244 | 277 | if (but3.read() == 0) { // If button SW2 is pressed: |
| Floris_Hoek | 23:ff73ee119244 | 278 | MyState = (States)((int)MyState+1); // set MyState to EMG_CALIBRATION and exit the while loop |
| Floris_Hoek | 23:ff73ee119244 | 279 | whileloop_boolean = false; // by making whileloop_boolean equal to false |
| Floris_Hoek | 23:ff73ee119244 | 280 | wait(0.5f); |
| Floris_Hoek | 9:e8cc37a94fec | 281 | } |
| Floris_Hoek | 9:e8cc37a94fec | 282 | } |
| Floris_Hoek | 9:e8cc37a94fec | 283 | } |
| Floris_Hoek | 12:f4331640e3ad | 284 | |
| Floris_Hoek | 22:cce4dc5738af | 285 | void measure_data(double &f_y0, double &f_y1, double &f_y2, double &f_y3) |
| Floris_Hoek | 22:cce4dc5738af | 286 | { |
| Floris_Hoek | 18:4a6be1893d7f | 287 | // High pass |
| Floris_Hoek | 18:4a6be1893d7f | 288 | double hb0 = 0.9169; // Coefficients from the following formula: |
| Floris_Hoek | 18:4a6be1893d7f | 289 | double hb1 = -1.8338; // |
| Floris_Hoek | 18:4a6be1893d7f | 290 | double hb2 = 0.9169; // b0 + b1 z^-1 + b2 z^-2 |
| Floris_Hoek | 18:4a6be1893d7f | 291 | double ha0 = 1.0; // H(z) = ---------------------- |
| Floris_Hoek | 18:4a6be1893d7f | 292 | double ha1 = -1.8268; // a0 + a1 z^-1 + a2 z^-2 |
| Floris_Hoek | 18:4a6be1893d7f | 293 | double ha2 = 0.8407; // |
| Floris_Hoek | 22:cce4dc5738af | 294 | |
| Floris_Hoek | 18:4a6be1893d7f | 295 | // Low pass |
| Floris_Hoek | 18:4a6be1893d7f | 296 | double lb0 = 0.000083621; // Coefficients from the following formula: |
| Floris_Hoek | 18:4a6be1893d7f | 297 | double lb1 = 0.0006724; // |
| Floris_Hoek | 18:4a6be1893d7f | 298 | double lb2 = 0.000083621; // b0 + b1 z^-1 + b2 z^-2 |
| Floris_Hoek | 18:4a6be1893d7f | 299 | double la0 = 1.0; // H(z) = ---------------------- |
| Floris_Hoek | 18:4a6be1893d7f | 300 | double la1 = -1.9740; // a0 + a1 z^-1 + a2 z^-2 |
| Floris_Hoek | 18:4a6be1893d7f | 301 | double la2 = 0.9743; // |
| Floris_Hoek | 22:cce4dc5738af | 302 | |
| Floris_Hoek | 23:ff73ee119244 | 303 | static double max_y0 = 0.001; |
| Floris_Hoek | 23:ff73ee119244 | 304 | static double max_y1 = 0.001; |
| Floris_Hoek | 23:ff73ee119244 | 305 | static double max_y2 = 0.001; |
| Floris_Hoek | 23:ff73ee119244 | 306 | static double max_y3 = 0.001; |
| Floris_Hoek | 22:cce4dc5738af | 307 | |
| Floris_Hoek | 18:4a6be1893d7f | 308 | static BiQuad hFilter0(hb0,hb1,hb2,ha0,ha1,ha2); // Create 4 equal filters used for the different EMG signals |
| Floris_Hoek | 18:4a6be1893d7f | 309 | static BiQuad hFilter1(hb0,hb1,hb2,ha0,ha1,ha2); |
| Floris_Hoek | 18:4a6be1893d7f | 310 | static BiQuad hFilter2(hb0,hb1,hb2,ha0,ha1,ha2); |
| Floris_Hoek | 18:4a6be1893d7f | 311 | static BiQuad hFilter3(hb0,hb1,hb2,ha0,ha1,ha2); |
| Floris_Hoek | 22:cce4dc5738af | 312 | |
| Floris_Hoek | 18:4a6be1893d7f | 313 | static BiQuad lFilter0(lb0,lb1,lb2,la0,la1,la2); // Create 4 equal filters used for the different EMG signals |
| Floris_Hoek | 18:4a6be1893d7f | 314 | static BiQuad lFilter1(lb0,lb1,lb2,la0,la1,la2); |
| Floris_Hoek | 18:4a6be1893d7f | 315 | static BiQuad lFilter2(lb0,lb1,lb2,la0,la1,la2); |
| Floris_Hoek | 18:4a6be1893d7f | 316 | static BiQuad lFilter3(lb0,lb1,lb2,la0,la1,la2); |
| Floris_Hoek | 22:cce4dc5738af | 317 | |
| Floris_Hoek | 23:ff73ee119244 | 318 | f_y0 = hFilter0.step(Shields[0]); // Apply filters on the different EMG signals |
| Floris_Hoek | 23:ff73ee119244 | 319 | f_y1 = hFilter1.step(Shields[1]); |
| Floris_Hoek | 23:ff73ee119244 | 320 | f_y2 = hFilter2.step(Shields[2]); |
| Floris_Hoek | 23:ff73ee119244 | 321 | f_y3 = hFilter3.step(Shields[3]); |
| Floris_Hoek | 22:cce4dc5738af | 322 | |
| Floris_Hoek | 19:b3e224e0cb85 | 323 | f_y0 = abs(f_y0); |
| Floris_Hoek | 19:b3e224e0cb85 | 324 | f_y1 = abs(f_y1); |
| Floris_Hoek | 19:b3e224e0cb85 | 325 | f_y2 = abs(f_y2); |
| Floris_Hoek | 19:b3e224e0cb85 | 326 | f_y3 = abs(f_y3); |
| Floris_Hoek | 22:cce4dc5738af | 327 | |
| Floris_Hoek | 18:4a6be1893d7f | 328 | f_y0 = lFilter0.step(f_y0); |
| Floris_Hoek | 18:4a6be1893d7f | 329 | f_y1 = lFilter1.step(f_y1); |
| Floris_Hoek | 18:4a6be1893d7f | 330 | f_y2 = lFilter2.step(f_y2); |
| Floris_Hoek | 18:4a6be1893d7f | 331 | f_y3 = lFilter3.step(f_y3); |
| Floris_Hoek | 18:4a6be1893d7f | 332 | |
| Floris_Hoek | 18:4a6be1893d7f | 333 | |
| Floris_Hoek | 15:5f9450964075 | 334 | if (MyState == EMG_CALIBRATION) { |
| Floris_Hoek | 22:cce4dc5738af | 335 | |
| Floris_Hoek | 18:4a6be1893d7f | 336 | det_max(f_y0, max_y0); // Determine the maximum RMS value of the EMG signals during the EMG_CALIBRATION state |
| Floris_Hoek | 18:4a6be1893d7f | 337 | det_max(f_y1, max_y1); |
| Floris_Hoek | 18:4a6be1893d7f | 338 | det_max(f_y2, max_y2); |
| Floris_Hoek | 18:4a6be1893d7f | 339 | det_max(f_y3, max_y3); |
| Floris_Hoek | 22:cce4dc5738af | 340 | |
| Floris_Hoek | 23:ff73ee119244 | 341 | } else if ((int)MyState > 3) { |
| Floris_Hoek | 18:4a6be1893d7f | 342 | f_y0 = f_y0/max_y0; // Normalise the RMS value by dividing by the maximum RMS value |
| Floris_Hoek | 23:ff73ee119244 | 343 | f_y1 = f_y1/max_y1; // This is done during the states with a value higher than 3, as this is when you start the operating mode |
| Floris_Hoek | 18:4a6be1893d7f | 344 | f_y2 = f_y2/max_y2; |
| Floris_Hoek | 18:4a6be1893d7f | 345 | f_y3 = f_y3/max_y3; |
| Floris_Hoek | 14:1343966a79e8 | 346 | } |
| Floris_Hoek | 22:cce4dc5738af | 347 | |
| Floris_Hoek | 10:8c38a1a5b522 | 348 | } |
| Floris_Hoek | 12:f4331640e3ad | 349 | |
| Floris_Hoek | 22:cce4dc5738af | 350 | void det_max(double y, double &max_y) |
| Floris_Hoek | 22:cce4dc5738af | 351 | { |
| Floris_Hoek | 18:4a6be1893d7f | 352 | max_y = max_y < y ? y : max_y; // if max_rms is smaller than rms, set rms as new max_rms, otherwise keep max_rms |
| Floris_Hoek | 14:1343966a79e8 | 353 | } |
| Floris_Hoek | 12:f4331640e3ad | 354 | |
| Floris_Hoek | 22:cce4dc5738af | 355 | void emgcalibration() |
| Floris_Hoek | 22:cce4dc5738af | 356 | { |
| Floris_Hoek | 18:4a6be1893d7f | 357 | double y0, y1, y2, y3; // RMS values of the different EMG signals |
| Floris_Hoek | 14:1343966a79e8 | 358 | |
| Floris_Hoek | 18:4a6be1893d7f | 359 | measure_data(y0, y1, y2, y3); // Calculate RMS values |
| Floris_Hoek | 22:cce4dc5738af | 360 | |
| Floris_Hoek | 19:b3e224e0cb85 | 361 | double duration = 20.0; // Duration of the emgcalibration function, in this case 10 seconds |
| Floris_Hoek | 14:1343966a79e8 | 362 | int rounds = (duration / timeinterval); // Determine the amount of times this function has to run to run for the duration time |
| Floris_Hoek | 14:1343966a79e8 | 363 | // rounds is an integer so the value of duration / timeinterval is floored |
| Floris_Hoek | 22:cce4dc5738af | 364 | |
| Floris_Hoek | 14:1343966a79e8 | 365 | static int counter = 0; // Counter which keeps track of the amount of times the function has executed |
| Floris_Hoek | 14:1343966a79e8 | 366 | if (counter >= rounds) { |
| Floris_Hoek | 23:ff73ee119244 | 367 | MyState = (States)((int)MyState+1); // If counter is larger than rounds, change MyState to the next state |
| Floris_Hoek | 23:ff73ee119244 | 368 | measurecontrol.attach(nothing,10000); |
| Floris_Hoek | 22:cce4dc5738af | 369 | } else { |
| Floris_Hoek | 14:1343966a79e8 | 370 | counter++; // Else increase counter by 1 |
| Floris_Hoek | 14:1343966a79e8 | 371 | } |
| Floris_Hoek | 22:cce4dc5738af | 372 | |
| Floris_Hoek | 14:1343966a79e8 | 373 | } |
| Floris_Hoek | 12:f4331640e3ad | 374 | |
| Floris_Hoek | 22:cce4dc5738af | 375 | void startgame() |
| Floris_Hoek | 22:cce4dc5738af | 376 | { |
| Floris_Hoek | 18:4a6be1893d7f | 377 | pc.printf("Please choose which game you would like to start:\r\n"); |
| Floris_Hoek | 18:4a6be1893d7f | 378 | |
| Floris_Hoek | 23:ff73ee119244 | 379 | pc.printf("- Press button SW2 to start the demo mode\r\n Demo mode is a mode in which the different movements of the robot are shown.\r\n"); |
| Floris_Hoek | 23:ff73ee119244 | 380 | pc.printf(" It will move in straight lines to show that the robot meets the requirements.\r\n"); |
| Floris_Hoek | 18:4a6be1893d7f | 381 | pc.printf(" It will also show how it is able to grab and lift objects which are on the board.\r\n\r\n"); |
| Floris_Hoek | 18:4a6be1893d7f | 382 | |
| Floris_Hoek | 23:ff73ee119244 | 383 | pc.printf("- Press button SW3 to start the operating mode\r\n The operating mode is a mode in which you can control the robot by flexing the muscles to which the electrodes are attached.\r\n"); |
| Floris_Hoek | 18:4a6be1893d7f | 384 | pc.printf(" You will be able to move the arm and use the gripper to try and grab and lift objects from the board to the container.\r\n\r\n"); |
| Floris_Hoek | 18:4a6be1893d7f | 385 | |
| Floris_Hoek | 22:cce4dc5738af | 386 | while (MyState == START_GAME) { |
| Floris_Hoek | 23:ff73ee119244 | 387 | |
| Floris_Hoek | 23:ff73ee119244 | 388 | if (but3.read() == 0) { |
| Floris_Hoek | 23:ff73ee119244 | 389 | MyState = (States)((int)MyState+1); |
| Floris_Hoek | 23:ff73ee119244 | 390 | wait(0.5f); |
| Floris_Hoek | 23:ff73ee119244 | 391 | } else if (but4.read() == 0) { |
| Floris_Hoek | 23:ff73ee119244 | 392 | MyState = (States)((int)MyState+2); |
| Floris_Hoek | 23:ff73ee119244 | 393 | wait(0.5f); |
| Floris_Hoek | 22:cce4dc5738af | 394 | } |
| Floris_Hoek | 23:ff73ee119244 | 395 | |
| Floris_Hoek | 22:cce4dc5738af | 396 | } |
| Floris_Hoek | 18:4a6be1893d7f | 397 | } |
| Floris_Hoek | 18:4a6be1893d7f | 398 | |
| Floris_Hoek | 23:ff73ee119244 | 399 | |
| Floris_Hoek | 23:ff73ee119244 | 400 | void demo_mode() |
| Floris_Hoek | 23:ff73ee119244 | 401 | { |
| Floris_Hoek | 23:ff73ee119244 | 402 | |
| Floris_Hoek | 23:ff73ee119244 | 403 | state_int = 10; |
| Floris_Hoek | 23:ff73ee119244 | 404 | |
| Floris_Hoek | 23:ff73ee119244 | 405 | // 5 pre determined positions of the end effector to show it can move in straight lines |
| Floris_Hoek | 23:ff73ee119244 | 406 | xendeffector=-5; |
| Floris_Hoek | 23:ff73ee119244 | 407 | yendeffector=10.6159; |
| Floris_Hoek | 23:ff73ee119244 | 408 | wait(0.5); |
| Floris_Hoek | 23:ff73ee119244 | 409 | |
| Floris_Hoek | 23:ff73ee119244 | 410 | xendeffector=10; |
| Floris_Hoek | 23:ff73ee119244 | 411 | yendeffector=25.6159; |
| Floris_Hoek | 23:ff73ee119244 | 412 | wait(0.5); |
| Floris_Hoek | 22:cce4dc5738af | 413 | |
| Floris_Hoek | 23:ff73ee119244 | 414 | xendeffector=-14; |
| Floris_Hoek | 23:ff73ee119244 | 415 | yendeffector=21.6159; |
| Floris_Hoek | 23:ff73ee119244 | 416 | wait(0.5); |
| Floris_Hoek | 23:ff73ee119244 | 417 | |
| Floris_Hoek | 23:ff73ee119244 | 418 | xendeffector=10; |
| Floris_Hoek | 23:ff73ee119244 | 419 | yendeffector=11.6159; |
| Floris_Hoek | 23:ff73ee119244 | 420 | wait(0.5); |
| Floris_Hoek | 23:ff73ee119244 | 421 | |
| Floris_Hoek | 23:ff73ee119244 | 422 | // Last position is the start position |
| Floris_Hoek | 23:ff73ee119244 | 423 | xendeffector=0; |
| Floris_Hoek | 23:ff73ee119244 | 424 | yendeffector=10.6159; |
| Floris_Hoek | 23:ff73ee119244 | 425 | wait(0.5); |
| Floris_Hoek | 23:ff73ee119244 | 426 | |
| Floris_Hoek | 23:ff73ee119244 | 427 | MyState = START_GAME; // Go back to START_GAME mode |
| Floris_Hoek | 18:4a6be1893d7f | 428 | } |
| Floris_Hoek | 23:ff73ee119244 | 429 | |
| Floris_Hoek | 18:4a6be1893d7f | 430 | |
| Floris_Hoek | 22:cce4dc5738af | 431 | void operating_mode() |
| Floris_Hoek | 22:cce4dc5738af | 432 | { |
| Floris_Hoek | 22:cce4dc5738af | 433 | double y0,y1,y2,y3; |
| Floris_Hoek | 22:cce4dc5738af | 434 | measure_data(y0,y1,y2,y3); |
| Floris_Hoek | 22:cce4dc5738af | 435 | |
| Floris_Hoek | 23:ff73ee119244 | 436 | double threshold = 0.3; // When the analysed signal is above this threshold, the position of the end effector is changed |
| Floris_Hoek | 23:ff73ee119244 | 437 | double dr = 0.1; // The change in position with each step |
| Floris_Hoek | 23:ff73ee119244 | 438 | |
| Floris_Hoek | 23:ff73ee119244 | 439 | if(y0 > threshold && xendeffector < 16) { |
| Floris_Hoek | 23:ff73ee119244 | 440 | xendeffector=xendeffector+dr; |
| Floris_Hoek | 23:ff73ee119244 | 441 | } |
| Floris_Hoek | 23:ff73ee119244 | 442 | else if(y1 > threshold && xendeffector > -16) { |
| Floris_Hoek | 23:ff73ee119244 | 443 | xendeffector=xendeffector-dr; |
| Floris_Hoek | 23:ff73ee119244 | 444 | } |
| Floris_Hoek | 23:ff73ee119244 | 445 | if(y2 > threshold && yendeffector < 28) { |
| Floris_Hoek | 23:ff73ee119244 | 446 | yendeffector=yendeffector+dr; |
| Floris_Hoek | 23:ff73ee119244 | 447 | } |
| Floris_Hoek | 23:ff73ee119244 | 448 | else if(y3 > threshold && yendeffector > 8) { |
| Floris_Hoek | 23:ff73ee119244 | 449 | yendeffector=yendeffector-dr; |
| Floris_Hoek | 22:cce4dc5738af | 450 | } |
| Floris_Hoek | 22:cce4dc5738af | 451 | |
| Floris_Hoek | 23:ff73ee119244 | 452 | //servo besturing |
| Floris_Hoek | 23:ff73ee119244 | 453 | |
| Floris_Hoek | 23:ff73ee119244 | 454 | if(but4.read() == 0 && ingedrukt == 0) { |
| Floris_Hoek | 23:ff73ee119244 | 455 | for(int i=0; i<100; i++) { |
| Floris_Hoek | 23:ff73ee119244 | 456 | myservo = i/100.0; |
| Floris_Hoek | 23:ff73ee119244 | 457 | |
| Floris_Hoek | 23:ff73ee119244 | 458 | wait(0.01); |
| Floris_Hoek | 23:ff73ee119244 | 459 | } |
| Floris_Hoek | 23:ff73ee119244 | 460 | ingedrukt = 1; |
| Floris_Hoek | 23:ff73ee119244 | 461 | } else if(but4.read() == 0 && ingedrukt == 1) { |
| Floris_Hoek | 23:ff73ee119244 | 462 | for(int i=100; i>0; i--) { |
| Floris_Hoek | 23:ff73ee119244 | 463 | myservo = i/100.0; |
| Floris_Hoek | 23:ff73ee119244 | 464 | |
| Floris_Hoek | 23:ff73ee119244 | 465 | wait(0.01); |
| Floris_Hoek | 23:ff73ee119244 | 466 | } |
| Floris_Hoek | 23:ff73ee119244 | 467 | ingedrukt = 0; |
| Floris_Hoek | 23:ff73ee119244 | 468 | } |
| Floris_Hoek | 23:ff73ee119244 | 469 | if (but3.read() == 0) { |
| Floris_Hoek | 23:ff73ee119244 | 470 | MyState = (States)((int)MyState+1); |
| Floris_Hoek | 23:ff73ee119244 | 471 | wait(0.5f); |
| Floris_Hoek | 23:ff73ee119244 | 472 | } |
| Floris_Hoek | 23:ff73ee119244 | 473 | measureandcontrol(); |
| Floris_Hoek | 23:ff73ee119244 | 474 | } |
| Floris_Hoek | 23:ff73ee119244 | 475 | |
| Floris_Hoek | 23:ff73ee119244 | 476 | void endgame() |
| Floris_Hoek | 23:ff73ee119244 | 477 | { |
| Floris_Hoek | 23:ff73ee119244 | 478 | pc.printf("The game has ended, will move the end effector to (0,0), put the motors off and will now return to the state START_GAME"); |
| Floris_Hoek | 23:ff73ee119244 | 479 | xendeffector=0.0; |
| Floris_Hoek | 23:ff73ee119244 | 480 | yendeffector=10.6159; |
| Floris_Hoek | 23:ff73ee119244 | 481 | wait(0.3f); |
| Floris_Hoek | 23:ff73ee119244 | 482 | sendtomotor(0.0f,0.0f); |
| Floris_Hoek | 23:ff73ee119244 | 483 | wait(0.1f); |
| Floris_Hoek | 23:ff73ee119244 | 484 | measurecontrol.attach(nothing,10000); |
| Floris_Hoek | 23:ff73ee119244 | 485 | MyState = START_GAME; |
| Floris_Hoek | 18:4a6be1893d7f | 486 | } |
| Floris_Hoek | 18:4a6be1893d7f | 487 | |
| Floris_Hoek | 22:cce4dc5738af | 488 | void New_State() |
| Floris_Hoek | 22:cce4dc5738af | 489 | { |
| Floris_Hoek | 22:cce4dc5738af | 490 | switch (MyState) { |
| Floris_Hoek | 9:e8cc37a94fec | 491 | case MOTORS_OFF : |
| Floris_Hoek | 22:cce4dc5738af | 492 | pc.printf("\r\nState: Motors turned off\r\n"); |
| Floris_Hoek | 9:e8cc37a94fec | 493 | motorsoff(); |
| Floris_Hoek | 9:e8cc37a94fec | 494 | break; |
| Floris_Hoek | 22:cce4dc5738af | 495 | |
| Floris_Hoek | 9:e8cc37a94fec | 496 | case EMG_CALIBRATION : |
| Floris_Hoek | 22:cce4dc5738af | 497 | pc.printf("\r\nState: EMG Calibration\r\n"); |
| Floris_Hoek | 22:cce4dc5738af | 498 | pc.printf("Emg calibration mode will run for 20 seconds. Try to flex the muscles to which the electrodes are attached as hard as possible during this time.\r\n"); |
| Floris_Hoek | 14:1343966a79e8 | 499 | measurecontrol.attach(emgcalibration,timeinterval); |
| Floris_Hoek | 9:e8cc37a94fec | 500 | break; |
| Floris_Hoek | 22:cce4dc5738af | 501 | |
| Floris_Hoek | 9:e8cc37a94fec | 502 | case START_GAME : |
| Floris_Hoek | 22:cce4dc5738af | 503 | pc.printf("\r\nState: Start game\r\n"); |
| Floris_Hoek | 18:4a6be1893d7f | 504 | startgame(); |
| Floris_Hoek | 9:e8cc37a94fec | 505 | break; |
| Floris_Hoek | 22:cce4dc5738af | 506 | |
| Floris_Hoek | 9:e8cc37a94fec | 507 | case DEMO_MODE : |
| Floris_Hoek | 22:cce4dc5738af | 508 | pc.printf("\r\nState: Demo mode\r\n"); |
| Floris_Hoek | 23:ff73ee119244 | 509 | measurecontrol.attach(measureandcontrol,timeinterval); |
| Floris_Hoek | 23:ff73ee119244 | 510 | demo_mode(); |
| Floris_Hoek | 9:e8cc37a94fec | 511 | break; |
| Floris_Hoek | 22:cce4dc5738af | 512 | |
| Floris_Hoek | 18:4a6be1893d7f | 513 | case OPERATING_MODE : |
| Floris_Hoek | 22:cce4dc5738af | 514 | pc.printf("\r\nState: Operating mode\r\n"); |
| Floris_Hoek | 18:4a6be1893d7f | 515 | measurecontrol.attach(operating_mode,timeinterval); |
| Floris_Hoek | 9:e8cc37a94fec | 516 | break; |
| Floris_Hoek | 22:cce4dc5738af | 517 | |
| Floris_Hoek | 9:e8cc37a94fec | 518 | case END_GAME : |
| Floris_Hoek | 22:cce4dc5738af | 519 | pc.printf("\r\nState: End of the game\r\n"); |
| Floris_Hoek | 23:ff73ee119244 | 520 | endgame(); |
| Floris_Hoek | 9:e8cc37a94fec | 521 | break; |
| Floris_Hoek | 22:cce4dc5738af | 522 | |
| Floris_Hoek | 9:e8cc37a94fec | 523 | default : |
| Floris_Hoek | 22:cce4dc5738af | 524 | pc.printf("\r\nDefault state: Motors are turned off\r\n"); |
| Floris_Hoek | 22:cce4dc5738af | 525 | measurecontrol.attach(nothing,10000); |
| Floris_Hoek | 23:ff73ee119244 | 526 | sendtomotor(0.0,0.0); |
| Floris_Hoek | 9:e8cc37a94fec | 527 | break; |
| Floris_Hoek | 9:e8cc37a94fec | 528 | } |
| Floris_Hoek | 9:e8cc37a94fec | 529 | } |
| Floris_Hoek | 9:e8cc37a94fec | 530 | |
| Floris_Hoek | 22:cce4dc5738af | 531 | void Set_State() |
| Floris_Hoek | 22:cce4dc5738af | 532 | { |
| Floris_Hoek | 23:ff73ee119244 | 533 | xendeffector=0.0; |
| Floris_Hoek | 23:ff73ee119244 | 534 | yendeffector=10.6159; |
| Floris_Hoek | 23:ff73ee119244 | 535 | wait(0.3f); |
| Floris_Hoek | 23:ff73ee119244 | 536 | sendtomotor(0.0,0.0); // Stop the motors |
| Floris_Hoek | 23:ff73ee119244 | 537 | measurecontrol.attach(nothing,10000); // Stop the ticker function from running |
| Floris_Hoek | 19:b3e224e0cb85 | 538 | |
| Floris_Hoek | 23:ff73ee119244 | 539 | pc.printf("\r\nPress number: | To go to state:"); |
| Floris_Hoek | 23:ff73ee119244 | 540 | pc.printf("\r\n (0) | MOTORS_OFF: Set motorspeed just in case to 0 and wait till button SW2 is pressed"); |
| Floris_Hoek | 23:ff73ee119244 | 541 | pc.printf("\r\n (1) | EMG_CALIBRATION: Calibrate the maximum of the emg signals and normalise the emg signals with these maxima"); |
| Floris_Hoek | 23:ff73ee119244 | 542 | pc.printf("\r\n (2) | START_GAME: Determine by keyboard input if you want to go to the demo or operating mode"); |
| Floris_Hoek | 23:ff73ee119244 | 543 | pc.printf("\r\n (3) | DEMO_MODE: The demo mode will show the different motions that the robot can make"); |
| Floris_Hoek | 23:ff73ee119244 | 544 | pc.printf("\r\n (4) | OPERATING_MODE: Move the arms and gripper of the arm by flexing your muscles"); |
| Floris_Hoek | 23:ff73ee119244 | 545 | pc.printf("\r\n (5) | END_GAME: End effector returns to (0,0) and the motors are turned off, returns to START_GAME mode afterwards"); |
| Floris_Hoek | 22:cce4dc5738af | 546 | |
| Floris_Hoek | 23:ff73ee119244 | 547 | wait(0.5f); |
| Floris_Hoek | 22:cce4dc5738af | 548 | |
| Floris_Hoek | 23:ff73ee119244 | 549 | char a = '0'; |
| Floris_Hoek | 23:ff73ee119244 | 550 | char b = '5'; |
| Floris_Hoek | 23:ff73ee119244 | 551 | bool boolean = true; |
| Floris_Hoek | 22:cce4dc5738af | 552 | |
| Floris_Hoek | 23:ff73ee119244 | 553 | while (boolean) { |
| Floris_Hoek | 23:ff73ee119244 | 554 | char c = pc.getc(); |
| Floris_Hoek | 22:cce4dc5738af | 555 | |
| Floris_Hoek | 23:ff73ee119244 | 556 | if (c >= a && c <= b) { |
| Floris_Hoek | 23:ff73ee119244 | 557 | MyState = (States)(c-'0'); |
| Floris_Hoek | 23:ff73ee119244 | 558 | boolean = false; |
| Floris_Hoek | 22:cce4dc5738af | 559 | |
| Floris_Hoek | 23:ff73ee119244 | 560 | } else { |
| Floris_Hoek | 23:ff73ee119244 | 561 | pc.printf("\r\nPlease enter a number between 0 and 5\r\n"); |
| Floris_Hoek | 19:b3e224e0cb85 | 562 | } |
| Floris_Hoek | 19:b3e224e0cb85 | 563 | } |
| Floris_Hoek | 19:b3e224e0cb85 | 564 | } |