For example, if I have a chain of them, and I can see them all on the network, is there any way to find out what order they are in the chain? In the C++ API for the Lookup class I see a "getConnectedGroupFromName" function but I suspect this is deprecated and don't know what it does since I mostly use the python API these days.
Similarly, if I have an ethernet switch where multiple modules are connected to it, can I find out which port each module is located on? I think this is less of a hebi problem and more of a switch problem-- I've been googling it and it seems to be possible if you have special software and a managed switch. But the small lightweight ones I like to use are unmanaged, and I'd like to do it via Python commands. Anyone have any thoughts on how I can do this?
- HEBI Official
- Posts: 12
- Joined: Fri Mar 27, 2020 6:55 pm
- Location: Pittsburgh, PA
There is not really an easy way to determine the order. The connected group functionality is specific to the snake modules - they have serial connections between each module in addition to the Ethernet connection. I know Dave has messed around with using the IMUs coupled with some amount of movement to work out the physical order of an arm. You could also wire up all of the M-Stop inputs separately to an IO Board and trigger them in order but this would make the wiring pretty messy. Maybe at least making a script that commands the LEDs to change color in a certain order would help.
Using Kinematics + IMUs:
We've tested out using the IMUs to quickly identify actuators that are rigidly attached in series, like for an arm. That requires you to move the arm during a 'system ID' step. As long as each actuator is rigidly attached with no passive links in between, you can use the actuator's gyros and compare them to the actuator velocities and get a really solid map of topology, and a decent estimate of relative orientations.
Using Network Latency:
We've also looked at using the latency of the round-trip-time (RTT) of the communications to see if we can identify the connection order. This can be done by taking a log and looking at log.pcRxTime - log.pcTxTime. This kinda works, as each switch adds a small amount of delay (on the order of ~10 microseconds). But there's occasionally just enough jitter to have 1-2 modules switch order. I'd say this method is ~80% accurate, which has kept it from being a widely used method for us.
I can dig up and post some Matlab code that does these methods if you're interested.
1) Using Network Latency
I just did a quick test regarding the network latency on a setup with 36 daisy-chained modules. As Dave mentioned, the latency added by each switch is very small compared to the noise/jitter, so it's tough to get it to work reliably. The below plot is for ~25k data points on a (reasonably idle) Windows machine when using a direct network connection with static ip. Unfortunately, even at that many samples there are still a few swaps. You may be able to make it work, but it'd probably require a dedicated linux machine on a separate network with several minutes of samples in order to be reliable enough.
Code: Select all
rtt = (log.pcRxTime - log.pcTxTime) * 1E3; [~,idx] = sort(mean(rtt));
2) Manual Setup
When I had to sort a large number of modules (e.g. the setup of 36) I wrote a little script that iterated through all modules, highlighted one of the device's LEDs, and asked for manual input about what index it should be. I then generated a sortable name, and used createGroupFromFamily() to create an alphabetically sorted group. I unfortunately don't have the full code handy, but below is a matlab snippet I use to visually verify the order.
Code: Select all
group = HebiLookup.newGroupFromFamily('robot'); leds = zeros(group.getNumModules, 3); while true leds(:) = 0; for i = 1:group.getNumModules leds(i,:) = [1 0 0]; group.send('led', leds); pause(0.05); % or pause and ask for the corresponding index end end
Since I don't have a serial-chain robot, the IMU method would be hard to use. I am looking for methods that could help me determine the leg ordering on a hexapod, for instance, where each leg is plugged into a network switch (my case), or when all legs are in a big chain like Daisy.
The network latency thing seems interesting. I wonder if there's some way to make that more reliable?
It seems unintuitive to me that this should be such a difficult problem, so I am still optimistic that some creative solution exists.
What about the network switch? Any ideas on whether it is possible to get which port a device is plugged into on a switch? If I could do that, then I could always use port 1 for leg 1, etc. but I am not sure if its really feasible to do via a script with a cheap switch.
This situation is why two of the buttons in Scope on the Dashboard, and in the right-click menu for the Module List, are 'Red LED' and 'Clear LED'. You can select an actuator, and manually check the position on the robot, and then change its name, paste its SN, or whatever other method you use to make your groups.
Sorry if you know about this already. Just wanted to point this out, since having all the serial numbers / names in Scope at least keeps you from having to physically find the serial numbers on the actuators on the robot. But you do have to be close enough to see the LED color.
Hope that helps,
It's a shame that the switches technically already know about the network topology (see Spanning Tree Protocl), but so far I've unfortunately never found a good way to access that information.