Basis aansturing projectgroep 3
Dependencies: Biquad HIDScope MODSERIAL QEI mbed
main.cpp
- Committer:
- s1588141
- Date:
- 2016-11-01
- Revision:
- 7:075ba23f3147
- Parent:
- 6:aa62e6650559
- Child:
- 8:656b0c493a45
File content as of revision 7:075ba23f3147:
#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 double Signal = 0.0; const int SampleFrequency = 400; 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 Left(A0); //Motorspeed control Left AnalogIn Right(A1); //MotorSpeed control Right AnalogIn Change(A2);//EMG signal for other controls double EMG_L; double EMG_R; double EMG_Change; //-------------------Hidscope---------------------------------- //-------------------------------------------------------------- //--------------------All Motors-------------------------------- //-------------------------------------------------------------- volatile int movement = 0,direction_L =0, direction_R =0; //determining the direction of the 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----------------------------- InterruptIn OnOff(SW3); //System On/off volatile bool Active = false; void Start_Stop(){ Active = !Active; } //--------------------------------Sampling------------------------------------------ Ticker Tick_Sample;// ticker for data 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; Encoder_L.reset(); Encoder_R.reset(); } bool Controller_Flag = false; Ticker Tick_Controller; void Set_controller_Flag(){ Controller_Flag = true; } //-------------------------------PI --------------------------------- double PI(double e, const double Kp, const double Ki, double Sf, double &e_int){ //This function is a PID controller that returns the errorsignal for the plant e_int = e_int + Sf * e; // PID return Kp*e + Ki*e_int ; } //---------------------------Controller--------------------------------------- // Controller gains (motor1−Kp,−Ki,...) const double Kpm= 0.1, Kim = 0*0.05; double er_int = 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 = PI( reference-signal*direction,Kpm, Kim, SampleFrequency, er_int ); //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 //PI controller double Speed_Set = PI( reference-signal*direction,Kpm, Kim, SampleFrequency, er_int); //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){ if(fabs(reference-signal*direction) < 0.5 and reference <0.5){ //Applying Setpoint tollerance return 0; } else { 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 <= 10 and check > 1 ){ grip1 = 1; } if (check > 10){ 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; } } //-----------------------------EMG Signal determinator---------------------- BiQuadChain bqc_L; BiQuadChain bqc_R; BiQuadChain bqc_Change; BiQuad bq1_R( 9.35527e-01, -1.87105e+00, 9.35527e-01, -1.86689e+00, 8.75215e-01 ); BiQuad bq2_R( 9.90278e-01, -1.40046e+00, 9.90278e-01, -1.40046e+00, 9.80555e-01 ); BiQuad bq3_R( 2.20594e-05, 4.41189e-05, 2.20594e-05, -1.98667e+00, 9.86760e-01 ); BiQuad bq1_L( 9.35527e-01, -1.87105e+00, 9.35527e-01, -1.86689e+00, 8.75215e-01 ); BiQuad bq2_L( 9.90278e-01, -1.40046e+00, 9.90278e-01, -1.40046e+00, 9.80555e-01 ); BiQuad bq3_L( 2.20594e-05, 4.41189e-05, 2.20594e-05, -1.98667e+00, 9.86760e-01 ); BiQuad bq1_Change( 9.35527e-01, -1.87105e+00, 9.35527e-01, -1.86689e+00, 8.75215e-01 ); BiQuad bq2_Change( 9.90278e-01, -1.40046e+00, 9.90278e-01, -1.40046e+00, 9.80555e-01 ); BiQuad bq3_Change( 2.20594e-05, 4.41189e-05, 2.20594e-05, -1.98667e+00, 9.86760e-01 ); HIDScope scope(5); // Sending two sets of data void getEMG(){ EMG_Change = bqc_Change.step(Change.read()); EMG_Change = fabs(EMG_Change); EMG_Change = bq3_Change.step(EMG_Change)*50; scope.set(0,EMG_Change);//=------------------------------------------------------------------------Scope scope.set(4,Change.read()); if (EMG_Change < 0.3){ EMG_Change=0; } else { EMG_Change=1.0; } EMG_L = bqc_L.step(Left.read()); EMG_L= fabs(EMG_L); EMG_L= bq3_L.step( EMG_L)*10; scope.set(1,EMG_L);//=------------------------------------------------------------------------Scope if (EMG_L < 0.3){ EMG_L=0; } else { EMG_L=1.0; } EMG_R = bqc_R.step(Right.read()); EMG_R= fabs(EMG_R); EMG_R= bq3_R.step( EMG_R)*10; scope.set(2,EMG_R);//=------------------------------------------------------------------------Scope if (EMG_R < 0.3){ EMG_R=0; } else { EMG_R= 1.0; } } /////////////-----------------------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; rotation = 1; translation = 0; Encoder_L.reset(); Encoder_R.reset(); Grap = 1; grip1 = 1; bqc_L.add( &bq1_L ).add( &bq2_L ); bqc_R.add(&bq1_R).add(&bq2_R); bqc_Change.add(&bq1_Change).add(&bq2_Change); 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); } int main() { //---------------------Setting constants and system booting--------------------- Boot(); //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ //\/\/\/\/\/\/\/\/\/\/\/\/\/\Main Loop for program\/\/\/\/\/\/\/\/\/\/\/\/\/ //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ while (true) { if (Sample_Flag == true){ Sample(); getEMG(); // EMG_Change = getEMG( bqc.step(Change.read())); Signal = pi*(EMG_R-EMG_L); scope.set(3,Signal);//------------------------------------------------------------scope scope.send(); 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; rotation = 1; translation = 0; break; case 1: //Radial movement outwards for a positive value direction_L = 1; direction_R = -1; rotation = 0; translation = 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; } } } }