With this script a Ball-E robot can be made and be operative for the use.

Dependencies:   HIDScope MODSERIAL QEI biquadFilter mbed

Fork of Samenvoegen_7_5 by Biorobotics10

Revision:
9:a5c2ddf2cb8e
Parent:
8:151e43b99156
Child:
10:57f090f3ddda
--- a/main.cpp	Tue Oct 27 09:57:21 2015 +0000
+++ b/main.cpp	Tue Oct 27 15:42:48 2015 +0000
@@ -2,11 +2,10 @@
 // Authors: Ewoud Velu, Lisa Verhoeven, Robert van der Wal, Thijs van der Wal, Emily Zoetbrood
 /* This is the script of a EMG measurment moving robot. The purpose of the robot is to amuse people with the disease of Ducenne.
    The robot is designed to throw a ball in to a certain chosen pocket.
-   In order to achieve this movement we use a ‘arm’ that can turn in the vertical plane and move in the horizontal plane.
-*/
+   In order to achieve this movement we use a ‘arm’ that can turn in the vertical plane and move in the horizontal plane. */
 
-//*********************************************** LIBRARY DECLARATION ********************************************
-// Libraries are files which contain standard formulas for reading surtain information. Every library contains its own information. 
+//================================================================================ LIBRARY DECLARATION ==============================================================================================================
+/* Libraries are files which contain standard formulas for reading surtain information. Every library contains its own information. */
 #include        "mbed.h"                                                    // Standard library. This includes the reading of AnalogIn, DigitalOut, PwmOut and other standard formules.  
 #include        "QEI.h"                                                     // This library includes the reading of of the Encoders from motors.
 #include        "MODSERIAL.h"                                               // MODSERIAL inherits Serial and adds extensions for buffering.  
@@ -15,7 +14,10 @@
 #include        <cmath>                                                     // This library declares a set of functions to compute common mathematical operations and transformations. Only used fabs. 
 #include        <stdio.h>                                                   // This library defines three variable types, several macros, and various functions for performing input and output.
 
-//*********************************************** FUNCTION DECLARATION *******************************************
+//================================================================================= INPUT, OUTPUT AND FUNCTION DECLARATION =============================================================================================
+/* Here are different inputs, outputs and functions decleared. There are differnt inputs. For the input and the reading of the encoders. 
+The outputs are for the different leds, the magnet and the motor. There is also an function decleared for the MODSERIAL and one for the scope.
+The one for the scope is in this script turned off because only putty is used but it is possible to turn it on. */
 //**************************** INPUTS ******************************************************
 AnalogIn        EMG1(A0);                                                   // Input left biceps EMG.
 AnalogIn        EMG2(A1);                                                   // Input right biceps EMG.
@@ -36,7 +38,11 @@
 //HIDScope        scope(2);                                               // HIDScope declared with 2 scopes.
 MODSERIAL       pc(USBTX, USBRX);                                           // Function for Serial communication with the Microcontroller to the pc.
 
-//*********************************************** GLOBAL VARIABLES DECLARATION ***********************************
+//========================================================================================= GLOBAL VARIABLES DECLARATION =====================================================================================================
+/* For every loop there are different variables and constants needed. All these variables and constants are decleared down here. First the constants and variables for the main program. 
+Second for the control of the motor and than for the different controls and fase switch. At the bottom tickers are defined. 
+Tickers count constantly. Formulas can be attacht to them so they are contantly calculated. */ 
+
 const int       led_on                      = 0;                            // This constant turns the led on. 
 const int       led_off                     = 1;                            // This constant turns the led off. 
 int             games_played1               = 0;                            // Counts number of games played. 
@@ -68,7 +74,7 @@
 double          y1;                                                         // Output from the filters from u1.
 double          u2;                                                         // Input from EMG 2. The right biceps.
 double          y2;                                                         // Output from the filters from u2. 
-
+// Declaring variables for calibration
 double          cali_fact1                  = 0.9;                          // Calibration factor to normalize filter output to a scale of 0 - 1. For signal y1.
 double          cali_fact2                  = 0.9;                          // Calibration factor to normalize filter output to a scale of 0 - 1. For signal y2.
 double          cali_max1                   = 0;                            // Declares max y1.
@@ -130,13 +136,21 @@
 bool            board                       = false;                        //
 
 // **************************************** Tickers ****************************************
-/* Tickers count constantly. The formulas attacht to the ticker count with them. */
 Ticker  Sensor_control;                                                     // This ticker counts for the position of the motors and the speed of the arm.
 Ticker  EMG_Control;                                                        // This ticker counts for the filtering of the EMG signal
 
 //=============================================================================================== SUB LOOPS ==================================================================================================================
