Running a python node using eval in roslaunch
In my roslaunch file structure, I have a launch file that stores spawn and goal coordinates in the parameter server. Then I have another launch file that needs those coordinates, but the values need to be stored in an argument tag. I found a Q&A that suggests making a simple python node that retrieves the parameter and writes the value to sysout and running it using eval. However when I tried running the launch file with the syntax that was provided in the Q&A, I get the following error:
while processing /home/csrobot/catkin_ws/src/uml_3d_race/launch/spawn_robot.launch:
Invalid <arg> tag: name 'convert_param_to_arg' is not defined.
Arg xml is <arg default="$(eval convert_param_to_arg.py /spawn_x)" name="x"/>
The traceback for the exception was written to the log file
Note: I'm trying to run a python script called convertparamtoarg.py and trying to a pass a string parameter of /spawnx
My question: how do I make this work? Also, I am using roscpp so are there any cmake changes I need to make?
The launch file in question:
<!-- Assumes Gazebo is already running -->
<launch>
<!-- Settings (Robot position args are overidden by spawn_world.launch)-->
<arg name="x" default="$(eval convert_param_to_arg.py /spawn_x)" />
<arg name="y" default="$(eval convert_param_to_arg.py /spawn_y)" />
<arg name="z" default="$(eval convert_param_to_arg.py /spawn_z)" />
<arg name="yaw" default="$(eval convert_param_to_arg.py /spawn_yaw)" /> <!-- Rotation in radians. -->
<arg name="level" />
<arg name="navigate" />
<arg name="model_name" />
<arg name="model_type" />
<arg name="invert_goals" />
<!-- Launch respective robot -->
<include file="$(find race)/launch/robots/spawn_$(arg model_type).launch">
<arg name="x" value="$(arg x)" />
<arg name="y" value="$(arg y)" />
<arg name="z" value="$(arg z)" />
<arg name="yaw" value="$(arg yaw)" />
<!-- Rotation in radians. -->
<arg name="level" value="$(arg level)" />
<arg name="navigate" value="$(arg navigate)" />
<arg name="model_name" value="$(arg model_name)" />
</include>
<!-- Publish the two different goals needed for the given .world -->
<node unless="$(arg invert_goals)" name="goal_publisher" pkg="race" type="goal_publisher" output="screen" ns="$(arg model_name)">
<!-- Goal Positions -->
<remap from="~goal_x" to="/goal_x" />
<remap from="~goal_y" to="/goal_y" />
<remap from="~spawn_x" to="/spawn_x" />
<remap from="~spawn_y" to="/spawn_y" />
</node>
</launch>
The python script convertparamto_arg.py
#!/usr/bin/env python
import rospy
import sys
rospy.init_node('convert_param_to_arg')
param_name = 'param'
if sys.argv.count > 0:
param_name = sys.argv[0]
value = rospy.get_param(param_name)
sys.stdout.write(value)
Asked by Cobra2154 on 2020-09-11 10:58:51 UTC
Answers
I'm equally baffled by the answer in the question that you linked. Looking at the code for roslaunch I don't see how it ever would have been possible to run full fledged python script. The underlying python code for eval eventually calls the python eval function. The eval function can really only evaluate expressions (something that can resolve to a value). With the setup given I just don't see any way to launch a python script to do what you want.
https://github.com/ros/ros_comm/issues/723 and the corresponding PR: https://github.com/ros/ros_comm/pull/1993 might be of interest as it proposes a new param substitution that would do what you are interested in doing. The last update on this issues was 10/5/20 so maybe this issue will be get merged soon.
Until then the only option that I know of is to to create a script that converts params into args that then roslaunches the actual script. This might look something like this for you:
#!/bin/bash
roslaunch package_name foo.launch x:=$(rosparam get /spawn_x) y:=$(rosparam get /spawn_y) z:=$(rosparam get /spawn_z) yaw:=$(rosparam get /spawn_yaw)
You could either call this script directly or wrap in another launch file. Yes this is ugly and it would be nice if you can access the params directly like in the above mentioned PR.
Asked by ddedrick on 2020-11-10 17:40:22 UTC
Comments
@Refresh Same issue for me. Don't say there is no way to get rosparams inside launch files...
Asked by definitive on 2020-10-20 07:34:44 UTC