MODSERIAL PID controller edit
Dependencies: HIDScope MODSERIAL QEI biquadFilter mbed
Fork of PID_controller_Motor by
main.cpp
- Committer:
- MBroek
- Date:
- 2016-10-19
- Revision:
- 12:8aba69d8d0d0
- Parent:
- 11:91613b22bc00
- Child:
- 13:b0d3c547bf2f
File content as of revision 12:8aba69d8d0d0:
// HET DEFINIEREN VAN ALLES ========================================================================================== // Includen van alle libraries --------------------------------------- #include "mbed.h" #include "MODSERIAL.h" #include "QEI.h" #include "math.h" #include "HIDScope.h" // Definieren van de HIDscope ---------------------------------------- HIDScope scope(3); // Definieren van de Serial en Encoder ------------------------------- MODSERIAL pc(USBTX, USBRX); #define SERIALBAUD 115200 QEI encoder_motor1(D10,D11,NC,64); QEI encoder_motor2(D12,D13,NC,64); // Definieren van de Motorpins --------------------------------------- DigitalOut motor1_direction_pin(D7); PwmOut motor1_speed_pin(D6); DigitalOut motor2_direction_pin(D4); PwmOut motor2_speed_pin(D5); //Definieren van bord-elementen -------------------------------------- InterruptIn kill_switch(D8); InterruptIn test_button(D9); AnalogIn pot1(A1); // Dit is de gesimuleerde emg1 AnalogIn pot2(A2); // Dit is de gesimuleerde emg2 //Definieren van de tickers ------------------------------------------ Ticker test_ticker; Ticker hidscope_ticker; // HET VASTSTELLEN VAN ALLE TE GEBRUIKEN VARIABELEN EN CONSTANTEN ====================================================== volatile bool safe = true; // Conditie voor de while-loop in main double position_motor1; int counts1; // Pulses van motoren int counts2; const double pi = 3.14159265358979323846264338327950288419716939937510; // pi const double rad_per_count = pi/8400.0; // Aantal rad per puls uit encoder const double radius_tandwiel = 1.0; const double meter_per_count = rad_per_count * radius_tandwiel; // Het aantal meter dat het karretje aflegt per puls, DIT IS NOG ONBEKEND!!! double error1_int = 0.00000; // Initiele error integral waardes double error2_int = 0.00000; const double T_getpos = 0.01; // Periode van de frequentie van het aanroepen van de positiechecker (get_position) volatile bool flag1 = false, flag2 = false; // De flags voor de functies aangeroepen door de tickers const double Kp_1 = 1.0000000; // De PID variablen voor motor 1 const double Kd_1 = 0.1; const double Ki_1 = 0.3; const double Kp_2 = 1.0000000; // De PID variablen voor motor 2 const double Kd_2 = 0.1; const double Ki_2 = 0.3; const double vrijheid_m1_rad = 0.5*pi; // Dit is de uiterste postitie vd arm in radialen const double vrijheid_m2_meter = 0.25; // Dit is de helft vd arm, dit is wat het karretje heen en weer kan bewegen const double starting_pos_m1 = 0.5*pi; // Startin posities van de motoren const double starting_pos_m2 = 0; double reference_position_motor1 = 0.5*pi; // Dit zijn de eerste posities waar de motoren heen willen, deze moeten dezelfde zijn als de startpositie! double reference_position_motor2 = 0; double PID_output_1 = 0; // De eerste PID_output, deze is nul anders gaan de motoren draaien double PID_output_2 = 0; double error_prev_1 = 0; // De initiele previous error double error_int_1 = 0; // De initiele intergral error double error_prev_2 = 0; double error_int_2 = 0; bool which_motor = 0; // ALLE FUNCTIES BUITEN DE MAIN-LOOP ==================================================================================== // De emergency break ------------------------------------------------ void emergency_stop(){ safe = false; pc.printf("Emergency stop!!! Please reset your K64F board\r\n"); } // Functie voor het switchen tussen de motors ------------------------------ void motor_switch(){ which_motor = !which_motor; // =0 activeert motor1 en =1 activeert motor2 } // Functie voor het vinden van de positie van motor 1 --------------------- double get_position_m1(const double radpercount, const double start_pos_m1){ //returned de positie van de motor in radialen (positie vd arm in radialen) counts1 = encoder_motor1.getPulses(); // Leest aantal pulses uit encoder af return radpercount * counts1 + start_pos_m1; // rekent positie motor1 uit en geeft deze als output vd functie } // Functie voor vinden van de positie van motor 2 ----------------------------- double get_position_m2(const double meterpercount, const double start_pos_m2){ // returned de positie van het karretje in meter counts2 = encoder_motor2.getPulses(); // leest aantal pulses vd encoder af return meterpercount * counts2 + start_pos_m2; // rekent de positie van het karretje uit en geeft dit als output vd functie } // Functie voor het vinden van de reference position van motor 1 -------------------- double get_reference_position_m1(const double aantal_rad, const double start_pos_m1){ double ref_pos = pot1.read() - pot2.read(); // De reference position als output (zit tussen -1 en 1, -1 is maximaal links en 1 is maximaal rechts) return ref_pos * aantal_rad + start_pos_m1; // Aantal rad is de uiterste positie vd arm in radialen } // Functie voor het vinden van de reference position van motor 2 -------------------- double get_reference_position_m2(const double aantal_meter, const double start_pos_m2){ double ref_pos = pot1.read() - pot2.read(); // De reference position als output (zit tussen -1 en 1, -1 is maximaal links en 1 is maximaal rechts) return ref_pos * aantal_meter + start_pos_m2; // Aantal meter is hoeveelheid radialen van middelpunt tot minima. } // HIDScope functie ---------------------------------------------------------------------- void set_scope(double input1, double input2, double input3){ scope.set(0, input1); scope.set(1, input2); scope.set(2, input3); scope.send(); } // De PID-controller voor de motors ------------------------------------------------- double PID_controller(double ref_pos, double mot_pos, double &e_prev, double &e_int, const double Kp, const double Kd, const double Ki){ double error = ref_pos - mot_pos; // error uitrekenen double error_dif = (error-e_prev)/T_getpos; // De error differentieren //error_dif = ..... // Filter biquad poep e_prev = error; // Hier wordt de error opgeslagen voor de volgende keer e_int = e_int + T_getpos*error; // De error integreren return Kp*error + Ki*e_int + Kd*error_dif; // De uiteindelijke PID output } // Motor 1 besturen --------------------------------------------------------------------- void set_motor1(double motor_input){ // functie die de motor aanstuurt mt als input de PID-output if (motor_input >= 0){ // Dit checkt welke kant de motor op moet draaien motor1_direction_pin = 1; // Clockwise } else { motor1_direction_pin = 0; // CounterClockwise } if (fabs(motor_input)>1){ // Dit fixed de PwmOutput op maximaal 1 motor_input = 1; } motor1_speed_pin = fabs(motor_input); // Dit geeft de uiteindelijke input door aan de motor } // Motor 2 besturen --------------------------------------------------------------------- void set_motor2(double motor_input){ // functie die de motor aanstuurt mt als input de PID-output if (motor_input >= 0){ // Dit checkt welke kant de motor op moet draaien motor2_direction_pin = 1; // Clockwise } else { motor2_direction_pin = 0; // CounterClockwise } if (fabs(motor_input)>1){ // Dit fixed de PwmOutput op maximaal 1 motor_input = 1; } motor2_speed_pin = fabs(motor_input); // Dit geeft de uiteindelijke input door aan de motor } // De go-flag functies ----------------------------------------------------------------- void flag1_activate(){flag1=true;} // Activeert de flag void flag2_activate(){flag2=true;} // DE MAIN ================================================================================================================= int main() { pc.baud(SERIALBAUD); pc.printf("Starting"); //test_button.fall(&); // Activeert test button kill_switch.fall(&emergency_stop); // Activeert kill switch test_button.fall(&motor_switch); // Switcht motoren test_ticker.attach(&flag1_activate,0.1); // Activeert de go-flag van motor positie hidscope_ticker.attach(&flag2_activate,0.01); while(safe){ // Draait loop zolang alles veilig is. if (flag1){ flag1 = false; if (!which_motor){ // als which_motor=0 gaat motor 1 lopen PID_output_1 = PID_controller(get_reference_position_m1(vrijheid_m1_rad, starting_pos_m1), get_position_m1(rad_per_count, starting_pos_m1), error_prev_1, error_int_1, Kp_1, Kd_1, Ki_1); set_motor1(PID_output_1); } else{ PID_output_2 = PID_controller(get_reference_position_m2(vrijheid_m2_meter, starting_pos_m2), get_position_m2(meter_per_count, starting_pos_m2), error_prev_2, error_int_2, Kp_2, Kd_2, Ki_2); set_motor2(PID_output_2); } } if (flag2){ flag2 = false; set_scope(PID_output_1, get_reference_position_m1(vrijheid_m1_rad, starting_pos_m1), get_position_m1(meter_per_count, starting_pos_m1)); } } motor1_speed_pin = 0; //Dit zet de motoren uit nadat de kill switch is gebruikt motor2_speed_pin = 0; }