Ask Your Question
2

Running a python node using eval in roslaunch

asked 2020-09-11 10:58:51 -0500

Cobra2154 gravatar image

updated 2020-09-11 11:07:11 -0500

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 convert_param_to_arg.py and trying to a pass a string parameter of /spawn_x

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 convert_param_to_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)
edit retag flag offensive close merge delete

Comments

1

@Refresh Same issue for me. Don't say there is no way to get rosparams inside launch files...

definitive gravatar image definitive  ( 2020-10-20 07:34:44 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2020-11-10 16:40:22 -0500

ddedrick gravatar image

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/issue... and the corresponding PR: https://github.com/ros/ros_comm/pull/... 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.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2020-09-11 10:58:51 -0500

Seen: 544 times

Last updated: Oct 20 '20