Resolving Node-ID conflicts

This is a possible case when we have two vehicles with the fully configured uavcan bus each. And we need to replace some CAN device of one vehicle to the device from another vehicle. We have got nonzero possibility that replaced device Node-ID is not unique in the new vehicle. Of course, the staff must solve this problem during exchange procedure, but I want to have automatic check of the uavcan bus integrity before start, that have to detetct Node-ID conflicts and solve it if it is possible.
I have performed some experiments with two differential_pressure_sensors from demos repo and yakut. When two sensors have the same Node-ID the yakut monitor displays one node with changing Unique-ID. So, as I understand, the standard pyuavcan node tracker can detect the Node-ID conflicts. After that I have written 65535 to uavcan.node.id register of nodes with non unique Node-ID and reboot that nodes. And pnp procedure have assigned unique Node-IDs to both nodes after reboot.
Could I use this technique in the production system for check integrity? Or are there some standard recommendations for resolving Node-ID conflicts?

Generally speaking, there is no robust way of detecting a node-ID collision externally, because the entire transport layer is built on the assumption that node-IDs are unique. You can rely on heuristics but the result is not guaranteed unless each individual node is responsible for looking out for collisions.

The approach you described suffers from the rather obvious problem: the node that is responsible for detecting collisions, Yakut monitor in your case, may either fail to detect the node that came online later (becaue its transfer-ID values for the heartbeat transfers will be consistently lower, causing Yakut to discard incoming transfers as duplicates), or – even if the node is detected, which it is in your case – sending the uavcan.node.GetInfo to an ambiguous node-ID will solicit a response from both nodes, and the client (Yakut monitor) will see two different transfers coming from what looks to be the same node with no robust way of separating one from the other. The only circumstance where this might work is when one node responds earlier than the other one, which is apparently what you are dealing with. Relying on this behavior for collision detection in a production system is no better than tossing a coin.

You might be tempted to detect collisions by checking the frequency of heartbeat transfers per node-ID, but this will only work if you assign a low transfer-ID timeout value for your heartbeat subscriber, which in turn may trigger false-positives if your transport network is prone to packet duplication (CAN is, at least in theory).

As I wrote above, one robust way is to make each node actively look out for collisions by subscribing to the heartbeat subject. For each received heartbeat just check if the source node-ID is the same as yours, and if so, erase your own node-ID and request a new one using the standard plug-and-play procedure (or just restart depending on your application).

1 Like