Add support for your car to Comma.ai Openpilot

This documents how openpilot works with a car and how support is added. In this article, I am focusing on a Honda Odyssey, but the concepts described can be applied to a Toyota or a new make not supported by openpilot once you grok how they are used.

You can find the openpilot github repository here:

https://github.com/commaai/openpilot

1. Database Container

The .dbc file is a key that describes all of the traffic on the car’s network. Openpilot requires this to read data from your car’s canbus. The DBC is referenced from opendbc which is used to decode traffic on the canbus in realtime.

There is a dbc required for each canbus (Examples: Powertrain CAN, ADAS CAN).

Learn more about DBCs and reverse engineering them here

File ./openpilot/opendbc/*.dbc

Example of a dbc addition

2. Fingerprint

The fingerprint identifies your car to openpilot, it is a list of all the ids (and length) on your car’s main canbus and their size in bytes. If you reference the dbc above, it is essentially an array of all the messages from that file. These are in decimal numbering.

If any of the messages on you car’s canbus 1 are not in this file or have a different size, the fingerprint will fail and not identify your car.

File ./openpilot/common/fingerprints.py

Example

“HONDA ODYSSEY 2018 EX-L”: {
57L: 3, 148L: 8, 228L: 5, 229L: 4, 316L: 8, 342L: 6, 344L: 8, 380L: 8, 399L: 7, 411L: 5, 419L: 8, 420L: 8, 427L: 3, 432L: 7, 450L: 8, 463L: 8, 464L: 8, 476L: 4, 490L: 8, 506L: 8, 542L: 7, 545L: 4, 597L: 8, 662L: 4, 773L: 7, 777L: 8, 780L: 8, 795L: 8, 800L: 8, 804L: 8, 806L: 8, 808L: 8, 817L: 4, 819L: 7, 821L: 5, 825L: 4, 829L: 5, 837L: 5, 856L: 7, 862L: 8, 871L: 8, 881L: 8, 882L: 4, 884L: 8, 891L: 8, 892L: 8, 905L: 8, 923L: 2, 927L: 8, 929L: 8, 963L: 8, 965L: 8, 966L: 8, 967L: 8, 983L: 8, 985L: 3, 1029L: 8, 1036L: 8, 1052L: 8, 1064L: 7, 1088L: 8, 1089L: 8, 1092L: 1, 1108L: 8, 1110L: 8, 1125L: 8, 1296L: 8, 1302L: 8, 1600L: 5, 1601L: 8, 1612L: 5, 1613L: 5, 1614L: 5, 1615L: 8, 1616L: 5, 1619L: 5, 1623L: 5, 1668L: 5
}

Structure

  • HONDA ODYSSEY 2018 EX-L: Make Model Year Trim
  • 57L: 3: 57 is a message id in decimal format, 3 is the length of the message in bytes.

Example Commit

3. Car State

Reads values about your car’s current state. Openpilot uses this information to know fast your is going, how much your wheel is turned, etc.

This file and the other files listed below (interface, car can, and car controller) are specific to every manufacturer. If a port exists for another car with same make (like Honda or Toyota), these already exist so you just need to add to them.

File ./openpilot/selfdrive/car/honda/carstate.py

Example Carstate Values

  • Transmission Speed
  • Wheel Speeds
  • Steer Angle
  • Doors open
  • Seatbelt Latched
  • Left and right blinkers on

Example Commit

4. Interface

Contains specifics about your car’s specs and details about your car’s UI like what error messages it has and what buttons are being pressed.

File ./openpilot/selfdrive/car/honda/interface.py

Example Commit

5. Car Can

This file is structured as <make>can.py.

All can message preparation and message compilation for can messages written to the canbus are set in this file. Messages created for braking, applying gas, and steering are contained in this file. If there are messages that your radar must read, they also would be sent from here. If your car’s messages have checksums, they are calculated here.

Checksums

Hondas have a counter and checksum in the last byte of most messages. The last four bits of a message contain the checksum and the two bits before the checksum is a counter (There are exceptions, reference the fix() function in hondacan.py to see how they are calculated).

The counter counts up from 0 to 3 and resets back to zero. This the 2 bit value is highlighted in the gold color below.

The checksum is calculated using the message id and contents of the message. It is highlighted below in blue.

File ./openpilot/selfdrive/car/honda/hondacan.py

Example Commit

6. Car Controller

Car controller sends control commands at appropriate frequencies. The maximum steering, gas, and braking values are also set in this file which can differ by car model.

File ./openpilot/selfdrive/car/honda/carcontroller.py

Example Commit


Thanks for reading, comment if you have any questions.