Basic Mid-Level control for the rebuilt MorphGI control unit, using PWM to communicate with the low level controllers.

Dependencies:   ros_lib_kinetic

Revision:
11:7029367a1840
Parent:
10:1b6daba32452
Child:
12:595ed862e52f
--- a/main.cpp	Tue Aug 07 15:31:59 2018 +0000
+++ b/main.cpp	Fri Aug 10 10:40:18 2018 +0000
@@ -4,41 +4,20 @@
 #include "mbed.h"
 #include "mbed_events.h"
 // CUSTOM IMPORTS
+#include "MLOptions.h"
 #include "HLComms.h"
 #include "LLComms.h"
 
-// SIMPLE CHANNEL SELECTION
-#define ADC_PRESSURE 1
-#define ADC_POSITION 3
-
-#define N_CHANNELS 8 // Number of channels to control
-// 1-3: front segment; 4-6: rear segment; 7-8: mid segment
-
-// SPI SETTINGS
-#define LOW_LEVEL_SPI_FREQUENCY 10000000
-// PATH GENERATION SETTINGS
-#define PATH_SAMPLE_TIME_S 0.005 //0.109
-#define MAX_LENGTH_MM 100.0
-#define MAX_ACTUATOR_LENGTH 52.2
-#define MAX_SPEED_MMPS 24.3457
-#define PATH_TOLERANCE_MM 0.2 // How close the linear path must get to the target position before considering it a success.
-
-#define BAUD_RATE 9600 //115200
-
-// COMMS SETTINGS
-const short int SERVER_PORT = 80;
-
-//const double DBL_MAX_CHAMBER_LENGTHS_MM[N_CHANNELS] = {80.0,80.0,80.0,80.0,80.0,80.0,80.0,80.0};
-//const double DBL_ACTUATOR_CONVERSION[N_CHANNELS] = {0.30586,0.30586,0.30586,0.30586,0.30586,0.4588,0.4588}; // Convert from chamber lengths to actuator lengths
-const double DBL_ACTUATOR_CONVERSION[N_CHANNELS] = {1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0}; // Convert from chamber lengths to actuator 
-const double DBL_SMOOTHING_FACTOR = 0.5; // 0<x<=1, where 1 is no smoothing
-const double DBL_PATH_TOLERANCE = MAX_SPEED_MMPS * PATH_SAMPLE_TIME_S * 1.05; // Path tolerance in mm with 5% tolerance
+const double DBL_PATH_TOLERANCE = MAX_SPEED_MMPS * PATH_SAMPLE_TIME_S * (1.0+DBL_PERCENT_PATH_TOLERANCE); // Path tolerance in mm with 5% tolerance
 
 // PATH VARIABLES
 double dblVelocity_mmps[N_CHANNELS] = { 0.0 }; // The linear path velocity (not sent to actuator)
 double dblLinearPathCurrentPos_mm[N_CHANNELS]={ 0.0 }; // The current position of the linear path (not sent to actuator)
 double dblTargetActPos_mm[N_CHANNELS] = { 0.0 }; // The final target position for the actuator
 
+double _dblVelocity_mmps[N_CHANNELS];
+double _dblLinearPathCurrentPos_mm[N_CHANNELS];
+
 Serial pc(USBTX, USBRX); // tx, rx for usb debugging
 LLComms llcomms(LOW_LEVEL_SPI_FREQUENCY);//(N_CHANNELS);
 
@@ -91,9 +70,9 @@
         
         // PROCESS INPUT
         double dblTargetChambLen_mm[N_CHANNELS]; // The currenly assigned final target position (actuator will reach this at end of path)
-        printf("REPLAN, %f\r\n",input.duration);
+        //printf("REPLAN, %f\r\n",input.duration);
         // Update front segment
-        dblTargetChambLen_mm[0] = input.psi[0][0]*1000;
+        /*dblTargetChambLen_mm[0] = input.psi[0][0]*1000;
         dblTargetChambLen_mm[1] = input.psi[0][1]*1000;
         dblTargetChambLen_mm[2] = input.psi[0][2]*1000;
         // Update mid segment
@@ -102,21 +81,29 @@
         // Update rear segment
         dblTargetChambLen_mm[3] = input.psi[2][0]*1000;
         dblTargetChambLen_mm[4] = input.psi[2][1]*1000;
-        dblTargetChambLen_mm[5] = input.psi[2][2]*1000;
+        dblTargetChambLen_mm[5] = input.psi[2][2]*1000;*/
+        dblTargetChambLen_mm[3] = input.psi[0][0]*1000;
+        dblTargetChambLen_mm[4] = input.psi[0][1]*1000;
+        dblTargetChambLen_mm[5] = input.psi[0][2]*1000;
+        // Update mid segment
+        dblTargetChambLen_mm[6] = input.psi[1][0]*1000;
+        dblTargetChambLen_mm[7] = dblTargetChambLen_mm[6]; // Same because two pumps are used
+        // Update rear segment
+        dblTargetChambLen_mm[0] = input.psi[2][0]*1000;
+        dblTargetChambLen_mm[1] = input.psi[2][1]*1000;
+        dblTargetChambLen_mm[2] = input.psi[2][2]*1000;
+
+        mutPathIn.lock(); // Lock variables to avoid race condition
+        for(int j = 0; j<N_CHANNELS; j++) {
+            //_dblVelocity_mmps[j] = dblVelocity_mmps[j]; 
+            _dblLinearPathCurrentPos_mm[j] = dblLinearPathCurrentPos_mm[j];
+        }
+        mutPathIn.unlock(); // Unlock mutex
 
         bool isTimeChanged = 0;
         double dblMaxRecalculatedTime = input.duration;
