Deploy code that will balance a ball on a beam
Introduction
The ball on the horizontal beam is unstable. Due to the effects of gravity the ball will roll to one end of the beam and the beam will not stay in the horizontal position. However using a motor we can control the beam’s orientation and the ball’s position.
The position of the ball is measured by an IR distance sensor. The beam is controlled by a servo motor. The operating voltage required by the motor is maintained by a power converter. The desired position of the ball is specified using a potentiometer. The controller, running on an Arduino Uno, measures the potentiometer and IR sensor values and sends an appropriate signal to the servo motor.
We will start by computing a model of the system. Then we will obtain the calibration for both the IR sensor and the servo motor. We will design three controllers: a PID controller, a pole-placement controller, and an integral controller and compare their responses.
Parts
Makeblock servo motor [link]
Shaft connector [link]
Makeblock Servo motor bracket pair [link]
Makeblock Beam0824-320 pair [link]
Makeblock Beam0824-192 pair [link]
Makeblock Beam0824-160 pair [link]
Makeblock Beam0824-144 [link]
Makeblock Beam0824-096 pair [link]
Makeblock Bracket 3x3 pair [link]
7 M4x22mm screws [link], 30 M4x14mm screws [link], 5 M4x8mm screws [link], 14 M4 nuts [link], and 3 4x7x2 plastic rings [link]
3D printed motor flange-to-beam female connector [link]
3D printed motor flange-to-beam male connector [link]
2 3D printed beam ends [link]
IR distance sensor [link] with 3-pin female cable [link] and housing [link]
Arduino Uno [link]
Potentiometer [link]
Protoshield [link]
Male header pins [link]
USB cable [link]
Adjustable DC&DC Power Converter [link]
Power supply adapter [link]
Misc standoffs [link]
A heavy weight or a clamp
Adhesive mounting squares [link]
A pin-pong ball
Assembly
Screw 2 0824-096 and 2 0824-160 beams together using 4 M4x14 screws to create the base. (Fix adhesive squares to the bottom if there is a possibilty of chattering during operation.)
Screw a 3x3 bracket to each 0824-160 beam using 2 M4x14 screws and 2 nuts.
Screw a 0824-192 beam to each 0824-160 beam using 2 M4x22 screws and 2 nuts.
Screw the 0824-144 beam to the top of the 2 0824-192 beams using 4 M4x14 screws.
Screw a motor bracket to the 0824-144 beam using 2 M4x14 screws and 2 nuts.
Screw together the motor, motor flange, shaft connector, and the flange-to-beam female connector using 1 M4x22 screws in the center and 2 M4x14 screws.
Screw the motor assembly to the motor bracket using 3 M4x8 mm screws and 3 plastic rings.
After inserting the 3-pin female cable in to IR distance sensor on one end and the housing on the other, screw the sensor onto one of the beam ends using 2 M4x8 screws.
On one of the 0824-320 beams create a scale with markings.
Screw the beam ends to the 2 0824-320 beams using 8 M4x14 screws.
Screw the flange-to-beam male connector the 0824-320 beam without the markings using 2 M14x22 screws and 2 nuts.
Screw the bracket onto one of the 0824-320 beams on the IR sensor side using 2 M4x14 screws and 2 nuts.
Insert the male connector holding the beam onto the female conenctor on the motor assembly, and clamp the setup using the weight.
Wire the electrical connections using a protoshield board or a breadboard. Before connecting the the power converter make sure that the output voltage (VOUT) is set to 6V.
Raise the Arduino using stand offs and stack the protoshield board on top of it
Connect the motor and sensor to the correct locations on the protoshield board.
Modeling
The ball and beam as viewed from the front.
We will consider the angle specified to the servo motor as the control input. Thus along with ignoring the dynamics of the motor, we can also ignore the mass of the beam.
The Lagrangian is computed as the difference between the kinetic and potential energies.
In[1]:= |
Out[1]= |
We will assume that the ball is a hollow sphere and that it rolls without slipping.
In[2]:= |
Use a linearizing feedback with control input u that will linearize the system.
In[3]:= |
The Lagrangian after including the additional assumptions and linearizing feedback.
In[4]:= |
Out[4]= |
The equation of motion.
In[5]:= |
Out[5]= |
The linear StateSpaceModel with u as input and r as output.
In[6]:= |
Out[6]= |
Out[7]= |
Sensor calibration
Embed the code that will read the IR sensor value and output it on the serial channel.
In[8]:= |
In[9]:= |
Out[9]= |
Open a connection to the microcontroller.
In[10]:= |
Out[10]= |
A function to parse the incoming data.
In[11]:= |
A task to read the incoming data.
In[13]:= |
Place the ball at various locations on the beam and record the sensor reading.
The sensor data.
In[24]:= |
In[25]:= |
Out[25]= |
After acquiring sufficient data points stop the task and close the connection.
In[26]:= |
Fit a nonlinear model to the data.
In[28]:= |
Out[28]= |
Compare the data and the model.
In[29]:= |
Out[29]= |
Restructure the model as a NonlinearStateSpaceModel.
In[30]:= |
Out[30]= |
Servo calibration
We will use the Arduino servo library to control the motor.
In[31]:= |
Out[31]= |
The servo output channel.
In[32]:= |
The ‘angle’ of the servo specified in the library takes a value from 0 to 180. This is not the same as θ used in the model. We will need to determine the map between θ and ‘angle’.
To do this, we will create a model with the servo output as a specific ‘angle’ value.
In[51]:= |
Out[51]= |
When it is embedded to the microcontroller the beam will orient itself accordingly.
In[52]:= |
Out[52]= |
Measure and record the resulting θ. Repeat the process to obtain several data points.
In[54]:= |
In[55]:= |
Out[55]= |
Fit a nonlinear model to the data.
In[56]:= |
Out[56]= |
Compare the data and the model.
In[57]:= |
Out[57]= |
Restructure the model as a NonlinearStateSpaceModel.
In[58]:= |
Out[58]= |
If θ is large the beam could strike the table. Also as the controller brings back the beam from a large θ value the, the ball could jump off the beam. To prevent this we put clamps on how much the servo can rotate from the equilibrium value of θ==0.
In[59]:= |
In[62]:= |
Out[62]= |
Create a model for the clamp.
In[63]:= |
Out[63]= |
Misc components
We will now create the model of some of the other components that we will be using.
The reference position is set by a potnentiometer that reads from 0 to 5V. Create a model that maps it to - 6 cm to 6 cm.
In[64]:= |
Out[64]= |
In[65]:= |
Out[65]= |
Restructure the model as a NonlinearStateSpaceModel.
In[66]:= |
Out[66]= |
The model of the comparator to compare the reference and actual positions.
In[67]:= |
Out[67]= |
For simuation we will also need a continuous-time comparator.
In[68]:= |
Out[68]= |
The arc sin function asin in the AVR-Libc library will give an error if the argument is not in the correct range. A model that gracefully handles the ArcSin computation.
In[69]:= |
Out[69]= |
Another model that ensures the arc sin argument is in the correct range.
In[70]:= |
Out[70]= |
The microcontroller specifications for the controller code.
In[71]:= |
The microcontroller, port, and library specifications.
In[72]:= |
The sampling period.
In[73]:= |
PID controller design
Design a PID controller with a filtered derivative part.
In[73]:= |
Out[73]= |
The closed-loop system.
In[74]:= |
Out[74]= |
Simulate the closed-loop system.
In[75]:= |
Out[75]= |
The simulation shows that is takes a while to settle down. Looking at the eigenvalues of the system we see that some are close to the imaginary axis.
In[76]:= |
Out[76]= |
The feedback controller.
In[77]:= |
Out[77]= |
The feedforward filter.
In[78]:= |
Out[78]= |
Discretize the pid controller.
In[79]:= |
Out[79]= |
PID controller deployment
The complete PID controller.
In[80]:= |
Out[80]= |
Load the package.
Embed the controller.
In[81]:= |
Out[81]= |
Pole-placement controller design
We will use pole-placement to move the poles further into the left half-plane. Because this uses full state-feedback and only the position r is measured, we also need to an estimator. In addition a feedforward term is needed for the controller to track the reference signal.
Compute the feedback gains using StateFeedbackGains.
In[82]:= |
Out[83]= |
Compute the estimator gains EstimatorGains.
In[84]:= |
Out[85]= |
The state estimator.
In[86]:= |
Out[86]= |
The feedback controller.
In[87]:= |
Out[87]= |
The feedforward controller.
In[88]:= |
In[90]:= |
Out[90]= |
The structure of the controller and plant.
The closed-loop system.
In[91]:= |
Out[91]= |
The eigenvalues of the closed-loop system.
In[92]:= |
Out[92]= |
Verify that they are at the designed locations.
In[93]:= |
Out[93]= |
In[94]:= |
Out[94]= |
Discretize the controllers.
In[95]:= |
Out[95]= |
Pole-placement deployment
The complete pole-placement controller.
In[96]:= |
Out[96]= |
Embed the controller.
In[97]:= |
Out[97]= |
Integral controller design
Augment the state equations with the integral of the error.
In[98]:= |
Out[98]= |
A set of optimal gains that heavily penalize the error.
In[99]:= |
Out[99]= |
The eigenvalues of the closed-loop system.
In[100]:= |
Out[100]= |
The feedforward controller.
In[101]:= |
Out[101]= |
The feedback controller.
In[102]:= |
Out[102]= |
The structure of the controller and plant.
The closed-loop system.
In[103]:= |
Out[103]= |
Compute the eigenvalues.
In[104]:= |
Out[104]= |
In[105]:= |
Out[105]= |
In[106]:= |
Out[106]= |
Discretize the controllers.
In[107]:= |
Out[107]= |
Integral controller deployment
The complete integral controller.
In[108]:= |
Out[108]= |
In[109]:= |
Out[109]= |
Conclusions
The simulations of the step reponses of the linear closed-loop systems with the three controllers shows the pole-placement controller performing better than the others.
In[110]:= |
Out[111]= |
As expected the PID controller does not perform well with the double integrator system. In the actual physical system it is characterized by large settling times and overshoots. It had good steady-state response.
The pole-placement controller worked well, but it perfommed very poorly on a different setup with a different IR sensor and motor.
Overall, the integral controller worked the best in terms of transient, steady-state, and disturbance response. It was robost enough to maintain good performance when the sensors and motor was changed.
More things to try
- Simulate the disturbance responses.
- Try different PID tuning rules.
- Try other feedback and estimator gains.
- Investigate the difference when the nonlinear ArcSin element is removed.
- Introduce antiwindup control.