Ignition入门教程-移动机器人
Ignition入门教程-移动机器人
说明:
- 介绍如何移动我们的机器人
- 我们将使用我们在构建您自己的机器人教程中构建的机器人。
- 您可以从这里下载机器人SDF模型, 这代码有错误273行有错
- 多了1位
<diffuse>0.0 1 0.0 1 1</diffuse>
更改为
<diffuse>0.0 1 0.0 1</diffuse>
- 您可以从移动机器人SDF文件,错误同上。
插件
- 为了让我们的机器人移动,我们将使用 diff_drive 插件。 但在此之前,让我们先回答“什么是插件?”这个问题。
- 插件是一段代码,它被编译为共享库并插入到模拟中。 插件使我们能够控制模拟的许多方面,例如世界、模型等。
- diff_drive 插件帮助我们控制我们的机器人,特别是可以差分驱动的机器人。
- 让我们在我们的机器人上设置插件。 打开 building_robot.sdf 并在 vehicle_blue 模型标签中添加以下代码。
<plugin
filename="libignition-gazebo-diff-drive-system.so"
name="ignition::gazebo::systems::DiffDrive">
<left_joint>left_wheel_joint</left_joint>
<right_joint>right_wheel_joint</right_joint>
<wheel_separation>1.2</wheel_separation>
<wheel_radius>0.4</wheel_radius>
<odom_publish_frequency>1</odom_publish_frequency>
<topic>cmd_vel</topic>
</plugin>
标签有两个属性,filename 采用库文件名和 name 采用插件名称。 - 在 <left_joint> 和 <right_joint> 标签中,我们定义了将左右轮与机器人身体连接起来的关节,在我们的例子中是 left_wheel_joint 和 right_wheel_joint。
- <wheel_separation> 获取两个轮子之间的距离。 我们的机器人在 y 轴上相对于底盘的 left_wheel 为 0.6 m,right_wheel 为 -0.6 m,因此 wheel_separation 为 1.2 m。
- <wheel_radius> 采用车轮链接下的
标签中定义的车轮半径。 - <odom_publish_frequency> 设置在 /model/vehicle_blue/odometry 上发布里程计的频率。
- cmd_vel 是 DiffDrive 插件的输入
。
话题和消息
- 现在我们的模型已经准备好了。
- 我们只需要向它发送命令(消息)。
- 这些消息将在上面定义的 cmd_vel 主题上发布(发送)。
- 话题只是对一组特定消息或特定服务进行分组的名称。 我们的模型将订阅(监听)在 cmd_vel 主题上发送的消息。
- 新终端,启动机器人世界:
ign gazebo building_robot.sdf
- 新终端,发送速度话题
ign topic -t "/cmd_vel" -m ignition.msgs.Twist -p "linear: {x: 0.5}, angular: {z: 0.05}"
- 现在你应该让你的机器人在模拟中移动。
- 注意:不要忘记在模拟中按下播放按钮。
- 该命令在 -t 选项之后指定要发布到的主题。 在 -m 之后我们指定消息类型。
- 我们的机器人需要 Twist 类型的消息,它由线性和角度两个分量组成。
- 在 -p 选项之后,我们指定消息的内容(值):线速度 x:0.5 和角速度 z:0.05。
- 提示:您可以使用以下命令了解每个主题选项的作用:ign topic -h
- 有关 Ignition 中的主题和消息的更多信息,请查看教程
使用键盘移动机器人
- 我们将使用键盘键发送消息,而不是从终端发送消息。
- 为此,我们将添加两个新插件:KeyPublisher 和 TriggeredPublisher。
KeyPublisher
- KeyPublisher是一个ign-gui 插件,它读取键盘的击键并将它们发送到默认主题/keyboard/keypress。
- 要使用此插件,请在
标记下添加以下代码。
<!-- KeyPublisher plugin-->
<plugin filename="KeyPublisher" name="Key Publisher"/>
- 让我们试试这个插件,如下所示:
- 新终端,执行
ign gazebo building_robot.sdf
- 新终端,执行
ign topic -e -t /keyboard/keypress
- 最后一个命令将显示在 /keyboard/keypress 主题上发送的所有消息。
- 在点击窗口中按不同的键,您应该在运行 ign topic -e -t /keyboard/keypress 命令的终端上看到数据(数字)。
- 我们希望将这些击键映射到 Twist 类型的消息中,并将它们发布到我们的模型侦听的 /cmd_vel 话题。
- TriggeredPublisher 插件将执行此操作。
Triggered Publisher
- TriggeredPublisher 插件在输出主题上发布用户指定的消息,以响应与用户指定条件匹配的输入消息。
- 让我们在
标签下添加以下代码:
<!-- Moving Forward-->
<plugin filename="libignition-gazebo-triggered-publisher-system.so"
name="ignition::gazebo::systems::TriggeredPublisher">
<input type="ignition.msgs.Int32" topic="/keyboard/keypress">
<match field="data">16777235</match>
</input>
<output type="ignition.msgs.Twist" topic="/cmd_vel">
linear: {x: 0.5}, angular: {z: 0.0}
</output>
</plugin>
- 此代码定义了触发发布者插件。 它接受 /keyboard/keypress 话题上的ignition.msgs.Int32类型的消息,如果数据字段中的值与 16777235(向上箭头键)匹配,它会在 cmd_vel 主题上输出一条 Twist 消息,其值为 x: 0.5, z: 0.0 .
- 现在启动 building_robot.sdf,当我们按下向上箭头键 ↑ 时,我们的机器人应该向前移动。
- 有一个演示解释了触发发布器的工作原理。
使用箭头键移动
- 要查看在按下箭头时在 /keyboard/keypress 主题上发送了哪些值,我们可以使用 --echo 或 -e 选项
- 新终端,执行
ign gazebo building_robot.sdf
- 新终端,执行
ign topic -e -t /keyboard/keypress
- 开始按箭头键并查看它们给出的值:
Left ← : 16777234
Up ↑ : 16777235
Right → : 16777236
Down ↓ : 16777237
- 我们将为每个箭头键添加Triggered publisher。 例如,向下箭头:
<!-- Moving Backward-->
<plugin filename="libignition-gazebo-triggered-publisher-system.so"
name="ignition::gazebo::systems::TriggeredPublisher">
<input type="ignition.msgs.Int32" topic="/keyboard/keypress">
<match field="data">16777237</match>
</input>
<output type="ignition.msgs.Twist" topic="/cmd_vel">
linear: {x: -0.5}, angular: {z: 0.0}
</output>
</plugin>
- 就像我们对向后箭头所做的那样,将每个箭头(按键)映射到所需的消息(移动):
Left ➞ 16777234 ➞ linear: {x: 0.0}, angular: {z: 0.5}
Up ➞ 16777235 ➞ linear: {x: 0.5}, angular: {z: 0.0}
Right ➞ 16777236 ➞ linear: {x: 0.0}, angular: {z: -0.5}
Down ➞ 16777237 ➞ linear: {x: 0.5}, angular: {z: 0.0}
- 点击播放按钮后,尝试使用不同的方向按键让机器人移动了
- 如图
- 完整代码
<?xml version="1.0" ?>
<sdf version="1.7">
<world name="Moving_robot">
<physics name="1ms" type="ignored">
<max_step_size>0.001</max_step_size>
<real_time_factor>1.0</real_time_factor>
</physics>
<plugin
filename="libignition-gazebo-physics-system.so"
name="ignition::gazebo::systems::Physics">
</plugin>
<plugin
filename="libignition-gazebo-user-commands-system.so"
name="ignition::gazebo::systems::UserCommands">
</plugin>
<plugin
filename="libignition-gazebo-scene-broadcaster-system.so"
name="ignition::gazebo::systems::SceneBroadcaster">
</plugin>
<gui fullscreen="0">
<!-- 3D scene -->
<plugin filename="GzScene3D" name="3D View">
<ignition-gui>
<title>3D View</title>
<property type="bool" key="showTitleBar">false</property>
<property type="string" key="state">docked</property>
</ignition-gui>
<engine>ogre2</engine>
<scene>scene</scene>
<ambient_light>0.4 0.4 0.4</ambient_light>
<background_color>0.8 0.8 0.8</background_color>
</plugin>
<!-- World control -->
<plugin filename="WorldControl" name="World control">
<ignition-gui>
<title>World control</title>
<property type="bool" key="showTitleBar">false</property>
<property type="bool" key="resizable">false</property>
<property type="double" key="height">72</property>
<property type="double" key="width">121</property>
<property type="double" key="z">1</property>
<property type="string" key="state">floating</property>
<anchors target="3D View">
<line own="left" target="left"/>
<line own="bottom" target="bottom"/>
</anchors>
</ignition-gui>
<play_pause>true</play_pause>
<step>true</step>
<start_paused>true</start_paused>
<service>/world/Moving_robot/control</service>
<stats_topic>/world/Moving_robot/stats</stats_topic>
</plugin>
<!-- World statistics -->
<plugin filename="WorldStats" name="World stats">
<ignition-gui>
<title>World stats</title>
<property type="bool" key="showTitleBar">false</property>
<property type="bool" key="resizable">false</property>
<property type="double" key="height">110</property>
<property type="double" key="width">290</property>
<property type="double" key="z">1</property>
<property type="string" key="state">floating</property>
<anchors target="3D View">
<line own="right" target="right"/>
<line own="bottom" target="bottom"/>
</anchors>
</ignition-gui>
<sim_time>true</sim_time>
<real_time>true</real_time>
<real_time_factor>true</real_time_factor>
<iterations>true</iterations>
<topic>/world/Moving_robot/stats</topic>
</plugin>
<!-- Entity tree -->
<plugin filename="EntityTree" name="Entity tree">
</plugin>
<!-- KeyPublisher plugin-->
<plugin filename="KeyPublisher" name="Key Publisher"/>
</gui>
<light type="directional" name="sun">
<cast_shadows>true</cast_shadows>
<pose>0 0 10 0 0 0</pose>
<diffuse>0.8 0.8 0.8 1</diffuse>
<specular>0.2 0.2 0.2 1</specular>
<attenuation>
<range>1000</range>
<constant>0.9</constant>
<linear>0.01</linear>
<quadratic>0.001</quadratic>
</attenuation>
<direction>-0.5 0.1 -0.9</direction>
</light>
<model name="ground_plane">
<static>true</static>
<link name="link">
<collision name="collision">
<geometry>
<plane>
<normal>0 0 1</normal>
</plane>
</geometry>
</collision>
<visual name="visual">
<geometry>
<plane>
<normal>0 0 1</normal>
<size>100 100</size>
</plane>
</geometry>
<material>
<ambient>0.8 0.8 0.8 1</ambient>
<diffuse>0.8 0.8 0.8 1</diffuse>
<specular>0.8 0.8 0.8 1</specular>
</material>
</visual>
</link>
</model>
<model name='vehicle_blue' canonical_link='chassis'>
<pose relative_to=world>0 0 0 0 0 0</pose> <!--the pose is relative to the world by default-->
<link name='chassis'>
<pose relative_to='__model__'>0.5 0 0.4 0 0 0</pose>
<inertial> <!--inertial properties of the link mass, inertia matix-->
<mass>1.14395</mass>
<inertia>
<ixx>0.126164</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.416519</iyy>
<iyz>0</iyz>
<izz>0.481014</izz>
</inertia>
</inertial>
<visual name='visual'>
<geometry>
<box>
<size>2.0 1.0 0.5</size> <!--question: this size is in meter-->
</box>
</geometry>
<!--let's add color to our link-->
<material>
<ambient>0.0 0.0 1.0 1</ambient>
<diffuse>0.0 0.0 1.0 1</diffuse>
<specular>0.0 0.0 1.0 1</specular>
</material>
</visual>
<collision name='collision'> <!--todo: describe why we need the collision-->
<geometry>
<box>
<size>2.0 1.0 0.5</size>
</box>
</geometry>
</collision>
</link>
<!--let's build the left wheel-->
<link name='left_wheel'>
<pose relative_to="chassis">-0.5 0.6 0 -1.5707 0 0</pose> <!--angles are in radian-->
<inertial>
<mass>2</mass>
<inertia>
<ixx>0.145833</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.145833</iyy>
<iyz>0</iyz>
<izz>0.125</izz>
</inertia>
</inertial>
<visual name='visual'>
<geometry>
<cylinder>
<radius>0.4</radius>
<length>0.2</length>
</cylinder>
</geometry>
<material>
<ambient>1.0 0.0 0.0 1</ambient>
<diffuse>1.0 0.0 0.0 1</diffuse>
<specular>1.0 0.0 0.0 1</specular>
</material>
</visual>
<collision name='collision'>
<geometry>
<cylinder>
<radius>0.4</radius>
<length>0.2</length>
</cylinder>
</geometry>
</collision>
</link>
<!--copy and paste for right wheel but change position-->
<link name='right_wheel'>
<pose relative_to="chassis">-0.5 -0.6 0 -1.5707 0 0</pose> <!--angles are in radian-->
<inertial>
<mass>1</mass>
<inertia>
<ixx>0.145833</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.145833</iyy>
<iyz>0</iyz>
<izz>0.125</izz>
</inertia>
</inertial>
<visual name='visual'>
<geometry>
<cylinder>
<radius>0.4</radius>
<length>0.2</length>
</cylinder>
</geometry>
<material>
<ambient>1.0 0.0 0.0 1</ambient>
<diffuse>1.0 0.0 0.0 1</diffuse>
<specular>1.0 0.0 0.0 1</specular>
</material>
</visual>
<collision name='collision'>
<geometry>
<cylinder>
<radius>0.4</radius>
<length>0.2</length>
</cylinder>
</geometry>
</collision>
</link>
<frame name="caster_frame" attached_to='chassis'>
<pose>0.8 0 -0.2 0 0 0</pose>
</frame>
<!--caster wheel-->
<link name='caster'>
<pose relative_to='caster_frame'/>
<inertial>
<mass>1</mass>
<inertia>
<ixx>0.1</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.1</iyy>
<iyz>0</iyz>
<izz>0.1</izz>
</inertia>
</inertial>
<visual name='visual'>
<geometry>
<sphere>
<radius>0.2</radius>
</sphere>
</geometry>
<material>
<ambient>0.0 1 0.0 1</ambient>
<diffuse>0.0 1 0.0 1</diffuse>
<specular>0.0 1 0.0 1</specular>
</material>
</visual>
<collision name='collision'>
<geometry>
<sphere>
<radius>0.2</radius>
</sphere>
</geometry>
</collision>
</link>
<!--connecting these links together using joints-->
<joint name='left_wheel_joint' type='revolute'> <!--continous joint is not supported yet-->
<pose relative_to='left_wheel'/>
<parent>chassis</parent>
<child>left_wheel</child>
<axis>
<xyz expressed_in='__model__'>0 1 0</xyz> <!--can be descired to any frame or even arbitrary frames-->
<limit>
<lower>-1.79769e+308</lower> <!--negative infinity-->
<upper>1.79769e+308</upper> <!--positive infinity-->
</limit>
</axis>
</joint>
<joint name='right_wheel_joint' type='revolute'>
<pose relative_to='right_wheel'/>
<parent>chassis</parent>
<child>right_wheel</child>
<axis>
<xyz expressed_in='__model__'>0 1 0</xyz>
<limit>
<lower>-1.79769e+308</lower> <!--negative infinity-->
<upper>1.79769e+308</upper> <!--positive infinity-->
</limit>
</axis>
</joint>
<!--different type of joints ball joint--> <!--defult value is the child-->
<joint name='caster_wheel' type='ball'>
<parent>chassis</parent>
<child>caster</child>
</joint>
<!--diff drive plugin-->
<plugin
filename="libignition-gazebo-diff-drive-system.so"
name="ignition::gazebo::systems::DiffDrive">
<left_joint>left_wheel_joint</left_joint>
<right_joint>right_wheel_joint</right_joint>
<wheel_separation>1.2</wheel_separation>
<wheel_radius>0.4</wheel_radius>
<odom_publish_frequency>1</odom_publish_frequency>
<topic>cmd_vel</topic>
</plugin>
</model>
<!-- Moving Forward-->
<plugin filename="libignition-gazebo-triggered-publisher-system.so"
name="ignition::gazebo::systems::TriggeredPublisher">
<input type="ignition.msgs.Int32" topic="/keyboard/keypress">
<match field="data">16777235</match>
</input>
<output type="ignition.msgs.Twist" topic="/cmd_vel">
linear: {x: 0.5}, angular: {z: 0.0}
</output>
</plugin>
<!-- Moving Backward-->
<plugin filename="libignition-gazebo-triggered-publisher-system.so"
name="ignition::gazebo::systems::TriggeredPublisher">
<input type="ignition.msgs.Int32" topic="/keyboard/keypress">
<match field="data">16777237</match>
</input>
<output type="ignition.msgs.Twist" topic="/cmd_vel">
linear: {x: -0.5}, angular: {z: 0.0}
</output>
</plugin>
<!-- Rotating right-->
<plugin filename="libignition-gazebo-triggered-publisher-system.so"
name="ignition::gazebo::systems::TriggeredPublisher">
<input type="ignition.msgs.Int32" topic="/keyboard/keypress">
<match field="data">16777236</match>
</input>
<output type="ignition.msgs.Twist" topic="/cmd_vel">
linear: {x: 0.0}, angular: {z: -0.5}
</output>
</plugin>
<!--Rotating left-->
<plugin filename="libignition-gazebo-triggered-publisher-system.so"
name="ignition::gazebo::systems::TriggeredPublisher">
<input type="ignition.msgs.Int32" topic="/keyboard/keypress">
<match field="data">16777234</match>
</input>
<output type="ignition.msgs.Twist" topic="/cmd_vel">
linear: {x: 0.0}, angular: {z: 0.5}
</output>
</plugin>
</world>
</sdf>
获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号