Hi David! Thank you for starting this thread, and apologies for taking my time to get back to you – am traveling.
As I indicated on Matrix, this matter is of interest but it is outside of the scope of the Cyphal standard (which is not to say that it can’t be discussed on this forum). Some time ago one would have said that it is within the domain of UDRAL, but UDRAL itself is currently being transferred to a completely separate effort that is maintained on GitHub here by @Dima:
Hence what we are discussing here is within the domain of DS-015. You will see that many of your valid concerns are already sensibly addressed by Cyphal out of the box.
In Cyphal, one should normally tend towards clarity and simplicity over bandwidth optimization. The idiomatic approach here is to use fixed larger types, like int16
or float32
(or float16
if you can tolerate ~10 bit resolution), for all analog channels. Variable-width encoding is not supported in Cyphal (nor DroneCAN). The topic of good interface design is covered at length in the Guide.
Cyphal (unlike DroneCAN) allows you to add/remove fields to a data type definition without breaking backward compatibility. Practical examples are covered both in the Guide linked above and in the Specification, section 3.8 “Compatibility and versioning”. This feature has limitations but the use case you outlined could serve as a perfect example of data type versioning.
On the high level, this description begs the objection of being too stateful and complex. Some systems are certain to benefit from the added flexibility, while others where functional safety guarantees are of interest will be difficult to reconcile with it. For an in-depth discussion, refer to the section of the Guide dedicated to stateful interfaces.
However, if you choose to express your configurables via dedicated topics, you will see that the logic you described can be implemented in Cyphal (not DroneCAN) out of the box without the need to reinvent custom negotiation protocols. The key here is to choose a particular topic naming format that encodes the required information in the topic name. For example, channels_0to8_13bit_200hz
, etc (this is just a crude example; at this point I see little reason to segregate options by resolution). Then, in the case of a high-integrity system, the integrator will be able to choose one (or several) topic once and configure it manually, while in the case of a more flexible PnP scenario the flight controller would simply list the available topics and find the one that suits its configuration best, and then enable it selectively. The other topics would remain, of course, unused, thus consuming zero resources from the network and from the publisher node.
A closely related topic is that of the PnP node configuration. Please read this:
You can further enhance your message definition somewhat to take advantage of the different, receiver-defined update rates per channel (and possibly resolution, although as I said earlier this may not be justifiable). To do this, you could define a separate data type that carries the channel value and its index, let’s call it Channel.1.0
:
# Channel.1.0
uint8 channel_index
Value.1.0 value
@extent 64
In the fixed-resolution case, Value.1.0
would be simply a native numeric type like int16
or float32
. In the variable-resolution case, you would make it a union like this:
# Value.1.0
@union
uint16 high_resolution
uint8 low_resolution
@sealed
Then you fold it into an array in the top-level type that is actually published by the receiver:
Channel.1.0[<=16] channels
# The array contains only those channels that are updated in this cycle.
To compensate for the possible message loss, the receiver could force an update every 100 ms or so regardless of whether there’s been an actual change.
Cyphal does not distinguish between Classic CAN and CAN FD (sic, FDCAN is not the correct spelling and may hinder forum searchability). As a designer of the network service, you should focus on the higher-level objectives and leave the matter of transport management to the transport layer. I recommend that you think in terms of network services, domain objects, and topics, and purposefully forget about the low-level aspects until the final stages of the design process.