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