Main Content

Driver Calibration using the Closed-Loop PID Autotuner

Since R2023b

This example shows how to tune a PID controller used to represent the driver in a hybrid electric vehicle (HEV) P2 reference application. The HEV P2 reference application represents a full HEV model with an internal combustion engine, transmission, battery, motor, and associated powertrain control algorithms.

HEV P2 Reference Application Overview

In this example, the hybrid electric vehicle is modeled using blocks from Simscape™ and Powertrain Blockset™ software. For more information on this model, see Build Hybrid Electric Vehicle P2 Model (Powertrain Blockset).

To get started, set up and open the Simulink® Project.

openProject('HEVP2');

Open the top level model.

open_system('HevP2ReferenceApplication')

Model Architecture and Conventions

The model is comprised of these blocks.

  1. Environment — Creates environment variables, including road grade, wind velocity, and atmospheric temperature and pressure.

  2. Drive Cycle Source block (FTP75 (2474 seconds)) — Generates a standard or user-specified drive cycle velocity versus time profile. Block output is the selected or specified vehicle longitudinal speed.

  3. Longitudinal Driver — Uses the Longitudinal Driver or Open Loop variant to generate normalized acceleration and braking commands.

  4. Controllers — Implements a powertrain control module (PCM) containing a P2 hybrid control module (HCM), an engine control module (ECM), and a transmission control module (TCM).

  5. Passenger Car — Implements a hybrid passenger car that contains drivetrain, electric plant, and engine subsystems.

  6. Visualization — Displays vehicle-level performance, battery state of charge (SOC), fuel economy, and emission results that are useful for powertrain matching and component selection analysis.

To perform calibration for the driver PID Controller, you focus on the Drive Cycle Source block and Longitudinal Driver subsystems.

PI Controller for Longitudinal Driver

The Longitudinal Driver subsystem allows you to select various control system types to represent the driver. In this example, you use a PI controller. The tuned gains of this controller determine the response of overall system and the driver. You can also deploy the controllers and driver to real hardware to test the performance of the hybrid electric vehicle in a variety of scenarios set by the Drive Cycle Source block or Environment block.

The longitudinal driver model used in this reference application accepts various inputs and outputs an acceleration and deceleration command. The downstream control system for controlling hybrid electric vehicle uses these output commands. By using a controller in place of an actual driver, you can perform repeated testing and verification. However, changing the type of driver requires you to retune the controller and update the gains, or control system used. To reduce the time and effort that is normally required to manually tune gains, regenerate code, and update gains, you can plug an external device such as a laptop into the system to perform the tuning to simulate a different driver. Once you obtain the tuned gains, you can unplug the device and run the system with these new gains. In this workflow, you don't deploy the autotuning algorithm and code to actual hardware and run them solely on an external device for calibration purposes. This example uses the Closed-Loop PID Autotuner block to automatically tune the driver PI controller.

Controller Calibration Setup

To facilitate PI autotuning, this example modifies the original HEV P2 Reference Application with these changes:

  • Add manual switch to grade input of Longitudinal Driver Model.

  • Add a subsystem representing external laptop device.

  • Route signals for velocity feedback, acceleration command, and deceleration command to the External Laptop subsystem.

  • Route perturbation signal to the second input of the manual switch before the grade input.

The subsystem Longitudinal Driver Model shown is a part of the original model and is not modified for this example. In order to inject a signal into the system necessary for calibration, the autotuner block uses the Grade input. Typically, this input is used in the Longitudinal Driver Model as a feedforward term on the output of the PI controller to compensate for the road angle. You can take advantage of this and set the gain value of this feedforward term to 1, and then use this input to inject the perturbation signal required from Closed-Loop PID Autotuner.

The External Laptop subsystem contains the Closed-Loop PID Autotuning block. You use the block to tune a PI controller for the driver as well as combine the acceleration and deceleration commands into a single input (this is necessary for use in the autotuner block). This subsystem saves the tuned gains to a variable PIDGains in the workspace in order to update the driver gains. For real hardware, you can write these gains to a memory location or simply update them manually using tunable parameters. For simulation purposes, use the two step blocks to enable and disable the autotuning process. For hardware, you can replace these with a Constant block or other tunable sources controlled by external hardware or a user.

Baseline Setup with No Autotuning

By default, the model is setup to use PI Control for the driver with gains of 0.1 for both Kp and Ki. All other gains are set to 0 (such as anti-windup and velocity feedforward) and the nominal velocity is set to 1 m/s. To run the simulation in its baseline configuration with no autotuning, click the Baseline Simulation project shortcut, which sets up the model in its default configuration using a Drive Cycle of FTP75.

