How to write a car port for openpilot

openpilot is an open source self-driving agent. Currently it performs the functions of Adaptive Cruise Control (ACC) and Lane Keeping Assist System (LKAS). There are hundreds of daily openpilot drivers, a community of thousands of enthusiasts who joined the comma’s Slack channel. Numbers are growing quickly and so does openpilot driving quality.

A significant number of developers contributed to the openpilot repository on GitHub in many ways: bug fixes, improvements, and car ports. A car port consists in adding support for additional car brands and models to openpilot’s code. As of July 2018, openpilot officially supports almost every Honda/Acura and Toyota/Lexus currently sold, plus a Chevy. Many of these car models have been added to the list thanks to the comma community.

We can distinguish between 2 main types of car ports:

  1. Model Port: the car’s brand is already supported, but the specific model, model year or trim isn’t. Despite some exceptions where apparently similar cars are very different “under the hood” (see Honda Civic 2018 sedan VS hatchback), usually such ports require minimal code changes. Here is an example of pull request for a Model Port.
  2. Brand Port: Either the car’s brand isn’t supported or the specific car model is substantially different from any currently supported cars. Those type of ports usually require a substantial amount of code to be written in openpilot and panda repositories. In particular, original safety logic needs to be added to panda.

comma already published a detailed guide on how to make a Model Port, specifically for Toyota. The goal for this guide is to provide a more high level procedure that covers all car ports, including Brand Ports. Particular attention is given to the safety aspect of the port.

Background — safety architecture

No safety relevant code runs on the EON. To use functional safety terminology, the EON functionality is considered Quality Management (QM). This means that any failure in delivering the desired output at the right time is perceived as bad quality and has no safety implications. You might be perplexed: the code running on the EON is responsible, for example, for determining the desired car trajectory and you might think that a bug in this algorithm might be a safety threat. But it’s not, openpilot is a Level 2 ADAS system and the driver must pay attention at all time! No ADAS system currently on the market has safety guarantees on perception or planning algorithms.

So, what must be guaranteed is the ability of the driver to easily regain full control of the vehicle at any time. In openpilot, this is done through the satisfaction of the 2 main safety principles that a Level 2 driver assistance system must have:

  1. the driver must always be capable to immediately re-take manual control of the vehicle, by stepping on either pedal or by pressing the cancel button;
  2. the vehicle must not alter its trajectory too quickly for the driver to safely react. This means that while the system is engaged, the actuators are constrained to operate within reasonable limits.

All the safety relevant code runs real-time on a STM32 micro (inside the Panda OBD II dongle), it’s written in C and it’s placed at the interface between the car and the EON. The safety code is included in openpilot as a submodule but it’s maintained in its own panda repository.

These safety requirements, written as is, are still a little abstract and a further step is required to translate them into implementable requirements. We can develop them as follow.

  • Upon stepping on either pedal or pressing the cancel button, the panda safety code shall not allow any non-zero gas, brake or steer command until the user presses the engage button again.
  • openpilot shall immediately cancel when the driver’s seat-belt is unlatched or the driver’s door is open. This is to prevent the driver leaving the vehicle while openpilot is still engaged.
  • Max accel and decel injections: the maximum acceleration and deceleration of the vehicle shall be limited between 2m/s² and -3.5m/s², respectively¹. These limits are a more conservative than what’s recommended in ISO 22179.
  • Max steer injection: in the case of a completely erroneous steering command, the driver shall have at least 1 second of reaction time before the car significantly deviates from its original path.
  • Steer loss: while in a turn, in the case of an immediate loss of steering torque, the driver shall have at least 1 second of reaction time before the car significantly deviates from the desired path (e.g. lane lines crossing).
  • Steer injection against driver’s desire: the driver shall be capable of overriding openpilot’s steering strenght with minimal effort: less than 3 Nm of extra torque applied at the steering wheel shall be necessary to correct openpilot’s steering control.

The specific implementation of those requirements depends on the specific car control APIs, as explained here.

Submit a successful car port pull request to openpilot

STEP 1a — Develop a car port
openpilot is written to be as generic as possible, by separating car specific code (e.g. decoding CAN messages into generic car states, such as speed and acceleration) from common openpilot functionalities (e.g. perception, planning and high level controls).
With the exception of the panda safety code and the dbc file, the car specific code if fully contained in /data/openpilot/selfdrive/car/. When developing a car port you should focus on making changes to this folder only, although it’s possible that some generalization to the rest of the code are required. If you are making a Brand Port, you should create a new folder with the name of the brand you intend supporting. Otherwise, in the case of a Model Brand, you should only modify files within the existing car brand folder (e.g. /data/openpilot/selfdrive/car/toyota/).

STEP 1b — Develop a safety model for your car port
In the case of a Brand Port, you should also implement a new safety model for the panda repo. Each car brand has at least one safety model associated to it (see header files in/data/openpilot/panda/board/safety/). Also, each safety model must have its own regression test file (see /data/openpilot/panda/tests/safety/), which you should submit as well as part of the pull request for the panda repo.

Writing a new safety model might seem hard at first. Luckily, there is a high chance that you car has longitudinal and lateral control APIs similar to some that already supported cars have.

For example, if the longitudinal control API allows to command directly the gas pedal and the brake pressure (see Chevy Volt), you might simply enforce that the gas and brake commands are constrained within values that satisfy the acceleration limits mentioned above.

In the case of a lateral control API based on steering torque (again, see Chevy Volt), you might want to enforce the max torque commanded and the rate at which such torque is commanded. Additionally, you might want to limit the steering torque when applied in the opposite direction of the torque applied by the driver.

STEP 2 — Open a pull request to openpilot, panda and opendbc repos
Opening a pull request to openpilot is probably the best way to get support from the large community. However, while you are welcome to open a car port pull request for openpilot at anytime, be conscious about the possibility that other users might be installing your WIP fork on their EON dev kit.

The panda repo is included within openpilot, but it’s maintained in its own repo. In the case of a Brand Port, you should submit a pull request to cover the safety in panda. See the above guidelines on how to write a safety model.

If needed, you should also open a pull request for the opendbc repo if the car you are writing the port for needs a new dbc file. We already have many dbc files, so your car might already be here.

STEP 3 — Get opendbc and panda pull requests merged
opendbc and panda are independent repositories (shipped as subtrees in openpilot), so comma will merge those pull request before and regardless the status of the openpilot pull request. New dbc files and panda safety models are always welcome.

STEP 4 — Have the port officially listed in “Community Maintained Cars”
comma will review that proper safety code has been implemented. In the case of a Model Port, this is usually unnecessary as the safety code is shared with other already supported models.
If the safety model review is successful and comma has proof that the car port meets the quality standards (send us a video of your car being controlled by openpilot!), then the port can be listed in the “Community Maintained Cars” section of the openpilot README. A car listed in “Community Maintained Cars” does not guarantee that the comma safety model is met, just that enough diligence has been done for this step; the port can then be listed in the “Community Maintained Cars” section of the openpilot README.

openpilot ported to a Hyundai
openpilot ported to a pre-Autopilot Tesla

STEP 5 — Get the openpilot pull request merged
At comma’s discretion, some car ports can be upstreamed into the openpilot repo and become officially supported, while other might maintain the status of “Community Maintained Cars” indefinitely. It mainly depends on the code quality/complexity of the pull request, and on the popularity of the car/the presence of such a brand in comma’s fleet. Feel free to bring your car to comma’s HQ for a test drive :)