-        mutPathIn.lock(); // Lock variables to avoid race condition
         for (ii = 0; ii< N_CHANNELS; ii++) {
             //check to see if positions are achievable
-            /*if(dblTargetChambLen_mm[ii]>DBL_MAX_CHAMBER_LENGTHS_MM[ii]) {
-                dblTargetChambLen_mm[ii] = DBL_MAX_CHAMBER_LENGTHS_MM[ii]; 
-                isTimeChanged = 1;
-            }
-            if(dblTargetChambLen_mm[ii]<0.0) {
-                dblTargetChambLen_mm[ii] = 0.0;
-                isTimeChanged = 1; 
-            }*/
             dblTargetActPos_mm[ii] = dblTargetChambLen_mm[ii]*DBL_ACTUATOR_CONVERSION[ii];
             //!! LIMIT CHAMBER LENGTHS TOO
             if( dblTargetActPos_mm[ii]<0.0 || dblTargetActPos_mm[ii]>25.0 ) {
@@ -127,32 +114,47 @@
         double dblActPosChange;
         short sgn;
         for (ii = 0; ii< N_CHANNELS; ii++) { // Work out new velocities
-            dblActPosChange = dblTargetActPos_mm[ii] - dblLinearPathCurrentPos_mm[ii];
+            /*dblActPosChange = 1.0; // or = 0.0;
+            _dblVelocity_mmps[ii] = 0.0;*/ // DOESN'T CRASH
+            /*dblActPosChange = dblTargetActPos_mm[ii];
+            _dblVelocity_mmps[ii] = 0.0;*/ // DOESN'T CRASH
+            /*dblActPosChange = _dblLinearPathCurrentPos_mm[ii];*/ // DOESN'T CRASH
+            /*_dblVelocity_mmps[ii] = _dblLinearPathCurrentPos_mm[ii];*/ // DOESN'T CRASH
+            /*dblActPosChange = 0.0;
+            _dblVelocity_mmps[ii] = _dblLinearPathCurrentPos_mm[ii];*/ // DOESN'T CRASH
+            
+            // DOES CRASH but not with a return at the end of while OR if _ variables are declared globally
+            /*dblActPosChange = _dblLinearPathCurrentPos_mm[ii];
+            _dblVelocity_mmps[ii] = 0.0;*/
+            
+            dblActPosChange = dblTargetActPos_mm[ii] - _dblLinearPathCurrentPos_mm[ii];
             if( fabs(dblActPosChange) < DBL_PATH_TOLERANCE ) {
                 dblActPosChange = 0.0;
                 isTimeChanged = 1;
             }
+            //IS BELOW
             if( input.duration < 0.000000001 ) {
                 sgn = (dblActPosChange > 0) ? 1 : ((dblActPosChange < 0) ? -1 : 0);
-                dblVelocity_mmps[ii] = sgn * MAX_SPEED_MMPS;
+                _dblVelocity_mmps[ii] = sgn * MAX_SPEED_MMPS;
                 isTimeChanged = 1;
             } else {
-                dblVelocity_mmps[ii] = dblActPosChange / input.duration;
+                _dblVelocity_mmps[ii] = dblActPosChange / input.duration;
             }
+            //IS ABOVE
             // Check to see if velocities are achievable
-            if(abs(dblVelocity_mmps[ii]) > MAX_SPEED_MMPS) {
-                if(dblVelocity_mmps[ii]>0) {
-                    dblVelocity_mmps[ii] = MAX_SPEED_MMPS;
+            if(abs(_dblVelocity_mmps[ii]) > MAX_SPEED_MMPS) {
+                if(_dblVelocity_mmps[ii]>0) {
+                    _dblVelocity_mmps[ii] = MAX_SPEED_MMPS;
                 } else {
-                    dblVelocity_mmps[ii] = -1*MAX_SPEED_MMPS;
+                    _dblVelocity_mmps[ii] = -1*MAX_SPEED_MMPS;
                 }
                 isTimeChanged = 1;
             }
             double dblRecalculatedTime;
-            if( fabs(dblVelocity_mmps[ii]) < 0.000000001 ) {
+            if( fabs(_dblVelocity_mmps[ii]) < 0.000000001 ) {
                 dblRecalculatedTime = 0;
             } else {
-                dblRecalculatedTime = (dblTargetActPos_mm[ii] - dblLinearPathCurrentPos_mm[ii]) / dblVelocity_mmps[ii];
+                dblRecalculatedTime = dblActPosChange / _dblVelocity_mmps[ii];
             }
             if( dblRecalculatedTime > dblMaxRecalculatedTime ) {
                 dblMaxRecalculatedTime = dblRecalculatedTime;
@@ -162,14 +164,17 @@
             if( dblMaxRecalculatedTime < input.duration ) {
                 dblMaxRecalculatedTime = input.duration;
             }
-            for (ii = 0; ii< N_CHANNELS; ii++) { // Work out new velocities
-                dblVelocity_mmps[ii] = (dblTargetActPos_mm[ii] - dblLinearPathCurrentPos_mm[ii]) / dblMaxRecalculatedTime;
+            if( dblMaxRecalculatedTime >= 0.000000001 ) {
+                for (ii = 0; ii< N_CHANNELS; ii++) { // Work out new velocities
+                    _dblVelocity_mmps[ii] = (dblTargetActPos_mm[ii] - _dblLinearPathCurrentPos_mm[ii]) / dblMaxRecalculatedTime;
+                    dblVelocity_mmps[ii] = _dblVelocity_mmps[ii];
+                }
             }
         }
-        mutPathIn.unlock(); // Unlock mutex
         
-        printf("Sending message...\r\n");
+        //printf("Sending message...\r\n");
         // SEND MESSAGE
+        //dblMaxRecalculatedTime = 1.0;
         hlcomms.make_message(&dblMaxRecalculatedTime);
         error_code = hlcomms.send_message();
         if( error_code < 0 ) {
@@ -179,7 +184,7 @@
             hlcomms.close_server();
             return;
         }
-        printf("Message sent.\r\n");
+        //printf("Message sent.\r\n");
     }
 
 }
@@ -207,19 +212,18 @@
             
             // Calculate next step in linear path
             mutPathIn.lock(); // Lock relevant mutex
-            dblLinearPathCurrentPos_mm[jj] = dblLinearPathCurrentPos_mm[jj] + dblVelocity_mmps[jj]*dblMeasuredSampleTime;
-            if(dblLinearPathCurrentPos_mm[jj] < 0.0) {
-                dblLinearPathCurrentPos_mm[jj] = 0.00;
-            }
             // Check tolerance
             if (fabs(dblLinearPathCurrentPos_mm[jj] - dblTargetActPos_mm[jj]) <= DBL_PATH_TOLERANCE) {
                 dblVelocity_mmps[jj] = 0.0; // Stop linear path generation when linear path is within tolerance of target position
             }
+            dblLinearPathCurrentPos_mm[jj] = dblLinearPathCurrentPos_mm[jj] + dblVelocity_mmps[jj]*dblMeasuredSampleTime;
+            dblLinearPathCurrentPos_mm[jj] = max( 0.0 , dblLinearPathCurrentPos_mm[jj] );
             mutPathIn.unlock(); // Unlock relevant mutex
             
             // Calculate next step in smooth path
             dblSmoothPathCurrentPos_mm[jj] = DBL_SMOOTHING_FACTOR*dblLinearPathCurrentPos_mm[jj] + (1.0-DBL_SMOOTHING_FACTOR)*dblSmoothPathCurrentPos_mm[jj];
-            llcomms.mutChannel[jj].lock(); // MUTEX LOCK
+            dblSmoothPathCurrentPos_mm[jj] = max( 0.0 , dblSmoothPathCurrentPos_mm[jj] );
+            llcomms.mutChannel[jj].lock(); // MUTEX LOCK            
             llcomms.demandPosition[jj] = (int) ((dblSmoothPathCurrentPos_mm[jj]/MAX_ACTUATOR_LENGTH)*8191);// Convert to a 13-bit number
             llcomms.demandPosition[jj] = llcomms.demandPosition[jj] & 0x1FFF; // Ensure number is 13-bit
             llcomms.mutChannel[jj].unlock(); // MUTEX UNLOCK
@@ -228,8 +232,8 @@
         } // end for
         
         //printf("%f, %d\r\n",dblSmoothPathCurrentPos_mm[0], intDemandPos_Tx[0]);
-        /*printf("%f, %f, %f, %f, %f, %f, %f, %f\r\n",dblLinearPathCurrentPos_mm[0],dblLinearPathCurrentPos_mm[1],dblLinearPathCurrentPos_mm[2],
-            dblLinearPathCurrentPos_mm[3],dblLinearPathCurrentPos_mm[4],dblLinearPathCurrentPos_mm[5],dblLinearPathCurrentPos_mm[6],dblLinearPathCurrentPos_mm[7]);*/
+        //printf("%f, %f, %f, %f, %f, %f, %f, %f\r\n",dblLinearPathCurrentPos_mm[0],dblLinearPathCurrentPos_mm[1],dblLinearPathCurrentPos_mm[2],
+        //  dblLinearPathCurrentPos_mm[3],dblLinearPathCurrentPos_mm[4],dblLinearPathCurrentPos_mm[5],dblLinearPathCurrentPos_mm[6],dblLinearPathCurrentPos_mm[7]);
         //printf("%f\r\n",dblLinearPathCurrentPos_mm[0]);
         
     } // end while