Set the default gains of the driver PI Controller.

set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/Longitudinal Driver Model','Kp','0.01')
set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/Longitudinal Driver Model','Ki','0.01')

Set the Drive Cycle to FTP75.

set_param('HevP2ReferenceApplication/Drive Cycle Source','cycleVar','FTP75')
set_param('HevP2ReferenceApplication','StopTime','2474')

Disable autotuning.

set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/External Laptop/Enable','Gain','0')
set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/Autotuning','sw','1')

Simulate the model.

sim('HevP2ReferenceApplication.slx')
### Searching for referenced models in model 'HevP2ReferenceApplication'.
### Found 8 model reference targets to update.
### Starting serial model reference simulation build.
### Successfully updated the model reference simulation target for: BattHevP2
### Successfully updated the model reference simulation target for: DrivetrainHevP2
### Successfully updated the model reference simulation target for: HevP2OptimalController
### Successfully updated the model reference simulation target for: HevP2TransmissionController
### Successfully updated the model reference simulation target for: MotMappedP2
### Successfully updated the model reference simulation target for: SiEngineController
### Successfully updated the model reference simulation target for: SiMappedEngine
### Successfully updated the model reference simulation target for: StarterSystemP2

Build Summary

Model reference simulation targets:

Model                        Build Reason                                                    Status                        Build Duration
=========================================================================================================================================
BattHevP2                    Target (BattHevP2_msf.mexa64) did not exist.                    Code generated and compiled.  0h 0m 21.7s   
DrivetrainHevP2              Target (DrivetrainHevP2_msf.mexa64) did not exist.              Code generated and compiled.  0h 0m 51.485s 
HevP2OptimalController       Target (HevP2OptimalController_msf.mexa64) did not exist.       Code generated and compiled.  0h 0m 27.94s  
HevP2TransmissionController  Target (HevP2TransmissionController_msf.mexa64) did not exist.  Code generated and compiled.  0h 0m 12.902s 
MotMappedP2                  Target (MotMappedP2_msf.mexa64) did not exist.                  Code generated and compiled.  0h 0m 11.124s 
SiEngineController           Target (SiEngineController_msf.mexa64) did not exist.           Code generated and compiled.  0h 0m 17.657s 
SiMappedEngine               Target (SiMappedEngine_msf.mexa64) did not exist.               Code generated and compiled.  0h 0m 16.359s 
StarterSystemP2              Target (StarterSystemP2_msf.mexa64) did not exist.              Code generated and compiled.  0h 0m 12.182s 

8 of 8 models built (0 models already up to date)
Build duration: 0h 3m 35.631s

The error between the commanded velocity and actual velocity is large and reaches a maximum value of almost 30 mph. This is due to the slow response time of the driver (or bandwidth).

The baseline driver setup achieves an average fuel economy of approximately 32 MPGe and doesn't track the velocity profile well. The battery SOC also holds a steady value of approximately 68 over the course of the simulation. However, if you want to simulate a different kind of driver, you need to retune the gains of the PI Controller.

Tuning Goals

Use the Closed-Loop PID Autotuner to retune the baseline PI controller in the Longitudinal Driver subsystem. For the Closed-Loop PID Autotuner to work properly, the existing PI Controller needs to be stabilizing and have a slower response (smaller bandwidth) than the final desired PI Controller (existing PI Controller has a bandwidth of 0.1 rad/s and retuned controller goal is 1 rad/s). The second requirement is because the autotuner injects a series of sine waves into the plant to estimate the plant response at five frequencies. If the existing PI Controller has a bandwidth higher than the desired bandwidth, the injections are rejected by the controller.

For this example, retune the existing controller to 1 rad/s then 10 rad/s, but all other settings remain the same. The bandwidth of the controller corresponds to the aggressiveness of the driver with 10 rad/sec representing an aggressive driver. In general, you want the injections into the plant to be large enough for the Closed-Loop PID Autotuner to obtain a good estimate of the plant, but not too large that the system moves away from steady-state or exceed the limits of the plant. For the injections, use an injection sine amplitude that corresponds to 10% of rated speed. This results in a sine amplitude of 0.02 (0.1/5 where 5 is the number of injected frequencies).

Tuning for Average Driver

The first scenario for autotuning is for a driver with a bandwidth of 1 rad/s.

set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/External Laptop/Closed-Loop PID Autotuner','Bandwidth','1')

In order to set up the simulation for autotuning, the vehicle must be at steady-state. Due to the nature of the vehicle dynamics model, the hybrid electric vehicle must have a speed far enough away from zero to avoid plant estimation errors around zero velocity. The Drive Cycle Source block has an option for Wide Open Throttle, which is set to 2 m/s for autotuning (2 m/s is already configured in the Drive Cycle Source block).

