The standard data type set PR that I submitted several days ago might look like a chunk of data that is too big to swallow in one PR. The motivation for pooling all of the items of the new data type set together was to encourage holistic approaches and reduce possible internal inconsistencies.
What we need to agree upon right now is the general structure and not bit-level implementation details. I probably made a mistake by assigning the version number 1 to most of the new data types – @kjetilkjeka was right to point out that some of them should be reverted to v0 pending stabilization. I am going to fix that right away.
Spreading the design process thinly over multiple subsequent PR might cause unnecessary delays, and we know that our design process is a soft real-time process, where delays can be harmful. I suggest we stick with that one PR unless we identified any particular blockers, in which case we can remove them from the PR and discuss separately later (although due to the above reasons that would be undesirable).
Seeing as my freshly coined term “vendor-specific public static” raised some eyebrows (justifiably), I should elaborate on that here.
As has been said elsewhere, the new standard UAVCAN data type set (can we call it “DTS”? yay another three-letter acronym) is not supposed to contain any domain-specific data types, rather it should be focused on very, very generic entities, such as physical quantities. Those should be sufficient to build very generic and flexible yet not very efficient interfaces.
Vendors and OEMs are encouraged to use the generic interfaces everywhere, resorting to vendor-specific data types where higher efficiency is desired. As I see it, there can be two kinds of vendor-specific DTS:
- Vendor-specific DTS designed for closed ecosystems. For instance, a vendor is building a vehicle or a combination of UAVCAN-interfaced modules which are tightly integrated and are not supposed to interface with any other UAVCAN hardware from any other vendor. This scenario means that the outside world does not care about the DTS defined by the vendor (or OEM, which are the same thing for the purposes of this scenario). I suggest calling such DTS a “vendor-specific private data type set”. It is said to be “private” because no one else is supposed to know or see these definitions because no one else needs to.
- Vendor-specific DTS designed for COTS equipment or open ecosystems. This is like the above, except that the equipment or vehicles designed by the vendor might need to be interfaced with third-party nodes. I suggest calling these “vendor-specific public data type set”, and I would like to further separate it into two sub-categories:
- Data type definitions where the Subject or Service ID is assigned statically (i.e., in the name of the DSDL file, such as
123.GetCalibrationData.2.3.uavcan
). As the ID is assigned statically, we call them “static”. - Data type definitions where the Subject ID is not assigned statically but rather chosen by the integrator or the application designer when configuring the node (perhaps this can be done automatically at some point in a future UAVCAN v1.x). As the ID is chosen at run-time rather than statically, we call these “dynamic”.
- Data type definitions where the Subject or Service ID is assigned statically (i.e., in the name of the DSDL file, such as
Upon closer review of the new concept of Subject and Service ID one might see that the requirement that the static ID to be changeable at runtime becomes unnecessary if we were to avoid assigning static IDs to data types where it might require changing in the first place. Therefore it seems sensible to remove that requirement, thereby declaring that if an ID is assigned statically, it is there to stay as long as the current version of the data type definition is not deprecated. This marginally simplifies implementations and removes a certain degree of uncertainty as integrators will always be certain that all static data types are always assigned a predetermined Subject/Service ID and therefore are always usable without the need for any pre-configuration.
The above has an implication that vendors can no longer define private DTS that contain static Subject/Service IDs, becase if that were the case, definitions from different vendors might conflict with each other and there would be no way of fixing that without modifying the DTS, because, see, the IDs are unchangeable. Public DTS, on the other hand, can rely on static ID as long as they are all centralized in one place, where the lack of collisions can be determined statically. Such centralized maintenance can be achieved by either assigning ID ranges to vendors (which seems wasteful, as the ID spaces are limited), or by keeping all vendor-specific definitions (in their respective namespaces) in one central repository, such as https://github.com/UAVCAN/vendor-specific-dsdl.
If the above reasoning is found sound, we are to end up with the following kinds of DTS:
- Standard DTS, where identifiers can be static (conflicts are not possible because the set is the same for everyone) or dynamic.
- Vendor-specific public DTS, where the identifiers can be static (conflicts are avoidable if we keep all definitions in one central repository or assign per-vendor ranges) or dynamic.
- Vendor-specific private DTS, where the identifiers can be only dynamic, because vendors wouldn’t be able to guarantee collision-free coexistence of their data types.
Extending the ideas towards the ID ranges, we might end up with the following. For Subjects:
From | To | Purpose |
---|---|---|
0 | 0 | Reserved for convenience; e.g., to represent an invalid ID |
1 | 32767 | Dynamic (assigned by the integrator or the application designer) |
61440 | 62803 | Vendor-specific public static, centralized management to avoid conflicts |
62804 | 65535 | Standard static |
For Services is likewise:
From | To | Purpose |
---|---|---|
0 | 0 | Reserved |
1 | 255 | Dynamic (assigned by the integrator or the application designer) |
256 | 383 | Vendor-specific public static, centralized management to avoid conflicts |
384 | 511 | Standard static |
Why standard definitions have been moved towards the end of the range: smaller numbers are easier to deal with, so by doing that we simplify the life of the integrator or application designer. The awkward looking range boundaries make more sense if viewed in base-16, e.g., 6144010 = F00016. The Subject ID 62805 used for uavcan.node.Status
is of a particular interest, as it contains a long sequence of alternating bits: 6280510 = 11110101010101012 – this is important for automatic bit rate detection in CAN-based networks (I won’t elaborate on this further, that would be out of the scope of this post).