ROS YAML文件中能否使用环境变量?Launch加载场景实现方法问询
当然可以实现!你说的这种把环境变量放进独立YAML文件的需求非常合理,尤其是参数较多的时候,能让配置更整洁。ROS本身就支持这个功能,下面给你两种简单靠谱的实现方法:
方法一:开启rosparam的参数替换功能
默认情况下,rosparam不会解析YAML里的环境变量占位符,但只需要在launch文件的rosparam标签里添加substitute_args="true"参数,就能让它自动识别并替换${}包裹的环境变量。
修改你的test.launch文件:
<launch> <rosparam command="load" file="example.yaml" substitute_args="true" /> </launch>
你的example.yaml保持不变即可:
vehicle_name: "${VEHICLE_NAME}_robot"
这样运行launch文件时,ROS会自动把${VEHICLE_NAME}替换成当前环境中该变量的值,最终得到类似my_robot_robot(假设VEHICLE_NAME=my_robot)的参数值。
方法二:使用ROS的命令替换语法(ROS Noetic+适用)
如果你使用的是ROS Noetic或更新的版本,还可以直接在YAML里用$(env)语法来引用环境变量,同样需要配合substitute_args="true":
修改example.yaml为:
vehicle_name: "$(env VEHICLE_NAME)_robot"
launch文件的修改和方法一一样,添加substitute_args="true"即可。这种语法的好处是可以和optenv结合,给环境变量设置默认值,避免变量不存在时出错:
vehicle_name: "$(optenv VEHICLE_NAME default_vehicle)_robot"
如果环境中没有设置VEHICLE_NAME,就会自动使用default_vehicle作为默认值,最终得到default_vehicle_robot。
额外提示:在launch中设置环境变量
如果你需要在launch文件内部定义环境变量,而不是依赖终端的环境,可以用<env>标签:
<launch> <!-- 直接设置环境变量 --> <env name="VEHICLE_NAME" value="my_car" /> <rosparam command="load" file="example.yaml" substitute_args="true" /> </launch>
这样不管终端环境有没有该变量,launch运行时都会使用这里设置的值。
内容的提问来源于stack exchange,提问作者Michael Everett

