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

Revision:
15:a84d54e25775
Parent:
11:fc82dd22a527
--- 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();
 }
 
 /**