pid foward back and reverse

Dependencies:   PID QEI chair_BNO055 ros_lib_kinetic

Dependents:  

Fork of wheelchaircontrol by ryan lin

Files at this revision

API Documentation at this revision

Comitter:
jvfausto
Date:
Tue Oct 16 23:03:40 2018 +0000
Parent:
20:f42db4ae16f0
Child:
22:d2f234fbc20d
Commit message:
revision

Changed in this revision

PID.lib Show annotated file Show diff for this revision Revisions of this file
wheelchair.cpp Show annotated file Show diff for this revision Revisions of this file
wheelchair.h Show annotated file Show diff for this revision Revisions of this file
--- a/PID.lib	Fri Aug 31 20:00:01 2018 +0000
+++ b/PID.lib	Tue Oct 16 23:03:40 2018 +0000
@@ -1,1 +1,1 @@
-https://os.mbed.com/users/jvfausto/code/PID/#60801ab3cbf9
+https://os.mbed.com/users/jvfausto/code/PID/#62f1e316f15b
--- a/wheelchair.cpp	Fri Aug 31 20:00:01 2018 +0000
+++ b/wheelchair.cpp	Tue Oct 16 23:03:40 2018 +0000
@@ -1,414 +1,202 @@
 #include "wheelchair.h"
 
-bool manual_drive = false;
-volatile float north;
-//volatile double curr_yaw;
-double curr_yaw;
-double encoder_distance;
-char myString[64];
-volatile double Setpoint, Output, Input, Input2;
-volatile double pid_yaw, Distance, Setpoint2, Output2, encoder_distance2;
-PID myPID(&pid_yaw, &Output, &Setpoint, 5.5, .00, 0.0036, P_ON_E, DIRECT);
-PID myPIDDistance(&Input, &Output, &Setpoint, 5.5, .00, 0.0025, P_ON_E, DIRECT);
+bool manual_drive = false;                                                             // Variable Changes between joystick and auto drive
+double curr_yaw;                                                                       // Variable that contains current relative angle
+double encoder_distance;                                                               // Keeps distanse due to original position
 
+volatile double Setpoint, Output, Input, Input2;                                       // Variables for PID
+volatile double pid_yaw, Distance, Setpoint2, Output2, encoder_distance2;              // Variables for PID
 
