如何自动从 .xacro 文件中提取 xacro 属性 并在 ROS 的 python 脚本中使用它
how to automate xacro property extraction from .xacro file and use it in a python script in ROS
我已经为轮式机器人创建了一个 xacro 文件。
它的一个片段是这样的:
<robot name="em_3905" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- Degree-to-radian conversions -->
<xacro:property name="degrees_45" value="0.785398163"/>
<xacro:property name="degrees_90" value="1.57079633"/>
<!-- chassis_length is measured along the x axis, chassis_width
along the y axis, and chassis_height along the z axis. -->
<xacro:property name="chassis_length" value="4"/>
<xacro:property name="chassis_width" value="1"/>
<xacro:property name="chassis_height" value="0.01"/>
<xacro:property name="chassis_mass" value="2.788"/>
<xacro:property name="wheel_radius" value="0.2"/>
我有一个 python 脚本,它依赖于此 xacro 文件中的 chassis_length and chassis_width and wheel_radius
参数。
和我的 python_script:
#!/usr/bin/env python
import rospy
import numpy as np
from numpy import pi
from std_msgs.msg import Float64
from geometry_msgs.msg import Twist
class steering:
def __init__(self):
rospy.init_node("steering_controller", anonymous=True)
rospy.Subscriber("/cmd_vel", Twist, self.cmd_vel_callback)
self.steering_L_pub = rospy.Publisher("/xacro/left_steering_wheel_position_controller/command", Float64, queue_size=10)
self.steering_R_pub = rospy.Publisher("/xacro/right_steering_wheel_position_controller/command", Float64, queue_size=10)
self.str_L = Float64()
self.str_R = Float64()
self.drive_L = Float64()
self.drive_R = Float64()
self.Vx = 0.0
self.Wz = 0.0
self.max_alp = pi/2.0
## Car paramters
self.wheel_radius = 0.2 # meter
self.chassis_length = 4
self.chassis_width = 1
self.run()
rospy.spin()
我不想手动更改这两个文件的这些参数,而是想通过某种方式在 ROS 中链接这些文件来自动执行此操作。
我知道我可以在 python 中使用一个简单的文件打开和提取操作,但是在 ROS 中有没有更好的方法来做到这一点,比如使用 set_params?
如果是,你如何从 xacro 文件中获取参数。
我在之前的项目中所做的实际上是将Xacro作为机器人模型加载到参数服务器,然后从参数服务器获取URDF到节点中,从中提取相应的参数。通过这种方式,您可以确保您的工作区是一致的,并且每个节点都具有相同的参数集。通常,这只有在您定义的参数随后也在 URDF 内部使用并且不仅用作中间步骤时才有用。 (如果你真的需要,你可以用额外的未使用的虚拟元素使它们可见。
让我们通过 Xacro 文件 urdf/some_robot.xacro
给出的简单机器人模型来完成它:
<?xml version="1.0"?>
<robot
xmlns:xacro="http://www.ros.org/wiki/xacro" name="some_robot">
<xacro:property name="angle_x" value="${pi/4}"/>
<xacro:property name="angle_y" value="${pi/2}"/>
<xacro:property name="length" value="1"/>
<xacro:property name="width" value="2"/>
<xacro:property name="height" value="3"/>
<xacro:property name="mass" value="4"/>
<link name="some_link">
<visual name="some_link_visual">
<geometry>
<box size="${length} ${width} ${height}"/>
</geometry>
<origin xyz="0 0 0" rpy="${angle_x} ${angle_y} 0"/>
</visual>
<inertial>
<mass value="${mass}"/>
<origin xyz="0 0 0" rpy="0 0 0"/>
<inertia ixx="1" ixy="0" ixz="0"
iyy="1" iyz="0"
izz="1"/>
</inertial>
</link>
</robot>
如您所见,也可以使用 pi
进行计算,而无需手动输入其数值:see 4. Math expressions.
然后让我们创建一个名为 launch/parsing_example.launch
的启动文件,它将此 Xacro 作为 robot description
加载到参数服务器上:
<launch>
<param name="robot_description" command="$(find xacro)/xacro '$(find parsing_example)/urdf/some_robot.xacro'"/>
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
</launch>
最后是一个真正读取机器人描述的节点scripts/parsing_example
#!/usr/bin/env python
import roslib; roslib.load_manifest("urdfdom_py");
import rospy
from urdf_parser_py.urdf import URDF
if __name__ == '__main__':
rospy.init_node("parsing_example", anonymous=True)
# Fetch model from parameter server
robot = URDF.from_parameter_server()
# Check if robot model is valid
robot.check_valid();
# Print the robot model
print(robot)
# Extract information from node
link = robot.link_map["some_link"]
print(link.inertial.mass)
print(link.visual.geometry.size[0])
机器人模型到底是一个结构体,你可能会提取different ways
中包含的信息
- 您可以使用
link_map
and joint_map
等地图与 link 或联合 robot.link_map["some_link"]
的相应名称
- 您可以通过他们的列表索引访问它们
link.visuals[0].geometry.size[0]
- 或者你可以简单地遍历它们
在 robot.joints 中联合:
打印(联合)
然后您应该能够通过打开两个新控制台启动代码,获取工作区并键入
$ roslaunch parsing_example some_robot.launch
$ rosrun parsing_example parsing_example.py
我已经为轮式机器人创建了一个 xacro 文件。 它的一个片段是这样的:
<robot name="em_3905" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- Degree-to-radian conversions -->
<xacro:property name="degrees_45" value="0.785398163"/>
<xacro:property name="degrees_90" value="1.57079633"/>
<!-- chassis_length is measured along the x axis, chassis_width
along the y axis, and chassis_height along the z axis. -->
<xacro:property name="chassis_length" value="4"/>
<xacro:property name="chassis_width" value="1"/>
<xacro:property name="chassis_height" value="0.01"/>
<xacro:property name="chassis_mass" value="2.788"/>
<xacro:property name="wheel_radius" value="0.2"/>
我有一个 python 脚本,它依赖于此 xacro 文件中的 chassis_length and chassis_width and wheel_radius
参数。
和我的 python_script:
#!/usr/bin/env python
import rospy
import numpy as np
from numpy import pi
from std_msgs.msg import Float64
from geometry_msgs.msg import Twist
class steering:
def __init__(self):
rospy.init_node("steering_controller", anonymous=True)
rospy.Subscriber("/cmd_vel", Twist, self.cmd_vel_callback)
self.steering_L_pub = rospy.Publisher("/xacro/left_steering_wheel_position_controller/command", Float64, queue_size=10)
self.steering_R_pub = rospy.Publisher("/xacro/right_steering_wheel_position_controller/command", Float64, queue_size=10)
self.str_L = Float64()
self.str_R = Float64()
self.drive_L = Float64()
self.drive_R = Float64()
self.Vx = 0.0
self.Wz = 0.0
self.max_alp = pi/2.0
## Car paramters
self.wheel_radius = 0.2 # meter
self.chassis_length = 4
self.chassis_width = 1
self.run()
rospy.spin()
我不想手动更改这两个文件的这些参数,而是想通过某种方式在 ROS 中链接这些文件来自动执行此操作。 我知道我可以在 python 中使用一个简单的文件打开和提取操作,但是在 ROS 中有没有更好的方法来做到这一点,比如使用 set_params? 如果是,你如何从 xacro 文件中获取参数。
我在之前的项目中所做的实际上是将Xacro作为机器人模型加载到参数服务器,然后从参数服务器获取URDF到节点中,从中提取相应的参数。通过这种方式,您可以确保您的工作区是一致的,并且每个节点都具有相同的参数集。通常,这只有在您定义的参数随后也在 URDF 内部使用并且不仅用作中间步骤时才有用。 (如果你真的需要,你可以用额外的未使用的虚拟元素使它们可见。
让我们通过 Xacro 文件 urdf/some_robot.xacro
给出的简单机器人模型来完成它:
<?xml version="1.0"?>
<robot
xmlns:xacro="http://www.ros.org/wiki/xacro" name="some_robot">
<xacro:property name="angle_x" value="${pi/4}"/>
<xacro:property name="angle_y" value="${pi/2}"/>
<xacro:property name="length" value="1"/>
<xacro:property name="width" value="2"/>
<xacro:property name="height" value="3"/>
<xacro:property name="mass" value="4"/>
<link name="some_link">
<visual name="some_link_visual">
<geometry>
<box size="${length} ${width} ${height}"/>
</geometry>
<origin xyz="0 0 0" rpy="${angle_x} ${angle_y} 0"/>
</visual>
<inertial>
<mass value="${mass}"/>
<origin xyz="0 0 0" rpy="0 0 0"/>
<inertia ixx="1" ixy="0" ixz="0"
iyy="1" iyz="0"
izz="1"/>
</inertial>
</link>
</robot>
如您所见,也可以使用 pi
进行计算,而无需手动输入其数值:see 4. Math expressions.
然后让我们创建一个名为 launch/parsing_example.launch
的启动文件,它将此 Xacro 作为 robot description
加载到参数服务器上:
<launch>
<param name="robot_description" command="$(find xacro)/xacro '$(find parsing_example)/urdf/some_robot.xacro'"/>
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
</launch>
最后是一个真正读取机器人描述的节点scripts/parsing_example
#!/usr/bin/env python
import roslib; roslib.load_manifest("urdfdom_py");
import rospy
from urdf_parser_py.urdf import URDF
if __name__ == '__main__':
rospy.init_node("parsing_example", anonymous=True)
# Fetch model from parameter server
robot = URDF.from_parameter_server()
# Check if robot model is valid
robot.check_valid();
# Print the robot model
print(robot)
# Extract information from node
link = robot.link_map["some_link"]
print(link.inertial.mass)
print(link.visual.geometry.size[0])
机器人模型到底是一个结构体,你可能会提取different ways
中包含的信息- 您可以使用
link_map
andjoint_map
等地图与 link 或联合robot.link_map["some_link"]
的相应名称
- 您可以通过他们的列表索引访问它们
link.visuals[0].geometry.size[0]
- 或者你可以简单地遍历它们 在 robot.joints 中联合: 打印(联合)
然后您应该能够通过打开两个新控制台启动代码,获取工作区并键入
$ roslaunch parsing_example some_robot.launch
$ rosrun parsing_example parsing_example.py