OpenCyphal / libcanard

A compact implementation of the Cyphal/CAN protocol in C for high-integrity real-time embedded systems
http://opencyphal.org
MIT License
328 stars 192 forks source link

Support for UAVCAN/CAN v0 #188

Closed Regelink closed 2 years ago

Regelink commented 2 years ago

Some sensors use UAVCAN/CAN v0, while newer sensors use v1. Currently libcanard rejects UAVCAN/CAN v0 transfers since the initial toggle bit is 0 in v0 and 1 in v1. This is a problem when nodes implementing different versions of UAVCAN need to be supported.

Why is v0 not supported in libcanard v2 (I mean is there a good reason for not supporting it)? Will simply changing INITIAL_TOGGLE_STATE to 0 work in order to support (only) UAVCAN/CAN v0 nodes? What would need to be done in order to support both v0 and v1 (simultaneously)? The specification for UAVCAN/CAN v1.0-beta says in paragraph 4.2.1 that UAVCAN/CAN and UAVCAN/CAN v0 nodes can share the same bus, so it seems not unreasonable to support both versions in libcanard simultaneously.

Reasons for using the latest libcanard (and not legacy-v0) for interfacing UAVCAN/CAN v0 nodes are for instance improved performance for CRC calculation.

pavel-kirienko commented 2 years ago

At the transport layer, supporting both versions of UAVCAN/CAN is, indeed, not expected to be very difficult. The necessary changes are: flipping the initial state of the toggle bit, moving the transfer-CRC to the first frame of the transfer, and pre-seeding the transfer-CRC calculation with the data type hash.

At the application layer, things will get slightly more involved because the standard data types used by v0 and v1 differ quite a bit. Again, this is certainly not impossible but you should expect that your application will need to implement separate logic for things like PnP node-ID allocation, node introspection, configuration management, etc.

You may get an idea of the scope of the required changes if you look at Kocherga: https://github.com/Zubax/kocherga/blob/master/kocherga/kocherga_can.hpp

New applications should not consider UAVCAN v0 unless compatibility with ArduPilot is a requirement. The reasons for that are far more extensive than mere improved CRC computation. As I recently wrote:

If compatibility with ArduPilot is a requirement, then staying with v0 might be a wise decision. In all other scenarios, this would likely be a mistake.

  1. v0 is only suitable for highly centralized systems where there is only one actor responsible for the consumption of data from the bus and the issuance of imperatives to other nodes.

  2. v0 is only suitable for networks that match the rigid architectural patterns envisioned by the authors of its data types. E.g., if you have a quadplane and the authors of the ESC service did not foresee that use case, you're out of luck.

  3. v0 only supports CAN, which is being phased out in the industry. In five years every major medium- to the high-end vehicle will be heavily leveraging Ethernet.

  4. All existing implementations of v0 (both official and third-party) are seriously lacking in quality compared to v1, which might make them inadmissible in many systems where UAVCAN would be useful.

You may find more information on the differences here: https://forum.uavcan.org/t/uavcan-2019-roadmap/666


Despite that, adding support for UAVCAN v0 would be accepted on a separate branch in the interest of easing the transition from the legacy to the stable version of the standard. If you are able to work on this, I would be happy to provide guidance and help.

pavel-kirienko commented 2 years ago

This is likely to be outside of the scope of the project going forward. See details at https://forum.uavcan.org/t/uavcan-v1-is-now-cyphal/1622/3. Perhaps this functionality could be implemented as an independent effort.