set_param('HevP2ReferenceApplication/Drive Cycle Source','cycleVar','Wide Open Throttle (WOT)')

Because you are tuning for a bandwidth of 1 rad/s, the autotuning experiment should be greater than 200/bandwidth. For the simulation length, this should be greater than the experiment start time plus the experiment length. For this driver bandwidth of 1 rad/s, use 250 seconds for the experiment length and 300 seconds for the total simulation time.

set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/External Laptop/Step1','Time','250')
set_param('HevP2ReferenceApplication','StopTime','300')

The final step to set the model up for autotuning is to connect the Closed-Loop PID Autotuner to the controller. There is a gain block that enables or disables the autotuner as well as a switch that toggles between the grade input and autotuner perturbations. To represent connecting an external device, toggle this switch and set the gain to 1.

set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/External Laptop/Enable','Gain','1')
set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/Autotuning','sw','0')

Now that the model is set up for autotuning, run the system up to 2 m/s, tune the P and I gains, and then stop the simulation.

sim('HevP2ReferenceApplication.slx')
### Searching for referenced models in model 'HevP2ReferenceApplication'.
### Found 8 model reference targets to update.
### Starting serial model reference simulation build.
### Model reference simulation target for BattHevP2 is up to date.
### Model reference simulation target for DrivetrainHevP2 is up to date.
### Model reference simulation target for HevP2OptimalController is up to date.
### Model reference simulation target for HevP2TransmissionController is up to date.
### Model reference simulation target for MotMappedP2 is up to date.
### Model reference simulation target for SiEngineController is up to date.
### Model reference simulation target for SiMappedEngine is up to date.
### Model reference simulation target for StarterSystemP2 is up to date.

Build Summary

0 of 8 models built (8 models already up to date)
Build duration: 0h 0m 2.9867s

The block saves the tuned gains to the workspace. Update the gains of the Longitudinal Driver Model PI controller.

set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/Longitudinal Driver Model','Kp',num2str(PIDGains(1)))
set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/Longitudinal Driver Model','Ki',num2str(PIDGains(2)))

Once you have tuned and updated the gains, run the same simulation you did previously to compare the performance of the driver with the new gains versus the original set of gains.

Set the Drive Cycle to FTP75.

set_param('HevP2ReferenceApplication/Drive Cycle Source','cycleVar','FTP75')
set_param('HevP2ReferenceApplication','StopTime','2474')

Disable autotuning to run the simulation with updated gains.

set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/External Laptop/Enable','Gain','0')
set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/Autotuning','sw','1')

Simulate the model.

sim('HevP2ReferenceApplication.slx')
### Searching for referenced models in model 'HevP2ReferenceApplication'.
### Found 8 model reference targets to update.
### Starting serial model reference simulation build.
### Model reference simulation target for BattHevP2 is up to date.
### Model reference simulation target for DrivetrainHevP2 is up to date.
### Model reference simulation target for HevP2OptimalController is up to date.
### Model reference simulation target for HevP2TransmissionController is up to date.
### Model reference simulation target for MotMappedP2 is up to date.
### Model reference simulation target for SiEngineController is up to date.
### Model reference simulation target for SiMappedEngine is up to date.
### Model reference simulation target for StarterSystemP2 is up to date.

Build Summary

0 of 8 models built (8 models already up to date)
Build duration: 0h 0m 1.8569s

With the new gains, the error between the commanded velocity and actual velocity is much smaller and reaches a maximum value of only about 3 mph compared to 30 mph previously. This is due to the much faster response time of the driver (or bandwidth).

The driver follows the target velocity much closer than before. The fuel economy improves from about 32 MPGe to 40 MPGe. The battery SOC is noticeably smaller for this increased bandwidth having a value of about 60 compared to 68 previously. You can retune the existing PI controller again with a much more aggressive bandwidth target of 10 rad/sec.

Tuning for Aggressive Driver

The last scenario for autotuning is for a driver with a bandwidth of 10 rad/sec.

set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/External Laptop/Closed-Loop PID Autotuner','Bandwidth','10')

Similar to the previous autotuning process, set the Drive Cycle Source block to use the Wide Open Throttle profile set to 2 m/s (2 m/s is already configured in the Drive Cycle Source block).

set_param('HevP2ReferenceApplication/Drive Cycle Source','cycleVar','Wide Open Throttle (WOT)')