-//**************************** CONTROL 1-EMG CALIBRATION ***********************************
-biquadFilter highpass1(high_a2, high_a3, high_b1, high_b2, high_b3);        // Different objects for different inputs, otherwise the v1 and v2 variables get fucked up
+/* Different subloops are used so the head loop doesn't get to full. One loop is used for the filtering and calibration of the EMG signals.
+Then there are two loops which are attached to a ticker so they are read through constantly. 
+One is for the reading of the encoders and one for turning on and off the EMG signal calibration and filtering. */
+
+//**************************** CONTROL 1 - EMG CALIBRATION AND FILTERING ***********************************
+/* There are highpass and lowpass filters used. For both the EMG signals is a highpass and a lowpass filter. The function biquadFilter makes these filters. 
+In the void loop is the filtering done. The u1 and u2 are the reading of the EMG signals. After reading the filters are used. These are the y signals.
+The filter order is highpass, recifyer and lowpass. The calibration is done at the same time as the lowpass filter. 
+The signal is multiplied with the calibarion factor to put the signal between 0 and 1. */
+
+biquadFilter highpass1(high_a2, high_a3, high_b1, high_b2, high_b3);        
 biquadFilter highpass2(high_a2, high_a3, high_b1, high_b2, high_b3);
 biquadFilter lowpass1(low_a2, low_a3, low_b1, low_b2, low_b3);
 biquadFilter lowpass2(low_a2, low_a3, low_b1, low_b2, low_b3);
@@ -146,30 +160,33 @@
     u1 = EMG1;
     u2 = EMG2;
     y1 = highpass1.step(u1);
-    y2 = highpass2.step(u2);                                                // filter order is: high-pass --> rectify --> low-pass
+    y2 = highpass2.step(u2);                                                
     y1 = fabs(y1);
     y2 = fabs(y2);
     y1 = lowpass1.step(y1)*cali_fact1;
-    y2 = lowpass2.step(y2)*cali_fact2;                                      // roughly normalize to a scale of 0 - 1, where 0 is minimum and 1 is roughly the maximum output.
+    y2 = lowpass2.step(y2)*cali_fact2;                                      
 }
 
-//**************************** TICKER LOOPS ************************************************
+//**************************** TICKER LOOPS ****************************************************************
+/* In the SENSOR_LOOP the signal from the encoders are read. This signal is calculated in degrees. This is the pos_arm and the pos_board. 
+For the arm there are also spreeds calculated. These are used to give a speed to the motor later on. Also the flag for the calibration is turned off here. */
 void SENSOR_LOOP()
 {
     Encoderread1 = wheel1.getPulses();
     previous_pos_arm = pos_arm;
-    pos_arm = (Encoderread1/((64.0*131.0)/360.0));                  // Omrekenen naar graden van arm
+    pos_arm = (Encoderread1/((64.0*131.0)/360.0));                  
     pos_arm1 = pos_arm;
     v_arm = (pos_arm - previous_pos_arm)/dt;
 
     Encoderread2 = wheel2.getPulses();
-    pos_board = (Encoderread2/((64.0*131.0)/360.0));                        // Omrekenen naar graden van board
+    pos_board = (Encoderread2/((64.0*131.0)/360.0));                        
     pos_board1 = pos_board;
     
     flag_s = true;
 }
 
