Biorobotics 2018: Project group 16

Dependencies:   HIDScope MODSERIAL QEI biquadFilter mbed

Committer:
ThomBMT
Date:
Thu Nov 01 10:52:03 2018 +0000
Revision:
3:766e9f13d84e
Parent:
2:bc6043623fb7
Child:
4:a682fb1f37d2
Added a discription to every function and/or variable declaration for clarity

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ThomBMT 0:94cf6b327972 1 #include "mbed.h"
ThomBMT 1:ba14d8f4d444 2 #include "MODSERIAL.h"
ThomBMT 1:ba14d8f4d444 3 #include "HIDScope.h"
ThomBMT 1:ba14d8f4d444 4 #include "QEI.h"
ThomBMT 1:ba14d8f4d444 5 #include "BiQuad.h"
ThomBMT 0:94cf6b327972 6
ThomBMT 3:766e9f13d84e 7 // Pin defintions:
ThomBMT 3:766e9f13d84e 8 MODSERIAL pc(USBTX, USBRX);
ThomBMT 3:766e9f13d84e 9 DigitalOut DirectionPin1(D4);
ThomBMT 3:766e9f13d84e 10 DigitalOut DirectionPin2(D7);
ThomBMT 3:766e9f13d84e 11 PwmOut PwmPin1(D5);
ThomBMT 3:766e9f13d84e 12 PwmOut PwmPin2(D6);
ThomBMT 3:766e9f13d84e 13 DigitalIn Knop1(D2);
ThomBMT 3:766e9f13d84e 14 DigitalIn Knop2(D3);
ThomBMT 3:766e9f13d84e 15 DigitalIn Knop3(PTA4);
ThomBMT 3:766e9f13d84e 16 DigitalIn Knop4(PTC6);
ThomBMT 3:766e9f13d84e 17 AnalogIn pot1 (A5);
ThomBMT 3:766e9f13d84e 18 AnalogIn pot2 (A4);
ThomBMT 3:766e9f13d84e 19 AnalogIn emg0( A0 );
ThomBMT 3:766e9f13d84e 20 AnalogIn emg1( A1 );
ThomBMT 3:766e9f13d84e 21 AnalogIn emg2( A2 );
ThomBMT 3:766e9f13d84e 22 AnalogIn emg3( A3 );
ThomBMT 3:766e9f13d84e 23 DigitalOut led_G(LED_GREEN);
ThomBMT 3:766e9f13d84e 24 DigitalOut led_R(LED_RED);
ThomBMT 3:766e9f13d84e 25 DigitalOut led_B(LED_BLUE);
ThomBMT 1:ba14d8f4d444 26
ThomBMT 3:766e9f13d84e 27 // Encoder functions.
ThomBMT 1:ba14d8f4d444 28 QEI Encoder1(D12,D13,NC,64,QEI::X4_ENCODING);
ThomBMT 1:ba14d8f4d444 29 QEI Encoder2(D10,D11,NC,64,QEI::X4_ENCODING);
ThomBMT 1:ba14d8f4d444 30
ThomBMT 3:766e9f13d84e 31 // Filter definitions:
ThomBMT 3:766e9f13d84e 32 BiQuadChain bqc1;
ThomBMT 3:766e9f13d84e 33 BiQuadChain bqc2;
ThomBMT 3:766e9f13d84e 34 BiQuadChain bqc3;
ThomBMT 3:766e9f13d84e 35 BiQuadChain bqc4;
ThomBMT 3:766e9f13d84e 36 BiQuadChain bqc5;
ThomBMT 3:766e9f13d84e 37 BiQuadChain bqc6;
ThomBMT 3:766e9f13d84e 38 BiQuadChain bqc7;
ThomBMT 3:766e9f13d84e 39 BiQuadChain bqc8;
ThomBMT 1:ba14d8f4d444 40
ThomBMT 3:766e9f13d84e 41 BiQuad BqNotch1_1( 9.65081e-01, -1.56203e+00, 9.65081e-01,-1.56858e+00, 9.64241e-01 );
ThomBMT 3:766e9f13d84e 42 BiQuad BqNotch2_1( 1.00000e+00, -1.61855e+00, 1.00000e+00 ,-1.61100e+00, 9.65922e-01);
ThomBMT 3:766e9f13d84e 43 BiQuad BqNotch1_2( 9.65081e-01, -1.56203e+00, 9.65081e-01,-1.56858e+00, 9.64241e-01 );
ThomBMT 3:766e9f13d84e 44 BiQuad BqNotch2_2( 1.00000e+00, -1.61855e+00, 1.00000e+00 ,-1.61100e+00, 9.65922e-01);
ThomBMT 3:766e9f13d84e 45 BiQuad BqNotch1_3( 9.65081e-01, -1.56203e+00, 9.65081e-01,-1.56858e+00, 9.64241e-01 );
ThomBMT 3:766e9f13d84e 46 BiQuad BqNotch2_3( 1.00000e+00, -1.61855e+00, 1.00000e+00 ,-1.61100e+00, 9.65922e-01);
ThomBMT 3:766e9f13d84e 47 BiQuad BqNotch1_4( 9.65081e-01, -1.56203e+00, 9.65081e-01,-1.56858e+00, 9.64241e-01 );
ThomBMT 3:766e9f13d84e 48 BiQuad BqNotch2_4( 1.00000e+00, -1.61855e+00, 1.00000e+00 ,-1.61100e+00, 9.65922e-01);
ThomBMT 3:766e9f13d84e 49 BiQuad BqHP1( 9.86760e-01, -1.97352e+00, 9.86760e-01, -1.97334e+00, 9.73695e-01 );
ThomBMT 3:766e9f13d84e 50 BiQuad BqHP2( 9.86760e-01, -1.97352e+00, 9.86760e-01, -1.97334e+00, 9.73695e-01 );
ThomBMT 3:766e9f13d84e 51 BiQuad BqHP3( 9.86760e-01, -1.97352e+00, 9.86760e-01, -1.97334e+00, 9.73695e-01 );
ThomBMT 3:766e9f13d84e 52 BiQuad BqHP4( 9.86760e-01, -1.97352e+00, 9.86760e-01, -1.97334e+00, 9.73695e-01 );
ThomBMT 1:ba14d8f4d444 53
ThomBMT 3:766e9f13d84e 54 BiQuad BqLP1( 3.91302e-05, 7.82604e-05, 3.91302e-05, -1.98223e+00, 9.82385e-01 );
ThomBMT 3:766e9f13d84e 55 BiQuad BqLP2( 3.91302e-05, 7.82604e-05, 3.91302e-05, -1.98223e+00, 9.82385e-01 );
ThomBMT 3:766e9f13d84e 56 BiQuad BqLP3( 3.91302e-05, 7.82604e-05, 3.91302e-05, -1.98223e+00, 9.82385e-01 );
ThomBMT 3:766e9f13d84e 57 BiQuad BqLP4( 3.91302e-05, 7.82604e-05, 3.91302e-05, -1.98223e+00, 9.82385e-01 );
ThomBMT 3:766e9f13d84e 58
ThomBMT 3:766e9f13d84e 59 BiQuad LowPassFilter(0.0640, 0.1279, 0.0640, -1.1683, 0.4241);
ThomBMT 1:ba14d8f4d444 60
ThomBMT 3:766e9f13d84e 61 // Tickers for the main loop:
ThomBMT 3:766e9f13d84e 62 Ticker StateTicker;
ThomBMT 3:766e9f13d84e 63 Ticker printTicker;
ThomBMT 1:ba14d8f4d444 64
ThomBMT 3:766e9f13d84e 65 // Setting the HIDscope:
ThomBMT 3:766e9f13d84e 66 HIDScope scope( 4 );
ThomBMT 1:ba14d8f4d444 67
ThomBMT 3:766e9f13d84e 68 // All variables for EMG-processing:
ThomBMT 1:ba14d8f4d444 69 volatile float Bicep_Right = 0.0;
ThomBMT 1:ba14d8f4d444 70 volatile float Bicep_Left = 0.0;
ThomBMT 1:ba14d8f4d444 71 volatile float Tricep_Right = 0.0;
ThomBMT 1:ba14d8f4d444 72 volatile float Tricep_Left = 0.0;
ThomBMT 1:ba14d8f4d444 73 volatile float FilterHP_Bi_R;
ThomBMT 1:ba14d8f4d444 74 volatile float Filterabs_Bi_R;
ThomBMT 1:ba14d8f4d444 75 volatile float Filtered_Bi_R;
ThomBMT 1:ba14d8f4d444 76 volatile float FilterHP_Bi_L;
ThomBMT 1:ba14d8f4d444 77 volatile float Filterabs_Bi_L;
ThomBMT 1:ba14d8f4d444 78 volatile float Filtered_Bi_L;
ThomBMT 1:ba14d8f4d444 79 volatile float FilterHP_Tri_R;
ThomBMT 1:ba14d8f4d444 80 volatile float Filterabs_Tri_R;
ThomBMT 1:ba14d8f4d444 81 volatile float Filtered_Tri_R;
ThomBMT 1:ba14d8f4d444 82 volatile float FilterHP_Tri_L;
ThomBMT 1:ba14d8f4d444 83 volatile float Filterabs_Tri_L;
ThomBMT 1:ba14d8f4d444 84 volatile float Filtered_Tri_L;
ThomBMT 1:ba14d8f4d444 85
ThomBMT 3:766e9f13d84e 86 // Variables for the PID-Controller:
ThomBMT 3:766e9f13d84e 87 volatile float error_1_integral = 0;
ThomBMT 3:766e9f13d84e 88 volatile float error_2_integral = 0;
ThomBMT 3:766e9f13d84e 89 volatile float error_1_prev; // initialization with this value only done once!
ThomBMT 3:766e9f13d84e 90 volatile float error_2_prev;
ThomBMT 3:766e9f13d84e 91 volatile const float Kp = 17.5;
ThomBMT 3:766e9f13d84e 92 volatile const float Ki = 1.02;
ThomBMT 3:766e9f13d84e 93 volatile const float Kd = 23.2;
ThomBMT 3:766e9f13d84e 94 volatile const float Ts = 0.002; // Sample time in seconds
ThomBMT 3:766e9f13d84e 95 volatile float error_1;
ThomBMT 3:766e9f13d84e 96 volatile float error_2;
ThomBMT 3:766e9f13d84e 97 volatile float U_1;
ThomBMT 3:766e9f13d84e 98 volatile float U_2;
ThomBMT 1:ba14d8f4d444 99
ThomBMT 3:766e9f13d84e 100 // Constant values used in computations and such:
ThomBMT 1:ba14d8f4d444 101 volatile const float pi = 3.1415926;
ThomBMT 1:ba14d8f4d444 102 volatile const float rad_count = 0.0007479; // 2pi/8400;
ThomBMT 1:ba14d8f4d444 103 volatile const float maxVelocity = 2.0f * pi; // in rad/s
ThomBMT 1:ba14d8f4d444 104 volatile const float r_3 = 0.035;
ThomBMT 1:ba14d8f4d444 105
ThomBMT 3:766e9f13d84e 106 // Some counting variables:
ThomBMT 1:ba14d8f4d444 107 volatile int i = 0; // Led blink status
ThomBMT 1:ba14d8f4d444 108 volatile int ii = 0; // Calibratie timer
ThomBMT 1:ba14d8f4d444 109 volatile int iii = 0; // Start up timer
ThomBMT 1:ba14d8f4d444 110
ThomBMT 3:766e9f13d84e 111 // Variables for computations of joint angle and velocities:
ThomBMT 3:766e9f13d84e 112 volatile float q_1;
ThomBMT 3:766e9f13d84e 113 volatile float q_2;
ThomBMT 3:766e9f13d84e 114 volatile float r_1;
ThomBMT 3:766e9f13d84e 115 volatile float r_2;
ThomBMT 3:766e9f13d84e 116 volatile float w_1;
ThomBMT 3:766e9f13d84e 117 volatile float w_2;
ThomBMT 3:766e9f13d84e 118 volatile float vx;
ThomBMT 3:766e9f13d84e 119 volatile float vy;
ThomBMT 3:766e9f13d84e 120 volatile float rad_m1;
ThomBMT 3:766e9f13d84e 121 volatile float rad_m2;
ThomBMT 3:766e9f13d84e 122 volatile int counts1;
ThomBMT 3:766e9f13d84e 123 volatile int counts2;
ThomBMT 1:ba14d8f4d444 124
ThomBMT 3:766e9f13d84e 125 // Threshold values and variables:
ThomBMT 3:766e9f13d84e 126 volatile float Flex_Bi_R;
ThomBMT 3:766e9f13d84e 127 volatile float Flex_Bi_L;
ThomBMT 3:766e9f13d84e 128 volatile float Flex_Tri_R;
ThomBMT 3:766e9f13d84e 129 volatile float Flex_Tri_L;
ThomBMT 3:766e9f13d84e 130 volatile float Threshold_Value;
ThomBMT 3:766e9f13d84e 131 volatile float Threshold_Bi_R;
ThomBMT 3:766e9f13d84e 132 volatile float Threshold_Bi_L;
ThomBMT 3:766e9f13d84e 133 volatile float Threshold_Tri_R;
ThomBMT 3:766e9f13d84e 134 volatile float Threshold_Tri_L;
ThomBMT 3:766e9f13d84e 135 volatile bool Checking_Bi_R = false;
ThomBMT 3:766e9f13d84e 136 volatile bool Checking_Bi_L = false;
ThomBMT 3:766e9f13d84e 137 volatile bool Checking_Tri_R = false;
ThomBMT 3:766e9f13d84e 138 volatile bool Checking_Tri_L = false;
ThomBMT 1:ba14d8f4d444 139
ThomBMT 3:766e9f13d84e 140 // States for the switch-statemachine:
ThomBMT 1:ba14d8f4d444 141 enum states{Starting, Calibration, Homing_M1, Homing_M2, Post_Homing, Function, Safe};
ThomBMT 3:766e9f13d84e 142
ThomBMT 3:766e9f13d84e 143 // The very first state:
ThomBMT 1:ba14d8f4d444 144 volatile states Active_State = Starting;
ThomBMT 1:ba14d8f4d444 145
ThomBMT 3:766e9f13d84e 146
ThomBMT 1:ba14d8f4d444 147 void Encoding()
ThomBMT 1:ba14d8f4d444 148 {
ThomBMT 3:766e9f13d84e 149 // Encoding is necessary for the computations of the joint angles and
ThomBMT 3:766e9f13d84e 150 // velocities of the arm given certain linear velocities.
ThomBMT 1:ba14d8f4d444 151
ThomBMT 1:ba14d8f4d444 152 counts1 = Encoder1.getPulses();
ThomBMT 1:ba14d8f4d444 153 counts2 = Encoder2.getPulses();
ThomBMT 1:ba14d8f4d444 154
ThomBMT 1:ba14d8f4d444 155 rad_m1 = rad_count * (float)counts1;
ThomBMT 1:ba14d8f4d444 156 rad_m2 = rad_count * (float)counts2;
ThomBMT 1:ba14d8f4d444 157 }
ThomBMT 1:ba14d8f4d444 158
ThomBMT 1:ba14d8f4d444 159 void Filter()
ThomBMT 1:ba14d8f4d444 160 {
ThomBMT 3:766e9f13d84e 161 // Our Filter function will take the raw (incomming) EMG-signal and process
ThomBMT 3:766e9f13d84e 162 // it in such a way that we can use it to opperate our system.
ThomBMT 3:766e9f13d84e 163
ThomBMT 1:ba14d8f4d444 164 FilterHP_Bi_R = bqc1.step( emg0.read() );
ThomBMT 1:ba14d8f4d444 165 Filterabs_Bi_R = fabs(FilterHP_Bi_R);
ThomBMT 1:ba14d8f4d444 166 Filtered_Bi_R = bqc2.step( Filterabs_Bi_R );
ThomBMT 1:ba14d8f4d444 167
ThomBMT 1:ba14d8f4d444 168 FilterHP_Bi_L = bqc3.step( emg1.read() );
ThomBMT 1:ba14d8f4d444 169 Filterabs_Bi_L = fabs(FilterHP_Bi_L);
ThomBMT 1:ba14d8f4d444 170 Filtered_Bi_L = bqc4.step( Filterabs_Bi_L );
ThomBMT 1:ba14d8f4d444 171
ThomBMT 1:ba14d8f4d444 172 FilterHP_Tri_R = bqc5.step( emg2.read() );
ThomBMT 1:ba14d8f4d444 173 Filterabs_Tri_R = fabs(FilterHP_Tri_R);
ThomBMT 1:ba14d8f4d444 174 Filtered_Tri_R = bqc6.step( Filterabs_Tri_R );
ThomBMT 1:ba14d8f4d444 175
ThomBMT 1:ba14d8f4d444 176 FilterHP_Tri_L = bqc7.step( emg3.read() );
ThomBMT 1:ba14d8f4d444 177 Filterabs_Tri_L = fabs(FilterHP_Tri_L);
ThomBMT 1:ba14d8f4d444 178 Filtered_Tri_L = bqc8.step( Filterabs_Tri_L );
ThomBMT 1:ba14d8f4d444 179 }
ThomBMT 1:ba14d8f4d444 180
ThomBMT 1:ba14d8f4d444 181 void BlinkLed()
ThomBMT 1:ba14d8f4d444 182 {
ThomBMT 3:766e9f13d84e 183 // This is a function used purely for feedback that will give insight in
ThomBMT 3:766e9f13d84e 184 // what the system is doing without having to fully opperate it.
ThomBMT 3:766e9f13d84e 185
ThomBMT 1:ba14d8f4d444 186 if(i==1)
ThomBMT 1:ba14d8f4d444 187 {
ThomBMT 1:ba14d8f4d444 188 led_G=led_B=1;
ThomBMT 1:ba14d8f4d444 189 static int rr = 0;
ThomBMT 1:ba14d8f4d444 190 rr++;
ThomBMT 1:ba14d8f4d444 191 if (rr == 1)
ThomBMT 1:ba14d8f4d444 192 {
ThomBMT 1:ba14d8f4d444 193 led_R = !led_R;
ThomBMT 1:ba14d8f4d444 194 }
ThomBMT 1:ba14d8f4d444 195 else if (rr == 50)
ThomBMT 1:ba14d8f4d444 196 {
ThomBMT 1:ba14d8f4d444 197 rr = 0;
ThomBMT 1:ba14d8f4d444 198 }
ThomBMT 1:ba14d8f4d444 199 }
ThomBMT 1:ba14d8f4d444 200 else if(i==2)
ThomBMT 1:ba14d8f4d444 201 {
ThomBMT 1:ba14d8f4d444 202 led_R=led_B=1;
ThomBMT 1:ba14d8f4d444 203
ThomBMT 1:ba14d8f4d444 204 static int gg = 0;
ThomBMT 1:ba14d8f4d444 205 gg++;
ThomBMT 1:ba14d8f4d444 206 if (gg == 1)
ThomBMT 1:ba14d8f4d444 207 {
ThomBMT 1:ba14d8f4d444 208 led_G = !led_G;
ThomBMT 1:ba14d8f4d444 209 }
ThomBMT 1:ba14d8f4d444 210 else if (gg == 250)
ThomBMT 1:ba14d8f4d444 211 {
ThomBMT 1:ba14d8f4d444 212 gg = 0;
ThomBMT 1:ba14d8f4d444 213 }
ThomBMT 1:ba14d8f4d444 214 }
ThomBMT 1:ba14d8f4d444 215 else if (i==3)
ThomBMT 1:ba14d8f4d444 216 {
ThomBMT 1:ba14d8f4d444 217 led_R=1;
ThomBMT 1:ba14d8f4d444 218 static int bb = 0;
ThomBMT 1:ba14d8f4d444 219 bb++;
ThomBMT 1:ba14d8f4d444 220 if (bb == 1)
ThomBMT 1:ba14d8f4d444 221 {
ThomBMT 1:ba14d8f4d444 222 led_B = !led_B;
ThomBMT 1:ba14d8f4d444 223 }
ThomBMT 1:ba14d8f4d444 224 else if (bb == 500)
ThomBMT 1:ba14d8f4d444 225 {
ThomBMT 1:ba14d8f4d444 226 bb = 0;
ThomBMT 1:ba14d8f4d444 227 }
ThomBMT 1:ba14d8f4d444 228 }
ThomBMT 1:ba14d8f4d444 229 else if (i==4)
ThomBMT 1:ba14d8f4d444 230 {
ThomBMT 1:ba14d8f4d444 231 led_G=1;
ThomBMT 1:ba14d8f4d444 232 static int rr = 0;
ThomBMT 1:ba14d8f4d444 233 rr++;
ThomBMT 1:ba14d8f4d444 234 if (rr == 1)
ThomBMT 1:ba14d8f4d444 235 {
ThomBMT 1:ba14d8f4d444 236 led_R = !led_R;
ThomBMT 1:ba14d8f4d444 237 led_B = !led_B;
ThomBMT 1:ba14d8f4d444 238 }
ThomBMT 1:ba14d8f4d444 239 else if (rr == 250)
ThomBMT 1:ba14d8f4d444 240 {
ThomBMT 1:ba14d8f4d444 241 rr = 0;
ThomBMT 1:ba14d8f4d444 242 }
ThomBMT 1:ba14d8f4d444 243 }
ThomBMT 1:ba14d8f4d444 244 else
ThomBMT 1:ba14d8f4d444 245 {
ThomBMT 1:ba14d8f4d444 246 led_R=led_G=led_B=1;
ThomBMT 1:ba14d8f4d444 247 }
ThomBMT 1:ba14d8f4d444 248 }
ThomBMT 1:ba14d8f4d444 249
ThomBMT 1:ba14d8f4d444 250 void EMG_Read()
ThomBMT 1:ba14d8f4d444 251 {
ThomBMT 3:766e9f13d84e 252 // This is only to define our first (raw) EMG-signals and give each a
ThomBMT 3:766e9f13d84e 253 // suitable name.
ThomBMT 3:766e9f13d84e 254
ThomBMT 1:ba14d8f4d444 255 Bicep_Right = emg0.read();
ThomBMT 1:ba14d8f4d444 256 Bicep_Left = emg1.read();
ThomBMT 1:ba14d8f4d444 257 Tricep_Right = emg2.read();
ThomBMT 1:ba14d8f4d444 258 Tricep_Left = emg3.read();
ThomBMT 1:ba14d8f4d444 259 }
ThomBMT 1:ba14d8f4d444 260
ThomBMT 1:ba14d8f4d444 261 void sample()
ThomBMT 1:ba14d8f4d444 262 {
ThomBMT 3:766e9f13d84e 263 // HIDscope allows us to check our filtered EMG-signal and gives insight
ThomBMT 3:766e9f13d84e 264 // into thresholdvalues and how well the calibration was done.
ThomBMT 1:ba14d8f4d444 265
ThomBMT 1:ba14d8f4d444 266 scope.set(0, Filtered_Bi_R*10.0f );
ThomBMT 1:ba14d8f4d444 267 scope.set(1, Filtered_Bi_L*10.0f );
ThomBMT 1:ba14d8f4d444 268 scope.set(2, Filtered_Tri_R*10.0f );
ThomBMT 1:ba14d8f4d444 269 scope.set(3, Filtered_Tri_L*10.0f );
ThomBMT 1:ba14d8f4d444 270
ThomBMT 1:ba14d8f4d444 271 scope.send();
ThomBMT 1:ba14d8f4d444 272 }
ThomBMT 1:ba14d8f4d444 273
ThomBMT 1:ba14d8f4d444 274 void Inverse()
ThomBMT 1:ba14d8f4d444 275 {
ThomBMT 3:766e9f13d84e 276 // Here we calculate the movement of each joint (Motor 1 and Motor 2) given
ThomBMT 3:766e9f13d84e 277 // a certain linear velocity-input.
ThomBMT 3:766e9f13d84e 278
ThomBMT 1:ba14d8f4d444 279 q_1= rad_m1+(pi/6.0f); // uit Encoder
ThomBMT 1:ba14d8f4d444 280 q_2= rad_m2+(pi/6.0f); // uit Encoder
ThomBMT 1:ba14d8f4d444 281 r_1= -0.2f;
ThomBMT 1:ba14d8f4d444 282 r_2= -0.2f;
ThomBMT 1:ba14d8f4d444 283
ThomBMT 1:ba14d8f4d444 284 float u = -r_2*sin(q_1)*cos(q_2)-(r_2)*cos(q_1)*sin(q_2);
ThomBMT 1:ba14d8f4d444 285 float z = 2.0f*(r_2*cos(q_1)*cos(q_2))-r_3;
ThomBMT 1:ba14d8f4d444 286 float y = r_2*cos(q_1)*cos(q_2)-r_2*sin(q_1)*sin(q_2)+2.0f*(r_1*cos(q_1))-r_3;
ThomBMT 1:ba14d8f4d444 287 float x = (-2.0f)*r_2*sin(q_1)*cos(q_2);
ThomBMT 1:ba14d8f4d444 288 float D = 1.0f/(u*z-x*y); // Determinant
ThomBMT 1:ba14d8f4d444 289 //printf("Determinant is %f\r\n", D);
ThomBMT 1:ba14d8f4d444 290
ThomBMT 1:ba14d8f4d444 291 float a = D*z; // Inverse jacobian a,b,c,d vormen 2 bij 2 matrix
ThomBMT 1:ba14d8f4d444 292 float b = -D*x; // Inverse jacobian
ThomBMT 1:ba14d8f4d444 293 float c = -D*y; // Inverse jacobian
ThomBMT 1:ba14d8f4d444 294 float d = D*u; // Inverse jacobian
ThomBMT 1:ba14d8f4d444 295
ThomBMT 1:ba14d8f4d444 296 vx = pot1.read()/5.0f; // uit emg data
ThomBMT 1:ba14d8f4d444 297 vy = pot2.read()/5.0f; // uit emg data
ThomBMT 1:ba14d8f4d444 298
ThomBMT 1:ba14d8f4d444 299 w_1 = vx*a+vy*b;
ThomBMT 1:ba14d8f4d444 300 w_2 = vx*c+vy*d;
ThomBMT 1:ba14d8f4d444 301 }
ThomBMT 1:ba14d8f4d444 302
ThomBMT 1:ba14d8f4d444 303 void Calibrating()
ThomBMT 1:ba14d8f4d444 304 {
ThomBMT 3:766e9f13d84e 305 // Calibration is done to ensure that threshold values not predetermined and
ThomBMT 3:766e9f13d84e 306 // can vary each user. This makes the system more universal.
ThomBMT 3:766e9f13d84e 307
ThomBMT 1:ba14d8f4d444 308 static float n = 0.0;
ThomBMT 1:ba14d8f4d444 309 static float m = 0.0;
ThomBMT 1:ba14d8f4d444 310 static float l = 0.0;
ThomBMT 1:ba14d8f4d444 311 static float k = 0.0;
ThomBMT 1:ba14d8f4d444 312
ThomBMT 1:ba14d8f4d444 313 ii++;
ThomBMT 1:ba14d8f4d444 314
ThomBMT 1:ba14d8f4d444 315 if (ii<=2500)
ThomBMT 1:ba14d8f4d444 316 {
ThomBMT 1:ba14d8f4d444 317 if (ii == 1)
ThomBMT 1:ba14d8f4d444 318 {
ThomBMT 1:ba14d8f4d444 319 pc.printf("Relax your muscles please. \r\n");
ThomBMT 1:ba14d8f4d444 320 i = 2;
ThomBMT 1:ba14d8f4d444 321 }
ThomBMT 1:ba14d8f4d444 322 else if (ii == 1750)
ThomBMT 1:ba14d8f4d444 323 {
ThomBMT 1:ba14d8f4d444 324 pc.printf("Flex your right bicep now please.\r\n");
ThomBMT 1:ba14d8f4d444 325 i = 3;
ThomBMT 1:ba14d8f4d444 326 }
ThomBMT 1:ba14d8f4d444 327 //chillen
ThomBMT 1:ba14d8f4d444 328 }
ThomBMT 1:ba14d8f4d444 329 else if (ii>2500 && ii<5000) //
ThomBMT 1:ba14d8f4d444 330 {
ThomBMT 1:ba14d8f4d444 331 n = n + Filtered_Bi_R; // dit wordt de variable naam na het filter
ThomBMT 1:ba14d8f4d444 332 i = 1;
ThomBMT 1:ba14d8f4d444 333 }
ThomBMT 1:ba14d8f4d444 334 else if (ii == 5000)
ThomBMT 1:ba14d8f4d444 335 {
ThomBMT 1:ba14d8f4d444 336 Flex_Bi_R = n / 2500.0f;
ThomBMT 1:ba14d8f4d444 337 pc.printf("You can relax your right bicep, thank you. \r\nYour mean flexing value was %f\r\n\r\n", Flex_Bi_R);
ThomBMT 1:ba14d8f4d444 338 i = 2;
ThomBMT 1:ba14d8f4d444 339 }
ThomBMT 1:ba14d8f4d444 340 else if (ii>5000 && ii<=6000)
ThomBMT 1:ba14d8f4d444 341 {
ThomBMT 1:ba14d8f4d444 342 if (ii == 5500)
ThomBMT 1:ba14d8f4d444 343 {
ThomBMT 1:ba14d8f4d444 344 pc.printf("Flex your left bicep now please. \r\n");
ThomBMT 1:ba14d8f4d444 345 i = 3;
ThomBMT 1:ba14d8f4d444 346 }
ThomBMT 1:ba14d8f4d444 347 //chillen
ThomBMT 1:ba14d8f4d444 348 }
ThomBMT 1:ba14d8f4d444 349 else if(ii>6000 && ii<8500)
ThomBMT 1:ba14d8f4d444 350 {
ThomBMT 1:ba14d8f4d444 351 m = m + Filtered_Bi_L;
ThomBMT 1:ba14d8f4d444 352 i = 1;
ThomBMT 1:ba14d8f4d444 353 }
ThomBMT 1:ba14d8f4d444 354 else if (ii == 8500)
ThomBMT 1:ba14d8f4d444 355 {
ThomBMT 1:ba14d8f4d444 356 Flex_Bi_L = m / 2500.0f;
ThomBMT 1:ba14d8f4d444 357 pc.printf("You can relax your left bicep, thank you. \r\nYour mean flexing value was %f\r\n\r\n", Flex_Bi_L);
ThomBMT 1:ba14d8f4d444 358 i = 2;
ThomBMT 1:ba14d8f4d444 359 }
ThomBMT 1:ba14d8f4d444 360 else if (ii>8500 && ii<=9500)
ThomBMT 1:ba14d8f4d444 361 {
ThomBMT 1:ba14d8f4d444 362 if (ii == 9000)
ThomBMT 1:ba14d8f4d444 363 {
ThomBMT 1:ba14d8f4d444 364 pc.printf("Flex your right tricep now please. \r\n");
ThomBMT 1:ba14d8f4d444 365 i = 3;
ThomBMT 1:ba14d8f4d444 366 }
ThomBMT 1:ba14d8f4d444 367 //chillen
ThomBMT 1:ba14d8f4d444 368 }
ThomBMT 1:ba14d8f4d444 369 else if (ii>9500 && ii<12000)
ThomBMT 1:ba14d8f4d444 370 {
ThomBMT 1:ba14d8f4d444 371 l = l + Filtered_Tri_R;
ThomBMT 1:ba14d8f4d444 372 i = 1;
ThomBMT 1:ba14d8f4d444 373 }
ThomBMT 1:ba14d8f4d444 374 else if (ii == 12000)
ThomBMT 1:ba14d8f4d444 375 {
ThomBMT 1:ba14d8f4d444 376 Flex_Tri_R = l / 2500.0f;
ThomBMT 1:ba14d8f4d444 377 pc.printf("You can relax your right tricep, thank you. \r\nYour mean flexing value was %f\r\n\r\n", Flex_Tri_R);
ThomBMT 1:ba14d8f4d444 378 i = 2;
ThomBMT 1:ba14d8f4d444 379 }
ThomBMT 1:ba14d8f4d444 380 else if (ii>12000 && ii <=13000)
ThomBMT 1:ba14d8f4d444 381 {
ThomBMT 1:ba14d8f4d444 382 if (ii == 12500)
ThomBMT 1:ba14d8f4d444 383 {
ThomBMT 1:ba14d8f4d444 384 pc.printf("Flex your left tricep now please. \r\n");
ThomBMT 1:ba14d8f4d444 385 i = 3;
ThomBMT 1:ba14d8f4d444 386 }
ThomBMT 1:ba14d8f4d444 387 //chillen
ThomBMT 1:ba14d8f4d444 388 }
ThomBMT 1:ba14d8f4d444 389 else if (ii>13000 && ii<15500)
ThomBMT 1:ba14d8f4d444 390 {
ThomBMT 1:ba14d8f4d444 391 k = k + Filtered_Tri_L;
ThomBMT 1:ba14d8f4d444 392 i = 1;
ThomBMT 1:ba14d8f4d444 393 }
ThomBMT 1:ba14d8f4d444 394 else if (ii == 15500)
ThomBMT 1:ba14d8f4d444 395 {
ThomBMT 1:ba14d8f4d444 396 Flex_Tri_L = k / 2500.0f;
ThomBMT 1:ba14d8f4d444 397 pc.printf("You can relax your left tricep, thank you. \r\nYour mean flexing value was %f\r\n\r\nThe calibration has been completed, the system is now operatable. \r\n",Flex_Tri_L);
ThomBMT 1:ba14d8f4d444 398 i = 2;
ThomBMT 1:ba14d8f4d444 399 }
ThomBMT 3:766e9f13d84e 400
ThomBMT 3:766e9f13d84e 401 // Setting the Threshold:
ThomBMT 1:ba14d8f4d444 402 Threshold_Value = 0.8f;
ThomBMT 1:ba14d8f4d444 403
ThomBMT 1:ba14d8f4d444 404 Threshold_Bi_R = Threshold_Value * Flex_Bi_R;
ThomBMT 1:ba14d8f4d444 405 Threshold_Bi_L = Threshold_Value * Flex_Bi_L;
ThomBMT 1:ba14d8f4d444 406 Threshold_Tri_R = Threshold_Value * Flex_Tri_R;
ThomBMT 1:ba14d8f4d444 407 Threshold_Tri_L = Threshold_Value * Flex_Tri_L;
ThomBMT 1:ba14d8f4d444 408
ThomBMT 1:ba14d8f4d444 409 if (ii == 16500)
ThomBMT 1:ba14d8f4d444 410 {
ThomBMT 1:ba14d8f4d444 411 pc.printf("\r\nThreshold value right bicep = %f\r\nThreshold value left bicep = %f\r\nThreshold value right tricep = %f\r\nThreshold value left tricep = %f\r\n\r\n",Threshold_Bi_R,Threshold_Bi_L,Threshold_Tri_R,Threshold_Tri_L);
ThomBMT 1:ba14d8f4d444 412 }
ThomBMT 1:ba14d8f4d444 413 else if (ii == 20000)
ThomBMT 1:ba14d8f4d444 414 {
ThomBMT 3:766e9f13d84e 415 pc.printf("\r\nAutomatic switch to Homing State for Motor 1\r\n");
ThomBMT 1:ba14d8f4d444 416 Active_State = Homing_M1;
ThomBMT 1:ba14d8f4d444 417 i = 0;
ThomBMT 1:ba14d8f4d444 418 }
ThomBMT 1:ba14d8f4d444 419 }
ThomBMT 1:ba14d8f4d444 420
ThomBMT 1:ba14d8f4d444 421
ThomBMT 1:ba14d8f4d444 422
ThomBMT 1:ba14d8f4d444 423 void Start_Up()
ThomBMT 1:ba14d8f4d444 424 {
ThomBMT 3:766e9f13d84e 425 // This function is active only when the system is started up or when the
ThomBMT 3:766e9f13d84e 426 // system has entered Sleep_Mode (iii > 40 000).
ThomBMT 3:766e9f13d84e 427 // It is not possible to get out of this function without some opperation on
ThomBMT 3:766e9f13d84e 428 // the Mbed.
ThomBMT 3:766e9f13d84e 429
ThomBMT 1:ba14d8f4d444 430 i++;
ThomBMT 1:ba14d8f4d444 431 iii++;
ThomBMT 1:ba14d8f4d444 432 if (iii == 1)
ThomBMT 1:ba14d8f4d444 433 {
ThomBMT 1:ba14d8f4d444 434 pc.printf("\r\n\r\nSystem is starting...\r\nWaiting for further input...\r\n");
ThomBMT 1:ba14d8f4d444 435 }
ThomBMT 1:ba14d8f4d444 436
ThomBMT 1:ba14d8f4d444 437 else if (iii == 30000)
ThomBMT 1:ba14d8f4d444 438 {
ThomBMT 1:ba14d8f4d444 439 pc.printf("1 minute without input..\r\nReseting start-up...\r\n");
ThomBMT 1:ba14d8f4d444 440 iii = 0;
ThomBMT 1:ba14d8f4d444 441 }
ThomBMT 1:ba14d8f4d444 442 else if (iii == 40001) // sleeping state is only added for designing purposes and will most likely never be used
ThomBMT 1:ba14d8f4d444 443 { // when working with patients. Furthermore it cannot be reached automaticly
ThomBMT 1:ba14d8f4d444 444 pc.printf("Sleeping... Press button 4 to wake me up!\r\n\r\n");
ThomBMT 1:ba14d8f4d444 445 iii++;
ThomBMT 1:ba14d8f4d444 446 }
ThomBMT 1:ba14d8f4d444 447 else if (iii == 45000)
ThomBMT 1:ba14d8f4d444 448 {
ThomBMT 1:ba14d8f4d444 449 iii = 40000;
ThomBMT 1:ba14d8f4d444 450 }
ThomBMT 1:ba14d8f4d444 451 }
ThomBMT 1:ba14d8f4d444 452
ThomBMT 1:ba14d8f4d444 453 void OFF_m1()
ThomBMT 1:ba14d8f4d444 454 {
ThomBMT 3:766e9f13d84e 455 // This function ensures that Motor 1 is turned off.
ThomBMT 3:766e9f13d84e 456
ThomBMT 1:ba14d8f4d444 457 PwmPin1 = 0;
ThomBMT 1:ba14d8f4d444 458 }
ThomBMT 1:ba14d8f4d444 459 void OFF_m2()
ThomBMT 1:ba14d8f4d444 460 {
ThomBMT 3:766e9f13d84e 461 // This function ensures that Motor 2 is turned off.
ThomBMT 3:766e9f13d84e 462
ThomBMT 1:ba14d8f4d444 463 PwmPin2 = 0;
ThomBMT 1:ba14d8f4d444 464 }
ThomBMT 1:ba14d8f4d444 465
ThomBMT 1:ba14d8f4d444 466 void Going_Home_Motor1()
ThomBMT 1:ba14d8f4d444 467 {
ThomBMT 3:766e9f13d84e 468 // This is the Homing function for Motor 1.
ThomBMT 3:766e9f13d84e 469
ThomBMT 1:ba14d8f4d444 470 if (counts1 == 0)
ThomBMT 1:ba14d8f4d444 471 {
ThomBMT 3:766e9f13d84e 472 pc.printf("Switching to Homing State for Motor 2\r\n");
ThomBMT 1:ba14d8f4d444 473 Active_State = Homing_M2; // Statement here instead of statemachine because of checking speed
ThomBMT 1:ba14d8f4d444 474 }
ThomBMT 1:ba14d8f4d444 475 else if (counts1 > 0)
ThomBMT 1:ba14d8f4d444 476 {
ThomBMT 1:ba14d8f4d444 477 PwmPin1 = 0.8f;
ThomBMT 1:ba14d8f4d444 478 DirectionPin1 = false;
ThomBMT 1:ba14d8f4d444 479 }
ThomBMT 1:ba14d8f4d444 480 else
ThomBMT 1:ba14d8f4d444 481 {
ThomBMT 1:ba14d8f4d444 482 PwmPin1 = 0.8f;
ThomBMT 1:ba14d8f4d444 483 DirectionPin1 = true;
ThomBMT 1:ba14d8f4d444 484 }
ThomBMT 1:ba14d8f4d444 485 }
ThomBMT 1:ba14d8f4d444 486
ThomBMT 1:ba14d8f4d444 487 void Going_Home_Motor2()
ThomBMT 1:ba14d8f4d444 488 {
ThomBMT 3:766e9f13d84e 489 // This is the Homing function for Motor 2.
ThomBMT 3:766e9f13d84e 490
ThomBMT 1:ba14d8f4d444 491 if (counts2 == 0)
ThomBMT 1:ba14d8f4d444 492 {
ThomBMT 1:ba14d8f4d444 493 // als het goed is hoeft hier niets te staan // Statement in statemachine because of the double check
ThomBMT 1:ba14d8f4d444 494 }
ThomBMT 1:ba14d8f4d444 495 else if (counts2 > 0)
ThomBMT 1:ba14d8f4d444 496 {
ThomBMT 1:ba14d8f4d444 497 PwmPin2 = 0.8f;
ThomBMT 1:ba14d8f4d444 498 DirectionPin2 = true;
ThomBMT 1:ba14d8f4d444 499 }
ThomBMT 1:ba14d8f4d444 500 else
ThomBMT 1:ba14d8f4d444 501 {
ThomBMT 1:ba14d8f4d444 502 PwmPin2 = 0.8f;
ThomBMT 1:ba14d8f4d444 503 DirectionPin2 = false;
ThomBMT 1:ba14d8f4d444 504 }
ThomBMT 1:ba14d8f4d444 505 }
ThomBMT 1:ba14d8f4d444 506
ThomBMT 1:ba14d8f4d444 507 void Checking_EMG()
ThomBMT 1:ba14d8f4d444 508 {
ThomBMT 3:766e9f13d84e 509 // This function will make the the setting of signal to movement easier.
ThomBMT 1:ba14d8f4d444 510
ThomBMT 1:ba14d8f4d444 511 if (Filtered_Bi_R >= Threshold_Bi_R)
ThomBMT 1:ba14d8f4d444 512 {
ThomBMT 1:ba14d8f4d444 513 Checking_Bi_R = true;
ThomBMT 1:ba14d8f4d444 514 }
ThomBMT 1:ba14d8f4d444 515 if (Filtered_Bi_L >= Threshold_Bi_L)
ThomBMT 1:ba14d8f4d444 516 {
ThomBMT 1:ba14d8f4d444 517 Checking_Bi_L = true;
ThomBMT 1:ba14d8f4d444 518 }
ThomBMT 1:ba14d8f4d444 519 if (Filtered_Tri_R >= Threshold_Tri_R)
ThomBMT 1:ba14d8f4d444 520 {
ThomBMT 1:ba14d8f4d444 521 Checking_Tri_R = true;
ThomBMT 1:ba14d8f4d444 522 }
ThomBMT 1:ba14d8f4d444 523 if (Filtered_Tri_L >= Threshold_Tri_L)
ThomBMT 1:ba14d8f4d444 524 {
ThomBMT 1:ba14d8f4d444 525 Checking_Tri_L = true;
ThomBMT 1:ba14d8f4d444 526 }
ThomBMT 1:ba14d8f4d444 527 }
ThomBMT 1:ba14d8f4d444 528
ThomBMT 1:ba14d8f4d444 529 void Setting_Movement()
ThomBMT 1:ba14d8f4d444 530 {
ThomBMT 3:766e9f13d84e 531 // Here we will set the emg values to the movement of the arm.
ThomBMT 1:ba14d8f4d444 532
ThomBMT 1:ba14d8f4d444 533 if (Checking_Bi_R && Checking_Bi_L) // sloping y = x, y > 0
ThomBMT 1:ba14d8f4d444 534 {
ThomBMT 1:ba14d8f4d444 535 vx = 0.5f;
ThomBMT 1:ba14d8f4d444 536 vy = 0.5f;
ThomBMT 1:ba14d8f4d444 537 }
ThomBMT 1:ba14d8f4d444 538 else if (Checking_Bi_R && Checking_Tri_L) // sloping y = -x, y > 0
ThomBMT 1:ba14d8f4d444 539 {
ThomBMT 1:ba14d8f4d444 540 vx = -0.5f;
ThomBMT 1:ba14d8f4d444 541 vy = 0.5f;
ThomBMT 1:ba14d8f4d444 542 }
ThomBMT 1:ba14d8f4d444 543 else if (Checking_Bi_L && Checking_Tri_R) // sloping y = -x, y < 0
ThomBMT 1:ba14d8f4d444 544 {
ThomBMT 1:ba14d8f4d444 545 vx = 0.5f;
ThomBMT 1:ba14d8f4d444 546 vy = -0.5f;
ThomBMT 1:ba14d8f4d444 547 }
ThomBMT 1:ba14d8f4d444 548 else if (Checking_Tri_R && Checking_Tri_L) // sloping y = x, y < 0
ThomBMT 1:ba14d8f4d444 549 {
ThomBMT 1:ba14d8f4d444 550 vx = -0.5f;
ThomBMT 1:ba14d8f4d444 551 vy = -0.5f;
ThomBMT 1:ba14d8f4d444 552 }
ThomBMT 1:ba14d8f4d444 553 else if (Checking_Bi_R) // y > 0
ThomBMT 1:ba14d8f4d444 554 {
ThomBMT 1:ba14d8f4d444 555 vx = 0.0f;
ThomBMT 1:ba14d8f4d444 556 vy = 0.5f;
ThomBMT 1:ba14d8f4d444 557 }
ThomBMT 1:ba14d8f4d444 558 else if (Checking_Bi_L) // x > 0
ThomBMT 1:ba14d8f4d444 559 {
ThomBMT 1:ba14d8f4d444 560 vx = 0.5f;
ThomBMT 1:ba14d8f4d444 561 vy = 0.0f;
ThomBMT 1:ba14d8f4d444 562 }
ThomBMT 1:ba14d8f4d444 563 else if (Checking_Tri_R) // y < 0
ThomBMT 1:ba14d8f4d444 564 {
ThomBMT 1:ba14d8f4d444 565 vx = 0.0f;
ThomBMT 1:ba14d8f4d444 566 vy = -0.5f;
ThomBMT 1:ba14d8f4d444 567 }
ThomBMT 1:ba14d8f4d444 568 else if (Checking_Tri_L) // y < 0
ThomBMT 1:ba14d8f4d444 569 {
ThomBMT 1:ba14d8f4d444 570 vx = -0.5f;
ThomBMT 1:ba14d8f4d444 571 vy = 0.0f;
ThomBMT 1:ba14d8f4d444 572 }
ThomBMT 1:ba14d8f4d444 573 }
ThomBMT 1:ba14d8f4d444 574
ThomBMT 2:bc6043623fb7 575 void PID_controller()
ThomBMT 2:bc6043623fb7 576 {
ThomBMT 3:766e9f13d84e 577 // The PID-controller reduces the error between the reference signal
ThomBMT 3:766e9f13d84e 578 // and the actual value.
ThomBMT 3:766e9f13d84e 579
ThomBMT 2:bc6043623fb7 580 error_1 = (w_1*0.002f) - rad_m1;
ThomBMT 2:bc6043623fb7 581 error_2 = (w_2*0.002f) - rad_m2;
ThomBMT 2:bc6043623fb7 582
ThomBMT 2:bc6043623fb7 583 error_1_prev = error_1;
ThomBMT 2:bc6043623fb7 584 error_2_prev = error_2;
ThomBMT 2:bc6043623fb7 585
ThomBMT 2:bc6043623fb7 586 // Proportional part:
ThomBMT 2:bc6043623fb7 587 float u_k_1 = Kp * error_1;
ThomBMT 2:bc6043623fb7 588 float u_k_2 = Kp * error_2;
ThomBMT 2:bc6043623fb7 589
ThomBMT 2:bc6043623fb7 590 // Integral part
ThomBMT 2:bc6043623fb7 591 error_1_integral = error_1_integral + error_1 * Ts;
ThomBMT 2:bc6043623fb7 592 error_2_integral = error_2_integral + error_2 * Ts;
ThomBMT 2:bc6043623fb7 593 float u_i_1 = Ki * error_1_integral;
ThomBMT 2:bc6043623fb7 594 float u_i_2 = Ki * error_2_integral;
ThomBMT 2:bc6043623fb7 595
ThomBMT 2:bc6043623fb7 596 // Derivative part
ThomBMT 2:bc6043623fb7 597 float error_1_derivative = (error_1 - error_1_prev)/Ts;
ThomBMT 2:bc6043623fb7 598 float error_2_derivative = (error_2 - error_2_prev)/Ts;
ThomBMT 2:bc6043623fb7 599 float filtered_error_1_derivative = LowPassFilter.step(error_1_derivative);
ThomBMT 2:bc6043623fb7 600 float filtered_error_2_derivative = LowPassFilter.step(error_2_derivative);
ThomBMT 2:bc6043623fb7 601 float u_d_1 = Kd * filtered_error_1_derivative;
ThomBMT 2:bc6043623fb7 602 float u_d_2 = Kd * filtered_error_2_derivative;
ThomBMT 2:bc6043623fb7 603 error_1_prev = error_1;
ThomBMT 2:bc6043623fb7 604 error_2_prev = error_2;
ThomBMT 2:bc6043623fb7 605
ThomBMT 2:bc6043623fb7 606 // Sum all parts and return it
ThomBMT 2:bc6043623fb7 607 U_1 = u_k_1 + u_i_1 + u_d_1;
ThomBMT 2:bc6043623fb7 608 U_2 = u_k_2 + u_i_2 + u_d_2;
ThomBMT 2:bc6043623fb7 609 }
ThomBMT 2:bc6043623fb7 610
ThomBMT 2:bc6043623fb7 611 void motor1()
ThomBMT 3:766e9f13d84e 612 {
ThomBMT 3:766e9f13d84e 613 // This is where Motor 1 is opperated.
ThomBMT 3:766e9f13d84e 614
ThomBMT 2:bc6043623fb7 615 float u = U_1;
ThomBMT 2:bc6043623fb7 616 DirectionPin1 = u < 0.0f;
ThomBMT 2:bc6043623fb7 617 PwmPin1 = fabs(u);
ThomBMT 2:bc6043623fb7 618 }
ThomBMT 2:bc6043623fb7 619
ThomBMT 2:bc6043623fb7 620 void motor2()
ThomBMT 2:bc6043623fb7 621 {
ThomBMT 3:766e9f13d84e 622 // This is where Motor 2 is opperated.
ThomBMT 3:766e9f13d84e 623
ThomBMT 2:bc6043623fb7 624 float u = U_2;
ThomBMT 2:bc6043623fb7 625 DirectionPin2 = u > 0.0f;
ThomBMT 2:bc6043623fb7 626 PwmPin2 = fabs(u);
ThomBMT 2:bc6043623fb7 627 }
ThomBMT 2:bc6043623fb7 628
ThomBMT 1:ba14d8f4d444 629 void Printing()
ThomBMT 1:ba14d8f4d444 630 {
ThomBMT 3:766e9f13d84e 631 // This function is merely for printing feedback from the system to our
ThomBMT 3:766e9f13d84e 632 // screen when we wish to see or check something.
ThomBMT 3:766e9f13d84e 633
ThomBMT 1:ba14d8f4d444 634 float v1 = PwmPin1 * maxVelocity;
ThomBMT 1:ba14d8f4d444 635 float v2 = PwmPin2 * maxVelocity;
ThomBMT 1:ba14d8f4d444 636
ThomBMT 3:766e9f13d84e 637 if (Active_State == Function )//|| Active_State == Homing_M1)
ThomBMT 1:ba14d8f4d444 638 {
ThomBMT 1:ba14d8f4d444 639 pc.printf("q1 = %f [rad] \r\nq2 = %f [rad] \r\ncount1= %i\r\ncount2= %i\r\nq1dot = %f [rad/s] \r\nq2dot = %f [rad/s] \r\n\r\n\r\n\r\n\r\n", rad_m1, rad_m2,counts1, counts2, v1, v2);
ThomBMT 1:ba14d8f4d444 640 }
ThomBMT 1:ba14d8f4d444 641 }
ThomBMT 1:ba14d8f4d444 642
ThomBMT 2:bc6043623fb7 643 void EMG_test() // even nalopen of dit ook kan met i++!
ThomBMT 1:ba14d8f4d444 644 {
ThomBMT 3:766e9f13d84e 645 // Here we can check the opperation of the system for checking purposes.
ThomBMT 3:766e9f13d84e 646
ThomBMT 1:ba14d8f4d444 647 led_G=led_R=led_B=1;
ThomBMT 1:ba14d8f4d444 648
ThomBMT 1:ba14d8f4d444 649 if (Filtered_Bi_R >= Threshold_Bi_R)
ThomBMT 1:ba14d8f4d444 650 {
ThomBMT 1:ba14d8f4d444 651 i = 1;
ThomBMT 1:ba14d8f4d444 652 //led_R = 0; // rood
ThomBMT 1:ba14d8f4d444 653 }
ThomBMT 1:ba14d8f4d444 654 if (Filtered_Bi_L >= Threshold_Bi_L)
ThomBMT 1:ba14d8f4d444 655 {
ThomBMT 1:ba14d8f4d444 656 i = 3;
ThomBMT 1:ba14d8f4d444 657 //led_B = 0; // blauw
ThomBMT 1:ba14d8f4d444 658 }
ThomBMT 1:ba14d8f4d444 659 if (Filtered_Tri_R >= Threshold_Tri_R)
ThomBMT 1:ba14d8f4d444 660 {
ThomBMT 1:ba14d8f4d444 661 i = 2;
ThomBMT 1:ba14d8f4d444 662 //led_G = 0; // groen
ThomBMT 1:ba14d8f4d444 663 }
ThomBMT 1:ba14d8f4d444 664 if (Filtered_Tri_L >= Threshold_Tri_L)
ThomBMT 1:ba14d8f4d444 665 {
ThomBMT 1:ba14d8f4d444 666 i = 4;
ThomBMT 1:ba14d8f4d444 667 //led_B = 0;
ThomBMT 1:ba14d8f4d444 668 //led_R = 0; // paars
ThomBMT 1:ba14d8f4d444 669 }
ThomBMT 1:ba14d8f4d444 670
ThomBMT 1:ba14d8f4d444 671 }
ThomBMT 1:ba14d8f4d444 672
ThomBMT 1:ba14d8f4d444 673 void StateMachine()
ThomBMT 1:ba14d8f4d444 674 {
ThomBMT 3:766e9f13d84e 675 // In the Statemachine every function is integrated into the system
ThomBMT 3:766e9f13d84e 676 // depending on the state that the system is in. This is makes the
ThomBMT 3:766e9f13d84e 677 // integration and the opperation of the system a lot simpeler.
ThomBMT 3:766e9f13d84e 678
ThomBMT 3:766e9f13d84e 679 // We have 5 main states:
ThomBMT 3:766e9f13d84e 680 // - Starting
ThomBMT 3:766e9f13d84e 681 // - Start_Up
ThomBMT 3:766e9f13d84e 682 // - Sleep_Mode
ThomBMT 3:766e9f13d84e 683 // - Calibration
ThomBMT 3:766e9f13d84e 684 // - Homing
ThomBMT 3:766e9f13d84e 685 // - Homing_M1
ThomBMT 3:766e9f13d84e 686 // - Homing_M2
ThomBMT 3:766e9f13d84e 687 // - Post_Homing
ThomBMT 3:766e9f13d84e 688 // - Function
ThomBMT 3:766e9f13d84e 689 // - Safe
ThomBMT 3:766e9f13d84e 690
ThomBMT 3:766e9f13d84e 691 // As seen above some states have substates that make the system run better
ThomBMT 3:766e9f13d84e 692 // or give the state some unique features. These are explained within the
ThomBMT 3:766e9f13d84e 693 // functions that are called in that state.
ThomBMT 3:766e9f13d84e 694
ThomBMT 1:ba14d8f4d444 695 switch (Active_State)
ThomBMT 1:ba14d8f4d444 696 {
ThomBMT 1:ba14d8f4d444 697 case Starting:
ThomBMT 1:ba14d8f4d444 698 Start_Up();
ThomBMT 1:ba14d8f4d444 699 OFF_m1();
ThomBMT 1:ba14d8f4d444 700 OFF_m2();
ThomBMT 1:ba14d8f4d444 701
ThomBMT 1:ba14d8f4d444 702 if (!Knop4 == true)
ThomBMT 1:ba14d8f4d444 703 {
ThomBMT 1:ba14d8f4d444 704 Active_State = Calibration;
ThomBMT 1:ba14d8f4d444 705 pc.printf("Entering Calibration State \r\n");
ThomBMT 1:ba14d8f4d444 706 }
ThomBMT 1:ba14d8f4d444 707 else if (!Knop3 == true)
ThomBMT 1:ba14d8f4d444 708 {
ThomBMT 1:ba14d8f4d444 709 Active_State = Homing_M1;
ThomBMT 1:ba14d8f4d444 710 pc.printf("Entering Homing State \r\n");
ThomBMT 1:ba14d8f4d444 711 }
ThomBMT 1:ba14d8f4d444 712
ThomBMT 1:ba14d8f4d444 713
ThomBMT 1:ba14d8f4d444 714 break;
ThomBMT 1:ba14d8f4d444 715
ThomBMT 1:ba14d8f4d444 716 case Calibration:
ThomBMT 1:ba14d8f4d444 717
ThomBMT 1:ba14d8f4d444 718 Filter();
ThomBMT 1:ba14d8f4d444 719 Calibrating();
ThomBMT 1:ba14d8f4d444 720 OFF_m1();
ThomBMT 1:ba14d8f4d444 721 OFF_m2();
ThomBMT 1:ba14d8f4d444 722 BlinkLed();
ThomBMT 1:ba14d8f4d444 723
ThomBMT 1:ba14d8f4d444 724 if (!Knop1 && !Knop2)
ThomBMT 1:ba14d8f4d444 725 {
ThomBMT 1:ba14d8f4d444 726 pc.printf("Switched to Sleeping State\r\n");
ThomBMT 1:ba14d8f4d444 727 Active_State = Starting;
ThomBMT 1:ba14d8f4d444 728 iii = 40001;
ThomBMT 1:ba14d8f4d444 729 }
ThomBMT 1:ba14d8f4d444 730 else if (Knop1==false)
ThomBMT 1:ba14d8f4d444 731 {
ThomBMT 1:ba14d8f4d444 732 pc.printf("Manual switch to Homing state \r\n");
ThomBMT 1:ba14d8f4d444 733 Active_State = Homing_M1;
ThomBMT 1:ba14d8f4d444 734 }
ThomBMT 1:ba14d8f4d444 735
ThomBMT 1:ba14d8f4d444 736
ThomBMT 1:ba14d8f4d444 737 sample();
ThomBMT 2:bc6043623fb7 738 EMG_Read();
ThomBMT 1:ba14d8f4d444 739 break;
ThomBMT 1:ba14d8f4d444 740
ThomBMT 1:ba14d8f4d444 741 case Homing_M1:
ThomBMT 1:ba14d8f4d444 742
ThomBMT 1:ba14d8f4d444 743 Going_Home_Motor1();
ThomBMT 1:ba14d8f4d444 744 OFF_m2();
ThomBMT 2:bc6043623fb7 745 Encoding();
ThomBMT 1:ba14d8f4d444 746
ThomBMT 1:ba14d8f4d444 747 if (fabs(rad_m1)>(pi/6.0f) || fabs(rad_m2)>(pi/6.0f)) // pi/4 is a safe value, can/will be editted
ThomBMT 1:ba14d8f4d444 748 {
ThomBMT 1:ba14d8f4d444 749 pc.printf("SAFE MODUS ACTIVE!\r\n RESET MANDATORY!\r\n");
ThomBMT 1:ba14d8f4d444 750 Active_State = Safe;
ThomBMT 1:ba14d8f4d444 751 }
ThomBMT 1:ba14d8f4d444 752 else if (!Knop1 && !Knop2)
ThomBMT 1:ba14d8f4d444 753 {
ThomBMT 1:ba14d8f4d444 754 pc.printf("Switched to Sleeping State\r\n");
ThomBMT 1:ba14d8f4d444 755 Active_State = Starting;
ThomBMT 1:ba14d8f4d444 756 iii = 40000;
ThomBMT 1:ba14d8f4d444 757 }
ThomBMT 1:ba14d8f4d444 758 else if (Knop2==false)
ThomBMT 1:ba14d8f4d444 759 {
ThomBMT 1:ba14d8f4d444 760 pc.printf("Manual switch to Funtioning State \r\n");
ThomBMT 1:ba14d8f4d444 761 Active_State = Function;
ThomBMT 1:ba14d8f4d444 762 }
ThomBMT 1:ba14d8f4d444 763 else if (Knop4==false)
ThomBMT 1:ba14d8f4d444 764 {
ThomBMT 1:ba14d8f4d444 765 Active_State = Calibration;
ThomBMT 1:ba14d8f4d444 766 pc.printf("Re-entering Calibration State \r\n");
ThomBMT 1:ba14d8f4d444 767 }
ThomBMT 2:bc6043623fb7 768
ThomBMT 1:ba14d8f4d444 769 break;
ThomBMT 1:ba14d8f4d444 770
ThomBMT 1:ba14d8f4d444 771 case Homing_M2:
ThomBMT 1:ba14d8f4d444 772
ThomBMT 1:ba14d8f4d444 773 Going_Home_Motor2();
ThomBMT 1:ba14d8f4d444 774 OFF_m1();
ThomBMT 2:bc6043623fb7 775 Encoding();
ThomBMT 1:ba14d8f4d444 776
ThomBMT 1:ba14d8f4d444 777 if (fabs(rad_m1)>(pi/6.0f) || fabs(rad_m2)>(pi/6.0f)) // pi/4 is a safe value, can/will be editted
ThomBMT 1:ba14d8f4d444 778 {
ThomBMT 1:ba14d8f4d444 779 pc.printf("SAFE MODUS ACTIVE!\r\n RESET MANDATORY!\r\n");
ThomBMT 1:ba14d8f4d444 780 Active_State = Safe;
ThomBMT 1:ba14d8f4d444 781 }
ThomBMT 1:ba14d8f4d444 782 else if (counts2 == 0 && counts1 == 0)
ThomBMT 1:ba14d8f4d444 783 {
ThomBMT 1:ba14d8f4d444 784 Active_State = Post_Homing;
ThomBMT 1:ba14d8f4d444 785 }
ThomBMT 1:ba14d8f4d444 786
ThomBMT 1:ba14d8f4d444 787 break;
ThomBMT 1:ba14d8f4d444 788
ThomBMT 1:ba14d8f4d444 789 case Post_Homing:
ThomBMT 1:ba14d8f4d444 790
ThomBMT 1:ba14d8f4d444 791 static int mm = 0;
ThomBMT 1:ba14d8f4d444 792 mm++;
ThomBMT 1:ba14d8f4d444 793 if (mm == 1000);
ThomBMT 1:ba14d8f4d444 794 {
ThomBMT 1:ba14d8f4d444 795 Active_State = Function;
ThomBMT 1:ba14d8f4d444 796 pc.printf("Homing was succesfull\r\n\r\nAutomatic switch to Funtioning state\r\n\r\n");
ThomBMT 1:ba14d8f4d444 797 mm=0; // reseting the state
ThomBMT 1:ba14d8f4d444 798 }
ThomBMT 1:ba14d8f4d444 799
ThomBMT 1:ba14d8f4d444 800 OFF_m1();
ThomBMT 1:ba14d8f4d444 801 OFF_m2();
ThomBMT 1:ba14d8f4d444 802 break;
ThomBMT 1:ba14d8f4d444 803
ThomBMT 1:ba14d8f4d444 804 case Function:
ThomBMT 2:bc6043623fb7 805
ThomBMT 2:bc6043623fb7 806 EMG_test();
ThomBMT 2:bc6043623fb7 807 Filter();
ThomBMT 2:bc6043623fb7 808 Inverse();
ThomBMT 2:bc6043623fb7 809 sample();
ThomBMT 2:bc6043623fb7 810 EMG_Read();
ThomBMT 2:bc6043623fb7 811 Encoding();
ThomBMT 2:bc6043623fb7 812 Checking_EMG();
ThomBMT 2:bc6043623fb7 813 Setting_Movement();
ThomBMT 2:bc6043623fb7 814 PID_controller();
ThomBMT 2:bc6043623fb7 815 motor1();
ThomBMT 2:bc6043623fb7 816 motor2();
ThomBMT 1:ba14d8f4d444 817
ThomBMT 1:ba14d8f4d444 818 if (fabs(rad_m1)>(pi/6.0f) || fabs(rad_m2)>(pi/6.0f)) // pi/4 is a safe value, can/will be editted
ThomBMT 1:ba14d8f4d444 819 {
ThomBMT 1:ba14d8f4d444 820 pc.printf("SAFE MODUS ACTIVE!\r\n RESET MANDATORY!\r\n");
ThomBMT 1:ba14d8f4d444 821 Active_State = Safe;
ThomBMT 1:ba14d8f4d444 822 }
ThomBMT 1:ba14d8f4d444 823 else if (Knop4==false)
ThomBMT 1:ba14d8f4d444 824 {
ThomBMT 1:ba14d8f4d444 825 pc.printf("Re-entering Calibration State \r\n");
ThomBMT 1:ba14d8f4d444 826 Active_State = Calibration;
ThomBMT 1:ba14d8f4d444 827 ii=0;
ThomBMT 1:ba14d8f4d444 828 }
ThomBMT 1:ba14d8f4d444 829 else if (Knop3==false)
ThomBMT 1:ba14d8f4d444 830 {
ThomBMT 1:ba14d8f4d444 831 pc.printf("Re-entering Homing State \r\n");
ThomBMT 1:ba14d8f4d444 832 Active_State = Homing_M1;
ThomBMT 1:ba14d8f4d444 833 }
ThomBMT 1:ba14d8f4d444 834 else if (!Knop1 && !Knop2)
ThomBMT 1:ba14d8f4d444 835 {
ThomBMT 1:ba14d8f4d444 836 pc.printf("Switched to Sleeping State\r\n");
ThomBMT 1:ba14d8f4d444 837 Active_State = Starting;
ThomBMT 1:ba14d8f4d444 838 iii = 40000;
ThomBMT 1:ba14d8f4d444 839 }
ThomBMT 2:bc6043623fb7 840
ThomBMT 1:ba14d8f4d444 841 break;
ThomBMT 1:ba14d8f4d444 842
ThomBMT 1:ba14d8f4d444 843 case Safe:
ThomBMT 1:ba14d8f4d444 844
ThomBMT 1:ba14d8f4d444 845 OFF_m1();
ThomBMT 1:ba14d8f4d444 846 OFF_m2();
ThomBMT 1:ba14d8f4d444 847
ThomBMT 1:ba14d8f4d444 848 break;
ThomBMT 1:ba14d8f4d444 849
ThomBMT 1:ba14d8f4d444 850 default:
ThomBMT 1:ba14d8f4d444 851 pc.printf("UNKNOWN COMMAND");
ThomBMT 1:ba14d8f4d444 852 }
ThomBMT 1:ba14d8f4d444 853 }
ThomBMT 1:ba14d8f4d444 854
ThomBMT 1:ba14d8f4d444 855 int main()
ThomBMT 1:ba14d8f4d444 856 {
ThomBMT 3:766e9f13d84e 857 // Our main loop is as empty as possible and contains only statements that
ThomBMT 3:766e9f13d84e 858 // cannot be put elsewhere due to functioning reasons.
ThomBMT 3:766e9f13d84e 859 // Also the "while-loop" is completely empty, which improves the running
ThomBMT 3:766e9f13d84e 860 // speed of the system.
ThomBMT 3:766e9f13d84e 861
ThomBMT 1:ba14d8f4d444 862 pc.baud(115200);
ThomBMT 1:ba14d8f4d444 863 PwmPin1.period_us(30); //60 microseconds pwm period, 16.7 kHz
ThomBMT 1:ba14d8f4d444 864
ThomBMT 1:ba14d8f4d444 865 bqc1.add( &BqNotch1_1 ).add( &BqNotch2_1 ).add( &BqHP1 ); //Oh wat lelijk...
ThomBMT 1:ba14d8f4d444 866 bqc2.add(&BqLP1);
ThomBMT 1:ba14d8f4d444 867 bqc3.add( &BqNotch1_2 ).add( &BqNotch2_2 ).add( &BqHP2 );
ThomBMT 1:ba14d8f4d444 868 bqc4.add(&BqLP2);
ThomBMT 1:ba14d8f4d444 869 bqc5.add( &BqNotch1_3 ).add( &BqNotch2_3 ).add( &BqHP3 );
ThomBMT 1:ba14d8f4d444 870 bqc6.add(&BqLP3);
ThomBMT 1:ba14d8f4d444 871 bqc7.add( &BqNotch1_4 ).add( &BqNotch2_4 ).add( &BqHP4 );
ThomBMT 1:ba14d8f4d444 872 bqc8.add(&BqLP4);
ThomBMT 1:ba14d8f4d444 873
ThomBMT 1:ba14d8f4d444 874 StateTicker.attach(&StateMachine, 0.002);
ThomBMT 1:ba14d8f4d444 875
ThomBMT 1:ba14d8f4d444 876 printTicker.attach(&Printing, 2);
ThomBMT 1:ba14d8f4d444 877
ThomBMT 1:ba14d8f4d444 878 while(true)
ThomBMT 1:ba14d8f4d444 879 {
ThomBMT 1:ba14d8f4d444 880 }
ThomBMT 1:ba14d8f4d444 881 }