Basis aansturing projectgroep 3
Dependencies: Biquad HIDScope MODSERIAL QEI mbed
main.cpp
- Committer:
- s1588141
- Date:
- 2016-10-25
- Revision:
- 4:8b1df22779a7
- Parent:
- 2:0954eb04bb4c
- Child:
- 5:4b2ff2a4664a
File content as of revision 4:8b1df22779a7:
#include "mbed.h" #include "MODSERIAL.h" #include "QEI.h" #include "math.h" #include "HIDScope.h" #include "Biquad.h" /////////////////////////// ////////Constantes///////// /////////////////////////// double const pi = 3.14159265359; /////////////////////////// // Initialise hardware///// /////////////////////////// MODSERIAL pc(USBTX, USBRX); //----------------------------------------------------------- //--------------------All lights----------------------------- //----------------------------------------------------------- DigitalOut green(LED_GREEN); DigitalOut red(LED_RED); //------------------------------------------------------------ //--------------------All sensors----------------------------- //------------------------------------------------------------ //--------------------Encoders-------------------------------- //Variables volatile int movement = 0,direction_L =0, direction_R =0; volatile double Signal = 0.0; const int SampleFrequency = 100; const double AnglePerPulse = 2*pi/4200; //Soms doet dit een beetje vaag, dus dit moet wel af en toe uitgetest worden volatile double Position_L = 0.0; //The position of the left motor in radiants volatile double Position_R = 0.0; //The position of the right motor in radiants volatile double Previous_Position_L =0.0; //The previous position of the left motor in radiants volatile double Previous_Position_R = 0.0; //The previous position of the right motor in radiants volatile double Speed_L = 0.0; //The speed of the left motor volatile double Speed_R = 0.0; //The speed of the right motor //Defining Pins QEI Encoder_L (D11, D10,NC, 64); //D11 is poort A D10 is poort b QEI Encoder_R (D13, D12,NC, 64); //D 13 is poort A 12 is poort b //--------------------AnalogInput--------------------------------- AnalogIn EMG_L(A0); //Motorspeed control Left AnalogIn EMG_R(A1); //MotorSpeed control Right AnalogIn EMG_Change(A2);//EMG signal for other controls //-------------------Hidscope---------------------------------- HIDScope scope(4); // Sending two sets of data //-------------------Interrupts------------------------------- InterruptIn Dir_L(D0); //Motor Dirrection left InterruptIn Dir_R(D1); //Motor Dirrection Right InterruptIn OnOff(SW3); //System On/off //------------------Tickers------------------------------------ Ticker Tick_Sample;// ticker for data sampling //-------------------------------------------------------------- //--------------------All Motors-------------------------------- //-------------------------------------------------------------- DigitalOut M_L_D(D4); //Richting motor links-> //while M_L_D is zero the motor's direction is counterclockwise and the pulses are positive PwmOut M_L_S(D5); //Speed motor links DigitalOut M_R_D(D7); //Richting motor Rechts PwmOut M_R_S(D6); //Speed motor Rechts const int Motor_Frequency = 1000; DigitalOut Grap(D9); //Graple active or not; //----------------------Lights ---------------------------------4 DigitalOut translation(D0); DigitalOut grip1(D1); DigitalOut rotation(D2); DigitalOut grip2(D3); //-------------------------------------------------------------- //-----------------------Functions------------------------------ //-------------------------------------------------------------- //-----------------------on of sitch of the sytem----------------------------- volatile bool Active = false; void Start_Stop(){ Active = !Active; } /////////////-----------------------Booting---------------------------------------= void Boot(){ //Fucnction that initializes variables that have to be initalized within the main of the script //And does the same thing for functions like encoder reset pc.baud(115200); pc.printf("\r\n**BOARD RESET**\r\n"); M_L_S.period(1.0/Motor_Frequency); M_L_S = 0.0; M_R_S.period(1.0/Motor_Frequency); M_R_S= 0.0; Encoder_L.reset(); Encoder_R.reset(); Grap = 1; grip1 = 1; } //--------------------------------Sampling------------------------------------------ bool Sample_Flag = false; void Set_Sample_Flag(){ Sample_Flag = true; } void Sample(){ //This function reads out the position and the speed of the motors in radiants //Aand stores them in the values Speed and Position //Position in Radials: Previous_Position_L = Position_L; Previous_Position_R = Position_R; Position_L = Encoder_L.getPulses()*AnglePerPulse+Previous_Position_L; Position_R = Encoder_R.getPulses()*AnglePerPulse+Previous_Position_R; //Speed in RadPers second Speed_L = (Position_L-Previous_Position_L)*SampleFrequency; Speed_R = (Position_R-Previous_Position_R)*SampleFrequency; scope.set(0,Speed_L); scope.set(1,Signal+Speed_L); scope.set(2,Speed_R); scope.set(3,Signal+Speed_R); scope.send(); Encoder_L.reset(); Encoder_R.reset(); } bool Controller_Flag = false; Ticker Tick_Controller; void Set_controller_Flag(){ Controller_Flag = true; } //---------------------------Defining the biquad filter function for controller---------------- double biquad( double u, double &v1, double &v2, const double a1, const double a2, const double b0, const double b1, const double b2 ){ double v = u - (a1*v1) -(a2*v2); double y = b0*v + b1*v1 + b2*v2; v2 = v1; v1 = v; return y; } //-------------------------------PID --------------------------------- double PID(double e, const double Kp, const double Ki, const double Kd, double Sf, double &e_int, double &e_prev, double &f_v1, double &f_v2, const double f_a1, const double f_a2, const double f_b0, const double f_b1, const double f_b2){ //This function is a PID controller that returns the errorsignal for the plant // Derivative Part with filtering double e_der = (e - e_prev)/Sf; // e_der = biquad( e_der, f_v1, f_v2, f_a1, f_a2, f_b0, f_b1, f_b2 ); e_prev = e; // Integral Part e_int = e_int + Sf * e; // PID return Kp*e + Ki*e_int + Kd * e_der; } //---------------------------Controller--------------------------------------- // Controller gains (motor1−Kp,−Ki,...) const double Kpm= 1, Kim = 0*0.02, Kdm = 0*0.041465; double er_int = 0, prev_er = 0; // Derivative filter coeicients (motor1−filter−b0,−b1,...) const double F_A1 = 1.0, F_A2 = 2.0, F_B0 = 1.0, F_B1 = 3.0, F_B2 = 4.0; // Filter variables (motor1−filter−v1,−v2) double f_v1 = 0, f_v2 = 0; double Controller_L(int direction, double signal, double reference ){ //This funcition returns a value that will be sent to drive the motor // - Motor_Direction_Input is the Digital in of the motor // 1 for dirrection means that a clockwise rotation wil be regarded as positive // and -1 for direction means the opposite //PID controller double Speed_Set = PID( reference-signal*direction,Kpm, Kim, Kdm, SampleFrequency, er_int, prev_er, f_v1, f_v2, F_A1, F_A2, F_B0, F_B1,F_B2 ); //Determining rotational direction of the motor if ((reference-signal*direction >= 0)){ M_L_D = 1; } else { M_L_D = 0; } return fabs(Speed_Set); } double Controller_R(int direction, double signal, double reference ){ //This funcition returns a value that will be sent to drive the motor // - Motor_Direction_Input is the Digital in of the motor // 1 for dirrection means that a clockwise rotation wil be regarded as positive // and -1 for direction means the opposite //PID controller double Speed_Set = PID( reference-signal*direction,Kpm, Kim, Kdm, SampleFrequency, er_int, prev_er, f_v1, f_v2, F_A1, F_A2, F_B0, F_B1,F_B2 ); //Determining rotational direction of the motor if ((reference-signal*direction >= 0)){ M_R_D = 0; } else { M_R_D = 1; } if (fabs(Speed_Set)< 0.4){ return fabs(Speed_Set); } else { return 0.4; } } //-----------------------------Change_Movement---------------------------------- // This function changes the movement type of the robot as a consequence of the input by EMG // Or when the EMG signal is hold for 1.5S The grapler wil activate Ticker Tick_Movement; int check = 0; bool Movement_Flag = false; void Set_movement_Flag(){ Movement_Flag = true; } void Change_Movement(){ if (Movement_Flag == true){ if (EMG_Change > 0.5f ){ check += 1; if (check <= 6 and check > 1 ){ grip1 = 1; } if (check > 6){ grip2 =1; } } else { //Hold the signal shorter than 1.5 seconds if (check <= 6 and check > 1 ){ movement = !movement; grip1 = 1; } // Hold the signal longer than 1.5 seconds if (check > 6){ grip2 =1; Grap = !Grap; } grip2 = 0; grip1 =0; check = 0; } Movement_Flag = false; } } int main() { //---------------------Setting constants and system booting--------------------- Boot(); Tick_Sample.attach(Set_Sample_Flag, 1.0/SampleFrequency); Tick_Controller.attach(Set_controller_Flag, 1.0/SampleFrequency); Tick_Movement.attach(Set_movement_Flag, 0.25); OnOff.fall(Start_Stop); //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ //\/\/\/\/\/\/\/\/\/\/\/\/\/\Main Loop for program\/\/\/\/\/\/\/\/\/\/\/\/\/ //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ while (true) { if (Sample_Flag == true){ Sample(); Signal = pi*(EMG_R.read()-EMG_L.read()); Sample_Flag = false; } //Main statement that states if the system is active or not if (Active == true){ green = 0; red = 1; Change_Movement(); if (Controller_Flag == true){ switch (movement) { case 0: //Clockwise rotation of the robot direction_L = -1; direction_R = -1; break; case 1: //Radial movement outwards for a positive value direction_L = 1; direction_R = -1; break; } M_L_S = Controller_L(direction_L,Signal,Speed_L); M_R_S = Controller_R(direction_R,Signal,Speed_R); Controller_Flag = false; } } else { if (Active == false){ green = 1; red = 0; M_R_S = 0; M_L_S = 0; } } } }