merged EMG and PID codes
Dependencies: FastPWM HIDScope MODSERIAL QEI biquadFilter mbed
Diff: main.cpp
- Revision:
- 0:d02f4c7e8906
- Child:
- 1:ffa6f4d78c8e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Oct 26 08:45:24 2016 +0000 @@ -0,0 +1,140 @@ +#include "mbed.h" +#include "FastPWM.h" +#include "MODSERIAL.h" +#include "QEI.h" +#include "HIDScope.h" //make sure hidscope cable is also attached +#include "BiQuad.h" + +// in gebruik: D(0,1,4,5,6,7,10,11,12,13) + +DigitalOut motor1dir(D7); //direction of motor 1, attach at m1, set to 0: cw +FastPWM motor1(D6); // speed of motor 1 +FastPWM motor2(D5); //speed of motor 2 +DigitalOut motor2dir(D4); //direction of motor 2, attach at m2, set to 0: ccw + +Ticker control; //Ticker for processing encoder input +volatile bool control_go=false; + +HIDScope scope(3); // aantal scopes in hidscope opzetten + + +double m1_pwm=0; //variable for PWM control motor 1 +double m2_pwm=0; //variable for PWM control motor 2 + +const double m1_Kp = 2.5, m1_Ki = 1.0, m1_Kd = 1.0, m1_N = 100; // controller constants motor 1 +double m1_v1 = 0, m1_v2 = 0; // Memory variables +const double m1_Ts = 0.01; // Controller sample time + +const double m2_Kp = 2.5, m2_Ki = 1.0, m2_Kd = 1.0, m2_N = 100; // controller constants motor 2 +double m2_v1 = 0, m2_v2 = 0; // Memory variables +const double m2_Ts = 0.01; // Controller sample time + +const double pi=3.14159265359; +const double res = 64/(1/131.25*2*pi); // resolution on gearbox shaft per pulse +const double V_max=9.0; // maximum voltage supplied by trafo +const double minRadius=0.3; // minimum radius of arm +const double maxRadius=0.6; // maximum radius of arm +const double pulleyDiameter=0.0398; // pulley diameter +const double minAngle=-1.25; // minimum angle for limiting controller + +QEI Encoder1(D13,D12,NC,64,QEI::X4_ENCODING); //defining encoder +QEI Encoder2(D11,D10,NC,64,QEI::X4_ENCODING); //defining encoder + + + +MODSERIAL pc(USBTX,USBRX); + +void activate_controller(){controller_go=true}; //activate go flag + +double PID( double err, const double Kp, const double Ki, const double Kd, +const double Ts, const double N, double &v1, double &v2 ) { + const double a1 =-4/(N*Ts+2), + a2=-(N*Ts-2)/(N*Ts+2), + b0=(4*Kp + 4*Kd*N + 2*Ki*Ts+2*Kp*N*Ts+Ki*N*pow(Ts,2))/(2*N*Ts+4), + b1=(Ki*N*pow(Ts,2)-4*Kp-4*Kd*N)/(N*Ts+2), + b2=(4*Kp+4*Kd*N-2*Ki*Ts-2*Kp*N*Ts+Ki*N*pow(Ts,2))/(2*N*Ts+4); + + double v=err-a1*v1-a2*v2; + double u=b0*v+b1*v1+b2*v2 + v2=v1; v1=v; + return u; +} + + + void controller(){ //function for executing controller action + // convert ref to gearbox angle + double theta=atan(refy/refx); + double radius=sqrt(pow(refx,2)+pow(refy,2)); + + //limit theta + if (theta =< minAngle){ + theta=minAngle + } + else if (theta => 0){ + theta=0; + } + + //limit radius + if (radius =< minRadius){ + radius=minRadius + } + else if (radius > maxRadius){ + radius=maxRadius; + } + + //converting radius and theta to gearbox angle + ref_angle1=16*theta; + ref_angle2=(-radius+minRadius)/pi/pulleyDiameter; + + + angle1 = Encoder1.getPulses()/res; //get number of pulses (counterclockwise is positive) + angle2 = Encoder2.getPulses()/res; //get number of pulses + m1_pwm = (PID(ref_angle1-angle1,m1_Kp,m1_Ki,m1_Kd,m1_Ts,m1_N,m1_v1,m1_v2))/V_max; + //divide by voltage to get pwm duty cycle percentage) + m2_pwm = (PID(ref_angle2-angle2,m2_Kp,m2_Ki,m2_Kd,m2_Ts,m2_N,m2_v1,m2_v2))/V_max; + + if (m1_pwm >=0.0f && m1_pwm <=1.0f){ + motor1dir=0; + motor1.write(m1_pwm); + } + else if (m1_pwm < 0.0f && m1_pwm >= -1.0f){ + motor1dir=1; + motor1.write(-m1_pwm); + } + + if (m2_pwm >=0.0f && m2_pwm <=1.0f){ + motor1dir=0; + motor1.write(m2_pwm); + } + else if (m2_pwm < 0.0f && m2_pwm >= -1.0f){ + motor1dir=1; + motor1.write(-m2_pwm); + } + + //hidsopce to check what the code does exactly + scope.set(0,angle1); + scope.set(1,refangle1-angle1); + scope.set(2,m1_pwm + scope.send(); + + + } + + + } + +int main() +{ + pc.baud(115200); + motor1.period(0.02f); //period of pwm signal for motor 1 + motor2.period(0.02f); // period of pwm signal for motor 2 + motor1dir=0; // setting direction to ccw + motor2dir=0; // setting direction to ccw + control.attach(&controller,m1_Ts); //Ticker for processing encoder input + pc.printf("RESET\n\r"); + while (true) { + if(controller_go){ + controller_go=false; + controller(); + } +} \ No newline at end of file