How to set ROS_MASTER_URI with snapcraft

Hi all,
As the title mentioned, I can not figure out the way to change the ROS_MASTER_URI for the a ros snap that I created by snapcraft.

Here are what I tried so far. My workspace has a package named main_launch, which has a launch file usb_cam.launch as follow:

<launch>
   <arg name="video_device" default="/dev/video0" />
  <machine name="quad_1" 
            address= "192.168.0.6"
            env-loader="~/.bashrc"
            user="master_computer"
            password="pwd1"
            default= "false" >
   </machine>
   <nodemachine="quad_1"  name="usb_cam" pkg="usb_cam" type="usb_cam_node" output="screen" >      
  </node>
</launch>

and in the ~/.bashrc file, i added the following line

export ROS_HOSTNAME=192.168.0.6
export ROS_MASTER_URI=http://192.168.0.28:11311/
source /opt/ros/lunar/setup.bash
source ~/my_Workspace/devel/setup.bash

Above, 192.168.0.28 is the ip address of Master compute, which will run roscore. 192.168.0.6 is the ip address of Remote computer, that I will run the snap package.

My snapcraft.yaml is as follows:

grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots

parts:
  workspace:    
    plugin: catkin
    rosdistro: lunar
    catkin-packages: [main_launch, aruco_localization]

apps:
  usbcam:
    command: roslaunch main_launch usb_cam_launch.launch 
    plugs: [network, network-bind]

Then I compiled snap by snapcraft, and install the snap package on my remote computer,
On MAster Computer, I run roscore.
On Remote, I do:my-ros-snap.usbcam, but I still see this

auto-starting new master
process[master]: started with pid [4297]
ROS_MASTER_URI=http://localhost:11311

Verify on the master by running rostopic list, none of the usb_cam topics are published.

I also tried edit the snapcraft.yaml file as

apps:
  usbcam:
    command: export ROS_MASTER_URI=http://192.168.0.28:11311
    command: roslaunch main_launch usb_cam_launch.launch 
    plugs: [network, network-bind]

but nothing works.

Please let me know if you need any additional info to clarify the problem. Thanks in advance.

have you tried putting it all in one line like:

command: ROS_MASTER_URI=http://192.168.0.28:11311 roslaunch main_launch usb_cam_launch.launch 

or alternatively create a wrapper shell script that exports and execs

Hi Ogra, thanks for your reply. The first solution gives me error.

FileNotFoundError: [Errno 2] No such file or directory: ~/workspace/prime/ROS_MASTER_URI=http://192.168.0.6:11311'

ABout the second solution, I am not sure how to proceed. Can you show me a minimal example how to do that?

I may be wrong, but I suspect that, when snapcraft compiles a ros package, it always runs roscore at beginning. That is why I can do two roscore at the same time, which is very against the principle of ROS.

Here is my experiement. In the same computer, I started roscore on terminal.
And then, I run the my-ros-snap.usbcam and they both run without complaining another roscore already run.

You probably want to either add a wrapper script which sets the environment, or use the snapcraft.yaml environment stanza:

apps:
  usbcam:
    command: roslaunch main_launch usb_cam_launch.launch 
    environment:
      ROS_MASTER_URI: http://192.168.0.28:11311
    plugs: [network, network-bind]

Hi Daniel,
Thanks for your reply, but it still does not work.
Here is what I did, after modifying the snapcraft.yaml as your suggestion

sudo snap remove my-ros-snap
snapcraft clean
snapcraft 
sudo snap install --devmode my-ros-snap_0.1_amd64.snap

but it still starts its own roscore.

I found the post from kyrofa blog, which needs to go through plugs. I will try it and report the results later. Thanks for your help.

Ok, I finally made it. It is actually very simple, just add the command:

catkin-ros-master-uri: http://192.168.0.28:11311

in the snapcraft.yaml file, as illustrated as follow:

parts:
  workspace:    
    plugin: catkin
    rosdistro: lunar
    catkin-packages: [main_launch]
    catkin-ros-master-uri: http://192.168.0.6:11311

apps:
  usbcam:
    command: roslaunch main_launch usb_cam_launch.launch 
    plugs: [network, network-bind]

Unfortunately, this ROS Snap document does not mention it. But you can find it by

snapcraft help catkin

Hopefully, it can help someone with the novice questions like me.

3 Likes

@kyrofa I need a dynamic value for ROS_MASTER_URI (not known at time of packaging the snap). Would it be possible to make this a configuration option for the snap (https://snapcraft.io/docs/configuration-in-snaps)?

Absolutely, @thymythos. There are a few different ways that can be achieved, but the easiest is probably to make your app a simple wrapper that handles that configuration and properly sets that environment variable. I worked up a quick example for you that does nothing more than snap rostopic.

The idea is this:

As a quick demo, I didn’t have roscore running locally, but I had it running on 10.203.138.130:

$ snapcraft
<snip>       
Snapped ros-configurable-master-uri_0.1_amd64.snap

$ sudo snap install ros-configurable-master-uri_0.1_amd64.snap --dangerous
ros-configurable-master-uri 0.1 installed

$ sudo snap get ros-configurable-master-uri ros-master-uri
http://localhost:11311

$ ros-configurable-master-uri.rostopic list
ERROR: Unable to communicate with master!

$ sudo snap set ros-configurable-master-uri ros-master-uri=http://10.203.138.130:11311

$ sudo snap get ros-configurable-master-uri ros-master-uri
http://10.203.138.130:11311

$ ros-configurable-master-uri.rostopic list
/rosout
/rosout_agg

Note that the configure hook can help ensure an invalid config isn’t accepted (although my regex is pretty bare-bones as you can tell):

$ sudo snap set ros-configurable-master-uri ros-master-uri=foo
error: cannot perform the following tasks:
- Run configure hook of "ros-configurable-master-uri" snap (run hook "configure": 'foo' is not a valid ROS master URI)

$ sudo snap get ros-configurable-master-uri ros-master-uri
http://10.203.138.130:11311

Thanks for your fast and thorough reply. Would it be possible to make this kind of default for the catkin plugin?

I’d need to think about it some more, but I’d say it’s possible. It would be breaking new ground as far as snapcraft plugins go to generate a default set of hooks like what would be required, though. And I don’t know how snapcraft would deconflict if the user wanted to include their own hooks. It might be too much magic to be user-friendly.

Snapcraft plugins could adopt a pattern that I’ve documented at https://snapcraft-utils-library.readthedocs.io/en/latest/lib/extensible-hooks.html

The big PRO here is that all snaps tend to have the same hook/parameters for the same thing. It’s not very user friendly if snap A has ros-master-uri while snap B uses my-ros-uri.