Documentation for namespace uavcan

uavcan

uavcan.internet

uavcan.internet.udp

uavcan.internet.udp.HandleIncomingPacket (v0.2) [service] [fixed port-ID 500]

This message carries UDP packets sent from a remote host on the Internet or a LAN to a node on the local UAVCAN bus.
Please refer to the definition of the message type OutgoingPacket for a general overview of the packet forwarding
logic.

This data type has been made a service type rather than a message type in order to make its transfers addressable,
allowing nodes to employ hardware acceptance filters for filtering out forwarded datagrams that are not addressed
to them. Additionally, requiring the destination nodes to always respond upon reception of the forwarded datagram
opens interesting opportunities for future extensions of the forwarding protocol. If the service invocation times
out, the modem node is permitted to remove the corresponding entry from the NAT table immediately, not waiting
for its TTL to expire.

It should be noted that this data type definition intentionally leaves out the source address. This is done in
order to simplify the implementation, reduce the bus traffic overhead, and because the nature of the
communication patterns proposed by this set of messages does not provide a valid way to implement server hosts
on the local UAVCAN bus. It is assumed that local nodes can be only clients, and therefore, they will be able to
determine the address of the sender simply by mapping the field session_id to their internally maintained states.
Furthermore, it is uncertain what is the optimal way of representing the source address for
client nodes: it is assumed that the local nodes will mostly use DNS names rather than IP addresses, so if there
was a source address field, modem nodes would have to perform reverse mapping from the IP address they received
the datagram from to the corresponding DNS name that was used by the local node with the outgoing message. This
approach creates a number of troubling corner cases and adds a fair amount of hidden complexities to the
implementation of modem nodes.

It is recommended to perform service invocations at the same transfer priority level as was used for broadcasting
the latest matching message of type OutgoingPacket. However, meeting this recommendation would require the modem
node to implement additional logic, which may be undesirable. Therefore, implementers are free to deviate from
this recommendation and resort to a fixed priority level instead. In the case of a fixed priority level, it is
advised to use the lowest transfer priority level.

uavcan.internet.udp.HandleIncomingPacket.Request (v0.2) request [extent 4832 bytes]

saturated uint16 session_id [extent 2.0 bytes]

This field shall contain the same value that was used by the local node when sending the corresponding outgoing
packet using the message type OutgoingPacket. This value will be used by the local node to match the response
with its local context.

saturated uint8[<=508] payload

saturated uint8

Effective payload. This data will be forwarded from the remote host verbatim.
UDP packets that contain more than 508 bytes of payload may be dropped by some types of
communication equipment. Refer to RFC 791 and 2460 for an in-depth review.
Datagrams that exceed the capacity of this field should be discarded by the modem node.

    
    
    




uavcan.internet.udp.HandleIncomingPacket.Response (v0.2) response [extent 536 bytes]

(data type is empty)


    
    
    

uavcan.internet.udp.HandleIncomingPacket (v0.1) [service] [fixed port-ID 500]

This message carries UDP packets sent from a remote host on the Internet or a LAN to a node on the local UAVCAN bus.
Please refer to the definition of the message type OutgoingPacket for a general overview of the packet forwarding
logic.

This data type has been made a service type rather than a message type in order to make its transfers addressable,
allowing nodes to employ hardware acceptance filters for filtering out forwarded datagrams that are not addressed
to them. Additionally, requiring the destination nodes to always respond upon reception of the forwarded datagram
opens interesting opportunities for future extensions of the forwarding protocol. If the service invocation times
out, the modem node is permitted to remove the corresponding entry from the NAT table immediately, not waiting
for its TTL to expire.

It should be noted that this data type definition intentionally leaves out the source address. This is done in
order to simplify the implementation, reduce the bus traffic overhead, and because the nature of the
communication patterns proposed by this set of messages does not provide a valid way to implement server hosts
on the local UAVCAN bus. It is assumed that local nodes can be only clients, and therefore, they will be able to
determine the address of the sender simply by mapping the field session_id to their internally maintained states.
Furthermore, it is uncertain what is the optimal way of representing the source address for
client nodes: it is assumed that the local nodes will mostly use DNS names rather than IP addresses, so if there
was a source address field, modem nodes would have to perform reverse mapping from the IP address they received
the datagram from to the corresponding DNS name that was used by the local node with the outgoing message. This
approach creates a number of troubling corner cases and adds a fair amount of hidden complexities to the
implementation of modem nodes.

It is recommended to perform service invocations at the same transfer priority level as was used for broadcasting
the latest matching message of type OutgoingPacket. However, meeting this recommendation would require the modem
node to implement additional logic, which may be undesirable. Therefore, implementers are free to deviate from
this recommendation and resort to a fixed priority level instead. In the case of a fixed priority level, it is
advised to use the lowest transfer priority level.

uavcan.internet.udp.HandleIncomingPacket.Request (v0.1) request [extent 4832 bytes]

saturated uint16 session_id [extent 2.0 bytes]

This field shall contain the same value that was used by the local node when sending the corresponding outgoing
packet using the message type OutgoingPacket. This value will be used by the local node to match the response
with its local context.

saturated uint8[<=309] payload

saturated uint8

Effective payload. This data will be forwarded from the remote host verbatim.
UDP packets that contain more than 508 bytes of payload may be dropped by some types of
communication equipment. Refer to RFC 791 and 2460 for an in-depth review.
UAVCAN further limits the maximum packet size to reduce the memory and traffic burden on the nodes.
Datagrams that exceed the capacity of this field should be discarded by the modem node.

    
    
    




uavcan.internet.udp.HandleIncomingPacket.Response (v0.1) response [extent 536 bytes]

(data type is empty)


    
    
    

uavcan.internet.udp.OutgoingPacket (v0.2) [extent 4832 bytes] [fixed port-ID 8174]

This message carries UDP packets from a node on the local bus to a remote host on the Internet or a LAN.

Any node can broadcast a message of this type.

All nodes that are capable of communication with the Internet or a LAN should subscribe to messages
of this type and forward the payload to the indicated host and port using exactly one UDP datagram
per message (i.e. additional fragmentation is to be avoided). Such nodes will be referred to as
"modem nodes".

It is expected that some systems will have more than one modem node available.
Each modem node is supposed to forward every message it sees, which will naturally create
some degree of modular redundancy and fault tolerance. The remote host should therefore be able to
properly handle possibly duplicated messages from different source addresses, in addition to
possible duplications introduced by the UDP/IP protocol itself. There are at least two obvious
strategies that can be employed by the remote host:

  - Accept only the first message, ignore duplicates. This approach requires that the UDP stream
    should contain some metadata necessary for the remote host to determine the source and ordering
    of each received datum. This approach works best for periodic data, such as telemetry, where
    the sender does not expect any responses.

  - Process all messages, including duplicates. This approach assumes that the remote host acts
    as a server, processing all received requests and providing responses to each. This arrangement
    implies that the client may receive duplicated responses. It is therefore the client's
    responsibility to resolve the possible ambiguity. An obvious solution is to accept the first
    arrived response and ignore the later ones.

Applications are free to choose whatever redundancy management strategy works best for them.

If the source node expects that the remote host will send some data back, it shall explicitly notify
the modem nodes about this, so that they could prepare to perform reverse forwarding when the
expected data arrives from the remote host. The technique of reverse forwarding is known in
networking as IP Masquerading, or (in general) Network Address Translation (NAT). The notification
is performed by means of setting one of the corresponding flags defined below.

In order to be able to match datagrams received from remote hosts and the local nodes they should
be forwarded to, modem nodes are required to keep certain metadata about outgoing datagrams. Such
metadata is stored in a data structure referred to as "NAT table", where every entry would normally
contain at least the following fields:
  - The local UDP port number that was used to send the outgoing datagram from.
    Per RFC 4787, the port number is chosen by the modem node automatically.
  - The node-ID of the local node that has sent the outgoing datagram.
  - Value of the field session_id defined below.
  - Possibly some other data, depending on the implementation.

The modem nodes are required to keep each NAT table entry for at least NAT_ENTRY_MIN_TTL seconds
since the last reverse forwarding action was performed. Should the memory resources of the modem node
be exhausted, it is allowed to remove old NAT entries earlier, following the policy of least recent use.

Having received a UDP packet from a remote host, the modem node would check the NAT table in order
to determine where on the UAVCAN bus the received data should be forwarded to. If the NAT table
contains no matches, the received data should be silently dropped. If a match is found, the
modem node will forward the data to the recipient node using the service HandleIncomingPacket.
If the service invocation times out, the modem node is permitted to remove the corresponding entry from
the NAT table immediately (but it is not required). This will ensure that the modem nodes will not be
tasked with translations for client nodes that are no longer online or are unreachable.
Additionally, client nodes will be able to hint the modem nodes to remove translation entries they no
longer need by simply refusing to respond to the corresponding service invocation. Please refer to
the definition of that service data type for a more in-depth review of the reverse forwarding process.

Modem nodes can also perform traffic shaping, if needed, by means of delaying or dropping UDP
datagrams that exceed the quota.

To summarize, a typical data exchange occurrence should amount to the following actions:

  - A local UAVCAN node broadcasts a message of type OutgoingPacket with the payload it needs
    to forward. If the node expects the remote host to send any data back, it sets the masquerading flag.

  - Every modem node on the bus receives the message and performs the following actions:

      - The domain name is resolved, unless the destination address provided in the message
        is already an IP address, in which case this step should be skipped.

      - The domain name to IP address mapping is added to the local DNS cache, although this
        part is entirely implementation defined and is not required.

      - The masquerading flag is checked. If it is set, a new entry is added to the NAT table.
        If such entry already existed, its expiration timeout is reset. If no such entry existed
        and a new one cannot be added because of memory limitations, the least recently used
        (i.e. oldest) entry of the NAT table is replaced with the new one.

      - The payload is forwarded to the determined IP address.

  - At this point, direct forwarding is complete. Should any of the modem nodes receive an incoming
    packet, they would attempt to perform a reverse forwarding according to the above provided algorithm.

It is recommended to use the lowest transport priority level when broadcasting messages of this type,
in order to avoid interference with a real-time traffic on the bus. Usage of higher priority levels is
unlikely to be practical because the latency and throughput limitations introduced by the on-board radio
communication equipment are likely to vastly exceed those of the local CAN bus.

saturated uint16 session_id [extent 2.0 bytes]

This field is set to an arbitrary value by the transmitting node in order to be able to match the response
with the locally kept context. The function of this field is virtually identical to that of UDP/IP port
numbers. This value can be set to zero safely if the sending node does not have multiple contexts to
distinguish between.

saturated uint16 destination_port [extent 2.0 bytes]

UDP destination port number.

saturated uint8[<=45] destination_address

saturated uint8

Domain name or IP address where the payload should be forwarded to.
Note that broadcast addresses are allowed here, for example, 255.255.255.255.
Broadcasting with masquerading enabled works the same way as unicasting with masquerading enabled: the modem
node should take care to channel all traffic arriving at the opened port from any source to the node that
requested masquerading.
The full domain name length may not exceed 253 octets, according to the DNS specification.
UAVCAN imposes a stricter length limit in order to reduce the memory and traffic burden on the bus: 45 characters.
45 characters is the amount of space that is required to represent the longest possible form of an IPv6 address
(an IPv4-mapped IPv6 address). Examples:
  "forum.uavcan.org"                              - domain name
  "192.168.1.1"                                   - IPv4 address
  "2001:0db8:85a3:0000:0000:8a2e:0370:7334"       - IPv6 address, full form
  "2001:db8:85a3::8a2e:370:7334"                  - IPv6 address, same as above, short form (preferred)
  "ABCD:ABCD:ABCD:ABCD:ABCD:ABCD:192.168.158.190" - IPv4-mapped IPv6, full form (length limit, 45 characters)

saturated bool use_masquerading [extent 1 bits]

Expect data back (i.e., instruct the modem to use the NAT table).

saturated bool use_dtls [extent 1 bits]

Use Datagram Transport Layer Security. Drop the packet if DTLS is not supported.
Option flags.

void6 [extent 6 bits]


    
    
    




saturated uint8[<=508] payload

saturated uint8

Effective payload. This data will be forwarded to the remote host verbatim.
UDP packets that contain more than 508 bytes of payload may be dropped by some types of
communication equipment. Refer to RFC 791 and 2460 for an in-depth review.

saturated uint32 NAT_ENTRY_MIN_TTL = 86400

[second]
Modem nodes are required to keep the NAT table entries alive for at least this amount of time, unless the
table is overflowed, in which case they are allowed to remove least recently used entries in favor of
newer ones. Modem nodes are required to be able to accommodate at least 100 entries in the NAT table.

uavcan.internet.udp.OutgoingPacket (v0.1) [extent 4832 bytes] [fixed port-ID 8174]

This message carries UDP packets from a node on the local bus to a remote host on the Internet or a LAN.

Any node can broadcast a message of this type.

All nodes that are capable of communication with the Internet or a LAN should subscribe to messages
of this type and forward the payload to the indicated host and port using exactly one UDP datagram
per message (i.e. additional fragmentation is to be avoided). Such nodes will be referred to as
"modem nodes".

It is expected that some systems will have more than one modem node available.
Each modem node is supposed to forward every message it sees, which will naturally create
some degree of modular redundancy and fault tolerance. The remote host should therefore be able to
properly handle possibly duplicated messages from different source addresses, in addition to
possible duplications introduced by the UDP/IP protocol itself. There are at least two obvious
strategies that can be employed by the remote host:

  - Accept only the first message, ignore duplicates. This approach requires that the UDP stream
    should contain some metadata necessary for the remote host to determine the source and ordering
    of each received datum. This approach works best for periodic data, such as telemetry, where
    the sender does not expect any responses.

  - Process all messages, including duplicates. This approach assumes that the remote host acts
    as a server, processing all received requests and providing responses to each. This arrangement
    implies that the client may receive duplicated responses. It is therefore the client's
    responsibility to resolve the possible ambiguity. An obvious solution is to accept the first
    arrived response and ignore the later ones.

Applications are free to choose whatever redundancy management strategy works best for them.

If the source node expects that the remote host will send some data back, it shall explicitly notify
the modem nodes about this, so that they could prepare to perform reverse forwarding when the
expected data arrives from the remote host. The technique of reverse forwarding is known in
networking as IP Masquerading, or (in general) Network Address Translation (NAT). The notification
is performed by means of setting one of the corresponding flags defined below.

In order to be able to match datagrams received from remote hosts and the local nodes they should
be forwarded to, modem nodes are required to keep certain metadata about outgoing datagrams. Such
metadata is stored in a data structure referred to as "NAT table", where every entry would normally
contain at least the following fields:
  - The local UDP port number that was used to send the outgoing datagram from.
    Per RFC 4787, the port number is chosen by the modem node automatically.
  - The node-ID of the local node that has sent the outgoing datagram.
  - Value of the field session_id defined below.
  - Possibly some other data, depending on the implementation.

The modem nodes are required to keep each NAT table entry for at least NAT_ENTRY_MIN_TTL seconds
since the last reverse forwarding action was performed. Should the memory resources of the modem node
be exhausted, it is allowed to remove old NAT entries earlier, following the policy of least recent use.

Having received a UDP packet from a remote host, the modem node would check the NAT table in order
to determine where on the UAVCAN bus the received data should be forwarded to. If the NAT table
contains no matches, the received data should be silently dropped. If a match is found, the
modem node will forward the data to the recipient node using the service HandleIncomingPacket.
If the service invocation times out, the modem node is permitted to remove the corresponding entry from
the NAT table immediately (but it is not required). This will ensure that the modem nodes will not be
tasked with translations for client nodes that are no longer online or are unreachable.
Additionally, client nodes will be able to hint the modem nodes to remove translation entries they no
longer need by simply refusing to respond to the corresponding service invocation. Please refer to
the definition of that service data type for a more in-depth review of the reverse forwarding process.

Modem nodes can also perform traffic shaping, if needed, by means of delaying or dropping UDP
datagrams that exceed the quota.

To summarize, a typical data exchange occurrence should amount to the following actions:

  - A local UAVCAN node broadcasts a message of type OutgoingPacket with the payload it needs
    to forward. If the node expects the remote host to send any data back, it sets the masquerading flag.

  - Every modem node on the bus receives the message and performs the following actions:

      - The domain name is resolved, unless the destination address provided in the message
        is already an IP address, in which case this step should be skipped.

      - The domain name to IP address mapping is added to the local DNS cache, although this
        part is entirely implementation defined and is not required.

      - The masquerading flag is checked. If it is set, a new entry is added to the NAT table.
        If such entry already existed, its expiration timeout is reset. If no such entry existed
        and a new one cannot be added because of memory limitations, the least recently used
        (i.e. oldest) entry of the NAT table is replaced with the new one.

      - The payload is forwarded to the determined IP address.

  - At this point, direct forwarding is complete. Should any of the modem nodes receive an incoming
    packet, they would attempt to perform a reverse forwarding according to the above provided algorithm.

It is recommended to use the lowest transport priority level when broadcasting messages of this type,
in order to avoid interference with a real-time traffic on the bus. Usage of higher priority levels is
unlikely to be practical because the latency and throughput limitations introduced by the on-board radio
communication equipment are likely to vastly exceed those of the local CAN bus.

saturated uint16 session_id [extent 2.0 bytes]

This field is set to an arbitrary value by the transmitting node in order to be able to match the response
with the locally kept context. The function of this field is virtually identical to that of UDP/IP port
numbers. This value can be set to zero safely if the sending node does not have multiple contexts to
distinguish between.

saturated uint16 destination_port [extent 2.0 bytes]

UDP destination port number.

saturated uint8[<=45] destination_address

saturated uint8

Domain name or IP address where the payload should be forwarded to.
Note that broadcast addresses are allowed here, for example, 255.255.255.255.
Broadcasting with masquerading enabled works the same way as unicasting with masquerading enabled: the modem
node should take care to channel all traffic arriving at the opened port from any source to the node that
requested masquerading.
The full domain name length may not exceed 253 octets, according to the DNS specification.
UAVCAN imposes a stricter length limit in order to reduce the memory and traffic burden on the bus: 45 characters.
45 characters is the amount of space that is required to represent the longest possible form of an IPv6 address
(an IPv4-mapped IPv6 address). Examples:
  "forum.uavcan.org"                              - domain name
  "192.168.1.1"                                   - IPv4 address
  "2001:0db8:85a3:0000:0000:8a2e:0370:7334"       - IPv6 address, full form
  "2001:db8:85a3::8a2e:370:7334"                  - IPv6 address, same as above, short form (preferred)
  "ABCD:ABCD:ABCD:ABCD:ABCD:ABCD:192.168.158.190" - IPv4-mapped IPv6, full form (length limit, 45 characters)

saturated bool use_masquerading [extent 1 bits]

Expect data back (i.e., instruct the modem to use the NAT table).

saturated bool use_dtls [extent 1 bits]

Use Datagram Transport Layer Security. Drop the packet if DTLS is not supported.
Option flags.

void6 [extent 6 bits]


    
    
    




saturated uint8[<=260] payload

saturated uint8

Effective payload. This data will be forwarded to the remote host verbatim.
UDP packets that contain more than 508 bytes of payload may be dropped by some types of
communication equipment. Refer to RFC 791 and 2460 for an in-depth review.
UAVCAN further limits the maximum packet size to reduce the memory and traffic burden on the nodes.

saturated uint32 NAT_ENTRY_MIN_TTL = 86400

[second]
Modem nodes are required to keep the NAT table entries alive for at least this amount of time, unless the
table is overflowed, in which case they are allowed to remove least recently used entries in favor of
newer ones. Modem nodes are required to be able to accommodate at least 100 entries in the NAT table.

uavcan.register

uavcan.register.Access (v1.0) [service] [fixed port-ID 384]

This service is used to write and read a register. Write is optional, it is performed if the value provided in
the request is not empty.

The write operation is performed first, unless skipped by sending an empty value in the request.
The server may attempt to convert the type of the value to the proper type if there is a type mismatch
(e.g. uint8 may be converted to uint16); however, servers are not required to perform implicit type conversion,
and the rules of such conversion are not explicitly specified, so this behavior should not be relied upon.

On the next step the register will be read regardless of the outcome of the write operation. As such, if the write
operation could not be performed (e.g. due to a type mismatch or any other issue), the register will retain its old
value. By evaluating the response the caller can determine whether the register was written successfully.

The write-read sequence is not guaranteed to be atomic, meaning that external influences may cause the register to
change its value between the write and the subsequent read operation. The caller is responsible for handling that
case properly.

The timestamp provided in the response corresponds to the time when the register was read. The timestamp may
be empty if the server does not support timestamping or its clock is not yet synchronized with the bus.

If only read is desired, but not write, the caller shall provide a value of type Empty. That will signal the server
that the write operation shall be skipped, and it will proceed to read the register immediately.

If the requested register does not exist, the write operation will have no effect and the returned value will be
empty. Existing registers should not return Empty when read since that would make them indistinguishable from
nonexistent registers.

Registers shall never change their type or flags as long as the server is running. Meaning that:
  - Mutability and persistence flags cannot change their states.
  - Read operations shall always return values of the same type and same dimensionality.
    The dimensionality requirement does not apply to inherently variable-length values such as strings and
    unstructured chunks.

In order to discover the type of a register, the caller needs to invoke this service with the write request set
to Empty. The response will contain the current value of the register with the type information (which doesn't
change).

Register name may contain:
  - All ASCII alphanumeric characters (a-z, A-Z, 0-9)
  - Dot (.)
  - Underscore (_)
  - Minus (-)
