This document is intended to review prior art in terms of vehicle interface implementations and implementation of components.
Autoware.Auto
Autoware.Auto does not have a holistic vehicle interface. Some discussion and documentation was started.
Use case discussion
DBW interfaces to support:
- Dataspeed
- NewEagle
- PACMod
- ZMP HEV
- YMC
Interfaces:
- Longitudinal
- Velocity
- Max/min acceleration
- Lateral
- Angular acceleration
- Desired/max curvature
- Other
- Gear shifting
- Turn signal
Misc discourse posts
Vehicle interface reference implementation
Apollo
Apollo has a centralized vehicle interface. Their primary communication mechanism appears to be CAN. They support various vehicles using a factory pattern.
The primary input to their vehicle interface is a ControlCmd, which has a many fields.
The primary output of their vehicle interface is Chassis and ChassisDetail.
CanBus
- Apollo CanBus
CanbusComponent
receives control command, and publishes chassis status
- Controller is embedded in the canbus
- Delays are tracked, and messages that arrive too soon are ignored
- Different vehicles are supported via the factory pattern
- Vehicle objects are used to instantiate a vehicle controller
- The vehicle controller is essentially an API to control the vehicle
- Brake, steer, throttle, enable/disable autonomous mode, gear, horn, signals, ebrake, steering only, speed only
- Have optional functionality to only control longitudinal, or only control lateral
- Appears to have autogenerated "protocol" code
CAN client
Link
- A timer-based sensor driver
- Separate sender and receiver
- Sender has a very high priority set (
99
)
- CAN client is an interface class
- They have different clients for different CAN cards (Fake, Esd, Hermes, Socket)
- Each type gets constructed via a factory pattern
- Send API is
std::vector<CanFrame> * const, int32_t * const)
Autoware.ai
Autoware.ai does not have a vehicle interface. There are scattered packages supporting various drive-by-wire interfaces. Some discussion for a holistic design was started.
Design work
- Autoware discussion in #1541
- Design
- Concrete node, wrapping
VehicleAbstraction
, which wraps the following:
- CanDriver interface
- CanMsg parent class
- Discussion primarily centers around the implementation of a CAN message class
- There's also discussion on whether to use the
can_msg/Frame
to separate the CAN driver from the vehicle interface (and get DDS in between)
Vehicle Socket
- vehicle_socket
- Separate the sender and receiver
- Sender
- Spins ROS to receive a
VehicleCmd
message, and place it into some global struct
- Creates a thread that creates a thread that writes data in plain text to a TCP port
- Receiver
- Has publisher of
CANInfo
type
- Creates a pthread that spawns a thread to listen on a TCP port and deserialize CAN data
YMC
- YMC
- A ROS node wrapping a library
- Has some extra logic for handling keyboard input
- Has logic for handling gamepad/joystick input
- May have a custom CAN sender
Kvaser
- kvaser
- Converter just listens to the
CANInfo
topic, deserializes it, and prints the contents
CanDraw
does the same, but also publishes a linelist for the steering direction
- The listener listens via Kvaser CanLib, and publishes a
CANInfo
message
mqtt socket
- mqtt_socket
- Separate the sender and receiver
- Sender sends as a plain-text string of the following:
- CANInfo
- PoseStamped
- TwistStamped
- String
- Receiver just handles a comma-delimited string
AS (AutonomouStuff) node
- as
- Plain translation node, subscribe, then publish
- Uses lots of message filters
- Has some emergency stopping built in
Comma.ai's OpenPilot
CAN
- openpilot CAN
- Autogenerates some code based on a DBC defintion
- Lots of vehicle-specific parsing code
boardd
- boardd
- Performs a VIN check on startup (via ODB codes)
- May connect to CAN via USB
- Health data: autonomous on, "gas interceptor" on, GPS, CAN send errors, CAN "fwd" errors, GMLan errors, hardware type, and USB power mode
car
Editorial
Overall architecture
Common themes in all implementations and designs are:
- Support of different vehicle platforms
- Support of different communication mechanisms
- Using a common component which can handle communication from the ADAS stack to the vehicle platform
- None of the implementations add much extra logic in the interface
The first three points are encapsulated in the VehicleInterfaceNode
and the VehicleInterface
abstract class.
It can also be argued that a generic sender/receiver class can be developed for different communication mechanisms. Specific platform interfaces can then use whichever communication mechanism is most appropriate (which is presumably fixed).
As such, it's probably appropriate to not try to modularize the vehicle interface on the communication level, but rather the platform level.
For the latter point, it can be argued that since we are supporting a federated stack rather than a monolithic stack that having extra logic in the interface is appropriate.
From a safety perspective, it also makes sense to have some amount of "safety" logic to ensure that the vehicle interface strictly assumes all other components are working properly.
Vehicle communication interfaces
Different vehicle platforms use different communication interfaces. Even within a particular interface type (i.e. CAN), there are many different implementations.
These interfaces include:
- CAN
- SocketCAN
- Kvaser
- Dataspeed
- NewEagle
- PACMod
- ZMP HEV
- YMC
- ESD
- Hermes
- ODB
- FlexRAY
In the near term, it likely makes the most sense to support CAN. Further developments will depend on customer demand.
Interfaces
Most interfaces (e.g. Apollo, OpenPilot, and even Autoware.AI to a lesser extent) include in a large amount of commands into a single message.
On aggregate, the net representation appears to be the same.
No other interface appears to directly support multiple possible input types, which is a consequence of a federated vs monolithic model.
Related issues
- #4942: Review prior art and related art in vehicle interface design
- #4770: Review new design articles for the 1.0.0 release