ROS Kinetic:如何从launch文件向xacro文件传递参数?
嘿,这个需求完全可以实现!我帮你梳理下正确的操作步骤,顺便解决你遇到的那个报错问题:
先解决launch报错问题
你碰到的xxx.launch requires the 'ns' arg to be set错误,本质是因为你在launch文件里定义了<arg name="ns"/>但没给默认值,也没在启动时传递该参数。解决方法很简单:
- 要么给arg添加默认值,比如:
<arg name="ns" default="robot1"/> - 要么启动launch时手动传参:
roslaunch your_package your_launch.launch ns:=robot2
核心实现:从launch向xacro传递参数
要让不同机器人有不同的颜色或话题名称,需要分两步修改:
第一步:修改Xacro文件,支持外部传参
在你的xacro模型中,用<xacro:property>定义可外部赋值的参数,同时给个默认值防止无参时出错。示例如下:
<!-- 定义可外部传入的参数 --> <xacro:property name="robot_color" value="0.0 0.0 1.0" /> <!-- 默认蓝色 --> <xacro:property name="topic_prefix" value="robot1" /> <!-- 默认话题前缀 --> <!-- 引用参数设置材质颜色 --> <material name="robot_body"> <color rgba="${robot_color} 1.0" /> <!-- 这里自动补全alpha通道为1.0 --> </material> <!-- 引用参数自定义话题名 --> <sensor type="laser" name="laser"> <plugin name="laser_plugin" filename="libgazebo_ros_laser.so"> <topicName>/$(topic_prefix)/scan</topicName> </plugin> </sensor>
第二步:在Launch文件中传递参数并启动多机器人
用<group>给每个机器人设置独立的命名空间(ns),同时传递不同的xacro参数。这里提供两种常用写法:
写法一:通过xacro命令生成URDF后加载
<launch> <!-- 定义世界文件参数 --> <arg name="world_file" default="$(find your_package)/worlds/your_world.world" /> <!-- 启动第一个机器人 --> <group ns="robot1"> <!-- 传递参数给xacro,生成URDF --> <param name="robot_description" command="$(find xacro)/xacro $(find your_package)/urdf/your_robot.xacro robot_color:='0.0 0.0 1.0' topic_prefix:='robot1'" /> <!-- 启动机器人状态发布器 --> <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" /> <!-- 在gazebo中生成模型 --> <node name="spawn_robot1" pkg="gazebo_ros" type="spawn_model" args="-urdf -model robot1 -param robot_description -x 0.0 -y 0.0 -z 0.1" /> </group> <!-- 启动第二个机器人 --> <group ns="robot2"> <param name="robot_description" command="$(find xacro)/xacro $(find your_package)/urdf/your_robot.xacro robot_color:='1.0 0.0 0.0' topic_prefix:='robot2'" /> <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" /> <node name="spawn_robot2" pkg="gazebo_ros" type="spawn_model" args="-urdf -model robot2 -param robot_description -x 2.0 -y 0.0 -z 0.1" /> </group> <!-- 启动gazebo世界 --> <include file="$(find gazebo_ros)/launch/empty_world.launch"> <arg name="world_name" value="$(arg world_file)" /> </include> </launch>
写法二:直接用xacro标签传递参数(ROS Melodic及以上支持)
这种写法更简洁,不需要手动调用xacro命令:
<launch> <arg name="world_file" default="$(find your_package)/worlds/your_world.world" /> <!-- 第一个机器人 --> <group ns="robot1"> <xacro:include filename="$(find your_package)/urdf/your_robot.xacro"> <xacro:arg name="robot_color" value="0.0 0.0 1.0" /> <xacro:arg name="topic_prefix" value="robot1" /> </xacro:include> <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" /> <node name="spawn_robot1" pkg="gazebo_ros" type="spawn_model" args="-urdf -model robot1 -param robot_description -x 0.0 -y 0.0 -z 0.1" /> </group> <!-- 第二个机器人 --> <group ns="robot2"> <xacro:include filename="$(find your_package)/urdf/your_robot.xacro"> <xacro:arg name="robot_color" value="1.0 0.0 0.0" /> <xacro:arg name="topic_prefix" value="robot2" /> </xacro:include> <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" /> <node name="spawn_robot2" pkg="gazebo_ros" type="spawn_model" args="-urdf -model robot2 -param robot_description -x 2.0 -y 0.0 -z 0.1" /> </group> <include file="$(find gazebo_ros)/launch/empty_world.launch"> <arg name="world_name" value="$(arg world_file)" /> </include> </launch>
额外小贴士
- 命名空间(ns)是区分多机器人话题的核心,每个机器人放在独立的
<group>里设置ns后,话题会自动带上前缀(比如/robot1/scan),无需手动修改所有话题名。 - 传递颜色参数时,如果需要自定义alpha通道,可以直接传完整的rgba值,比如
1.0 0.0 0.0 0.8,然后在xacro里用<color rgba="${robot_color}" />。
内容的提问来源于stack exchange,提问作者BenW
相关产品推荐
相关产品推荐

