Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: Demo_TEST3 QEI biquadFilter mbed
Fork of Demo_TEST3 by
Revision 8:1efebfebe733, committed 2018-10-30
- Comitter:
- SilHeuvelink
- Date:
- Tue Oct 30 12:17:35 2018 +0000
- Parent:
- 7:b53f0c4cf2b9
- Child:
- 9:d5c561b3ea5a
- Commit message:
- test1
Changed in this revision
QEI.lib | Show annotated file Show diff for this revision Revisions of this file |
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QEI.lib Tue Oct 30 12:17:35 2018 +0000 @@ -0,0 +1,1 @@ +http://os.mbed.com/users/aberk/code/QEI/#5c2ad81551aa
--- a/main.cpp Fri Oct 26 10:24:09 2018 +0000 +++ b/main.cpp Tue Oct 30 12:17:35 2018 +0000 @@ -2,279 +2,101 @@ #include "math.h" #include "BiQuad.h" #include "Servo.h" - - - +#include <string> +#include "QEI.h" -//Define objects -AnalogIn emgL(A0); // EMG Left Arm -AnalogIn emgR(A1); // EMG Right Arm -AnalogIn emgS(A2); // EMG Servo spier -DigitalOut ledB(LED_BLUE); // Informative LED for gaining zero and max -DigitalOut ledR(LED_RED); -DigitalOut ledG(LED_GREEN); // Informative LED for gaining zero and max -DigitalIn CalButton(PTA4); // Button used for gaining zero and max -DigitalIn zeromax(PTC6); // Button used for switching between zero and max -Ticker emgSampleTicker; // Ticker for sample frequency - -Servo myservo(D9); +//-----------------GET ENCODER VALUES ------------------------- +QEI Encoder1(D12,D13,NC,64,QEI::X2_ENCODING); +QEI Encoder2(D2,D3,NC,64,QEI::X2_ENCODING); +Ticker EncoderTicker; DigitalOut motor1direction(D7); PwmOut motor1control(D6); - + DigitalOut motor2direction(D4); PwmOut motor2control(D5); - -InterruptIn button1(D10); -InterruptIn button2(D11); - - int P= 200; // Number of points for movag first emg - int Q = 200; // Number of points for movag second emg - int R = 200; // Number of points for movag third emg - double A[200]; // Vector for storing data of first emg - double B[200]; // Vector for storing data of second emg - double C[200]; // Vector for storing data of third emg - int k = 0; // Counter for configuration: - double Lvector[200]; // Vector for Rwaarde configuration - double Lwaarde[2]; // Vector for storage of max and zero of left biceps - double Rvector[200]; // Vector for Lwaarde configuration - double Rwaarde[2]; // Vector for storage of max and zero of right biceps - double Svector[200]; // Vector for Swaarde configuration - double Swaarde[2]; // Vector for storage of max and zero of servo emg - int x = 0; // Variable for switching between zero and max - double movagR; // Moving Average mean value of right biceps - double movagL; // Moving Average mean value of left biceps - double movagS; // Moving Average mean value of servo spier - float thresholdL = 10; // Startvalue for threshold, to block signals - - float thresholdR = 10; // - before the zero and max values are calculated - float thresholdS = 10; //------- -const bool clockwise1 = true; //Clockwise direction for motor 1 -const bool clockwise2 = true; //Clockwise direction for motor 2 -volatile bool direction1 = clockwise1; //Bool to make direction 1 clockwise -volatile bool direction2 = clockwise2; //Bool to make direction 2 clockwise - - //------------Filter parameters---------------------- +void EncoderFunc() { + + const float pi = 3.141592653589793; // Value of pi + double gearratio = 3.857142857; + double radiuspulley = 0.015915; // Radius pulley [m] + double hoekgraad = Encoder1.getPulses() * 0.0857142857; // Angle arm [degree] + double hoekrad = hoekgraad * 0.0174532925; + double hoekgraad2 = Encoder2.getPulses() * 0.0857142857; + double hoekrad2 = hoekgraad2 * 0.0174532925; + double hoekarm = hoekgraad2 / gearratio; + double translatie = hoekgraad /360 * 2 * pi * radiuspulley; // Translatie arm [m] + } -//Lowpassfilter -//const double b0LP = 0.0014831498359569692; -//const double b1LP = 0.0029662996719139385; -//const double b2LP = 0.0014831498359569692; -//const double a1LP = -1.918570032544273; -//const double a2LP = 0.9245026318881009; -//Highpassfilter Fc = 10 Hz;, Q = 0.5, Fs = 500 Hz -const double b0HP = 0.8851221317817073; -const double b1HP = -1.7702442635634146; -const double b2HP = 0.8851221317817073; -const double a1HP = -1.7632371847263784; -const double a2HP = 0.777251342400451; -//Notchfilter Fc = 50 Hz, Q = 10, Fs = 500 Hz -const double b0NO = 0.9714498065192796; -const double b1NO = -1.5718388053127037; -const double b2NO = 0.9714498065192796; -const double a1NO = -1.5718388053127037; -const double a2NO = 0.9428996130385592; +//----------------INVERSE KINEMATICS --------------------------- +double K_v = 1; // Velocity constant (VALUE???) Maximaal 6.6667 +double L0 = 0.09; + +int main() +{ +EncoderTicker.attach(&EncoderFunc, 1); -//--------------Filter------------ -//BiQuad LPR( b0LP, b1LP, b2LP, a1LP, a2LP ); //Lowpass filter Biquad -BiQuad HPR( b0HP, b1HP, b2HP, a1HP, a2HP ); //Highpass filter Biquad -BiQuad NOR( b0NO, b1NO, b2NO, a1NO, a2NO ); //Notch filter Biquad +double p_old_x = (translatie+L0)*cos(hoekgraad); // Everytime the x-value from encoder calculated +double p_old_y = (translatie+L0)*sin(hoekgraad); // Everytime the y-value from encoder calculated -//BiQuad LPL( b0LP, b1LP, b2LP, a1LP, a2LP ); //Lowpass filter Biquad -BiQuad HPL( b0HP, b1HP, b2HP, a1HP, a2HP ); //Highpass filter Biquad -BiQuad NOL( b0NO, b1NO, b2NO, a1NO, a2NO ); //Notch filter Biquad - -//BiQuad LPS( b0LP, b1LP, b2LP, a1LP, a2LP ); //Lowpass filter Biquad -BiQuad HPS( b0HP, b1HP, b2HP, a1HP, a2HP ); //Highpass filter Biquad -BiQuad NOS( b0NO, b1NO, b2NO, a1NO, a2NO ); //Notch filter Biquad +double J_inv_1_1 = -sin(hoekgraad)/translatie; +double J_inv_1_2 = cos(hoekgraad)/translatie; +double J_inv_2_1 = cos(hoekgraad); +double J_inv_2_2 = sin(hoekgraad); -void emgSample() { // EMG function - - double emgNOFilteredL = NOL.step(emgL.read()); // Filtered NO value of EMG signal left biceps - double emgHPFilteredL = HPL.step(emgNOFilteredL); // Filtered HP value of EMG signal left biceps - double emgabsL = fabs(emgHPFilteredL); // Absolute value of EMG signal left biceps - - - double emgNOFilteredR = NOR.step(emgR.read()); // Filtered NO value of EMG signal right biceps - double emgHPFilteredR = HPR.step(emgNOFilteredR); // Filtered HP value of EMG signal right biceps - double emgabsR = fabs(emgHPFilteredR); // Absolute value of EMG signal right biceps - - - double emgNOFilteredS = NOS.step(emgS.read()); // Filtered NO value of EMG signal servo spier - double emgHPFilteredS = HPS.step(emgNOFilteredS); // Filtered HP value of EMG signal servo spier - double emgabsS = fabs(emgHPFilteredS); // Absolute value of EMG signal servo spier - - - - -//-------------------Linker bicep------------------------------------- +// Demo path: rectangular + double x_path[5]; // Matrix heeft 5 elementen: beginnend vanaf element 0 tot en met element 4 + x_path[0] = L0; + x_path[1] = L0; + x_path[2] = L0+0.15; + x_path[3] = L0+0.15; + x_path[4] = x_path[0]; + + double y_path[5]; + y_path[0] = 0.0; + y_path[1] = 0.1; + y_path[2] = 0.1; + y_path[3] = 0.0; + y_path[4] = y_path[0]; + +// for loop +for(int i=0 ; i<=4 ; i++) + { + double p_new_x = x_path[i]; + double p_new_y = y_path[i]; - for(int i = P-1; i >= 0; i--){ // For-loop used for moving average - if (i == 0) { - A[i] = emgabsL; - } - else { - A[i] = A[i-1]; - } - } - double sumL = 0; - for (int n = 0; n < P-1; n++) { // Summation of array - sumL = sumL + A[n]; - } - movagL = sumL/P; - - + double p_dot_new_x = K_v * (p_new_x - p_old_x); + double p_dot_new_y = K_v * (p_new_y - p_old_y); -//--------------Rechter bicep--------------------------------------- - - for(int i = Q-1; i >= 0; i--){ // For-loop used for moving average - if (i == 0) { - B[i] = emgabsR; - } - else { - B[i] = B[i-1]; - } - } - double sumR = 0; - - for (int n = 0; n < Q-1; n++) { // Summation of array - sumR = sumR + B[n]; - } - movagR = sumR/Q; // Moving average value right biceps - -//---------------Servo spier ------------------------------------ + // printf("x=%f , y=%f , p_dot_new_x=%f , p_dot_new_y=%f\n",p_new_x,p_new_y,p_dot_new_x,p_dot_new_y); - for(int i = R-1; i >= 0; i--){ // For-loop used for moving average - if (i == 0) { - C[i] = emgabsS; - } - else { - C[i] = C[i-1]; - } - } - double sumS = 0; - for (int n = 0; n < R-1; n++) { // Summation of array - sumS = sumS + C[n]; - } - movagS = sumS/R; + double angle_old = atan(p_old_y/p_old_x)*180/pi; + double L_old = sqrt(pow(p_old_x,2)+pow(p_old_y,2)); + + double angle_new = atan(p_new_y/p_new_x)*180/pi; + double L_new = sqrt(pow(p_new_x,2)+pow(p_new_y,2)); + + if (angle_new - angle_old) <= 0 + { + motor1direction.write(direction1 = !direction1); + } - /* Set the sampled emg values in channel 0 (the first channel) and 1 (the second channel) in the 'HIDScope' instance named 'scope' */ - //scope.set(0, emgL.read()); -// scope.set(1, movagL); -// scope.set(2, emgR.read()); -// scope.set(3, movagR); -// scope.set(4, emgS.read()); -// scope.set(5, movagS); - /* Repeat the step above if required for more channels of required (channel 0 up to 5 = 6 channels) - * Ensure that enough channels are available (HIDScope scope( 2 )) - * Finally, send all channels to the PC at once */ - // scope.send(); // Moving average value left biceps - - - if (CalButton==0 & k<200) { // Loop used for gaining max and zero value - Lvector[k] = movagL; - Rvector[k] = movagR; - Svector[k] = movagS; - - if (x==0){ - ledB = !ledB; // SPIER NIET AANSPANNEN BIJ BLAUW - } // SPIER WEL AANSPANNEN BIJ ROOD - else if (x==1){ - ledR = !ledR; - } - k++; - } - else if (k==200) { // End of the loop, used for calculation value - double sumY = 0; - double sumZ = 0; - double sumX = 0; - for (int n = 0; n < 199; n++) { - sumY = sumY + Lvector[n]; - sumZ = sumZ + Rvector[n]; - sumX = sumX + Svector[n]; - } - Lwaarde[x] = sumY/200; // Value of zero for left biceps - Rwaarde[x] = sumZ/200; // Value of zero for right biceps - Swaarde[x] = sumX/200; // Value of zero for Servo spier - k++; - ledB = 1; - ledR = 1; - ledG = !ledG; - } - else if (k == 201 && zeromax ==0) { // Loop used for switching between zero and max - ledG = !ledG; - k = 0; - if (x==0) { - x++; - } - else if (x==1) { - x=0; + if (L_new - L_old) <= 0 + { + motor2direction.write(direction2 = !direction2); + } + + while ( (fabs(p_new_x - p_old_x)) > 0.005 || (fabs(p_new_y - p_old_y)) > 0.005 ) + { + double q_dot_angle = J_inv_1_1 * p_dot_new_x + J_inv_1_2 * p_dot_new_y; //hoekgraad1 + double q_dot_L = J_inv_2_1 * p_dot_new_x + J_inv_2_2 * p_dot_new_y; //translatie + double q_dot_q2 = q_dot_L/radiuspulley; //hoekgraad2 (translatie) + motor1control.write(q_dot_angle); + wait(0.1); + motor2control.write(q_dot_q2); + wait(0.1); // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Berekening niet tegelijk, eventuele fout? %%% } } - if (x==1) // Determining threshold using zero and max - { - thresholdL = Lwaarde[0]+(Lwaarde[1]-Lwaarde[0])*(0.25f); - thresholdR = Rwaarde[0]+(Rwaarde[1]-Rwaarde[0])*(0.25f); - thresholdS = Swaarde[0]+(Swaarde[1]-Swaarde[0])*(0.25f); - } -} -//----------------Buttons to change direction motors---------------------------- -void onButtonPress1() { - // reverses the direction - motor1direction.write(direction1 = !direction1); - //pc.printf("direction: %s\r\n\n", direction ? "clockwise" : "counter clockwise"); -} - -void onButtonPress2() { - // reverses the direction - motor2direction.write(direction2 = !direction2); - //pc.printf("direction: %s\r\n\n", direction ? "clockwise" : "counter clockwise"); -} - -int main() -{ -ledB = 1; -ledG = 1; -ledR = 1; -emgSampleTicker.attach( &emgSample, 0.002 ); // Ticker for EMG function -Lwaarde[0] = 0.01; // Startvalue for zerovalue, to - -Rwaarde[0] = 0.01; // - prevent dividing by 0 -Swaarde[0] = 0.01; - - button1.fall(&onButtonPress1); - button2.fall(&onButtonPress2); - - while(1) { - - - - if (movagL > thresholdL) - { motor1control.write(0.12); - wait(0.1); - } - else { - motor1control.write(0); - wait(0.1); - } - - if (movagR > thresholdR) - { motor2control.write(0.8); - wait(0.1); - } - else { - motor2control.write(0); - wait(0.1); - } - - - if (movagS > thresholdS) - { myservo = 0.5; - wait(0.01); - } - else { - myservo = 0.0; - wait(0.01); - } - } } \ No newline at end of file