Force Torque Sensor - modulabs/gazebo-tutorial GitHub Wiki
์ด๋ฒ ํํ ๋ฆฌ์ผ์ ๊ด์ (joint)์ ์์ฉํ๋ forcre/torque sensor์ ์ฌ์ฉ๋ฒ์ ์ค๋ช ํ๋ค. ์ด ์ผ์๋ force, torque ์ฝ์๊ฐ์ topic์ผ๋ก publish ํ๋ค.
force_torque_tutorial.world
์ด๋ฆ์ผ๋ก 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>terminal์ ์ด๊ณ , ์ด ์ฝ๋๋ฅผ ์คํํ๋ค. (--verbose)
gazebo --verbose force_torque_tutorial.world
์๋ก์ด terminal์์ ๋ค์๊ณผ ๊ฐ์ ๋ช ๋ น์ด์ ํจ๊ป topic viewer๋ฅผ ์ฐ๋ค:
gz topic --view /gazebo/default/model_1/joint_01/force_torque/wrench
Y๋ฐฉํฅ์ผ๋ก 500N์ ํฌ๊ธฐ๋ก link_1์ Apply a force. topic viewer (ctrl-t)๋ก ๊ฒฐ๊ณผ๊ฐ์ ๋ณด์.
์ด world๋ ํ๋์ ๋งํฌ์ ํ๋์ ๊ด์ ์ ๊ฐ๋๋ค. ๋งํฌ๋ ๊ด์ ๋ก๋ถํฐ 1.5m offser์ ๊ฐ๋ 10kg, ๊ตฌ ๋ชจ์์ด๋ค. ๊ด์ ์ ๋งํฌ(child)์ world(parent)๋ก ์ฐ๊ฒฐ๋์ด ์๊ณ , x๋ฐฉํฅ์ผ๋ก ํ์ ์ด ๊ฐ๋ฅํ๋ค. ์๋ฎฌ๋ ์ด์ ์ด ์ฒ์ ์์ํ ๋๋ ๋งํฌ๋ ๊ด์ ์์์ ํํ์ ์ด๋ฃจ๊ณ ์๋ค. ์ด๋ torque๋ ์๋ค. ๊ด์ ์ ์์ฉํ๋ ํ์ ์ค๋ ฅ(-z ๋ฐฉํฅ)์ผ๋ก๋ถํฐ ์จ๋ค.
forceJointZ = mass * g
= 10 kg * -9.8 m/s^2
= -98 N
link_1์ ์ธ๋ ฅ์ ๋ฃ์ด์ฃผ๋ฉด, ๋งํฌ๋ฅผ ๋์ด์ง๊ณ , ๊ด์ ํ๊ณ์ธ 90๋์์ ๋ฉ์ถ๊ฒ ๋๋ค. ๊ด์ ํ๊ณ๋ ๋งํฌ๊ฐ ground plane ์์์ ๋ฉ์ถ ์ ์๋๋ก ์ ์งํด์ฃผ๋ ์ญํ ์ด๋ค. ๊ด์ ์ +Y๋ฐฉํฅ์ ground plane๋ก ๋ค์ด๊ฐ๋ ๋ฐฉํฅ์ด๋ค. ๋งํฌ์ ์์ฉํ๋ ์ค๋ ฅ์ x๋ฐฉํฅ์ผ๋ก ํ ํฌ๋ฅผ ๋ง๋ ๋ค.
์ง๋์ ๋์ผํ๊ณ , ํ์ ํฌ๊ธฐ๋ ๋์ผ. ํ์ ๋ฐฉํฅ์ Y๋ฐฉํฅ์ผ๋ก +98N๋๋๋ก ๋ณํํ๋ค. ๊ตฌ๋ Joint์ 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
Note: ๊ด์ limit ๊ทผ์ฒ ๊ตฌ๊ฐ์ ์ธก์ ๊ฐ์ ๋ฌผ๋ฆฌ ์์ง์ ํ๋ผ๋ฏธํฐ์ ๋ฐ๋ผ ํ ์ ์๋ค. issue #2209๋ฅผ ๋ณด์๋ผ
๋ชจ๋ ์ผ์๋ SDF sensor schema์์์ ๊ณตํต๋ ํ๋ผ๋ฏธํฐ set์ ๊ฐ๋๋ค.
๋ง์ฝ true๋ผ๋ฉด ์ผ์๋ ํญ์ force์ torque๋ฅผ ์ธก์ ํ๋ค. ๋ง์ฝ false๋ผ๋ฉด ์ผ์๋ subscriber๊ฐ sensor's topic์ ์ฐ๊ฒฐ๋์ด ์์๋๋ง ์
๋ฐ์ดํธ๊ฐ ๋๋ค. ์ด๋ฌํ ์ค์ ์ code๋ฅผ ํตํด ์ผ์๋ฅผ ์ ๊ทผํ ๋ ๋งค์ฐ ์ค์ํ๋ค. ๋ง์ฝ subscriber๊ฐ ์๋ค๋ฉด
ForceTorqueSensor::Torque() or ForceTorqueSensor::Force()๋ฅผ ๋ถ๋ฅด๋ ๊ฒ์ ์์ ํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ ๊ฒ์ด๋ค. ์ด๋ฌํ ๋ฌธ์ ๋ IsActive()๊ฐ false๋ฅผ ๋ฐํํ๋์ง๋ฅผ ํ์ธํ๋๊ฒ์ผ๋ก ๋ฐ๊ฒฌํ ์ ์๋ค. ์ฝ๋๋ SetActive(true)๋ฅผ
๋ถ๋ฆ์ผ๋ก์จ, ์ผ์๊ฐ subscriber๊ฐ ์๋ ์ํฉ์์ ์
๋ฐ์ดํธ ํ ์ ์๋๋ก ํ๋ค.
์ด๊ฒ์ ์ผ์๊ฐ ์ค์ค๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฐ์ดํธ ํ๋ rate (Hz)๋ฅผ ๋งํ๋ค. ์ด๊ฒ์ simulated second ๋ง๋ค ์ผ์์ ์ํด published๋๋ ๋ฉ์ธ์ง์ ์์ผ ๊ฒ์ด๋ค.
๋ง์ฝ ture๋ผ๋ฉด, gazebo client๋ ๊ด์ ์ ์์ฉํ๋ force์ torque๋ฅผ visualizationํ๋๊ฒ์ ๋ณด์ฌ์ค ๊ฒ์ด๋ค.
force/torque ์ผ์๋ ํ์ฌ ์ด ํ๋ผ๋ฏธํฐ๋ฅผ ์ง์ํ์ง ํ๋๋ค.
force/torque ์ผ์๋ ํ์ฌ ์ด ํ๋ผ๋ฏธํฐ๋ฅผ ์ง์ํ์ง ํ๋๋ค.
๊ณต๊ฐ์์์ 'x y z roll pitch yaw (position + orientation)'์ ์์์ Floating point number ์๋ฏธํ๋ค. ์ด๊ฒ์ parent joint๋ก๋ถํฐ ์ผ์ frame์ ๋ฌ์ฌํ๋ค.
force/torque sensor๋ <sensor> tag with the attribute type set to force_torque๋ฅผ ์ถ๊ฐํจ์ผ๋ก์จ ์์ฑํ ์ ์๋ค.
์๋์๋ ์ ๋ฐฉ๋ฒ ์ธ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ด 2๊ฐ์ง ๋ ์ ์๋์ด์๋ค.
<sensor name="my_cool_sensor" type="force_torque">
<force_torque>
<frame>child</frame>
<measure_direction>child_to_parent</measure_direction>
</force_torque>
</sensor>The value of this element may be one of: child, parent, or sensor.
It is the frame in which the forces and torques should be expressed.
The values parent and child refer to the parent or child links of the joint.
The value sensor means the measurement is rotated by the rotation component of the <pose> of this sensor.
The translation component of the pose has no effect on the measurement.
Regardless of this setting, the torque component is always expressed about the origin of the joint frame.
This is the direction of the measurement.
Try changing the example above to parent_to_child.
After being toppled the sensor reports a force of -98 N on the Y axis and a torque of +147 Nm about the X axis.
This is the same magnitude as before but opposite direction.
While the SDF schema allows a <sensor> tag to be placed on either a link or a joint, the force/torque sensor only works on joints.
If the sensor is added to a link, running gazebo with --verbose shows the following error:
[Err] [Link.cc:114] A link cannot load a [force_torque] sensor.
The above example places a force/torque sensor on a revolute joint. However, real force/torque sensors are typically rigidly mounted to another rigid body. A real sensor could not measure the force and torque exactly at the revolute joint origin. Modeling this way is reasonable if the real sensor is close enough to the joint that the error from the offset is negligible.
If this error is not negligible, the rigid body can be split into two links with a fixed joint at the location of the real sensor.




