Code for the COVR project DROPSAW project test rig (previously used for the Heros testing).

Dependencies:   SPTE_10Bar_5V mbed AS5048 SDFileSystem MODSERIAL LCM101_DROPSAW LinearActuator

Files at this revision

API Documentation at this revision

Comitter:
cnckiwi31
Date:
Mon Oct 26 11:55:27 2020 +0000
Parent:
14:dd4193213be9
Commit message:
Code ready for inclusion in documentation (compiles, but no last check on runBenchmarkExperiment1() code done)

Changed in this revision

AS5048.lib Show annotated file Show diff for this revision Revisions of this file
LCM101.lib Show annotated file Show diff for this revision Revisions of this file
bench.cpp Show annotated file Show diff for this revision Revisions of this file
bench.h Show annotated file Show diff for this revision Revisions of this file
constants.cpp Show annotated file Show diff for this revision Revisions of this file
constants.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r dd4193213be9 -r a84d54e25775 AS5048.lib
--- a/AS5048.lib	Mon Oct 26 08:33:02 2020 +0000
+++ b/AS5048.lib	Mon Oct 26 11:55:27 2020 +0000
@@ -1,1 +1,1 @@
-https://developer.mbed.org/users/megrootens/code/AS5048/#1b84babf3042
+https://os.mbed.com/users/cnckiwi31/code/AS5048/#1b84babf3042
diff -r dd4193213be9 -r a84d54e25775 LCM101.lib
--- a/LCM101.lib	Mon Oct 26 08:33:02 2020 +0000
+++ b/LCM101.lib	Mon Oct 26 11:55:27 2020 +0000
@@ -1,1 +1,1 @@
-https://os.mbed.com/users/cnckiwi31/code/LCM101/#f7af875abe50
+https://os.mbed.com/users/cnckiwi31/code/LCM101_DROPSAW/#f7af875abe50
diff -r dd4193213be9 -r a84d54e25775 bench.cpp
--- a/bench.cpp	Mon Oct 26 08:33:02 2020 +0000
+++ b/bench.cpp	Mon Oct 26 11:55:27 2020 +0000
@@ -1,6 +1,21 @@
+/*  Copyright 2020 Allan Joshua Veale
+ 
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+ 
+        http://www.apache.org/licenses/LICENSE-2.0
+ 
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+*/
+
 #include "bench.h"
 
-/**
+/** constructor
  * Create an object representing the test rig
  * @param mosi: mosi pin for sensor chain (SPI angle sensors)
  * @param miso: miso pin for sensor chain (SPI angle sensors)
@@ -38,16 +53,16 @@
     //init serial things
     pc.baud(timing::kSerialBaudrate);//set the serial rate
     
-    sd_card_present = false;
-    fname_prepend = 0;
-    is_logging = false;
-    is_printing = false;
-    was_printing = false;
+    sd_card_present = false;//have not checked for an sd card
+    fname_prepend = 0;//have not checked what is on the sd card
+    is_logging = false;//not datalogging
+    is_printing = false;//not printing anything
+    was_printing = false;//was not printing
         
-    usedExtraCols = 0;
+    usedExtraCols = 0;//default
     
     firstReadMS = 0; //first timer value read
-    startedLogging = false; //in the middle of a logging cycle
+    startedLogging = false; //not in the middle of a logging cycle
     
     keyIntOffset = timing::minKeyInt;//any right keypress is ok at the start
     k = '\0'; //keyboard value starts off as a null value
@@ -56,6 +71,7 @@
     loggingUS = timing::kTimeLogDataUs;    
     loggingHz = (int)(1000000/timing::kTimeLogDataUs); 
     
+    //set all angle sensor calibration data
     for (int i=0; i<sensors::kNumJoints; ++i) {
         as5048_.setOffsetDegrees(i,sensors::kOffsetsDegrees[i]);
         as5048_.setDirection(i,sensors::kDirections[i]);
@@ -69,7 +85,7 @@
  */
 void Bench::initialise()
 {
-    //setup the timing
+    //setup the timing for the control loop (which only reads the angle sensors)
     tick_update.attach_us(this,&Bench::update,timing::kTimeControlUs);
             
     // set rate at which data is printed
@@ -80,7 +96,7 @@
     
     //display welcome message
     pc.printf("\r\n**Hello!**\r\n");
-    pc.printf("Version: 3/12/2019 - 00:00\r\n\n");
+    pc.printf("Version: V4\r\n\n");
     
     Bench::pc.printf("5kN load cell? %s\r\n\n",sensors::use5kN?"Yes":"No");
     
@@ -95,7 +111,7 @@
 }
 
 /**
- * Sets the rate at which data is logged in an experiment
+ * Sets the rate at which data is logged in an experiment - when automatic datalogging is used
  * @param hertz: logging frequency in Hz
  */
 void Bench::setLoggingFrequency(float hertz)
