2.74 Jerboa Robot Code

Dependencies:   EthernetInterface ExperimentServer QEI_pmw experiment_example mbed-rtos mbed

Fork of experiment_example by Patrick Wensing

Committer:
mchoun95
Date:
Tue Dec 05 02:37:28 2017 +0000
Revision:
3:3c00f1332d9b
Parent:
1:95a7fddd25a9
2.74 Jerboa Robot Code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pwensing 0:43448bf056e8 1 #include "mbed.h"
pwensing 0:43448bf056e8 2 #include "rtos.h"
pwensing 0:43448bf056e8 3 #include "EthernetInterface.h"
pwensing 0:43448bf056e8 4 #include "ExperimentServer.h"
pwensing 0:43448bf056e8 5 #include "QEI.h"
pwensing 0:43448bf056e8 6
mchoun95 3:3c00f1332d9b 7 #define NUM_INPUTS 10
mchoun95 3:3c00f1332d9b 8 #define NUM_OUTPUTS 9
pwensing 0:43448bf056e8 9
mchoun95 3:3c00f1332d9b 10 //leg 50 deg
mchoun95 3:3c00f1332d9b 11 //tail 45 deg
mchoun95 3:3c00f1332d9b 12
mchoun95 3:3c00f1332d9b 13 Ticker control;
pwensing 0:43448bf056e8 14 Serial pc(USBTX, USBRX); // USB Serial Terminal
pwensing 0:43448bf056e8 15 ExperimentServer server; // Object that lets us communicate with MATLAB
mchoun95 3:3c00f1332d9b 16
mchoun95 3:3c00f1332d9b 17 // Tail Motor Control Pins
mchoun95 3:3c00f1332d9b 18 PwmOut tailPWM(D5); // Tail motor PWM output
mchoun95 3:3c00f1332d9b 19 DigitalOut tailFwd(D6); // Tail motor forward enable
mchoun95 3:3c00f1332d9b 20 DigitalOut tailRev(D7); // Tail motor backward enable
mchoun95 3:3c00f1332d9b 21
mchoun95 3:3c00f1332d9b 22 // Leg Motor Control Pins
mchoun95 3:3c00f1332d9b 23 PwmOut legPWM(D11); // Leg motor PWM output
mchoun95 3:3c00f1332d9b 24 DigitalOut legFwd(D10); // Leg motor forward enable
mchoun95 3:3c00f1332d9b 25 DigitalOut legRev(D9); // Leg motor backward enable
mchoun95 3:3c00f1332d9b 26
mchoun95 3:3c00f1332d9b 27 Timer t; // Timer to measure elapsed time of experiment
mchoun95 3:3c00f1332d9b 28 float time_ = 0.0; // time variable
mchoun95 3:3c00f1332d9b 29 float tfinal = 20;
mchoun95 3:3c00f1332d9b 30
mchoun95 3:3c00f1332d9b 31 // Motor current sensors
mchoun95 3:3c00f1332d9b 32 AnalogIn tailCurrent(A0); // Tail current sensor
mchoun95 3:3c00f1332d9b 33 AnalogIn legCurrent(A1); // Leg current sensor
mchoun95 3:3c00f1332d9b 34
mchoun95 3:3c00f1332d9b 35 // Motor Encoders
mchoun95 3:3c00f1332d9b 36 QEI tailEncoder(D1 ,D2 ,NC ,1200, QEI::X4_ENCODING); // Tail encoder
mchoun95 3:3c00f1332d9b 37 QEI legEncoder(D3 ,D4 ,NC ,1200, QEI::X4_ENCODING); // Leg encoder
mchoun95 3:3c00f1332d9b 38
mchoun95 3:3c00f1332d9b 39 // Physical motor parameters
mchoun95 3:3c00f1332d9b 40 float R = 2.79; // Estimated motor resistance from lab
mchoun95 3:3c00f1332d9b 41 float Kb = .1603; // Estimated motor torque constant measured from lab
mchoun95 3:3c00f1332d9b 42 float Kcurrent = 1.5; // Proportional gain of the current control
mchoun95 3:3c00f1332d9b 43 float v = 0.01; // BackEMF constant
mchoun95 3:3c00f1332d9b 44
mchoun95 3:3c00f1332d9b 45
mchoun95 3:3c00f1332d9b 46 // Matlab inputs/Control variables
mchoun95 3:3c00f1332d9b 47 float tailCmd = 0.0; // Commanded angle (Rads) for the tail
mchoun95 3:3c00f1332d9b 48 float legCmd = 0.0; // Commanded angle (Rads) for the leg
mchoun95 3:3c00f1332d9b 49 float tailt0 = 0.0; // Initial angle (Rads)
mchoun95 3:3c00f1332d9b 50 float legt0 = 0.0; // Initial angle (Rads)
mchoun95 3:3c00f1332d9b 51 float Kptail = 0.0; // Tail proportional gain of position control
mchoun95 3:3c00f1332d9b 52 float Kpleg = 0.0; // Leg proportional gain of position control
mchoun95 3:3c00f1332d9b 53 float Kdtail = 0.0; // Tail derivative gain of position control
mchoun95 3:3c00f1332d9b 54 float Kdleg = 0.0; // Leg derivative gain for position control
mchoun95 3:3c00f1332d9b 55
mchoun95 3:3c00f1332d9b 56 // State varibles/sensed parameters
mchoun95 3:3c00f1332d9b 57 float idtail = 0.0; // Tail desired current
mchoun95 3:3c00f1332d9b 58 float idleg = 0.0; // Leg desired current
mchoun95 3:3c00f1332d9b 59 float taild = 0.0; // Desired angle (Rads) for the tail
mchoun95 3:3c00f1332d9b 60 float legd = 0.0; // Desired angle (Rads) for the leg
mchoun95 3:3c00f1332d9b 61 float wtail = 0.0; // Measured angular velocity of the tail
mchoun95 3:3c00f1332d9b 62 float wleg = 0.0; // Measured angular velocity of the leg
mchoun95 3:3c00f1332d9b 63 float ttail = 0.0; // Measured angular position of the tail
mchoun95 3:3c00f1332d9b 64 float tleg = 0.0; // Measured angular position of the leg
mchoun95 3:3c00f1332d9b 65 float itail = 0.0; // Current sensed in the tail motor
mchoun95 3:3c00f1332d9b 66 float ileg = 0.0; // Current sensed in the leg motor
mchoun95 3:3c00f1332d9b 67 float vctail = 0.0; // Tail voltage command
mchoun95 3:3c00f1332d9b 68 float vcleg = 0.0; // Leg voltage command
mchoun95 3:3c00f1332d9b 69
mchoun95 3:3c00f1332d9b 70 // Error terms
mchoun95 3:3c00f1332d9b 71 float etail = 0.0; // Error term for tail
mchoun95 3:3c00f1332d9b 72 float eleg = 0.0; // Error term for leg
mchoun95 3:3c00f1332d9b 73 float eptail = 0.0; // Previous error term for tail
mchoun95 3:3c00f1332d9b 74 float epleg = 0.0; // Previous error term for leg
mchoun95 3:3c00f1332d9b 75 float edtail = 0.0; // Derivative error term for tail
mchoun95 3:3c00f1332d9b 76 float edleg = 0.0; // Derivative error term for leg
mchoun95 3:3c00f1332d9b 77
mchoun95 3:3c00f1332d9b 78 float max_cmd = 1.0;
mchoun95 3:3c00f1332d9b 79
mchoun95 3:3c00f1332d9b 80 bool new_data = false;
mchoun95 3:3c00f1332d9b 81 bool end = false;
mchoun95 3:3c00f1332d9b 82
pwensing 0:43448bf056e8 83
mchoun95 3:3c00f1332d9b 84 void control_loop() {
mchoun95 3:3c00f1332d9b 85 if (end){
mchoun95 3:3c00f1332d9b 86 tailPWM.write(0);
mchoun95 3:3c00f1332d9b 87 legPWM.write(0);
mchoun95 3:3c00f1332d9b 88 }
mchoun95 3:3c00f1332d9b 89 else{
mchoun95 3:3c00f1332d9b 90 //Sensing
mchoun95 3:3c00f1332d9b 91 itail = (tailCurrent.read()-.5)*36.7; // Tail current
mchoun95 3:3c00f1332d9b 92 ileg = (legCurrent.read()-.5)*36.7; // Leg current
mchoun95 3:3c00f1332d9b 93 ttail = tailEncoder.getPulses()/1200.0*2*3.14159 + tailt0; // Leg angle
mchoun95 3:3c00f1332d9b 94 tleg = legEncoder.getPulses()/1200.0*2*3.14159 + legt0; // Leg angle
mchoun95 3:3c00f1332d9b 95 wtail = tailEncoder.getVelocity()*2*3.14159/1200.0; // Tail angular velocity
mchoun95 3:3c00f1332d9b 96 wleg = legEncoder.getVelocity()*2*3.14159/1200.0; // Leg angular velocity
mchoun95 3:3c00f1332d9b 97 time_ = t.read();
mchoun95 3:3c00f1332d9b 98
mchoun95 3:3c00f1332d9b 99 // Error update
mchoun95 3:3c00f1332d9b 100 etail = taild - ttail; // Error in tail's angle position
mchoun95 3:3c00f1332d9b 101 eleg = legd - tleg; // Error in leg's angle position
mchoun95 3:3c00f1332d9b 102 edtail = (etail - eptail)/.001; // Rate of change in tail's error
mchoun95 3:3c00f1332d9b 103 edleg = (eleg - epleg)/.001; // Rate of change in leg's error
mchoun95 3:3c00f1332d9b 104 eptail = etail; // Update previous tail error
mchoun95 3:3c00f1332d9b 105 epleg = eleg; // Update previous leg error
mchoun95 3:3c00f1332d9b 106
mchoun95 3:3c00f1332d9b 107 // Perform control loop logic
mchoun95 3:3c00f1332d9b 108 idtail = (Kptail*etail + Kdtail*edtail + v*wtail) / Kb; // Tail position control
mchoun95 3:3c00f1332d9b 109 idleg = (Kpleg*eleg + Kdleg*edleg + v*wleg) / Kb; // Leg position control
mchoun95 3:3c00f1332d9b 110
mchoun95 3:3c00f1332d9b 111 vctail = (R*idtail + Kcurrent * (idtail - itail) - Kb * wtail) / 24.0; // Tail current control
mchoun95 3:3c00f1332d9b 112 vcleg = (R*idleg + Kcurrent * (idleg - ileg) - Kb * wleg) / 24.0; // Leg current control
mchoun95 3:3c00f1332d9b 113
mchoun95 3:3c00f1332d9b 114 // Tail set command
mchoun95 3:3c00f1332d9b 115 if (vctail < 0){
mchoun95 3:3c00f1332d9b 116 tailFwd = 1;
mchoun95 3:3c00f1332d9b 117 tailRev = 0;
mchoun95 3:3c00f1332d9b 118 if (abs(vctail) > 1){
mchoun95 3:3c00f1332d9b 119 vctail = -1;
mchoun95 3:3c00f1332d9b 120 }
mchoun95 3:3c00f1332d9b 121 tailPWM.write(max_cmd*abs(vctail));
mchoun95 3:3c00f1332d9b 122 }else if (vctail > 0){
mchoun95 3:3c00f1332d9b 123 tailFwd = 0;
mchoun95 3:3c00f1332d9b 124 tailRev = 1;
mchoun95 3:3c00f1332d9b 125 if (abs(vctail) > 1){
mchoun95 3:3c00f1332d9b 126 vctail = 1;
mchoun95 3:3c00f1332d9b 127 }
mchoun95 3:3c00f1332d9b 128 tailPWM.write(max_cmd*abs(vctail));
mchoun95 3:3c00f1332d9b 129 } else {
mchoun95 3:3c00f1332d9b 130 tailPWM.write(0);
mchoun95 3:3c00f1332d9b 131 }
mchoun95 3:3c00f1332d9b 132
mchoun95 3:3c00f1332d9b 133 // Leg set command
mchoun95 3:3c00f1332d9b 134 if (vcleg < 0){
mchoun95 3:3c00f1332d9b 135 legFwd = 1;
mchoun95 3:3c00f1332d9b 136 legRev = 0;
mchoun95 3:3c00f1332d9b 137 if (abs(vcleg) > 1){
mchoun95 3:3c00f1332d9b 138 vcleg = -1;
mchoun95 3:3c00f1332d9b 139 }
mchoun95 3:3c00f1332d9b 140 legPWM.write(max_cmd*abs(vcleg));
mchoun95 3:3c00f1332d9b 141 }else if (vcleg > 0){
mchoun95 3:3c00f1332d9b 142 legFwd = 0;
mchoun95 3:3c00f1332d9b 143 legRev = 1;
mchoun95 3:3c00f1332d9b 144 if (abs(vcleg) > 1){
mchoun95 3:3c00f1332d9b 145 vcleg = 1;
mchoun95 3:3c00f1332d9b 146 }
mchoun95 3:3c00f1332d9b 147 legPWM.write(max_cmd*abs(vcleg));
mchoun95 3:3c00f1332d9b 148 } else {
mchoun95 3:3c00f1332d9b 149 legPWM.write(0);
mchoun95 3:3c00f1332d9b 150 }
mchoun95 3:3c00f1332d9b 151 new_data = true;
mchoun95 3:3c00f1332d9b 152 }
mchoun95 3:3c00f1332d9b 153 }
pwensing 0:43448bf056e8 154
pwensing 0:43448bf056e8 155 int main (void) {
pwensing 0:43448bf056e8 156 // Link the terminal with our server and start it up
pwensing 0:43448bf056e8 157 server.attachTerminal(pc);
pwensing 0:43448bf056e8 158 server.init();
pwensing 0:43448bf056e8 159
Patrick Wensing 1:95a7fddd25a9 160 // PWM period should nominally be a multiple of our control loop
mchoun95 3:3c00f1332d9b 161 tailPWM.period_us(500);
mchoun95 3:3c00f1332d9b 162 legPWM.period_us(500);
pwensing 0:43448bf056e8 163
pwensing 0:43448bf056e8 164 // Continually get input from MATLAB and run experiments
pwensing 0:43448bf056e8 165 float input_params[NUM_INPUTS];
mchoun95 3:3c00f1332d9b 166 control.attach(&control_loop, .001);
mchoun95 3:3c00f1332d9b 167
pwensing 0:43448bf056e8 168
pwensing 0:43448bf056e8 169 while(1) {
pwensing 0:43448bf056e8 170 if (server.getParams(input_params,NUM_INPUTS)) {
mchoun95 3:3c00f1332d9b 171 tailCmd = input_params[0]; // Desired angle (Rads) for the tail
mchoun95 3:3c00f1332d9b 172 legCmd = input_params[1]; // Desired angle (Rads) for the leg
mchoun95 3:3c00f1332d9b 173 tailt0 = input_params[2]; // Initial angle (Rads)
mchoun95 3:3c00f1332d9b 174 legt0 = input_params[3]; // Initial angle (Rads)
mchoun95 3:3c00f1332d9b 175 Kptail = input_params[4]; // Tail proportional gain of position control
mchoun95 3:3c00f1332d9b 176 Kpleg = input_params[5]; // Leg proportional gain of position control
mchoun95 3:3c00f1332d9b 177 Kdtail = input_params[6]; // Tail derivative gain of position control
mchoun95 3:3c00f1332d9b 178 Kdleg = input_params[7]; // Leg derivative gain for position control
mchoun95 3:3c00f1332d9b 179 max_cmd = input_params[8]; // cmd thresholder
mchoun95 3:3c00f1332d9b 180 tfinal = input_params[9];
mchoun95 3:3c00f1332d9b 181
mchoun95 3:3c00f1332d9b 182 if (max_cmd > 1.0 || max_cmd < 0){
mchoun95 3:3c00f1332d9b 183 max_cmd = 1.0;
mchoun95 3:3c00f1332d9b 184 }
pwensing 0:43448bf056e8 185 // Setup experiment
pwensing 0:43448bf056e8 186 t.reset();
pwensing 0:43448bf056e8 187 t.start();
mchoun95 3:3c00f1332d9b 188 end = false;
mchoun95 3:3c00f1332d9b 189
mchoun95 3:3c00f1332d9b 190 // Reset the encoders
mchoun95 3:3c00f1332d9b 191 tailEncoder.reset();
mchoun95 3:3c00f1332d9b 192 legEncoder.reset();
mchoun95 3:3c00f1332d9b 193
mchoun95 3:3c00f1332d9b 194 // Default forward rotation
mchoun95 3:3c00f1332d9b 195 tailFwd = 1;
mchoun95 3:3c00f1332d9b 196 tailRev = 0;
mchoun95 3:3c00f1332d9b 197 legFwd = 1;
mchoun95 3:3c00f1332d9b 198 legRev = 0;
mchoun95 3:3c00f1332d9b 199
mchoun95 3:3c00f1332d9b 200 // Stop the motors
mchoun95 3:3c00f1332d9b 201 tailPWM.write(0);
mchoun95 3:3c00f1332d9b 202 legPWM.write(0);
mchoun95 3:3c00f1332d9b 203
pwensing 0:43448bf056e8 204 // Run experiment
mchoun95 3:3c00f1332d9b 205 while( t.read() < tfinal) {
mchoun95 3:3c00f1332d9b 206 // Set desired parameters at specific times
mchoun95 3:3c00f1332d9b 207 if(t.read()<5){
mchoun95 3:3c00f1332d9b 208 taild = tailt0;
mchoun95 3:3c00f1332d9b 209 legd = legt0;
mchoun95 3:3c00f1332d9b 210 }else{
mchoun95 3:3c00f1332d9b 211 taild = tailCmd;
mchoun95 3:3c00f1332d9b 212 legd = legCmd;
mchoun95 3:3c00f1332d9b 213 }
mchoun95 3:3c00f1332d9b 214
pwensing 0:43448bf056e8 215 // Send data to MATLAB
mchoun95 3:3c00f1332d9b 216 if(new_data) {
mchoun95 3:3c00f1332d9b 217 // Form output to send to MATLAB
mchoun95 3:3c00f1332d9b 218 float output_data[NUM_OUTPUTS];
mchoun95 3:3c00f1332d9b 219 output_data[0] = time_;
mchoun95 3:3c00f1332d9b 220 output_data[1] = vctail;
mchoun95 3:3c00f1332d9b 221 output_data[2] = vcleg;
mchoun95 3:3c00f1332d9b 222 output_data[3] = itail;
mchoun95 3:3c00f1332d9b 223 output_data[4] = ileg;
mchoun95 3:3c00f1332d9b 224 output_data[5] = ttail;
mchoun95 3:3c00f1332d9b 225 output_data[6] = tleg;
mchoun95 3:3c00f1332d9b 226 output_data[7] = wtail;
mchoun95 3:3c00f1332d9b 227 output_data[8] = wleg;
mchoun95 3:3c00f1332d9b 228 server.sendData(output_data,NUM_OUTPUTS);
mchoun95 3:3c00f1332d9b 229 new_data = false;
mchoun95 3:3c00f1332d9b 230 }
pwensing 0:43448bf056e8 231 }
mchoun95 3:3c00f1332d9b 232 end = true;
pwensing 0:43448bf056e8 233 // Cleanup after experiment
pwensing 0:43448bf056e8 234 server.setExperimentComplete();
mchoun95 3:3c00f1332d9b 235 tailPWM.write(0);
mchoun95 3:3c00f1332d9b 236 legPWM.write(0);
pwensing 0:43448bf056e8 237 } // end if
pwensing 0:43448bf056e8 238 } // end while
pwensing 0:43448bf056e8 239 } // end main