Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Synchronize controls with the CAN bus #547

wants to merge 33 commits into
base: devel


None yet
1 participant
Copy link

Gernby commented Mar 4, 2019

This enhancement works way better than I hoped, and actually reduces the CPU utilization of boardd. The primary goal was to ensure that steering sensor data from the vehicle was neither skipped OR reused by controls due to mismatches in sample timing.

The current logic uses a static 5 ms sleep time between the end of one CAN sample and the start of the next CAN sample in boardd. This results in very irregular sample resolution due to varying traffic loads and USB thread contention. For cars with heavy CAN traffic, the sample period of a particular 100Hz CAN frame can be deteriorated to an effective alternating 50Hz / 200Hz rate. This irregularity causes a direct deterioration of controls.


The proposed logic has 2 synchronization modes. Both modes require the cp.update() method to wait for a packet from boardd. The difference is in the way boardd determines when to send the packet. If the new "syncID" value is set in interface for a vehicle, then boardd will synchronize itself on the receipt of that CAN frame. This ensures that controls will never outpace the CAN bus (even if it runs below 100Hz).


The second mode is the default mode, when there isn't a syncID defined in interface. In this mode, boardd will precisely synchronize on time. It will drain the Panda 3 times per 0.01 seconds, but it will only send the data 1 time per 0.01 seconds. To ensure precision, the first 2 calls to the Panda will occur at a "soft" 4.5 ms, with the sleep occurring outside of the USB lock. However, the 3rd call to the Panda will occur inside the USB lock, so that USB contention doesn't disrupt timing.

In order to prevent irregularity in control processing after the packet is received from boardd, the existing rate keeper is used to stage the data that will be sent back to the vehicle. However, there can be only 1 absolute rate keeper, so an optional offset was added to the rk.keep_time() method. This allows for occasional disruptions in the system without overrunning the secondary rate keeper.

Gernby added some commits Jan 10, 2019


This comment has been minimized.

Copy link

Gernby commented Mar 4, 2019

FYI... I just fixed some [embarrassing] mistakes I made while cleaning up the code for this PR. I apparently cleaned too deep ,and broke a couple things. I just finished retesting both sync modes, and have a cabana drive to share from each.

Here is a drive using the default time-based synchronization, and here is one using the STEERING_SENSORS frame as the syncID.

Gernby added some commits Mar 5, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.