Nowadays, modern cars incorporate automatic cruise controllers to enhance the driving experience. The main objective of a cruise controller is to maintain car speed despite any external disturbance related to road surfaces or wind profiles. In this example, we will show how to optimally tune a PI controller for a car cruise controller using Collimator.
For a cruise control model, we will consider the longitudinal dynamics of a car. The dynamics can be abstracted as the cascade of the engine force dynamics and the car dynamics Figure 1.
The car dynamics can be modeled as a first-order differential equation:
where \(m=1000\) is the car mass, \(b=50\) is a dynamical damping factor, \(v\) is the car speed, and \(F\) is the engine force. We can build this differential equation in Collimator as a submodel block diagram Figure 2:
The engine dynamics is also modeled as a first-order differential equation:
$$\dot f ̇+λf=u$$
where \(λ=2\) is the engine traction coefficient, \(u\) is the the throttle input, and \(f\) is the generated engine force. The delivered force is amplified by the engine power factor \(μ=100\)
The engine dynamics submodel is shown in Figure 3.
Finally, Figure 4 illustrates the overall cruise control system simulation is implemented in Collimator:
Before we start analyzing the model and tuning the controller, we will import some useful libraries:
From the models we investigated before for the car cruise system, we can abstract the overall model as the linear system block diagram in Figure 5.
Therefore, we will linearize the car dynamics submodel and the engine dynamics submodel to extract the total transfer function of the car cruise system.
The open-loop car cruise system is:
Assuming the PI controller transfer function is \(C(s)\) and to simply the analysis, we will make use of the following closed loop transfer functions:
We will start designing the controller by introducing proportional controller and evaluating some empirical gains:
From the output responses above, we might infer that we can use a high proportional gain to have the required controller. However, let’s have a look at the generated control actions first.
From the control action responses, we can see that the controllers with extremely high gains lead to impractical control actions. This means that for this controller to work, we will need a very powerfull engine that might be physically unrealizable. We can further investigate the error responses.
We can see that increasing the proportional gain reduces the steady state error but might be impractical. Therefore, we will add an integrator to the controller to eliminate the steady error. However, we need to tune two gains \(K_p\) and \(K_i\) . Empirical tuning can be tedious.
We will formulate the PI tuning problem as an optimization problem. Tuning controllers for constrained systems is a non-convex optimization problem. This means that we can get stuck at many local minima. Therefore, we need to use a global optimization algorithm such as the simplicial homology global optimization. But first, we need to define an objective function. We can use the following integral performance index as the objective function.
The squared error integral reflects a higher penalty on larger errors. Also, a weighted squared control action is added to the objective function to penalize higher control actions. We can define the objective function in the Equation above as:
Then, we run the optimization algorithm to find the optimal gains:
The optimal PI gains are \(K_p=7.37\) and \(K_i=0.29\). Now, we investigate the behavior of the obtained controller:
We can see that the tuned controller has a zero steady error with no overshoot and a fast-settling time. By investigating the control action response, we can see that the controller yields a reasonable control action.