Because you are tuning for a bandwidth of 10 rad/sec, the autotuning experiment should be greater than 200/bandwidth, as indicated in the block dialog of the Closed-Loop PID Autotuner. For this driver bandwidth of 10 rad/sec, use 25 seconds for the experiment length and 30 seconds for the total simulation time.

set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/External Laptop/Step1','Time','25')
set_param('HevP2ReferenceApplication','StopTime','30')

The final step to set the model up for autotuning is to connect the Closed-Loop PID Autotuner to the controller. Set the gain to 1 and toggle the switch to connect the autotuner to the controller.

set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/External Laptop/Enable','Gain','1')
set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/Autotuning','sw','0')

Run the system up to 2 m/s, tune the P and I gains, and then stop the simulation.

sim('HevP2ReferenceApplication.slx')
### Searching for referenced models in model 'HevP2ReferenceApplication'.
### Found 8 model reference targets to update.
### Starting serial model reference simulation build.
### Model reference simulation target for BattHevP2 is up to date.
### Model reference simulation target for DrivetrainHevP2 is up to date.
### Model reference simulation target for HevP2OptimalController is up to date.
### Model reference simulation target for HevP2TransmissionController is up to date.
### Model reference simulation target for MotMappedP2 is up to date.
### Model reference simulation target for SiEngineController is up to date.
### Model reference simulation target for SiMappedEngine is up to date.
### Model reference simulation target for StarterSystemP2 is up to date.

Build Summary

0 of 8 models built (8 models already up to date)
Build duration: 0h 0m 1.4912s

The block saves the tuned gains to the workspace. Update the gains of the Longitudinal Driver Model PI controller.

set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/Longitudinal Driver Model','Kp',num2str(PIDGains(1)))
set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/Longitudinal Driver Model','Ki',num2str(PIDGains(2)))

Once you have tuned and updated the gains, run the same simulation to compare the performance of the driver with the new gains versus the original set of gains.

Set the Drive Cycle to FTP75.

set_param('HevP2ReferenceApplication/Drive Cycle Source','cycleVar','FTP75')
set_param('HevP2ReferenceApplication','StopTime','2474')

Disable autotuning to simulate the model with the updated gains.

set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/External Laptop/Enable','Gain','0')
set_param('HevP2ReferenceApplication/Longitudinal Driver/Longitudinal Driver/Autotuning','sw','1')

Simulate the model.

sim('HevP2ReferenceApplication.slx')
### Searching for referenced models in model 'HevP2ReferenceApplication'.
### Found 8 model reference targets to update.
### Starting serial model reference simulation build.
### Model reference simulation target for BattHevP2 is up to date.
### Model reference simulation target for DrivetrainHevP2 is up to date.
### Model reference simulation target for HevP2OptimalController is up to date.
### Model reference simulation target for HevP2TransmissionController is up to date.
### Model reference simulation target for MotMappedP2 is up to date.
### Model reference simulation target for SiEngineController is up to date.
### Model reference simulation target for SiMappedEngine is up to date.
### Model reference simulation target for StarterSystemP2 is up to date.

Build Summary

0 of 8 models built (8 models already up to date)
Build duration: 0h 0m 1.7525s

The error between the commanded velocity and actual velocity is larger for this higher bandwidth peaking over 3 mph compared to be just under 3 mph previously. This is due to the driver being over responsive to smaller changes in the target velocity. There are also a lot of higher frequency oscillations most notable around 0 trace velocity error.

The driver follows the target velocity closely, but this results in a reduced fuel economy compared to before. The fuel economy is reduced from 40 MPGe to less than 22 MPGe which is even less than the first simulation result of 32 MPGe. The battery SOC is noticeably smaller for this increased bandwidth having a value of about 45 vs 60 previously. The high bandwidth can result in numerous small adjustments to try and maintain the desired velocity and this has a negative impact on fuel consumption and other aspects of the hybrid electric vehicle.

Summary

This example showed how to automatically tune a longitudinal driver model using PI Control and the Closed-Loop PID Autotuner block. You retune a baseline set of gains to obtain a control bandwidth of 1 rad/sec, and then for 10 rad/sec. The control bandwidth of 1 rad/sec results in the best fuel economy and the lowest velocity error among the three gain sets. While the 10 rad/sec driver follows the target velocity more closely than the baseline driver, the result is a greatly reduced fuel economy.

The Closed-Loop PID Autotuner block is placed in a separate subsystem to represent it on an external device such as a laptop. Using the autotuner on a laptop allows for calibration of the driver controller without the need to generate code for the vehicle. The Autotuner makes use of the Grade input port for the Longitudinal Driver block , but you can adapt it to use an externally supplied injection port for more flexibility.

See Also

Related Topics