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
Revision 27:e704fdc41e87, committed 2019-11-04
- Comitter:
- Floris_Hoek
- Date:
- Mon Nov 04 14:47:17 2019 +0000
- Parent:
- 26:418f025a30c6
- Commit message:
- FINAL VERSION V1
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Fri Nov 01 17:18:39 2019 +0000 +++ b/main.cpp Mon Nov 04 14:47:17 2019 +0000 @@ -1,5 +1,3 @@ -// Operating mode might not go to next state when SW2 is pressed - #include "mbed.h" #include "HIDScope.h" #include "BiQuad.h" @@ -11,49 +9,58 @@ #include "Servo.h" // Included to control the servo motor -Servo myservo(D13); // To control the servo motor -DigitalIn but3(SW2); // To go to the next state or to choose one of two game modes when in state START_GAME -DigitalIn but4(SW3); // To choose one of two game modes when in state START_GAME or to move the gripper -DigitalOut ledr(LED_RED); +Servo myservo(D13); // To control the servo motor + +DigitalIn button1(SW2); // Button to go to the next state or to choose one of two game modes when in state START_GAME +DigitalIn button2(SW3); // Button to choose one of two game modes when in state START_GAME or to move the gripper in the operating mode + +DigitalOut ledr(LED_RED); // Define the output for the three different LED's on the K64F. These will be used to show in which state the robot currently is in DigitalOut ledg(LED_GREEN); DigitalOut ledb(LED_BLUE); -AnalogIn S0(A0); +AnalogIn S0(A0); // Define the different analog inputs for the four EMG shields that are connected to the AnalogIn S1(A1); AnalogIn S2(A2); AnalogIn S3(A3); -DigitalOut motor1Direction(D7); -FastPWM motor1Velocity(D6); -DigitalOut motor2Direction(D4); -FastPWM motor2Velocity(D5); +DigitalOut motor1Direction(D7); // Digital out to control the direction of motor1 +FastPWM motor1Velocity(D6); // FastPWM to control the velocity of motor1 +DigitalOut motor2Direction(D4); // Digital out to control the direction of motor2 +FastPWM motor2Velocity(D5); // FastPWM to control the velocity of motor2 -// Encoders 1 and 2 respectively +// Encoder for motor1 and motor2 QEI Encoder1(D8,D9,NC,8400); QEI Encoder2(D11,D10,NC,8400); -Ticker measurecontrol; // Ticker function for the measurements +Ticker measurecontrol; // Ticker function for the measurements + +Serial pc(USBTX, USBRX); // Used to get information about the different states and choises if a laptop is attached -// Make arrays for the different variables for the motors -//AnalogIn Shields[4] = {S0, S1, S2, S3}; -//DigitalOut MotorDirections[2] = {MD0, MD1}; -//FastPWM MotorVelocities[2] = {MV0, MV1}; -//QEI Encoders[2] = {E0, E1}; - -Serial pc(USBTX, USBRX); - -double PI = 3.14159265358;//97932384626433832795028841971693993; +double PI = 3.14159265358; // Defined pi because it is used multiple times volatile double timeinterval = 0.001f; // Time interval of the Ticker function -volatile double frequency = 17000.0; // Set motorfrequency +volatile double frequency = 17000.0; // Motorfrequency of both motors double period_signal = 1.0/frequency; // Convert to period of the signal +/* + Motor calibration is done by manually moving the arms to the start position. This is the position in which the arms + that are connected to the motors are in line with each other. If they are in the correct position, the robot needs + to be reset. Then this programm will run and yendeffector and xendeffector are set to be 10.6159 and 0 which are the + correct physical positions on the board. +*/ double yendeffector = 10.6159; double xendeffector = 0; -int ingedrukt = 0; -int state_int; -int previous_state_int; -double motorvalue1; -double motorvalue2; + +/* + Boolean that keeps track in which configuration the hook is + when 0, the hook is ready to grab a ring + when 1, it is ready to drob an object if it grabbed one +*/ +bool pressed = 0; + +int previous_state_int; // Keeps track of the previous state to check if the state has changed +double motorvalue1; // Motorvalue that has to be send to motor1 +double motorvalue2; // Motorvalue that has to be send to motor2 + // Define the different states in which the robot can be enum States {MOTORS_OFF, EMG_CALIBRATION, START_GAME, DEMO_MODE, OPERATING_MODE, END_GAME @@ -64,79 +71,58 @@ // Initialise the functions - +double PID_controller1(double error1); +double PID_controller2(double error2); +void getmeasuredposition(double & measuredposition1, double & measuredposition2); +void getreferenceposition(double & referenceposition1, double & referenceposition2); +void sendtomotor(double motorvalue1, double motorvalue2); +void measureandcontrol(); void motorsoff(); - void measure_data(double &f_y0, double &f_y1, double &f_y2, double &f_y3); - void det_max(double y, double &max_y); - void emgcalibration(); - -void nothing() -{ - // Do nothing -} - void startgame() ; - void demo_mode(); - void operating_mode(); - +void endgame(); void New_State(); -void Set_State(); - -double PID_controller1(double error1); - -double PID_controller2(double error2); - -void getmeasuredposition(double & measuredposition1, double & measuredposition2); - -void getreferenceposition(double & referenceposition1, double & referenceposition2); - -void sendtomotor(double motorvalue1, double motorvalue2); - -void measureandcontrol(); - int main() { - ledr = 1; + ledr = 1; // Set all LEDs to off ledg = 1; ledb = 1; - pc.baud(115200); + pc.baud(115200); // Define bitrate for the communication pc.printf("Starting...\r\n\r\n"); - motor1Velocity.period(period_signal); // Set the period of the PWMfunction - motor2Velocity.period(period_signal); // Set the period of the PWMfunction + motor1Velocity.period(period_signal); // Set the period of the PWMfunction + motor2Velocity.period(period_signal); // Set the period of the PWMfunction previous_state_int = (int)MyState; // Save previous state to compare with current state and possibly execute New_State() // in the while loop - New_State(); // Execute the functions belonging to the current state + New_State(); // For initialising the state of the robot run New_State() once while(true) { - if ( (previous_state_int - (int)MyState) != 0 ) { // If current state is not previous state execute New_State() - New_State(); + if ( (previous_state_int - (int)MyState) != 0 ) { + New_State(); // If current state is not previous state run New_State() } } } - +// Parallel PID controller to calculate the error for motor1 double PID_controller1(double error1) { - // Define errors for motor 1 and 2 - static double error_integral1 = 0; - static double error_prev1 = error1; + static double error_integral1 = 0; // Keep track of the integral error within this function + static double error_prev1 = error1; // Safe previous error to use for the derivative part - // Low-pass filter + // Low-pass filter to reduce noise from the derivative part static BiQuad LowPassFilter(0.0640, 0.1279, 0.0640, -1.1683, 0.4241); - // PID variables: we assume them to be the same for both motors + // PID variables: we assume them to be the same for both motors, found by trial and error double Kp = 63; double Ki = 3.64; double Kd = 5; @@ -159,16 +145,16 @@ } +// Parallel PID controller to calculate the error for motor2 double PID_controller2(double error2) { - // Define errors for motor 1 and 2 - static double error_integral2 = 0; - static double error_prev2 = error2; + static double error_integral2 = 0; // Keep track of the integral error within this function + static double error_prev2 = error2; // Safe previous error to use for the derivative part - // Low-pass filter + // Low-pass filter to reduce noise from the derivative part static BiQuad LowPassFilter(0.0640, 0.1279, 0.0640, -1.1683, 0.4241); - // PID variables: we assume them to be the same for both motors + // PID variables: we assume them to be the same for both motors, found by trial and error double Kp = 63; double Ki = 3.64; double Kd = 5; @@ -191,53 +177,49 @@ } -//get the measured position +// Calculate the current configuration of both motors void getmeasuredposition(double & measuredposition1, double & measuredposition2) { // Obtain the counts of motors 1 and 2 from the encoder - int countsmotor1; - int countsmotor2; - countsmotor1 = Encoder1.getPulses(); - countsmotor2 = Encoder2.getPulses(); + int countsmotor1 = Encoder1.getPulses(); + int countsmotor2 = Encoder2.getPulses(); // Obtain the measured position for motor 1 and 2 + // Devide by 8400 because 8400 counts is one rotation and times 2 to calculate the measuredposition as a fraction of the rotation measuredposition1 = ((double)countsmotor1) / 8400.0f * 2.0f; measuredposition2 = ((double)countsmotor2) / 8400.0f * 2.0f; } -//get the reference of the +// Calculates the desired configuration of both motors by using the inverse kinematics void getreferenceposition(double & referenceposition1, double & referenceposition2) { //Measurements of the arm - double L0=1.95; - double L1=15; - double L2=20; + double L0=1.95; // Distance from both motors to (0,0), (0,0) is between motors 1 and 2 + double L1=15; // Length of the arms attached to motor 1 and 2 + double L2=20; // Length of the arms attached to the end-effector - //Inverse kinematics: given the end position, what are the desired motor angles of 1 and 2 + //Inverse kinematics: given the end position, what are the desired motor angles of 1 and 2 (explained in the report) double desiredmotorangle1, desiredmotorangle2; 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; 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; //Convert motor angles to counts - double desiredmotorrounds1; - double desiredmotorrounds2; + double desiredmotorrounds1, desiredmotorrounds2; desiredmotorrounds1 = (desiredmotorangle1)/360.0; desiredmotorrounds2 = (desiredmotorangle2)/360.0; - //Assign this to new variables because otherwise it doesn't work + // Assign this to new variables because otherwise it doesn't work referenceposition1 = desiredmotorrounds1; referenceposition2 = desiredmotorrounds2; } -//send value to motor -// IT WAS "void sendtomotor(float & motorvalue1, float & motorvalue2)" BUT I REMOVED THE REFERENCE, BECAUSE I THOUGHT IT WAS NOT NEEDED +// Send the absolute motorvalues as velocity to the motors and set the motor directions by checking if the motorvalues are positive void sendtomotor(double motorvalue1, double motorvalue2) { // Define the absolute motor values - double absolutemotorvalue1; - double absolutemotorvalue2; + double absolutemotorvalue1, absolutemotorvalue2; absolutemotorvalue1 = fabs(motorvalue1); absolutemotorvalue2 = fabs(motorvalue2); @@ -254,7 +236,8 @@ motor2Direction = (motorvalue2 > 0.0f); } -// function to call reference absolutemotorvalueocity, measured absolutemotorvalueocity and controls motor with feedback + +// function to call different functions and control the motors void measureandcontrol() { // Get the reference positions of motor 1 and 2 @@ -266,25 +249,20 @@ getmeasuredposition(measured1, measured2); // Calculate the motor values - //double motorvalue1, motorvalue2; motorvalue1 = PID_controller1(reference1 - measured1); motorvalue2 = PID_controller2(reference2 - measured2); sendtomotor(motorvalue1, motorvalue2); } -void motorsoff() -{ - // Function to turn the motors off. First state that the robot has. Robot will stay in this state untill button SW2 is pressed. - // Robot will not return to this state anymore unless the user sets it back to this state with the keyboard input. +// Function that is called once in the MOTORS_OFF state, motorvelocities are zero, will run the while loop until button1 is pressed. +void motorsoff() { sendtomotor(0.0,0.0); // Set motor velocity to 0 - state_int = 10; - bool whileloop_boolean = true; // Boolean for the while loop while (whileloop_boolean) { - if (but3.read() == 0) { // If button SW2 is pressed: + if (button1.read() == 0) { // If button1 is pressed: MyState = (States)((int)MyState+1); // set MyState to EMG_CALIBRATION and exit the while loop whileloop_boolean = false; // by making whileloop_boolean equal to false wait(0.5f); @@ -292,9 +270,14 @@ } } +/* + Uses a high-pass filter, rectifier and a low-pass filter on all EMG signals and then normalises the signal + by deviding by the maximum value that was measured during the EMG_CALIBRATION state. This maximum value + is determined within this function if the state is EMG_CALIBRATION +*/ void measure_data(double &f_y0, double &f_y1, double &f_y2, double &f_y3) { - // High pass + // High-pass double hb0 = 0.9169; // Coefficients from the following formula: double hb1 = -1.8338; // double hb2 = 0.9169; // b0 + b1 z^-1 + b2 z^-2 @@ -302,7 +285,7 @@ double ha1 = -1.8268; // a0 + a1 z^-1 + a2 z^-2 double ha2 = 0.8407; // - // Low pass + // Low-pass double lb0 = 0.000083621; // Coefficients from the following formula: double lb1 = 0.0006724; // double lb2 = 0.000083621; // b0 + b1 z^-1 + b2 z^-2 @@ -310,41 +293,40 @@ double la1 = -1.9740; // a0 + a1 z^-1 + a2 z^-2 double la2 = 0.9743; // - static double max_y0 = 0.001; - static double max_y1 = 0.001; + static double max_y0 = 0.001; // Maxima have to be static because they have to be changed during the + static double max_y1 = 0.001; // calibration and have to be used afterwards to normalise the signal static double max_y2 = 0.001; static double max_y3 = 0.001; - static BiQuad hFilter0(hb0,hb1,hb2,ha0,ha1,ha2); // Create 4 equal filters used for the different EMG signals + static BiQuad hFilter0(hb0,hb1,hb2,ha0,ha1,ha2); // Create 4 equal high-pass filters used for the different EMG signals static BiQuad hFilter1(hb0,hb1,hb2,ha0,ha1,ha2); static BiQuad hFilter2(hb0,hb1,hb2,ha0,ha1,ha2); static BiQuad hFilter3(hb0,hb1,hb2,ha0,ha1,ha2); - static BiQuad lFilter0(lb0,lb1,lb2,la0,la1,la2); // Create 4 equal filters used for the different EMG signals + static BiQuad lFilter0(lb0,lb1,lb2,la0,la1,la2); // Create 4 equal low-pass filters used for the different EMG signals static BiQuad lFilter1(lb0,lb1,lb2,la0,la1,la2); static BiQuad lFilter2(lb0,lb1,lb2,la0,la1,la2); static BiQuad lFilter3(lb0,lb1,lb2,la0,la1,la2); - f_y0 = hFilter0.step(S0); // Apply filters on the different EMG signals + f_y0 = hFilter0.step(S0); // Apply high-pass filters on the different EMG signals f_y1 = hFilter1.step(S1); f_y2 = hFilter2.step(S2); f_y3 = hFilter3.step(S3); - f_y0 = abs(f_y0); + f_y0 = abs(f_y0); // Apply rectifier on the different EMG signals f_y1 = abs(f_y1); f_y2 = abs(f_y2); f_y3 = abs(f_y3); - f_y0 = lFilter0.step(f_y0); + f_y0 = lFilter0.step(f_y0); // Apply low-pass filters on the different EMG signals f_y1 = lFilter1.step(f_y1); f_y2 = lFilter2.step(f_y2); f_y3 = lFilter3.step(f_y3); if (MyState == EMG_CALIBRATION) { - - det_max(f_y0, max_y0); // Determine the maximum RMS value of the EMG signals during the EMG_CALIBRATION state - det_max(f_y1, max_y1); + det_max(f_y0, max_y0); // Determine the maximum value of the EMG signals during the EMG_CALIBRATION state + det_max(f_y1, max_y1); // If a new maximum is found, the max_y_ value is adjusted det_max(f_y2, max_y2); det_max(f_y3, max_y3); @@ -357,65 +339,74 @@ } + +// Function to determine if y is larger than max_y void det_max(double y, double &max_y) { - 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 + max_y = max_y < y ? y : max_y; // if max_y is smaller than y, set y as new max_y, otherwise keep max_y } + +// Function that is attached to the measurecontrol ticker when the state is EMG_CALIBRATION, the ticker will run this function for a specific amount of time void emgcalibration() { - double y0, y1, y2, y3; // RMS values of the different EMG signals + double y0, y1, y2, y3; // variables to safe the output from measure_data - measure_data(y0, y1, y2, y3); // Calculate RMS values + measure_data(y0, y1, y2, y3); // Calculate y values - double duration = 20.0; // Duration of the emgcalibration function, in this case 10 seconds + double duration = 20.0; // Duration that the emgcalibration() has to run int rounds = (duration / timeinterval); // Determine the amount of times this function has to run to run for the duration time - // rounds is an integer so the value of duration / timeinterval is floored + // Rounds is an integer so the value of duration / timeinterval is floored - static int counter = 0; // Counter which keeps track of the amount of times the function has executed + static int counter = 0; // Counter which keeps track of the amount of times the function has executed if (counter >= rounds) { - MyState = START_GAME; // If counter is larger than rounds, change MyState to the next state - ledb = 1; - measurecontrol.detach(); + MyState = START_GAME; // If counter is larger than rounds, change MyState to the START_GAME state + ledb = 1; // Turn the blue LED off + measurecontrol.detach(); // detach emgcalibration() from the ticker function } else { counter++; // Else increase counter by 1 } - int duration_led = 0.1 / timeinterval; - if (counter % duration_led == 0) { + int rounds_led = 0.1f / timeinterval; // Amount of rounds that the blue LED has to be on and off + if (counter % rounds_led == 0) { ledb = !ledb; } } + +// Function that is executed when the state is changed to START_GAME, will run a while loop until +// button1 or 2 are pressed to choose the game mode void startgame() { + // Print messages with information for the user pc.printf("Please choose which game you would like to start:\r\n"); - 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"); + pc.printf("- Press button1 to start the demo mode\r\n Demo mode is a mode in which the different movements of the robot are shown.\r\n"); pc.printf(" It will move in straight lines to show that the robot meets the requirements.\r\n"); pc.printf(" It will also show how it is able to grab and lift objects which are on the board.\r\n\r\n"); - 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"); + pc.printf("- Press button2 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"); 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"); while (MyState == START_GAME) { - - if (but3.read() == 0) { - MyState = (States)((int)MyState+1); + if (button1.read() == 0) { + MyState = DEMO_MODE; // Press button1 to choose DEMO_MODE wait(0.5f); - } else if (but4.read() == 0) { - MyState = (States)((int)MyState+2); + } else if (button2.read() == 0) { + MyState = OPERATING_MODE; // Press button2 to choose OPERATING_MODE wait(0.5f); } - } } +// Function that is executed when the state is changed to DEMO_MODE, will move the end-effector +// to 5 different positions to show it can move in straight lines and then go back to the START_GAME state void demo_mode() { - - // 5 pre determined positions of the end effector to show it can move in straight lines + // CURRENTLY STILL NOT WORKING, ARMS WILL MOVE TO SINGULARITY, WATCH OUT WITH THIS MODE + + // 5 pre determined positions of the end-effector to show it can move in straight lines xendeffector=-5; yendeffector=10.6159; wait(0.5); @@ -440,49 +431,55 @@ MyState = START_GAME; // Go back to START_GAME mode } - +/* + Function that is attached to the measurecontrol ticker when the state is OPERATING_MODE + Turns the green LED on and off, calls measuredata(), changes the configuration of the hook + when button2 is pressed, sets a new position for the end-effector and goes to the state + END_GAME when button1 is pressed. +*/ void operating_mode() { - // green turns on and off while running this function - static int counter = 0; - int duration_led = 0.1 / timeinterval; - - if (counter % duration_led == 0) { + // Turn green LED on or off + static int counter = 0; // Keep track of the amount of times the function has executed + int rounds_led = 0.1 / timeinterval; // Amount of rounds that the green LED has to be on and off + if (counter % rounds_led == 0) { ledg = !ledg; counter = 0; } counter++; - double y0,y1,y2,y3; - measure_data(y0,y1,y2,y3); + measure_data(y0,y1,y2,y3); // Calculate y values //servo besturing - - if(but4.read() == 0 && ingedrukt == 0) { - for(int i=0; i<100; i++) { - myservo = i/100.0; - } - ingedrukt = 1; + if(button2.read() == 0 && pressed == 0) { + // if button2 is pressed, set y0, y1, y2 and y3 to zero, change pressed and change + // the servo configuration one step at a time to reduce the speed of the rotation y0 = 0; y1 = 0; y2 = 0; y3 = 0; - } - else if(but4.read() == 0 && ingedrukt == 1) { - for(int i=100; i>0; i--) { + pressed = 1; + for(int i=0; i<100; i++) { myservo = i/100.0; } + } + else if(button2.read() == 0 && pressed == 1) { + // if button2 is pressed, set y0, y1, y2 and y3 to zero, change pressed and change + // the servo configuration one step at a time to reduce the speed of the rotation y0 = 0; y1 = 0; y2 = 0; y3 = 0; - ingedrukt = 0; + pressed = 0; + for(int i=100; i>0; i--) { + myservo = i/100.0; + } } - - double threshold = 0.4; // When the analysed signal is above this threshold, the position of the end effector is changed - double dr = 0.01; // The change in position with each step + // The threshold has been set to 0.4 by trial and error + double threshold = 0.4; // When the analysed signal is above this threshold, the position of the end-effector is changed + double dr = 0.01; // The change in position with each execution if(y0 > threshold && xendeffector < 16) { xendeffector=xendeffector+dr; @@ -490,6 +487,7 @@ else if(y1 > threshold && xendeffector > -16) { xendeffector=xendeffector-dr; } + // The threshold was adjusted for the y-position because this worked better, this maybe had to be done because of a broken EMG cable if(y2 > threshold+0.2 && yendeffector < 28) { yendeffector=yendeffector+dr; } @@ -497,43 +495,49 @@ yendeffector=yendeffector-dr; } - - if (but3.read() == 0) { + // When button1 is pressed, run while loop until button is released again to prevent bouncing + if (button1.read() == 0) { bool buttonss = true; while (buttonss) { - if (but3.read() == 1) { + if (button1.read() == 1) { buttonss = false; } } - 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"); - MyState = END_GAME; - measurecontrol.detach(); + pc.printf("The game has ended, will move the end-effector to (0,0), put the motors off and will return to the state START_GAME"); + MyState = END_GAME; // Set MyState to END_GAME + measurecontrol.detach(); // Detach the operating_mode() function from measurecontrol } - measureandcontrol(); + measureandcontrol(); // Call measureandcontrol() to adjust the motors } + +// Function that is executed once when state is changed to END_GAME, returns the end-effector to +// the start position and detaches the measureandcontrol function from the measurecontrol ticker void endgame() { measurecontrol.attach(measureandcontrol,timeinterval); double tempx = xendeffector; double tempy = yendeffector-10.6159; - double steps = 20; + double steps = 20; // Change the position of the end-effector in a certain amount of steps to the start-position + // This is done in steps to reduce abrupt movement of the end-effector for (int i = 0; i < steps; i++) { xendeffector = xendeffector - tempx/steps; yendeffector = yendeffector - tempy/steps; wait(0.1); } - measurecontrol.detach(); - MyState = START_GAME; + MyState = START_GAME; // Return the state to START_GAME so a new game mode can be chosen again } + +// Function that is called by the while loop in the main function if the current state is changed +// Attaches or executes the functions belonging to the current state void New_State() { - previous_state_int = (int)MyState; // Change previous state to current state + previous_state_int = (int)MyState; // Change previous state to current state switch (MyState) { case MOTORS_OFF : @@ -546,7 +550,7 @@ case EMG_CALIBRATION : pc.printf("\r\nState: EMG Calibration\r\n"); 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"); - measurecontrol.attach(emgcalibration,timeinterval); + measurecontrol.attach(emgcalibration,timeinterval); // Attach emgcalibration() to the measurecontrol ticker break; case START_GAME : @@ -559,12 +563,12 @@ case DEMO_MODE : pc.printf("\r\nState: Demo mode\r\n"); - measurecontrol.attach(measureandcontrol,timeinterval); + measurecontrol.attach(measureandcontrol,timeinterval); // Attach measureandcontrol() to the measurecontrol ticker ledr = 1; // red led is on when you enter START_GAME state ledb = 0; // blue led is on when you enter START_GAME state ledg = 0; // green led is on when you enter START_GAME state demo_mode(); - measurecontrol.detach(); + measurecontrol.detach(); // Detach measureandcontrol() grom the measurecontrol ticker break; case OPERATING_MODE : @@ -572,7 +576,7 @@ ledr = 1; // red led is off when you enter OPERATING_MODE state ledb = 1; // blue led is off when you enter OPERATING_MODE state ledg = 0; // green led is on when you enter OPERATING_MODE state - measurecontrol.attach(operating_mode,timeinterval); + measurecontrol.attach(operating_mode,timeinterval); // Attach operating_mode() to the measurecontrol ticker break; case END_GAME : @@ -584,44 +588,14 @@ break; default : - pc.printf("\r\nDefault state: Motors are turned off\r\n"); - + pc.printf("\r\nSTATE IS CHANGED TO A NONEXISTING STATE!\r\n"); + pc.printf("\r\nMotors are turned off\r\n"); sendtomotor(0.0,0.0); - break; + ledg = 1; + ledb = 1; + while (true) { + ledr = !ledr; + wait(0.1f); + } } } - -void Set_State() -{ - xendeffector=0.0; - yendeffector=10.6159; - wait(0.3f); - sendtomotor(0.0,0.0); // Stop the motors - // Stop the ticker function from running - - pc.printf("\r\nPress number: | To go to state:"); - pc.printf("\r\n (0) | MOTORS_OFF: Set motorspeed just in case to 0 and wait till button SW2 is pressed"); - pc.printf("\r\n (1) | EMG_CALIBRATION: Calibrate the maximum of the emg signals and normalise the emg signals with these maxima"); - pc.printf("\r\n (2) | START_GAME: Determine by keyboard input if you want to go to the demo or operating mode"); - pc.printf("\r\n (3) | DEMO_MODE: The demo mode will show the different motions that the robot can make"); - pc.printf("\r\n (4) | OPERATING_MODE: Move the arms and gripper of the arm by flexing your muscles"); - 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"); - - wait(0.5f); - - char a = '0'; - char b = '5'; - bool boolean = true; - - while (boolean) { - char c = pc.getc(); - - if (c >= a && c <= b) { - MyState = (States)(c-'0'); - boolean = false; - - } else { - pc.printf("\r\nPlease enter a number between 0 and 5\r\n"); - } - } -}