< >
Home » ROS2与Ignition入门教程 » Ignition入门教程-移动机器人

Ignition入门教程-移动机器人

Ignition入门教程-移动机器人

说明:

  • 介绍如何移动我们的机器人
  • 我们将使用我们在构建您自己的机器人教程中构建的机器人。
  • 您可以从这里下载机器人SDF模型, 这代码有错误273行有错
  • 多了1位
<diffuse>0.0 1 0.0 1 1</diffuse>
 更改为
<diffuse>0.0 1 0.0 1</diffuse>

插件

  • 为了让我们的机器人移动,我们将使用 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>

纠错,疑问,交流: 请进入讨论区点击加入Q群

获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号


标签: ignition入门教程