Alle subfiles samengevoegd
Dependencies: HIDScope biquadFilter mbed MODSERIAL FastPWM QEI
Diff: main.cpp
- Revision:
- 0:c96cf9760185
- Child:
- 1:e1267e72ade8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Oct 20 11:15:59 2016 +0000 @@ -0,0 +1,346 @@ +#include "mbed.h" +#include "HIDScope.h" +#include "BiQuad.h" +#include "math.h" +#include "iostream" +#define SERIAL_BAUD 115200 + +Serial pc(USBTX,USBRX); +//EMG aansluitingen +AnalogIn emg0( A0 ); //Biceps Rechts +AnalogIn emg1( A1 ); //Bicpes Links +AnalogIn emg2( A2 ); //Upper leg +//Leds +DigitalOut led(LED1); // lampje om te zien dat het programma werkt +DigitalOut led2(LED2); +DigitalOut led3(LED3); +//HIDScope +HIDScope scope( 6 ); // aantal channels op de HIDscope +//Button om Calibratie te beëindigen +InterruptIn Button1(PTC6); // DIT WORDT EEN ANDERE BUTTON + +// Tickers +Ticker sample_timer; +Ticker TickerCalculationsForTheta; + +//BiQuad +// making the biquads and chains; imported from matlab +BiQuadChain bqc; //Chain for right biceps +BiQuadChain bqc2; //Chain for left biceps +BiQuadChain bqc3; //Chain for Upper leg +// 1 to 3 are for right biceps +BiQuad bq1( 9.14969e-01, -1.82994e+00, 9.14969e-01, -1.82269e+00, 8.37182e-01 ); +BiQuad bq2( 9.91104e-01, -1.60364e+00, 9.91104e-01, -1.60364e+00, 9.82207e-01 ); +BiQuad bq3( 8.76555e-05, 1.75311e-04, 8.76555e-05, -1.97334e+00, 9.73695e-01 ); +// 4 to 6 are for left biceps +BiQuad bq4( 9.14969e-01, -1.82994e+00, 9.14969e-01, -1.82269e+00, 8.37182e-01 ); +BiQuad bq5( 9.91104e-01, -1.60364e+00, 9.91104e-01, -1.60364e+00, 9.82207e-01 ); +BiQuad bq6( 8.76555e-05, 1.75311e-04, 8.76555e-05, -1.97334e+00, 9.73695e-01 ); +// 7 to 9 are for upper leg +BiQuad bq7( 9.14969e-01, -1.82994e+00, 9.14969e-01, -1.82269e+00, 8.37182e-01 ); +BiQuad bq8( 9.91104e-01, -1.60364e+00, 9.91104e-01, -1.60364e+00, 9.82207e-01 ); +BiQuad bq9( 3.91302e-05, 7.82604e-05, 3.91302e-05, -1.98223e+00, 9.82385e-01 ); + +// Variabelen voor filter +// spier EMG niet boven treshhold +volatile bool BicepsLeft = false; +volatile bool BicepsRight = false; +volatile bool Leg = false; +// filtergo uit zetten, zodat deze niet fout gaat. +volatile bool filtergo = false; + +// Variabelen voor MotorHoekBerekenen +double x = 0.0; // beginpositie x en y +double y = 305.5; +volatile const double pi = 3.14159265359; +double Theta1Gear = 1.0/3.0*pi; // Beginpositie op 60 graden +double Theta2Gear = 1.0/3.0*pi; +double Theta1 = Theta1Gear*42/12; // Beginpositie van MotorHoek +double Theta2 = Theta2Gear*42/12; +double Fr_Speed_Theta = 100.0; // frequentie in Hz waarmee theta wordt uigerekend +bool Calibration = true; // beginnen met calibreren +volatile bool Stepper_State = false; // false = we zijn niet bezig met flippen + +/////////////////////// functies voor filters ///////////////////////////////////////////// +void sample() +{ + /* Sample function + samples the emg0 (of the rightBiceps) + samples the emg1 (of the leftBiceps) + samples the emg2 (of the Upper leg) + filter the singals + sends it to HIDScope + */ + + // Rechts Biceps + double inRechts = emg0.read(); // EMG signal + double FilterRechts = bqc.step(inRechts); // High pass + Notch (50 HZ) + double RectifyRechts = fabs(FilterRechts); // Rectify + double outRechts = bq3.step(RectifyRechts); // Low pass + + // Links Biceps + double inLinks = emg1.read(); // EMG signal + double FilterLinks = bqc2.step(inLinks); // High pass + Notch (50 HZ) + double RectifyLinks = fabs(FilterLinks); // Rectify + double outLinks = bq6.step(RectifyLinks); // Low pass + + // Upper leg + double inBeen = emg2.read(); // EMG signal + double FilterBeen = bqc3.step(inBeen); // High pass + Notch (50 HZ) + double RectifyBeen = fabs(FilterBeen); // Rectify + double outBeen = bq9.step(RectifyBeen); // Low pass + + + + /* EMG signal in channel 0 (the first channel) + and the filtered EMG signal in channel 1 (the second channel) + of the HIDscope */ + scope.set(0,inRechts); + scope.set(1,outRechts); + scope.set(2,inLinks); + scope.set(3,outLinks); + scope.set(4,inBeen); + scope.set(5,outBeen); + + // send all channels to the PC at once + scope.send(); + + // To indicate that the function is working, the LED is on + if (outRechts >= 0.015){ + led2 = 0; + led = 1; + BicepsRight = true; + } + else{ + led2 = 1; + led = 0; + BicepsRight = false; + } + + // If Biceps links is actuated then: + if (outLinks >= 0.015){ + led3 = 0; + led = 1; + BicepsLeft = true; + } + else{ + led3 = 1; + led = 0; + BicepsLeft = false; + } + // If upper leg is actuated then: + if (outBeen >= 0.01){ + led3 = 0; + led2 = 0; + led = 1; + Leg = true; + } + else{ + led3 = 1; + led2 = 1; + led = 0; + Leg = false; + } + filtergo = false; +} + +// zet de filter aan +void filter() + { + filtergo=true; + } + +///////////////////// functies voor motorhoekberekenen ////////////////////////// +// vorige x berekenen +double Calc_Prev_x () { + double Prev_x = x; + //pc.printf("prev x = %f\r\n", Prev_x); + return Prev_x; +} + +// vorige y berekenen +double Calc_Prev_y () { + double Prev_y = y; + //pc.printf("prev y = %f\r\n", Prev_y); + return Prev_y; +} + +// berekenen van de nieuwe x en y waardes +bool CalcXY (bool BicepsLeft, bool BicepsRight, bool Leg, bool Stepper_State) { + double Step = 10/Fr_Speed_Theta ; //10 mm per seconde afleggen + + if (BicepsLeft==true && BicepsRight==true && Leg==true && Stepper_State==false) { + Stepper_State = true; // we zijn aan het flipper dus geen andere dingen doen + // flipper functie aanroepen + } + else if (BicepsLeft==true && BicepsRight==false && Leg==false && Stepper_State==false) { + x = x - Step; + } + else if (BicepsLeft==false && BicepsRight==true && Leg==false && Stepper_State==false) { + x = x + Step; // naar Right bewegen + } + else if (BicepsLeft==true && BicepsRight==true && Leg==false && Stepper_State==false) { + y = y + Step; // naar voren bewegen + } + else if (BicepsLeft==false && BicepsRight==true && Leg==true && Stepper_State==false) { + y = y - Step; // naar achter bewegen + } + else if (BicepsLeft==false && BicepsRight==false && Leg==false || Stepper_State==true) { + } + + // Grenswaardes LET OP: ARMEN MISSCHIEN GEBLOKKEERD DOOR BALK AAN DE BINNENKANT + if (x > 200) { + x = 200; + } + else if (x < -200) { + x = -200; + } + if (y > 306) { + y = 306; + } + else if (y < 50) { + y = 50; // GOKJE, UITPROBEREN + } + pc.printf("x = %f, y = %f\r\n", x, y); + + return Stepper_State; +} + +// diagonaal berekenen voor linker arm +double CalcDia1 (double x, double y) { + double a = 50.0; // de afstand van gekozen assenstelsel tot de armas (assenstelsel precies in het midden) KEERTJE NAMETEN + double BV1 = sqrt(pow((a+x),2) + pow(y,2)); // diagonaal (afstand van armas tot locatie) berekenen + double Dia1 = pow(BV1,2)/(2*BV1); // berekenen van de afstand oorsprong tot diagonaal + + //pc.printf("dia = %f, x = %f, y= %f\r\n", Dia1, x, y); + return Dia1; +} + +// diagonaal berekenen voor rechter arm +double CalcDia2 (double x, double y) { + double a = 50.0; + double BV2 = sqrt(pow((x-a),2) + pow(y,2)); // zelfde nog een keer doen maar nu voor de rechter arm + double Dia2 = pow(BV2,2)/(2*BV2); + + //pc.printf("dia = %f, x = %f, y= %f\r\n", Dia2, x, y); + return Dia2; +} + +// calculate Theta1 +void CalcTheta1 (double Dia1, double Prev_x, double Prev_y) { + double a = 50.0; + double Bar = 200.0; // lengte van de armen + double Prev_Theta1_Gear = Theta1Gear; + double MaxThetaGear = pi - 30.0*pi/180.0; // de hoek voordat arm het opstakel raakt (max hoek is 24.9 tussen arm en opstakel) + + // Hoek berekenen van het grote tandwiel (gear) + if (x > -a) { + Theta1Gear = pi - atan(y/(x+a)) - acos(Dia1/Bar); + } + else if (x > -a) { + Theta1Gear = pi - (pi + atan(y/(x+a))) - acos(Dia1/Bar); + } + else { // als x=-a + Theta1Gear = 0.5*pi - acos(Dia1/Bar); + } + + // limiten (als de hoek te groot wordt, reset dan de hoek en de x en y waardes) + if (Theta1Gear >= MaxThetaGear) { // is de maximale hoek in radialen + Theta1Gear = Prev_Theta1_Gear; + x = Prev_x; + y = Prev_y; + } + + // omrekenen van grote tandwiel naar motortandwiel + Theta1 = Theta1Gear*42.0/12.0; // grote tandwiel heeft 42 tanden. Motortandwiel heeft er 12. + + pc.printf("thetaMotor = %f, thetaGear = %f, Prev_Gear = %f\r\n", Theta1, Theta1Gear, Prev_Theta1_Gear); +} + +void CalcTheta2 (double Dia2, double Prev_x, double Prev_y) { + double a = 50.0; + double Bar = 200.0; // lengte van de armen + double Prev_Theta2_Gear = Theta2Gear; + double MaxThetaGear = pi - 30.0*pi/180.0; // de hoek voordat arm het opstakel raakt (max hoek is 24.9 tussen arm en opstakel) + + // Hoek berekenen van het grote tandwiel (gear) + if (x < a) { + Theta2Gear = pi + atan(y/(x-a)) - acos(Dia2/Bar); + } + else if (x > a) { + Theta2Gear = pi - (pi - atan(y/(x-a))) - acos(Dia2/Bar); + } + else { // als x=a + Theta2Gear = 0.5*pi - acos(Dia2/Bar); + } + + // limiten (als de hoek te groot wordt, reset dan de hoek en de x en y waardes) + if (Theta2Gear >= MaxThetaGear) { + Theta2Gear = Prev_Theta2_Gear; + x = Prev_x; + y = Prev_y; + } + + // omrekenen van grote tandwiel naar motortandwiel + Theta2 = Theta2Gear*42.0/12.0; // grote tandwiel heeft 42 tanden. Motortandwiel heeft er 12. + + pc.printf("thetaMotor = %f, thetaGear = %f, Prev_Gear = %f\r\n", Theta2, Theta2Gear, Prev_Theta2_Gear); +} + +void CalculationsForTheta () { + double Prev_x = Calc_Prev_x (); + double Prev_y = Calc_Prev_y (); + bool Stepper_State = CalcXY (BicepsLeft, BicepsRight, Leg, Stepper_State); + double Dia1 = CalcDia1 (x, y); + double Dia2 = CalcDia2 (x, y); + CalcTheta1 (Dia1, Prev_x, Prev_y); + CalcTheta2 (Dia2, Prev_x, Prev_y); +} + +// als de button ingedrukt wordt dan stoppen we met calibreren +void EndCalibration () { + Calibration = false; +} + +//////////////// functies voor aansturing motoren /////////////////////////////// + + + +////////////////////////// main loop //////////////////////////////////////////// +int main() +{ + pc.baud(SERIAL_BAUD); + pc.printf("\r\n Nieuwe code uitproberen :) \r\n"); + + /* making the biquad chain for filtering the emg + notch and high pass */ + bqc.add( &bq1 ).add( &bq2 ); + bqc2.add( &bq4 ).add( &bq5 ); + bqc3.add( &bq7 ).add( &bq8 ); + + // Calibreren + while (Calibration == true) { + // potmeter dingen aanpassen + + pc.printf("calibreren is bezig\r\n"); + Button1.fall(&EndCalibration); + } + + /**Attach the 'sample' function to the timer 'sample_timer'. + * this ensures that 'sample' is executed every 0.002 seconds = 500 Hz + */ + sample_timer.attach(&filter, 0.002); + + // extra stap, zodat er geen op onthoudt komt. + while (filtergo == true) + { + sample(); + } + + // ticker voor hoek berekenen aanzetten + TickerCalculationsForTheta.attach(&CalculationsForTheta,2); ///Fr_Speed_Theta + + + //empty loop, sample() is executed periodically + while(1) {} +} \ No newline at end of file