All other printable non-whitespace ASCII characters are reserved for standard functions;
they may appear in register names to support such standard functions defined by the register protocol,
but they cannot be freely used by applications outside of such standard functions.

The following optional special function register names are defined:
  - suffix '<' is used to define an immutable persistent value that contains the maximum value
    of the respective register.
  - suffix '>' is like above, used to define the minimum value of the respective register.
  - suffix '=' is like above, used to define the default value of the respective register.
  - prefix '*' is reserved for raw memory access (to be defined later).
Examples:
  - register name "system.parameter"
  - maximum value is contained in the register named "system.parameter<" (optional)
  - minimum value is contained in the register named "system.parameter>" (optional)
  - default value is contained in the register named "system.parameter=" (optional)

The type and dimensionality of the special function registers containing the minimum, maximum, and the default
value of a register shall be the same as those of the register.

If a written value exceeds the minimum/maximum specified by the respective special function registers,
the server may either adjust the value automatically, or to retain the old value, depending on which behavior
suits the objectives of the application better.
The values of registers containing non-scalar numerical entities should be compared elementwise.

The following table specifies the register name patterns that are reserved by the specification for
common functions. These conventions are not mandatory to follow, but implementers are recommended to adhere because
they enable enhanced introspection capabilities and simplify device configuration and diagnostics.

  REGISTER NAME PATTERN                               TYPE            FLAGS                   RECOMMENDED DEFAULT
=====================================================================================================================

  uavcan.node.id                                      natural16       mutable, persistent     65535 (unset/PnP)

Contains the node-ID of the local node. Values above the maximum valid node-ID for the current transport
indicate that the node-ID is not set; if plug-and-play is supported, it will be used by the node to obtain an
automatic node-ID. Invalid values other than 65535 should be avoided for consistency.

---------------------------------------------------------------------------------------------------------------------

  uavcan.node.description                             string          mutable, persistent     (empty)

User/integrator-defined, human-readable description of this specific node.
This is intended for use by a system integrator and should not be set by the manufacturer of a component.
For example: on a quad-rotor drone this might read "motor 2" for one of the ESC nodes.

---------------------------------------------------------------------------------------------------------------------

  uavcan.pub.PORT_NAME.id                             natural16       mutable, persistent     65535 (unset, invalid)
  uavcan.sub.PORT_NAME.id                             ditto           ditto                   ditto
  uavcan.cln.PORT_NAME.id                             ditto           ditto                   ditto
  uavcan.srv.PORT_NAME.id                             ditto           ditto                   ditto

Publication/subscription/client/server port-ID, respectively. These registers are configured by the system integrator
or an autoconfiguration authority when the node is first connected to a network.

The "PORT_NAME" defines the human-friendly name of the port, which is related to the corresponding function
or a network service supported by the node. The name shall match the following POSIX ERE expression:

  [a-zA-Z_][a-zA-Z0-9_]*

The names are defined by the vendor of the node. The user/integrator is expected to understand their meaning and
relation to the functional capabilities of the node by reading the technical documentation provided by the vendor.

A port whose port-ID register is unset (invalid value) remains inactive (unused); the corresponding function may
be disabled. For example, a register named "uavcan.pub.measurement.id" defines the subject-ID of a measurement
published by this node; if the register contains an invalid value (above the maximum valid subject-ID),
said measurement is not published.

The same name is used in other similar registers defined below. Network introspection and autoconfiguration tools
will expect to find a register of this form for every configurable port supported by the node.

---------------------------------------------------------------------------------------------------------------------

  uavcan.pub.PORT_NAME.type                           string          immutable, persistent   N/A
  uavcan.sub.PORT_NAME.type                           ditto           ditto                   ditto
  uavcan.cln.PORT_NAME.type                           ditto           ditto                   ditto
  uavcan.srv.PORT_NAME.type                           ditto           ditto                   ditto

Publication/subscription/client/server full data type name and dot-separated version numbers, respectively.
These registers are set by the vendor once and typically they are to remain unchanged (hence "immutable").
The "PORT_NAME" defines the human-friendly name of the port as specified above.
For example, a register named "uavcan.pub.measurement.type" may contain "uavcan.si.sample.angle.Quaternion.1.0".

---------------------------------------------------------------------------------------------------------------------

uavcan.register.Access.Request (v1.0) request [extent 4120 bytes]

uavcan.register.Name (v1.0) name [extent 2048 bytes]

An UTF8-encoded register name.

saturated uint8[<=255] name

saturated uint8


    
    
    
The name of the accessed register. Shall not be empty.
Use the List service to obtain the list of registers on the node.

uavcan.register.Value (v1.0) value [extent 2072 bytes]

This union contains all possible value types supported by the register protocol.
Numeric types can be either scalars or arrays; the former is a special case of the latter.

uavcan.primitive.Empty (v1.0) empty [extent 0 bytes]

(data type is empty)

Tag 0     Used to represent an undefined value

uavcan.primitive.String (v1.0) string [extent 2064 bytes]

A UTF8-encoded string of text.
Since the string is represented as a dynamic array of bytes, it is not null-terminated. Like Pascal string.

saturated uint8[<=256] value

saturated uint8


    
    
    
Tag 1     UTF-8 encoded text

uavcan.primitive.Unstructured (v1.0) unstructured [extent 2064 bytes]

An unstructured collection of bytes, e.g., raw binary image.

saturated uint8[<=256] value

saturated uint8


    
    
    
Tag 2     Raw unstructured binary image

uavcan.primitive.array.Bit (v1.0) bit [extent 2064 bytes]

2048 bits + 11 bit length + 4 bit padding = 2064 bits = 258 bytes

saturated bool[<=2048] value

saturated bool


    
    
    
Tag 3     Bit array

uavcan.primitive.array.Integer64 (v1.0) integer64 [extent 2056 bytes]

saturated int64[<=32] value

saturated int64


    
    
    
Tag 4

uavcan.primitive.array.Integer32 (v1.0) integer32 [extent 2056 bytes]

saturated int32[<=64] value

saturated int32


    
    
    
Tag 5

uavcan.primitive.array.Integer16 (v1.0) integer16 [extent 2056 bytes]

saturated int16[<=128] value

saturated int16


    
    
    
Tag 6

uavcan.primitive.array.Integer8 (v1.0) integer8 [extent 2064 bytes]

saturated int8[<=256] value

saturated int8


    
    
    
Tag 7

uavcan.primitive.array.Natural64 (v1.0) natural64 [extent 2056 bytes]

saturated uint64[<=32] value

saturated uint64


    
    
    
Tag 8

uavcan.primitive.array.Natural32 (v1.0) natural32 [extent 2056 bytes]

saturated uint32[<=64] value

saturated uint32


    
    
    
Tag 9

uavcan.primitive.array.Natural16 (v1.0) natural16 [extent 2056 bytes]

saturated uint16[<=128] value

saturated uint16


    
    
    
Tag 10

uavcan.primitive.array.Natural8 (v1.0) natural8 [extent 2064 bytes]

saturated uint8[<=256] value

saturated uint8


    
    
    
Tag 11

uavcan.primitive.array.Real64 (v1.0) real64 [extent 2056 bytes]

Exactly representable integers: [-2**53, +2**53]

saturated float64[<=32] value

saturated float64


    
    
    
Tag 12    Exactly representable integers: [-2**53,    +2**53]

uavcan.primitive.array.Real32 (v1.0) real32 [extent 2056 bytes]

Exactly representable integers: [-16777216, +16777216]

saturated float32[<=64] value

saturated float32


    
    
    
Tag 13    Exactly representable integers: [-16777216, +16777216]

uavcan.primitive.array.Real16 (v1.0) real16 [extent 2056 bytes]

Exactly representable integers: [-2048, +2048]

saturated float16[<=128] value

saturated float16


    
    
    
Tag 14    Exactly representable integers: [-2048,     +2048]
Value to be written. Empty if no write is required.

    
    
    