-//PID myPIDDistance2(&Input2, &Output2, &Setpoint2, 5.5, .00, 0.0036, P_ON_E, DIRECT);
-//QEI wheel_right(D0, D1, NC, 450);
-void Wheelchair::compass_thread() {
+PID myPID(&pid_yaw, &Output, &Setpoint, 5.5, .00, 0.0036, P_ON_E, DIRECT);             // Angle PID object constructor
+PID myPIDDistance(&Input, &Output, &Setpoint, 5.5, .00, 0.002, P_ON_E, DIRECT);       // Distance PID object constructor
+
+void Wheelchair::compass_thread() {                                                    // Thread that measures which angle we are at
      curr_yaw = imu->yaw();
-     north = boxcar(imu->angle_north());
-
     }
     
-Wheelchair::Wheelchair(PinName xPin, PinName yPin, Serial* pc, Timer* time, QEI* qei)
+Wheelchair::Wheelchair(PinName xPin, PinName yPin, Serial* pc, Timer* time, QEI* qei)   // Function Constructor for Wheelchair class
 {
-    x = new PwmOut(xPin);
+    //Initializes X and Y variables to Pins
+    x = new PwmOut(xPin);                                                               
     y = new PwmOut(yPin);
+    
+    // Initializes IMU Library
     imu = new chair_BNO055(pc, time);
-    //imu = new chair_MPU9250(pc, time);
-    Wheelchair::stop();
-    imu->setup();
-    out = pc;
-    wheel = qei;
-    out->printf("wheelchair setup done \r\n");
+    Wheelchair::stop();                                                                 // Wheelchair is not moving when initializing
+    imu->setup();                                                                       // turns on the IMU
+    out = pc;                                                                           // "out" is called for serial monitor
+    wheel = qei;                                                                        // "wheel" is called for encoder
+    out->printf("wheelchair setup done \r\n");                                          // make sure it initialized
     ti = time;
-    //wheel = new QEI(Encoder1, Encoder2, NC, EncoderReadRate);
-    myPID.SetMode(AUTOMATIC);
+    myPID.SetMode(AUTOMATIC);                                                           // set PID to automatic
 }
 
-/*
-* joystick has analog out of 200-700, scale values between 1.3 and 3.3
-*/
-void Wheelchair::move(float x_coor, float y_coor)
+void Wheelchair::move(float x_coor, float y_coor)                                       // moves the chair with joystick on manual
 {
 
-    float scaled_x = ((x_coor * 1.6f) + 1.7f)/3.3f;
-    float scaled_y = (3.3f - (y_coor * 1.6f))/3.3f;
-    
-   // lowPass(scaled_x);
-    //lowPass(scaled_y);
+    float scaled_x = ((x_coor * 1.6f) + 1.7f)/3.3f;                                     // Scales one joystic measurement to the
+    float scaled_y = (3.3f - (y_coor * 1.6f))/3.3f;                                     // chair's joystic measurement
     
-    x->write(scaled_x);
+    x->write(scaled_x);                                                                 // Sends the scaled joystic values to the chair
     y->write(scaled_y);
-    
-    //out->printf("yaw %f\r\r\n", imu->yaw());
-
 }
 
-void Wheelchair::forward()
+void Wheelchair::forward()                                                              // In auto to move foward
 {
     x->write(high);
     y->write(def+offset);
-  //  out->printf("distance %f\r\n", wheel_right.getDistance(37.5));
 }
 
-void Wheelchair::backward()
+void Wheelchair::backward()                                                             // In auto to move reverse
 {
     x->write(low);
     y->write(def);
 }
 
-void Wheelchair::right()
+void Wheelchair::right()                                                                // In auto to move right
 {
     x->write(def);
     y->write(low);
 }
 
-void Wheelchair::left()
+void Wheelchair::left()                                                                 // In auto to move left
 {
     x->write(def);
     y->write(high);
 }
 
-void Wheelchair::stop()
+void Wheelchair::stop()                                                                 // Stops the chair
 {
     x->write(def);
     y->write(def);
 }
 // counter clockwise is -
 // clockwise is +
-void Wheelchair::pid_right(int deg) 
+void Wheelchair::pid_right(int deg)                                                     // Takes in degree and turns right
 {
-    bool overturn = false;
+    bool overturn = false;                                                              //Boolean if we have to turn over relative 360˚
     
-    out->printf("pid right\r\r\n");
-    x->write(def);
-    Setpoint = curr_yaw + deg;
-    pid_yaw = curr_yaw;
-    if(Setpoint > 360) {
-     //   Setpoint -= 360;
+    out->printf("pid right\r\r\n");                                
+    x->write(def);                                                                      // Not moving fowards or reverse
+    Setpoint = curr_yaw + deg;                                                          // Relative angle we want to turn
+    pid_yaw = curr_yaw;                                                                 // Sets input to current angle(pid_yaw = input)
+    
+    if(Setpoint > 360) {                                                                //Turns on overturn boolean if setpoint over 360˚
         overturn = true;
     }
-    myPID.SetTunings(5.5,0, 0.0035);
-    myPID.SetOutputLimits(0, def-low-.15);
-    myPID.SetControllerDirection(DIRECT);
-    while(pid_yaw < Setpoint - 3){//curr_yaw <= Setpoint) {
-        if(overturn && curr_yaw < Setpoint-deg-1)
+    
+    myPID.SetTunings(5.5,0, 0.0035);                                                    // Sets the constants for P and D
+    myPID.SetOutputLimits(0, def-low-.15);                                              // Limits to the differnce between def and low
+    myPID.SetControllerDirection(DIRECT);                                               // PID mode Direct
+    
+    while(pid_yaw < Setpoint - 3){                                                      // Tells PID to stop when reaching
+                                                                                        // a little less than desired angle
+        if(overturn && curr_yaw < Setpoint-deg-1)                                       // Sets PID yaw to coterminal angle if necesary
         {
             pid_yaw = curr_yaw + 360;
         }   
         else
             pid_yaw = curr_yaw;
-        myPID.Compute();
-        double tempor = -Output+def;
-        y->write(tempor);
-        out->printf("curr_yaw %f\r\r\n", curr_yaw);
+            
+        myPID.Compute();                                                                // Does PID calculations
+        double tempor = -Output+def;                                                    // Temporary value with the voltage output
+        y->write(tempor);                                                               // Sends to chair y output command
+        
+        out->printf("curr_yaw %f\r\r\n", curr_yaw);                              
         out->printf("Setpoint = %f \r\n", Setpoint);
 
-        wait(.05);
+        wait(.05);                                                                      // Small delay
         }
-    Wheelchair::stop();
+    Wheelchair::stop();                                                                 // Safety Stop
     out->printf("done \r\n");
-    }
+}
 
-void Wheelchair::pid_left(int deg) 
+void Wheelchair::pid_left(int deg)                                                      // Takes in degree and turns left
 {
-    bool overturn = false;
+    bool overturn = false;                                                              //Boolean if we have to turn under relative 0˚
     
-    out->printf("pid Left\r\r\n");
-    x->write(def);
-    Setpoint = curr_yaw - deg;
-    pid_yaw = curr_yaw;
-    if(Setpoint < 0) {
-   //     Setpoint += 360;
+    out->printf("pid Left\r\r\n");                                                     
+    x->write(def);                                                                      // Not moving fowards or reverse
+    Setpoint = curr_yaw - deg;                                                          // Relative angle we want to turn
+    pid_yaw = curr_yaw;                                                                 // Sets input to current angle(pid_yaw = input)
+    if(Setpoint < 0) {                                                                  //Turns on overturn boolean if setpoint under 0˚
         overturn = true;
     }
-    myPID.SetTunings(5,0, 0.004);
-    myPID.SetOutputLimits(0,high-def-.12);
-    myPID.SetControllerDirection(REVERSE);
-    while(pid_yaw > Setpoint+3){//pid_yaw < Setpoint + 2) {
-       myPID.Compute();
-       if(overturn && curr_yaw > Setpoint+deg+1)
+    myPID.SetTunings(5,0, 0.004);                                                       // Sets the constants for P and D
+    myPID.SetOutputLimits(0,high-def-.12);                                              // Limits to the differnce between High and Def
+    myPID.SetControllerDirection(REVERSE);                                              // PID mode Reverse
+    while(pid_yaw > Setpoint+3){                                                        // Tells PID to stop when reaching
+                                                                                        // a little more than desired angle
+       if(overturn && curr_yaw > Setpoint+deg+1)                                        // Sets PID yaw to coterminal angle if necesary
        {
           pid_yaw = curr_yaw - 360;
         }   
         else
             pid_yaw = curr_yaw;
-       double tempor = Output+def;
-
-        y->write(tempor);
+            
+        myPID.Compute();                                                                // Does PID calculations
+        double tempor = Output+def;                                                     // Temporary value with the voltage output
+        y->write(tempor);                                                               // Sends to chair y output command
+        
         out->printf("curr_yaw %f\r\n", curr_yaw);
-        wait(.05);
+        wait(.05);                                                                      // Small Delay
         }
-        Wheelchair::stop();
-    }
+    Wheelchair::stop();                                                                 // Safety Stop
+}
 
-void Wheelchair::pid_turn(int deg) {
-    if(deg > 180) {
+void Wheelchair::pid_turn(int deg) {                                                    // Determine wether we are turn right or left
+
+    if(deg > 180) {                                                                     // If deg > 180 turn left: coterminal angle
         deg -= 360;
     }
 
-    else if(deg < -180) {
+    else if(deg < -180) {                                                               // If deg < -180 turn right: coterminal angle
         deg+=360;
     }  
     
-    int turnAmt = abs(deg);
-    ti->reset();
+    int turnAmt = abs(deg);                                                             // Makes sure input angle is positive
 
     if(deg >= 0){
-        Wheelchair::pid_right(turnAmt);
-        }
+        Wheelchair::pid_right(turnAmt);                                                 // Calls PID right if positive degree
+    }
     else {
-        Wheelchair::pid_left(turnAmt);
-        }
+        Wheelchair::pid_left(turnAmt);                                                  // Calls PID left if negative degree
     }
+}
 void Wheelchair::pid_forward(double mm)
 {
-    mm -= 20;
-    Input = 0;
-    wheel->reset();
+    mm -= 20;                                                                           // Makes sure distance does not overshoot
+    Input = 0;                                                                          // Initializes imput to cero: Test latter w/o
+    wheel->reset();                                                                     // Resets encoders so that they start at 0
     out->printf("pid foward\r\n");
 
-    double tempor;
-    Setpoint = mm;
+    double tempor;                                                                      // Initializes Temporary variable for x input
+    Setpoint = mm;                                                                      // Initializes the setpoint to desired value
 
-  //  Setpoint = wheel_right.getDistance(37.5)+mm;
-    myPIDDistance.SetTunings(5,0, 0.004);
-    myPIDDistance.SetOutputLimits(0,high-def-.15);
-    myPIDDistance.SetControllerDirection(DIRECT);
-    y->write(def+offset);
-    while(Input < Setpoint-5){//pid_yaw < Setpoint + 2) {
-        if(out->readable())
+    myPIDDistance.SetTunings(5.5,0, 0.0015);                                            // Sets constants for P and D
+    myPIDDistance.SetOutputLimits(0,high-def-.15);                                      // Limits to the differnce between High and Def 
+    myPIDDistance.SetControllerDirection(DIRECT);                                       // PID to Direct
+    y->write(def+offset);                                                               // Sets chair to not turn
+    
+    while(Input < Setpoint){                                                            // Stop moving when reaching setpoint
+    
+        if(out->readable())                                                             // Emergency Break
             break;
-        Input = wheel->getDistance(53.975);
-        //out->printf("input foward %d\r\n", wheel->getPulses());
-        wait(.05);
-        myPIDDistance.Compute();
+            
+        Input = wheel->getDistance(53.975);                                             // Gets Distance from Encoder onto PID
+        wait(.05);                                                                      // Slight Delay: *****Test without
+        myPIDDistance.Compute();                                                        // Compute Output for chair
 
-        tempor = Output + def;
-        x->write(tempor);
+        tempor = Output + def;                                                          // Temporary output variable                    
+        x->write(tempor);                                                               // Sends to chair x output
         out->printf("distance %f\r\n", Input);
         }
-        
     
 }   
 void Wheelchair::pid_reverse(double mm)
 {
-   /* qei.putc('r');
-    out->printf("pid reverse\r\n");
 
-    double tempor;
-    Setpoint2 = mm;
-
-  //  Setpoint = wheel_right.getDistance(37.5)+mm;
-    myPIDDistance.SetTunings(5,0, 0.004);
-    myPIDDistance.SetOutputLimits(0,def);
-    myPIDDistance.SetControllerDirection(REVERSE);
-    y->write(def);
-    while(encoder_distance > Setpoint2+5){//pid_yaw < Setpoint + 2) {
-        int i;
-        qei.putc('h');
-        //qei.gets(myString, 10);
-        ti->reset();
-
-        for (i=0; myString[i-1] != '\n'; i++) {
-            while (true) {
-                //pc.printf("%f\r\n", ti.read());
-                if (ti->read() > .02) break;
-                if (qei.readable()) {
-                    myString[i]= qei.getc();
-                    break;
-                    }
-                }
-        }            
-        myString[i-1] = 0;
-        double tempor = atof(myString);
-        out->printf("displacement = %f\r\n", tempor);
-        if(abs(tempor - encoder_distance) < 500)
-        {
-            encoder_distance = tempor;
-            out->printf("this is fine\r\n");
-        }
-        for(i = 0; i < 64; i++)
-        {
-            myString[i] = 0;
-        } 
-        Input = encoder_distance;
-        out->printf("input foward %f\r\n", Input);
-        wait(.1);
-        myPIDDistance.Compute();
-        
-        // get value from encoder2
-        qei.putc('k');
-        ti->reset();
-
-        for (i=0; myString[i-1] != '\n'; i++) {
-            while (true) {
-                //pc.printf("%f\r\n", ti.read());
-                if (ti->read() > .02) break;
-                if (qei.readable()) {
-                    myString[i]= qei.getc();
-                    break;
-                    }
-                }
-        }            
-        myString[i-1] = 0;
-        double tempor2 = atof(myString);
-        out->printf("displacement = %f\r\n", tempor2);
-        
-        if(abs(tempor - encoder_distance) < 500)
-        {
-            encoder_distance = tempor;
-            out->printf("this is fine\r\n");
-        }        
-        if(abs(tempor2 - encoder_distance2) < 500)
-        {
-            encoder_distance2 = tempor2;
-            out->printf("this is fine\r\n");
-        }
-        for(i = 0; i < 64; i++)
-        {
-            myString[i] = 0;
-        } 
-        tempor = Output;
-        x->write(tempor);
-        out->printf("distance %f\r\n", encoder_distance);
-        }*/
 }   
-double Wheelchair::turn_right(int deg)
-{
-    bool overturn = false;
-    out->printf("turning right\r\n");
-
-    double start = curr_yaw;
-    double final = start + deg;
-
-    if(final > 360) {
-        final -= 360;
-        overturn = true;
-    }
-
-    out->printf("start %f, final %f\r\n", start, final);
-
-    double curr = -1;
-    while(curr <= final - 30) {
-        Wheelchair::right();
-        if( out->readable()) {
-            out->printf("stopped\r\n");
-            Wheelchair::stop();
-            return;
-        }
-        curr = curr_yaw;
-        if(overturn && curr > (360 - deg) ) {
-            curr = 0;
-        }
-    }
-    
-    out->printf("done turning start %f final %f\r\n", start, final);
-    Wheelchair::stop();
-    
-     //delete me
-    wait(5);
-    
-    float correction = final - curr_yaw;
-    out->printf("final pos %f actual pos %f\r\n", final, curr_yaw);
-    Wheelchair::turn_left(abs(correction));
-    Wheelchair::stop();
-    
-    wait(5);
-    out->printf("curr_yaw %f\r\n", curr_yaw);
-    return final;
-}
-
-double Wheelchair::turn_left(int deg)
-{
-    bool overturn = false;
-    out->printf("turning left\r\n");
-
-    double start = curr_yaw;
-    double final = start - deg;
-
-    if(final < 0) {
-        final += 360;
-        overturn = true;
-    }
-
-    out->printf("start %f, final %f\r\n", start, final);
-
-    double curr = 361;
-    while(curr >= final) {
-        Wheelchair::left();
-        if( out->readable()) {
-            out->printf("stopped\r\n");
-            Wheelchair::stop();
-            return;
-        }
-        curr = curr_yaw;
-
-        if(overturn && curr >= 0 && curr <= start ) {
-            curr = 361;
-        }
-    }
-
-    out->printf("done turning start %f final %f\r\n", start, final);
-    Wheelchair::stop();
-    
-    //delete me
-    wait(2);
-    /*
-    float correction = final - curr_yaw;
-    out->printf("final pos %f actual pos %f\r\n", final, curr_yaw);
-    Wheelchair::turn_right(abs(correction));
-    Wheelchair::stop();
-*/
-    return final;
-}
-
-void Wheelchair::turn(int deg)
-{
-    if(deg > 180) {
-        deg -= 360;
-    }
-
-    else if(deg < -180) {
-        deg+=360;
-    }  
-    
-    double finalpos;
-    int turnAmt = abs(deg);
-    //ti->reset();
-    /*
-    if(deg >= 0){
-        finalpos = Wheelchair::turn_right(turnAmt);
-        }
-    else {
-        finalpos = Wheelchair::turn_left(turnAmt);
-        }
-    */
-    wait(2);
-    
-    float correction = finalpos - curr_yaw;
-    out->printf("final pos %f actual pos %f\r\n", finalpos, curr_yaw);
-    
-    
-    //if(abs(correction) > turn_precision) {
-        out->printf("correcting %f\r\n", correction);
-        //ti->reset();
-        Wheelchair::turn_left(curr_yaw - finalpos);
-        return;
-        //} 
-    
-}
 
 float Wheelchair::getDistance() {
     return wheel->getDistance(Diameter);
@@ -417,6 +205,7 @@
 void Wheelchair::resetDistance(){
     wheel->reset();
     }
+/*Predetermined paths For Demmo*/    
 void Wheelchair::desk() {
     Wheelchair::pid_forward(5461);
     Wheelchair::pid_right(87);
--- a/wheelchair.h	Fri Aug 31 20:00:01 2018 +0000
+++ b/wheelchair.h	Tue Oct 16 23:03:40 2018 +0000
@@ -1,37 +1,30 @@
 #ifndef wheelchair
 #define wheelchair
 
+//Importing libraries into wheelchair.h
 #include "chair_BNO055.h"
 #include "PID.h"
 #include "QEI.h"
 #include <ros.h>
 #include <geometry_msgs/Twist.h>
-//#include "BufferedSerial.h"
 
-//#include "chair_MPU9250.h"
-
-#define turn_precision 10
-#define def (2.5f/3.3f)
-#define high 3.3f/3.3f
-#define offset .02742f
-#define low (1.7f/3.3f)
-#define process .1
 
-/* for big mbed board
-#define xDir D12 //top right two pins
-#define yDir D13 //top left two pins
-#define Encoder1 D0
-#define Encoder2 D1
-*/
+/*
+* joystick has analog out of 200-700, scale values between 1.3 and 3.3
+*/             
+#define def (2.5f/3.3f)                 //Default axis on joystick to stay neutral; used on x and y axis
+#define high 3.3f/3.3f                  //High power on joystick; used on x and y axis
+#define low (1.7f/3.3f)                 //Low power on joystick; used on x and y axis
+#define offset .035f                  //Joystick ajustment to be able to go strait. Chair dependent on manufactoring presision
+#define process .1                      //Defines default time delay in seconds
 
-//for small mbed board
-#define xDir D9
+//Pin plug in for Nucleo-L432KC
+#define xDir D9                         //PWM Pins
 #define yDir D10
-#define Encoder1 D7
+#define Encoder1 D7                     //Digital In Pull Up Pin
 #define Encoder2 D8
 
-#define EncoderReadRate 1200
-#define Diameter 31.75
+#define Diameter 31.75                  //Diameter of encoder wheel
 /** Wheelchair class
  * Used for controlling the smart wheelchair
  */
@@ -47,21 +40,12 @@
     /** move using the joystick */
     void move(float x_coor, float y_coor);
     
-    /* turn right a certain amount of degrees (overshoots)*/
-    double turn_right(int deg);
-    
-    /* turn left a certain amount of degrees (overshoots)*/
-    double turn_left(int deg);
-    
     /* turn right a certain amount of degrees using PID*/
     void pid_right(int deg);
     
     /* turn left a certain amount of degrees using PID*/
     void pid_left(int deg);
     
-    /* turning function that turns any direction */
-    void turn(int deg);
-    
     /* drive the wheelchair forward */
     void forward();
     
@@ -79,23 +63,35 @@
     
     /* function to get imu data*/
     void compass_thread();
-    void distance_thread();
+    
+    /* move x millimiters foward using PID*/
     void pid_forward(double mm);
+    
+    /* move x millimiters reverse using PID*/
     void pid_reverse(double mm);
+    
+    /*  gets the encoder distance moved since encoder reset*/
     float getDistance();
+    
+    /* resets encoder*/
     void resetDistance();
+    
+    /* function to to determine whether we are turning left or right*/
     void pid_turn(int deg);
+    
+    /* functions with a predetermined path demmo*/
     void desk();
     void kitchen();
     void desk_to_kitchen();
 private:
+    /* Pointers for the joystick speed*/
     PwmOut* x;
     PwmOut* y;
-    chair_BNO055* imu;
-    Serial* out;
-    Timer* tim;
-    Timer* ti;
-    QEI* wheel;
+    
+    chair_BNO055* imu;                  // Pointer to IMU
+    Serial* out;                        // Pointer to Serial Monitor
+    Timer* ti;                          // Pointer to the timer
+    QEI* wheel;                         // Pointer to encoder
 
 };
 #endif
\ No newline at end of file