lego_ball_and_beam
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
lego_ball_and_beam [2016/01/25 23:02] – created joaomatos | lego_ball_and_beam [2016/02/04 17:07] (current) – joaomatos | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | . | + | ** #WEEK 1 REPORT ** |
+ | |||
+ | | ||
+ | |||
+ | **# Finished building the structure.** | ||
+ | |||
+ | **# Sensor limitations: | ||
+ | I got the Syntax to get the reading of this sensor in the seller' | ||
+ | |||
+ | |||
+ | **# Attempt to use PID:** | ||
+ | |||
+ | I will start only with PD control , and after i 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. | ||
+ | |||
+ | * __Derivative control:__ to avoid oscillations from pure proportional control ( helps to brake the ball when close to setpoint).Power output command proportional to velocity ( d/dt distance). | ||
+ | |||
+ | |||
+ | ** # Code Sketch ** | ||
+ | |||
+ | | ||
+ | |||
+ | |||
+ | |||
+ | | ||
+ | |||
+ | |||
+ | |||
+ | | ||
+ | |||
+ | |||
+ | d_actual = sensor reading | ||
+ | error = d_actual – d_prev | ||
+ | dt= (currenttick – prevtick ) // unity is ms | ||
+ | velocity = error/dt | ||
+ | d_prev= d_actual | ||
+ | prevtick=currenttick | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Task to calculate the motor output to keep the balance | ||
+ | |||
+ | kp= ... | ||
+ | | ||
+ | while true | ||
+ | | ||
+ | |||
+ | if power <0 // as the OnFwd does not accept negative values for the power output | ||
+ | OnRev(port , ABS(power)) | ||
+ | |||
+ | | ||
+ | | ||
+ | end if | ||
+ | |||
+ | End while | ||
+ | |||
+ | |||
+ | ** #WEEK 2 REPORT ** | ||
+ | |||
+ | After working on the code idea from week 1 , the final code flowchart is shown below: | ||
+ | |||
+ | {{:: | ||
+ | |||
+ | ** PROBLEMS: | ||
+ | |||
+ | ** Sensor Imprecision ** : Even with the ball stable , the distance measured by the sensor keeps changing ( See video below, the distance keeps changing around 490~~500 ).This floating on the distance induce a wrong velocity calculation ( The ball is stable but the velocity is not 0 ). | ||
+ | |||
+ | * __Solution: | ||
+ | |||
+ | | ||
+ | |||
+ | |||
+ | |||
+ | ** TUNING THE GAINS : IS THE ALGORITHM CORRECT? | ||
+ | |||
+ | **Proportional Control **: Using only the proportional control the system responses seems to be good , the system is showing the desired behavior . The motor only changes the rotation direction when the ball cross the set point distance. | ||
+ | |||
+ | {{youtube> | ||
+ | |||
+ | ** Derivative Control **: After applying the filter in the distance measures ( still floating 5mm ) , the first step i took was to find a gain value for the derivative term that is low enough to ignore the floating when the ball is stable and high enough to be sensible and brake the ball when it's accelerating. | ||
+ | |||
+ | |||
+ | ** 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> | ||
+ | |||
+ | |||
+ | ** 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 : ** | ||
+ | | ||
+ | |||
+ | ** NXT CODE **: | ||
+ | |||
+ | |||
+ | // Files from the Long Range IR sensor | ||
+ | #include " | ||
+ | #define DIST_ADDR 0x02 | ||
+ | |||
+ | task main() { | ||
+ | // Set and Start the Sensor on Port1 | ||
+ | SetSensorLowspeed(S1); | ||
+ | DISTNxSendCommand(S1, | ||
+ | byte result; | ||
+ | PosRegEnable(OUT_A); | ||
+ | |||
+ | // Defining Variables | ||
+ | float KP=1, | ||
+ | int position, dist, d_setpoint, i=0 , d_array[5]; | ||
+ | float velocity; | ||
+ | int prevdist, | ||
+ | float prevtick, dt; | ||
+ | string positionstr, | ||
+ | |||
+ | // Preparing to enter the loop | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | |||
+ | // Control Loop | ||
+ | while (true) | ||
+ | { | ||
+ | // The distance used is the average from 5 measures. | ||
+ | while (i<5) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | // ball position equation applying PD control: | ||
+ | | ||
+ | |||
+ | // Show the raw distance and the position on the screen | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | // conditional statements to control the platform | ||
+ | if (position >35 & position <45) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | if (position >45 & position <55) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | if (position >55 & position <65) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | if (position >65 & position <75) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | if (position >75 & position <85) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | if (position >85 & position <100) | ||
+ | { | ||
+ | | ||
+ | } | ||
+ | |||
+ | if (position >100 & position <300) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | if (position >300) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | // Especial conditions , close to the setpoint | ||
+ | if (position <35 & position >-35) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | if (position <-35 & position >-45) | ||
+ | { | ||
+ | | ||
+ | } | ||
+ | |||
+ | if (position <-45 & position >-55) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | if (position <-55 & position >-65) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | if (position <-65 & position >-75) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | if (position <-75 & position >-85) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | if (position <-85 & position >-100) | ||
+ | { | ||
+ | | ||
+ | } | ||
+ | |||
+ | if (position <-100 & position >-300) | ||
+ | { | ||
+ | | ||
+ | } | ||
+ | |||
+ | if (position <-300) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | |||
+ | ** #WEEK 3 REPORT **: | ||
+ | |||
+ | *1: I changed the algorithm to make the system run smoothly. | ||
+ | |||
+ | *2: Derivation of the transfer function that represent the ball and beam system. | ||
+ | |||
+ | *3: Simulation using Simulink and comparison with real system | ||
+ | |||
+ | |
lego_ball_and_beam.1453791740.txt.gz · Last modified: by joaomatos