PID Controller
Dependencies: HIDScope MODSERIAL PinDetect QEI biquadFilter
main.cpp
- Committer:
- AeroKev
- Date:
- 2015-10-19
- Revision:
- 1:fe23126b0389
- Parent:
- 0:d38eb4622914
File content as of revision 1:fe23126b0389:
#include "mbed.h" #include "QEI.h" #include "HIDScope.h" #include "MODSERIAL.h" #include "PinDetect.h" #include "main.h" #include "biquadFilter.h" Serial pc(USBTX, USBRX); PinDetect stop(SW2); PinDetect start(SW3); AnalogIn pot1(m1_pot); AnalogIn pot2(m2_pot); // PWM Speed Control: DigitalOut dir1(m1_dir); PwmOut pwm1(m1_pwm); DigitalOut dir2(m2_dir); PwmOut pwm2(m2_pwm); QEI enc1(m1_enc_a, m1_enc_b, NC, 1); QEI enc2(m2_enc_a, m2_enc_b, NC, 1); Ticker potTicker; Ticker motorTicker; Ticker graphTicker; //HIDScope grapher(4); float currentRotation1 = 0, currentRotation2 = 0; float desiredRotation1 = 0, desiredRotation2 = 0; double error1 = 0, error2 = 0; double m1_error_integral = 0, m2_error_integral = 0; double m1_error_derivative = 0, m2_error_derivative = 0; biquadFilter m1_filter(m1_f_a1, m1_f_a2, m1_f_b0, m1_f_b1, m1_f_b2); biquadFilter m2_filter(m2_f_a1, m2_f_a2, m2_f_b0, m2_f_b1, m2_f_b2); bool shutup = true; bool go_pot = false; bool go_motor = false; bool go_graph = false; float getPotRad(AnalogIn pot) { return pot.read() * 4.0f - 2.0f; } float toRadians(int pulses) { int remaining = pulses;// % sigPerRev; float percent = (float) remaining / (float) sigPerRev; return percent * 2.0f; } void readPot() { go_pot = true; } void getMotorRotation() { go_motor = true; } void stopMotors() { shutup = true; } void startMotors() { shutup = false; } void sendGraph() { go_graph = true; } double p_control(double error, double kp) { return kp * error; } double pi_control(double error, double kp, double ki, double ts, double &error_integral) { error_integral = error_integral + ts * error; double result = kp * error + ki * error_integral; return result; } double pid_control(double error, double kp, double ki, double ts, double &error_integral, double kd, double previous_error, double &error_derivative, biquadFilter filter) { error_integral = error_integral + ts * error; error_derivative = (error - previous_error) / ts; // error_derivative = filter.step(error_derivative); double result = kp * error + ki * error_integral + kd * error_derivative; return result; } int getPDirection(double control, int motor) { if (control >= 0) return (motor == 1)?1:0; else return (motor == 1)?0:1; } void initialize() { pc.printf("Initializing...\r\n"); // Set the shutup and start buttons stop.mode(PullUp); stop.attach_deasserted(&stopMotors); stop.setSampleFrequency(); start.mode(PullUp); start.attach_deasserted(&startMotors); start.setSampleFrequency(); pc.printf("Buttons done\r\n"); // Set proper baudrate // pc.baud(115200); // Reset encoders enc1.reset(); enc2.reset(); pc.printf("Encoders reset\r\n"); // Start tickers potTicker.attach(&readPot, tickRate); motorTicker.attach(&getMotorRotation, tickRate); graphTicker.attach(&sendGraph, graphTickRate); pc.printf("Tickers attached\r\n"); pc.printf("Initialized\r\n"); } int main() { pc.printf("Started\r\n"); initialize(); while (true) { if (shutup) { pwm1 = 0; pwm2 = 0; } else { if (go_pot) { desiredRotation1 = getPotRad(pot1); desiredRotation2 = getPotRad(pot2); go_pot = false; } if (go_motor) { currentRotation1 = toRadians(enc1.getPulses()); currentRotation2 = toRadians(enc2.getPulses()); pc.printf("PULSE: %i | CUR ROT: %f | ERR: %f | DES ROT: %f\r\n",enc2.getPulses(),currentRotation2, error2,desiredRotation2); double previous_error1 = error1; double previous_error2 = error2; error1 = desiredRotation1 - currentRotation1; error2 = desiredRotation2 - currentRotation2; // P control // double control1 = p_control(error1, motor1_kp); // double control2 = p_control(error2, motor2_kp); // PI control //double control1 = pi_control(error1, motor1_kp, motor1_ki, tickRate, m1_error_integral); // double control2 = pi_control(error2, motor2_kp, motor2_ki, tickRate, m2_error_integral); // PID control double control1 = pid_control(error1, motor1_kp, motor1_ki, tickRate, m1_error_integral, motor1_kd, previous_error1, m1_error_derivative, m1_filter); double control2 = pid_control(error2, motor2_kp, motor2_ki, tickRate, m2_error_integral, motor2_kd, previous_error2, m2_error_derivative, m2_filter); int d1 = getPDirection(control1,1); int d2 = getPDirection(control2,2); float speed1 = fabs(control1); float speed2 = fabs(control2); if (speed1 < 0.1f) speed1 = 0.0f; if (speed2 < 0.1f) speed2 = 0.0f; dir1 = d1; dir2 = d2; pwm1 = speed1; pwm2 = speed2; pc.printf("SPEED: %f | DIR: %i\r\n",speed2,d2); go_motor = false; } /*if (go_graph) { pc.printf("Trying to send graph\r\n"); pc.printf("Desired Rotation: %f %f\r\n", desiredRotation1, desiredRotation2); pc.printf("Rotation: %f %f\r\n", currentRotation1, desiredRotation2); grapher.set(0, desiredRotation1); grapher.set(1, currentRotation1); grapher.set(2, desiredRotation2); grapher.set(3, currentRotation2); grapher.send(); go_graph = false; }*/ } } }