A UAVCAN port (subject or service) is conceptually similar to a topic in DDS/ROS. Ports identify the meaning (semantics) of data within a particular system while its type identifies its structure (syntax). Semantics and syntax are orthogonal concepts and they are modeled as such in UAVCAN.
In some exceptional cases it makes sense to bind a particular type to a specific purpose. A related concept from OOP is a singleton. UAVCAN models this with the help of fixed ports. A data type designer may assign a fixed port-ID to a data type at the data type definition time if necessary. This feature is dangerous if misused because it opens a direct path to overly rigid unmaintainable systems. As such, it is used only for special use cases like standard low-level interfaces common for many applications regardless of the domain: heartbeat, logging, file transfer, etc. Another decent analogy is the set of well-known TCP/UDP ports.
A domain-specific data type such as an actuator control type or a camera frame normally should not have a fixed port-ID. It is assumed that the port-IDs are to be assigned by the system integrator once when the system is constructed or when a new participant is added. While simple, this approach creates usability issues when it is desirable to have a plug-and-play capability such that a new node could be added to an existing bus and auto-configure itself automatically.
Observe that UAVCAN already defines the plug-and-play procedure but it is related to the node-ID allocation and it has nothing to do with the port-ID assignment. Hence, we need to find a way how to assign non-fixed port-ID automatically for newly inserted nodes.
It is expected that high-DAL systems will be unlikely to rely on this capability because in such scenarios static configurations are generally preferred. Therefore, it is acceptable to resort to a solution that requires a certain degree of centralization, such that, for example, some actions are to be performed by a master component of some kind such as a flight controller.
One obvious approach to the problem of automatic port-ID assignment is to leverage the already existing register API which already defines the concept of standard register name patterns:
The idea is to add a new standard pattern of the form (wildcard)
uavcan.sub.* where the asterisk is some human-friendly semantic name of a subject, like
uavcan.pub.camera_left, etc. Then provide some human-defined configuration file to the aforementioned central component (e.g., flight controller) and have it monitor the network for new nodes. Once a new node is detected, it would read its registers and see if there are any whose name matches the wildcard. If matching registers are detected, they would be written by the central component according to the instructions provided in the configuration file and the node would be commanded to restart afterward to adopt the new configuration. Similar behavior is needed for service servers/clients as well, where the wildcard could be defined as
In this way, we get auto-configuration while not relying on the problematic fixed port identifiers unnecessarily.
Edit – another example:
|123||my_namespace.camera.Image.1.0||Left camera image|
|124||my_namespace.camera.Image.1.0||Right camera image|
|200||my_namespace.battery.Status.1.0||Main battery status|
|201||my_namespace.battery.Status.1.0||Payload battery status|
|300||my_namespace.geometry.geo.Pose.1.0||Estimated position and orientation of the vehicle|
|301||my_namespace.geometry.geo.Pose.1.0||Target position and orientation of the vehicle|
Edit – please read The UAVCAN Guide to better understand the motivation.