Bachelor Assignment for delayed teleoperating systems

Dependencies:   EthernetInterface FastPWM mbed-rtos mbed MODSERIAL

Committer:
darth_bachious
Date:
Tue May 15 11:28:18 2018 +0000
Revision:
6:ccbbf4c77d35
Parent:
5:4d5b077b3fe6
Child:
7:984f363f5e87
Working switch functionality between systems, passivityfunction NOT working;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
darth_bachious 0:2f89dec3e2ab 1 #include "mbed.h"
darth_bachious 0:2f89dec3e2ab 2 #include "EthernetInterface.h"
darth_bachious 0:2f89dec3e2ab 3 #include "rtos.h"
darth_bachious 2:c27b0654cffd 4 #include <vector>
darth_bachious 5:4d5b077b3fe6 5 #include "FastPWM.h"
darth_bachious 6:ccbbf4c77d35 6 #include <cmath>
darth_bachious 0:2f89dec3e2ab 7
darth_bachious 1:853939e38acd 8 //Master or Slave? 1=Master, 0=Slave
darth_bachious 6:ccbbf4c77d35 9 static const int identity = 1;
darth_bachious 0:2f89dec3e2ab 10
darth_bachious 0:2f89dec3e2ab 11 //network config
darth_bachious 1:853939e38acd 12 static const char* master_ip = "192.168.1.101";
darth_bachious 1:853939e38acd 13 static const char* slave_ip = "192.168.1.102";
darth_bachious 1:853939e38acd 14 static const char* MASK = "255.255.255.0";
darth_bachious 1:853939e38acd 15 static const char* GATEWAY = "192.168.1.1";
darth_bachious 0:2f89dec3e2ab 16 static const int port = 865;
darth_bachious 0:2f89dec3e2ab 17
darth_bachious 0:2f89dec3e2ab 18 //declaration of interfaces
darth_bachious 0:2f89dec3e2ab 19 DigitalOut led(LED_GREEN);
darth_bachious 0:2f89dec3e2ab 20 DigitalOut led2(LED_RED);
darth_bachious 0:2f89dec3e2ab 21 EthernetInterface eth; //network
darth_bachious 0:2f89dec3e2ab 22 Serial pc(USBTX, USBRX);//create PC interface
darth_bachious 0:2f89dec3e2ab 23 UDPSocket socket; //socket to receive data on
darth_bachious 0:2f89dec3e2ab 24 Endpoint client; //The virtual other side, not to send actual information to
darth_bachious 0:2f89dec3e2ab 25 Endpoint counterpart; //The actual other side, this is where the information should go to
darth_bachious 6:ccbbf4c77d35 26 InterruptIn Button1(SW2);
darth_bachious 6:ccbbf4c77d35 27 InterruptIn Button2(SW3);
darth_bachious 5:4d5b077b3fe6 28 Ticker controllerloop;
darth_bachious 0:2f89dec3e2ab 29 Ticker mainloop;
darth_bachious 6:ccbbf4c77d35 30 DigitalOut debug(D11);
darth_bachious 0:2f89dec3e2ab 31
darth_bachious 4:610b5051182a 32 //Motor interfaces and variables
darth_bachious 3:376fccdc7cd6 33 InterruptIn EncoderA(D2);
darth_bachious 6:ccbbf4c77d35 34 DigitalIn EncoderB(D3);
darth_bachious 3:376fccdc7cd6 35 DigitalOut M1_DIR(D4);
darth_bachious 5:4d5b077b3fe6 36 FastPWM M1_pwm(D5);
darth_bachious 4:610b5051182a 37 AnalogIn measuredForce(A5);
darth_bachious 4:610b5051182a 38
darth_bachious 4:610b5051182a 39 //Low pass filter filter coeffs, 2nd order, 50 Hz
darth_bachious 4:610b5051182a 40 double b[3] = {0.020083365564211, 0.020083365564211*2, 0.020083365564211};
darth_bachious 4:610b5051182a 41 double a[3] = {1.00000000000000, -1.561018075, 0.64135153805};
darth_bachious 4:610b5051182a 42
darth_bachious 4:610b5051182a 43 //variables related to networking
darth_bachious 1:853939e38acd 44 char data[30]= {""};
darth_bachious 0:2f89dec3e2ab 45 int size;
darth_bachious 1:853939e38acd 46 int counter = 1;
darth_bachious 1:853939e38acd 47 int counter_received = 1;
darth_bachious 0:2f89dec3e2ab 48 char * var;
darth_bachious 1:853939e38acd 49 char output[30] = {""};
darth_bachious 2:c27b0654cffd 50 float input = 0.0;
darth_bachious 4:610b5051182a 51
darth_bachious 4:610b5051182a 52 //measured variables
darth_bachious 2:c27b0654cffd 53 float angle = 0.0;
darth_bachious 5:4d5b077b3fe6 54 int encoderPos = 0;
darth_bachious 5:4d5b077b3fe6 55 int prev_encoderPos = 0;
darth_bachious 4:610b5051182a 56 float encoder_vel = 0.0;
darth_bachious 4:610b5051182a 57 float motor_vel = 0.0;
darth_bachious 4:610b5051182a 58 float force = 0.0;
darth_bachious 5:4d5b077b3fe6 59 float control_torque = 0.0;
darth_bachious 6:ccbbf4c77d35 60 float force_offset = 0.5;
darth_bachious 3:376fccdc7cd6 61
darth_bachious 4:610b5051182a 62 //Reference, used in admittance
darth_bachious 4:610b5051182a 63 float ref_angle = 0.0;
darth_bachious 4:610b5051182a 64 float ref_vel = 0.0;
darth_bachious 4:610b5051182a 65 float ref_acc = 0.0;
darth_bachious 6:ccbbf4c77d35 66 const float virtualMass = 0.005;
darth_bachious 6:ccbbf4c77d35 67 const float virtualDamping = 0.05;
darth_bachious 4:610b5051182a 68 const float virtualStiffness = 5;
darth_bachious 6:ccbbf4c77d35 69 const float arm = 0.07;
darth_bachious 4:610b5051182a 70
darth_bachious 6:ccbbf4c77d35 71 //Controller required variables
darth_bachious 5:4d5b077b3fe6 72 bool controller_check = 0;
darth_bachious 5:4d5b077b3fe6 73 const float looptime = 1.0/50; //50Hz, for the controller
darth_bachious 5:4d5b077b3fe6 74 const float ADDMlooptime = 1.0/5000; //5KHz, for the admittance controller
darth_bachious 6:ccbbf4c77d35 75 enum States {stateCalibration, stateHoming, stateOperation};
darth_bachious 4:610b5051182a 76 int currentState = stateCalibration;
darth_bachious 6:ccbbf4c77d35 77 int transparancy = 1; // 1=Pos-Pos, 2=Pos-Force, 3=Force-Pos
darth_bachious 6:ccbbf4c77d35 78 int passivity =0; // 0=off, 1=on
darth_bachious 6:ccbbf4c77d35 79 int received_transparancy = 1;
darth_bachious 6:ccbbf4c77d35 80 int received_passivity = 0;
darth_bachious 4:610b5051182a 81
darth_bachious 4:610b5051182a 82 //Controller parameters
darth_bachious 5:4d5b077b3fe6 83 const float Ktl = 1; //high level controller parameters
darth_bachious 3:376fccdc7cd6 84 const float Dtl=0.1;
darth_bachious 4:610b5051182a 85 const float Kp = 5; //low level controller parameters
darth_bachious 4:610b5051182a 86 const float Dp = 0.05;
darth_bachious 6:ccbbf4c77d35 87 float u = 0.0; //serves as input variable for the motor;
darth_bachious 4:610b5051182a 88
darth_bachious 6:ccbbf4c77d35 89 //passivity layer constant
darth_bachious 6:ccbbf4c77d35 90 const float beta = 0.15;
darth_bachious 6:ccbbf4c77d35 91 const float Hd = 0.5;
darth_bachious 6:ccbbf4c77d35 92 const float alpha = 10;
darth_bachious 6:ccbbf4c77d35 93
darth_bachious 6:ccbbf4c77d35 94 //passivity layer variables
darth_bachious 6:ccbbf4c77d35 95 float tank = 0.0;
darth_bachious 6:ccbbf4c77d35 96 float prev_ref_angle = 0.0;
darth_bachious 6:ccbbf4c77d35 97 float package_out = 0.0;
darth_bachious 6:ccbbf4c77d35 98 float received_package = 0.0;
darth_bachious 6:ccbbf4c77d35 99 float prev_torque = 0.0;
darth_bachious 6:ccbbf4c77d35 100
darth_bachious 4:610b5051182a 101
darth_bachious 4:610b5051182a 102 //Constants
darth_bachious 0:2f89dec3e2ab 103 const float PI = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679;
darth_bachious 2:c27b0654cffd 104 const float RadsPerCount = (2 * PI)/(1024*10);
darth_bachious 4:610b5051182a 105 const float FORCESENSORGAIN = 15.134;
darth_bachious 4:610b5051182a 106 const int MAX_ENCODER_LEFT = 1333;
darth_bachious 4:610b5051182a 107 const int MAX_ENCODER_RIGHT = -1453;
darth_bachious 5:4d5b077b3fe6 108 const float WORKSPACEBOUND = PI/6;
darth_bachious 2:c27b0654cffd 109
darth_bachious 6:ccbbf4c77d35 110 const int frequency_pwm = 20000;
darth_bachious 0:2f89dec3e2ab 111
darth_bachious 4:610b5051182a 112 //Time delay related variables
darth_bachious 4:610b5051182a 113 float timedelay = 0.04; //SECONDS
darth_bachious 6:ccbbf4c77d35 114 int delaysteps = timedelay/looptime;
darth_bachious 6:ccbbf4c77d35 115 std::vector<float> delayArrayINPUT(max(delaysteps,1),0.0);
darth_bachious 6:ccbbf4c77d35 116 std::vector<float> delayArrayMODE(max(delaysteps,1),0.0);
darth_bachious 6:ccbbf4c77d35 117 std::vector<float> delayArrayPASS(max(delaysteps,1),0.0);
darth_bachious 6:ccbbf4c77d35 118 std::vector<float> delayArrayENERGY(max(delaysteps,1),0.0);
darth_bachious 4:610b5051182a 119 Timer t;
darth_bachious 4:610b5051182a 120
darth_bachious 3:376fccdc7cd6 121 //FUNCTIONS START HERE
darth_bachious 3:376fccdc7cd6 122
darth_bachious 3:376fccdc7cd6 123 void encoderFunctionA()
darth_bachious 3:376fccdc7cd6 124 {
darth_bachious 3:376fccdc7cd6 125 if ((bool)EncoderA == (bool)EncoderB) { //Increment or decrement encoder position during interrupt
darth_bachious 3:376fccdc7cd6 126 encoderPos++;
darth_bachious 3:376fccdc7cd6 127 } else {
darth_bachious 3:376fccdc7cd6 128 encoderPos--;
darth_bachious 3:376fccdc7cd6 129 }
darth_bachious 3:376fccdc7cd6 130 }
darth_bachious 4:610b5051182a 131 double velocityFilter(float x)
darth_bachious 4:610b5051182a 132 {
darth_bachious 4:610b5051182a 133 double y = 0.0; //Output
darth_bachious 4:610b5051182a 134 static double y_1 = 0.0; //Output last loop
darth_bachious 4:610b5051182a 135 static double y_2 = 0.0; //Output 2 loops ago
darth_bachious 4:610b5051182a 136 static double x_1 = 0.0; //Input last loop
darth_bachious 4:610b5051182a 137 static double x_2 = 0.0; //Input two loops ago
darth_bachious 3:376fccdc7cd6 138
darth_bachious 4:610b5051182a 139 //Finite difference equation for 2nd order Butterworth low-pass
darth_bachious 4:610b5051182a 140 y = -a[1]*y_1 - a[2]*y_2 + x*b[0] + x_1*b[1] + x_2*b[2];
darth_bachious 4:610b5051182a 141 y_2 = y_1;
darth_bachious 4:610b5051182a 142 y_1 = y;
darth_bachious 4:610b5051182a 143 x_2 = x_1;
darth_bachious 4:610b5051182a 144 x_1 = x;
darth_bachious 4:610b5051182a 145 return (float)y;
darth_bachious 4:610b5051182a 146 }
darth_bachious 0:2f89dec3e2ab 147
darth_bachious 0:2f89dec3e2ab 148 void inet_eth(){
darth_bachious 1:853939e38acd 149 if(identity==1)
darth_bachious 1:853939e38acd 150 {
darth_bachious 1:853939e38acd 151 eth.init(master_ip, MASK,GATEWAY);
darth_bachious 1:853939e38acd 152 eth.connect();
darth_bachious 0:2f89dec3e2ab 153
darth_bachious 1:853939e38acd 154 socket.bind(port);
darth_bachious 1:853939e38acd 155 counterpart.set_address(slave_ip,port);
darth_bachious 1:853939e38acd 156 }
darth_bachious 1:853939e38acd 157 else if(identity==0)
darth_bachious 1:853939e38acd 158 {
darth_bachious 1:853939e38acd 159 eth.init(slave_ip, MASK,GATEWAY);
darth_bachious 1:853939e38acd 160 eth.connect();
darth_bachious 1:853939e38acd 161
darth_bachious 1:853939e38acd 162 socket.bind(port);
darth_bachious 1:853939e38acd 163 counterpart.set_address(master_ip,port);
darth_bachious 1:853939e38acd 164 }
darth_bachious 1:853939e38acd 165
darth_bachious 0:2f89dec3e2ab 166 }
darth_bachious 0:2f89dec3e2ab 167
darth_bachious 0:2f89dec3e2ab 168 void inet_USB(){
darth_bachious 2:c27b0654cffd 169 pc.baud(115200);
darth_bachious 0:2f89dec3e2ab 170 }
darth_bachious 0:2f89dec3e2ab 171
darth_bachious 0:2f89dec3e2ab 172
darth_bachious 0:2f89dec3e2ab 173 void end_eth(){
darth_bachious 0:2f89dec3e2ab 174 socket.close();
darth_bachious 0:2f89dec3e2ab 175 eth.disconnect();
darth_bachious 0:2f89dec3e2ab 176 }
darth_bachious 0:2f89dec3e2ab 177
darth_bachious 5:4d5b077b3fe6 178 void controllertrigger()
darth_bachious 0:2f89dec3e2ab 179 {
darth_bachious 5:4d5b077b3fe6 180 controller_check = 1;
darth_bachious 0:2f89dec3e2ab 181 }
darth_bachious 2:c27b0654cffd 182
darth_bachious 4:610b5051182a 183
darth_bachious 2:c27b0654cffd 184 float update_delay(std::vector<float>&array, float new_value)
darth_bachious 2:c27b0654cffd 185 {
darth_bachious 3:376fccdc7cd6 186 float return_value = array[1];
darth_bachious 3:376fccdc7cd6 187 for (int i=0; i<array.size()-1; ++i)
darth_bachious 3:376fccdc7cd6 188 {
darth_bachious 3:376fccdc7cd6 189 array[i]=array[i+1];
darth_bachious 3:376fccdc7cd6 190 }
darth_bachious 3:376fccdc7cd6 191 array.back() = new_value;
darth_bachious 3:376fccdc7cd6 192 return return_value;
darth_bachious 3:376fccdc7cd6 193 }
darth_bachious 3:376fccdc7cd6 194
darth_bachious 3:376fccdc7cd6 195 void limit(float &x, float lower, float upper)
darth_bachious 3:376fccdc7cd6 196 {
darth_bachious 3:376fccdc7cd6 197 if (x > upper)
darth_bachious 3:376fccdc7cd6 198 x = upper;
darth_bachious 3:376fccdc7cd6 199 if (x < lower)
darth_bachious 3:376fccdc7cd6 200 x = lower;
darth_bachious 3:376fccdc7cd6 201 }
darth_bachious 3:376fccdc7cd6 202
darth_bachious 4:610b5051182a 203 void motor_update(float PWM) //angle required to safeguard it from crashing into its stops
darth_bachious 4:610b5051182a 204 {
darth_bachious 4:610b5051182a 205 limit(PWM,-1.0f,1.0f);
darth_bachious 4:610b5051182a 206 if(PWM >= 0.0f)
darth_bachious 4:610b5051182a 207 {
darth_bachious 4:610b5051182a 208 M1_DIR = false;
darth_bachious 4:610b5051182a 209 M1_pwm = PWM;
darth_bachious 4:610b5051182a 210 } else {
darth_bachious 4:610b5051182a 211 M1_DIR = true;
darth_bachious 4:610b5051182a 212 M1_pwm = -PWM;
darth_bachious 4:610b5051182a 213 }
darth_bachious 4:610b5051182a 214 }
darth_bachious 4:610b5051182a 215
darth_bachious 4:610b5051182a 216 void sensorUpdate()
darth_bachious 4:610b5051182a 217 {
darth_bachious 4:610b5051182a 218 angle = encoderPos * RadsPerCount;
darth_bachious 5:4d5b077b3fe6 219 encoder_vel = (encoderPos - prev_encoderPos)/ADDMlooptime; //careful, this function should be called every 1/5000 seconds
darth_bachious 4:610b5051182a 220 motor_vel = velocityFilter(encoder_vel * RadsPerCount);
darth_bachious 4:610b5051182a 221 prev_encoderPos = encoderPos;
darth_bachious 6:ccbbf4c77d35 222 force = -FORCESENSORGAIN*2.0f*(measuredForce - force_offset); //Measured force
darth_bachious 4:610b5051182a 223 }
darth_bachious 4:610b5051182a 224
darth_bachious 4:610b5051182a 225 void doCalibration()
darth_bachious 4:610b5051182a 226 {
darth_bachious 4:610b5051182a 227 u = 0.09;
darth_bachious 4:610b5051182a 228 motor_update(u);
darth_bachious 6:ccbbf4c77d35 229 led2=0;
darth_bachious 6:ccbbf4c77d35 230 led=1;
darth_bachious 4:610b5051182a 231 //switching states
darth_bachious 6:ccbbf4c77d35 232 if((abs(motor_vel)<0.001f)&& t.read()>3.0f)
darth_bachious 3:376fccdc7cd6 233 {
darth_bachious 4:610b5051182a 234 encoderPos = MAX_ENCODER_LEFT;
darth_bachious 4:610b5051182a 235 ref_angle = encoderPos * RadsPerCount;
darth_bachious 4:610b5051182a 236 currentState = stateHoming;
darth_bachious 4:610b5051182a 237 t.stop();
darth_bachious 4:610b5051182a 238 }
darth_bachious 4:610b5051182a 239 }
darth_bachious 4:610b5051182a 240
darth_bachious 4:610b5051182a 241 void doHoming()
darth_bachious 4:610b5051182a 242 {
darth_bachious 4:610b5051182a 243 led2=0;
darth_bachious 4:610b5051182a 244 led=0;
darth_bachious 4:610b5051182a 245 ref_vel = -0.2;
darth_bachious 6:ccbbf4c77d35 246 if(ref_angle > 0.0f)
darth_bachious 4:610b5051182a 247 {
darth_bachious 5:4d5b077b3fe6 248 ref_angle += ref_vel*ADDMlooptime; //careful, this function should be called every 1/50 seconds
darth_bachious 4:610b5051182a 249 }
darth_bachious 4:610b5051182a 250 else
darth_bachious 4:610b5051182a 251 {
darth_bachious 4:610b5051182a 252 ref_angle = 0.0;
darth_bachious 4:610b5051182a 253 ref_vel = 0.0;
darth_bachious 4:610b5051182a 254 }
darth_bachious 4:610b5051182a 255 u = Kp*(ref_angle - angle) + Dp*(ref_vel - motor_vel);
darth_bachious 4:610b5051182a 256 motor_update(u);
darth_bachious 4:610b5051182a 257
darth_bachious 4:610b5051182a 258 //switching states
darth_bachious 6:ccbbf4c77d35 259 if ((abs(encoderPos)<20)&&abs((ref_vel - motor_vel)<0.02f))
darth_bachious 4:610b5051182a 260 {
darth_bachious 4:610b5051182a 261 currentState = stateOperation;
darth_bachious 6:ccbbf4c77d35 262 force_offset = measuredForce;
darth_bachious 4:610b5051182a 263 motor_update(0.0);
darth_bachious 5:4d5b077b3fe6 264 led2=1;
darth_bachious 6:ccbbf4c77d35 265 led=1;
darth_bachious 4:610b5051182a 266 }
darth_bachious 3:376fccdc7cd6 267
darth_bachious 4:610b5051182a 268 }
darth_bachious 4:610b5051182a 269
darth_bachious 4:610b5051182a 270 void doOperation()
darth_bachious 4:610b5051182a 271 {
darth_bachious 5:4d5b077b3fe6 272 ref_acc = (force*arm + control_torque- virtualDamping*ref_vel)/virtualMass;
darth_bachious 5:4d5b077b3fe6 273 ref_vel += ref_acc*ADDMlooptime;
darth_bachious 5:4d5b077b3fe6 274 ref_angle += ref_vel*ADDMlooptime;
darth_bachious 5:4d5b077b3fe6 275 if(ref_angle > WORKSPACEBOUND)
darth_bachious 5:4d5b077b3fe6 276 {
darth_bachious 5:4d5b077b3fe6 277 ref_vel = 0.0;
darth_bachious 5:4d5b077b3fe6 278 ref_acc = 0.0;
darth_bachious 5:4d5b077b3fe6 279 ref_angle = WORKSPACEBOUND;
darth_bachious 5:4d5b077b3fe6 280 } else if(ref_angle < -WORKSPACEBOUND)
darth_bachious 5:4d5b077b3fe6 281 {
darth_bachious 5:4d5b077b3fe6 282 ref_vel = 0.0;
darth_bachious 5:4d5b077b3fe6 283 ref_acc = 0.0;
darth_bachious 5:4d5b077b3fe6 284 ref_angle = -WORKSPACEBOUND;
darth_bachious 5:4d5b077b3fe6 285 }
darth_bachious 5:4d5b077b3fe6 286 u = Kp*(ref_angle - angle) + Dp*(ref_vel - motor_vel);
darth_bachious 4:610b5051182a 287 motor_update(u);
darth_bachious 6:ccbbf4c77d35 288
darth_bachious 6:ccbbf4c77d35 289 //no switching states for now
darth_bachious 5:4d5b077b3fe6 290 }
darth_bachious 5:4d5b077b3fe6 291
darth_bachious 5:4d5b077b3fe6 292 void loopfunction()
darth_bachious 5:4d5b077b3fe6 293 {
darth_bachious 5:4d5b077b3fe6 294 sensorUpdate();
darth_bachious 5:4d5b077b3fe6 295 switch(currentState)
darth_bachious 5:4d5b077b3fe6 296 {
darth_bachious 5:4d5b077b3fe6 297 case stateCalibration:
darth_bachious 5:4d5b077b3fe6 298 doCalibration();
darth_bachious 5:4d5b077b3fe6 299 break;
darth_bachious 5:4d5b077b3fe6 300 case stateHoming:
darth_bachious 5:4d5b077b3fe6 301 doHoming();
darth_bachious 5:4d5b077b3fe6 302 break;
darth_bachious 5:4d5b077b3fe6 303 case stateOperation:
darth_bachious 5:4d5b077b3fe6 304 doOperation();
darth_bachious 5:4d5b077b3fe6 305 break;
darth_bachious 5:4d5b077b3fe6 306 }
darth_bachious 4:610b5051182a 307 }
darth_bachious 0:2f89dec3e2ab 308
darth_bachious 6:ccbbf4c77d35 309 void updateTransparency()
darth_bachious 6:ccbbf4c77d35 310 {
darth_bachious 6:ccbbf4c77d35 311 transparancy++;
darth_bachious 6:ccbbf4c77d35 312 if(transparancy>3)
darth_bachious 6:ccbbf4c77d35 313 transparancy = 1;
darth_bachious 6:ccbbf4c77d35 314 }
darth_bachious 6:ccbbf4c77d35 315
darth_bachious 6:ccbbf4c77d35 316 void updatePassivity()
darth_bachious 6:ccbbf4c77d35 317 {
darth_bachious 6:ccbbf4c77d35 318 passivity++;
darth_bachious 6:ccbbf4c77d35 319 if(passivity>1)
darth_bachious 6:ccbbf4c77d35 320 passivity = 0;
darth_bachious 6:ccbbf4c77d35 321 }
darth_bachious 6:ccbbf4c77d35 322
darth_bachious 6:ccbbf4c77d35 323 float passivityLayer(float Ftl, float E_in)
darth_bachious 6:ccbbf4c77d35 324 {
darth_bachious 6:ccbbf4c77d35 325 tank = tank + E_in - prev_torque*(ref_angle-prev_ref_angle);
darth_bachious 6:ccbbf4c77d35 326 if(tank>0.0f)
darth_bachious 6:ccbbf4c77d35 327 {
darth_bachious 6:ccbbf4c77d35 328 package_out = tank*beta;
darth_bachious 6:ccbbf4c77d35 329 tank = tank - package_out;
darth_bachious 6:ccbbf4c77d35 330 } else
darth_bachious 6:ccbbf4c77d35 331 package_out = 0.0;
darth_bachious 6:ccbbf4c77d35 332
darth_bachious 6:ccbbf4c77d35 333 float FMAX1 = 0.0;
darth_bachious 6:ccbbf4c77d35 334 if(tank>0.0f)
darth_bachious 6:ccbbf4c77d35 335 {
darth_bachious 6:ccbbf4c77d35 336 float FMAX1 = abs(Ftl);
darth_bachious 6:ccbbf4c77d35 337 }
darth_bachious 6:ccbbf4c77d35 338 float FMAX2 = abs(tank/(ref_vel*looptime));
darth_bachious 6:ccbbf4c77d35 339
darth_bachious 6:ccbbf4c77d35 340 float FMAX3 = 0.15;
darth_bachious 6:ccbbf4c77d35 341
darth_bachious 6:ccbbf4c77d35 342 prev_ref_angle = ref_angle;
darth_bachious 6:ccbbf4c77d35 343
darth_bachious 6:ccbbf4c77d35 344 float Ftlc = 0.0;
darth_bachious 6:ccbbf4c77d35 345
darth_bachious 6:ccbbf4c77d35 346 if((tank<Hd)&&(identity==1))
darth_bachious 6:ccbbf4c77d35 347 {
darth_bachious 6:ccbbf4c77d35 348 Ftlc = - alpha*(Hd-tank)*ref_vel;
darth_bachious 6:ccbbf4c77d35 349 }
darth_bachious 6:ccbbf4c77d35 350 //pc.printf("Ftlc: %f\r\n",Ftlc);
darth_bachious 6:ccbbf4c77d35 351 //pc.printf("tank: %f\r\n",tank);
darth_bachious 6:ccbbf4c77d35 352 if(Ftl>=0.0f)
darth_bachious 6:ccbbf4c77d35 353 {
darth_bachious 6:ccbbf4c77d35 354 prev_torque = min(min(abs(Ftl),FMAX1),min(FMAX2,FMAX3))+Ftlc;
darth_bachious 6:ccbbf4c77d35 355 return min(min(abs(Ftl),FMAX1),min(FMAX2,FMAX3))+Ftlc; //min() only takes to arguments, so nested min()'s
darth_bachious 6:ccbbf4c77d35 356 }
darth_bachious 6:ccbbf4c77d35 357 else
darth_bachious 6:ccbbf4c77d35 358 {
darth_bachious 6:ccbbf4c77d35 359 prev_torque = -min(min(abs(Ftl),FMAX1),min(FMAX2,FMAX3))-Ftlc;
darth_bachious 6:ccbbf4c77d35 360 return -min(min(abs(Ftl),FMAX1),min(FMAX2,FMAX3))-Ftlc;
darth_bachious 6:ccbbf4c77d35 361 }
darth_bachious 6:ccbbf4c77d35 362
darth_bachious 6:ccbbf4c77d35 363 }
darth_bachious 6:ccbbf4c77d35 364
darth_bachious 0:2f89dec3e2ab 365 void receiveUDP(void const *argument){
darth_bachious 4:610b5051182a 366 while(true)
darth_bachious 4:610b5051182a 367 {
darth_bachious 0:2f89dec3e2ab 368 size = socket.receiveFrom(client, data, sizeof(data));
darth_bachious 4:610b5051182a 369 if(size > 0)
darth_bachious 4:610b5051182a 370 {
darth_bachious 0:2f89dec3e2ab 371 data[size] = '\0';
darth_bachious 6:ccbbf4c77d35 372 pc.printf("data:%s\r\n",data);
darth_bachious 2:c27b0654cffd 373 if(size>5) //first check, an minimum amount of data must have arrived
darth_bachious 4:610b5051182a 374 {
darth_bachious 2:c27b0654cffd 375 var = strtok(data,"; ");
darth_bachious 2:c27b0654cffd 376 if(counter_received < atof(var)) //second check, data must be newer
darth_bachious 4:610b5051182a 377 {
darth_bachious 2:c27b0654cffd 378 counter_received = atof(var);
darth_bachious 2:c27b0654cffd 379 var = strtok(NULL,"; ");
darth_bachious 6:ccbbf4c77d35 380 received_transparancy = atof(var);
darth_bachious 6:ccbbf4c77d35 381 var = strtok(NULL,"; ");
darth_bachious 6:ccbbf4c77d35 382 received_passivity = atof(var);
darth_bachious 6:ccbbf4c77d35 383 var = strtok(NULL,"; ");
darth_bachious 2:c27b0654cffd 384 input = atof(var);
darth_bachious 6:ccbbf4c77d35 385 var = strtok(NULL,"; ");
darth_bachious 6:ccbbf4c77d35 386 received_package += atof(var);
darth_bachious 4:610b5051182a 387 }
darth_bachious 0:2f89dec3e2ab 388 }
darth_bachious 0:2f89dec3e2ab 389 }
darth_bachious 0:2f89dec3e2ab 390 }
darth_bachious 4:610b5051182a 391 }
darth_bachious 0:2f89dec3e2ab 392
darth_bachious 0:2f89dec3e2ab 393 osThreadDef(receiveUDP, osPriorityNormal, DEFAULT_STACK_SIZE);
darth_bachious 0:2f89dec3e2ab 394
darth_bachious 0:2f89dec3e2ab 395 int main(){
darth_bachious 1:853939e38acd 396 inet_eth();
darth_bachious 0:2f89dec3e2ab 397 inet_USB();
darth_bachious 0:2f89dec3e2ab 398
darth_bachious 0:2f89dec3e2ab 399 osThreadCreate(osThread(receiveUDP), NULL);
darth_bachious 0:2f89dec3e2ab 400 led2=1;
darth_bachious 0:2f89dec3e2ab 401 led=1;
darth_bachious 5:4d5b077b3fe6 402
darth_bachious 6:ccbbf4c77d35 403 //Set all interrupt requests to 2nd place priority
darth_bachious 5:4d5b077b3fe6 404 for(int n = 0; n < 86; n++) {
darth_bachious 5:4d5b077b3fe6 405 NVIC_SetPriority((IRQn)n,1);
darth_bachious 5:4d5b077b3fe6 406 }
darth_bachious 5:4d5b077b3fe6 407 //Set out motor encoder interrupt to 1st place priority
darth_bachious 5:4d5b077b3fe6 408 NVIC_SetPriority(PORTB_IRQn,0);
darth_bachious 6:ccbbf4c77d35 409
darth_bachious 5:4d5b077b3fe6 410 controllerloop.attach(&controllertrigger,looptime);
darth_bachious 5:4d5b077b3fe6 411 mainloop.attach(&loopfunction,ADDMlooptime);
darth_bachious 5:4d5b077b3fe6 412
darth_bachious 4:610b5051182a 413 M1_pwm.period(1.0/frequency_pwm);
darth_bachious 4:610b5051182a 414 EncoderA.rise(&encoderFunctionA);
darth_bachious 0:2f89dec3e2ab 415
darth_bachious 6:ccbbf4c77d35 416 Button1.fall(&updateTransparency);
darth_bachious 6:ccbbf4c77d35 417 Button2.fall(&updatePassivity);
darth_bachious 6:ccbbf4c77d35 418
darth_bachious 4:610b5051182a 419 t.start();
darth_bachious 3:376fccdc7cd6 420
darth_bachious 0:2f89dec3e2ab 421 while(true){
darth_bachious 5:4d5b077b3fe6 422 if(controller_check==1){
darth_bachious 6:ccbbf4c77d35 423 debug = 1;
darth_bachious 6:ccbbf4c77d35 424 float received_input = update_delay(delayArrayINPUT,input);
darth_bachious 6:ccbbf4c77d35 425 float current_transparancy = update_delay(delayArrayMODE,received_transparancy);
darth_bachious 6:ccbbf4c77d35 426 float current_passivity = update_delay(delayArrayPASS,received_passivity);
darth_bachious 6:ccbbf4c77d35 427 float package_in = update_delay(delayArrayENERGY,received_package);
darth_bachious 6:ccbbf4c77d35 428 received_package = 0; //IMPORTANT, WILL EXPLODE OTHERWISE
darth_bachious 3:376fccdc7cd6 429
darth_bachious 6:ccbbf4c77d35 430 if(identity==0)
darth_bachious 6:ccbbf4c77d35 431 {
darth_bachious 6:ccbbf4c77d35 432 transparancy = current_transparancy;
darth_bachious 6:ccbbf4c77d35 433 passivity = current_passivity;
darth_bachious 6:ccbbf4c77d35 434 if(transparancy==1)
darth_bachious 6:ccbbf4c77d35 435 {
darth_bachious 6:ccbbf4c77d35 436 float torque_tlc = Ktl*(received_input-ref_angle) - Dtl*ref_vel;
darth_bachious 6:ccbbf4c77d35 437 if(current_passivity==1)
darth_bachious 6:ccbbf4c77d35 438 control_torque = passivityLayer(torque_tlc,package_in);
darth_bachious 6:ccbbf4c77d35 439 else
darth_bachious 6:ccbbf4c77d35 440 control_torque = torque_tlc;
darth_bachious 6:ccbbf4c77d35 441 sprintf(output,"%i;%i;%i;%f;%f",counter,transparancy,passivity,ref_angle,package_out);
darth_bachious 6:ccbbf4c77d35 442 }
darth_bachious 6:ccbbf4c77d35 443 else if(transparancy==2)
darth_bachious 6:ccbbf4c77d35 444 {
darth_bachious 6:ccbbf4c77d35 445 float torque_tlc = Ktl*(received_input-ref_angle) - Dtl*ref_vel;
darth_bachious 6:ccbbf4c77d35 446 if(current_passivity==1)
darth_bachious 6:ccbbf4c77d35 447 control_torque = passivityLayer(torque_tlc,package_in);
darth_bachious 6:ccbbf4c77d35 448 else
darth_bachious 6:ccbbf4c77d35 449 control_torque = torque_tlc;
darth_bachious 6:ccbbf4c77d35 450 sprintf(output,"%i;%i;%i;%f;%f",counter,transparancy,passivity,force,package_out);
darth_bachious 6:ccbbf4c77d35 451 }
darth_bachious 6:ccbbf4c77d35 452 else if(transparancy==3)
darth_bachious 6:ccbbf4c77d35 453 {
darth_bachious 6:ccbbf4c77d35 454 float torque_tlc = received_input*arm;
darth_bachious 6:ccbbf4c77d35 455 if(current_passivity==1)
darth_bachious 6:ccbbf4c77d35 456 control_torque = passivityLayer(torque_tlc,package_in);
darth_bachious 6:ccbbf4c77d35 457 else
darth_bachious 6:ccbbf4c77d35 458 control_torque = torque_tlc;
darth_bachious 6:ccbbf4c77d35 459 sprintf(output,"%i;%i;%i;%f;%f",counter,transparancy,passivity,ref_angle,package_out);
darth_bachious 6:ccbbf4c77d35 460 }
darth_bachious 6:ccbbf4c77d35 461 }
darth_bachious 6:ccbbf4c77d35 462 else if(identity == 1)
darth_bachious 6:ccbbf4c77d35 463 {
darth_bachious 6:ccbbf4c77d35 464 if(transparancy==1)
darth_bachious 6:ccbbf4c77d35 465 {
darth_bachious 6:ccbbf4c77d35 466 float torque_tlc = Ktl*(received_input-ref_angle) - Dtl*ref_vel;
darth_bachious 6:ccbbf4c77d35 467 if(current_passivity==1)
darth_bachious 6:ccbbf4c77d35 468 control_torque = passivityLayer(torque_tlc,package_in);
darth_bachious 6:ccbbf4c77d35 469 else
darth_bachious 6:ccbbf4c77d35 470 control_torque = torque_tlc;
darth_bachious 6:ccbbf4c77d35 471 sprintf(output,"%i;%i;%i;%f;%f",counter,transparancy,passivity,ref_angle,package_out);
darth_bachious 6:ccbbf4c77d35 472 }
darth_bachious 6:ccbbf4c77d35 473 else if(transparancy==2)
darth_bachious 6:ccbbf4c77d35 474 {
darth_bachious 6:ccbbf4c77d35 475 float torque_tlc = received_input*arm;
darth_bachious 6:ccbbf4c77d35 476 if(current_passivity==1)
darth_bachious 6:ccbbf4c77d35 477 control_torque = passivityLayer(torque_tlc,package_in);
darth_bachious 6:ccbbf4c77d35 478 else
darth_bachious 6:ccbbf4c77d35 479 control_torque = torque_tlc;
darth_bachious 6:ccbbf4c77d35 480 sprintf(output,"%i;%i;%i;%f;%f",counter,transparancy,passivity,ref_angle,package_out);
darth_bachious 6:ccbbf4c77d35 481 }
darth_bachious 6:ccbbf4c77d35 482 else if(transparancy==3)
darth_bachious 6:ccbbf4c77d35 483 {
darth_bachious 6:ccbbf4c77d35 484 float torque_tlc = Ktl*(received_input-ref_angle) - Dtl*ref_vel;
darth_bachious 6:ccbbf4c77d35 485 if(current_passivity==1)
darth_bachious 6:ccbbf4c77d35 486 control_torque = passivityLayer(torque_tlc,package_in);
darth_bachious 6:ccbbf4c77d35 487 else
darth_bachious 6:ccbbf4c77d35 488 control_torque = torque_tlc;
darth_bachious 6:ccbbf4c77d35 489 sprintf(output,"%i;%i;%i;%f;%f",counter,transparancy,passivity,force,package_out);
darth_bachious 6:ccbbf4c77d35 490 }
darth_bachious 6:ccbbf4c77d35 491 }
darth_bachious 6:ccbbf4c77d35 492
darth_bachious 5:4d5b077b3fe6 493 socket.sendTo(counterpart, output, sizeof(output));
darth_bachious 5:4d5b077b3fe6 494 counter ++;
darth_bachious 6:ccbbf4c77d35 495 led=!led;
darth_bachious 6:ccbbf4c77d35 496 if(current_passivity==1)
darth_bachious 6:ccbbf4c77d35 497 led2=0;
darth_bachious 6:ccbbf4c77d35 498 else
darth_bachious 6:ccbbf4c77d35 499 led2=1;
darth_bachious 5:4d5b077b3fe6 500 controller_check = 0;
darth_bachious 6:ccbbf4c77d35 501 debug = 0;
darth_bachious 0:2f89dec3e2ab 502 }
darth_bachious 4:610b5051182a 503 osDelay(0.1); //this might be the most ugliest piece of code that somehow still works. BK
darth_bachious 0:2f89dec3e2ab 504 }
darth_bachious 0:2f89dec3e2ab 505 }