Mid level control code

Dependencies:   ros_lib_kinetic

Revision:
19:e5acb2183d4e
Parent:
18:6533fb7f5a91
Child:
20:b2139294c547
--- a/main.cpp	Wed Oct 10 13:36:57 2018 +0000
+++ b/main.cpp	Tue Nov 27 16:52:06 2018 +0000
@@ -21,7 +21,6 @@
 // These have to be declared in the global scope or we get a stack overflow. No idea why.
 double _dblVelocity_mmps[N_CHANNELS];
 //double _dblLinearPathCurrentPos_mm[N_CHANNELS];
-double dblADCCurrentPosition[N_CHANNELS];
 
 Serial pc(USBTX, USBRX); // tx, rx for usb debugging
 LLComms llcomms;
@@ -82,7 +81,6 @@
     
     SendSensorDataTicker.attach(&signalSendSensorData, 0.1); // Set up planning thread to recur at fixed intervals
     
-    int ii;
     struct msg_format input; //hlcomms.msg_format
     
     while( true ) {
@@ -103,31 +101,63 @@
         input = hlcomms.process_message();
         
         // PROCESS INPUT
-        double dblTargetChambLen_mm[N_CHANNELS]; // The currenly assigned final target position (actuator will reach this at end of path)
-        if(IS_PRINT_OUTPUT) printf("REPLAN, %f\r\n",input.duration);
+        if(IS_PRINT_OUTPUT) printf("REPLAN, %f\r\n",input.speed);
         
-        //update rear Segment
-        dblTargetChambLen_mm[3] = input.psi[0][0]*1000;
-        dblTargetChambLen_mm[5] = 0.0;//input.psi[0][1]*1000;//not used
-        dblTargetChambLen_mm[6] = 0.0;//input.psi[0][2]*1000;//not used
-        
-        //update mid segment
-        dblTargetChambLen_mm[4] = input.psi[1][0]*1000;
-        dblTargetChambLen_mm[7] = dblTargetChambLen_mm[4]; // Same because two pumps are used
-
+        double dblTarget_mm[N_CHANNELS]; // The currenly assigned final target position (actuator will reach this at end of path)
+        // Update rear segment
+        dblTarget_mm[3] = input.psi[0][0]*1000;
+        dblTarget_mm[5] = 0.0; //input.psi[0][1]*1000;
+        dblTarget_mm[6] = 0.0; //input.psi[0][2]*1000;
+        // Update mid segment
+        dblTarget_mm[4] = input.psi[1][0]*1000;
+        dblTarget_mm[7] = dblTarget_mm[4]; // Same because two pumps are used
         // Update front 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;
+        dblTarget_mm[0] = input.psi[2][0]*1000;
+        dblTarget_mm[1] = input.psi[2][1]*1000;
+        dblTarget_mm[2] = input.psi[2][2]*1000;
 
-        mutPathIn.lock(); // Lock variables to avoid race condition
-        for(int j = 0; j<N_CHANNELS; j++) {
-            dblADCCurrentPosition[j] = dblLinearPathCurrentPos_mm[j];
-            //dblADCCurrentPosition[j] = llcomms.ReadADCPosition_mtrs(j); // Read position from channel
+        // Lock mutex, preventing CalculateSmoothPath from running
+        mutPathIn.lock();        
+        // Limit requested speed
+        double limitedSpeed_mmps = min( max( 0.0 , input.speed ) , (double)MAX_SPEED_MMPS );
+        // For each actuator, limit the input position, calculate the position change, and select the absolute max
+        double dblDisplacementToTarget_mm[N_CHANNELS];
+        double maxDistanceToTarget_mm = 0.0;
+        for(int i=0; i<N_CHANNELS; i++) {
+            // If requested position is negative
+            if(dblTarget_mm[i]<0) {
+                // Set actuator position change to 0
+                dblDisplacementToTarget_mm[i] = 0.0;
+            } else { // Requested position is positive
+                // ? Limit requested chamber lengths
+                // ? Convert from chamber length to actuator space
+                // Limit actuator position
+                dblTarget_mm[i] = min( max( 0.0 , dblTarget_mm[i] ) , 40.0 ); // !!! USE A CONSTANT FOR THIS
+                // Calculate actuator position change
+                double dblCurrentPosition = dblLinearPathCurrentPos_mm[i];
+                //dblCurrentPosition[i] = llcomms.ReadADCPosition_mtrs(i); // Read position from channel
+                dblDisplacementToTarget_mm[i] = dblTarget_mm[i] - dblCurrentPosition;
+                // Select the max absolute actuator position change
+                if(fabs(dblDisplacementToTarget_mm[i])>maxDistanceToTarget_mm) {
+                    maxDistanceToTarget_mm = fabs(dblDisplacementToTarget_mm[i]);
+                }
+            }
         }
+        // For max actuator position change, calculate the time to destination at the limited speed
+        double maxTimeToTarget_s = fabs(maxDistanceToTarget_mm) / limitedSpeed_mmps;
+        // For each actuator, replan target position and velocity as required
+        for(int i=0; i<N_CHANNELS; i++) {
+            // If requested actuator position change is already within tolerance, do NOT replan that actuator
+            if( fabs(dblDisplacementToTarget_mm[i]) < FLT_PATH_TOLERANCE ) continue;
+            // Calculate velocity for each motor to synchronise movements to complete in max time
+            // Set dblTargetActPos_mm and dblVelocity_mmps
+            dblTargetActPos_mm[i] = dblTarget_mm[i];
+            dblVelocity_mmps[i] = dblDisplacementToTarget_mm[i] / maxTimeToTarget_s;
+        }
+        // Unlock mutex, allowing CalculateSmoothPath to run again
+        mutPathIn.unlock();
         
-        mutPathIn.unlock(); // Unlock mutex
-
+/*
         //bool isTimeChanged = 0;
         double dblMaxRecalculatedTime = input.duration;
         // Convert from requested chamber to actuator space and limit actuator positions
@@ -207,8 +237,9 @@
             _dblVelocity_mmps[ii] = (dblTargetActPos_mm[ii] - dblADCCurrentPosition[ii]) / dblMaxRecalculatedTime;
             dblVelocity_mmps[ii] = _dblVelocity_mmps[ii];
         }
+*/
         // SEND MESSAGE
-        error_code = hlcomms.send_duration_message(&dblMaxRecalculatedTime);
+        error_code = hlcomms.send_duration_message(&maxTimeToTarget_s);
         if( error_code < 0 ) {
             if(IS_PRINT_OUTPUT) printf("Error %i. Could not send data over the TCP socket. "
                 "Perhaps the server socket is not bound or not set to listen for connections? "