
Werkt
Dependencies: Encoder HIDScope MODSERIAL QEI mbed
Fork of Inverse_kinematics_PIDController by
main.cpp
- Committer:
- CasperK
- Date:
- 2018-10-31
- Revision:
- 13:2d2763be031c
- Parent:
- 12:9a2d3d544426
- Child:
- 14:a98bc99ea004
File content as of revision 13:2d2763be031c:
#include "mbed.h" #include "math.h" #include "MODSERIAL.h" #include "HIDScope.h" #include "QEI.h" #define PI 3.141592f //65358979323846 // pi PwmOut pwmpin1(D6); PwmOut pwmpin2(D5); DigitalOut directionpin2(D4); DigitalOut directionpin1(D7); QEI motor1(D13,D12,NC, 32); QEI motor2(D11,D10,NC, 32); DigitalOut ledred(LED_RED); DigitalIn KillSwitch(SW2); DigitalIn button(SW3); MODSERIAL pc(USBTX, USBRX); HIDScope scope(6); DigitalIn buttonleft(D2); DigitalIn buttonright(D3); //values of inverse kinematics volatile bool emg0Bool = false; volatile bool emg1Bool = false; volatile bool emg2Bool = false; volatile bool x_direction = true; volatile bool a; const float C1 = 3.0; //motor 1 gear ratio const float C2 = 0.013; //motor 2 gear ratio/radius of the circular gear in m const float length = 0.300; //length in m (placeholder) const float Timestep = 0.01; volatile float x_position = length; volatile float y_position = 0.0; volatile float old_y_position; volatile float old_x_position; volatile float old_motor1_angle; volatile float old_motor2_angle; volatile float motor1_angle = 0.0; //sawtooth gear motor volatile float motor2_angle = 0.0; //rotational gear motor volatile float direction; volatile char c; //values of PID controller const float Kp = 0.05; const float Ki = 0.01; const float Kd = 0; volatile float Output1 = 0 ; //Starting value volatile float Output2 = 0 ; //Starting value volatile float P1 = 0; //encoder value volatile float P2 = 0; volatile float e1 = 0 ; //Starting value volatile float e2 = 0 ; //Starting value volatile float e3 = 0; volatile float f1 = 0 ; //Starting value volatile float f2 = 0 ; //Starting value volatile float f3 = 0; volatile float df3 = 0; volatile float if3 = 0; volatile float de3 = 0; volatile float ie3 = 0; volatile float Output_Last1; // Remember previous position volatile float Output_Last2; // Remember previous position volatile float Y1 = 0; // Value that is outputted to motor control volatile float Y2 = 0; // Value that is outputted to motor control volatile float pwm_value1 = 0; volatile float pwm_value2 = 0; volatile float P_Last = 0; // Starting position Ticker pwm_ticker; Ticker mainticker;; void yDirection() { //direction of the motion if (emg0Bool && !emg1Bool) { //if a is pressed and not d, move to the left direction = -1; } else if (!emg0Bool && emg1Bool) { //if d is pressed and not a, move to the right direction = 1; } if (emg0Bool || emg1Bool){ //correction from motor 1 to keep x position the same //calculating the motion old_y_position = y_position; y_position = old_y_position + (0.1f * direction); old_motor2_angle = motor2_angle; motor2_angle = asin( y_position / length )* C1; //saw tooth motor angle in rad //correction on x- axis old_x_position = x_position; x_position = old_x_position + (cos(motor2_angle/ C1)-cos(old_motor2_angle/ C1)); // old x + correction old_motor1_angle = motor1_angle; motor1_angle = old_motor1_angle + ( x_position - length ) / C2; } //reset the booleans, only for demo purposes emg0Bool = false; emg1Bool = false; } void xDirection () { //if the button is pressed, reverse the y direction if (!button) { x_direction = !x_direction; //wait(0.5f); } if (emg2Bool) { //if w is pressed, move up/down //direction of the motion if (x_direction) { direction = 1.0f; } else if (!x_direction) { direction = -1.0f; } //calculating the motion old_x_position = x_position; x_position = old_x_position + (0.0001f * direction); old_motor1_angle = motor1_angle; motor1_angle = old_motor1_angle + ( x_position - length ) / C2; // sawtooth-gear motor angle in rad //reset the boolean, for demo purposes emg2Bool = false; } } volatile float Plek1; void PIDController1() { //Plek1 = motor1.getPulses(); P1 = motor1.getPulses() / 8400.0f * 2.0f*PI; //actual motor angle in rad e1 = e2; e2 = e3; e3 = motor1_angle - P1; de3 = (e3-e2)/Timestep; ie3 = ie3 + e3*Timestep; Output1 = Kp * e3 + Ki * ie3 + Kd * de3; // Output_Last1 = Output1; // Output1 = Kp * (e3 - e2) + Output_Last1 +Ki * e3 + Kd * (e3 - 2*e2 + e1); Y1 = 0.5f * Output1; if (Y1 >= 1){ Y1 = 1; } else if (Y1 <= -1){ Y1 = -1; } } volatile float Plek2; void PIDController2() { //Plek2 = motor2.getPulses(); P2 = motor2.getPulses() / 8400.0f * 2.0f*PI; // actual motor angle in rad f2 = f3; f3 = motor2_angle - P2; df3 = (f3-f2)/Timestep; if3 = if3 + f3*Timestep; Output2 = Kp * f3 + Ki * if3 + Kd * df3; // Output_Last2 = Output2; // Output2 = Kp * (f3 - f2) + Output_Last2 +Ki * f3 + Kd * (f3 - 2*f2 + f1); Y2 = 0.5f * Output2; if (Y2 >= 1){ Y2 = 1; } else if (Y2 <= -1){ Y2 = -1; } } void ControlMotor1() { if (Y1 > 0.0f) { Y1 = 0.4f * Y1 + 0.2f; directionpin1 = false; } else if(Y1 < -0.0f){ Y1 = -0.2f + 0.4f * Y1; directionpin1 = true; } pwm_value1 = fabs(Y1); } void ControlMotor2() { if (Y2 > 0.1f) { Y2 = 0.3f * Y2 + 0.2f; directionpin2 = true; } else if(Y2 < -0.1f){ Y2 = -0.2f + 0.3f * Y2; directionpin2 = false; } else { Y2 = 0; } pwm_value2 = fabs(Y2); } void motorPWM() { pwmpin1 = pwm_value1; pwmpin2 = pwm_value2; } void tickermain() { if(!buttonleft){ emg0Bool = true; } else if(!buttonright) { emg2Bool = true; } xDirection(); //call the function to move in the y direction yDirection(); //call the function to move in the x direction PIDController1(); PIDController2(); ControlMotor1(); ControlMotor2(); if (!KillSwitch) { //even in mekaar gebeund voor het hebben van een stop knop ledred = false; pwm_value1 = 0; pwm_value2 = 0; //for fun blink sos maybe??? wait(2.0f); bool u = true; while(u) { if (!KillSwitch) { u = false; ledred = true; wait(1.0f); } } } scope.set(0, pwm_value1); scope.set(1, P1); scope.set(2, Y2); scope.set(3, P2); scope.set(4, motor1_angle); scope.set(5, motor2_angle); scope.send(); //pwm_value1 = 0; //pwm_value2 = 0; //Y1 = 0; //Y2 = 0; emg0Bool = false; emg1Bool = false; emg2Bool = false; } int main() { //pc.baud(115200); //pc.printf(" ** program reset **\n\r"); mainticker.attach(&tickermain, Timestep); pwm_ticker.attach(&motorPWM, Timestep); ledred = true; while (true) { } }