Mid level control code
Dependencies: ros_lib_kinetic
main.cpp@11:7029367a1840, 2018-08-10 (annotated)
- Committer:
- dofydoink
- Date:
- Fri Aug 10 10:40:18 2018 +0000
- Revision:
- 11:7029367a1840
- Parent:
- 10:1b6daba32452
- Child:
- 12:595ed862e52f
Tested and working with 1 actuator.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
WD40andTape | 7:5b6a2cefbf3b | 1 | // STANDARD IMPORTS |
WD40andTape | 7:5b6a2cefbf3b | 2 | #include "math.h" |
WD40andTape | 7:5b6a2cefbf3b | 3 | // MBED IMPORTS |
dofydoink | 0:607bc887b6e0 | 4 | #include "mbed.h" |
WD40andTape | 6:f0a18e28a322 | 5 | #include "mbed_events.h" |
WD40andTape | 7:5b6a2cefbf3b | 6 | // CUSTOM IMPORTS |
dofydoink | 11:7029367a1840 | 7 | #include "MLOptions.h" |
WD40andTape | 7:5b6a2cefbf3b | 8 | #include "HLComms.h" |
WD40andTape | 8:d6657767a182 | 9 | #include "LLComms.h" |
dofydoink | 0:607bc887b6e0 | 10 | |
dofydoink | 11:7029367a1840 | 11 | 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 |
dofydoink | 0:607bc887b6e0 | 12 | |
WD40andTape | 7:5b6a2cefbf3b | 13 | // PATH VARIABLES |
WD40andTape | 7:5b6a2cefbf3b | 14 | double dblVelocity_mmps[N_CHANNELS] = { 0.0 }; // The linear path velocity (not sent to actuator) |
WD40andTape | 7:5b6a2cefbf3b | 15 | double dblLinearPathCurrentPos_mm[N_CHANNELS]={ 0.0 }; // The current position of the linear path (not sent to actuator) |
WD40andTape | 7:5b6a2cefbf3b | 16 | double dblTargetActPos_mm[N_CHANNELS] = { 0.0 }; // The final target position for the actuator |
dofydoink | 0:607bc887b6e0 | 17 | |
dofydoink | 11:7029367a1840 | 18 | double _dblVelocity_mmps[N_CHANNELS]; |
dofydoink | 11:7029367a1840 | 19 | double _dblLinearPathCurrentPos_mm[N_CHANNELS]; |
dofydoink | 11:7029367a1840 | 20 | |
WD40andTape | 7:5b6a2cefbf3b | 21 | Serial pc(USBTX, USBRX); // tx, rx for usb debugging |
WD40andTape | 8:d6657767a182 | 22 | LLComms llcomms(LOW_LEVEL_SPI_FREQUENCY);//(N_CHANNELS); |
WD40andTape | 3:c83291bf9fd2 | 23 | |
WD40andTape | 10:1b6daba32452 | 24 | Thread threadLowLevelSPI(osPriorityRealtime); |
WD40andTape | 4:303584310071 | 25 | Thread threadReceiveAndReplan(osPriorityBelowNormal); |
WD40andTape | 4:303584310071 | 26 | Thread threadSmoothPathPlan(osPriorityNormal); |
dofydoink | 0:607bc887b6e0 | 27 | |
WD40andTape | 4:303584310071 | 28 | Mutex mutPathIn; |
WD40andTape | 7:5b6a2cefbf3b | 29 | Semaphore semPathPlan(1); |
dofydoink | 0:607bc887b6e0 | 30 | |
WD40andTape | 7:5b6a2cefbf3b | 31 | Timer timer; |
WD40andTape | 7:5b6a2cefbf3b | 32 | Ticker PathCalculationTicker; |
dofydoink | 0:607bc887b6e0 | 33 | |
WD40andTape | 7:5b6a2cefbf3b | 34 | void startPathPlan() { // Plan a new linear path after receiving new target data |
WD40andTape | 4:303584310071 | 35 | semPathPlan.release(); // Uses threadReceiveAndReplan which is below normal priority to ensure consistent transmission to LL |
dofydoink | 0:607bc887b6e0 | 36 | } |
dofydoink | 0:607bc887b6e0 | 37 | |
WD40andTape | 7:5b6a2cefbf3b | 38 | // This function will be called when a new transmission is received from high level |
WD40andTape | 7:5b6a2cefbf3b | 39 | void ReceiveAndReplan() { |
WD40andTape | 7:5b6a2cefbf3b | 40 | HLComms hlcomms(SERVER_PORT); |
WD40andTape | 6:f0a18e28a322 | 41 | |
WD40andTape | 6:f0a18e28a322 | 42 | int error_code; |
WD40andTape | 7:5b6a2cefbf3b | 43 | error_code = hlcomms.setup_server(); |
WD40andTape | 6:f0a18e28a322 | 44 | if( error_code == -1 ) return; |
WD40andTape | 7:5b6a2cefbf3b | 45 | error_code = hlcomms.accept_connection(); |
WD40andTape | 7:5b6a2cefbf3b | 46 | if( error_code == -1 ) { |
WD40andTape | 7:5b6a2cefbf3b | 47 | hlcomms.close_server(); |
WD40andTape | 7:5b6a2cefbf3b | 48 | return; |
WD40andTape | 7:5b6a2cefbf3b | 49 | } |
WD40andTape | 6:f0a18e28a322 | 50 | |
WD40andTape | 7:5b6a2cefbf3b | 51 | int ii; |
WD40andTape | 7:5b6a2cefbf3b | 52 | struct msg_format input; //hlcomms.msg_format |
WD40andTape | 4:303584310071 | 53 | |
WD40andTape | 6:f0a18e28a322 | 54 | while( true ) { |
WD40andTape | 6:f0a18e28a322 | 55 | // RECEIVE MESSAGE |
WD40andTape | 9:cd3607ba5643 | 56 | error_code = hlcomms.receive_message(); |
WD40andTape | 6:f0a18e28a322 | 57 | if( error_code == NSAPI_ERROR_NO_CONNECTION ) { // -3004 |
WD40andTape | 6:f0a18e28a322 | 58 | printf("Client disconnected.\n\r"); |
WD40andTape | 7:5b6a2cefbf3b | 59 | hlcomms.close_server(); |
WD40andTape | 6:f0a18e28a322 | 60 | return; |
WD40andTape | 6:f0a18e28a322 | 61 | } else if( error_code < 0 ) { |
WD40andTape | 6:f0a18e28a322 | 62 | printf("Error %i. Could not send data over the TCP socket. " |
WD40andTape | 6:f0a18e28a322 | 63 | "Perhaps the server socket is not connected to a remote host? " |
WD40andTape | 6:f0a18e28a322 | 64 | "Or the socket is set to non-blocking or timed out?\n\r", error_code); |
WD40andTape | 7:5b6a2cefbf3b | 65 | hlcomms.close_server(); |
WD40andTape | 6:f0a18e28a322 | 66 | return; |
WD40andTape | 6:f0a18e28a322 | 67 | } |
WD40andTape | 6:f0a18e28a322 | 68 | //printf("Message received.\r\n"); |
WD40andTape | 9:cd3607ba5643 | 69 | input = hlcomms.process_message(); |
WD40andTape | 1:2a43cf183a62 | 70 | |
WD40andTape | 7:5b6a2cefbf3b | 71 | // PROCESS INPUT |
WD40andTape | 7:5b6a2cefbf3b | 72 | double dblTargetChambLen_mm[N_CHANNELS]; // The currenly assigned final target position (actuator will reach this at end of path) |
dofydoink | 11:7029367a1840 | 73 | //printf("REPLAN, %f\r\n",input.duration); |
WD40andTape | 7:5b6a2cefbf3b | 74 | // Update front segment |
dofydoink | 11:7029367a1840 | 75 | /*dblTargetChambLen_mm[0] = input.psi[0][0]*1000; |
WD40andTape | 6:f0a18e28a322 | 76 | dblTargetChambLen_mm[1] = input.psi[0][1]*1000; |
WD40andTape | 6:f0a18e28a322 | 77 | dblTargetChambLen_mm[2] = input.psi[0][2]*1000; |
WD40andTape | 7:5b6a2cefbf3b | 78 | // Update mid segment |
WD40andTape | 6:f0a18e28a322 | 79 | dblTargetChambLen_mm[6] = input.psi[1][0]*1000; |
WD40andTape | 7:5b6a2cefbf3b | 80 | dblTargetChambLen_mm[7] = dblTargetChambLen_mm[6]; // Same because two pumps are used |
WD40andTape | 7:5b6a2cefbf3b | 81 | // Update rear segment |
WD40andTape | 6:f0a18e28a322 | 82 | dblTargetChambLen_mm[3] = input.psi[2][0]*1000; |
WD40andTape | 6:f0a18e28a322 | 83 | dblTargetChambLen_mm[4] = input.psi[2][1]*1000; |
dofydoink | 11:7029367a1840 | 84 | dblTargetChambLen_mm[5] = input.psi[2][2]*1000;*/ |
dofydoink | 11:7029367a1840 | 85 | dblTargetChambLen_mm[3] = input.psi[0][0]*1000; |
dofydoink | 11:7029367a1840 | 86 | dblTargetChambLen_mm[4] = input.psi[0][1]*1000; |
dofydoink | 11:7029367a1840 | 87 | dblTargetChambLen_mm[5] = input.psi[0][2]*1000; |
dofydoink | 11:7029367a1840 | 88 | // Update mid segment |
dofydoink | 11:7029367a1840 | 89 | dblTargetChambLen_mm[6] = input.psi[1][0]*1000; |
dofydoink | 11:7029367a1840 | 90 | dblTargetChambLen_mm[7] = dblTargetChambLen_mm[6]; // Same because two pumps are used |
dofydoink | 11:7029367a1840 | 91 | // Update rear segment |
dofydoink | 11:7029367a1840 | 92 | dblTargetChambLen_mm[0] = input.psi[2][0]*1000; |
dofydoink | 11:7029367a1840 | 93 | dblTargetChambLen_mm[1] = input.psi[2][1]*1000; |
dofydoink | 11:7029367a1840 | 94 | dblTargetChambLen_mm[2] = input.psi[2][2]*1000; |
dofydoink | 11:7029367a1840 | 95 | |
dofydoink | 11:7029367a1840 | 96 | mutPathIn.lock(); // Lock variables to avoid race condition |
dofydoink | 11:7029367a1840 | 97 | for(int j = 0; j<N_CHANNELS; j++) { |
dofydoink | 11:7029367a1840 | 98 | //_dblVelocity_mmps[j] = dblVelocity_mmps[j]; |
dofydoink | 11:7029367a1840 | 99 | _dblLinearPathCurrentPos_mm[j] = dblLinearPathCurrentPos_mm[j]; |
dofydoink | 11:7029367a1840 | 100 | } |
dofydoink | 11:7029367a1840 | 101 | mutPathIn.unlock(); // Unlock mutex |
dofydoink | 0:607bc887b6e0 | 102 | |
WD40andTape | 6:f0a18e28a322 | 103 | bool isTimeChanged = 0; |
WD40andTape | 6:f0a18e28a322 | 104 | double dblMaxRecalculatedTime = input.duration; |
WD40andTape | 4:303584310071 | 105 | for (ii = 0; ii< N_CHANNELS; ii++) { |
dofydoink | 0:607bc887b6e0 | 106 | //check to see if positions are achievable |
WD40andTape | 6:f0a18e28a322 | 107 | dblTargetActPos_mm[ii] = dblTargetChambLen_mm[ii]*DBL_ACTUATOR_CONVERSION[ii]; |
WD40andTape | 6:f0a18e28a322 | 108 | //!! LIMIT CHAMBER LENGTHS TOO |
WD40andTape | 6:f0a18e28a322 | 109 | if( dblTargetActPos_mm[ii]<0.0 || dblTargetActPos_mm[ii]>25.0 ) { |
WD40andTape | 6:f0a18e28a322 | 110 | dblTargetActPos_mm[ii] = min( max( 0.0 , dblTargetActPos_mm[ii] ) , 25.0 ); |
WD40andTape | 6:f0a18e28a322 | 111 | isTimeChanged = 1; |
WD40andTape | 6:f0a18e28a322 | 112 | } |
WD40andTape | 6:f0a18e28a322 | 113 | } |
WD40andTape | 6:f0a18e28a322 | 114 | double dblActPosChange; |
WD40andTape | 6:f0a18e28a322 | 115 | short sgn; |
WD40andTape | 7:5b6a2cefbf3b | 116 | for (ii = 0; ii< N_CHANNELS; ii++) { // Work out new velocities |
dofydoink | 11:7029367a1840 | 117 | /*dblActPosChange = 1.0; // or = 0.0; |
dofydoink | 11:7029367a1840 | 118 | _dblVelocity_mmps[ii] = 0.0;*/ // DOESN'T CRASH |
dofydoink | 11:7029367a1840 | 119 | /*dblActPosChange = dblTargetActPos_mm[ii]; |
dofydoink | 11:7029367a1840 | 120 | _dblVelocity_mmps[ii] = 0.0;*/ // DOESN'T CRASH |
dofydoink | 11:7029367a1840 | 121 | /*dblActPosChange = _dblLinearPathCurrentPos_mm[ii];*/ // DOESN'T CRASH |
dofydoink | 11:7029367a1840 | 122 | /*_dblVelocity_mmps[ii] = _dblLinearPathCurrentPos_mm[ii];*/ // DOESN'T CRASH |
dofydoink | 11:7029367a1840 | 123 | /*dblActPosChange = 0.0; |
dofydoink | 11:7029367a1840 | 124 | _dblVelocity_mmps[ii] = _dblLinearPathCurrentPos_mm[ii];*/ // DOESN'T CRASH |
dofydoink | 11:7029367a1840 | 125 | |
dofydoink | 11:7029367a1840 | 126 | // DOES CRASH but not with a return at the end of while OR if _ variables are declared globally |
dofydoink | 11:7029367a1840 | 127 | /*dblActPosChange = _dblLinearPathCurrentPos_mm[ii]; |
dofydoink | 11:7029367a1840 | 128 | _dblVelocity_mmps[ii] = 0.0;*/ |
dofydoink | 11:7029367a1840 | 129 | |
dofydoink | 11:7029367a1840 | 130 | dblActPosChange = dblTargetActPos_mm[ii] - _dblLinearPathCurrentPos_mm[ii]; |
WD40andTape | 6:f0a18e28a322 | 131 | if( fabs(dblActPosChange) < DBL_PATH_TOLERANCE ) { |
WD40andTape | 6:f0a18e28a322 | 132 | dblActPosChange = 0.0; |
WD40andTape | 6:f0a18e28a322 | 133 | isTimeChanged = 1; |
dofydoink | 0:607bc887b6e0 | 134 | } |
dofydoink | 11:7029367a1840 | 135 | //IS BELOW |
WD40andTape | 6:f0a18e28a322 | 136 | if( input.duration < 0.000000001 ) { |
WD40andTape | 6:f0a18e28a322 | 137 | sgn = (dblActPosChange > 0) ? 1 : ((dblActPosChange < 0) ? -1 : 0); |
dofydoink | 11:7029367a1840 | 138 | _dblVelocity_mmps[ii] = sgn * MAX_SPEED_MMPS; |
WD40andTape | 6:f0a18e28a322 | 139 | isTimeChanged = 1; |
WD40andTape | 6:f0a18e28a322 | 140 | } else { |
dofydoink | 11:7029367a1840 | 141 | _dblVelocity_mmps[ii] = dblActPosChange / input.duration; |
WD40andTape | 6:f0a18e28a322 | 142 | } |
dofydoink | 11:7029367a1840 | 143 | //IS ABOVE |
WD40andTape | 7:5b6a2cefbf3b | 144 | // Check to see if velocities are achievable |
dofydoink | 11:7029367a1840 | 145 | if(abs(_dblVelocity_mmps[ii]) > MAX_SPEED_MMPS) { |
dofydoink | 11:7029367a1840 | 146 | if(_dblVelocity_mmps[ii]>0) { |
dofydoink | 11:7029367a1840 | 147 | _dblVelocity_mmps[ii] = MAX_SPEED_MMPS; |
WD40andTape | 6:f0a18e28a322 | 148 | } else { |
dofydoink | 11:7029367a1840 | 149 | _dblVelocity_mmps[ii] = -1*MAX_SPEED_MMPS; |
WD40andTape | 6:f0a18e28a322 | 150 | } |
WD40andTape | 6:f0a18e28a322 | 151 | isTimeChanged = 1; |
WD40andTape | 6:f0a18e28a322 | 152 | } |
WD40andTape | 6:f0a18e28a322 | 153 | double dblRecalculatedTime; |
dofydoink | 11:7029367a1840 | 154 | if( fabs(_dblVelocity_mmps[ii]) < 0.000000001 ) { |
WD40andTape | 6:f0a18e28a322 | 155 | dblRecalculatedTime = 0; |
WD40andTape | 6:f0a18e28a322 | 156 | } else { |
dofydoink | 11:7029367a1840 | 157 | dblRecalculatedTime = dblActPosChange / _dblVelocity_mmps[ii]; |
WD40andTape | 6:f0a18e28a322 | 158 | } |
WD40andTape | 6:f0a18e28a322 | 159 | if( dblRecalculatedTime > dblMaxRecalculatedTime ) { |
WD40andTape | 6:f0a18e28a322 | 160 | dblMaxRecalculatedTime = dblRecalculatedTime; |
WD40andTape | 6:f0a18e28a322 | 161 | } |
WD40andTape | 6:f0a18e28a322 | 162 | } |
WD40andTape | 6:f0a18e28a322 | 163 | if( isTimeChanged ) { |
WD40andTape | 6:f0a18e28a322 | 164 | if( dblMaxRecalculatedTime < input.duration ) { |
WD40andTape | 6:f0a18e28a322 | 165 | dblMaxRecalculatedTime = input.duration; |
WD40andTape | 6:f0a18e28a322 | 166 | } |
dofydoink | 11:7029367a1840 | 167 | if( dblMaxRecalculatedTime >= 0.000000001 ) { |
dofydoink | 11:7029367a1840 | 168 | for (ii = 0; ii< N_CHANNELS; ii++) { // Work out new velocities |
dofydoink | 11:7029367a1840 | 169 | _dblVelocity_mmps[ii] = (dblTargetActPos_mm[ii] - _dblLinearPathCurrentPos_mm[ii]) / dblMaxRecalculatedTime; |
dofydoink | 11:7029367a1840 | 170 | dblVelocity_mmps[ii] = _dblVelocity_mmps[ii]; |
dofydoink | 11:7029367a1840 | 171 | } |
WD40andTape | 6:f0a18e28a322 | 172 | } |
WD40andTape | 6:f0a18e28a322 | 173 | } |
WD40andTape | 6:f0a18e28a322 | 174 | |
dofydoink | 11:7029367a1840 | 175 | //printf("Sending message...\r\n"); |
WD40andTape | 6:f0a18e28a322 | 176 | // SEND MESSAGE |
dofydoink | 11:7029367a1840 | 177 | //dblMaxRecalculatedTime = 1.0; |
WD40andTape | 9:cd3607ba5643 | 178 | hlcomms.make_message(&dblMaxRecalculatedTime); |
WD40andTape | 9:cd3607ba5643 | 179 | error_code = hlcomms.send_message(); |
WD40andTape | 6:f0a18e28a322 | 180 | if( error_code < 0 ) { |
WD40andTape | 6:f0a18e28a322 | 181 | printf("Error %i. Could not send data over the TCP socket. " |
WD40andTape | 6:f0a18e28a322 | 182 | "Perhaps the server socket is not bound or not set to listen for connections? " |
WD40andTape | 6:f0a18e28a322 | 183 | "Or the socket is set to non-blocking or timed out?\n\r", error_code); |
WD40andTape | 7:5b6a2cefbf3b | 184 | hlcomms.close_server(); |
WD40andTape | 6:f0a18e28a322 | 185 | return; |
WD40andTape | 6:f0a18e28a322 | 186 | } |
dofydoink | 11:7029367a1840 | 187 | //printf("Message sent.\r\n"); |
WD40andTape | 6:f0a18e28a322 | 188 | } |
WD40andTape | 6:f0a18e28a322 | 189 | |
dofydoink | 0:607bc887b6e0 | 190 | } |
dofydoink | 0:607bc887b6e0 | 191 | |
WD40andTape | 4:303584310071 | 192 | void CalculateSmoothPath() { |
dofydoink | 5:712e7634c779 | 193 | int jj; |
WD40andTape | 1:2a43cf183a62 | 194 | double dblMeasuredSampleTime; |
WD40andTape | 7:5b6a2cefbf3b | 195 | double dblSmoothPathCurrentPos_mm[N_CHANNELS] = { 0.0 }; // The current position of the smooth path (not sent to actuator) |
WD40andTape | 7:5b6a2cefbf3b | 196 | //double dblPosition_mtrs[N_CHANNELS]; // The actual chamber lengths in meters given as the change in length relative to neutral (should always be >=0) |
WD40andTape | 7:5b6a2cefbf3b | 197 | //double dblPressure_bar[N_CHANNELS]; // The pressure in a given chamber in bar (1 bar = 100,000 Pa) |
WD40andTape | 4:303584310071 | 198 | while(1) { |
dofydoink | 0:607bc887b6e0 | 199 | semPathPlan.wait(); |
WD40andTape | 1:2a43cf183a62 | 200 | |
WD40andTape | 1:2a43cf183a62 | 201 | // If run time is more than 50 us from expected, calculate from measured time step |
WD40andTape | 4:303584310071 | 202 | if (fabs(PATH_SAMPLE_TIME_S*1000000 - timer.read_us()) > 50) { |
dofydoink | 5:712e7634c779 | 203 | dblMeasuredSampleTime = timer.read(); |
WD40andTape | 4:303584310071 | 204 | } else { |
WD40andTape | 1:2a43cf183a62 | 205 | dblMeasuredSampleTime = PATH_SAMPLE_TIME_S; |
WD40andTape | 1:2a43cf183a62 | 206 | } |
WD40andTape | 4:303584310071 | 207 | timer.reset(); |
WD40andTape | 1:2a43cf183a62 | 208 | |
dofydoink | 5:712e7634c779 | 209 | for(jj = 0; jj < N_CHANNELS; jj++) { |
WD40andTape | 7:5b6a2cefbf3b | 210 | //dblPressure_bar[jj] = ReadADCPressure_bar(jj); // Read pressure from channel |
WD40andTape | 7:5b6a2cefbf3b | 211 | //dblPosition_mtrs[jj] = ReadADCPosition_mtrs(jj); // Read position from channel |
WD40andTape | 1:2a43cf183a62 | 212 | |
WD40andTape | 7:5b6a2cefbf3b | 213 | // Calculate next step in linear path |
WD40andTape | 7:5b6a2cefbf3b | 214 | mutPathIn.lock(); // Lock relevant mutex |
WD40andTape | 7:5b6a2cefbf3b | 215 | // Check tolerance |
WD40andTape | 7:5b6a2cefbf3b | 216 | if (fabs(dblLinearPathCurrentPos_mm[jj] - dblTargetActPos_mm[jj]) <= DBL_PATH_TOLERANCE) { |
WD40andTape | 7:5b6a2cefbf3b | 217 | dblVelocity_mmps[jj] = 0.0; // Stop linear path generation when linear path is within tolerance of target position |
WD40andTape | 7:5b6a2cefbf3b | 218 | } |
dofydoink | 11:7029367a1840 | 219 | dblLinearPathCurrentPos_mm[jj] = dblLinearPathCurrentPos_mm[jj] + dblVelocity_mmps[jj]*dblMeasuredSampleTime; |
dofydoink | 11:7029367a1840 | 220 | dblLinearPathCurrentPos_mm[jj] = max( 0.0 , dblLinearPathCurrentPos_mm[jj] ); |
WD40andTape | 7:5b6a2cefbf3b | 221 | mutPathIn.unlock(); // Unlock relevant mutex |
dofydoink | 0:607bc887b6e0 | 222 | |
WD40andTape | 7:5b6a2cefbf3b | 223 | // Calculate next step in smooth path |
dofydoink | 5:712e7634c779 | 224 | dblSmoothPathCurrentPos_mm[jj] = DBL_SMOOTHING_FACTOR*dblLinearPathCurrentPos_mm[jj] + (1.0-DBL_SMOOTHING_FACTOR)*dblSmoothPathCurrentPos_mm[jj]; |
dofydoink | 11:7029367a1840 | 225 | dblSmoothPathCurrentPos_mm[jj] = max( 0.0 , dblSmoothPathCurrentPos_mm[jj] ); |
dofydoink | 11:7029367a1840 | 226 | llcomms.mutChannel[jj].lock(); // MUTEX LOCK |
WD40andTape | 10:1b6daba32452 | 227 | llcomms.demandPosition[jj] = (int) ((dblSmoothPathCurrentPos_mm[jj]/MAX_ACTUATOR_LENGTH)*8191);// Convert to a 13-bit number |
WD40andTape | 10:1b6daba32452 | 228 | llcomms.demandPosition[jj] = llcomms.demandPosition[jj] & 0x1FFF; // Ensure number is 13-bit |
WD40andTape | 8:d6657767a182 | 229 | llcomms.mutChannel[jj].unlock(); // MUTEX UNLOCK |
dofydoink | 0:607bc887b6e0 | 230 | |
WD40andTape | 10:1b6daba32452 | 231 | llcomms.isDataReady[jj] = 1; // Signal that data ready |
WD40andTape | 4:303584310071 | 232 | } // end for |
WD40andTape | 7:5b6a2cefbf3b | 233 | |
WD40andTape | 6:f0a18e28a322 | 234 | //printf("%f, %d\r\n",dblSmoothPathCurrentPos_mm[0], intDemandPos_Tx[0]); |
dofydoink | 11:7029367a1840 | 235 | //printf("%f, %f, %f, %f, %f, %f, %f, %f\r\n",dblLinearPathCurrentPos_mm[0],dblLinearPathCurrentPos_mm[1],dblLinearPathCurrentPos_mm[2], |
dofydoink | 11:7029367a1840 | 236 | // dblLinearPathCurrentPos_mm[3],dblLinearPathCurrentPos_mm[4],dblLinearPathCurrentPos_mm[5],dblLinearPathCurrentPos_mm[6],dblLinearPathCurrentPos_mm[7]); |
WD40andTape | 6:f0a18e28a322 | 237 | //printf("%f\r\n",dblLinearPathCurrentPos_mm[0]); |
WD40andTape | 7:5b6a2cefbf3b | 238 | |
WD40andTape | 4:303584310071 | 239 | } // end while |
WD40andTape | 3:c83291bf9fd2 | 240 | } |
dofydoink | 0:607bc887b6e0 | 241 | |
WD40andTape | 9:cd3607ba5643 | 242 | int main() { |
WD40andTape | 7:5b6a2cefbf3b | 243 | pc.baud(BAUD_RATE); |
dofydoink | 0:607bc887b6e0 | 244 | printf("Hi, there! I'll be your mid-level controller for today.\r\n"); |
dofydoink | 5:712e7634c779 | 245 | wait(3); |
WD40andTape | 9:cd3607ba5643 | 246 | |
dofydoink | 0:607bc887b6e0 | 247 | timer.start(); |
WD40andTape | 7:5b6a2cefbf3b | 248 | |
WD40andTape | 10:1b6daba32452 | 249 | threadLowLevelSPI.start(callback(&llcomms.queue, &EventQueue::dispatch_forever)); // Start the event queue |
WD40andTape | 7:5b6a2cefbf3b | 250 | threadReceiveAndReplan.start(ReceiveAndReplan);// Start replanning thread |
WD40andTape | 7:5b6a2cefbf3b | 251 | threadSmoothPathPlan.start(CalculateSmoothPath); // Start planning thread |
WD40andTape | 7:5b6a2cefbf3b | 252 | |
WD40andTape | 7:5b6a2cefbf3b | 253 | PathCalculationTicker.attach(&startPathPlan, PATH_SAMPLE_TIME_S); // Set up planning thread to recur at fixed intervals |
dofydoink | 0:607bc887b6e0 | 254 | |
WD40andTape | 7:5b6a2cefbf3b | 255 | Thread::wait(1); |
WD40andTape | 1:2a43cf183a62 | 256 | while(1) { |
WD40andTape | 1:2a43cf183a62 | 257 | Thread::wait(osWaitForever); |
dofydoink | 0:607bc887b6e0 | 258 | } |
WD40andTape | 7:5b6a2cefbf3b | 259 | } |