@@ -104,26 +120,25 @@
     if (hertz > 0) {
         loggingUS = 1000000/hertz;
         loggingHz = hertz;
-    } else {
+    } else { //default if bad value supplied
         loggingUS = timing::kTimeLogDataUs;
         loggingHz = (int)(1000000/timing::kTimeLogDataUs);
     }
 }
 
 /**
- * Sets names of extra columns of data to be recorded
+ * Sets names of extra columns of data to be recorded (those more than maxCols are 
+ * ignored)
  * @param extraColumnNames: string array of the column names
  * @param numCols: number of elements in the string array
  */
 void Bench::setExtraColumns(string extraColumnNames[], int numCols)
 {
     usedExtraCols = numCols;
-    //pc.printf("Length: %i\r\n",usedExtraCols);
     // save the names   
     for(int i=0; i<maxCols; i++) {
         if (i<numCols) {
             extraColNames[i] = extraColumnNames[i];
-            //pc.printf("\r\nS%d: %s\r\n",i,extraColNames[i]);
         } else {
             extraColNames[i] = ""; //less columns than the max possible are filled with a null space
         }
@@ -139,9 +154,7 @@
 {
     for (int i=0; i<usedExtraCols; i++) {
         extraColValues[i] = data[i];
-        //pc.printf("\r\nD%d: %f\r\n",i,extraColValues[i]);
-    }
-    
+    }    
 }
 
 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
@@ -151,7 +164,6 @@
 /**
  * Update routine for the test rig
  * - Updates the angle buffer of the sensor array
- * - ... that's it for now (add filtering?)
  * Note that angles lag one update() behind, due to the way the SPI
  * protocol works.
  */
@@ -163,18 +175,6 @@
 /**
  * Obtain the joint angle in degrees
  * These are the angles at the time of two Update() calls back
- * @param joint: the joint for which the angle is requested (as enumerated in 
- * class header - TOES, KNEE, ANKLE, HIP
- * @return: joint angle
- */
-float Bench::getDegrees(Joint joint) 
-{
-    return getDegrees(joint);
-}
-
-/**
- * Obtain the joint angle in degrees
- * These are the angles at the time of two Update() calls back
  * @param joint: the joint for which the angle is requested (a number starting 
  * from 0 indicating the position in the sensor daisy chain)
  * @return: joint angle
@@ -189,44 +189,18 @@
 }
 
 /**
- * Obtain the joint angle in radians
- * These are the angles at the time of two Update() calls back
- * @param joint: the joint for which the angle is requested (as enumerated in 
- * class header - TOES, KNEE, ANKLE, HIP
- * @return: joint angle
- */
-float Bench::getRadians(Joint joint) 
-{
-    return getRadians(joint);
-}
-
-/**
- * Obtain the joint angle in radians
- * These are the angles at the time of two Update() calls back
  * @param joint: the joint for which the angle is requested (a number starting 
  * from 0 indicating the position in the sensor daisy chain)
- * @return: joint angle
+ * @return the name of the joint number
  */
-float Bench::getRadians(int i_joint) 
-{
-    float ang = as5048_.getAngleRadians(i_joint);
-    if (ang>kCutOffRadians) {
-        return ang-As5048::kRadPerRev;
-    }
-    return ang;
-}
-
-
 const char* Bench::getJointName(int i_joint) 
 {
     return sensors::kJointNames[i_joint];
 }
 
-const char* Bench::getJointName(Joint joint) 
-{
-    return getJointName(joint);
-}
-
+/**
+ * @return the encoder object reference
+ */
 As5048* Bench::get_as5048() 
 {
     return &as5048_;
@@ -246,6 +220,9 @@
     
 }
 
+/**
+ * zero the force reading (like a tare function)
+ */
 void Bench::nullForce()
 {
     if (use5kN) {
@@ -264,16 +241,26 @@
     return spte0.getPressure();
 }
 
+/**
+ * zero the pressure reading (like a tare function)
+ */
 void Bench::nullPressure0()
 {
     return spte0.nullPressure();
 }
 
+/**
+ * The pressure measured by pressure sensor 0 in bar
+ * @return: pressure
+ */
 float Bench::getPressure1() 
 {
     return spte1.getPressure();
 }
 
+/**
+ * zero the pressure reading (like a tare function)
+ */
 void Bench::nullPressure1()
 {
     return spte1.nullPressure();
@@ -323,6 +310,7 @@
 {
     LinAct.setPWM(pwm);
 }
+
 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 // IMPLEMENTATION DATA LOGGING
 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
@@ -342,9 +330,10 @@
     struct dirent *p;
 
     d = opendir("/sd");
-    if (d != NULL) {
+    if (d != NULL) {//if there is an SD card
         sd_card_present = true;
-
+        
+        //print existing files
         pc.printf("\t> Contents of SD Card:\r\n");
         while ((p = readdir(d)) != NULL) {
             if (p->d_name[0] != '.') {
@@ -367,7 +356,9 @@
 }
 
 /**
- * Start logging data
+ * Start logging data (now manual, meaning user has to call a method to record a datapoint
+ * but if tick_logging.attach...(...) is uncommmented
+ * then recording becomes automatic)
  * param fname_append: a string describing the name appended to each logged file
  * (along with its unique loggging number).
  */
@@ -375,7 +366,6 @@
 {    
     pc.printf("\r\nDATA LOGGING");
     if (sd_card_present) {
-
         // create unique file name
         ++fname_prepend;
         char fname[50];
@@ -386,24 +376,19 @@
         // open file for writing and start logging after success
         fp_data = fopen(fname,"w");
         if (fp_data==NULL) {
-            pc.printf("\t> ERROR: failed to open log file (t=%d ms)\r\n",
-                      timer.read_ms());
+            pc.printf("\t> ERROR: failed to open log file (t=%d ms)\r\n",timer.read_ms());
         } else {
-            string fHeader = "time (s),theta_knee (deg),force (N),pressure (kPa)";
+            string fHeader = "time (s),theta_knee (deg),force (N),pressure (kPa)";//default data points recorded
             
             for (int i=0; i<usedExtraCols; i++) {
                 if (extraColNames[i] != "") {
                     fHeader = fHeader + "," + extraColNames[i];
                 }
             }
-            //pc.printf("%s", fHeader.c_str());
             fprintf(fp_data, "%s", fHeader.c_str());
-            //tick_logging.attach_us(this,&Bench::LogData,loggingUS);
-            timer.start();
-            startedLogging = true;
-            
-            //pc.printf("\t> Logging started.\r\n");
-            
+            //tick_logging.attach_us(this,&Bench::LogData,loggingUS); - uncomment to automatically log data
+            timer.start();//enable a time stamp for the logging file
+            startedLogging = true;            
             is_logging = true;
         }
     } else {
@@ -430,8 +415,7 @@
         // open file for writing and start logging after success
         fp_data = fopen(fname,"w");
         if (fp_data==NULL) {
-            pc.printf("\t> ERROR: failed to open log file (t=%d ms)\r\n",
-                      timer.read_ms());
+            pc.printf("\t> ERROR: failed to open log file (t=%d ms)\r\n",timer.read_ms());
         } else {            
             timer.start();
             startedLogging = true;
@@ -447,13 +431,13 @@
 }
 
 /**
- * Stop logging data.
+ * Stop automatically logging data.
  */
 void Bench::StopLogging()
 {
     Bench::pc.printf("\r\nDATA LOGGING:");
     if (sd_card_present) {
-        // close data file, stop logging
+        // close data file, stop logging, reset time stamp
         fclose(fp_data);
         tick_logging.detach();
         timer.stop();
@@ -461,8 +445,7 @@
         Bench::pc.printf("\r> Stopped.");
     } else {
         Bench::pc.printf("\t> No data was logged.");
-    }
-    
+    }    
     is_logging = false;
 }
 
@@ -479,26 +462,27 @@
 }
 
 /**
- * Log data
+ * Log data (record all the data points, default and custom with a timestamp)
  */
 void Bench::LogData()
 {
     int currTime = timer.read_ms();
-    if(startedLogging) {
+    if(startedLogging) {//the first time this is called, save the timer offset
         firstReadMS = currTime;
         startedLogging = false;
     }
-    double currTimeS = ((double)currTime - firstReadMS)/1000;
+    double currTimeS = ((double)currTime - firstReadMS)/1000;//time stamp
     
     // time
     fprintf(fp_data,"\n%f",currTimeS);
 
-    // bench: joint angles and force sensor and pressure sensor values
+    // bench default datapoints: joint angles and force sensor and pressure sensor values
     fprintf(fp_data,",%f,%f,%f",
             getDegrees(0),
             getForce(),            
             getPressure0()*100
            );
+    //custom datapoints
     for (int i=0; i<usedExtraCols; i++) {
         fprintf(fp_data,",%f",extraColValues[i]);
     }            
@@ -515,19 +499,20 @@
     if (is_printing) {
         if(sd_card_present)
         {
+            //file name and whether logging is happening
             Bench::pc.printf("\tFile number %15i\r\n", fname_prepend);
             Bench::pc.printf("\tLogging? %18s\r\n",is_logging?"Yes":"No");
         }
         
+        //angles printed
         for (int i=0; i<sensors::kNumJoints; ++i)
         {
             string jointName = sensors::kJointNames[i];
             jointName = jointName + " (deg)";
             Bench::pc.printf("\t%15s %7.2f\r\n",jointName, getDegrees(i));
         }
-        Bench::pc.printf("\t%15s %7.2f\r\n","Force (N)",  getForce()); 
-        
-        Bench::pc.printf("\t%15s %7.2f\r\n","Pressure0 (kPa)",  getPressure0()*100);   
+        Bench::pc.printf("\t%15s %7.2f\r\n","Force (N)",  getForce()); //force reading        
+        Bench::pc.printf("\t%15s %7.2f\r\n","Pressure0 (kPa)",  getPressure0()*100); //pressure reading 
     }
 }
 
@@ -570,25 +555,24 @@
 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 
 /**
- * d toggles printing state of sensors and l toggles logging of data
+ * s toggles printing state of sensors and l toggles logging of data
  * use the keyboard on the pc
- * do not press longer than a second or it will toggle back
+ * do not press longer than a minKeyInt or it will toggle back
  */
 void Bench::ToggleState(MODSERIAL_IRQ_INFO *q)
 {
     //if we have data and it was not too soon since the last data
     if(Bench::pc.readable() && (((Bench::keyIntT.read() + keyIntOffset) >= timing::minKeyInt))) {
-    k = Bench::pc.getc();//read the keystroke
-        Bench::pc.rxBufferFlush();
-        //toggle status of logging
+        k = Bench::pc.getc();//read the keystroke
+        Bench::pc.rxBufferFlush();//delete all recorded keystrokes
+        
         if(k == 's') {//toggle printing of data
             Bench::pc.printf("\tInput: %c\r\n",k);
             TogglePrinting();
             keyIntT.reset();
             keyIntT.start();
             keyIntOffset = 0;
-
-        } else if (k == 'l') {
+        } else if (k == 'l') {//toggle status of logging
             Bench::pc.printf("\tInput: %c\r\n",k);
             ToggleLogging();
             keyIntT.reset();
@@ -608,7 +592,7 @@
         is_printing = true;
     } else {
         is_printing = false;
-        PrintMenu();
+        PrintMenu();//data no longer printed, print home menu
     }
     was_printing = is_printing;
 }
@@ -623,7 +607,6 @@
     } else {
         is_logging = false;
     }        
-    //PrintMenu();
 }
 
 /**
diff -r dd4193213be9 -r a84d54e25775 bench.h
--- a/bench.h	Mon Oct 26 08:33:02 2020 +0000
+++ b/bench.h	Mon Oct 26 11:55:27 2020 +0000
@@ -1,3 +1,18 @@
+/*  Copyright 2020 Allan Joshua Veale
+ 
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+ 
+        http://www.apache.org/licenses/LICENSE-2.0
+ 
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+*/
+
 #ifndef _BENCH02_H_
 #define _BENCH02_H_
 #include "MODSERIAL.h"
@@ -15,30 +30,21 @@
 #include "LinearActuator.h"
 
 /**
- * Class to read out sensory information from the second test bench:
+ * Class to read out sensory information from the test rig:
  * the knee joint angle as measured by an AMS AS5048 absolute rotary sensor
  * the vertical force applied externally at the hip joint
  * the pressure (for example of an actuator used in the device under test).
- * Additionally, an on /off valve can pressurise the actuator on the leg
+ * Additionally, an on /off valve can pressurise the actuator on the leg and a linear
+ * actuator can be used to raise and lower the test leg
  */
 class Bench {
 public:
     
-    static const float kCutOffDegrees = 180.0f;
+    //angle is only allowed to be< this value 
+    static const float kCutOffDegrees = 180.0f; 
     static const float kCutOffRadians = 3.14159265359f;
-    
-    enum Joint {
-        TOES,
-        ANKLE,
-        KNEE,
-        HIP
-    };
-    
-    enum DACChannel {
-        A,
-        B
-    };
-    
+   
+   
     // constructor
     Bench(PinName mosi = AS5048_MOSI, PinName miso = AS5048_MISO, PinName sck = AS5048_SCLK, PinName cs = AS5048_CS, 
         bool use5kN = sensors::use5kN,PinName p_lcm101 = LCM101, 
@@ -50,59 +56,50 @@
     //setup
     void initialise();
     
-    void setLoggingFrequency(float logHertz);
-    void setExtraColumns(string extraColumnNames[], int numCols);
-    void setExtraData(float data[]);
-    void update(); 
+    void setLoggingFrequency(float logHertz); //set datalogging frequency (for when automatic data logging is used - not in this code)
+    void setExtraColumns(string extraColumnNames[], int numCols);//manually add extra columns of data so user can have custom data recorded
+    void setExtraData(float data[]);//manually add extra datapoints
+    void update(); //read angle data afresh
 
     bool isLogging();//indicates if we are now datalogging
-    void stopLogging();//halts the data logging if we are now datalogging
-    void StopLogging(); //halts the data logging if we are now datalogging
-    void StartLogging(const char * fname_append = "data"); //starts datalogging
+    void stopLogging();//halts the manual data logging if we are now datalogging
+    void StopLogging(); //halts the automatic data logging if we are now datalogging
+    void StartLogging(const char * fname_append = "data"); //starts datalogging (now manual)
     void RestartLogging(const char * fname_append = "data");//restart datalogging
-    void LogData();
+    void LogData(); //records the predetermined datapoints (and those in extracolumns)
     
-    //reading angle sensors
+    //for reading angle sensors
     As5048* get_as5048();
     
-    float getDegrees(int i_joint);
-    float getDegrees(Joint joint);
-
-    float getRadians(int i_joint);
-    float getRadians(Joint joint);
+    float getDegrees(int i_joint); //read angle
+    const char* getJointName(int i_joint);//return joint name
 
-    const char* getJointName(int i_joint);
-    const char* getJointName(Joint joint);
-
-    //reading and calibrating force and pressure sensors
-    float getForce();
-    void nullForce();
+    //for reading and calibrating force and pressure sensors
+    float getForce();//read force
+    void nullForce();//tare reading
     
-    float getPressure0();
-    void nullPressure0();
-    float getPressure1();
-    void nullPressure1();
+    float getPressure0();//read pressure
+    void nullPressure0();//tare reading
+    float getPressure1();//read pressure
+    void nullPressure1();//tare reading
     
-    //MAX5322 DACs (two channels per DAC)
-    void setDACA(DACChannel ch, unsigned int bitValue);
-    void setDACB(DACChannel ch, unsigned int bitValue);
     
-    //controlling valve
-    bool getValve();
-    void setValve(bool pressurise); 
+    //for controlling valve
+    bool getValve();//return valve state
+    void setValve(bool pressurise); //turn valve on/off
     
     // controlling linear actuator
-    void setDir(bool dir);
-    bool getDir();
-    void setPWM(int pwm);    
+    void setDir(bool dir);//set actuator direction
+    bool getDir();//return actuator direction
+    void setPWM(int pwm);  //actuator speed  
     
     /** Object for printing/receiving data to the PC the test rig is connected 
     * to. Note that it uses the MODSERIAL.h class.
     */
     MODSERIAL pc;
     
-    void pausePrint();
-    void resumePrint();
+    void pausePrint();//stops automatic printing of data
+    void resumePrint();//resumes automatic printing of data
     
 private:
     //timing
@@ -118,8 +115,8 @@
     
     bool is_logging;
     bool is_printing;
-    bool was_printing; //if printing is paused true if is_printing was true
-    char k; //value from keyboard
+    bool was_printing; //if printing is paused true, or if is_printing was true
+    char k; //value from keyboard press
             
     //joint angle 
     As5048 as5048_;
@@ -144,22 +141,23 @@
     FILE * fp_data;
     int fname_prepend;//file number
     bool sd_card_present;//card detected    
-       
+    void InitSdCard(); //setup the SD card
+    
+    // recording extra data   
     static const int maxCols = 5;
     int usedExtraCols; //number of extra columns useds
     string extraColNames[maxCols];//names of extra columns (up to maxCols allowed with 15 characters)  
     float extraColValues[maxCols];//value held in extra columns for current time step
-       
-    void InitSdCard();      
+                
 
     //for toggling logging or printing
-    void ToggleState(MODSERIAL_IRQ_INFO *q);
+    void ToggleState(MODSERIAL_IRQ_INFO *q);//method for parsing keyboard presses
 
-    void ToggleLogging();
+    void ToggleLogging();//change state of logging (between on and off)
     
     // serial printing
-    void TogglePrinting();
-    void PrintStatus();
-    void PrintMenu();  
+    void TogglePrinting(); //change state of printing (between on and off)
+    void PrintStatus();//print the read out from the test rig sensors
+    void PrintMenu();  //print the standard menu showing which keys control what in the test rig
 };
 #endif
\ No newline at end of file
diff -r dd4193213be9 -r a84d54e25775 constants.cpp
--- a/constants.cpp	Mon Oct 26 08:33:02 2020 +0000
+++ b/constants.cpp	Mon Oct 26 11:55:27 2020 +0000
@@ -1,9 +1,30 @@
+/*  Copyright 2020 Allan Joshua Veale
+ 
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+ 
+        http://www.apache.org/licenses/LICENSE-2.0
+ 
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+*/
+
 #include "constants.h"
 
+/** Default values for constants
+ */
+
 namespace sensors {
     const bool use5kN = false;
     
     // LCM101-100kgf force sensor
+    const float kLcm101Offset = -1.5;
+    const float kLcm101Factor = 970.55;
+    
     // Equation from 7/6/2018 calibration used:
     // kLcm101Offset = 1.99
     // kLcm101Factor = 969.2
@@ -11,57 +32,51 @@
     // kLcm101Offset = 4.31
     // kLcm101Factor = 1001.1
     
-    const float kLcm101Offset = -1.5;//-1.52;
-    //This is currently the offset for the S610 sensor -5.41;
-    //Offset for LCM101 sensor = -1.52
-    const float kLcm101Factor = 970.55;//970.55;
-    //This is currently the factor for the S610 sensor 977.35;
-    //Factor for LCM101 sensor is 970.55
     
     // Gen5kN force sensor
+    const float kGen5kNOffset = 0;
+    const float kGen5kNFactor = 5530; 
+    
     // Equation from 21/2/2019 calibration used:
     // kLcm101Offset = 21.2
     // kLcm101Factor = 5530
-    
-    const float kGen5kNOffset = 0;
-    const float kGen5kNFactor = 5530;    
+      
     
     // Pressure sensor slope and offset values for a gauge pressure reading in bar
     // Equation from 25/6/2018 calibration used:
-    // kSPTE0Offset = -2.47
-    // kSPTE0Factor = 12.5
+    const float kSPTE0Offset = -2.33;    
+    const float kSPTE0Factor = 12.0;
+        
+    const float kSPTE1Offset = -2.47;    
+    const float kSPTE1Factor = 12.5;   
     
     // Equation from 21/2/2019 calibration used
     // kSPTE0Offset = -2.33
     // kSPTE0Factor = 12.0
-    
-    const float kSPTE0Offset = -2.33;
-    
-    const float kSPTE0Factor = 12.0;
         
-    const float kSPTE1Offset = -2.47;
-    
-    const float kSPTE1Factor = 12.5; //   
         
     // AS5048 abs angle sensor chain
-    const int kNumJoints = 1;
+    const int kNumJoints = 1;// if hard leg used again - use 4
 
-    const char *kJointNames[]     = {"Knee"};//{"1","Knee","3","4"};
-    const float kOffsetsDegrees[] = {250};//{180,180,180,180};
-    const bool kDirections[] = {true};//{true,true,true,true};
+    const char *kJointNames[]     = {"Knee"};// if hard leg used again - use {"Toes","Ankle","Knee","Hip"}
+    const float kOffsetsDegrees[] = {250};// if hard leg used again - use {83.2f,6.3f,170.7f,6.5f}
+    const bool kDirections[] = {true};// if hard leg used again - use {false,true,false,true}
 }
 
 namespace timing {
     const int TimeControlHertz = 1000;// control loop sample rate
     const int LogDataHertz = 249; //data log sample rate
-    const int SerialPrintHertz = 2; //print rate of serial 
+    const int SerialPrintHertz = 2; //print rate of serial
+    
+    //corresponding values as a period
     const int kTimeControlUs            =   1000000/TimeControlHertz;   // 1000 Hz control loop
     const int kTimeLogDataUs            =  1000000/LogDataHertz;   //   200 Hz data logging
     const int kTimeSerialPrintUs        = 1000000/SerialPrintHertz;   //    2 Hz serial print
-    const int minKeyInt                   = 1;                  //minimum key press interval in s
-    const int kSerialBaudrate = 115200;
     
-    const int PWMHertz = 10000;
+    const int minKeyInt                   = 1;                  //minimum key press interval in s. if key is pressed more than once in this time interval it will just register as one press
+    const int kSerialBaudrate = 115200; //serial data rate
+    
+    const int PWMHertz = 10000;//linear actuator PWM frequency
 }
 
 namespace rigStructure {
diff -r dd4193213be9 -r a84d54e25775 constants.h
--- a/constants.h	Mon Oct 26 08:33:02 2020 +0000
+++ b/constants.h	Mon Oct 26 11:55:27 2020 +0000
@@ -1,3 +1,18 @@
+/*  Copyright 2020 Allan Joshua Veale
+ 
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+ 
+        http://www.apache.org/licenses/LICENSE-2.0
+ 
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+*/
+
 #ifndef _CONSTANTS_HARDWARE_H_
 #define _CONSTANTS_HARDWARE_H_
 
@@ -7,6 +22,10 @@
 #define M_PI 3.14159265359f
 #endif
 
+/**
+ * Hardware connections to the mbed
+ */
+
 // SPI Communication AS5048 joint encoders
 #define AS5048_MOSI         PTD6        // D11
 #define AS5048_MISO         PTD7        // D12
@@ -30,8 +49,8 @@
 #define LCM101              A1
 
 // SPTE analog output pressure sensors (0-10bar for 0-5V output)
-#define SPTE_0             A0
-#define SPTE_1             A5
+#define SPTE_0             A0 //this is the one currently in use
+#define SPTE_1             A5 //this one is not used, and its use on this pin needs to be tested - hence not in schematics
 
 //Festo digital valve (one for inflate)
 #define VALVE_PIN           D0
@@ -75,9 +94,9 @@
     extern const int kTimeLogDataUs;                    // data logging
     extern const int TimeControlHertz;                  // control loop sample rate
     extern const int kTimeSerialPrintUs;                // serial printing 
-    extern const int minKeyInt;                   //key interval time out value
+    extern const int minKeyInt;                         //key interval time out value
     
-    extern const int kSerialBaudrate;
+    extern const int kSerialBaudrate;                   //frequency of serial port
     
     extern const int PWMHertz;                          //Linear actuator frequency for pwm
 }
diff -r dd4193213be9 -r a84d54e25775 main.cpp
--- a/main.cpp	Mon Oct 26 08:33:02 2020 +0000
+++ b/main.cpp	Mon Oct 26 11:55:27 2020 +0000
@@ -28,9 +28,9 @@
 #include "bench.h"
  
 //Methods describing the tests
-void runFatigueExperiment0(int cycles, float targetkPa, float inflateTimeOut,float deflateTimeOut);
-void runFailureExperiment0(float targetkPa);
-void runBenchmarkExperiment0();
+void runFatigueExperiment0(int cycles, float targetkPa, float inflateTimeOut,float deflateTimeOut,int logHz);
+void runFailureExperiment0(float targetkPa,int logHz);
+void runBenchmarkExperiment0(int logHz);
 void runBenchmarkExperiment1(int minForce, float maxAngle, float inflationT, int pwm, int cycles, int logHz);
 
 // Create bench object - this is used to control the test rig
@@ -40,17 +40,27 @@
  * Main loop
  */
 int main()
-{   
-    leg.setLoggingFrequency(10); //Set datalogging frequency (Hz)
-    
+{       
     /* Two extra columns of data will be recorded in this experiment.
     One for the target pressure, and the other for the number of inflation-deflation
     cycles currently completed in the experiment */ 
-    string colNames[] = {"Target pressure (kPa)","Cycle",}; //add data headings
+    string colNames[] = {"Target pressure (kPa)","Cycle"}; //add data headings
     leg.setExtraColumns(colNames,2);
     
-    float targetP = 300; //Pressure at which inflation is stopped and deflation begins (kPa)                                                                                                                                                                                       
-    int expCycles = 40; //Number of inflation cycles 
+    int logHz = 10; //(Hz) datalogging frequency
+    float targetP = 300; //Pressure at which inflation is stopped and deflation begins (kPa)  
+                                                                                                                                                                                         
+    int fatCycles = 40; //Number of inflation cycles for the fatigue test    
+    float infTimeAllow = 10;// (s) time allowed for inflation in a fatigue cycle
+    float defTimeAllow = 10;// (s) time allowed for deflation in a fatigue cycle
+    
+    //for benchmark experiment
+    float minForce = 5;//(N) force threshold at which leg extension changes to flexion
+    float maxAngle = 70;//(deg) angle threshold at which leg flexion changes to extension
+    float inflationTime = 3;//(s) time actuator given to inflate before starting experiment
+    int pwm = 75; //(%) linear actuator motor pwm
+    int benchCycles = 1;//(-) number of flexion/extension cycles
+    
     float vals[] = {targetP,0}; //set of initial values of data that will be logged
     leg.setExtraData(vals);
     
@@ -62,14 +72,16 @@
     stop it if the button is pressed again to stop datalogging 
     (or when experiment stops - then datalogging stops by itself) */
     while (true) {
-        if (leg.isLogging()) {
-            leg.pc.printf("Logging started");
-            runFatigueExperiment0(expCycles,targetP,10,10);
-            //runBenchmarkExperiment0();
-            runBenchmarkExperiment1(5, 70, 3, 75, 1, 10);
-            //runFailureExperiment0(targetP);        
+        if (leg.isLogging()) {//check if logging has started, if so, run an experiment procedure
+            leg.pc.printf("Logging started");//user feedback
+            
+            //uncomment the type of experiment you want to try
+            runFatigueExperiment0(fatCycles,targetP,infTimeAllow,defTimeAllow,logHz);
+            //runBenchmarkExperiment0(logHz);
+            //runBenchmarkExperiment1(minForce, maxAngle, inflationTime, pwm, benchCycles, logHz);
+            //runFailureExperiment0(targetP,logHz);        
         }
-        wait(0.5);
+        wait(0.5);//wait a bit before checking again
     }
 }
 
@@ -81,13 +93,19 @@
  * @param targetkPa: the pressure at which the valve is opened to let the leg go down (kPa)
  * @param inflateTimeOut: (s) if inflation takes longer than this, experiment is assumed to fail and stops, saving data
  * @param deflateTimeOut: (s) if deflation takes longer than this, experiment is assumed to fail and stops, saving data
+ * @param logHz: datalogging frequency
  */
-void runFatigueExperiment0(int cycles, float targetkPa, float inflateTimeOut, float deflateTimeOut) 
+void runFatigueExperiment0(int cycles, float targetkPa, float inflateTimeOut, float deflateTimeOut,int logHz) 
 {
     //method constants
     Timer flowT;//timer used to time flow into and out of actuator
-    float loopTime = 0.1; //(s) time between checking pressure
-    int num_file = 1; //number of data files to save 
+        
+    float loopTime = 1/logHz; //(s) time between checking pressure
+    
+    //number of data files to save (so we can create a safety barrier 
+    //when lots of cycles are done e.g. you may want 100 cycles in each file 
+    //so if something goes wrong, you will have most of the data, to within a 100 cycles)    
+    int num_file = 1; 
     
     for (int i=0; i<num_file; i++) {
         //record data
@@ -165,6 +183,7 @@
 
         /* Logging stopped as experiment is fully completed (desired number of cycles
         reached)*/
+        leg.pc.printf("\r\nExit Fatigue Test");
         leg.setValve(false); //Depressurise
         leg.StopLogging(); //Stop logging data
         leg.resumePrint(); //Let the Bench class print
@@ -177,11 +196,13 @@
  * increasing the actuator pressure by manually opening up the pressure regulator
  * connected to the actuator. It is also assumed that the user will stop inflation 
  * if they deem the actuator to have failed.
- * Data is recorded at ~10Hz.
  * @param targetkPa: the pressure at which the valve is opened to deflate the actuator (kPa)
+ * @param logHz: datalogging frequency
  */
-void runFailureExperiment0(float targetkPa) 
+void runFailureExperiment0(float targetkPa,int logHz) 
 {    
+    double logTime = 1/logHz;//s interval between logging data
+
     //Pressurise the actuator under test
     leg.StartLogging();
     leg.setValve(true);
@@ -191,12 +212,12 @@
     while(leg.isLogging() && (leg.getPressure0()*100 < targetkPa)) {        
         leg.pc.printf("\r\nPressure (kPa): \t%7.2f",leg.getPressure0()*100);//print the pressure
         leg.LogData();//record a datapoint
-        wait(0.1);//wait
+        wait(logTime);//wait
     }
     
     //Depressurise when the user is done with benchmarking or the target pressure is
     //reached    
-    leg.pc.printf("\r\nExit Benchmarking Test");
+    leg.pc.printf("\r\nExit Failure Test");
     leg.setValve(false);
     leg.StopLogging(); //Stop logging data
     leg.resumePrint(); //Let the Bench class print    
@@ -205,17 +226,19 @@
 /**
  * A method used to benchmark the actuator under test before the linear actuator
  * was fitted to the test rig. It simply pressurises the actuator and records data
- * at ~10 Hz
+ * @param logHz: datalogging frequency
  */
-void runBenchmarkExperiment0()
+void runBenchmarkExperiment0(int logHz)
 {
+    double logTime = 1/logHz;//s interval between logging data
+    
     //Pressurise the actuator under test
     leg.StartLogging();
     leg.setValve(true);//inflation
     while(leg.isLogging()) {//until the user presses the key to stop datalogging        
         leg.pc.printf("\r\nPressure (kPa): \t%7.2f",leg.getPressure0()*100); //print the pressure
         leg.LogData();//record a datapoint
-        wait(0.1);//wait
+        wait(logTime);//wait
     }
     
     //Depressurise when the user is done with benchmarking   
@@ -226,8 +249,8 @@
 }
 
 /**
- * A benchmark test with the linear actuator. The actuator is cycled from its flexed position
- * to the point at which it no longer produces force. This is considered its range of motion.
+ * A benchmark test with the linear actuator. The actuator is cycled from its flexed position,
+ * to the point at which it no longer produces force, and back again. This is considered its range of motion.
  * NOTE - not extensively tested
  * @param minForce: (N) force at which cycle goes from extension to flexion
  * @param maxAngle: (deg) angle at which cycle goes from flexion to extension
@@ -270,7 +293,8 @@
             wait(logTime);//wait
         }
         
-        if (!leg.isLogging()) {//If the user stopped
+        //If the user stopped
+        if (!leg.isLogging()) {
             leg.pc.printf("\r\nUser stopped during extension Exit");
             leg.setPWM(0); //turn off linear actuator
             leg.setValve(false);//Depressurise
@@ -292,7 +316,8 @@
             wait(logTime);//wait
         }
         
-        if (!leg.isLogging()) {//If the user stopped
+        //If the user stopped
+        if (!leg.isLogging()) {
             leg.pc.printf("\r\nUser stopped during flexion Exit");
             leg.setPWM(0); 
             leg.setValve(false);//Depressurise