not working yet
Dependencies: Motor_with_encoder MODSERIAL mbed HIDScope
main.cpp
- Committer:
- EvB
- Date:
- 2017-10-23
- Revision:
- 10:39a97906fa4b
- Parent:
- 9:d4927ec5862f
File content as of revision 10:39a97906fa4b:
#include "mbed.h" #include "MODSERIAL.h" #include "encoder.h" #include "math.h" #include "HIDScope.h" #include "BiQuad.h" #include "EMG_filter.h" MODSERIAL pc(USBTX,USBRX); // ---- EMG parameters ---- HIDScope scope (2); EMG_filter emg1(A0); float emgthreshold = 0.20; double MVC = 0.0; // ------------------------ // ---- Motor input and outputs ---- PwmOut speed1(D5); PwmOut speed2(D6); DigitalOut dir1(D4); DigitalOut dir2(D7); DigitalIn press(PTA4); DigitalOut led1(D8); DigitalOut led2(D11); AnalogIn pot(A2); AnalogIn pot2(A1); Encoder motor1(PTD0,PTC4); Encoder motor2(D12,D13); // ---------------------------------- // --- Define Ticker and Timeout --- Ticker mainticker; //Ticker that calls every function. Functions are called by means of a variable named go, e.g. go_EMG Timeout calibrationgo; // Timeout that will determine the duration of the calibration. // --------------------------------- float PwmPeriod = 0.0001f; double count = 0; //set the counts of the encoder double countmax = 0; //counter to find max peak of EMG signal every second volatile double angle = 0;//set the angles double count2 = 0; //set the counts of the encoder volatile double angle2 = 0;//set the angles double setpoint;//I am setting it to move through 180 degrees double setpoint2 = 6.28;//I am setting it to move through 180 degrees double Kp = 250;// you can set these constants however you like depending on trial & error double Ki = 100; double Kd = 0; float last_error = 0; float error1 = 0; float changeError = 0; float totalError = 0; float pidTerm = 0; float pidTerm_scaled = 0; float last_error2 = 0; float error2 = 0; float changeError2 = 0; float totalError2 = 0; float pidTerm2 = 0; float pidTerm_scaled2 = 0;// if the total gain we get is not in the PWM range we scale it down so that it's not bigger than |255| volatile double potvalue = 0.0; volatile double potvalue2 = 0.0; volatile double position = 0.0; volatile double position2 = 0.0; // --- Booleans for the maintickerfunction --- //bool readoutsetpoint = true; bool go_EMG; // Boolean to put on/off the EMG readout bool go_calibration; // Boolean to put on/off the calibration of the EMG // ------------------------------------------- // --- calibrate EMG signal ---- void calibrationGO() // Function for go or no go of calibration { go_calibration = false; led2 = 0; } /* Calibration of the robot works as follows: EMG signal is read out for 5 seconds, 1000 times a second. This signal is filtered and the maximum value is compared to the current value of the MVC. The value of the MVC is overwritten when the value of the filtered signal is bigger than the current value. During the calibration the user should exert maximum force. */ void calibrationEMG() // Function for calibrating the EMG signal { if (go_calibration) { led2 = 1; emg1.calibration(); // Using the calibration function of the EMG_filter class } } // ------------------------------ //Function that reads out the raw EMG and filters the signal void processEMG () { led1 = 1; //go_EMG = false; //set the variable to false --> misschien nodig? emg1.filter(); //filter the incoming emg signal //emg2.filter(); //emg3.filter(); scope.set(0, emg1.normalized); //views emg1.normalized on port 0 of HIDScope scope.set(1, emg1.emg0); scope.send(); } double peakdetection () { if (emg1.normalized>=MVC) { MVC = emg1.normalized; } countmax++; if(countmax==100 && MVC>=emgthreshold) { setpoint = MVC*6.50; //setpoint in translational direction (cm). EMG output (0.2-1.0) scaled to maximal translation distance (52 cm). countmax = 0; MVC = 0; } return setpoint; } /*void setpointreadout() { potvalue = pot.read(); potvalue2 = pot2.read(); setpoint2 = potvalue2*6.28f; }*/ void PIDcalculation() // inputs: potvalue, motor#, setpoint { setpoint = peakdetection(); angle = motor1.getPosition()/4200.00; angle2 = motor2.getPosition()/4200.00*6.28; //pc.printf("pos: %d, speed %f reference position = %.2f\r ",motor1.getPosition(), motor1.getSpeed(), setpoint); //motorpid = PID(potvalue - position, M1_KP, M1_KI, M1_KD, M1_TS, m1_err_int, m1_prev_err, m1_f_v1, m1_f_v2, M1_F_A1, M1_F_A2, M1_F_B0, M1_F_B1, M1_F_B2); error1 = setpoint - angle; error2 = setpoint2 - angle2; changeError = (error1 - last_error)/0.001f; // derivative term totalError += error1*0.001f; //accumalate errors to find integral term pidTerm = (Kp * error1) + (Ki * totalError) + (Kd * changeError);//total gain pidTerm = pidTerm; if (pidTerm >= 1000) { pidTerm = 1000; } else if (pidTerm <= -1000) { pidTerm = -1000; } else { pidTerm = pidTerm; } //constraining to appropriate value if (pidTerm >= 0) { dir1 = 1;// Forward motion } else { dir1 = 0;//Reverse motion } pidTerm_scaled = abs(pidTerm)/1000.0f; //make sure it's a positive value if(pidTerm_scaled >= 0.55f){ pidTerm_scaled = 0.55f; } changeError2 = (error2 - last_error2)/0.001f; // derivative term totalError2 += error2*0.001f; //accumalate errors to find integral term pidTerm2 = (Kp * error2) + (Ki * totalError2) + (Kd * changeError2);//total gain pidTerm2 = pidTerm2; if (pidTerm2 >= 1000) { pidTerm2 = 1000; } else if (pidTerm2 <= -1000) { pidTerm2 = -1000; } else { pidTerm2 = pidTerm2; } //constraining to appropriate value if (pidTerm2 >= 0) { dir2 = 1;// Forward motion } else { dir2 = 0;//Reverse motion } pidTerm_scaled2 = abs(pidTerm2)/1000.0f; //make sure it's a positive value if(pidTerm_scaled2 >= 0.55f){ pidTerm_scaled2 = 0.55f; } last_error = error1; speed1 = pidTerm_scaled+0.45f; last_error2 = error2; speed2 = pidTerm_scaled2+0.45f; } void maintickerfunction() { if(go_EMG) { processEMG(); } PIDcalculation(); } int main() { go_EMG = true; // Setting ticker variables go_calibration = true; // Setting the timeout variable speed1.period(PwmPeriod); speed2.period(PwmPeriod); calibrationgo.attach(&calibrationGO, 5.0); // Attach calibration timeout to calibration function mainticker.attach(&calibrationEMG, 0.001f); // Attach ticker to the calibration function wait(5.0f); mainticker.attach(&maintickerfunction,0.001f); int count = 0; while(true) { count++; if(count == 100){ count = 0; pc.printf("Angle = %f, pidTerm = %f ,PID_scaled = %f, Error = %f, setpoint = %f, MVC = %f\r\n", angle, pidTerm ,pidTerm_scaled, error1,setpoint,MVC); // pc.printf("Angle 2 = %f, pidTerm 2 = %f ,PID_scaled 2 = %f, Error 2 = %f, setpoint 2 = %f\r\n", angle2, pidTerm2 ,pidTerm_scaled2, error2,setpoint2); } wait(0.001f); } }