mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-19 04:53:35 +08:00
New dynamic node ID allocation client
This commit is contained in:
@@ -1,147 +0,0 @@
|
||||
#
|
||||
# This message is used for dynamic Node ID allocation. This algorithm is an
|
||||
# optional extension to the UAVCAN specification, and it is not mandatory to
|
||||
# support it.
|
||||
#
|
||||
# The dynamic Node ID allocation algorithm works as follows:
|
||||
#
|
||||
# - As a prerequisite, the network contains at least one node that has some
|
||||
# Node ID assigned, that will handle allocation requests from other nodes.
|
||||
# This node will be later referred to as Allocator. It is recognized that
|
||||
# since UAVCAN is a decentralized network, there might be more than one
|
||||
# Allocator, but only one of them should handle allocation requests at any
|
||||
# given time. This issue is covered below in detail.
|
||||
#
|
||||
# - The network may also contain any number of nodes that seek to have
|
||||
# Node IDs assigned to them. In order to get a Node ID assigned, these nodes
|
||||
# make a request to the Allocator. Requesting nodes will be referred to as
|
||||
# Allocatees.
|
||||
#
|
||||
# - In order to get a Node ID allocated, the Allocatee fills this message
|
||||
# structure with its short unique ID (see below to learn how to compute one)
|
||||
# and its preferred Node ID (which is basically the Node ID it would like to
|
||||
# take, if possible). If the Allocatee doesn't have any preference, the
|
||||
# preferred Node ID can be set to zero.
|
||||
#
|
||||
# - The Allocatee broadcasts the message to the bus. Since it doesn't have a
|
||||
# Node ID at the moment, the field Source Node ID in the broadcasted message
|
||||
# must be zero. Note that it may require special logic in the transport
|
||||
# layer to receive messages where Source Node ID is zeroed.
|
||||
#
|
||||
# - The Allocator receives the message and refers to its Node ID Table, where
|
||||
# it looks for any unallocated Node ID value that equal to or greater than
|
||||
# the value that was requested by the Allocatee. If the desired Node ID is
|
||||
# set to zero, or if all Node IDs that are larger than the preferred one are
|
||||
# already taken, the Allocator traverses the Node ID Table from top to
|
||||
# bottom (i.e. from high to low Node ID) until it finds first unallocated
|
||||
# entry. In a case if all available entires are taken, the Allocator ignores
|
||||
# the request. Please note that it is recommended to restrict the range of
|
||||
# dynamically assignable Node IDs, as described below.
|
||||
#
|
||||
# - The Allocator fills the response message. The short unique ID is set the
|
||||
# same as in the request, the Node ID field is assigned the value obtained
|
||||
# on the previous step. When filled, the message is broadcasted as usual,
|
||||
# i.e. the field Source Node ID must be set to the actual Node ID of the
|
||||
# Allocator. This allows other Allocators, if any, to understand that this
|
||||
# message is not an allocation request, otherwise Source Node ID would be
|
||||
# zero.
|
||||
#
|
||||
# - The Allocatee receives the response. Sice there can be other nodes trying
|
||||
# to get a Node ID at the same time, the Allocatee filters other messages
|
||||
# by means of comparing its own short unique ID with short unique ID in the
|
||||
# messages passing by. When a message is received such that its short unique
|
||||
# ID equals the short unique ID of the Allocatee, the Allocatee gets the
|
||||
# allocated Node ID from the message, accepts it and continues its normal
|
||||
# operation as a full-fledged UAVCAN node.
|
||||
#
|
||||
# - It is recommended that once Allocatee was granted a Node ID, it stops
|
||||
# listening to other messages of this type and reconfigures its CAN
|
||||
# acceptance filters accordingly.
|
||||
#
|
||||
# It has been mentioned above that a network may accomodate more than one
|
||||
# Allocator at the time. In this case, the Allocators should agree between
|
||||
# each other that only one of them is handling allocation requests at the
|
||||
# moment. A possible way to reach such an agreement is to let one Allocator
|
||||
# monitor the presence of the second one (e.g. by means of listening to its
|
||||
# NodeStatus messages), so that the second Allocator will ignore allocation
|
||||
# requests as long as the first one is alive.
|
||||
#
|
||||
# Every Allocator must continuously maintain a table that indicates which
|
||||
# Node IDs are taken, and which are free. The logic is like that: immediately
|
||||
# after initialization, only one Node ID is considered to be taken - the one
|
||||
# that belongs to the Allocator itself. The allocator subscribes to the
|
||||
# messages uavcan.protocol.NodeStatus and this one, that are then used to
|
||||
# update the table in real time - once a NodeStatus or this message are
|
||||
# received, the table is updated to indicate that the Node ID that sent the
|
||||
# NodeStatus message is taken. The Allocator must not process allocation
|
||||
# requests sooner than a few seconds after its initialization, in order to
|
||||
# ensure that all nodes that exist in the network were able to transmit their
|
||||
# NodeStatus message at least once. The exact duration of initialization delay
|
||||
# is defined in a constant below.
|
||||
#
|
||||
# In order to minimize chances of Node ID collision between nodes that rely on
|
||||
# the dynamic allocation and the nodes that use statically allocated Node IDs,
|
||||
# it is recommended to restrict the range of dynamically allocatable Node IDs.
|
||||
# Two constants below define a range for dynamically allocated Node ID.
|
||||
#
|
||||
# There is a limit that restricts the maximum frequency at which the Allocatee
|
||||
# is allowed to broadcast allocation requests. It is defined in a constant
|
||||
# below.
|
||||
#
|
||||
# Fields of this message are documented below.
|
||||
#
|
||||
|
||||
#
|
||||
# This is the delay that Allocator must take to initialize its Node ID Table.
|
||||
#
|
||||
uint8 ALLOCATOR_INITIALIZATION_DELAY_SEC = 10
|
||||
|
||||
#
|
||||
# This is the minimum interval (maximum frequency) at which the Allocatee can
|
||||
# broadcast allocation requests.
|
||||
#
|
||||
uint8 ALLOCATEE_MIN_BROADCAST_INTERVAL_SEC = 1
|
||||
|
||||
#
|
||||
# It is recommended to pick Node IDs from this range only, even if the
|
||||
# Allocatee requests a Node ID that is outside of this range.
|
||||
#
|
||||
uint7 RECOMMENDED_DYNAMIC_NODE_ID_RANGE_MIN = 64
|
||||
uint7 RECOMMENDED_DYNAMIC_NODE_ID_RANGE_MAX = 125
|
||||
|
||||
#
|
||||
# This field contains 57 bits that uniquely identify the node that requests
|
||||
# Node ID allocation. The specification does not define exact algorithm for
|
||||
# computing short unique ID, but it is recommended to stick to the following
|
||||
# recommendations:
|
||||
#
|
||||
# 1. If the node's unique ID is 64 bit large, lower 57 bits should be used.
|
||||
#
|
||||
# 2. If the node's unique ID is larger than 64 bits, it should be reduced
|
||||
# to 64 bit using the CRC-64-WE hash function (the same function that is
|
||||
# used in DSDL signature computation, see specification for details), and
|
||||
# the result should be processed as desribed in the first item above.
|
||||
#
|
||||
# Many microcontrollers provide vendor-assigned unique product IDs that are
|
||||
# typically 12 to 16 bytes long (e.g. STM32, LPC11), which should be employed
|
||||
# as described in the second item above.
|
||||
#
|
||||
# A node is not allowed to use this algorithm if it doesn't have a unique ID
|
||||
# that is 57 or more bits long.
|
||||
#
|
||||
# Regarding the collision probability: the birthday paradox suggests that a
|
||||
# network with n=30 nodes will experience a short unique ID collision with
|
||||
# approximate probability of (n^2)/(2*(2^57-1)) = 3.1e-15, assuming that
|
||||
# the ID reduction function is perfect.
|
||||
#
|
||||
truncated uint57 short_unique_id
|
||||
|
||||
#
|
||||
# In the request, this field should contain Node ID that the requesting node
|
||||
# would like to take. The allocator then may choose to provide the requested
|
||||
# Node ID, or to assign a higher one, or to disregard this preference
|
||||
# completely. It is recommended that the allocator always tries to provide
|
||||
# Node ID that is equal or higher than requested one, as it would allow nodes
|
||||
# to get Node ID according to their desired priority on the bus.
|
||||
#
|
||||
truncated uint7 node_id
|
||||
@@ -0,0 +1,64 @@
|
||||
#
|
||||
# This message is used for dynamic Node ID allocation. This algorithm is an optional extension to the UAVCAN
|
||||
# specification, and it is not mandatory to support it.
|
||||
#
|
||||
# On the client's side the protocol is defined through the following set of rules:
|
||||
#
|
||||
# Rule A. On initialization:
|
||||
# 1. The client subscribes to this message.
|
||||
# 2. The client starts the Request Timer with interval of DEFAULT_REQUEST_INTERVAL_MS.
|
||||
#
|
||||
# Rule B. On expiration of Request Timer:
|
||||
# 1. Request Timer restarts.
|
||||
# 2. The client broadcasts a first-stage Allocation request message, where the fields are assigned following values:
|
||||
# node_id - preferred node ID, or zero if the client doesn't have any preference
|
||||
# first_part_of_unique_id - true
|
||||
# unique_id - first MAX_LENGTH_OF_UNIQUE_ID_IN_REQUEST bytes of unique ID
|
||||
#
|
||||
# Rule C. On any Allocation message, even if other rules also match:
|
||||
# 1. Request Timer restarts.
|
||||
#
|
||||
# Rule D. On an Allocation message WHERE (source node ID is non-anonymous) AND (client's unique ID starts with the
|
||||
# bytes available in the field unique_id) AND (unique_id is less than 16 bytes long):
|
||||
# 1. The client broadcasts a second-stage Allocation request message, where the fields are assigned following values:
|
||||
# node_id - same value as in the first-stage
|
||||
# first_part_of_unique_id - false
|
||||
# unique_id - at most MAX_LENGTH_OF_UNIQUE_ID_IN_REQUEST bytes of local unique ID with an offset
|
||||
# equal to number of bytes in the received unique ID
|
||||
#
|
||||
# Rule E. On an Allocation message WHERE (source node ID is non-anonymous) AND (unique_id fully matches client's
|
||||
# unique ID) AND (node_id in the received message is not zero):
|
||||
# 1. Request Timer stops.
|
||||
# 2. The client initializes its node_id with the received value.
|
||||
# 3. The client terminates subscription to Allocation messages.
|
||||
# 4. Exit.
|
||||
#
|
||||
|
||||
#
|
||||
# Recommended request transmission period.
|
||||
#
|
||||
uint16 DEFAULT_REQUEST_PERIOD_MS = 1000
|
||||
|
||||
#
|
||||
# Any request message can accommodate no more than this number of bytes of unique ID.
|
||||
# This limitation is needed to ensure that all request transfers are single-frame.
|
||||
#
|
||||
uint8 MAX_LENGTH_OF_UNIQUE_ID_IN_REQUEST = 7
|
||||
|
||||
#
|
||||
# If transfer is anonymous, this is the preferred ID.
|
||||
# If transfer is non-anonymous, this is allocated ID.
|
||||
#
|
||||
uint7 node_id
|
||||
|
||||
#
|
||||
# If transfer is anonymous, this field indicates first-stage request.
|
||||
# If transfer is non-anonymous, this field should be ignored.
|
||||
#
|
||||
bool first_part_of_unique_id
|
||||
|
||||
#
|
||||
# If transfer is anonymous, this array must not contain more than MAX_LENGTH_OF_UNIQUE_ID_IN_REQUEST items.
|
||||
# Note that array is tail-optimized, i.e. it will not be prepended with length field.
|
||||
#
|
||||
uint8[<=16] unique_id
|
||||
Reference in New Issue
Block a user