ROS2与Gazebo11入门教程-力/扭矩传感器
说明:
- 介绍如何在关节上使用力/扭矩传感器
快速开始
第1部分:查看运行中的传感器
创建一个含有力/扭矩传感器的仿真世界
将下述代码表示的仿真世界另存为force_torque_tutorial.world文件:
<?xml version="1.0"?>
<sdf version="1.6">
<world name="default">
<physics name="default_physics" default="0" type="ode">
<max_step_size>0.001</max_step_size>
<real_time_factor>1</real_time_factor>
<real_time_update_rate>1000</real_time_update_rate>
<ode>
<solver>
<type>quick</type>
<iters>50</iters>
<sor>1.0</sor> <!-- Important, see issue #2209 -->
<use_dynamic_moi_rescaling>false</use_dynamic_moi_rescaling>
</solver>
</ode>
</physics>
<include>
<uri>model://ground_plane</uri>
</include>
<include>
<uri>model://sun</uri>
</include>
<model name="model_1">
<link name="link_1">
<pose>0 0 2.0 0 0 0</pose>
<inertial>
<inertia>
<ixx>0.100000</ixx>
<ixy>0.000000</ixy>
<ixz>0.000000</ixz>
<iyy>0.100000</iyy>
<iyz>0.000000</iyz>
<izz>0.100000</izz>
</inertia>
<mass>10.000000</mass>
</inertial>
<visual name="visual_sphere">
<geometry>
<sphere>
<radius>0.100000</radius>
</sphere>
</geometry>
</visual>
<visual name="visual_cylinder">
<pose>0 0 -0.75 0 0 0</pose>
<geometry>
<cylinder>
<radius>0.0100000</radius>
<length>1.5</length>
</cylinder>
</geometry>
</visual>
<collision name="collision_sphere">
<max_contacts>250</max_contacts>
<geometry>
<sphere>
<radius>0.100000</radius>
</sphere>
</geometry>
</collision>
</link>
<joint name="joint_01" type="revolute">
<parent>world</parent>
<child>link_1</child>
<pose>0 0 -1.5 0 0 0</pose>
<axis>
<limit>
<lower>-1.57079</lower>
<upper>1.57079</upper>
</limit>
<dynamics>
<damping>0.000000</damping>
<friction>0.000000</friction>
</dynamics>
<xyz>1.000000 0.000000 0.000000</xyz>
</axis>
<sensor name="force_torque" type="force_torque">
<update_rate>30</update_rate>
</sensor>
</joint>
</model>
</world>
</sdf>
- 启动该仿真世界,打开一个终端,并运行以下命令:
gazebo --verbose force_torque_tutorial.world
- 浏览力/扭矩传感器的输出数据,在一个新终端中,用以下命令打开话题浏览器:
gz topic --view /gazebo/default/model_1/joint_01/force_torque/wrench
- 在Gazebo中施加力和扭矩,在Y轴正方向上向link_1施加一个力,该力的大小为500N,然后在话题浏览器窗口中观察输出结果。
第2部分:上述步骤的说明
- 仿真世界开始时
- 这个仿真世界有一个链接和一个关节。该链接是一个质量为10kg的球体,与关节之间的距离为1.5m。该关节将球体与仿真世界连接起来,允许其绕X轴旋转。开始时,球体在关节上保持平衡。此时,该关节上没有扭矩。该关节上的力来自重力。
forceJointZ = mass * g
= 10 kg * -9.8 m/s^2
= -98 N
- 向链接施加一个力之后
- 向链接link_1施加一个力会使它倾倒并以90度角(关节的极限)停下来。该极限是使球体悬停在地面上的原因。此时,关节的Y轴正方向指向地面。作用在球体上的重力会绕X轴施加一个扭矩
- 该关节支撑的质量仍然是相同的,因此重力的大小也还是相同的。但重力的方向变成了Y轴上的+98N。由于球体位于该关节Z轴的1.5m处,因此绕X轴的扭矩为:
torqueJoint01_x = r X R
= ||r|| * ||F|| * sin(theta)
= distanceZ * (massLink * g) * sin(theta)
= 1.5 m * (10 kg * 9.8 m/s^2) * sin(-90)
= -147 Nm
- 取决于物理引擎参数,关节极限附近的测量值可能会发生跳跃。更多相关信息,请参见问题#2209
了解力/扭矩传感器
- SDF参数
- 通用参数,在SDF传感器结构中,所有传感器都有一组通用的参数,包括:
always_on
- 如果为true,则传感器将会一直测量力和扭矩。如果为false,则仅当有订阅者连接到传感器的话题时,传感器才会更新力和扭矩。在通过代码访问传感器时,这个设置很重要。如果没有订阅者,对ForceTorqueSensor :: Torque()或ForceTorqueSensor :: Force()的调用将会返回旧数据。这可以通过检查IsActive()是否返回false值来发现。通过调用SetActive(true),代码可以在没有订阅者的情况下对传感器数据进行更新。
update_rate
- 这是传感器应自行更新的速率(单位为Hz)。它是该传感器每秒仿真时间内发布的消息条数。
visualize
- 如果为true,则Gazebo客户端将会显示关节处力和扭矩的可视化效果。
topic
- 力/扭矩传感器当前不支持此参数。
frame
- 力/扭矩传感器当前不支持此参数。
pose
- 以x y z roll pitch yaw的顺序由空格分隔开的6个浮点数。此参数描述了传感器坐标系相对于父关节的位置。
力/扭矩特定参数
- 通过添加属性type值设置为force_torque的
标签来创建力/扭矩传感器。可以设置另外两个参数。
<sensor name="my_cool_sensor" type="force_torque">
<force_torque>
<frame>child</frame>
<measure_direction>child_to_parent</measure_direction>
</force_torque>
</sensor>
frame
- 此元素的值可以是下面中的一个:child,parent或sensor。它是用于表示力和扭矩的坐标系。值parent和值child分别指关节的父级链接和子级链接。值sensor表示由传感器的
的旋转分量旋转的度量值。位姿的平移分量对度量没有影响。
不管此设置的值为哪个,扭矩分量始终是绕关节坐标系原点的一种表示。
measure_direction
- 这就是度量的方向。尝试将上面的示例更改为parent_to_child。 倾倒后,该传感器会报告在Y轴上的力为-98N,而在X轴上的扭矩为+147Nm。这两个度量值与先前度量方向为child_to_parent时相同,但它们的方向则恰好相反。
向链接添加力/扭矩传感器
- 虽然SDF结构允许将
标签放置在链接上或关节上,但是力/扭矩传感器仅在关节上起作用。如果将力/扭矩传感器添加到某个链接上,则用--verbose参数运行gazebo会显示以下错误:
[Err] [http://Link.cc:114] A link cannot load a [force_torque] sensor.
对真实的力/扭矩传感器建模
- 上面的示例中将一个力/扭矩传感器放置在一个旋转关节上。然而,现实中的力/扭矩传感器通常刚性地安装到另一个刚体上。真实的传感器无法准确地测量旋转关节原点处的力和扭矩。如果真实传感器距离关节足够近,以至于与关节的偏移产生的误差可以忽略不计,则这种情况下进行力/扭矩传感器建模是合理的。
- 如果这个误差不能忽略,则可以在真实传感器所在位置处用一个固定关节将刚体拆分成两个链节。
参考:
获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号