RFC: add array of ports


I suggest adding a new term to section 6.8. uavcan.register of the specification. Let’s call it an array of ports or a group of ports.

Problem description

There are few cases where we need to handle a large number of subjects with the same data type and meaning. Typically, this happens on the subscriber side. The problem is pretty clear in the autopilot ESC feedback example. Let’s take a look.
In UAVs we typically want to support 16, but more likely up to 32 esc/servo. If an ESC/servo publishes only a single subject (let’s say feedback), the autopilot will have the following pairs of registers:

# Publishers:
uavcan.pub.setpoint.id=2000   and uavcan.pub.setpoint.type=reg.udral.service.actuator.common.sp.Vector31
uavcan.pub.readiness.id=2001  and uavcan.pub.readiness.type=reg.udral.service.common.Readiness

# Subscribers:
uavcan.sub.feedback.0.id=2100  and uavcan.sub.feedback.0.type=reg.udral.service.actuator.common.Feedback
uavcan.sub.feedback.1.id=2101  and uavcan.sub.feedback.1.type=reg.udral.service.actuator.common.Feedback
uavcan.sub.feedback.31.id=2131 and uavcan.sub.feedback.31.type=reg.udral.service.actuator.common.Feedback

Here the autopilot must have 32 port values in parameters and show 64 registers for subscribers: 32 IDs and 32 types.

According to the current UDRAL, each ESC/servo interface should have 4 subjects: feedback, status, PowerTs and PlanarTs. This means 4 * 32 = 128 ID and 4 * 32 = 128 type registers on the autopilot side.

Zubax Telega publishes 7 ESC related topics. If we want to fully support it, an autopilot should have 7 * 32 * 2 = 448 registers total.

A user may want to add more topics.

This is a pretty easy example and it will rapidly grow into a complex system that is hard to manually maintain even with Yukon.

It would be nice to be able to group the same things together somehow without significantly affecting the flexibility of the system.


I suggest introducing a new term called an array of ports to handle the situation in the example above in a single registers pair. The type register indicates the data type as usual. The ID register indicates the first port identifier in the group. Other port identifiers are automatically incremented sequentially. So, if the identifier register has 2000 and the number of ports is 32, their ID will be 2000,…,2031. Internally the application should subscribe as many times as we have ports, so port.List will have all these 2000,…,2031 ports and we can introspect the Cyphal network as usual.
I see 3 ways how to put the number of ports into this register pair:

  1. A type register value may end with [N] to indicate that we handle. For example: reg.udral.service.actuator.common.Feedback[32]. This solution will probably break something, so we probably should skip it.
  2. A PORT_NAME may end with [N], for example: uavcan.sub.feedback[32].id uavcan.sub.feedback[32].type.
  3. We can come up with a new standard register name. It might be: uavcan.sub_array.feedback[32].id or something like that.


  • This feature most likely should be considered only for a group of subscribers, but not for publishers. Though it is clear to think about a group of setpoints as it is described in UDRAL, I’m not sure if this logic applies to redundant sensors. A sensor doesn’t need to worry about its number in the system - that’s actually why we don’t need a sensor_idx in its message.
  • Currently [ and ] symbols are not allowed in the register name, so we should add them
  • port.List should keep port identifiers separately as usual. If we have group of 32 ports, we should put all of their identifiers into port.List
  • Diagnostic utilities such as Yukon should understand that a single pair of type and ID registers are represent an array. Yukon may also benefit by grouping similar ports on the Monitor window


I see a few drawbacks here:

  1. It occupies extra port identifiers if we only need the last one. If we only have feedback from the eight ESC, we still need to occupy at least 8 port identifiers. Since we have 8k port identifiers, I think this is not really significant.
  2. It may be confusing. If we have feedback only from the eight ESC with port id 2007, we should set 2000 to the register value.
  3. In a really complex network this feature may lead to a fragmentation. We still have 8k ports identifiers.

This feature significantly reduces the number of registers in some applications, making integration and manual configuration much easier. At the same time, it has some effect on the configuration flexibility. Should we consider it?


Let’s say, we have a UDRAL application with 8 ESC. Right now we have the following registers:

If we use array of ports, it might be reduced as follows:


I think this is a worthy proposal and it does indeed address a salient problem. Initially, I wanted to postpone its discussion until the named topic support is implemented; however, @maksim.drachov is unable to continue his work on the named topics support due to other commitments at Zubax, so delaying this further is probably unwise.

A related problem was brought up just recently at Subject-ID Assignment.

I think this option is the most aligned with the existing design. We can modify the uavcan.register.Access specification accordingly to permit arrays and the bracket syntax. The same specification should also provide a detailed explanation of the feature (close to what is written in the OP post).

I think there is merit in extending this proposal not only to subscribers but also to publishers, as nodes that publish multiple related topics are not entirely uncommon (continuing the topic of ESCs, it might be a 4-in-1 motor controller). Another matter is the inner consistency of the specification: publishers and subscribers are two sides of the same thing, and any significant divergence between the two is undesirable.

As there are no other comments so far, I assume there are no strong objections to the proposal, hence I recommend @Dima to submit a pull request to the standard DSDL definitions so that we can discuss the specifics further.