first commit

Dependencies:   mbed MMA8451Q

steering_methods.h

Committer:
aalawfi
Date:
2021-11-22
Revision:
34:cb9a0cec2feb
Parent:
31:d570f957e083

File content as of revision 34:cb9a0cec2feb:

//#include "steering_header.h"
/* 
    Include methods and functions
*/

// --------- LANDMARK COUNTER --------
static int decimal_to_bin[16][BITS] = {
    {0,0,0,0}, // zero
    {0,0,0,1}, // one 
    {0,0,1,0}, //two
    {0,0,1,1}, //three 
    {0,1,0,0}, // four 
    {0,1,0,1}, //five 
    {0,1,1,0}, // six 
    {0,1,1,1}, //seven
    {1,0,0,0}, //eight 
    {1,0,0,1}, //nine 
    {1,0,1,0}, //ten 
    {1,0,1,1}, //11 
    {1,1,0,0}, //12 
    {1,1,0,1}, //13 
    {1,1,1,0}, //14
    {1,1,1,1}, //15 
    } ;
void turn_seg_off(DigitalOut segment[]){
    for(int i =0; i<BITS; i++){
        segment[i] = 0; 
        }
    }
    void show_decimal(int number, DigitalOut segment[]) {
        turn_seg_off(segment);
        for(int i =0; i < BITS; i++){
            segment[i] = decimal_to_bin[number][i]; 
            };
    }
//  ------------ LANDMARK DETECTION ------------
Timer land;

volatile bool landmark_triggered=false; // Debugging purposes only
volatile bool restarted = false;        // Debugging purposes only

void landmark_counter(void){
    land.start();
    landmark_triggered=false; // Debugging purposes only
    restarted = false;        // Debugging purposes only
    if(counter >= 15)
        counter =0;
    turn_seg_off(seg1);
    if((right_landmark_sensor.read() == 1 || left_landmark_sensor.read() == 1) && land.read_us() > 10  )
    { 
              landmark_triggered =true; // Debugging purpose only
              (counter > 6 ? counter = 7 : counter++);
            land.stop();
            }

   //  }  
    if(right_landmark_sensor.read() == 1 && left_landmark_sensor.read() == 1)
      {  
        lap++;
        counter = 0;
        restarted=true;  
            // Debugging purposes only
      }
    land.stop();
   show_decimal(counter, seg1);
    }

  
 float rad2dc (float angle){
    angle = std::max(MIN_TURN_ANGLE, std::min(angle, MAX_TURN_ANGLE));
    float x = (angle - MIN_TURN_ANGLE)/(MAX_TURN_ANGLE - MIN_TURN_ANGLE);
    float dutyCycle = 0.05*x+0.05;
    return dutyCycle;
    }

float current_duty_cycle=0.075;
//  -------------- PD CONTROLLER --------------
    // Global declearation
float err_prev = 0;
float prev_duty = 0;
float errorArea;
float errorAreaPrev =0.0;
float feedback;
float err;
float left_sens; float right_sens;
volatile bool clamp;
float OFFSET_ANGLE=0.0; float KICK_ERR; float PREV_KICK_ERR; float KICK_CHNG_ERR;
Timer k;
void steering_control(void)
{
    
    
    if(steering_enabled == true ){
        //Read each sensor and calculate the sensor difference
        

    float sensor_difference = left_distance_sensor.read() -
                                  right_distance_sensor.read();
    
        REF = 0.0;
        if(counter ==1 || counter == 2 )
            REF = 0.01;
        if(counter == 3)
            {
                k.start();
                REF = -0.01;
                if(k.read_ms() > 500)
                    REF = 0.0;
                    k.stop();
                }
        if(counter == 6 || counter == 7)
           {
                REF=0.02;
                
            }

        
     
       /*if (counter == 1 && lap == 3){
        KP = 6; 
        KD = 1;
        KI_STEERINg = 0.8;
        
        }*/
        //calculate the feedback term for the controller. distance (meters) from
        //track to sensor
        feedback = (sensor_difference/SEN_DIFF_TO_DIST); //
          
        //calculate the error term for the controller. distance (meters) from
        //desired position to sensor
         err = REF - feedback; //
         KICK_ERR = -1 * feedback;
       //Area of the error: TimeStep*err (width*length of a rectangle)
       
      // if(clamp == false)
        errorArea= TI_STEERING*err + errorAreaPrev; 
          
        //Calculate the derivative of the error term for the controller.
        //  e'(t) = (error(t) - error(t-1))/dt
        float errChange = (err - err_prev)/(TI_STEERING);
        KICK_CHNG_ERR = (KICK_ERR - PREV_KICK_ERR)/(TI_STEERING);
        //Calculate the controller output
        //Angle in radians
        float servo_angle = (OFFSET_ANGLE+KP*err + KD*KICK_CHNG_ERR*TIME_DERIVATIVE + KI_STEERING*errorArea*TIME_INTEGRAL);
        //Calculate the duty cycle for the servo motor
        current_duty_cycle = rad2dc(servo_angle);
        
               //--- integral anti-windup ---
        if (servo_angle > 0.1 || servo_angle < 0.05){
            if (errorArea > 0.0){
                clamp = true;
                }
         } else {
             clamp = false;
            }
            
         float strCheck = rad2dc(0);
        servo_motor_pwm.write(current_duty_cycle);
        
        err_prev = err;
        PREV_KICK_ERR = KICK_ERR;
        errorAreaPrev = errorArea;
        
      }
      else {
            current_duty_cycle = rad2dc(M_PI/4);
      
            servo_motor_pwm.write(current_duty_cycle);
          };
        
}