You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
3.4 KiB
95 lines
3.4 KiB
# What is cereal?
|
|
|
|
cereal is the messaging system for openpilot. It uses [msgq](https://github.com/commaai/msgq) as a pub/sub backend, and [Cap'n proto](https://capnproto.org/capnp-tool.html) for serialization of the structs.
|
|
|
|
|
|
## Messaging Spec
|
|
|
|
You'll find the message types in [log.capnp](log.capnp). It uses [Cap'n proto](https://capnproto.org/capnp-tool.html) and defines one struct called `Event`.
|
|
|
|
All `Events` have a `logMonoTime` and a `valid`. Then a big union defines the packet type.
|
|
|
|
### Best Practices
|
|
|
|
- **All fields must describe quantities in SI units**, unless otherwise specified in the field name.
|
|
- In the context of the message they are in, field names should be completely unambiguous.
|
|
- All values should be easy to plot and be human-readable with minimal parsing.
|
|
|
|
### Maintaining backwards-compatibility
|
|
|
|
When making changes to the messaging spec you want to maintain backwards-compatibility, such that old logs can
|
|
be parsed with a new version of cereal. Adding structs and adding members to structs is generally safe, most other
|
|
things are not. Read more details [here](https://capnproto.org/language.html).
|
|
|
|
### Custom forks
|
|
|
|
Forks of [openpilot](https://github.com/commaai/openpilot) might want to add things to the messaging
|
|
spec, however this could conflict with future changes made in mainline cereal/openpilot. Rebasing against mainline openpilot
|
|
then means breaking backwards-compatibility with all old logs of your fork. So we added reserved events in
|
|
[custom.capnp](custom.capnp) that we will leave empty in mainline cereal/openpilot. **If you only modify those, you can ensure your
|
|
fork will remain backwards-compatible with all versions of mainline openpilot and your fork.**
|
|
|
|
An example of compatible changes:
|
|
```diff
|
|
diff --git a/cereal/custom.capnp b/cereal/custom.capnp
|
|
index 3348e859e..3365c7b98 100644
|
|
--- a/cereal/custom.capnp
|
|
+++ b/cereal/custom.capnp
|
|
@@ -10,7 +10,11 @@ $Cxx.namespace("cereal");
|
|
# DO rename the structs
|
|
# DON'T change the identifier (e.g. @0x81c2f05a394cf4af)
|
|
|
|
-struct CustomReserved0 @0x81c2f05a394cf4af {
|
|
+struct SteeringInfo @0x81c2f05a394cf4af {
|
|
+ active @0 :Bool;
|
|
+ steeringAngleDeg @1 :Float32;
|
|
+ steeringRateDeg @2 :Float32;
|
|
+ steeringAccelDeg @3 :Float32;
|
|
}
|
|
|
|
struct CustomReserved1 @0xaedffd8f31e7b55d {
|
|
diff --git a/cereal/log.capnp b/cereal/log.capnp
|
|
index 1209f3fd9..b189f58b6 100644
|
|
--- a/cereal/log.capnp
|
|
+++ b/cereal/log.capnp
|
|
@@ -2558,14 +2558,14 @@ struct Event {
|
|
|
|
# DO change the name of the field
|
|
# DON'T change anything after the "@"
|
|
- customReservedRawData0 @124 :Data;
|
|
+ rawCanData @124 :Data;
|
|
customReservedRawData1 @125 :Data;
|
|
customReservedRawData2 @126 :Data;
|
|
|
|
# DO change the name of the field and struct
|
|
# DON'T change the ID (e.g. @107)
|
|
# DON'T change which struct it points to
|
|
- customReserved0 @107 :Custom.CustomReserved0;
|
|
+ steeringInfo @107 :Custom.SteeringInfo;
|
|
customReserved1 @108 :Custom.CustomReserved1;
|
|
customReserved2 @109 :Custom.CustomReserved2;
|
|
customReserved3 @110 :Custom.CustomReserved3;
|
|
```
|
|
|
|
---
|
|
|
|
Example
|
|
---
|
|
```python
|
|
import cereal.messaging as messaging
|
|
|
|
# in subscriber
|
|
sm = messaging.SubMaster(['sensorEvents'])
|
|
while 1:
|
|
sm.update()
|
|
print(sm['sensorEvents'])
|
|
|
|
```
|
|
|
|
```python
|
|
# in publisher
|
|
pm = messaging.PubMaster(['sensorEvents'])
|
|
dat = messaging.new_message('sensorEvents', size=1)
|
|
dat.sensorEvents[0] = {"gyro": {"v": [0.1, -0.1, 0.1]}}
|
|
pm.send('sensorEvents', dat)
|
|
```
|
|
|