oysstu / pyimc

Python bindings for Inter-Module Communication Protocol (IMC)
Other
9 stars 6 forks source link

Vehicle not connected & Estimated State #7

Open JuanFuriaz opened 2 years ago

JuanFuriaz commented 2 years ago

Hi Oysstu,

first of all thanks for developing this awesome project!

I'm trying to develop an avoidance system for UAV and I'll like to use pyimc for sending instructions to the vehicle. I installed pyimc using the current IMC, Dune and Neptus versions available in their repositories with python 3.7. I'm using a DUNE simulation of the 'lauv-xplore-1' vehicle to test keyboard_input_example.py but I'm not able to use it correctly. It works to stop the vehicle but the start method doesn't work:

INFO:pyimc.actors.base:Starting file log (/tmp/pyimc/ccu-pyimc-jm/20211203/083813)
DEBUG:asyncio:Using selector: EpollSelector
DEBUG:pyimc.actors.base:Connected nodes: []
DEBUG:pyimc.actors.base:Connected nodes: [(30, 'lauv-xplore-1')]
DEBUG:pyimc.actors.base:Connected nodes: [(30, 'lauv-xplore-1')]
start
INFO:examples.KeyboardActor:Vehicle not connected

In addition, I tried to get more info about the estimated state using @Subscribe(pyimc.EstimatedState) but I doesn't get any response, which could be an answer to why the start method in keyboard_input_example.py says that the vehicle is not connected.

Any help will be appreciated!

Best regards

Juan

oysstu commented 2 years ago

Hi Juan,

Have you changed the name of the vehicle at the bottom of keyboard_input_example.py (actor = KeyboardActor('lauv-simulator-1'))?

There's two modes of communication in DUNE/IMC. The first, uses multicast, and is intended to broadcast the name, location, and ip address/connection info of all vehicles (this uses multicast, so that the IP of the target does not need to be known). The second, is direct communication between two IMC-nodes. This generally requires a heartbeat message to be sent periodically. In pyimc, the heartbeat sending is done automatically by adding the name of the target vehicle in the heartbeat list (see the constructor in the example). Since the vehicle appears in the connected nodes list, the multicast announce has been received, but to subscribe to additional messages, you need to establish the second communcation link.

I hope this answers your question

Regards, Øystein

JuanFuriaz commented 2 years ago

Hi Øystein,

Thanks for your quick response!

Yes, I used initially actor = KeyboardActor('lauv-xplore-1') but I also now tried with actor = KeyboardActor('lauv-xplore-1') in keyboard_input_example.py, while running in dune the command ./dune -d ../etc -c lauv-xplore-1 -p Simulation. This didn't work...

In addition, I checked if the heartbeats are getting activated and they do (I went into the DynamicActor class). If I understand correctly the second communication link should now happen automatically but it's not working for some reason. Can I do something else in order to force the second communication link? Or do you have any other ideas?

Best regards, Juan

oysstu commented 2 years ago

Hi Juan,

The announces are sent on a fixed ip/port using udp multicast. Any other messages (such as heartbeat) is sent using the following function: https://github.com/oysstu/pyimc/blob/5dd6a70f823fd9c7d94b4e1da310337fe40d95cf/pyimc/node.py#L136

This basically takes the "services" field in the announce message from the target and sends to an ip/port which is listed as "udp+imc" (e.g. IMC over UDP). The target may have multiple network interfaces, and the loop in that function therefore sends to the first service which appears to be reachable from a local network interface. If none are connectable, it sends over the local loopback interface (127.0.0.1), e.g. if both dune and pyimc is running on a local computer without any network connection.

I suggest that you attempt to start your debugging in this function. The reason why it only sends on one reachable interface is to avoid duplicate messages, but perhaps it's using the wrong interface for some reason. Try to simplify your network connection to the computer running DUNE.

You can also try to add a static transport to the DUNE IMC ip:port using the following function, then it will be completely independent of the node discovery. https://github.com/oysstu/pyimc/blob/5dd6a70f823fd9c7d94b4e1da310337fe40d95cf/pyimc/actors/base.py#L279

Edit: also check if the DUNE instance recieves your announce messages. There's currently a bug on Windows with multicast sending.