User Tools

Site Tools


lego_ball_and_beam

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
lego_ball_and_beam [2016/01/31 16:44] joaomatoslego_ball_and_beam [2016/02/04 17:07] (current) joaomatos
Line 11: Line 11:
  **# Attempt to use PID:**  **# Attempt to use PID:**
    
- Researching on the internet found that the integral term is not necessary. ( possible to see after obtaining the transfer function of the B&B system , the integral term will add another integrator , making the system more unstable).+ I will start only with PD control , and after got a good response i will introduce the integral term to avoid the case where the motor does not rotate if the ball stop close to the set point distance.
            
  * __Proportional control:__ The bar will lift up or down as fast as how far is the ball from the setpoint.Power output command proportional to distance from sensor.  * __Proportional control:__ The bar will lift up or down as fast as how far is the ball from the setpoint.Power output command proportional to distance from sensor.
Line 63: Line 63:
 After working on the code idea from week 1 , the final code flowchart is shown below: After working on the code idea from week 1 , the final code flowchart is shown below:
  
-{{:flow_final.png?200|}}+{{::flow_ballandbeam.png?200|}}
  
 ** PROBLEMS:** ** PROBLEMS:**
Line 84: Line 84:
  
  
-** PD Control :** Since then i'm trying to tune the gains to make the system works smoothly, but i can't do it. Analyzing the video below , it feels like the system is not fast enough to brake the ball when it's accelerating from one end to another of the platform ( the motor takes too long to rotate when the ball is moving around the set point distance , so the ball overshoot it everytime ). I'm not sure if this is gain problem or the algorithm is wrong.+** PD Control :** Since then i'm trying to tune the gains to make the system works smoothly, see video below. The system response still very slow taking 20 seconds to reject a disturbance. I'm not sure if i can make it better tuning the gains or i should change the algorithm.
  
-{{youtube>i7qcr_2QfYA?medium}}+{{youtube>l0wOiOC10NE?medium}}
    
 +
 +** PID Control :** I will apply the integral term after i can make the PD works. So the integral term will help on the case where the ball stops near to the setpoint , but not on it. ( the derivative term goes to 0 and the proportional term is very small ).
 +
 +
    
 +**ALGORITHM IDEA : **
 + I'm using a PD (after will be PID) to get the ball distance from the set point. A serie of conditional statements makes the platform goes down and up depending on how far is the ball from the set point. After the motor get to the desired angle , it will go back to 0 deg.  
  
 ** NXT CODE **: ** NXT CODE **:
  
-     // Sensor files 
            
-      #include "dist-nx-lib.nxc" +   // Files from the Long Range IR sensor 
-      #define DIST_ADDR 0x02+    #include "dist-nx-lib.nxc" 
 +    #define DIST_ADDR 0x02
  
-     // PID GAINS +   task main() { 
-       +    // Set and Start the Sensor on Port1 
-      #define KP 3 +    SetSensorLowspeed(S1); 
-      #define KD 2+    DISTNxSendCommand(S1, DIST_CMD_ENERGIZED, DIST_ADDR); 
 +    byte result; 
 +    PosRegEnable(OUT_A);
  
-     // A function that calculates the distance and the velocity. +   // Defining Variables 
-       +    float KP=1,KD=0.5;     // Proportional and Derivative Gains 
-      void calculatedistvelo(int &dist, float &velocity) +    int positiondistd_setpoint, i=0 d_array[5]
-      { +    float velocity; 
-       int i,prevdist=481,d_array[5]; +    int prevdist,d_test
-       float prevtick, dt; +    float prevtick, dt
-        +    string positionstr,ptext,rawstr,rtext;
-      // The distance used is the average from 5 measures.  +
-       +
-      while (i<5) +
-      { +
-      d_array[i]=(DISTNxReadValue(S1DIST_REG_DIST_LSB2DIST_ADDR)); +
-      i=i+1; +
-      } +
-      i=0+
-       +
-      dist=ArrayMean(d_array,NA,NA);   // Distance is avg from measures +
-      dt=CurrentTick()- prevtick    // Time interval from each loop +
-      velocity=(dist-prevdist)/dt;    // Calculating Velocity +
-      velocity=velocity*1000        //Converting to mm/s +
-      prevtick=CurrentTick()+
-      prevdist=dist; +
-      }   // end calculate distance and velocity +
-     +
  
