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