-void EMG_LOOP()                                                             // ticker function, set flag to true every sample interval
+/* This loop determines if the calibration can be done or not. */
+void EMG_LOOP()                                                             
 {
     if(flag_calibration == false) 
     {
@@ -178,10 +195,15 @@
 }
 
 //================================================================================================== HEAD LOOP ================================================================================================================
+/* Here is the main loop defined. First 
+Then the tickers are attached to the subloops above. Next some lines to turn led off and some lines that are shown in putty.
+After this a while loop starts. This loop is always on. It starts with the calibration. Then the board returns to its begin settings.
+Then the game can begin in the switch with fase 1, then fase 2 and eventually fase 3. After 5 games the calibration needs to be done again. */
+
 int main()
 {
     pc.baud(115200);
-    Sensor_control.attach(&SENSOR_LOOP, 0.01);                              // TICKER FUNCTION
+    Sensor_control.attach(&SENSOR_LOOP, 0.01);                              
     EMG_Control.attach(&EMG_LOOP, (float)1/Fs);
 
     led_green.write(0);
@@ -197,23 +219,23 @@
     wait(2.5);
     pc.printf("===============================================================\n");
 
-    //************************* CONTROL 1-EMG CALIBRATION ****************************
+//**************************** CONTROL 1 - EMG CALIBRATION AND FILTERING ***********************************
     while(1) 
     {
-        if (flag_calibration)                   // function to calibrate the emg signals from the user. It takes 5 seconds of measurements of maximum output, then takes the max and normalizes to that.
+        if (flag_calibration)                   
         {            
             calibration_measurements ++;
             pc.printf(" \n\n EMG Signal starting up Calibration measurement........... \n");
             
-            cali_max1 = 0;                                   // declare max y1
-            cali_max2 = 0;                                   //declare max y2
-            cali_fact1 = 0.9;                                          // calibration factor to normalize filter output to a scale of 0 - 1
+            cali_max1 = 0;                                                          
+            cali_max2 = 0;                                                          
+            cali_fact1 = 0.9;                                                       
             cali_fact2 = 0.9;
             
             wait(2);
             led_red.write(0);
             wait(0.2);
-            led_red.write(1);                                      //Toggles red calibration LED on
+            led_red.write(1);                                     
             wait(0.2);
             led_red.write(0);
             wait(0.2);
@@ -231,35 +253,34 @@
             wait(0.5);
             pc.printf("\t......contract muscles..... \n");
 
-            for(int cali_index1 = 0; cali_index1 < 2560; cali_index1++) // Records 5 seconds of y1
+            for(int cali_index1 = 0; cali_index1 < 2560; cali_index1++)                     // Records 5 seconds of y1.
             {
                 hoog_laag_filter();
                 cali_array1[cali_index1] = y1;
                 wait((float)1/Fs);
             }
-            for(int cali_index2 = 0; cali_index2 < 2560; cali_index2++)  // Records 5 seconds of y2
+            for(int cali_index2 = 0; cali_index2 < 2560; cali_index2++)                     // Records 5 seconds of y2.
             {    
                 hoog_laag_filter();
                 cali_array2[cali_index2] = y2;
                 wait((float)1/Fs);
             }
-            for(int cali_index3 = 0; cali_index3 < 2560; cali_index3++)  // Scales y1
+            for(int cali_index3 = 0; cali_index3 < 2560; cali_index3++)                     // Scales y1.
             {    
                 if(cali_array1[cali_index3] > cali_max1) 
                 {
                     cali_max1 = cali_array1[cali_index3];
                 }
             }
-            for(int cali_index4 = 0; cali_index4 < 2560; cali_index4++)  // Scales y2
+            for(int cali_index4 = 0; cali_index4 < 2560; cali_index4++)                     // Scales y2.
             {    
                 if(cali_array2[cali_index4] > cali_max2) {
                     cali_max2 = cali_array2[cali_index4];
                 }
             }
-            cali_fact1 = (double)1/cali_max1;                              // Calibration factor for y1
-            cali_fact2 = (double)1/cali_max2;                              // Calibration factor for y2
+            cali_fact1 = (double)1/cali_max1;                                               // Calibration factor for y1.
+            cali_fact2 = (double)1/cali_max2;                                               // Calibration factor for y2.
 
-            // Toggles green sampling LED off
             led_yellow.write(0);
             pc.printf(" \t....... Calibration has been completed!\n");
             wait(0.2);
@@ -277,42 +298,41 @@
             y1 = 0;
             y2 = 0;
 
-            j = 1;                                         // Wachten van fase switch initialiseren
+            j = 1;                                                                          // Wait for the fase swith to initiate. 
             fase_switch_wait = true;
             flag_calibration = false;
         }
 
-
-        //************************* CONTROL MOTOR ****************************************
-        if (flag_s) 
+        if (flag_s)                                                                         // Turns calibration off. 
         {
             flag_calibration = false;
         }
-        //************************* FASE SWITCH ******************************************
-        //******************** Fase determination *************
-        if (fase_switch_wait) 
+//**************************** FASE SWITCH *****************************************************************
+
+        if (fase_switch_wait)                                                               // There needs to be a wait before the script can start so the sample loop has the time to do the calibration.
         {
             j++;
-            wait(0.01);                                              // Problemen met EMG metingen die te hoog zijn op het begin van script na calibratie. vandaar ff wachten en de sample loop een paar keer doorlopen.
+            wait(0.01);                                              
             pc.printf("waarde j = %i \n",j);
             led_red.write(0);
             led_green.write(1);
             led_yellow.write(0);
         }
 
-        if( j > N) 
+        if( j > N)                                                                          // When the wait is long enough the game starts. 
         {
             fase_switch_wait = false;
             switch(fase) 
             {
-                    //******************* Fase 1 **************************
+    //************************ Fase 1 ******************************************************************
                 case(1):
                     led_red.write(1);
                     led_green.write(0);
                     led_yellow.write(0);
                     rounds = 0;
-                    if (y1> contract) 
-                    {
+                    
+                    if (y1> contract)                                                       // If the left arm is above this value flag_left turns true so the motor can run ccw.
+                    {                                                                       // The  left and right can not be true at the same time so right has to turn off when left is on.
                         flag_right = false;
                         flag_left = true;
                     }
@@ -372,7 +392,8 @@
                         j = 0;
                     }
                     break;
-                    //******************* Fase 2 **************************
+    //************************ Fase 2 ******************************************************************
+        
                 case(2):
                     led_red.write(0);
                     led_green.write(0);
@@ -485,7 +506,7 @@
                     }
                     pc.printf("Snelheid arm = \t %f \t EMG1 en EMG2 = %f \t %f \n", speed_control_arm, y1, y2);
                     break;
-                    //********************************************* Fase 3 **********************************************
+    //************************ Fase 3 ******************************************************************
                 case(3):
                     led_red.write(0);
                     led_green.write(1);
@@ -586,7 +607,7 @@
                             break;
                     }
                     break;
-                    //=================================================== STOP SCRIPT ============================================================
+//================================================================================================== END SCRIPT ===============================================================================================================
             }
         }
     }