-    task main() +    // Preparing to enter the loop 
-    +     d_setpoint=460; 
-    // Initialize and set the Long Range IR Sensor+     prevdist=461; 
 +     prevtick=0; 
 + 
 + 
 +    // Control Loop 
 +     while (true
 +     
 +     // The distance used is the average from 5 measures. 
 +     while (i<5) 
 +     { 
 +     d_array[i]=(DISTNxReadValue(S1, DIST_REG_DIST_LSB, 2, DIST_ADDR)) ; 
 +     i=i+1; 
 +     } 
 +     i=0; 
 + 
 +     dist=ArrayMean(d_array,NA,NA);   // Distance is avg from 5 measures 
 +     dt=CurrentTick()- prevtick;     // Time interval from each loop 
 +     velocity=(dist-prevdist)/dt;    // Calculating Velocity 
 +     velocity=velocity*1000;         //Converting to mm/s 
 +     prevtick=CurrentTick(); 
 +     prevdist=dist; 
 + 
 +    // ball position equation applying PD control: 
 +     position = KP*(dist-d_setpoint) + KD*(velocity); 
 + 
 +    // Show the raw distance and the position on the screen 
 +     rawstr=NumToStr(dist); 
 +     rtext=StrCat("raw:",rawstr); 
 +     TextOut(10,LCD_LINE4,rtext); 
 +     positionstr=NumToStr(position); 
 +     ptext=StrCat("distance:", positionstr); 
 +     TextOut(10,LCD_LINE2,ptext); 
 + 
 +     // conditional statements to control the platform 
 +     if (position >35 & position <45) 
 +     { 
 +     PosRegAddAngle(OUT_A,-20); 
 +     Wait(100); 
 +     }
            
-     SetSensorLowspeed(S1); +     if (position >45 & position <55) 
-     DISTNxSendCommand(S1DIST_CMD_ENERGIZED, DIST_ADDR); +     { 
-     byte result;+     PosRegAddAngle(OUT_A,-21); 
 +     Wait(100); 
 +     } 
 +     if (position >55 & position <65) 
 +     { 
 +     PosRegAddAngle(OUT_A,-23); 
 +     Wait(100); 
 +     }
            
-    // Defining variables+     if (position >65 & position <75) 
 +     
 +     PosRegAddAngle(OUT_A,-22); 
 +     Wait(100); 
 +     }
            
-     int power, dist, d_setpoint=480; +     if (position >75 & position <85)
-     float velocity; +
-     while(true)+
      {      {
 +     PosRegAddAngle(OUT_A,-25);
 +     Wait(100);
 +     }
 +
 +     if (position >85 & position <100)
 +     {
 +     PosRegAddAngle(OUT_A,-30);
 +     }
 +
 +     if (position >100 & position <300)
 +     {
 +     PosRegAddAngle(OUT_A,-65);
 +     Wait(80);
 +     }
 +
 +     if (position >300)
 +     {
 +     PosRegAddAngle(OUT_A,-80);
 +     Wait(100);
 +     }
 +
 +     // Especial conditions , close to the setpoint
 +     if (position <35 & position >-35)
 +     {
 +     PosRegSetAngle(OUT_A,0);
 +     Wait(150);
 +     }
 +
 +     if (position <-35 & position >-45)
 +     {
 +     PosRegAddAngle(OUT_A,20);
 +     }
 +
 +     if (position <-45 & position >-55)
 +     {
 +     PosRegAddAngle(OUT_A,25);
 +     Wait(100);
 +     }
            
-     // Get the Distance and Velocity of the ball from the function +     if (position <-55 & position >-65) 
-       +     { 
-     calculatedistvelo(dist,velocity);+     PosRegAddAngle(OUT_A,30); 
 +     Wait(100); 
 +     }
            
-     //Power equation using PD control: +     if (position <-65 & position >-75) 
 +     { 
 +     PosRegAddAngle(OUT_A,35); 
 +     Wait(100); 
 +     }
            
-     power = KP*(dist-d_setpoint+ KD*(velocity); +     if (position <-75 & position >-85
-      +     { 
-     // Power < 0 means the ball is going in direction to the sensor +     PosRegAddAngle(OUT_A,40); 
-     // OnFwd makes the platform goes down to break the ball +     Wait(100); 
-     // Power >0 0 means the ball is going in direction to the motor +     }
-     // OnRev makes the platform goes up ( to break the ball )+
  
-     if (power 0)+     if (position <-85 & position >-100)
      {      {
-     OnRev(OUT_A,(power/15));+     PosRegAddAngle(OUT_A,45);
      }      }
-    if (power )+ 
 +     if (position <-100 & position >-300)
      {      {
-     OnFwd(OUT_A,abs((power/15)));+     PosRegAddAngle(OUT_A,50); 
 +     } 
 + 
 +     if (position <-300) 
 +     { 
 +     PosRegAddAngle(OUT_A,60)
 +     Wait(100);
      }      }
-      
-      // end while 
-      // end task 
  
 +     Wait(130);
 +     ClearScreen();
 +     PosRegSetAngle(OUT_A,0);  // Return the platform to 0 deg
 +          // end while
 +           // end task
  
-** #WEEK 3 SCHEDULE**: 
  
- *1I'm planning to spend one more day trying to do the gain tune.+** #WEEK 3 REPORT **:
  
- *2Finish all the theoretical work: derive the transfer function and simulate it on Simulink to get the system parameters.+ *1I changed the algorithm to make the system run smoothly.
  
- *3Get back to the algorithm and think in something new+ *2Derivation of the transfer function that represent the ball and beam system.
  
- *4Make the system run smoothly+ *3Simulation using Simulink and comparison with real system
  
- *5: Include a File Saving function on the code, plot a disturbance rejection situation and compare it to the simulink model. + [[pid_vs_lqr_ballandbeam| WEEK 3 WORK ]]
lego_ball_and_beam.1454287495.txt.gz · Last modified: by joaomatos