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
Diff: bench.cpp
- 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(); } /**