Merged to branch

Dependencies:   USBDevice mbed EquatorStrutController LightWeightSerialTransmit

Fork of EquatorStrutDigitalMonitor by Stewart Coulden-Smith

Files at this revision

API Documentation at this revision

Comitter:
alpesh
Date:
Wed Aug 13 08:31:24 2014 +0000
Parent:
12:814db1249a19
Child:
14:67466da6663d
Commit message:
Implemented 2 PID (Position and Velocity). Also, clamping mechanism for Integral Term

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Wed Aug 13 06:43:02 2014 +0000
+++ b/main.cpp	Wed Aug 13 08:31:24 2014 +0000
@@ -196,7 +196,8 @@
     //return SmoothedInterruptPeriod();
 }
 
-double Error = 0;
+double PosError = 0;    //This has been defined here as it's being used in the serial transmit function
+double VelError = 0;
 
 void SerialOut(double outputValue)
 {
@@ -262,9 +263,13 @@
     }
 }
 
-double KpGain = 0.0;
-double KiGain = 0.0;
-double KdGain = 0.0;
+double PosKpGain = 0.0;
+double PosKiGain = 0.0;
+double PosKdGain = 0.0;
+
+double VelKpGain = 0.0;
+double VelKiGain = 0.0;
+double VelKdGain = 0.0;
 
 void SerialTransmit()
 {    
@@ -284,19 +289,19 @@
     
     pc.putc('\t');
     
-    SerialOut(Error);
+    SerialOut(PosError);
     
     pc.putc('\t');
     
-    SerialOut(KpGain);
+    SerialOut(PosKpGain);
     
     pc.putc('\t');
     
-    SerialOut(KiGain);
+    SerialOut(PosKiGain);
     
     pc.putc('\t');
     
-    SerialOut(KdGain);
+    SerialOut(PosKdGain);
     
     pc.putc(10);
     pc.putc(13);
@@ -322,52 +327,116 @@
     RGHCosInterrupt.enable_irq();
 }
 
-double SetPoint = 50.0; //Millimeter per second
+
+double SetPoint = 50.0; //Target Position in Millimeter per second
 
-double KpTerm;
-double ErrorInt;
-double ErrorDer;
+double PosProError;
+double PosIntError;
+double PosDifError;
+
+double VelProError;
+double VelIntError;
+double VelDifError;
 
 int errorcounter;
-double PreviousError [10];
+double PosPreviousError [10];
+double VelPreviousError [10];
 
 double PwmChange=0;
 
 double pwm;
-double NewPwm;
+double TargetPwm;
+double TargetVelocity;
 
-int previousTime = 0;
+double PosiState;
+double VeliState;
+
+int PreviousTime = 0;
+
+double vMax = 60;
 
 void Controller ()
 {
-    if (position <= SetPoint || 1)
-    {
-        int timeStep = RunningTime.read_us() - previousTime;
-        previousTime = RunningTime.read_us();
+    
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    //Position PID
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    
+    //if (position <= SetPoint || 1)
+    
     
-        Error = SetPoint - position;
+    //{
+        int timeStep = RunningTime.read_us() - PreviousTime;
+        PreviousTime = RunningTime.read_us();
+        
+        double integral_velmax = vMax/VelKiGain;
+        double integral_velmin = -vMax/VelKiGain ;
+           
+        PosError = SetPoint - position;
+
+        PosProError = PosError * PosKpGain;
+
+        PosDifError = (PosError - PosPreviousError[errorcounter]) / timeStep;           
 
-        KpTerm = Error * KpGain;
-
-        ErrorDer = (Error - PreviousError[errorcounter]) / timeStep;           
-
-        ErrorInt = ErrorInt + Error * timeStep;
-
-        NewPwm = (KpTerm + KiGain * ErrorInt + KdGain * ErrorDer);
-
-        if (NewPwm > 1.0) 
+        
+        PosiState += PosError;
+        
+        if (PosiState > integral_velmax)     
+        {
+            PosiState = integral_velmax;   
+        }
+        else if (PosiState < integral_velmin)   
+        {
+            PosiState = integral_velmin;
+        }
+        PosIntError = PosKiGain * PosiState;
+        
+        TargetVelocity = (PosKpGain * PosError + PosKdGain * PosDifError + PosIntError);
+        
+    
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    //Velocity PID
+    ///////////////////////////////////////////////////////////////////////////////////////////////     
+       
+       double integral_pwmmax = 1.0/VelKiGain;
+       double integral_pwmmin = -1.0/VelKiGain;
+       
+        VelError = TargetVelocity - GetSpeed();
+        
+        VelProError = VelError * VelKpGain;
+        
+        VelDifError = (VelError - VelPreviousError[errorcounter]) / timeStep; 
+        
+        //Calculate the integral state with appropriate limiting
+        
+        VeliState += VelError;
+        
+        if (VeliState > integral_pwmmax)
+        {
+            VeliState = integral_pwmmax;
+        }
+        else if (VeliState < integral_pwmmin)
+        {
+            VeliState = integral_pwmmin;
+        }
+    
+        VelIntError = VelKiGain * VeliState;
+        
+        TargetPwm = (VelKpGain * VelError + VelKdGain * VelDifError + VelIntError);
+    
+        if (TargetPwm > 1.0) 
         {
             pwm = 1.0;
         }
     
-        else if (NewPwm < -1.0)
+        else if (TargetPwm < -1.0)
         {
             pwm = -1.0;
         }
     
         else
         {
-            pwm = NewPwm;
+            pwm = TargetPwm;
         }
     
         SetPower(pwm);
@@ -379,8 +448,12 @@
             errorcounter = 0;   
         }
 
-        PreviousError[errorcounter] = Error;
-    }
+        PosPreviousError[errorcounter] = PosError;
+        VelPreviousError[errorcounter] = VelError;
+   // }
+        
+    
+  
 }
 
 int main()
@@ -399,23 +472,23 @@
     //Enable();
     
     errorcounter = 0;
-    PreviousError[errorcounter]=0;
+    PosPreviousError[errorcounter]=0;
     
-    previousTime = RunningTime.read_us();
+    PreviousTime = RunningTime.read_us();
 
     while(Enabled)
     {
         //double pow = 0.0;
-        while(KpGain < 1.0)
+        while(PosKpGain < 1.0)
         {
-            KpGain += 0.01;
-            while(KiGain < 1.0)
+            PosKpGain += 0.01;
+            while(PosKiGain < 1.0)
             {
-                KiGain += 0.01;
+                PosKiGain += 0.01;
                 
-                while(KdGain < 1.0)
+                while(PosKdGain < 1.0)
                 {
-                    KdGain += 0.01;
+                    PosKdGain += 0.01;
                     
                     float iterationStart = RunningTime.read();
                     
@@ -436,7 +509,7 @@
 }
 
 /* Change this throttle value range to 1.0 and 0.0 for car speed
-m_throttlechange = (m_kpGain * m_error + m_kdGain * m_ErrorDer + m_ErrorInt);
+m_throttlechange = (m_kpGain * m_error + m_kdGain * m_PosDifError + m_PosIntError);
 
             double throttle = m_throttle + m_throttlechange;