uavcan.register.Access.Response (v1.0) response [extent 2136 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.
The moment of time when the register was read (not written).
Zero if the server does not support timestamping.

saturated bool mutable [extent 1 bits]

Mutable means that the register can be written using this service.
Immutable registers cannot be written, but that doesn't imply that their values are constant (unchanging).

saturated bool persistent [extent 1 bits]

Persistence means that the register retains its value permanently across power cycles or any other changes
in the state of the server, until it is explicitly overwritten (either via UAVCAN, any other interface,
or by the device itself).

The server is recommended to manage persistence automatically by committing changed register values to a
non-volatile storage automatically as necessary. If automatic persistence management is not implemented, it
can be controlled manually via the standard service uavcan.node.ExecuteCommand. The same service can be used
to return the configuration to a factory-default state. Please refer to its definition for more information.

Consider the following examples:
  - Configuration parameters are usually both mutable and persistent.
  - Diagnostic values are usually immutable and non-persisient.
  - Registers that trigger an activity when written are typically mutable but non-persisient.
  - Registers that contain factory-programmed values such as calibration coefficients that can't
    be changed are typically immutable but persistent.

void6 [extent 6 bits]


    
    
    




uavcan.register.Value (v1.0) value [extent 2072 bytes]

This union contains all possible value types supported by the register protocol.
Numeric types can be either scalars or arrays; the former is a special case of the latter.

uavcan.primitive.Empty (v1.0) empty [extent 0 bytes]

(data type is empty)

Tag 0     Used to represent an undefined value

uavcan.primitive.String (v1.0) string [extent 2064 bytes]

A UTF8-encoded string of text.
Since the string is represented as a dynamic array of bytes, it is not null-terminated. Like Pascal string.

saturated uint8[<=256] value

saturated uint8


    
    
    
Tag 1     UTF-8 encoded text

uavcan.primitive.Unstructured (v1.0) unstructured [extent 2064 bytes]

An unstructured collection of bytes, e.g., raw binary image.

saturated uint8[<=256] value

saturated uint8


    
    
    
Tag 2     Raw unstructured binary image

uavcan.primitive.array.Bit (v1.0) bit [extent 2064 bytes]

2048 bits + 11 bit length + 4 bit padding = 2064 bits = 258 bytes

saturated bool[<=2048] value

saturated bool


    
    
    
Tag 3     Bit array

uavcan.primitive.array.Integer64 (v1.0) integer64 [extent 2056 bytes]

saturated int64[<=32] value

saturated int64


    
    
    
Tag 4

uavcan.primitive.array.Integer32 (v1.0) integer32 [extent 2056 bytes]

saturated int32[<=64] value

saturated int32


    
    
    
Tag 5

uavcan.primitive.array.Integer16 (v1.0) integer16 [extent 2056 bytes]

saturated int16[<=128] value

saturated int16


    
    
    
Tag 6

uavcan.primitive.array.Integer8 (v1.0) integer8 [extent 2064 bytes]

saturated int8[<=256] value

saturated int8


    
    
    
Tag 7

uavcan.primitive.array.Natural64 (v1.0) natural64 [extent 2056 bytes]

saturated uint64[<=32] value

saturated uint64


    
    
    
Tag 8

uavcan.primitive.array.Natural32 (v1.0) natural32 [extent 2056 bytes]

saturated uint32[<=64] value

saturated uint32


    
    
    
Tag 9

uavcan.primitive.array.Natural16 (v1.0) natural16 [extent 2056 bytes]

saturated uint16[<=128] value

saturated uint16


    
    
    
Tag 10

uavcan.primitive.array.Natural8 (v1.0) natural8 [extent 2064 bytes]

saturated uint8[<=256] value

saturated uint8


    
    
    
Tag 11

uavcan.primitive.array.Real64 (v1.0) real64 [extent 2056 bytes]

Exactly representable integers: [-2**53, +2**53]

saturated float64[<=32] value

saturated float64


    
    
    
Tag 12    Exactly representable integers: [-2**53,    +2**53]

uavcan.primitive.array.Real32 (v1.0) real32 [extent 2056 bytes]

Exactly representable integers: [-16777216, +16777216]

saturated float32[<=64] value

saturated float32


    
    
    
Tag 13    Exactly representable integers: [-16777216, +16777216]

uavcan.primitive.array.Real16 (v1.0) real16 [extent 2056 bytes]

Exactly representable integers: [-2048, +2048]

saturated float16[<=128] value

saturated float16


    
    
    
Tag 14    Exactly representable integers: [-2048,     +2048]
The value of the register when it was read (beware of race conditions).
Registers never change their type and dimensionality while the node is running.
Empty value means that the register does not exist (in this case the flags should be cleared/ignored).
By comparing the returned value against the write request the caller can determine whether the register
was written successfully, unless write was not requested.
An empty value shall never be returned for an existing register.

    
    
    

uavcan.register.List (v1.0) [service] [fixed port-ID 385]

This service allows the caller to discover the names of all registers available on the server
by iterating the index field from zero until an empty name is returned.

The ordering of the registers shall remain constant while the server is running.
The ordering is not guaranteed to remain unchanged when the server node is restarted.

uavcan.register.List.Request (v1.0) request [extent 16 bytes]

saturated uint16 index [extent 2.0 bytes]


    
    
    

    
    
    




uavcan.register.List.Response (v1.0) response [extent 2048 bytes]

uavcan.register.Name (v1.0) name [extent 2048 bytes]

An UTF8-encoded register name.

saturated uint8[<=255] name

saturated uint8


    
    
    
Empty name in response means that the index is out of bounds, i.e., discovery is finished.

    
    
    

uavcan.register.Name (v1.0) [extent 2048 bytes]

An UTF8-encoded register name.

saturated uint8[<=255] name

saturated uint8


    
    
    

uavcan.register.Value (v1.0) [extent 2072 bytes]

This union contains all possible value types supported by the register protocol.
Numeric types can be either scalars or arrays; the former is a special case of the latter.

uavcan.primitive.Empty (v1.0) empty [extent 0 bytes]

(data type is empty)

Tag 0     Used to represent an undefined value

uavcan.primitive.String (v1.0) string [extent 2064 bytes]

A UTF8-encoded string of text.
Since the string is represented as a dynamic array of bytes, it is not null-terminated. Like Pascal string.

saturated uint8[<=256] value

saturated uint8


    
    
    
Tag 1     UTF-8 encoded text

uavcan.primitive.Unstructured (v1.0) unstructured [extent 2064 bytes]

An unstructured collection of bytes, e.g., raw binary image.

saturated uint8[<=256] value

saturated uint8


    
    
    
Tag 2     Raw unstructured binary image

uavcan.primitive.array.Bit (v1.0) bit [extent 2064 bytes]

2048 bits + 11 bit length + 4 bit padding = 2064 bits = 258 bytes

saturated bool[<=2048] value

saturated bool


    
    
    
Tag 3     Bit array

uavcan.primitive.array.Integer64 (v1.0) integer64 [extent 2056 bytes]

saturated int64[<=32] value

saturated int64


    
    
    
Tag 4

uavcan.primitive.array.Integer32 (v1.0) integer32 [extent 2056 bytes]

saturated int32[<=64] value

saturated int32


    
    
    
Tag 5

uavcan.primitive.array.Integer16 (v1.0) integer16 [extent 2056 bytes]

saturated int16[<=128] value

saturated int16


    
    
    
Tag 6

uavcan.primitive.array.Integer8 (v1.0) integer8 [extent 2064 bytes]

saturated int8[<=256] value

saturated int8


    
    
    
Tag 7

uavcan.primitive.array.Natural64 (v1.0) natural64 [extent 2056 bytes]

saturated uint64[<=32] value

saturated uint64


    
    
    
Tag 8

uavcan.primitive.array.Natural32 (v1.0) natural32 [extent 2056 bytes]

saturated uint32[<=64] value

saturated uint32


    
    
    
Tag 9

uavcan.primitive.array.Natural16 (v1.0) natural16 [extent 2056 bytes]

saturated uint16[<=128] value

saturated uint16


    
    
    
Tag 10

uavcan.primitive.array.Natural8 (v1.0) natural8 [extent 2064 bytes]

saturated uint8[<=256] value

saturated uint8


    
    
    
Tag 11

uavcan.primitive.array.Real64 (v1.0) real64 [extent 2056 bytes]

Exactly representable integers: [-2**53, +2**53]

saturated float64[<=32] value

saturated float64


    
    
    
Tag 12    Exactly representable integers: [-2**53,    +2**53]

uavcan.primitive.array.Real32 (v1.0) real32 [extent 2056 bytes]

Exactly representable integers: [-16777216, +16777216]

saturated float32[<=64] value

saturated float32


    
    
    
Tag 13    Exactly representable integers: [-16777216, +16777216]

uavcan.primitive.array.Real16 (v1.0) real16 [extent 2056 bytes]

Exactly representable integers: [-2048, +2048]

saturated float16[<=128] value

saturated float16


    
    
    
Tag 14    Exactly representable integers: [-2048,     +2048]

uavcan.metatransport

uavcan.metatransport.udp

uavcan.metatransport.udp.Endpoint (v0.1) [extent 256 bytes]

A UDP/IP endpoint address specification.

saturated uint8[16] ip_address

saturated uint8

The IP address of the host in the network byte order (big endian).
IPv6 addresses are represented as-is.
IPv4 addresses are represented using IPv4-mapped IPv6 addresses.

saturated uint8[6] mac_address

saturated uint8

MAC address of the host in the network byte order (big endian).

saturated uint16 port [extent 2.0 bytes]

The UDP port number.

void64 [extent 8.0 bytes]


    
    
    

uavcan.metatransport.udp.Frame (v0.1) [extent 81952 bytes]

A generic UDP/IP frame.
Jumboframes are supported in the interest of greater application compatibility.

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

void8 [extent 1.0 bytes]


    
    
    




uavcan.metatransport.udp.Endpoint (v0.1) source [extent 256 bytes]

A UDP/IP endpoint address specification.

saturated uint8[16] ip_address

saturated uint8

The IP address of the host in the network byte order (big endian).
IPv6 addresses are represented as-is.
IPv4 addresses are represented using IPv4-mapped IPv6 addresses.

saturated uint8[6] mac_address

saturated uint8

MAC address of the host in the network byte order (big endian).

saturated uint16 port [extent 2.0 bytes]

The UDP port number.

void64 [extent 8.0 bytes]


    
    
    

    
    
    




uavcan.metatransport.udp.Endpoint (v0.1) destination [extent 256 bytes]

A UDP/IP endpoint address specification.

saturated uint8[16] ip_address

saturated uint8

The IP address of the host in the network byte order (big endian).
IPv6 addresses are represented as-is.
IPv4 addresses are represented using IPv4-mapped IPv6 addresses.

saturated uint8[6] mac_address

saturated uint8

MAC address of the host in the network byte order (big endian).

saturated uint16 port [extent 2.0 bytes]

The UDP port number.

void64 [extent 8.0 bytes]


    
    
    

    
    
    




saturated uint8[<=9188] data

saturated uint8


    
    
    

saturated uint14 MTU = 9188

Max jumbo frame 9 KiB, IP header min 20 B, UDP header 8 B.

uavcan.metatransport.serial

uavcan.metatransport.serial.Fragment (v0.2) [extent 16400 bytes]

A chunk of raw bytes exchanged over a serial transport. Serial links do not support framing natively.
The chunk may be of arbitrary size.

If this data type is used to encapsulate UAVCAN/serial, then it is recommended to ensure that each message
contains at most one UAVCAN/serial transport frame (frames are separated by zero-valued delimiter bytes).

saturated uint8[<=2048] data

saturated uint8


    
    
    

saturated uint12 CAPACITY_BYTES = 2048


    
    
    

uavcan.metatransport.serial.Fragment (v0.1) [extent 2120 bytes]

A chunk of raw bytes exchanged over a serial transport. Serial links do not support framing natively.
The chunk may be of arbitrary size.

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    




saturated uint8[<=256] data

saturated uint8


    
    
    

saturated uint9 CAPACITY_BYTES = 256


    
    
    

uavcan.metatransport.ethernet

uavcan.metatransport.ethernet.EtherType (v0.1) [extent 16 bytes]

Standard EtherType constants as defined by IEEE Registration Authority and IANA.
This list is only a small subset of constants that are considered to be relevant for UAVCAN.

saturated uint16 value [extent 2.0 bytes]


    
    
    

saturated uint16 IP_V4 = 2048


    
    
    

saturated uint16 ARP = 2054


    
    
    

saturated uint16 IP_V6 = 34525


    
    
    

uavcan.metatransport.ethernet.Frame (v0.1) [extent 73856 bytes]

IEEE 802.3 Ethernet frame encapsulation.
In terms of libpcap/tcpdump, the corresponding link type is LINKTYPE_ETHERNET/DLT_EN10MB.

saturated uint8[6] destination

saturated uint8


    
    
    




saturated uint8[6] source

saturated uint8


    
    
    




uavcan.metatransport.ethernet.EtherType (v0.1) ethertype [extent 16 bytes]

Standard EtherType constants as defined by IEEE Registration Authority and IANA.
This list is only a small subset of constants that are considered to be relevant for UAVCAN.

saturated uint16 value [extent 2.0 bytes]


    
    
    

saturated uint16 IP_V4 = 2048


    
    
    

saturated uint16 ARP = 2054


    
    
    

saturated uint16 IP_V6 = 34525


    
    
    

    
    
    




saturated uint8[<=9216] payload

saturated uint8

Supports conventional jumbo frames (up to 9 KiB).

uavcan.metatransport.can

uavcan.metatransport.can.ArbitrationID (v0.1) [extent 40 bytes]

CAN frame arbitration field.

uavcan.metatransport.can.BaseArbitrationID (v0.1) base [extent 32 bytes]

11-bit identifier.

truncated uint11 value [extent 11 bits]


    
    
    

void21 [extent 21 bits]


    
    
    

    
    
    




uavcan.metatransport.can.ExtendedArbitrationID (v0.1) extended [extent 32 bytes]

29-bit identifier.

truncated uint29 value [extent 29 bits]


    
    
    

void3 [extent 3 bits]


    
    
    

    
    
    

uavcan.metatransport.can.BaseArbitrationID (v0.1) [extent 32 bytes]

11-bit identifier.

truncated uint11 value [extent 11 bits]


    
    
    

void21 [extent 21 bits]


    
    
    

uavcan.metatransport.can.DataClassic (v0.1) [extent 112 bytes]

Classic data frame payload.

uavcan.metatransport.can.ArbitrationID (v0.1) arbitration_id [extent 40 bytes]

CAN frame arbitration field.

uavcan.metatransport.can.BaseArbitrationID (v0.1) base [extent 32 bytes]

11-bit identifier.

truncated uint11 value [extent 11 bits]


    
    
    

void21 [extent 21 bits]


    
    
    

    
    
    




uavcan.metatransport.can.ExtendedArbitrationID (v0.1) extended [extent 32 bytes]

29-bit identifier.

truncated uint29 value [extent 29 bits]


    
    
    

void3 [extent 3 bits]


    
    
    

    
    
    

    
    
    




saturated uint8[<=8] data

saturated uint8


    
    
    

uavcan.metatransport.can.DataFD (v0.1) [extent 560 bytes]

CAN FD data frame payload.

uavcan.metatransport.can.ArbitrationID (v0.1) arbitration_id [extent 40 bytes]

CAN frame arbitration field.

uavcan.metatransport.can.BaseArbitrationID (v0.1) base [extent 32 bytes]

11-bit identifier.

truncated uint11 value [extent 11 bits]


    
    
    

void21 [extent 21 bits]


    
    
    

    
    
    




uavcan.metatransport.can.ExtendedArbitrationID (v0.1) extended [extent 32 bytes]

29-bit identifier.

truncated uint29 value [extent 29 bits]


    
    
    

void3 [extent 3 bits]


    
    
    

    
    
    

    
    
    




saturated uint8[<=64] data

saturated uint8


    
    
    

uavcan.metatransport.can.Error (v0.1) [extent 32 bytes]

CAN bus error report: either an intentionally generated error frame or a disturbance.

void32 [extent 4.0 bytes]


    
    
    

uavcan.metatransport.can.ExtendedArbitrationID (v0.1) [extent 32 bytes]

29-bit identifier.

truncated uint29 value [extent 29 bits]


    
    
    

void3 [extent 3 bits]


    
    
    

uavcan.metatransport.can.Frame (v0.2) [extent 568 bytes]

Classic CAN or CAN FD frame representation. This is the top-level data type in its namespace.

uavcan.metatransport.can.Error (v0.1) error [extent 32 bytes]

CAN bus error report: either an intentionally generated error frame or a disturbance.

void32 [extent 4.0 bytes]


    
    
    
CAN error (intentional or disturbance)

uavcan.metatransport.can.DataFD (v0.1) data_fd [extent 560 bytes]

CAN FD data frame payload.

uavcan.metatransport.can.ArbitrationID (v0.1) arbitration_id [extent 40 bytes]

CAN frame arbitration field.

uavcan.metatransport.can.BaseArbitrationID (v0.1) base [extent 32 bytes]

11-bit identifier.

truncated uint11 value [extent 11 bits]


    
    
    

void21 [extent 21 bits]


    
    
    

    
    
    




uavcan.metatransport.can.ExtendedArbitrationID (v0.1) extended [extent 32 bytes]

29-bit identifier.

truncated uint29 value [extent 29 bits]


    
    
    

void3 [extent 3 bits]


    
    
    

    
    
    

    
    
    




saturated uint8[<=64] data

saturated uint8


    
    
    
Bit rate switch flag active

uavcan.metatransport.can.DataClassic (v0.1) data_classic [extent 112 bytes]

Classic data frame payload.

uavcan.metatransport.can.ArbitrationID (v0.1) arbitration_id [extent 40 bytes]

CAN frame arbitration field.

uavcan.metatransport.can.BaseArbitrationID (v0.1) base [extent 32 bytes]

11-bit identifier.

truncated uint11 value [extent 11 bits]


    
    
    

void21 [extent 21 bits]


    
    
    

    
    
    




uavcan.metatransport.can.ExtendedArbitrationID (v0.1) extended [extent 32 bytes]

29-bit identifier.

truncated uint29 value [extent 29 bits]


    
    
    

void3 [extent 3 bits]


    
    
    

    
    
    

    
    
    




saturated uint8[<=8] data

saturated uint8


    
    
    
Bit rate switch flag not active

uavcan.metatransport.can.RTR (v0.1) remote_transmission_request [extent 40 bytes]

Classic remote transmission request (not defined for CAN FD).

uavcan.metatransport.can.ArbitrationID (v0.1) arbitration_id [extent 40 bytes]

CAN frame arbitration field.

uavcan.metatransport.can.BaseArbitrationID (v0.1) base [extent 32 bytes]

11-bit identifier.

truncated uint11 value [extent 11 bits]


    
    
    

void21 [extent 21 bits]


    
    
    

    
    
    




uavcan.metatransport.can.ExtendedArbitrationID (v0.1) extended [extent 32 bytes]

29-bit identifier.

truncated uint29 value [extent 29 bits]


    
    
    

void3 [extent 3 bits]


    
    
    

    
    
    

    
    
    
Bit rate switch flag not active

uavcan.metatransport.can.Frame (v0.1) [extent 624 bytes]

CAN 2.0 or CAN FD frame representation. This is the top-level data type in its namespace.

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    




uavcan.metatransport.can.Manifestation (v0.1) manifestation [extent 568 bytes]

CAN frame properties that can be manifested on the bus.

uavcan.metatransport.can.Error (v0.1) error [extent 32 bytes]

CAN bus error report: either an intentionally generated error frame or a disturbance.

void32 [extent 4.0 bytes]


    
    
    
CAN error (intentional or disturbance)

uavcan.metatransport.can.DataFD (v0.1) data_fd [extent 560 bytes]

CAN FD data frame payload.

uavcan.metatransport.can.ArbitrationID (v0.1) arbitration_id [extent 40 bytes]

CAN frame arbitration field.

uavcan.metatransport.can.BaseArbitrationID (v0.1) base [extent 32 bytes]

11-bit identifier.

truncated uint11 value [extent 11 bits]


    
    
    

void21 [extent 21 bits]


    
    
    

    
    
    




uavcan.metatransport.can.ExtendedArbitrationID (v0.1) extended [extent 32 bytes]

29-bit identifier.

truncated uint29 value [extent 29 bits]


    
    
    

void3 [extent 3 bits]


    
    
    

    
    
    

    
    
    




saturated uint8[<=64] data

saturated uint8


    
    
    
Bit rate switch flag active

uavcan.metatransport.can.DataClassic (v0.1) data_classic [extent 112 bytes]

Classic data frame payload.

uavcan.metatransport.can.ArbitrationID (v0.1) arbitration_id [extent 40 bytes]

CAN frame arbitration field.

uavcan.metatransport.can.BaseArbitrationID (v0.1) base [extent 32 bytes]

11-bit identifier.

truncated uint11 value [extent 11 bits]


    
    
    

void21 [extent 21 bits]


    
    
    

    
    
    




uavcan.metatransport.can.ExtendedArbitrationID (v0.1) extended [extent 32 bytes]

29-bit identifier.

truncated uint29 value [extent 29 bits]


    
    
    

void3 [extent 3 bits]


    
    
    

    
    
    

    
    
    




saturated uint8[<=8] data

saturated uint8


    
    
    
Bit rate switch flag not active

uavcan.metatransport.can.RTR (v0.1) remote_transmission_request [extent 40 bytes]

Classic remote transmission request (not defined for CAN FD).

uavcan.metatransport.can.ArbitrationID (v0.1) arbitration_id [extent 40 bytes]

CAN frame arbitration field.

uavcan.metatransport.can.BaseArbitrationID (v0.1) base [extent 32 bytes]

11-bit identifier.

truncated uint11 value [extent 11 bits]


    
    
    

void21 [extent 21 bits]


    
    
    

    
    
    




uavcan.metatransport.can.ExtendedArbitrationID (v0.1) extended [extent 32 bytes]

29-bit identifier.

truncated uint29 value [extent 29 bits]


    
    
    

void3 [extent 3 bits]


    
    
    

    
    
    

    
    
    
Bit rate switch flag not active

    
    
    

uavcan.metatransport.can.Manifestation (v0.1) [extent 568 bytes]

CAN frame properties that can be manifested on the bus.

uavcan.metatransport.can.Error (v0.1) error [extent 32 bytes]

CAN bus error report: either an intentionally generated error frame or a disturbance.

void32 [extent 4.0 bytes]


    
    
    
CAN error (intentional or disturbance)

uavcan.metatransport.can.DataFD (v0.1) data_fd [extent 560 bytes]

CAN FD data frame payload.

uavcan.metatransport.can.ArbitrationID (v0.1) arbitration_id [extent 40 bytes]

CAN frame arbitration field.

uavcan.metatransport.can.BaseArbitrationID (v0.1) base [extent 32 bytes]

11-bit identifier.

truncated uint11 value [extent 11 bits]


    
    
    

void21 [extent 21 bits]


    
    
    

    
    
    




uavcan.metatransport.can.ExtendedArbitrationID (v0.1) extended [extent 32 bytes]

29-bit identifier.

truncated uint29 value [extent 29 bits]


    
    
    

void3 [extent 3 bits]


    
    
    

    
    
    

    
    
    




saturated uint8[<=64] data

saturated uint8


    
    
    
Bit rate switch flag active

uavcan.metatransport.can.DataClassic (v0.1) data_classic [extent 112 bytes]

Classic data frame payload.

uavcan.metatransport.can.ArbitrationID (v0.1) arbitration_id [extent 40 bytes]

CAN frame arbitration field.

uavcan.metatransport.can.BaseArbitrationID (v0.1) base [extent 32 bytes]

11-bit identifier.

truncated uint11 value [extent 11 bits]


    
    
    

void21 [extent 21 bits]


    
    
    

    
    
    




uavcan.metatransport.can.ExtendedArbitrationID (v0.1) extended [extent 32 bytes]

29-bit identifier.

truncated uint29 value [extent 29 bits]


    
    
    

void3 [extent 3 bits]


    
    
    

    
    
    

    
    
    




saturated uint8[<=8] data

saturated uint8


    
    
    
Bit rate switch flag not active

uavcan.metatransport.can.RTR (v0.1) remote_transmission_request [extent 40 bytes]

Classic remote transmission request (not defined for CAN FD).

uavcan.metatransport.can.ArbitrationID (v0.1) arbitration_id [extent 40 bytes]

CAN frame arbitration field.

uavcan.metatransport.can.BaseArbitrationID (v0.1) base [extent 32 bytes]

11-bit identifier.

truncated uint11 value [extent 11 bits]


    
    
    

void21 [extent 21 bits]


    
    
    

    
    
    




uavcan.metatransport.can.ExtendedArbitrationID (v0.1) extended [extent 32 bytes]

29-bit identifier.

truncated uint29 value [extent 29 bits]


    
    
    

void3 [extent 3 bits]


    
    
    

    
    
    

    
    
    
Bit rate switch flag not active

uavcan.metatransport.can.RTR (v0.1) [extent 40 bytes]

Classic remote transmission request (not defined for CAN FD).

uavcan.metatransport.can.ArbitrationID (v0.1) arbitration_id [extent 40 bytes]

CAN frame arbitration field.

uavcan.metatransport.can.BaseArbitrationID (v0.1) base [extent 32 bytes]

11-bit identifier.

truncated uint11 value [extent 11 bits]


    
    
    

void21 [extent 21 bits]


    
    
    

    
    
    




uavcan.metatransport.can.ExtendedArbitrationID (v0.1) extended [extent 32 bytes]

29-bit identifier.

truncated uint29 value [extent 29 bits]


    
    
    

void3 [extent 3 bits]


    
    
    

    
    
    

    
    
    

uavcan.pnp

uavcan.pnp.NodeIDAllocationData (v2.0) [extent 416 bytes] [fixed port-ID 8165]

In order to be able to operate in a UAVCAN network, a node shall have a node-ID that is unique within the network.
Typically, a valid node-ID can be configured manually for each node; however, in certain use cases the manual
approach is either undesirable or impossible, therefore UAVCAN defines the high-level feature of plug-and-play
nodes that allows nodes to obtain a node-ID value automatically upon connection to the network. When combined
with automatic physical layer configuration (such as auto bit rate detection), this feature allows one to implement
nodes that can join a UAVCAN network without any prior manual configuration whatsoever. Such nodes are referred to
as "plug-and-play nodes" (or "PnP nodes" for brevity).

The feature is fundamentally non-deterministic and is likely to be unfit for some high-reliability systems;
the designers need to carefully consider the trade-offs involved before deciding to rely on this feature.
Normally, static node-ID settings should be preferred.

This feature relies on the concept of "anonymous message transfers", please consult with the UAVCAN transport
layer specification for details.

An allocated node-ID should not be persistent. This means that if a node is configured to use plug-and-play node-ID
allocation, it shall perform a new allocation every time it is started or rebooted. The allocated node-ID value
should not be stored on the node itself, because there exist edge cases that may lead to node-ID conflicts under
certain circumstances (reviewed later).

The process of plug-and-play node-ID allocation always involves two types of nodes: "allocators", which serve
allocation requests; and "allocatees", which request PnP node-ID from allocators. A UAVCAN network may implement
the following configurations of allocators:

  - Zero allocators, in which case plug-and-play node-ID allocation cannot be used, only nodes with statically
    configured node-ID can communicate.

  - One allocator, in which case the feature of plug-and-play node-ID allocation will become unavailable
    if the allocator fails. In this configuration, the role of the allocator can be performed even by a very
    resource-constrained system, e.g. a low-end microcontroller.

  - Three allocators, in which case the allocators will be using a replicated allocation table via a
    distributed consensus algorithm. In this configuration, the network can tolerate the loss of one
    allocator and continue to serve allocation requests. This configuration requires the allocators to
    maintain large data structures for the needs of the distributed consensus algorithm, and may therefore
    require a slightly more sophisticated computational platform, e.g., a high-end microcontroller.

  - Five allocators, it is the same as the three allocator configuration reviewed above except that the network
    can tolerate the loss of two allocators and still continue to serve allocation requests.

In order to get a PnP node-ID, an allocatee shall have a globally unique 128-bit integer identifier, known as
unique-ID (where "globally unique" means that the probability of having two nodes anywhere in the world that share
the same unique-ID is negligibly low). This is the same value that is used in the field unique_id of the data type
uavcan.node.GetInfo. All PnP nodes shall support the service uavcan.node.GetInfo, and they shall use the same
unique-ID value when requesting node-ID allocation and when responding to the GetInfo requests (there may exist
other usages of the unique-ID value, but they lie outside of the scope of the PnP protocol).

During allocation, the allocatee communicates its unique-ID to the allocator (or allocators in the case of a
redundant allocator configuration), which then use it to produce an appropriate allocation response. Unique-ID
values are kept by allocators in the "allocation table" - a data structure that contains the mapping between
unique-ID and the corresponding node-ID values. The allocation table is a write-only data structure that can
only expand. When a new allocatee requests a PnP node-ID, its unique-ID is recorded in the allocation table,
and all subsequent allocation requests from the same allocatee will be served with the same node-ID value.

In configurations with redundant allocators, every allocator maintains a replica of the same allocation table
(a UAVCAN network cannot contain more than one allocation table, regardless of the number of allocators employed).
While the allocation table is a write-only data structure that can only grow, it is still possible to wipe the
table completely (as long as it is removed from all redundant allocators on the network simultaneously),
forcing the allocators to forget known nodes and perform all future allocations anew.

In the context of the following description, nodes that use a manually-configured node-ID will be referred to as
"static nodes". It is assumed that allocators are always static nodes themselves since there is no other authority
on the network that can grant a PnP node-ID, so allocators are unable to request a PnP node-ID for themselves.
Excepting allocators, it is not recommended to mix PnP and static nodes on the same network; i.e., normally,
a UAVCAN network should contain either all static nodes, or all PnP nodes (excepting allocators). If this
recommendation cannot be followed, the following rules of safe co-existence of PnP nodes with static nodes should
be adopted:
  - It is safe to connect PnP nodes to the bus at any time.
  - A static node can be connected to the bus if the allocator (allocators) is (are) already aware of it.
    I.e., the static node is already listed in the allocation table.
  - A new static node (i.e., a node that does not meet the above criterion) can be connected to the bus only if
    no PnP allocation requests are happening at the moment.

Due to the possibility of coexistence of static nodes with PnP nodes, allocators are tasked with monitoring
the nodes present in the network. If the allocator detects an online node in the network the node-ID of which is
not found in the allocation table (or the local copy thereof in the case of redundant allocators), the allocator
shall create a new mock entry where the node-ID matches that of the newly detected node and the unique-ID is set to
zero (i.e., a 128-bit long sequence of zero bits). This behavior ensures that PnP nodes will never be granted
node-ID values that are already taken by static nodes. Allocators are allowed to request the true unique-ID of the
newly detected nodes by issuing requests uavcan.node.GetInfo instead of using mock zero unique-IDs, but this is not
required for the sake of simplicity and determinism (some nodes may fail to respond to the GetInfo request, e.g.,
if this service is not supported). Note that in the case of redundant allocators, some of them may be relieved of
this task due to the intrinsic properties of the distributed consensus algorithm; please refer to the documentation
for the data type uavcan.pnp.cluster.AppendEntries for more information.

The unique-ID & node-ID pair of each allocator shall be kept in the allocation table as well. It is allowed to replace
the unique-ID values of allocators with zeros at the discretion of the implementer.

As can be inferred from the above, the process of PnP node-ID allocation involves up to two types of communications:

  - "Allocatee-allocator exchange" - this communication is used when an allocatee requests a PnP node-ID from the
    allocator (or redundant allocators), and also when the allocator transmits a response back to the allocatee.
    This communication is invariant to the allocator configuration used, i.e., the allocatees are not aware of
    how many allocators are available on the network and how they are configured. In configurations with
    non-redundant (i.e., single) allocator, this is the only type of PnP allocation exchanges.

  - "Allocator-allocator exchange" - this communication is used by redundant allocators for the maintenance of
    the replicated allocation table and for other needs of the distributed consensus algorithm. Allocatees are
    completely isolated and are unaware of these exchanges. This communication is not used with the single-allocator
    configuration, since there is only one server and the allocation table is not distributed. The data types
    used for the allocator-allocator exchanges are defined in the namespace uavcan.pnp.cluster.

As has been said earlier, the logic used for communication between allocators (for the needs of the maintenance of
the distributed allocation table) is completely unrelated to the allocatees. The allocatees are unaware of these
exchanges, and they are also unaware of the allocator configuration used on the network: single or redundant.
As such, the documentation you're currently reading does not describe the logic and requirements of the
allocator-allocator exchanges for redundant configurations; for that, please refer to the documentation for the
data type uavcan.pnp.cluster.AppendEntries.

Allocatee-allocator exchanges are performed using only this message type uavcan.pnp.NodeIDAllocationData. Allocators
use it with regular message transfers; allocatees use it with anonymous message transfers. The specification and
usage info for this data type is provided below.

The general idea of the allocatee-allocator exchanges is that the allocatee communicates to the allocator its
unique-ID and, if applicable, the preferred node-ID value that it would like to have. The allocatee uses
anonymous message transfers of this type. The allocator performs the allocation and sends a response using
the same message type, where the field for unique-ID is populated with the unique-ID of the requesting node
and the field for node-ID is populated with the allocated node-ID. All exchanges from allocatee to allocator use
single-frame transfers only (see the specification for more information on the limitations of anonymous messages).

The allocatee-allocator exchange logic differs between allocators and allocatees. For allocators, the logic is
trivial: upon reception of a request, the allocator performs an allocation and sends a response back. If the
allocation could not be performed for any reason (e.g., the allocation table is full, or there was a failure),
no response is sent back (i.e., the request is simply ignored); the recommended strategy for the allocatee is to
continue sending new allocation requests until a response is granted or a higher-level system (e.g., a maintenance
technician or some automation) intervenes to rectify the problem (e.g., by purging the allocation table).
The allocator that could not complete an allocation for any reason is recommended to emit a diagnostic message
with a human-readable description of the problem. For allocatees, the logic is described below.

This message is used for PnP node-ID allocation on all transports where the maximum transmission unit size is
sufficiently large. For low-MTU transports such as Classic CAN there is an older version of the definition (v1)
that takes the low MTU into account (the unique-ID value is replaced with a short hash in order to fit the data
into one 7-byte-long transfer).

Generally, the randomly chosen values of the request period (Trequest) should be in the range from 0 to 1 seconds.
Applications that are not concerned about the allocation time are recommended to pick higher values, as it will
reduce interference with other nodes where faster allocations may be desirable. The random interval shall be chosen
anew per transmission, whereas the pseudo node-ID value is allowed to stay constant per node.

The source of random data for Trequest shall be likely to yield different values for participating nodes, avoiding
common sequences. This implies that the time since boot alone is not a sufficiently robust source of randomness,
as that would be probable to cause nodes powered up at the same time to emit colliding messages repeatedly.

The response timeout is not explicitly defined for this protocol, as the allocatee will request a new allocation
Trequest units of time later again, unless an allocation has been granted. Since the request and response messages
are fully idempotent, accidentally repeated messages (e.g., due to benign race conditions that are inherent to this
protocol) are harmless.

On the allocatee's side the protocol is defined through the following set of rules:

  Rule A. On initialization:
    1. The allocatee subscribes to this message.
    2. The allocatee starts the Request Timer with a random interval of Trequest.

  Rule B. On expiration of the Request Timer:
    1. Request Timer restarts with a random interval of Trequest (chosen anew).
    2. The allocatee broadcasts an allocation request message, where the fields are populated as follows:
       node_id   - the preferred node-ID, or the highest valid value if the allocatee doesn't have any preference.
       unique_id - the 128-bit unique-ID of the allocatee, same value that is reported via uavcan.node.GetInfo.

  Rule C. On an allocation message WHERE (source node-ID is non-anonymous, i.e., regular allocation response)
                                   AND   (the field unique_id matches the allocatee's unique-ID):
    1. Request Timer stops.
    2. The allocatee initializes its node-ID with the received value.
    3. The allocatee terminates its subscription to allocation messages.
    4. Exit.

As can be seen, the algorithm assumes that the allocatee will continue to emit requests at random intervals
until an allocation is granted or the allocatee is disconnected.

uavcan.node.ID (v1.0) node_id [extent 16 bytes]

Defines a node-ID.
The maximum valid value is dependent on the underlying transport layer.
Values lower than 128 are always valid for all transports.
Refer to the specification for more info.

saturated uint16 value [extent 2.0 bytes]


    
    
    
If the message transfer is anonymous (i.e., allocation request), this is the preferred ID.
If the message transfer is non-anonymous (i.e., allocation response), this is the allocated ID.

If the allocatee does not have any preference, it should request the highest possible node-ID. Keep in mind that
the two highest node-ID values are reserved for network maintenance tools; requesting those is not prohibited,
but the allocator is recommended to avoid granting these node-ID, using nearest available lower value instead.
The allocator will traverse the allocation table starting from the preferred node-ID upward,
until a free node-ID is found (or the first ID reserved for network maintenance tools is reached).
If a free node-ID could not be found, the allocator will restart the search from the preferred node-ID
downward, until a free node-ID is found.

saturated uint8[16] unique_id

saturated uint8

The unique-ID of the allocatee. This is the SAME value that is reported via uavcan.node.GetInfo.
The value is subjected to the same set of constraints; e.g., it can't be changed while the node is running,
and the same value should be unlikely to be used by any two different nodes anywhere in the world.

If this is a non-anonymous transfer (i.e., allocation response), allocatees will match this value against their
own unique-ID, and ignore the message if there is no match. If the IDs match, then the field node_id contains
the allocated node-ID value for this node.

uavcan.pnp.NodeIDAllocationData (v1.0) [extent 72 bytes] [fixed port-ID 8166]

This definition of the allocation message is intended for use with transports where anonymous transfers are limited
to 7 bytes of payload, such as Classic CAN. The definition is carried over from the original UAVCAN v0 specification
with some modifications. For transports other than Classic CAN (e.g., CAN FD, serial, UDP, etc.) there is a more
general, more capable definition NodeIDAllocationData v2.0. The PnP protocol itself is described in the documentation
for the v2 definition. The documentation provided here builds upon the general case, so read that first please.

The full 128-bit unique-ID can't be accommodated in a single-frame anonymous message transfer over Classic CAN, so
this definition substitutes the full 128-bit ID with a smaller 48-bit hash of it. The 48-bit hash is obtained by
applying an arbitrary hash function to the unique-ID that outputs at least 48 bit of data. The recommended hash
function is the standard CRC-64WE where only the lowest 48 bit of the result are used.

Allocators that support allocation messages of different versions should maintain a shared allocation table for all.
Requests received via the v1 message obviously do not contain the full unique-ID; the allocators are recommended
to left-zero-pad the small 48-bit hash in order to obtain a "pseudo unique-ID", and use this value in the
allocation table as a substitute for the real unique-ID. It is recognized that this behavior will have certain
side effects, such as the same allocatee obtaining different allocated node-ID values depending on which version
of the message is used, but they are considered tolerable.

Allocatees that may need to operate over Classic CAN along with high-MTU transports may choose to use
only this constrained method of allocation for consistency and simplification.

In order to save space for the hash, the preferred node-ID is removed from the request. The allocated node-ID
is provided in the response, however; this is achieved by means of an optional field that is not populated in
the request but is populated in the response. This implies that the response may be a multi-frame transfer,
which is acceptable since responses are sent by allocators, which are regular nodes, and therefore they are
allowed to use regular message transfers rather than being limited to anonymous message transfers as allocatees are.

On the allocatee's side the protocol is defined through the following set of rules:

  Rule A. On initialization:
    1. The allocatee subscribes to this message.
    2. The allocatee starts the Request Timer with a random interval of Trequest.

  Rule B. On expiration of the Request Timer (started as per rules A, B, or C):
    1. Request Timer restarts with a random interval of Trequest (chosen anew).
    2. The allocatee broadcasts an allocation request message, where the fields are populated as follows:
       unique_id_hash    - a 48-bit hash of the unique-ID of the allocatee.
       allocated_node_id - empty (not populated).

  Rule C. On any allocation message, even if other rules also match:
    1. Request Timer restarts with a random interval of Trequest (chosen anew).

  Rule D. On an allocation message WHERE (source node-ID is non-anonymous, i.e., regular allocation response)
                                   AND   (the field unique_id_hash matches the allocatee's 48-bit unique-ID hash)
                                   AND   (the field allocated_node_id is populated):
    1. Request Timer stops.
    2. The allocatee initializes its node-ID with the received value.
    3. The allocatee terminates its subscription to allocation messages.
    4. Exit.

truncated uint48 unique_id_hash [extent 6.0 bytes]

An arbitrary 48-bit hash of the unique-ID of the local node.

uavcan.node.ID.1.0[<=1] allocated_node_id

uavcan.node.ID (v1.0) [extent 16 bytes]

Defines a node-ID.
The maximum valid value is dependent on the underlying transport layer.
Values lower than 128 are always valid for all transports.
Refer to the specification for more info.

saturated uint16 value [extent 2.0 bytes]


    
    
    
Shall be empty in request messages.
Shall be populated in response messages.

uavcan.pnp.cluster

uavcan.pnp.cluster.AppendEntries (v1.0) [service] [fixed port-ID 390]

This type is a part of the Raft consensus algorithm. The Raft consensus is used for the maintenance of the
distributed allocation table between redundant allocators. The following description is focused on the exchanges
between redundant PnP node-ID allocators. It does not apply to the case of non-redundant allocators, because
in that case the allocation table is stored locally and the process of node-ID allocation is trivial and fully local.
Exchanges between allocatees and allocators are documented in the appropriate message type definition.

The algorithm used for replication of the allocation table across redundant allocators is a fairly direct
implementation of the Raft consensus algorithm, as published in the paper
"In Search of an Understandable Consensus Algorithm (Extended Version)" by Diego Ongaro and John Ousterhout.
The following text assumes that the reader is familiar with the paper.

The Raft log contains entries of type Entry (in the same namespace), where every entry contains the Raft term
number, the unique-ID, and the corresponding node-ID value (or zeros if it could not be requested from a static
node). Therefore, the Raft log is the allocation table itself.

Since the maximum number of entries in the allocation table is limited by the range of node-ID values, the log
capacity is bounded. Therefore, the snapshot transfer and log compaction functions are not required,
so they are not used in this implementation of the Raft algorithm.

When an allocator becomes the leader of the Raft cluster, it checks if the Raft log contains an entry for its own
node-ID, and if it doesn't, the leader adds its own allocation entry to the log (the unique-ID can be replaced with
zeros at the discretion of the implementer). This behavior guarantees that the Raft log always contains at least
one entry, therefore it is not necessary to support negative log indices, as proposed by the Raft paper.

Since the log is write-only and limited in growth, all allocations are permanent. This restriction is acceptable,
since UAVCAN is a vehicle bus, and configuration of vehicle's components is not expected to change frequently.
Old allocations can be removed in order to free node-IDs for new allocations by clearing the Raft log on all
allocators; such clearing shall be performed simultaneously while the network is down, otherwise the Raft cluster
will automatically attempt to restore the lost state on the allocators where the table was cleared.

The allocators need to be aware of each other's node-ID in order to form a cluster. In order to learn each other's
node-ID values, the allocators broadcast messages of type Discovery (in the same namespace) until the cluster is
fully discovered and all allocators know of each other's node-ID. This extension to the Raft algorithm makes the
cluster almost configuration-free - the only parameter that shall be configured on all allocators of the cluster
is the number of nodes in the cluster (everything else will be auto-detected).

Runtime cluster membership changes are not supported, since they are not needed for a vehicle bus.

As has been explained in the general description of the PnP node-ID allocation feature, allocators shall watch for
unknown static nodes appearing on the bus. In the case of a non-redundant allocator, the task is trivial, since the
allocation table can be updated locally. In the case of a Raft cluster, however, the network monitoring task shall
be performed by the leader only, since other cluster members cannot commit to the shared allocation table (i.e.,
the Raft log) anyway. Redundant allocators should not attempt to obtain the true unique-ID of the newly detected
static nodes (use zeros instead), because the allocation table is write-only: if the unique-ID of a static node
ever changes (e.g., a replacement unit is installed, or network configuration is changed manually), the change
will be impossible to reflect in the allocation table.

Only the current Raft leader can process allocation requests and engage in communication with allocatees.
An allocator is allowed to send allocation responses only if both conditions are met:

  - The allocator is currently the Raft leader.
  - Its replica of the Raft log does not contain uncommitted entries (i.e. the last allocation request has been
    completed successfully).

All cluster maintenance traffic should normally use either the lowest or the next-to-lowest transfer priority level.

uavcan.pnp.cluster.AppendEntries.Request (v1.0) request [extent 800 bytes]

saturated uint32 term [extent 4.0 bytes]


    
    
    

saturated uint32 prev_log_term [extent 4.0 bytes]


    
    
    

saturated uint16 prev_log_index [extent 2.0 bytes]


    
    
    

saturated uint16 leader_commit [extent 2.0 bytes]

Refer to the Raft paper for explanation.

uavcan.pnp.cluster.Entry.1.0[<=1] entries

uavcan.pnp.cluster.Entry (v1.0) [extent 176 bytes]

One PnP node-ID allocation entry.
This type is a part of the Raft consensus algorithm. Please refer to the type AppendEntries for details.

saturated uint32 term [extent 4.0 bytes]

Refer to the Raft paper for explanation.

saturated uint8[16] unique_id

saturated uint8

Unique-ID of this allocation; zero if unknown.

uavcan.node.ID (v1.0) node_id [extent 16 bytes]

Defines a node-ID.
The maximum valid value is dependent on the underlying transport layer.
Values lower than 128 are always valid for all transports.
Refer to the specification for more info.

saturated uint16 value [extent 2.0 bytes]


    
    
    
Node-ID of this allocation.
Worst case replication time per Follower can be computed as:

  worst replication time = (node-ID capacity) * (2 trips of next_index) * (request interval per Follower)

E.g., given the request interval of 0.5 seconds, the worst case replication time for CAN bus is:

  128 nodes * 2 trips * 0.5 seconds = 128 seconds.

This is the amount of time it will take for a new Follower to reconstruct a full replica of the distributed log.

saturated uint8 DEFAULT_MIN_ELECTION_TIMEOUT = 2

[second]

saturated uint8 DEFAULT_MAX_ELECTION_TIMEOUT = 4

[second]
Given the minimum election timeout and the cluster size,
the maximum recommended request interval can be derived as follows:

  max recommended request interval = (min election timeout) / 2 requests / (cluster size - 1)

The equation assumes that the Leader requests one Follower at a time, so that there's at most one pending call
at any moment. Such behavior is optimal as it creates a uniform bus load, although it is implementation-specific.
Obviously, the request interval can be lower than that if needed, but higher values are not recommended as they may
cause Followers to initiate premature elections in case of frame losses or delays.

The timeout value is randomized in the range (MIN, MAX], according to the Raft paper. The randomization granularity
should be at least one millisecond or higher.

    
    
    




uavcan.pnp.cluster.AppendEntries.Response (v1.0) response [extent 416 bytes]

saturated uint32 term [extent 4.0 bytes]


    
    
    

saturated bool success [extent 1 bits]

Refer to the Raft paper for explanation.

    
    
    

uavcan.pnp.cluster.Discovery (v1.0) [extent 800 bytes] [fixed port-ID 8164]

This message is used by redundant allocators to find each other's node-ID.
Please refer to the type AppendEntries for details.

An allocator should stop publishing this message as soon as it has discovered all other allocators in the cluster.

An exception applies: when an allocator receives a Discovery message where the list of known nodes is incomplete
(i.e. len(known_nodes) < configured_cluster_size), it shall publish a Discovery message once. This condition
allows other allocators to quickly re-discover the cluster after a restart.

saturated uint3 configured_cluster_size [extent 3 bits]

The number of allocators in the cluster as configured on the sender.
This value shall be the same across all allocators.

void5 [extent 5 bits]


    
    
    




uavcan.node.ID.1.0[<=5] known_nodes

uavcan.node.ID (v1.0) [extent 16 bytes]

Defines a node-ID.
The maximum valid value is dependent on the underlying transport layer.
Values lower than 128 are always valid for all transports.
Refer to the specification for more info.

saturated uint16 value [extent 2.0 bytes]


    
    
    
Node-IDs of the allocators that are known to the publishing allocator, including the publishing allocator itself.

saturated uint8 BROADCASTING_PERIOD = 1

[second]
This message should be broadcasted by the allocator at this interval until all other allocators are discovered.

saturated uint3 MAX_CLUSTER_SIZE = 5

The redundant allocator cluster cannot contain more than 5 allocators.

uavcan.pnp.cluster.Entry (v1.0) [extent 176 bytes]

One PnP node-ID allocation entry.
This type is a part of the Raft consensus algorithm. Please refer to the type AppendEntries for details.

saturated uint32 term [extent 4.0 bytes]

Refer to the Raft paper for explanation.

saturated uint8[16] unique_id

saturated uint8

Unique-ID of this allocation; zero if unknown.

uavcan.node.ID (v1.0) node_id [extent 16 bytes]

Defines a node-ID.
The maximum valid value is dependent on the underlying transport layer.
Values lower than 128 are always valid for all transports.
Refer to the specification for more info.

saturated uint16 value [extent 2.0 bytes]


    
    
    
Node-ID of this allocation.

uavcan.pnp.cluster.RequestVote (v1.0) [service] [fixed port-ID 391]

This type is a part of the Raft consensus algorithm. Please refer to the type AppendEntries for details.

uavcan.pnp.cluster.RequestVote.Request (v1.0) request [extent 416 bytes]

saturated uint32 term [extent 4.0 bytes]


    
    
    

saturated uint32 last_log_term [extent 4.0 bytes]


    
    
    

saturated uint16 last_log_index [extent 2.0 bytes]

Refer to the Raft paper for explanation.

    
    
    




uavcan.pnp.cluster.RequestVote.Response (v1.0) response [extent 416 bytes]

saturated uint32 term [extent 4.0 bytes]


    
    
    

saturated bool vote_granted [extent 1 bits]

Refer to the Raft paper for explanation.

    
    
    

uavcan.file

uavcan.file.Error (v1.0) [extent 16 bytes]

Nested type.
Result of a file system operation.

saturated uint16 value [extent 2.0 bytes]


    
    
    

saturated uint16 OK = 0


    
    
    

saturated uint16 UNKNOWN_ERROR = 65535


    
    
    

saturated uint16 NOT_FOUND = 2


    
    
    

saturated uint16 IO_ERROR = 5


    
    
    

saturated uint16 ACCESS_DENIED = 13


    
    
    

saturated uint16 IS_DIRECTORY = 21

I.e., attempted read/write on a path that points to a directory

saturated uint16 INVALID_VALUE = 22

E.g., file name is not valid for the target file system

saturated uint16 FILE_TOO_LARGE = 27


    
    
    

saturated uint16 OUT_OF_SPACE = 28


    
    
    

saturated uint16 NOT_SUPPORTED = 38


    
    
    

uavcan.file.GetInfo (v0.2) [service] [fixed port-ID 405]

Information about a remote file system entry (file, directory, etc).

uavcan.file.GetInfo.Request (v0.2) request [extent 2432 bytes]

uavcan.file.Path (v2.0) path [extent 2048 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

saturated uint8[<=255] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 255


    
    
    

    
    
    

    
    
    




uavcan.file.GetInfo.Response (v0.2) response [extent 416 bytes]

uavcan.file.Error (v1.0) error [extent 16 bytes]

Nested type.
Result of a file system operation.

saturated uint16 value [extent 2.0 bytes]


    
    
    

saturated uint16 OK = 0


    
    
    

saturated uint16 UNKNOWN_ERROR = 65535


    
    
    

saturated uint16 NOT_FOUND = 2


    
    
    

saturated uint16 IO_ERROR = 5


    
    
    

saturated uint16 ACCESS_DENIED = 13


    
    
    

saturated uint16 IS_DIRECTORY = 21

I.e., attempted read/write on a path that points to a directory

saturated uint16 INVALID_VALUE = 22

E.g., file name is not valid for the target file system

saturated uint16 FILE_TOO_LARGE = 27


    
    
    

saturated uint16 OUT_OF_SPACE = 28


    
    
    

saturated uint16 NOT_SUPPORTED = 38


    
    
    
Result of the operation.

truncated uint40 size [extent 5.0 bytes]

File size in bytes. Should be set to zero for directories.

truncated uint40 unix_timestamp_of_last_modification [extent 5.0 bytes]

The UNIX Epoch time when the entry was last modified. Zero if unknown.

saturated bool is_file_not_directory [extent 1 bits]

True if file, false if directory.

saturated bool is_link [extent 1 bits]

This is a link to another entry; the above flag indicates the type of the target.

saturated bool is_readable [extent 1 bits]

The item can be read by the caller (applies to files and directories).

saturated bool is_writeable [extent 1 bits]

The item can be written by the caller (applies to files and directories).
If such entry does not exist, all flags should be cleared/ignored.

void4 [extent 4 bits]


    
    
    

    
    
    

uavcan.file.GetInfo (v0.1) [service] [fixed port-ID 405]

Information about a remote file system entry (file, directory, etc).

uavcan.file.GetInfo.Request (v0.1) request [extent 2432 bytes]

uavcan.file.Path (v1.0) path [extent 904 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

The maximum path length limit is chosen as a trade-off between compatibility with deep directory structures and
the worst-case transfer length. The limit is 112 bytes, which allows all transfers containing a single instance
of path and no other large data chunks to fit into two CAN FD frames.

saturated uint8[<=112] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 112


    
    
    

    
    
    

    
    
    




uavcan.file.GetInfo.Response (v0.1) response [extent 416 bytes]

uavcan.file.Error (v1.0) error [extent 16 bytes]

Nested type.
Result of a file system operation.

saturated uint16 value [extent 2.0 bytes]


    
    
    

saturated uint16 OK = 0


    
    
    

saturated uint16 UNKNOWN_ERROR = 65535


    
    
    

saturated uint16 NOT_FOUND = 2


    
    
    

saturated uint16 IO_ERROR = 5


    
    
    

saturated uint16 ACCESS_DENIED = 13


    
    
    

saturated uint16 IS_DIRECTORY = 21

I.e., attempted read/write on a path that points to a directory

saturated uint16 INVALID_VALUE = 22

E.g., file name is not valid for the target file system

saturated uint16 FILE_TOO_LARGE = 27


    
    
    

saturated uint16 OUT_OF_SPACE = 28


    
    
    

saturated uint16 NOT_SUPPORTED = 38


    
    
    
Result of the operation.

truncated uint40 size [extent 5.0 bytes]

File size in bytes. Should be set to zero for directories.

truncated uint40 unix_timestamp_of_last_modification [extent 5.0 bytes]

The UNIX Epoch time when the entry was last modified. Zero if unknown.

saturated bool is_file_not_directory [extent 1 bits]

True if file, false if directory.

saturated bool is_link [extent 1 bits]

This is a link to another entry; the above flag indicates the type of the target.

saturated bool is_readable [extent 1 bits]

The item can be read by the caller (applies to files and directories).

saturated bool is_writeable [extent 1 bits]

The item can be written by the caller (applies to files and directories).
If such entry does not exist, all flags should be cleared/ignored.

void4 [extent 4 bits]


    
    
    

    
    
    

uavcan.file.List (v0.2) [service] [fixed port-ID 406]

This service can be used to list a remote directory, one entry per request.

The client should query each entry independently, iterating 'entry_index' from 0 until the last entry.
When the index reaches the number of elements in the directory, the server will report that there is
no such entry by returning an empty name.

The field entry_index shall be applied to an ordered list of directory entries (e.g. alphabetically ordered).
The exact sorting criteria does not matter as long as it provides the same ordering for subsequent service calls.

Observe that this listing operation is fundamentally non-atomic. The caller shall beware of possible race conditions
and is responsible for handling them properly. Particularly, consider what happens if a new item is inserted into
the directory between two subsequent calls: if the item happened to be inserted at the index that is lower than the
index of the next request, the next returned item (or several, if more items were inserted) will repeat the ones
that were listed earlier. The caller should handle that properly, either by ignoring the repeated items or by
restarting the listing operation from the beginning (index 0).

uavcan.file.List.Request (v0.2) request [extent 2432 bytes]

saturated uint32 entry_index [extent 4.0 bytes]


    
    
    

void32 [extent 4.0 bytes]

Reserved for future use.

uavcan.file.Path (v2.0) directory_path [extent 2048 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

saturated uint8[<=255] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 255


    
    
    

    
    
    

    
    
    




uavcan.file.List.Response (v0.2) response [extent 2432 bytes]

void32 [extent 4.0 bytes]

Reserved for future use.

uavcan.file.Path (v2.0) entry_base_name [extent 2048 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

saturated uint8[<=255] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 255


    
    
    
The base name of the referenced entry, i.e., relative to the outer directory.
The outer directory path is not included to conserve bandwidth.
Empty if such entry does not exist.

For example, suppose there is a file "/foo/bar/baz.bin". Listing the directory with the path "/foo/bar/" (the slash
at the end is optional) at the index 0 will return "baz.bin". Listing the same directory at the index 1 (or any
higher) will return an empty name "", indicating that the caller has reached the end of the list.

    
    
    

uavcan.file.List (v0.1) [service] [fixed port-ID 406]

This service can be used to list a remote directory, one entry per request.

The client should query each entry independently, iterating 'entry_index' from 0 until the last entry.
When the index reaches the number of elements in the directory, the server will report that there is
no such entry by returning an empty name.

The field entry_index shall be applied to an ordered list of directory entries (e.g. alphabetically ordered).
The exact sorting criteria does not matter as long as it provides the same ordering for subsequent service calls.

Observe that this listing operation is fundamentally non-atomic. The caller shall beware of possible race conditions
and is responsible for handling them properly. Particularly, consider what happens if a new item is inserted into
the directory between two subsequent calls: if the item happened to be inserted at the index that is lower than the
index of the next request, the next returned item (or several, if more items were inserted) will repeat the ones
that were listed earlier. The caller should handle that properly, either by ignoring the repeated items or by
restarting the listing operation from the beginning (index 0).

uavcan.file.List.Request (v0.1) request [extent 2432 bytes]

saturated uint32 entry_index [extent 4.0 bytes]


    
    
    

void32 [extent 4.0 bytes]

Reserved for future use.

uavcan.file.Path (v1.0) directory_path [extent 904 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

The maximum path length limit is chosen as a trade-off between compatibility with deep directory structures and
the worst-case transfer length. The limit is 112 bytes, which allows all transfers containing a single instance
of path and no other large data chunks to fit into two CAN FD frames.

saturated uint8[<=112] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 112


    
    
    

    
    
    

    
    
    




uavcan.file.List.Response (v0.1) response [extent 2432 bytes]

void32 [extent 4.0 bytes]

Reserved for future use.

uavcan.file.Path (v1.0) entry_base_name [extent 904 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

The maximum path length limit is chosen as a trade-off between compatibility with deep directory structures and
the worst-case transfer length. The limit is 112 bytes, which allows all transfers containing a single instance
of path and no other large data chunks to fit into two CAN FD frames.

saturated uint8[<=112] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 112


    
    
    
The base name of the referenced entry, i.e., relative to the outer directory.
The outer directory path is not included to conserve bandwidth.
Empty if such entry does not exist.

For example, suppose there is a file "/foo/bar/baz.bin". Listing the directory with the path "/foo/bar/" (the slash
at the end is optional) at the index 0 will return "baz.bin". Listing the same directory at the index 1 (or any
higher) will return an empty name "", indicating that the caller has reached the end of the list.

    
    
    

uavcan.file.Modify (v1.1) [service] [fixed port-ID 407]

Manipulate a remote file system entry. Applies to files, directories, and links alike.
If the remote entry is a directory, all nested entries will be affected, too.

The server should perform all operations atomically, unless atomicity is not supported by
the underlying file system.

Atomic copying can be effectively employed by remote nodes before reading or after writing
the file to minimize the possibility of race conditions.
For example, before reading a large file from the server, the cilent might opt to create
a temporary copy of it first, then read the copy, and delete it upon completion. Likewise,
a similar strategy can be employed for writing, where the file is first written at a
temporary location, and then moved to its final destination. These approaches, however,
may lead to creation of dangling temporary files if the client failed to dispose of them
properly, so that risk should be taken into account.

Move/Copy
  Specify the source path and the destination path.
  If the source does not exist, the operation will fail.
  Set the preserve_source flag to copy rather than move.
  If the destination exists and overwrite_destination is not set, the operation will fail.
  If the target path includes non-existent directories, they will be created (like "mkdir -p").

Touch
  Specify the destination path and make the source path empty.
  If the path exists (file/directory/link), its modification time will be updated.
  If the path does not exist, an empty file will be created.
  If the target path includes non-existent directories, they will be created (like "mkdir -p").
  Flags are ignored.

Remove
  Specify the source path (file/directory/link) and make the destination path empty.
  Fails if the path does not exist.
  Flags are ignored.

uavcan.file.Modify.Request (v1.1) request [extent 4832 bytes]

saturated bool preserve_source [extent 1 bits]

Do not remove the source. Used to copy instead of moving.

saturated bool overwrite_destination [extent 1 bits]

If the destination exists, remove it beforehand.

void30 [extent 30 bits]


    
    
    




uavcan.file.Path (v2.0) source [extent 2048 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

saturated uint8[<=255] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 255


    
    
    

    
    
    




uavcan.file.Path (v2.0) destination [extent 2048 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

saturated uint8[<=255] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 255


    
    
    

    
    
    

    
    
    




uavcan.file.Modify.Response (v1.1) response [extent 416 bytes]

uavcan.file.Error (v1.0) error [extent 16 bytes]

Nested type.
Result of a file system operation.

saturated uint16 value [extent 2.0 bytes]


    
    
    

saturated uint16 OK = 0


    
    
    

saturated uint16 UNKNOWN_ERROR = 65535


    
    
    

saturated uint16 NOT_FOUND = 2


    
    
    

saturated uint16 IO_ERROR = 5


    
    
    

saturated uint16 ACCESS_DENIED = 13


    
    
    

saturated uint16 IS_DIRECTORY = 21

I.e., attempted read/write on a path that points to a directory

saturated uint16 INVALID_VALUE = 22

E.g., file name is not valid for the target file system

saturated uint16 FILE_TOO_LARGE = 27


    
    
    

saturated uint16 OUT_OF_SPACE = 28


    
    
    

saturated uint16 NOT_SUPPORTED = 38


    
    
    

    
    
    

    
    
    

uavcan.file.Modify (v1.0) [service] [fixed port-ID 407]

Manipulate a remote file system entry. Applies to files, directories, and links alike.
If the remote entry is a directory, all nested entries will be affected, too.

The server should perform all operations atomically, unless atomicity is not supported by
the underlying file system.

Atomic copying can be effectively employed by remote nodes before reading or after writing
the file to minimize the possibility of race conditions.
For example, before reading a large file from the server, the cilent might opt to create
a temporary copy of it first, then read the copy, and delete it upon completion. Likewise,
a similar strategy can be employed for writing, where the file is first written at a
temporary location, and then moved to its final destination. These approaches, however,
may lead to creation of dangling temporary files if the client failed to dispose of them
properly, so that risk should be taken into account.

Move/Copy
  Specify the source path and the destination path.
  If the source does not exist, the operation will fail.
  Set the preserve_source flag to copy rather than move.
  If the destination exists and overwrite_destination is not set, the operation will fail.
  If the target path includes non-existent directories, they will be created (like "mkdir -p").

Touch
  Specify the destination path and make the source path empty.
  If the path exists (file/directory/link), its modification time will be updated.
  If the path does not exist, an empty file will be created.
  If the target path includes non-existent directories, they will be created (like "mkdir -p").
  Flags are ignored.

Remove
  Specify the source path (file/directory/link) and make the destination path empty.
  Fails if the path does not exist.
  Flags are ignored.

uavcan.file.Modify.Request (v1.0) request [extent 4832 bytes]

saturated bool preserve_source [extent 1 bits]

Do not remove the source. Used to copy instead of moving.

saturated bool overwrite_destination [extent 1 bits]

If the destination exists, remove it beforehand.

void30 [extent 30 bits]


    
    
    




uavcan.file.Path (v1.0) source [extent 904 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

The maximum path length limit is chosen as a trade-off between compatibility with deep directory structures and
the worst-case transfer length. The limit is 112 bytes, which allows all transfers containing a single instance
of path and no other large data chunks to fit into two CAN FD frames.

saturated uint8[<=112] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 112


    
    
    

    
    
    




uavcan.file.Path (v1.0) destination [extent 904 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

The maximum path length limit is chosen as a trade-off between compatibility with deep directory structures and
the worst-case transfer length. The limit is 112 bytes, which allows all transfers containing a single instance
of path and no other large data chunks to fit into two CAN FD frames.

saturated uint8[<=112] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 112


    
    
    

    
    
    

    
    
    




uavcan.file.Modify.Response (v1.0) response [extent 416 bytes]

uavcan.file.Error (v1.0) error [extent 16 bytes]

Nested type.
Result of a file system operation.

saturated uint16 value [extent 2.0 bytes]


    
    
    

saturated uint16 OK = 0


    
    
    

saturated uint16 UNKNOWN_ERROR = 65535


    
    
    

saturated uint16 NOT_FOUND = 2


    
    
    

saturated uint16 IO_ERROR = 5


    
    
    

saturated uint16 ACCESS_DENIED = 13


    
    
    

saturated uint16 IS_DIRECTORY = 21

I.e., attempted read/write on a path that points to a directory

saturated uint16 INVALID_VALUE = 22

E.g., file name is not valid for the target file system

saturated uint16 FILE_TOO_LARGE = 27


    
    
    

saturated uint16 OUT_OF_SPACE = 28


    
    
    

saturated uint16 NOT_SUPPORTED = 38


    
    
    

    
    
    

    
    
    

uavcan.file.Path (v2.0) [extent 2048 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

saturated uint8[<=255] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 255


    
    
    

uavcan.file.Path (v1.0) [extent 904 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

The maximum path length limit is chosen as a trade-off between compatibility with deep directory structures and
the worst-case transfer length. The limit is 112 bytes, which allows all transfers containing a single instance
of path and no other large data chunks to fit into two CAN FD frames.

saturated uint8[<=112] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 112


    
    
    

uavcan.file.Read (v1.1) [service] [fixed port-ID 408]

Read file from a remote node.

There are two possible outcomes of a successful call:
 1. Data array size equals its capacity. This means that the end of the file is not reached yet.
 2. Data array size is less than its capacity, possibly zero. This means that the end of the file is reached.

Thus, if the client needs to fetch the entire file, it should repeatedly call this service while increasing the
offset, until a non-full data array is returned.

If the object pointed by 'path' cannot be read (e.g. it is a directory or it does not exist), an appropriate error
code will be returned, and the data array will be empty.

It is easy to see that this protocol is prone to race conditions because the remote file can be modified
between read operations which might result in the client obtaining a damaged file. To combat this,
application designers are recommended to adhere to the following convention. Let every file whose integrity
is of interest have a hash or a digital signature, which is stored in an adjacent file under the same name
suffixed with the appropriate extension according to the type of hash or digital signature used.
For example, let there be file "image.bin", integrity of which shall be ensured by the client upon downloading.
Suppose that the file is hashed using SHA-256, so the appropriate file extension for the hash would be
".sha256". Following this convention, the hash of "image.bin" would be stored in "image.bin.sha256".
After downloading the file, the client would read the hash (being small, the hash can be read in a single
request) and check it against a locally computed value. Some servers may opt to generate such hash files
automatically as necessary; for example, if such file is requested but it does not exist, the server would
compute the necessary signature or hash (the type of hash/signature can be deduced from the requested file
extension) and return it as if the file existed. Obviously, this would be impractical for very large files;
in that case, hash/signature should be pre-computed and stored in a real file. If this approach is followed,
implementers are advised to use only SHA-256 for hashing, in order to reduce the number of fielded
incompatible implementations.

uavcan.file.Read.Request (v1.1) request [extent 2432 bytes]

truncated uint40 offset [extent 5.0 bytes]


    
    
    




uavcan.file.Path (v2.0) path [extent 2048 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

saturated uint8[<=255] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 255


    
    
    

    
    
    

    
    
    




uavcan.file.Read.Response (v1.1) response [extent 2432 bytes]

uavcan.file.Error (v1.0) error [extent 16 bytes]

Nested type.
Result of a file system operation.

saturated uint16 value [extent 2.0 bytes]


    
    
    

saturated uint16 OK = 0


    
    
    

saturated uint16 UNKNOWN_ERROR = 65535


    
    
    

saturated uint16 NOT_FOUND = 2


    
    
    

saturated uint16 IO_ERROR = 5


    
    
    

saturated uint16 ACCESS_DENIED = 13


    
    
    

saturated uint16 IS_DIRECTORY = 21

I.e., attempted read/write on a path that points to a directory

saturated uint16 INVALID_VALUE = 22

E.g., file name is not valid for the target file system

saturated uint16 FILE_TOO_LARGE = 27


    
    
    

saturated uint16 OUT_OF_SPACE = 28


    
    
    

saturated uint16 NOT_SUPPORTED = 38


    
    
    

    
    
    




uavcan.primitive.Unstructured (v1.0) data [extent 2064 bytes]

An unstructured collection of bytes, e.g., raw binary image.

saturated uint8[<=256] value

saturated uint8


    
    
    

    
    
    

    
    
    

uavcan.file.Read (v1.0) [service] [fixed port-ID 408]

Read file from a remote node.

There are two possible outcomes of a successful call:
 1. Data array size equals its capacity. This means that the end of the file is not reached yet.
 2. Data array size is less than its capacity, possibly zero. This means that the end of the file is reached.

Thus, if the client needs to fetch the entire file, it should repeatedly call this service while increasing the
offset, until a non-full data array is returned.

If the object pointed by 'path' cannot be read (e.g. it is a directory or it does not exist), an appropriate error
code will be returned, and the data array will be empty.

It is easy to see that this protocol is prone to race conditions because the remote file can be modified
between read operations which might result in the client obtaining a damaged file. To combat this,
application designers are recommended to adhere to the following convention. Let every file whose integrity
is of interest have a hash or a digital signature, which is stored in an adjacent file under the same name
suffixed with the appropriate extension according to the type of hash or digital signature used.
For example, let there be file "image.bin", integrity of which shall be ensured by the client upon downloading.
Suppose that the file is hashed using SHA-256, so the appropriate file extension for the hash would be
".sha256". Following this convention, the hash of "image.bin" would be stored in "image.bin.sha256".
After downloading the file, the client would read the hash (being small, the hash can be read in a single
request) and check it against a locally computed value. Some servers may opt to generate such hash files
automatically as necessary; for example, if such file is requested but it does not exist, the server would
compute the necessary signature or hash (the type of hash/signature can be deduced from the requested file
extension) and return it as if the file existed. Obviously, this would be impractical for very large files;
in that case, hash/signature should be pre-computed and stored in a real file. If this approach is followed,
implementers are advised to use only SHA-256 for hashing, in order to reduce the number of fielded
incompatible implementations.

uavcan.file.Read.Request (v1.0) request [extent 2432 bytes]

truncated uint40 offset [extent 5.0 bytes]


    
    
    




uavcan.file.Path (v1.0) path [extent 904 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

The maximum path length limit is chosen as a trade-off between compatibility with deep directory structures and
the worst-case transfer length. The limit is 112 bytes, which allows all transfers containing a single instance
of path and no other large data chunks to fit into two CAN FD frames.

saturated uint8[<=112] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 112


    
    
    

    
    
    

    
    
    




uavcan.file.Read.Response (v1.0) response [extent 2432 bytes]

uavcan.file.Error (v1.0) error [extent 16 bytes]

Nested type.
Result of a file system operation.

saturated uint16 value [extent 2.0 bytes]


    
    
    

saturated uint16 OK = 0


    
    
    

saturated uint16 UNKNOWN_ERROR = 65535


    
    
    

saturated uint16 NOT_FOUND = 2


    
    
    

saturated uint16 IO_ERROR = 5


    
    
    

saturated uint16 ACCESS_DENIED = 13


    
    
    

saturated uint16 IS_DIRECTORY = 21

I.e., attempted read/write on a path that points to a directory

saturated uint16 INVALID_VALUE = 22

E.g., file name is not valid for the target file system

saturated uint16 FILE_TOO_LARGE = 27


    
    
    

saturated uint16 OUT_OF_SPACE = 28


    
    
    

saturated uint16 NOT_SUPPORTED = 38


    
    
    

    
    
    




saturated uint8[<=256] data

saturated uint8


    
    
    

    
    
    

uavcan.file.Write (v1.1) [service] [fixed port-ID 409]

Write into a remote file.
The server shall place the contents of the field 'data' into the file pointed by 'path' at the offset specified by
the field 'offset'.

When writing a file, the client should repeatedly call this service with data while advancing the offset until the
file is written completely. When the write sequence is completed, the client shall call the service one last time,
with the offset set to the size of the file and with the data field empty, which will signal the server that the
transfer is finished.

When the write operation is complete, the server shall truncate the resulting file past the specified offset.

uavcan.file.Write.Request (v1.1) request [extent 4832 bytes]

truncated uint40 offset [extent 5.0 bytes]


    
    
    




uavcan.file.Path (v2.0) path [extent 2048 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

saturated uint8[<=255] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 255


    
    
    

    
    
    




uavcan.primitive.Unstructured (v1.0) data [extent 2064 bytes]

An unstructured collection of bytes, e.g., raw binary image.

saturated uint8[<=256] value

saturated uint8


    
    
    

    
    
    

    
    
    




uavcan.file.Write.Response (v1.1) response [extent 416 bytes]

uavcan.file.Error (v1.0) error [extent 16 bytes]

Nested type.
Result of a file system operation.

saturated uint16 value [extent 2.0 bytes]


    
    
    

saturated uint16 OK = 0


    
    
    

saturated uint16 UNKNOWN_ERROR = 65535


    
    
    

saturated uint16 NOT_FOUND = 2


    
    
    

saturated uint16 IO_ERROR = 5


    
    
    

saturated uint16 ACCESS_DENIED = 13


    
    
    

saturated uint16 IS_DIRECTORY = 21

I.e., attempted read/write on a path that points to a directory

saturated uint16 INVALID_VALUE = 22

E.g., file name is not valid for the target file system

saturated uint16 FILE_TOO_LARGE = 27


    
    
    

saturated uint16 OUT_OF_SPACE = 28


    
    
    

saturated uint16 NOT_SUPPORTED = 38


    
    
    

    
    
    

    
    
    

uavcan.file.Write (v1.0) [service] [fixed port-ID 409]

Write into a remote file.
The server shall place the contents of the field 'data' into the file pointed by 'path' at the offset specified by
the field 'offset'.

When writing a file, the client should repeatedly call this service with data while advancing the offset until the
file is written completely. When the write sequence is completed, the client shall call the service one last time,
with the offset set to the size of the file and with the data field empty, which will signal the server that the
transfer is finished.

When the write operation is complete, the server shall truncate the resulting file past the specified offset.

uavcan.file.Write.Request (v1.0) request [extent 4832 bytes]

truncated uint40 offset [extent 5.0 bytes]


    
    
    




uavcan.file.Path (v1.0) path [extent 904 bytes]

Nested type.
A file system path encoded in UTF8. The only valid separator is the forward slash "/".
A single slash ("/") refers to the root directory (the location of which is defined by the server).
Relative references (e.g. "..") are not defined and not permitted (although this may change in the future).
Conventions (not enforced):
  - A path pointing to a file or a link to file should not end with a separator.
  - A path pointing to a directory or to a link to directory should end with a separator.

The maximum path length limit is chosen as a trade-off between compatibility with deep directory structures and
the worst-case transfer length. The limit is 112 bytes, which allows all transfers containing a single instance
of path and no other large data chunks to fit into two CAN FD frames.

saturated uint8[<=112] path

saturated uint8


    
    
    

saturated uint8 SEPARATOR = 47


    
    
    

saturated uint8 MAX_LENGTH = 112


    
    
    

    
    
    




saturated uint8[<=192] data

saturated uint8

192 = 128 + 64; the write protocol permits usage of smaller chunks.

    
    
    




uavcan.file.Write.Response (v1.0) response [extent 416 bytes]

uavcan.file.Error (v1.0) error [extent 16 bytes]

Nested type.
Result of a file system operation.

saturated uint16 value [extent 2.0 bytes]


    
    
    

saturated uint16 OK = 0


    
    
    

saturated uint16 UNKNOWN_ERROR = 65535


    
    
    

saturated uint16 NOT_FOUND = 2


    
    
    

saturated uint16 IO_ERROR = 5


    
    
    

saturated uint16 ACCESS_DENIED = 13


    
    
    

saturated uint16 IS_DIRECTORY = 21

I.e., attempted read/write on a path that points to a directory

saturated uint16 INVALID_VALUE = 22

E.g., file name is not valid for the target file system

saturated uint16 FILE_TOO_LARGE = 27


    
    
    

saturated uint16 OUT_OF_SPACE = 28


    
    
    

saturated uint16 NOT_SUPPORTED = 38


    
    
    

    
    
    

    
    
    

uavcan.time

uavcan.time.GetSynchronizationMasterInfo (v0.1) [service] [fixed port-ID 510]

Every node that acts as a time synchronization master, or is capable of acting as such,
should support this service.
Its objective is to provide information about which time system is currently used in the network.

Once a time system is chosen, it cannot be changed as long as at least one node on the network is running.
In other words, the time system cannot be changed while the network is operating.
An implication of this is that if there are redundant time synchronization masters, they all shall
use the same time system always.

uavcan.time.GetSynchronizationMasterInfo.Request (v0.1) request [extent 416 bytes]

(data type is empty)


    
    
    




uavcan.time.GetSynchronizationMasterInfo.Response (v0.1) response [extent 1568 bytes]

saturated float32 error_variance [extent 4.0 bytes]

[second^2]
Error variance, in second^2, of the time value reported by this master.
This value is allowed to change freely while the master is running.
For example, if the master's own clock is synchronized with a GNSS, the error variance is expected to increase
as signal reception deteriorates. If the signal is lost, this value is expected to grow steadily, the rate of
growth would be dependent on the quality of the time keeping hardware available locally (bad hardware yields
faster growth). Once the signal is regained, this value would drop back to nominal.

uavcan.time.TimeSystem (v0.1) time_system [extent 8 bytes]

Time system enumeration.
The time system shall be the same for all masters in the network.
It cannot be changed while the network is running.

truncated uint4 value [extent 4 bits]


    
    
    

saturated uint4 MONOTONIC_SINCE_BOOT = 0

Monotonic time since boot.
Monotonic time is a time reference that doesn't change rate or make leaps.

saturated uint4 TAI = 1

International Atomic Time; https://en.wikipedia.org/wiki/International_Atomic_Time.
The timestamp value contains the number of microseconds elapsed since 1970-01-01T00:00:00Z TAI.
TAI is always a fixed integer number of seconds ahead of GPS time.
Systems that use GPS time as a reference should convert that to TAI by adding the fixed difference.
GPS time is not supported for reasons of consistency across different positioning systems and applications.

saturated uint4 APPLICATION_SPECIFIC = 15

Application-specific time system of unknown properties.
Time system currently in use by the master.
Cannot be changed while the network is operating.

uavcan.time.TAIInfo (v0.1) tai_info [extent 16 bytes]

This data types defines constants and runtime values pertaining to the International Atomic Time, also known as TAI.
See https://en.wikipedia.org/wiki/International_Atomic_Time.

The relationship between the three major time systems -- TAI, GPS, and UTC -- is as follows:

  TAI = GPS + 19 seconds
  TAI = UTC + LS + 10 seconds

Where "LS" is the current number of leap seconds: https://en.wikipedia.org/wiki/Leap_second.

UAVCAN applications should only rely on TAI whenever a global time system is needed.
GPS time is strongly discouraged for reasons of consistency across different positioning systems and applications.

saturated uint10 difference_tai_minus_utc [extent 10 bits]

The current difference between TAI and UTC, if known. If unknown, set to zero.

This value may change states between known and unknown while the master is running,
depending on its ability to obtain robust values from external sources.

This value may change twice a year, possibly while the system is running; https://en.wikipedia.org/wiki/Leap_second.
Since the rotation of Earth is decelerating, this value may only be positive. Do not use outside Earth.

For reference, here is the full list of recorded TAI-UTC difference values, valid at the time of writing:

    Date     | TAI-UTC difference [second]
   ----------|-----------------------------
    Jan 1972 | 10
    Jul 1972 | 11
    Jan 1973 | 12
    Jan 1974 | 13
    Jan 1975 | 14
    Jan 1976 | 15
    Jan 1977 | 16
    Jan 1978 | 17
    Jan 1979 | 18
    Jan 1980 | 19
    Jul 1981 | 20
    Jul 1982 | 21
    Jul 1983 | 22
    Jul 1985 | 23
    Jan 1988 | 24
    Jan 1990 | 25
    Jan 1991 | 26
    Jul 1992 | 27
    Jul 1993 | 28
    Jul 1994 | 29
    Jan 1996 | 30
    Jul 1997 | 31
    Jan 1999 | 32
    Jan 2006 | 33
    Jan 2009 | 34
    Jul 2012 | 35
    Jul 2015 | 36
    Jan 2017 | 37

As of 2020, the future of the leap second and the relation between UTC and TAI remains uncertain.

saturated uint8 DIFFERENCE_TAI_MINUS_GPS = 19

[second]
The fixed difference, in seconds, between TAI and GPS time. Does not change ever.
Systems that use GPS time as a reference should convert that to TAI by adding this difference.

saturated uint10 DIFFERENCE_TAI_MINUS_UTC_UNKNOWN = 0


    
    
    
Actual information about TAI provided by this master, if supported.
The fields in this data type are optional.

    
    
    

uavcan.time.Synchronization (v1.0) [extent 56 bytes] [fixed port-ID 7168]

Network-wide time synchronization message.
Any node that publishes timestamped data should use this time reference.

The time synchronization algorithm is based on the work
"Implementing a Distributed High-Resolution Real-Time Clock using the CAN-Bus" by M. Gergeleit and H. Streich.
The general idea of the algorithm is to have one or more nodes that periodically publish a message of this type
containing the exact timestamp of the PREVIOUS transmission of this message.
A node that publishes this message periodically is referred to as a "time synchronization master",
whereas nodes that synchronize their clocks with the master are referred to as "time synchronization slaves".

Once a time base is chosen, it cannot be changed as long as at least one node on the network is running.
In other words, the time base cannot be changed while the network is operating.
An implication of this is that if there are redundant time synchronization masters, they all shall
use the same time base.

The resolution is dependent on the transport and its physical layer, but generally it can be assumed
to be close to one bit time but not better than one microsecond (e.g., for a 500 kbps CAN bus,
the resolution is two microseconds). The maximum accuracy is achievable only if the transport layer
supports precise timestamping in hardware; otherwise, the accuracy may be degraded.

This algorithm allows the slaves to precisely estimate the difference (i.e., phase error) between their
local time and the master clock they are synchronized with. The algorithm for clock rate adjustment
is entirely implementation-defined (for example, a simple phase-locked loop or a PID rate controller can be used).

The network can accommodate more than one time synchronization master for purposes of increased reliability:
if one master fails, the others will continue to provide the network with accurate and consistent time information.
The risk of undesirable transients while the masters are swapped is mitigated by the requirement that all masters
use the same time base at all times, as described above.

The master with the lowest node-ID is called the "dominant master". The current dominant master ceases to be one
if its last synchronization message was published more than 3X seconds ago, where X is the time interval
between the last and the previous messages published by it. In this case, the master with the next-higher node-ID
will take over as the new dominant master. The current dominant master will be displaced immediately as soon as
the first message from a new master with a lower node-ID is seen on the bus.

In the presence of multiple masters, they all publish their time synchronization messages concurrently at all times.
The slaves shall listen to the master with the lowest node-ID and ignore the messages published by masters with
higher node-ID values.

Currently, there is a work underway to develop and validate a highly robust fault-operational time synchronization
algorithm where the slaves select the median time base among all available masters rather than using only the
one with the lowest node-ID value. Follow the work at https://forum.uavcan.org. When complete, this algorithm
will be added in a backward-compatible way as an option for high-reliability systems.

For networks with redundant transports, the timestamp value published on different interfaces is likely to be
different, since different transports are generally not expected to be synchronized. Synchronization slaves
are allowed to use any of the available redundant interfaces for synchronization at their discretion.

The following pseudocode shows the logic of a time synchronization master. This example assumes that the master
does not need to synchronize its own clock with other masters on the bus, which is the case if the current master
is the only master, or if all masters synchronize their clocks with a robust external source, e.g., a GNSS system.
If several masters need to synchronize their clock through the bus, their logic will be extended with the
slave-side behavior explained later.

      // State variables
      transfer_id := 0;
      previous_tx_timestamp_per_iface[NUM_IFACES] := {0};

      // This function publishes a message with a specified transfer-ID using only one transport interface.
      function publishMessage(transfer_id, iface_index, msg);

      // This callback is invoked when the transport layer completes the transmission of a time sync message.
      // Observe that the time sync message is always a single-frame message by virtue of its small size.
      // The tx_timestamp argument contains the exact timestamp when the transport frame was delivered to the bus.
      function messageTxTimestampCallback(iface_index, tx_timestamp)
      {
          previous_tx_timestamp_per_iface[iface_index] := tx_timestamp;
      }

      // Publishes messages of type uavcan.time.Synchronization to each available transport interface.
      // It is assumed that this function is invoked with a fixed frequency not lower than 1 hertz.
      function publishTimeSync()
      {
          for (i := 0; i < NUM_IFACES; i++)
          {
              message := uavcan.time.Synchronization();
              message.previous_transmission_timestamp_usec := previous_tx_timestamp_per_iface[i];
              previous_tx_timestamp_per_iface[i] := 0;
              publishMessage(transfer_id, i, message);
          }
          transfer_id++; // Overflow shall be handled correctly
      }

(end of the master-side logic pseudocode)
The following pseudocode describes the logic of a time synchronization slave.

      // State variables:
      previous_rx_real_timestamp := 0;            // This clock is being synchronized
      previous_rx_monotonic_timestamp := 0;       // Monotonic time -- doesn't leap or change rate
      previous_transfer_id := 0;
      state := STATE_UPDATE;                      // Variants: STATE_UPDATE, STATE_ADJUST
      master_node_id := -1;                       // Invalid value
      iface_index := -1;                          // Invalid value

      // This function adjusts the local clock by the specified amount
      function adjustLocalTime(phase_error);

      function adjust(message)
      {
          // Clock adjustment will be performed every second message
          local_time_phase_error := previous_rx_real_timestamp - msg.previous_transmission_timestamp_microsecond;
          adjustLocalTime(local_time_phase_error);
          state := STATE_UPDATE;
      }

      function update(message)
      {
          // A message is assumed to have two timestamps:
          //   Real      - sampled from the clock that is being synchronized
          //   Monotonic - clock that never leaps and never changes rate
          previous_rx_real_timestamp := message.rx_real_timestamp;
          previous_rx_monotonic_timestamp := message.rx_monotonic_timestamp;
          master_node_id := message.source_node_id;
          iface_index := message.iface_index;
          previous_transfer_id := message.transfer_id;
          state := STATE_ADJUST;
      }

      // Accepts the message of type uavcan.time.Synchronization
      function handleReceivedTimeSyncMessage(message)
      {
          time_since_previous_msg := message.monotonic_timestamp - previous_rx_monotonic_timestamp;

          needs_init := (master_node_id < 0) or (iface_index < 0);
          switch_master := message.source_node_id < master_node_id;

          // The value publisher_timeout is computed as described in the specification (3x interval)
          publisher_timed_out := time_since_previous_msg > publisher_timeout;

          if (needs_init or switch_master or publisher_timed_out)
          {
              update(message);
          }
          else if ((message.iface_index == iface_index) and (message.source_node_id == master_node_id))
          {
              // Revert the state to STATE_UPDATE if needed
              if (state == STATE_ADJUST)
              {
                  msg_invalid := message.previous_transmission_timestamp_microsecond == 0;
                  // Overflow shall be handled correctly
                  wrong_tid := message.transfer_id != (previous_transfer_id + 1);
                  wrong_timing := time_since_previous_msg > MAX_PUBLICATION_PERIOD;
                  if (msg_invalid or wrong_tid or wrong_timing)
                  {
                      state := STATE_UPDATE;
                  }
              }
              // Handle the current state
              if (state == STATE_ADJUST)
              {
                  adjust(message);
              }
              else
              {
                  update(message);
              }
          }   // else ignore
      }

(end of the slave-side logic pseudocode)

truncated uint56 previous_transmission_timestamp_microsecond [extent 7.0 bytes]

The time when the PREVIOUS message was transmitted from the current publisher, in microseconds.
If this message is published for the first time, or if the previous transmission was more than
one second ago, this field shall be zero.

saturated uint8 MAX_PUBLICATION_PERIOD = 1

[second]
Publication period limits.
A master should not change its publication period while running.

saturated uint8 PUBLISHER_TIMEOUT_PERIOD_MULTIPLIER = 3

Synchronization slaves should normally switch to a new master if the current master was silent
for thrice the interval between the reception of the last two messages published by it.
For example, imagine that the last message was received at the time X, and the previous message
was received at the time (X - 0.5 seconds); the period is 0.5 seconds, and therefore the publisher
timeout is (0.5 seconds * 3) = 1.5 seconds. If there was no message from the current master in
this amount of time, all slaves will synchronize with another master with the next-higher node-ID.

uavcan.time.SynchronizedTimestamp (v1.0) [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

uavcan.time.TAIInfo (v0.1) [extent 16 bytes]

This data types defines constants and runtime values pertaining to the International Atomic Time, also known as TAI.
See https://en.wikipedia.org/wiki/International_Atomic_Time.

The relationship between the three major time systems -- TAI, GPS, and UTC -- is as follows:

  TAI = GPS + 19 seconds
  TAI = UTC + LS + 10 seconds

Where "LS" is the current number of leap seconds: https://en.wikipedia.org/wiki/Leap_second.

UAVCAN applications should only rely on TAI whenever a global time system is needed.
GPS time is strongly discouraged for reasons of consistency across different positioning systems and applications.

saturated uint10 difference_tai_minus_utc [extent 10 bits]

The current difference between TAI and UTC, if known. If unknown, set to zero.

This value may change states between known and unknown while the master is running,
depending on its ability to obtain robust values from external sources.

This value may change twice a year, possibly while the system is running; https://en.wikipedia.org/wiki/Leap_second.
Since the rotation of Earth is decelerating, this value may only be positive. Do not use outside Earth.

For reference, here is the full list of recorded TAI-UTC difference values, valid at the time of writing:

    Date     | TAI-UTC difference [second]
   ----------|-----------------------------
    Jan 1972 | 10
    Jul 1972 | 11
    Jan 1973 | 12
    Jan 1974 | 13
    Jan 1975 | 14
    Jan 1976 | 15
    Jan 1977 | 16
    Jan 1978 | 17
    Jan 1979 | 18
    Jan 1980 | 19
    Jul 1981 | 20
    Jul 1982 | 21
    Jul 1983 | 22
    Jul 1985 | 23
    Jan 1988 | 24
    Jan 1990 | 25
    Jan 1991 | 26
    Jul 1992 | 27
    Jul 1993 | 28
    Jul 1994 | 29
    Jan 1996 | 30
    Jul 1997 | 31
    Jan 1999 | 32
    Jan 2006 | 33
    Jan 2009 | 34
    Jul 2012 | 35
    Jul 2015 | 36
    Jan 2017 | 37

As of 2020, the future of the leap second and the relation between UTC and TAI remains uncertain.

saturated uint8 DIFFERENCE_TAI_MINUS_GPS = 19

[second]
The fixed difference, in seconds, between TAI and GPS time. Does not change ever.
Systems that use GPS time as a reference should convert that to TAI by adding this difference.

saturated uint10 DIFFERENCE_TAI_MINUS_UTC_UNKNOWN = 0


    
    
    

uavcan.time.TimeSystem (v0.1) [extent 8 bytes]

Time system enumeration.
The time system shall be the same for all masters in the network.
It cannot be changed while the network is running.

truncated uint4 value [extent 4 bits]


    
    
    

saturated uint4 MONOTONIC_SINCE_BOOT = 0

Monotonic time since boot.
Monotonic time is a time reference that doesn't change rate or make leaps.

saturated uint4 TAI = 1

International Atomic Time; https://en.wikipedia.org/wiki/International_Atomic_Time.
The timestamp value contains the number of microseconds elapsed since 1970-01-01T00:00:00Z TAI.
TAI is always a fixed integer number of seconds ahead of GPS time.
Systems that use GPS time as a reference should convert that to TAI by adding the fixed difference.
GPS time is not supported for reasons of consistency across different positioning systems and applications.

saturated uint4 APPLICATION_SPECIFIC = 15

Application-specific time system of unknown properties.

uavcan.node

uavcan.node.ExecuteCommand (v1.1) [service] [fixed port-ID 435]

Instructs the server node to execute or commence execution of a simple predefined command.
All standard commands are optional; i.e., not guaranteed to be supported by all nodes.

uavcan.node.ExecuteCommand.Request (v1.1) request [extent 2432 bytes]

saturated uint16 command [extent 2.0 bytes]

Standard pre-defined commands are at the top of the range (defined below).
Vendors can define arbitrary, vendor-specific commands in the bottom part of the range (starting from zero).
Vendor-specific commands shall not use identifiers above 32767.

saturated uint8[<=255] parameter

saturated uint8

A string parameter supplied to the command. The format and interpretation is command-specific.
The standard commands do not use this field (ignore it), excepting the following:
  - COMMAND_BEGIN_SOFTWARE_UPDATE

saturated uint16 COMMAND_RESTART = 65535

Reboot the node.
Note that some standard commands may or may not require a restart in order to take effect; e.g., factory reset.

saturated uint16 COMMAND_POWER_OFF = 65534

Shut down the node; further access will not be possible until the power is turned back on.

saturated uint16 COMMAND_BEGIN_SOFTWARE_UPDATE = 65533

Begin the software update process using uavcan.file.Read. This command makes use of the "parameter" field below.
The parameter contains the path to the new software image file to be downloaded by the server from the client
using the standard service uavcan.file.Read. Observe that this operation swaps the roles of the client and
the server.

Upon reception of this command, the server (updatee) will evaluate whether it is possible to begin the
software update process. If that is deemed impossible, the command will be rejected with one of the
error codes defined in the response section of this definition (e.g., BAD_STATE if the node is currently
on-duty and a sudden interruption of its activities is considered unsafe, and so on).
If an update process is already underway, the updatee should abort the process and restart with the new file,
unless the updatee can determine that the specified file is the same file that is already being downloaded,
in which case it is allowed to respond SUCCESS and continue the old update process.
If there are no other conditions precluding the requested update, the updatee will return a SUCCESS and
initiate the file transfer process by invoking the standard service uavcan.file.Read repeatedly until the file
is transferred fully (please refer to the documentation for that data type for more information about its usage).

While the software is being updated, the updatee should set its mode (the field "mode" in uavcan.node.Heartbeat)
to MODE_SOFTWARE_UPDATE. Please refer to the documentation for uavcan.node.Heartbeat for more information.

It is recognized that most systems will have to interrupt their normal services to perform the software update
(unless some form of software hot swapping is implemented, as is the case in some high-availability systems).

Microcontrollers that are requested to update their firmware may need to stop execution of their current firmware
and start the embedded bootloader (although other approaches are possible as well). In that case,
while the embedded bootloader is running, the mode reported via the message uavcan.node.Heartbeat should be
MODE_SOFTWARE_UPDATE as long as the bootloader is runing, even if no update-related activities
are currently underway. For example, if the update process failed and the bootloader cannot load the software,
the same mode MODE_SOFTWARE_UPDATE will be reported.
It is also recognized that in a microcontroller setting, the application that served the update request will have
to pass the update-related metadata (such as the node-ID of the server and the firmware image file path) to
the embedded bootloader. The tactics of that transaction lie outside of the scope of this specification.

saturated uint16 COMMAND_FACTORY_RESET = 65532

Return the node's configuration back to the factory default settings (may require restart).
Due to the uncertainty whether a restart is required, generic interfaces should always force a restart.

saturated uint16 COMMAND_EMERGENCY_STOP = 65531

Cease activities immediately, enter a safe state until restarted.
Further operation may no longer be possible until a restart command is executed.

saturated uint16 COMMAND_STORE_PERSISTENT_STATES = 65530

This command instructs the node to store the current configuration parameter values and other persistent states
to the non-volatile storage. Nodes are allowed to manage persistent states automatically, obviating the need for
this command by committing all such data to the non-volatile memory automatically as necessary. However, some
nodes may lack this functionality, in which case this parameter should be used. Generic interfaces should always
invoke this command in order to ensure that the data is stored even if the node doesn't implement automatic
persistence management.

    
    
    




uavcan.node.ExecuteCommand.Response (v1.1) response [extent 416 bytes]

saturated uint8 status [extent 1.0 bytes]

The result of the request.

saturated uint8 STATUS_SUCCESS = 0

Started or executed successfully

saturated uint8 STATUS_FAILURE = 1

Could not start or the desired outcome could not be reached

saturated uint8 STATUS_NOT_AUTHORIZED = 2

Denied due to lack of authorization

saturated uint8 STATUS_BAD_COMMAND = 3

The requested command is not known or not supported

saturated uint8 STATUS_BAD_PARAMETER = 4

The supplied parameter cannot be used with the selected command

saturated uint8 STATUS_BAD_STATE = 5

The current state of the node does not permit execution of this command

saturated uint8 STATUS_INTERNAL_ERROR = 6

The operation should have succeeded but an unexpected failure occurred

    
    
    

uavcan.node.ExecuteCommand (v1.0) [service] [fixed port-ID 435]

Instructs the server node to execute or commence execution of a simple predefined command.
All standard commands are optional; i.e., not guaranteed to be supported by all nodes.

uavcan.node.ExecuteCommand.Request (v1.0) request [extent 2432 bytes]

saturated uint16 command [extent 2.0 bytes]

Standard pre-defined commands are at the top of the range (defined below).
Vendors can define arbitrary, vendor-specific commands in the bottom part of the range (starting from zero).
Vendor-specific commands shall not use identifiers above 32767.

saturated uint8[<=112] parameter

saturated uint8

A string parameter supplied to the command. The format and interpretation is command-specific.
The standard commands do not use this field (ignore it), excepting the following:
  - COMMAND_BEGIN_SOFTWARE_UPDATE

saturated uint16 COMMAND_RESTART = 65535

Reboot the node.
Note that some standard commands may or may not require a restart in order to take effect; e.g., factory reset.

saturated uint16 COMMAND_POWER_OFF = 65534

Shut down the node; further access will not be possible until the power is turned back on.

saturated uint16 COMMAND_BEGIN_SOFTWARE_UPDATE = 65533

Begin the software update process using uavcan.file.Read. This command makes use of the "parameter" field below.
The parameter contains the path to the new software image file to be downloaded by the server from the client
using the standard service uavcan.file.Read. Observe that this operation swaps the roles of the client and
the server.

Upon reception of this command, the server (updatee) will evaluate whether it is possible to begin the
software update process. If that is deemed impossible, the command will be rejected with one of the
error codes defined in the response section of this definition (e.g., BAD_STATE if the node is currently
on-duty and a sudden interruption of its activities is considered unsafe, and so on).
If an update process is already underway, the updatee should abort the process and restart with the new file,
unless the updatee can determine that the specified file is the same file that is already being downloaded,
in which case it is allowed to respond SUCCESS and continue the old update process.
If there are no other conditions precluding the requested update, the updatee will return a SUCCESS and
initiate the file transfer process by invoking the standard service uavcan.file.Read repeatedly until the file
is transferred fully (please refer to the documentation for that data type for more information about its usage).

While the software is being updated, the updatee should set its mode (the field "mode" in uavcan.node.Heartbeat)
to MODE_SOFTWARE_UPDATE. Please refer to the documentation for uavcan.node.Heartbeat for more information.

It is recognized that most systems will have to interrupt their normal services to perform the software update
(unless some form of software hot swapping is implemented, as is the case in some high-availability systems).

Microcontrollers that are requested to update their firmware may need to stop execution of their current firmware
and start the embedded bootloader (although other approaches are possible as well). In that case,
while the embedded bootloader is running, the mode reported via the message uavcan.node.Heartbeat should be
MODE_SOFTWARE_UPDATE as long as the bootloader is runing, even if no update-related activities
are currently underway. For example, if the update process failed and the bootloader cannot load the software,
the same mode MODE_SOFTWARE_UPDATE will be reported.
It is also recognized that in a microcontroller setting, the application that served the update request will have
to pass the update-related metadata (such as the node-ID of the server and the firmware image file path) to
the embedded bootloader. The tactics of that transaction lie outside of the scope of this specification.

saturated uint16 COMMAND_FACTORY_RESET = 65532

Return the node's configuration back to the factory default settings (may require restart).
Due to the uncertainty whether a restart is required, generic interfaces should always force a restart.

saturated uint16 COMMAND_EMERGENCY_STOP = 65531

Cease activities immediately, enter a safe state until restarted.
Further operation may no longer be possible until a restart command is executed.

saturated uint16 COMMAND_STORE_PERSISTENT_STATES = 65530

This command instructs the node to store the current configuration parameter values and other persistent states
to the non-volatile storage. Nodes are allowed to manage persistent states automatically, obviating the need for
this command by committing all such data to the non-volatile memory automatically as necessary. However, some
nodes may lack this functionality, in which case this parameter should be used. Generic interfaces should always
invoke this command in order to ensure that the data is stored even if the node doesn't implement automatic
persistence management.

    
    
    




uavcan.node.ExecuteCommand.Response (v1.0) response [extent 416 bytes]

saturated uint8 status [extent 1.0 bytes]

The result of the request.

saturated uint8 STATUS_SUCCESS = 0

Started or executed successfully

saturated uint8 STATUS_FAILURE = 1

Could not start or the desired outcome could not be reached

saturated uint8 STATUS_NOT_AUTHORIZED = 2

Denied due to lack of authorization

saturated uint8 STATUS_BAD_COMMAND = 3

The requested command is not known or not supported

saturated uint8 STATUS_BAD_PARAMETER = 4

The supplied parameter cannot be used with the selected command

saturated uint8 STATUS_BAD_STATE = 5

The current state of the node does not permit execution of this command

saturated uint8 STATUS_INTERNAL_ERROR = 6

The operation should have succeeded but an unexpected failure occurred

    
    
    

uavcan.node.GetInfo (v1.0) [service] [fixed port-ID 430]

Full node info request.
All of the returned information shall be static (unchanged) while the node is running.
It is highly recommended to support this service on all nodes.

uavcan.node.GetInfo.Request (v1.0) request [extent 0 bytes]

(data type is empty)


    
    
    




uavcan.node.GetInfo.Response (v1.0) response [extent 3616 bytes]

uavcan.node.Version (v1.0) protocol_version [extent 16 bytes]

A shortened semantic version representation: only major and minor.
The protocol generally does not concern itself with the patch version.

saturated uint8 major [extent 1.0 bytes]


    
    
    

saturated uint8 minor [extent 1.0 bytes]


    
    
    
The UAVCAN protocol version implemented on this node, both major and minor.
Not to be changed while the node is running.

uavcan.node.Version (v1.0) hardware_version [extent 16 bytes]

A shortened semantic version representation: only major and minor.
The protocol generally does not concern itself with the patch version.

saturated uint8 major [extent 1.0 bytes]


    
    
    

saturated uint8 minor [extent 1.0 bytes]


    
    
    

    
    
    




uavcan.node.Version (v1.0) software_version [extent 16 bytes]

A shortened semantic version representation: only major and minor.
The protocol generally does not concern itself with the patch version.

saturated uint8 major [extent 1.0 bytes]


    
    
    

saturated uint8 minor [extent 1.0 bytes]


    
    
    
The version information shall not be changed while the node is running.
The correct hardware version shall be reported at all times, excepting software-only nodes, in which
case it should be set to zeros.
If the node is equipped with a UAVCAN-capable bootloader, the bootloader should report the software
version of the installed application, if there is any; if no application is found, zeros should be reported.

saturated uint64 software_vcs_revision_id [extent 8.0 bytes]

A version control system (VCS) revision number or hash. Not to be changed while the node is running.
For example, this field can be used for reporting the short git commit hash of the current
software revision.
Set to zero if not used.

saturated uint8[16] unique_id

saturated uint8

The unique-ID (UID) is a 128-bit long sequence that is likely to be globally unique per node.
The vendor shall ensure that the probability of a collision with any other node UID globally is negligibly low.
UID is defined once per hardware unit and should never be changed.
All zeros is not a valid UID.
If the node is equipped with a UAVCAN-capable bootloader, the bootloader shall use the same UID.

saturated uint8[<=50] name

saturated uint8

Human-readable non-empty ASCII node name. An empty name is not permitted.
The name shall not be changed while the node is running.
Allowed characters are: a-z (lowercase ASCII letters) 0-9 (decimal digits) . (dot) - (dash) _ (underscore).
Node name is a reversed Internet domain name (like Java packages), e.g. "com.manufacturer.project.product".

saturated uint64[<=1] software_image_crc

saturated uint64

The value of an arbitrary hash function applied to the software image. Not to be changed while the node is running.
This field can be used to detect whether the software or firmware running on the node is an exact
same version as a certain specific revision. This field provides a very strong identity guarantee,
unlike the version fields above, which can be the same for different builds of the software.
As can be seen from its definition, this field is optional.

The exact hash function and the methods of its application are implementation-defined.
However, implementations are recommended to adhere to the following guidelines, fully or partially:
  - The hash function should be CRC-64-WE.
  - The hash function should be applied to the entire application image padded to 8 bytes.
  - If the computed image CRC is stored within the software image itself, the value of
    the hash function becomes ill-defined, because it becomes recursively dependent on itself.
    In order to circumvent this issue, while computing or checking the CRC, its value stored
    within the image should be zeroed out.

saturated uint8[<=222] certificate_of_authenticity

saturated uint8

The certificate of authenticity (COA) of the node, 222 bytes max, optional. This field can be used for
reporting digital signatures (e.g., RSA-1776, or ECDSA if a higher degree of cryptographic strength is desired).
Leave empty if not used. Not to be changed while the node is running.

    
    
    

uavcan.node.GetTransportStatistics (v0.1) [service] [fixed port-ID 434]

Returns a set of general low-level transport statistical counters.
Servers are encouraged but not required to sample the data atomically.

uavcan.node.GetTransportStatistics.Request (v0.1) request [extent 0 bytes]

(data type is empty)


    
    
    




uavcan.node.GetTransportStatistics.Response (v0.1) response [extent 1568 bytes]

uavcan.node.IOStatistics (v0.1) transfer_statistics [extent 120 bytes]

A standard set of generic input/output statistical counters that generally should not overflow.
If a 40-bit counter is incremented every millisecond, it will overflow in ~35 years.
If an overflow occurs, the value will wrap over to zero.

The values should not be reset while the node is running.

truncated uint40 num_emitted [extent 5.0 bytes]

The number of successfully emitted entities.

truncated uint40 num_received [extent 5.0 bytes]

The number of successfully received entities.

truncated uint40 num_errored [extent 5.0 bytes]

How many errors have occurred.
The exact definition of "error" and how they are counted are implementation-defined,
unless specifically defined otherwise.
UAVCAN transfer performance statistics:
the number of UAVCAN transfers successfully sent, successfully received, and failed.
The methods of error counting are implementation-defined.

uavcan.node.IOStatistics.0.1[<=3] network_interface_statistics

uavcan.node.IOStatistics (v0.1) [extent 120 bytes]

A standard set of generic input/output statistical counters that generally should not overflow.
If a 40-bit counter is incremented every millisecond, it will overflow in ~35 years.
If an overflow occurs, the value will wrap over to zero.

The values should not be reset while the node is running.

truncated uint40 num_emitted [extent 5.0 bytes]

The number of successfully emitted entities.

truncated uint40 num_received [extent 5.0 bytes]

The number of successfully received entities.

truncated uint40 num_errored [extent 5.0 bytes]

How many errors have occurred.
The exact definition of "error" and how they are counted are implementation-defined,
unless specifically defined otherwise.
Network interface statistics, separate per interface.
E.g., for a doubly redundant transport, this array would contain two elements,
the one at the index zero would apply to the first interface, the other to the second interface.
The methods of counting are implementation-defined.

saturated uint8 MAX_NETWORK_INTERFACES = 3

UAVCAN supports up to triply modular redundant interfaces.

    
    
    

uavcan.node.Health (v1.0) [extent 8 bytes]

Abstract component health information. If the node performs multiple activities (provides multiple network services),
its health status should reflect the status of the worst-performing activity (network service).
Follows:
  https://www.law.cornell.edu/cfr/text/14/23.1322
  https://www.faa.gov/documentLibrary/media/Advisory_Circular/AC_25.1322-1.pdf section 6

saturated uint2 value [extent 2 bits]


    
    
    

saturated uint2 NOMINAL = 0

The component is functioning properly (nominal).

saturated uint2 ADVISORY = 1

A critical parameter went out of range or the component encountered a minor failure that does not prevent
the subsystem from performing any of its real-time functions.

saturated uint2 CAUTION = 2

The component encountered a major failure and is performing in a degraded mode or outside of its designed limitations.

saturated uint2 WARNING = 3

The component suffered a fatal malfunction and is unable to perform its intended function.

uavcan.node.Heartbeat (v1.0) [extent 128 bytes] [fixed port-ID 7509]

Abstract node status information.
This is the only high-level function that shall be implemented by all nodes.

All UAVCAN nodes that have a node-ID are required to publish this message to its fixed subject periodically.
Nodes that do not have a node-ID (also known as "anonymous nodes") shall not publish to this subject.

The default subject-ID 7509 is 1110101010101 in binary. The alternating bit pattern at the end helps transceiver
synchronization (e.g., on CAN-based networks) and on some transports permits automatic bit rate detection.

Network-wide health monitoring can be implemented by subscribing to the fixed subject.

saturated uint32 uptime [extent 4.0 bytes]

[second]
The uptime seconds counter should never overflow. The counter will reach the upper limit in ~136 years,
upon which time it should stay at 0xFFFFFFFF until the node is restarted.
Other nodes may detect that a remote node has restarted when this value leaps backwards.

uavcan.node.Health (v1.0) health [extent 8 bytes]

Abstract component health information. If the node performs multiple activities (provides multiple network services),
its health status should reflect the status of the worst-performing activity (network service).
Follows:
  https://www.law.cornell.edu/cfr/text/14/23.1322
  https://www.faa.gov/documentLibrary/media/Advisory_Circular/AC_25.1322-1.pdf section 6

saturated uint2 value [extent 2 bits]


    
    
    

saturated uint2 NOMINAL = 0

The component is functioning properly (nominal).

saturated uint2 ADVISORY = 1

A critical parameter went out of range or the component encountered a minor failure that does not prevent
the subsystem from performing any of its real-time functions.

saturated uint2 CAUTION = 2

The component encountered a major failure and is performing in a degraded mode or outside of its designed limitations.

saturated uint2 WARNING = 3

The component suffered a fatal malfunction and is unable to perform its intended function.
The abstract health status of this node.

uavcan.node.Mode (v1.0) mode [extent 8 bytes]

The operating mode of a node.
Reserved values can be used in future revisions of the specification.

saturated uint3 value [extent 3 bits]


    
    
    

saturated uint3 OPERATIONAL = 0

Normal operating mode.

saturated uint3 INITIALIZATION = 1

Initialization is in progress; this mode is entered immediately after startup.

saturated uint3 MAINTENANCE = 2

E.g., calibration, self-test, etc.

saturated uint3 SOFTWARE_UPDATE = 3

New software/firmware is being loaded or the bootloader is running.
The abstract operating mode of the publishing node.
This field indicates the general level of readiness that can be further elaborated on a per-activity basis
using various specialized interfaces.

saturated uint8 vendor_specific_status_code [extent 1.0 bytes]

Optional, vendor-specific node status code, e.g. a fault code or a status bitmask.

saturated uint16 MAX_PUBLICATION_PERIOD = 1

[second]
The publication period shall not exceed this limit.
The period should not change while the node is running.

saturated uint16 OFFLINE_TIMEOUT = 3

[second]
If the last message from the node was received more than this amount of time ago, it should be considered offline.

uavcan.node.ID (v1.0) [extent 16 bytes]

Defines a node-ID.
The maximum valid value is dependent on the underlying transport layer.
Values lower than 128 are always valid for all transports.
Refer to the specification for more info.

saturated uint16 value [extent 2.0 bytes]


    
    
    

uavcan.node.IOStatistics (v0.1) [extent 120 bytes]

A standard set of generic input/output statistical counters that generally should not overflow.
If a 40-bit counter is incremented every millisecond, it will overflow in ~35 years.
If an overflow occurs, the value will wrap over to zero.

The values should not be reset while the node is running.

truncated uint40 num_emitted [extent 5.0 bytes]

The number of successfully emitted entities.

truncated uint40 num_received [extent 5.0 bytes]

The number of successfully received entities.

truncated uint40 num_errored [extent 5.0 bytes]

How many errors have occurred.
The exact definition of "error" and how they are counted are implementation-defined,
unless specifically defined otherwise.

uavcan.node.Mode (v1.0) [extent 8 bytes]

The operating mode of a node.
Reserved values can be used in future revisions of the specification.

saturated uint3 value [extent 3 bits]


    
    
    

saturated uint3 OPERATIONAL = 0

Normal operating mode.

saturated uint3 INITIALIZATION = 1

Initialization is in progress; this mode is entered immediately after startup.

saturated uint3 MAINTENANCE = 2

E.g., calibration, self-test, etc.

saturated uint3 SOFTWARE_UPDATE = 3

New software/firmware is being loaded or the bootloader is running.

uavcan.node.Version (v1.0) [extent 16 bytes]

A shortened semantic version representation: only major and minor.
The protocol generally does not concern itself with the patch version.

saturated uint8 major [extent 1.0 bytes]


    
    
    

saturated uint8 minor [extent 1.0 bytes]


    
    
    

uavcan.node.port

uavcan.node.port.ID (v1.0) [extent 24 bytes]

Used to refer either to a Service or to a Subject.
The chosen tag identifies the kind of the port, then the numerical ID identifies the port within the kind.

uavcan.node.port.SubjectID (v1.0) subject_id [extent 16 bytes]

Subject-ID. The ranges are defined by the specification.

saturated uint13 value [extent 13 bits]


    
    
    

saturated uint13 MAX = 8191


    
    
    

    
    
    




uavcan.node.port.ServiceID (v1.0) service_id [extent 16 bytes]

Service-ID. The ranges are defined by the specification.

saturated uint9 value [extent 9 bits]


    
    
    

saturated uint9 MAX = 511


    
    
    

    
    
    

uavcan.node.port.List (v0.1) [extent 67728 bytes] [fixed port-ID 7510]

A list of ports that this node is using:
- Subjects published by this node (whether periodically or ad-hoc).
- Subjects that this node is subscribed to (a datalogger or a debugger would typically subscribe to all subjects).
- RPC services consumed by this node (i.e., service clients).
- RPC services provided by this node (i.e., service servers).

All nodes should implement this capability to provide network introspection and diagnostic capabilities.
This message should be published using the fixed subject-ID as follows:
- At the OPTIONAL priority level at least every MAX_PUBLICATION_PERIOD seconds.
- At the OPTIONAL or SLOW priority level within MAX_PUBLICATION_PERIOD after the port configuration is changed.

uavcan.node.port.SubjectIDList (v0.1) publishers [extent 32808 bytes]

A list of subject identifiers.
The range of subject-ID is large, so using a fixed-size bitmask would make this type difficult to handle on
resource-constrained systems. To address that, we provide two extra options: a simple variable-length list,
and a special case that indicates that every subject-ID is in use.

saturated bool[8192] mask

saturated bool

The index represents the identifier value. True -- present/used. False -- absent/unused.

uavcan.node.port.SubjectID.1.0[<=255] sparse_list

uavcan.node.port.SubjectID (v1.0) [extent 16 bytes]

Subject-ID. The ranges are defined by the specification.

saturated uint13 value [extent 13 bits]


    
    
    

saturated uint13 MAX = 8191


    
    
    
A list of identifiers that can be used instead of the mask if most of the identifiers are unused.

uavcan.primitive.Empty (v1.0) total [extent 0 bytes]

(data type is empty)

A special case indicating that all identifiers are in use.

saturated uint16 CAPACITY = 8192


    
    
    

    
    
    




uavcan.node.port.SubjectIDList (v0.1) subscribers [extent 32808 bytes]

A list of subject identifiers.
The range of subject-ID is large, so using a fixed-size bitmask would make this type difficult to handle on
resource-constrained systems. To address that, we provide two extra options: a simple variable-length list,
and a special case that indicates that every subject-ID is in use.

saturated bool[8192] mask

saturated bool

The index represents the identifier value. True -- present/used. False -- absent/unused.

uavcan.node.port.SubjectID.1.0[<=255] sparse_list

uavcan.node.port.SubjectID (v1.0) [extent 16 bytes]

Subject-ID. The ranges are defined by the specification.

saturated uint13 value [extent 13 bits]


    
    
    

saturated uint13 MAX = 8191


    
    
    
A list of identifiers that can be used instead of the mask if most of the identifiers are unused.

uavcan.primitive.Empty (v1.0) total [extent 0 bytes]

(data type is empty)

A special case indicating that all identifiers are in use.

saturated uint16 CAPACITY = 8192


    
    
    

    
    
    




uavcan.node.port.ServiceIDList (v0.1) clients [extent 1056 bytes]

A list of service identifiers.
This is a trivial constant-size bitmask with some reserved space in case the range of service-ID is increased
in a future revision of the protocol.

saturated bool[512] mask

saturated bool

The index represents the identifier value. True -- present/used. False -- absent/unused.

saturated uint16 CAPACITY = 512


    
    
    

    
    
    




uavcan.node.port.ServiceIDList (v0.1) servers [extent 1056 bytes]

A list of service identifiers.
This is a trivial constant-size bitmask with some reserved space in case the range of service-ID is increased
in a future revision of the protocol.

saturated bool[512] mask

saturated bool

The index represents the identifier value. True -- present/used. False -- absent/unused.

saturated uint16 CAPACITY = 512


    
    
    

    
    
    

saturated uint8 MAX_PUBLICATION_PERIOD = 10

[seconds]
If the port configuration is not updated in this amount of time, the node should publish this message anyway.

uavcan.node.port.ServiceID (v1.0) [extent 16 bytes]

Service-ID. The ranges are defined by the specification.

saturated uint9 value [extent 9 bits]


    
    
    

saturated uint9 MAX = 511


    
    
    

uavcan.node.port.ServiceIDList (v0.1) [extent 1056 bytes]

A list of service identifiers.
This is a trivial constant-size bitmask with some reserved space in case the range of service-ID is increased
in a future revision of the protocol.

saturated bool[512] mask

saturated bool

The index represents the identifier value. True -- present/used. False -- absent/unused.

saturated uint16 CAPACITY = 512


    
    
    

uavcan.node.port.SubjectID (v1.0) [extent 16 bytes]

Subject-ID. The ranges are defined by the specification.

saturated uint13 value [extent 13 bits]


    
    
    

saturated uint13 MAX = 8191


    
    
    

uavcan.node.port.SubjectIDList (v0.1) [extent 32808 bytes]

A list of subject identifiers.
The range of subject-ID is large, so using a fixed-size bitmask would make this type difficult to handle on
resource-constrained systems. To address that, we provide two extra options: a simple variable-length list,
and a special case that indicates that every subject-ID is in use.

saturated bool[8192] mask

saturated bool

The index represents the identifier value. True -- present/used. False -- absent/unused.

uavcan.node.port.SubjectID.1.0[<=255] sparse_list

uavcan.node.port.SubjectID (v1.0) [extent 16 bytes]

Subject-ID. The ranges are defined by the specification.

saturated uint13 value [extent 13 bits]


    
    
    

saturated uint13 MAX = 8191


    
    
    
A list of identifiers that can be used instead of the mask if most of the identifiers are unused.

uavcan.primitive.Empty (v1.0) total [extent 0 bytes]

(data type is empty)

A special case indicating that all identifiers are in use.

saturated uint16 CAPACITY = 8192


    
    
    

uavcan.si

uavcan.si.sample

uavcan.si.sample.electric_charge

uavcan.si.sample.electric_charge.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 coulomb [extent 4.0 bytes]


    
    
    

uavcan.si.sample.mass

uavcan.si.sample.mass.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 kilogram [extent 4.0 bytes]


    
    
    

uavcan.si.sample.acceleration

uavcan.si.sample.acceleration.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 meter_per_second_per_second [extent 4.0 bytes]


    
    
    

uavcan.si.sample.acceleration.Vector3 (v1.0) [extent 152 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    




saturated float32[3] meter_per_second_per_second

saturated float32


    
    
    

uavcan.si.sample.electric_current

uavcan.si.sample.electric_current.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 ampere [extent 4.0 bytes]


    
    
    

uavcan.si.sample.power

uavcan.si.sample.power.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 watt [extent 4.0 bytes]


    
    
    

uavcan.si.sample.force

uavcan.si.sample.force.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 newton [extent 4.0 bytes]


    
    
    

uavcan.si.sample.force.Vector3 (v1.0) [extent 152 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    




saturated float32[3] newton

saturated float32


    
    
    

uavcan.si.sample.torque

uavcan.si.sample.torque.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 newton_meter [extent 4.0 bytes]


    
    
    

uavcan.si.sample.torque.Vector3 (v1.0) [extent 152 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    




saturated float32[3] newton_meter

saturated float32


    
    
    

uavcan.si.sample.energy

uavcan.si.sample.energy.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 joule [extent 4.0 bytes]


    
    
    

uavcan.si.sample.pressure

uavcan.si.sample.pressure.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 pascal [extent 4.0 bytes]


    
    
    

uavcan.si.sample.voltage

uavcan.si.sample.voltage.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 volt [extent 4.0 bytes]


    
    
    

uavcan.si.sample.volumetric_flow_rate

uavcan.si.sample.volumetric_flow_rate.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 cubic_meter_per_second [extent 4.0 bytes]


    
    
    

uavcan.si.sample.angular_acceleration

uavcan.si.sample.angular_acceleration.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 radian_per_second_per_second [extent 4.0 bytes]


    
    
    

uavcan.si.sample.angular_acceleration.Vector3 (v1.0) [extent 152 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    




saturated float32[3] radian_per_second_per_second

saturated float32


    
    
    

uavcan.si.sample.temperature

uavcan.si.sample.temperature.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 kelvin [extent 4.0 bytes]


    
    
    

uavcan.si.sample.volume

uavcan.si.sample.volume.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 cubic_meter [extent 4.0 bytes]


    
    
    

uavcan.si.sample.length

uavcan.si.sample.length.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 meter [extent 4.0 bytes]


    
    
    

uavcan.si.sample.length.Vector3 (v1.0) [extent 152 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    




saturated float32[3] meter

saturated float32


    
    
    

uavcan.si.sample.length.WideScalar (v1.0) [extent 120 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float64 meter [extent 8.0 bytes]


    
    
    

uavcan.si.sample.length.WideVector3 (v1.0) [extent 248 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    




saturated float64[3] meter

saturated float64


    
    
    

uavcan.si.sample.magnetic_field_strength

uavcan.si.sample.magnetic_field_strength.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 tesla [extent 4.0 bytes]


    
    
    

uavcan.si.sample.magnetic_field_strength.Vector3 (v1.0) [extent 152 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    




saturated float32[3] tesla

saturated float32


    
    
    

uavcan.si.sample.velocity

uavcan.si.sample.velocity.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 meter_per_second [extent 4.0 bytes]


    
    
    

uavcan.si.sample.velocity.Vector3 (v1.0) [extent 152 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    




saturated float32[3] meter_per_second

saturated float32


    
    
    

uavcan.si.sample.angle

uavcan.si.sample.angle.Quaternion (v1.0) [extent 184 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    




saturated float32[4] wxyz

saturated float32


    
    
    

uavcan.si.sample.angle.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 radian [extent 4.0 bytes]


    
    
    

uavcan.si.sample.angular_velocity

uavcan.si.sample.angular_velocity.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 radian_per_second [extent 4.0 bytes]


    
    
    

uavcan.si.sample.angular_velocity.Vector3 (v1.0) [extent 152 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    




saturated float32[3] radian_per_second

saturated float32


    
    
    

uavcan.si.sample.frequency

uavcan.si.sample.frequency.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 hertz [extent 4.0 bytes]


    
    
    

uavcan.si.sample.duration

uavcan.si.sample.duration.Scalar (v1.0) [extent 88 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float32 second [extent 4.0 bytes]


    
    
    

uavcan.si.sample.duration.WideScalar (v1.0) [extent 120 bytes]

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.

    
    
    

saturated float64 second [extent 8.0 bytes]


    
    
    

uavcan.si.unit

uavcan.si.unit.voltage

uavcan.si.unit.voltage.Scalar (v1.0) [extent 32 bytes]

saturated float32 volt [extent 4.0 bytes]


    
    
    

uavcan.si.unit.temperature

uavcan.si.unit.temperature.Scalar (v1.0) [extent 32 bytes]

saturated float32 kelvin [extent 4.0 bytes]


    
    
    

uavcan.si.unit.duration

uavcan.si.unit.duration.Scalar (v1.0) [extent 32 bytes]

saturated float32 second [extent 4.0 bytes]


    
    
    

uavcan.si.unit.duration.WideScalar (v1.0) [extent 64 bytes]

saturated float64 second [extent 8.0 bytes]


    
    
    

uavcan.si.unit.volumetric_flow_rate

uavcan.si.unit.volumetric_flow_rate.Scalar (v1.0) [extent 32 bytes]

saturated float32 cubic_meter_per_second [extent 4.0 bytes]


    
    
    

uavcan.si.unit.mass

uavcan.si.unit.mass.Scalar (v1.0) [extent 32 bytes]

saturated float32 kilogram [extent 4.0 bytes]


    
    
    

uavcan.si.unit.torque

uavcan.si.unit.torque.Scalar (v1.0) [extent 32 bytes]

saturated float32 newton_meter [extent 4.0 bytes]


    
    
    

uavcan.si.unit.torque.Vector3 (v1.0) [extent 96 bytes]

saturated float32[3] newton_meter

saturated float32


    
    
    

uavcan.si.unit.energy

uavcan.si.unit.energy.Scalar (v1.0) [extent 32 bytes]

saturated float32 joule [extent 4.0 bytes]


    
    
    

uavcan.si.unit.volume

uavcan.si.unit.volume.Scalar (v1.0) [extent 32 bytes]

saturated float32 cubic_meter [extent 4.0 bytes]


    
    
    

uavcan.si.unit.power

uavcan.si.unit.power.Scalar (v1.0) [extent 32 bytes]

saturated float32 watt [extent 4.0 bytes]


    
    
    

uavcan.si.unit.acceleration

uavcan.si.unit.acceleration.Scalar (v1.0) [extent 32 bytes]

saturated float32 meter_per_second_per_second [extent 4.0 bytes]


    
    
    

uavcan.si.unit.acceleration.Vector3 (v1.0) [extent 96 bytes]

saturated float32[3] meter_per_second_per_second

saturated float32


    
    
    

uavcan.si.unit.length

uavcan.si.unit.length.Scalar (v1.0) [extent 32 bytes]

saturated float32 meter [extent 4.0 bytes]


    
    
    

uavcan.si.unit.length.Vector3 (v1.0) [extent 96 bytes]

saturated float32[3] meter

saturated float32


    
    
    

uavcan.si.unit.length.WideScalar (v1.0) [extent 64 bytes]

saturated float64 meter [extent 8.0 bytes]


    
    
    

uavcan.si.unit.length.WideVector3 (v1.0) [extent 192 bytes]

saturated float64[3] meter

saturated float64


    
    
    

uavcan.si.unit.electric_charge

uavcan.si.unit.electric_charge.Scalar (v1.0) [extent 32 bytes]

saturated float32 coulomb [extent 4.0 bytes]


    
    
    

uavcan.si.unit.pressure

uavcan.si.unit.pressure.Scalar (v1.0) [extent 32 bytes]

saturated float32 pascal [extent 4.0 bytes]


    
    
    

uavcan.si.unit.force

uavcan.si.unit.force.Scalar (v1.0) [extent 32 bytes]

saturated float32 newton [extent 4.0 bytes]


    
    
    

uavcan.si.unit.force.Vector3 (v1.0) [extent 96 bytes]

saturated float32[3] newton

saturated float32


    
    
    

uavcan.si.unit.velocity

uavcan.si.unit.velocity.Scalar (v1.0) [extent 32 bytes]

saturated float32 meter_per_second [extent 4.0 bytes]


    
    
    

uavcan.si.unit.velocity.Vector3 (v1.0) [extent 96 bytes]

saturated float32[3] meter_per_second

saturated float32


    
    
    

uavcan.si.unit.electric_current

uavcan.si.unit.electric_current.Scalar (v1.0) [extent 32 bytes]

saturated float32 ampere [extent 4.0 bytes]


    
    
    

uavcan.si.unit.frequency

uavcan.si.unit.frequency.Scalar (v1.0) [extent 32 bytes]

saturated float32 hertz [extent 4.0 bytes]


    
    
    

uavcan.si.unit.angular_acceleration

uavcan.si.unit.angular_acceleration.Scalar (v1.0) [extent 32 bytes]

saturated float32 radian_per_second_per_second [extent 4.0 bytes]


    
    
    

uavcan.si.unit.angular_acceleration.Vector3 (v1.0) [extent 96 bytes]

saturated float32[3] radian_per_second_per_second

saturated float32


    
    
    

uavcan.si.unit.angle

uavcan.si.unit.angle.Quaternion (v1.0) [extent 128 bytes]

saturated float32[4] wxyz

saturated float32


    
    
    

uavcan.si.unit.angle.Scalar (v1.0) [extent 32 bytes]

saturated float32 radian [extent 4.0 bytes]


    
    
    

uavcan.si.unit.magnetic_field_strength

uavcan.si.unit.magnetic_field_strength.Scalar (v1.0) [extent 32 bytes]

saturated float32 tesla [extent 4.0 bytes]


    
    
    

uavcan.si.unit.magnetic_field_strength.Vector3 (v1.0) [extent 96 bytes]

saturated float32[3] tesla

saturated float32


    
    
    

uavcan.si.unit.angular_velocity

uavcan.si.unit.angular_velocity.Scalar (v1.0) [extent 32 bytes]

saturated float32 radian_per_second [extent 4.0 bytes]


    
    
    

uavcan.si.unit.angular_velocity.Vector3 (v1.0) [extent 96 bytes]

saturated float32[3] radian_per_second

saturated float32


    
    
    

uavcan.diagnostic

uavcan.diagnostic.Record (v1.1) [extent 2432 bytes] [fixed port-ID 8184]

Generic human-readable text message for logging and displaying purposes.
Generally, it should be published at the lowest priority level.

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.
Optional timestamp in the network-synchronized time system; zero if undefined.
The timestamp value conveys the exact moment when the reported event took place.

uavcan.diagnostic.Severity (v1.0) severity [extent 8 bytes]

Generic message severity representation.

saturated uint3 value [extent 3 bits]

The severity level ranging from 0 to 7, where low values represent low-severity (unimportant) messages, and
high values represent high-severity (important) messages. Several mnemonics for the severity levels are
defined below. Nodes are advised to implement output filtering mechanisms, allowing users to select
the minimal severity for emitted messages; messages of the selected and higher severity levels will
be published, and messages of lower severity will be suppressed (discarded).

saturated uint3 TRACE = 0

Messages of this severity can be used only during development.
They shall not be used in a fielded operational system.

saturated uint3 DEBUG = 1

Messages that can aid in troubleshooting.
Messages of this severity and lower should be disabled by default.

saturated uint3 INFO = 2

General informational messages of low importance.
Messages of this severity and lower should be disabled by default.

saturated uint3 NOTICE = 3

General informational messages of high importance.
Messages of this severity and lower should be disabled by default.

saturated uint3 WARNING = 4

Messages reporting abnormalities and warning conditions.
Messages of this severity and higher should be enabled by default.

saturated uint3 ERROR = 5

Messages reporting problems and error conditions.
Messages of this severity and higher should be enabled by default.

saturated uint3 CRITICAL = 6

Messages reporting serious problems and critical conditions.
Messages of this severity and higher should be always enabled.

saturated uint3 ALERT = 7

Notifications of dangerous circumstances that demand immediate attention.
Messages of this severity should be always enabled.

    
    
    




saturated uint8[<=255] text

saturated uint8

Message text.
Normally, messages should be kept as short as possible, especially those of high severity.

uavcan.diagnostic.Record (v1.0) [extent 2432 bytes] [fixed port-ID 8184]

Generic human-readable text message for logging and displaying purposes.
Generally, it should be published at the lowest priority level.

uavcan.time.SynchronizedTimestamp (v1.0) timestamp [extent 56 bytes]

Nested data type used for representing a network-wide synchronized timestamp with microsecond resolution.
This data type is highly recommended for use both in standard and vendor-specific messages alike.

truncated uint56 microsecond [extent 7.0 bytes]

The number of microseconds that have passed since some arbitrary moment in the past.
The moment of origin (i.e., the time base) is defined per-application. The current time base in use
can be requested from the time synchronization master, see the corresponding service definition.

This value is to never overflow. The value is 56-bit wide because:

  - 2^56 microseconds is about 2285 years, which is plenty. A 64-bit microsecond counter would be
    unnecessarily wide and its overflow interval of 585 thousand years induces a mild existential crisis.

  - Classic-CAN (not FD) transports carry up to 7 bytes of payload per frame.
    Time sync messages shall use single-frame transfers, which means that the value can't be wider than 56 bits.

saturated uint56 UNKNOWN = 0

Zero means that the time is not known.
Optional timestamp in the network-synchronized time system; zero if undefined.
The timestamp value conveys the exact moment when the reported event took place.

uavcan.diagnostic.Severity (v1.0) severity [extent 8 bytes]

Generic message severity representation.

saturated uint3 value [extent 3 bits]

The severity level ranging from 0 to 7, where low values represent low-severity (unimportant) messages, and
high values represent high-severity (important) messages. Several mnemonics for the severity levels are
defined below. Nodes are advised to implement output filtering mechanisms, allowing users to select
the minimal severity for emitted messages; messages of the selected and higher severity levels will
be published, and messages of lower severity will be suppressed (discarded).

saturated uint3 TRACE = 0

Messages of this severity can be used only during development.
They shall not be used in a fielded operational system.

saturated uint3 DEBUG = 1

Messages that can aid in troubleshooting.
Messages of this severity and lower should be disabled by default.

saturated uint3 INFO = 2

General informational messages of low importance.
Messages of this severity and lower should be disabled by default.

saturated uint3 NOTICE = 3

General informational messages of high importance.
Messages of this severity and lower should be disabled by default.

saturated uint3 WARNING = 4

Messages reporting abnormalities and warning conditions.
Messages of this severity and higher should be enabled by default.

saturated uint3 ERROR = 5

Messages reporting problems and error conditions.
Messages of this severity and higher should be enabled by default.

saturated uint3 CRITICAL = 6

Messages reporting serious problems and critical conditions.
Messages of this severity and higher should be always enabled.

saturated uint3 ALERT = 7

Notifications of dangerous circumstances that demand immediate attention.
Messages of this severity should be always enabled.

    
    
    




saturated uint8[<=112] text

saturated uint8

Message text.
Normally, messages should be kept as short as possible, especially those of high severity.

uavcan.diagnostic.Severity (v1.0) [extent 8 bytes]

Generic message severity representation.

saturated uint3 value [extent 3 bits]

The severity level ranging from 0 to 7, where low values represent low-severity (unimportant) messages, and
high values represent high-severity (important) messages. Several mnemonics for the severity levels are
defined below. Nodes are advised to implement output filtering mechanisms, allowing users to select
the minimal severity for emitted messages; messages of the selected and higher severity levels will
be published, and messages of lower severity will be suppressed (discarded).

saturated uint3 TRACE = 0

Messages of this severity can be used only during development.
They shall not be used in a fielded operational system.

saturated uint3 DEBUG = 1

Messages that can aid in troubleshooting.
Messages of this severity and lower should be disabled by default.

saturated uint3 INFO = 2

General informational messages of low importance.
Messages of this severity and lower should be disabled by default.

saturated uint3 NOTICE = 3

General informational messages of high importance.
Messages of this severity and lower should be disabled by default.

saturated uint3 WARNING = 4

Messages reporting abnormalities and warning conditions.
Messages of this severity and higher should be enabled by default.

saturated uint3 ERROR = 5

Messages reporting problems and error conditions.
Messages of this severity and higher should be enabled by default.

saturated uint3 CRITICAL = 6

Messages reporting serious problems and critical conditions.
Messages of this severity and higher should be always enabled.

saturated uint3 ALERT = 7

Notifications of dangerous circumstances that demand immediate attention.
Messages of this severity should be always enabled.

uavcan.primitive

uavcan.primitive.Empty (v1.0) [extent 0 bytes]

(data type is empty)

uavcan.primitive.String (v1.0) [extent 2064 bytes]

A UTF8-encoded string of text.
Since the string is represented as a dynamic array of bytes, it is not null-terminated. Like Pascal string.

saturated uint8[<=256] value

saturated uint8


    
    
    

uavcan.primitive.Unstructured (v1.0) [extent 2064 bytes]

An unstructured collection of bytes, e.g., raw binary image.

saturated uint8[<=256] value

saturated uint8


    
    
    

uavcan.primitive.scalar

uavcan.primitive.scalar.Bit (v1.0) [extent 8 bytes]

saturated bool value [extent 1 bits]


    
    
    

uavcan.primitive.scalar.Integer16 (v1.0) [extent 16 bytes]

saturated int16 value [extent 2.0 bytes]


    
    
    

uavcan.primitive.scalar.Integer32 (v1.0) [extent 32 bytes]

saturated int32 value [extent 4.0 bytes]


    
    
    

uavcan.primitive.scalar.Integer64 (v1.0) [extent 64 bytes]

saturated int64 value [extent 8.0 bytes]


    
    
    

uavcan.primitive.scalar.Integer8 (v1.0) [extent 8 bytes]

saturated int8 value [extent 1.0 bytes]


    
    
    

uavcan.primitive.scalar.Natural16 (v1.0) [extent 16 bytes]

saturated uint16 value [extent 2.0 bytes]


    
    
    

uavcan.primitive.scalar.Natural32 (v1.0) [extent 32 bytes]

saturated uint32 value [extent 4.0 bytes]


    
    
    

uavcan.primitive.scalar.Natural64 (v1.0) [extent 64 bytes]

saturated uint64 value [extent 8.0 bytes]


    
    
    

uavcan.primitive.scalar.Natural8 (v1.0) [extent 8 bytes]

saturated uint8 value [extent 1.0 bytes]


    
    
    

uavcan.primitive.scalar.Real16 (v1.0) [extent 16 bytes]

saturated float16 value [extent 2.0 bytes]

Exactly representable integers: [-2048, +2048]

uavcan.primitive.scalar.Real32 (v1.0) [extent 32 bytes]

saturated float32 value [extent 4.0 bytes]

Exactly representable integers: [-16777216, +16777216]

uavcan.primitive.scalar.Real64 (v1.0) [extent 64 bytes]

saturated float64 value [extent 8.0 bytes]

Exactly representable integers: [-2**53, +2**53]

uavcan.primitive.array

uavcan.primitive.array.Bit (v1.0) [extent 2064 bytes]

2048 bits + 11 bit length + 4 bit padding = 2064 bits = 258 bytes

saturated bool[<=2048] value

saturated bool


    
    
    

uavcan.primitive.array.Integer16 (v1.0) [extent 2056 bytes]

saturated int16[<=128] value

saturated int16


    
    
    

uavcan.primitive.array.Integer32 (v1.0) [extent 2056 bytes]

saturated int32[<=64] value

saturated int32


    
    
    

uavcan.primitive.array.Integer64 (v1.0) [extent 2056 bytes]

saturated int64[<=32] value

saturated int64


    
    
    

uavcan.primitive.array.Integer8 (v1.0) [extent 2064 bytes]

saturated int8[<=256] value

saturated int8


    
    
    

uavcan.primitive.array.Natural16 (v1.0) [extent 2056 bytes]

saturated uint16[<=128] value

saturated uint16


    
    
    

uavcan.primitive.array.Natural32 (v1.0) [extent 2056 bytes]

saturated uint32[<=64] value

saturated uint32


    
    
    

uavcan.primitive.array.Natural64 (v1.0) [extent 2056 bytes]

saturated uint64[<=32] value

saturated uint64


    
    
    

uavcan.primitive.array.Natural8 (v1.0) [extent 2064 bytes]

saturated uint8[<=256] value

saturated uint8


    
    
    

uavcan.primitive.array.Real16 (v1.0) [extent 2056 bytes]

Exactly representable integers: [-2048, +2048]

saturated float16[<=128] value

saturated float16


    
    
    

uavcan.primitive.array.Real32 (v1.0) [extent 2056 bytes]

Exactly representable integers: [-16777216, +16777216]

saturated float32[<=64] value

saturated float32


    
    
    

uavcan.primitive.array.Real64 (v1.0) [extent 2056 bytes]

Exactly representable integers: [-2**53, +2**53]

saturated float64[<=32] value

saturated float64