fkie / multimaster_fkie

ROS stack with FKIE packages for multi-robot (discovering, synchronizing and management GUI)
BSD 3-Clause "New" or "Revised" License
272 stars 106 forks source link

Possible to use localhost for ROS and define an external IP? #75

Closed AlexisTM closed 6 years ago

AlexisTM commented 6 years ago

I am willing to start the multimaster at boot, but the network (Zerotier VPN) is not ready so roscore fails.

The VPN conncets to the internet via a 4G module, meaning that it takes at least 1 minute to be "ready".

I guess the master sync is using the ros master server directly, so it does not allow to use localhost to start and listen to/advertise another IP?

atiderko commented 6 years ago

Using localhost for communication between master_sync and roscore is not the problem. But if you use localhost in _ROS_MASTERURI it can lead to problems in communication to remote ROS nodes.

See http://wiki.ros.org/ROS/EnvironmentVariables

Is it possible to delay start of ROS nodes until VPN is ready?

AlexisTM commented 6 years ago

The VPN is a "virtual interface" so the systemd triggers are not working; The network is not ready when the virtual device wakes up.

Which of the following solutions would be best:

atiderko commented 6 years ago

Does the ROS Master start if VPN is not ready? If yes: it would be better to wait in the main function of FKIE application until VPN is ready. if no: you need an external script or something else what trigger a roslaunch start after VPN is ready.

_default_cfgfkie can delay a start of nodes or start these after a defined publisher topic is available. Each node in roslauch needs follow parameter:

    <param name="default_cfg/autostart/required/publisher" value="topic_name" />
AlexisTM commented 6 years ago

No, the master will not start before the IP is set. I'll go for the script checking the interface and starting the roslaunch as soon as ready

AlexisTM commented 6 years ago

For future reference, this it the solution I chose:

Service file: /lib/systemd/system/robot.service

[Unit]
Description=Robot bringup for the universe app manager and multimaster 

[Service]
User=alexis
Group=alexis
ExecStart=/usr/share/bringup.sh

[Install]
WantedBy=multi-user.target

Bringup script: /usr/share/bringup.sh

#!/bin/bash

# Wait until zerotier network is ready using python one-liner
FOUND_IP=$(python -c "import socket; import fcntl; import struct; from time import sleep

def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,  # SIOCGIFADDR
        struct.pack('256s', ifname[:15])
    )[20:24])

while True:
  try:
    print get_ip_address('ztuzethfie')
    break
  except: 
    sleep(0.1)")
# End of python

bash -c "source /home/alexis/rossetup.bash && ROS_IP=$FOUND_IP ROS_HOSTNAME=$FOUND_IP ROS_MASTER_URI=http://$FOUND_IP:11311 stdbuf -oL roslaunch platform bringup_robot.launch"
atiderko commented 6 years ago

@AlexisTM thank you for sharing!