Biorobotics / Robot-Software

Dependencies:   HIDScope MODSERIAL QEI biquadFilter mbed Servo

Committer:
SvenD97
Date:
Wed Oct 31 11:50:28 2018 +0000
Revision:
36:dc0571d14e30
Parent:
35:6110d0b5513b
Child:
37:5ddfd9e6cdb2
Got rid of hidscope and modserial stuff;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MaikOvermars 0:4cb1de41d049 1 #include "mbed.h"
MaikOvermars 0:4cb1de41d049 2 #include "MODSERIAL.h"
MaikOvermars 0:4cb1de41d049 3 #include "QEI.h"
MaikOvermars 0:4cb1de41d049 4 #include "HIDScope.h"
MaikOvermars 0:4cb1de41d049 5 #include "BiQuad.h"
MaikOvermars 0:4cb1de41d049 6 #include "PID_controller.h"
MaikOvermars 0:4cb1de41d049 7 #include "kinematics.h"
MaikOvermars 17:1f93c83e211f 8 #include "processing_chain_emg.h"
MaikOvermars 0:4cb1de41d049 9
MaikOvermars 10:7339dca7d604 10 // emg inputs
MaikOvermars 0:4cb1de41d049 11 AnalogIn emg0( A0 );
MaikOvermars 0:4cb1de41d049 12 AnalogIn emg1( A1 );
MaikOvermars 0:4cb1de41d049 13
MaikOvermars 10:7339dca7d604 14 // motor ouptuts
MaikOvermars 0:4cb1de41d049 15 PwmOut motor1_pwm(D5);
MaikOvermars 0:4cb1de41d049 16 DigitalOut motor1_dir(D4);
MaikOvermars 0:4cb1de41d049 17 PwmOut motor2_pwm(D7);
MaikOvermars 0:4cb1de41d049 18 DigitalOut motor2_dir(D6);
MaikOvermars 0:4cb1de41d049 19
SvenD97 14:4744cc6c90f4 20 // defining encoders
MaikOvermars 16:0280a604cf7e 21 QEI motor_1_encoder(D12,D13,NC,32);
MaikOvermars 16:0280a604cf7e 22 QEI motor_2_encoder(D10,D11,NC,32);
SvenD97 14:4744cc6c90f4 23
MaikOvermars 17:1f93c83e211f 24 // other objects
MaikOvermars 0:4cb1de41d049 25 AnalogIn potmeter1(A2);
MaikOvermars 0:4cb1de41d049 26 AnalogIn potmeter2(A3);
MaikOvermars 0:4cb1de41d049 27 DigitalIn button(D0);
SvenD97 31:393a7ec1d396 28 DigitalOut led_R(LED_RED);
SvenD97 31:393a7ec1d396 29 DigitalOut led_B(LED_BLUE);
SvenD97 31:393a7ec1d396 30 DigitalOut led_G(LED_GREEN);
MaikOvermars 0:4cb1de41d049 31
SvenD97 14:4744cc6c90f4 32 // tickers and timers
MaikOvermars 16:0280a604cf7e 33 Ticker loop_ticker;
MaikOvermars 0:4cb1de41d049 34 Timer state_timer;
SvenD97 27:eee900e0a47d 35 Timer emg_timer;
MaikOvermars 0:4cb1de41d049 36
SvenD97 34:7d672cd04486 37 // Timeouts and related variables
SvenD97 34:7d672cd04486 38 Timeout make_button_active;
SvenD97 34:7d672cd04486 39 bool button_suppressed = false;
SvenD97 34:7d672cd04486 40
SvenD97 34:7d672cd04486 41 // States
SvenD97 31:393a7ec1d396 42 enum States {failure, waiting, calib_emg, calib_enc, operational, demo, homing}; //All possible robot states
SvenD97 27:eee900e0a47d 43 enum Emg_measures_states {not_in_calib_emg, calib_right_bicep, calib_right_tricep, calib_left_bicep, calib_left_tricep}; // States inside
MaikOvermars 0:4cb1de41d049 44
MaikOvermars 0:4cb1de41d049 45 //Global variables/objects
MaikOvermars 0:4cb1de41d049 46 States current_state;
SvenD97 31:393a7ec1d396 47 Emg_measures_states current_emg_calibration_state = not_in_calib_emg;
MaikOvermars 16:0280a604cf7e 48
SvenD97 35:6110d0b5513b 49 double des_vx, des_vy, x, y, q1, q2, qref1, qref2, e1, e2; //will be set by the motor_controller function
SvenD97 35:6110d0b5513b 50 double u1 = 0, u2= 0;
MaikOvermars 17:1f93c83e211f 51 double vxmax = 1.0, vymax = 1.0;
SvenD97 27:eee900e0a47d 52 double right_bicep_max = 0.0, right_tricep_max = 0.0, left_bicep_max= 0.0, left_tricep_max = 0.0;
SvenD97 27:eee900e0a47d 53
SvenD97 31:393a7ec1d396 54 // Variables for emg
SvenD97 31:393a7ec1d396 55 double raw_emg_0, process_emg_0;
SvenD97 31:393a7ec1d396 56 double raw_emg_1, process_emg_1;
SvenD97 31:393a7ec1d396 57 double raw_emg_2, process_emg_2;
SvenD97 31:393a7ec1d396 58 double raw_emg_3, process_emg_3;
SvenD97 31:393a7ec1d396 59
SvenD97 31:393a7ec1d396 60
SvenD97 33:eb77ed8d167c 61 // Variables for calibration
SvenD97 35:6110d0b5513b 62 double calib_q1 = 3.1415926535f;
SvenD97 35:6110d0b5513b 63 double calib_q2 = 1.5f*3.1415926535f;
SvenD97 33:eb77ed8d167c 64 double off_set_q1 = 0; // This variable is used to determine the off set from our definition from q1 and q2.
SvenD97 33:eb77ed8d167c 65 double off_set_q2 = 0;
SvenD97 33:eb77ed8d167c 66
SvenD97 30:7a66951a0122 67 // Variables defined for the homing state
SvenD97 35:6110d0b5513b 68 double q1_homing = 0.5f*3.1415926535f, q2_homing = 3.1415926535f;
SvenD97 30:7a66951a0122 69 double beta = 5;
SvenD97 31:393a7ec1d396 70 double k_hom = 2;
SvenD97 31:393a7ec1d396 71
SvenD97 31:393a7ec1d396 72 // For the state calib_enc
SvenD97 31:393a7ec1d396 73 double q1old;
SvenD97 31:393a7ec1d396 74 double q2old;
SvenD97 30:7a66951a0122 75
SvenD97 27:eee900e0a47d 76 // Meaning of process_emg_0 and such
SvenD97 27:eee900e0a47d 77 // - process_emg_0 is right biceps
SvenD97 27:eee900e0a47d 78 // - process_emg_1 is right triceps
SvenD97 27:eee900e0a47d 79 // - process_emg_2 is left biceps
SvenD97 27:eee900e0a47d 80 // - process_emg_3 is left triceps
bjonkheer 23:7d83af123c43 81
MaikOvermars 0:4cb1de41d049 82 int counts_per_rotation = 32;
MaikOvermars 0:4cb1de41d049 83 bool state_changed = false;
SvenD97 8:bba05e863b68 84 const double T = 0.001;
bjonkheer 23:7d83af123c43 85
SvenD97 30:7a66951a0122 86 // Resolution of the encoder at the output axle
SvenD97 30:7a66951a0122 87 double resolution = (2.0f*3.1415926535f/double(counts_per_rotation))*(1.0/131.0); // In radians
SvenD97 30:7a66951a0122 88
MaikOvermars 17:1f93c83e211f 89 // Functions
MaikOvermars 0:4cb1de41d049 90 void measure_all()
MaikOvermars 0:4cb1de41d049 91 {
bjonkheer 23:7d83af123c43 92
SvenD97 33:eb77ed8d167c 93 q1 = motor_1_encoder.getPulses()*2.0f*3.1415926535f/counts_per_rotation + off_set_q1; //do this here, and not in the encoder interrupt, to reduce computational load
SvenD97 33:eb77ed8d167c 94 q2 = motor_2_encoder.getPulses()*2.0f*3.1415926535f/counts_per_rotation + off_set_q2;
SvenD97 33:eb77ed8d167c 95 forwardkinematics_function(q1,q2,x,y);
MaikOvermars 17:1f93c83e211f 96 raw_emg_0 = emg0.read(); //sample analog voltages (all sampling theory applies, you might get aliasing etc.)
MaikOvermars 17:1f93c83e211f 97 raw_emg_1 = emg1.read();
MaikOvermars 17:1f93c83e211f 98 processing_chain_emg(raw_emg_0, raw_emg_1, process_emg_0, process_emg_1); // processes the emg signals
MaikOvermars 0:4cb1de41d049 99 }
MaikOvermars 0:4cb1de41d049 100
MaikOvermars 0:4cb1de41d049 101 void output_all() {
MaikOvermars 0:4cb1de41d049 102 motor1_pwm = fabs(u1);
MaikOvermars 16:0280a604cf7e 103 motor1_dir = u1 > 0.0f;
MaikOvermars 0:4cb1de41d049 104 motor2_pwm = fabs(u2);
MaikOvermars 16:0280a604cf7e 105 motor2_dir = u2 > 0.0f;
MaikOvermars 0:4cb1de41d049 106 static int output_counter = 0;
MaikOvermars 0:4cb1de41d049 107 output_counter++;
MaikOvermars 0:4cb1de41d049 108 }
MaikOvermars 0:4cb1de41d049 109
SvenD97 34:7d672cd04486 110 void unsuppressing_button(){
SvenD97 34:7d672cd04486 111 button_suppressed = false;
SvenD97 34:7d672cd04486 112 }
SvenD97 34:7d672cd04486 113
MaikOvermars 0:4cb1de41d049 114 void state_machine() {
MaikOvermars 0:4cb1de41d049 115 switch(current_state) { //States can be: failure, wait, calib_enc, calib_emg, operational, demo,
MaikOvermars 0:4cb1de41d049 116 case waiting: //Nothing useful here, maybe a blinking LED for fun and communication to the user
MaikOvermars 0:4cb1de41d049 117 if (button.read()==true)
MaikOvermars 0:4cb1de41d049 118 {
MaikOvermars 0:4cb1de41d049 119 current_state = calib_enc; //the NEXT loop we will be in calib_enc state
SvenD97 31:393a7ec1d396 120 state_changed = true;
MaikOvermars 0:4cb1de41d049 121 }
bjonkheer 29:d1e8eb135e6c 122
MaikOvermars 0:4cb1de41d049 123 break; //to avoid falling through to the next state, although this can sometimes be very useful.
MaikOvermars 0:4cb1de41d049 124
MaikOvermars 0:4cb1de41d049 125 case calib_enc:
bjonkheer 29:d1e8eb135e6c 126
MaikOvermars 0:4cb1de41d049 127 if (state_changed==true)
MaikOvermars 0:4cb1de41d049 128 {
MaikOvermars 0:4cb1de41d049 129 state_timer.reset();
MaikOvermars 0:4cb1de41d049 130 state_timer.start();
MaikOvermars 0:4cb1de41d049 131 state_changed = false;
bjonkheer 29:d1e8eb135e6c 132 n = 0;
bjonkheer 29:d1e8eb135e6c 133 led_G = 0;
bjonkheer 29:d1e8eb135e6c 134 led_B = 1;
bjonkheer 29:d1e8eb135e6c 135 led_R = 1;
bjonkheer 29:d1e8eb135e6c 136 u1 = 0.55f; //a low PWM value to move the motors slowly (0.0 to 0.45 don’t do much due to friction)
bjonkheer 29:d1e8eb135e6c 137 u2 = 0.55f;
bjonkheer 29:d1e8eb135e6c 138 q1old = 0;
bjonkheer 29:d1e8eb135e6c 139 q2old = 0;
MaikOvermars 0:4cb1de41d049 140 }
bjonkheer 29:d1e8eb135e6c 141
SvenD97 31:393a7ec1d396 142 if (q1-q1old == 0.0 && q2 - q2old < 0.0 && state_timer.read() > 5.0f)
bjonkheer 29:d1e8eb135e6c 143 {
MaikOvermars 0:4cb1de41d049 144 current_state = calib_emg; //the NEXT loop we will be in calib_emg state
SvenD97 31:393a7ec1d396 145 current_emg_calibration_state = calib_right_bicep;
MaikOvermars 0:4cb1de41d049 146 state_changed = true;
SvenD97 33:eb77ed8d167c 147 off_set_q1 = calib_q1 - q1;
SvenD97 33:eb77ed8d167c 148 off_set_q2 = calib_q2 - q2;
SvenD97 35:6110d0b5513b 149 u1 = 0;
SvenD97 35:6110d0b5513b 150 u2 = 0;
bjonkheer 29:d1e8eb135e6c 151 }
bjonkheer 29:d1e8eb135e6c 152 q1old = q1;
bjonkheer 29:d1e8eb135e6c 153 q2old = q2;
bjonkheer 29:d1e8eb135e6c 154
bjonkheer 29:d1e8eb135e6c 155 n++;
bjonkheer 29:d1e8eb135e6c 156 if (n%1000 == 0)
bjonkheer 29:d1e8eb135e6c 157 {
bjonkheer 29:d1e8eb135e6c 158 led_G = !led_G;
MaikOvermars 0:4cb1de41d049 159 }
bjonkheer 29:d1e8eb135e6c 160
MaikOvermars 0:4cb1de41d049 161 break;
MaikOvermars 0:4cb1de41d049 162
MaikOvermars 0:4cb1de41d049 163 case calib_emg: //calibrate emg-signals
SvenD97 27:eee900e0a47d 164 if (state_changed == true){
SvenD97 27:eee900e0a47d 165 state_timer.reset();
SvenD97 27:eee900e0a47d 166 state_timer.start();
SvenD97 27:eee900e0a47d 167 emg_timer.reset();
SvenD97 27:eee900e0a47d 168 emg_timer.start();
SvenD97 27:eee900e0a47d 169 state_changed = false;
SvenD97 27:eee900e0a47d 170 }
SvenD97 27:eee900e0a47d 171
SvenD97 31:393a7ec1d396 172 switch(current_emg_calibration_state){
SvenD97 27:eee900e0a47d 173 case calib_right_bicep:
SvenD97 27:eee900e0a47d 174 if(emg_timer < 5.0f){
SvenD97 27:eee900e0a47d 175 if (process_emg_0 > right_bicep_max){
SvenD97 27:eee900e0a47d 176 right_bicep_max = process_emg_0;
SvenD97 27:eee900e0a47d 177 }
SvenD97 27:eee900e0a47d 178 }
SvenD97 30:7a66951a0122 179 else if (process_emg_0 < 0.1*right_bicep_max){
SvenD97 27:eee900e0a47d 180 current_emg_calibration_state = calib_right_tricep;
SvenD97 27:eee900e0a47d 181 emg_timer.reset();
SvenD97 27:eee900e0a47d 182 emg_timer.start();
SvenD97 27:eee900e0a47d 183 }
SvenD97 27:eee900e0a47d 184 break;
SvenD97 27:eee900e0a47d 185 case calib_right_tricep:
SvenD97 27:eee900e0a47d 186 if(emg_timer < 5.0f){
SvenD97 27:eee900e0a47d 187 if (process_emg_1 > right_tricep_max){
SvenD97 27:eee900e0a47d 188 right_tricep_max = process_emg_1;
SvenD97 27:eee900e0a47d 189 }
SvenD97 27:eee900e0a47d 190 }
SvenD97 30:7a66951a0122 191 else if (process_emg_1 < 0.1*right_tricep_max){
SvenD97 30:7a66951a0122 192 current_emg_calibration_state = calib_left_bicep;
SvenD97 30:7a66951a0122 193 emg_timer.reset();
SvenD97 30:7a66951a0122 194 emg_timer.start();
SvenD97 30:7a66951a0122 195 }
SvenD97 27:eee900e0a47d 196 break;
SvenD97 31:393a7ec1d396 197 case calib_left_bicep:
SvenD97 30:7a66951a0122 198 if(emg_timer < 5.0f){
SvenD97 30:7a66951a0122 199 if (process_emg_2 > left_bicep_max){
SvenD97 30:7a66951a0122 200 left_bicep_max = process_emg_2;
SvenD97 27:eee900e0a47d 201 }
SvenD97 30:7a66951a0122 202 }
SvenD97 30:7a66951a0122 203 else if (process_emg_2 < 0.1*left_bicep_max){
SvenD97 30:7a66951a0122 204 current_emg_calibration_state = calib_left_tricep;
SvenD97 30:7a66951a0122 205 emg_timer.reset();
SvenD97 30:7a66951a0122 206 emg_timer.start();
SvenD97 30:7a66951a0122 207 }
SvenD97 27:eee900e0a47d 208 break;
SvenD97 27:eee900e0a47d 209 case calib_left_tricep:
SvenD97 27:eee900e0a47d 210 if(emg_timer < 5.0f){
SvenD97 27:eee900e0a47d 211 if (process_emg_3 > left_tricep_max){
SvenD97 27:eee900e0a47d 212 left_tricep_max = process_emg_3;
SvenD97 27:eee900e0a47d 213 }
SvenD97 27:eee900e0a47d 214 }
SvenD97 30:7a66951a0122 215 else if (process_emg_3 < 0.1*left_tricep_max){
SvenD97 30:7a66951a0122 216 current_emg_calibration_state = not_in_calib_emg;
SvenD97 30:7a66951a0122 217 current_state = homing;
SvenD97 30:7a66951a0122 218 state_changed = true;
SvenD97 30:7a66951a0122 219 emg_timer.reset();
SvenD97 30:7a66951a0122 220 }
SvenD97 27:eee900e0a47d 221 break;
SvenD97 27:eee900e0a47d 222 default:
SvenD97 27:eee900e0a47d 223 current_state = failure;
SvenD97 27:eee900e0a47d 224 state_changed = true;
SvenD97 31:393a7ec1d396 225 }
SvenD97 31:393a7ec1d396 226
SvenD97 31:393a7ec1d396 227 break;
SvenD97 27:eee900e0a47d 228
SvenD97 30:7a66951a0122 229 case homing:
SvenD97 30:7a66951a0122 230 if (state_changed == true){
SvenD97 30:7a66951a0122 231 state_timer.reset();
SvenD97 30:7a66951a0122 232 state_timer.start();
SvenD97 30:7a66951a0122 233 qref1 = q1; //NOT SURE IF WE NEED THIS. I do not think so, but just to be sure.
SvenD97 30:7a66951a0122 234 qref2 = q2;
SvenD97 30:7a66951a0122 235 }
SvenD97 33:eb77ed8d167c 236 des_vx = min(beta, k_hom*(q1 - q1_homing)); // Little bit different then that Arvid told us, but now it works with the motor controller
SvenD97 33:eb77ed8d167c 237 des_vy = min(beta, k_hom*(q2 - q2_homing));
SvenD97 30:7a66951a0122 238
SvenD97 31:393a7ec1d396 239 // The value of 3.0 and 2*resolution can be changed
SvenD97 31:393a7ec1d396 240 if (fabs(q1-q1_homing) <= 2*resolution && fabs(q2-q2_homing) <= 2 * resolution ){
SvenD97 31:393a7ec1d396 241 if (state_timer > 3.0f){
SvenD97 31:393a7ec1d396 242 current_state = operational;
SvenD97 31:393a7ec1d396 243 state_changed = true;
SvenD97 33:eb77ed8d167c 244 des_vx = 0; // Not sure if needed but added it anyways.
SvenD97 33:eb77ed8d167c 245 des_vy = 0;
SvenD97 30:7a66951a0122 246 }
SvenD97 30:7a66951a0122 247 }
SvenD97 31:393a7ec1d396 248 else{
SvenD97 31:393a7ec1d396 249 state_timer.reset();
SvenD97 31:393a7ec1d396 250 }
SvenD97 31:393a7ec1d396 251 break;
MaikOvermars 0:4cb1de41d049 252
MaikOvermars 0:4cb1de41d049 253 case operational: //interpreting emg-signals to move the end effector
SvenD97 30:7a66951a0122 254 if (state_changed == true){
SvenD97 30:7a66951a0122 255 state_changed = false;
SvenD97 30:7a66951a0122 256 }
SvenD97 30:7a66951a0122 257
bjonkheer 23:7d83af123c43 258
MaikOvermars 17:1f93c83e211f 259 // here we have to determine the desired velocity based on the processed emg signals and calibration
MaikOvermars 17:1f93c83e211f 260 if (process_emg_0 >= 0.16) { des_vx = vxmax; }
MaikOvermars 17:1f93c83e211f 261 else if(process_emg_0 >= 0.09) { des_vx = vxmax * 0.66; }
MaikOvermars 17:1f93c83e211f 262 else if(process_emg_0 >= 0.02) { des_vx = vxmax * 0.33; }
MaikOvermars 17:1f93c83e211f 263 else { des_vx = 0; }
MaikOvermars 17:1f93c83e211f 264
MaikOvermars 17:1f93c83e211f 265 if (process_emg_1 >= 0.16) { des_vy = vymax; }
MaikOvermars 17:1f93c83e211f 266 else if(process_emg_1 >= 0.09) { des_vy = vymax * 0.66; }
MaikOvermars 17:1f93c83e211f 267 else if(process_emg_1 >= 0.02) { des_vy = vymax * 0.33; }
MaikOvermars 17:1f93c83e211f 268 else { des_vy = 0; }
MaikOvermars 17:1f93c83e211f 269
SvenD97 34:7d672cd04486 270 if (button.read() == true && button_suppressed == false ) {
SvenD97 30:7a66951a0122 271 current_state = demo;
SvenD97 30:7a66951a0122 272 state_changed = true;
SvenD97 34:7d672cd04486 273 button_suppressed = true;
SvenD97 34:7d672cd04486 274
SvenD97 34:7d672cd04486 275 make_button_active.attach(&unsuppressing_button,0.5);
SvenD97 34:7d672cd04486 276
SvenD97 34:7d672cd04486 277 }
bjonkheer 29:d1e8eb135e6c 278
MaikOvermars 0:4cb1de41d049 279 break;
MaikOvermars 0:4cb1de41d049 280
MaikOvermars 0:4cb1de41d049 281 case demo: //moving according to a specified trajectory
SvenD97 33:eb77ed8d167c 282 // We want to draw a square. Hence, first move to a certain point and then start moving a square.
SvenD97 30:7a66951a0122 283 if (state_changed == true){
SvenD97 30:7a66951a0122 284 state_changed = false;
SvenD97 30:7a66951a0122 285 }
SvenD97 30:7a66951a0122 286
SvenD97 34:7d672cd04486 287 if (button.read() == true && button_suppressed == false ) {
SvenD97 30:7a66951a0122 288 current_state = operational;
SvenD97 30:7a66951a0122 289 state_changed = true;
SvenD97 34:7d672cd04486 290
SvenD97 34:7d672cd04486 291 button_suppressed = true;
SvenD97 34:7d672cd04486 292
SvenD97 34:7d672cd04486 293 make_button_active.attach(&unsuppressing_button,0.5);
SvenD97 30:7a66951a0122 294 }
MaikOvermars 0:4cb1de41d049 295
MaikOvermars 0:4cb1de41d049 296 break;
MaikOvermars 0:4cb1de41d049 297
MaikOvermars 0:4cb1de41d049 298 case failure: //no way to get out
MaikOvermars 0:4cb1de41d049 299 u1 = 0.0f;
MaikOvermars 17:1f93c83e211f 300 u2 = 0.0f;
bjonkheer 29:d1e8eb135e6c 301 led_R = 0;
bjonkheer 29:d1e8eb135e6c 302 led_G = 1;
bjonkheer 29:d1e8eb135e6c 303 led_B = 1;
MaikOvermars 0:4cb1de41d049 304 break;
MaikOvermars 0:4cb1de41d049 305 }
MaikOvermars 0:4cb1de41d049 306 }
MaikOvermars 0:4cb1de41d049 307
MaikOvermars 0:4cb1de41d049 308 void motor_controller()
MaikOvermars 0:4cb1de41d049 309 {
MaikOvermars 0:4cb1de41d049 310 if (current_state >= operational) { // we can (ab)use the fact that an enum is actually an integer, so math/logic rules still apply
MaikOvermars 16:0280a604cf7e 311 inversekinematics_function(x,y,T,qref1,qref2,q1,q2,des_vx,des_vy); //many different states can modify your reference position, so just do the inverse kinematics once, here
MaikOvermars 16:0280a604cf7e 312 e1 = qref1 - q1; //tracking error (q_ref - q_meas)
MaikOvermars 16:0280a604cf7e 313 e2 = qref2 - q2;
MaikOvermars 17:1f93c83e211f 314 PID_controller(e1,e2,u1,u2,T); //feedback controller or with possibly fancy controller additions...; pass by reference
MaikOvermars 0:4cb1de41d049 315 } //otherwise we just don’t mess with the value of control variable ‘u’ that is set somewhere in the state-machine.
MaikOvermars 0:4cb1de41d049 316 }
MaikOvermars 0:4cb1de41d049 317
MaikOvermars 0:4cb1de41d049 318
MaikOvermars 0:4cb1de41d049 319 void loop_function() {
MaikOvermars 0:4cb1de41d049 320 measure_all(); //measure all signals
MaikOvermars 0:4cb1de41d049 321 state_machine(); //Do relevant state dependent things
MaikOvermars 0:4cb1de41d049 322 motor_controller(); //Do not put different motor controllers in the states, because every state can re-use the same motor-controller!
MaikOvermars 0:4cb1de41d049 323 output_all(); //Output relevant signals, messages, screen outputs, LEDs etc.
MaikOvermars 0:4cb1de41d049 324 }
MaikOvermars 0:4cb1de41d049 325
MaikOvermars 0:4cb1de41d049 326
MaikOvermars 0:4cb1de41d049 327 int main()
MaikOvermars 0:4cb1de41d049 328 {
MaikOvermars 0:4cb1de41d049 329 motor1_pwm.period_us(60);
MaikOvermars 0:4cb1de41d049 330 motor2_pwm.period_us(60);
MaikOvermars 0:4cb1de41d049 331 current_state = waiting; //we start in state ‘waiting’ and current_state can be accessed by all functions
MaikOvermars 0:4cb1de41d049 332 u1 = 0.0f; //initial output to motors is 0.
MaikOvermars 10:7339dca7d604 333 u2 = 0.0f;
MaikOvermars 25:734a26538711 334 bqc0.add(&bq0high).add(&bq0notch); // filter cascade for emg
MaikOvermars 25:734a26538711 335 bqc1.add(&bq1high).add(&bq1notch); // filter cascade for emg
MaikOvermars 17:1f93c83e211f 336 loop_ticker.attach(&loop_function, T); //Run the function loop_function 1000 times per second
SvenD97 32:2596cc9156ec 337 led_R = 1;
SvenD97 32:2596cc9156ec 338 led_B = 1;
SvenD97 32:2596cc9156ec 339 led_G = 1;
SvenD97 32:2596cc9156ec 340
MaikOvermars 0:4cb1de41d049 341 while (true) { } //Do nothing here (timing purposes)
MaikOvermars 0:4cb1de41d049 342 }