Make a Mobile Robot - modulabs/gazebo-tutorial GitHub Wiki

1. Overview

์ด ํŠœํ† ๋ฆฌ์–ผ์€ Gazebo์˜ ๊ธฐ๋ณธ์ ์ธ ๋ชจ๋ธ ๊ด€๋ฆฌ์— ๊ด€ํ•ด ์„ค๋ช…ํ•˜๊ณ  ์›€์ง์ž„์„ ์œ„ํ•ด differential drive mechanism์„ ์‚ฌ์šฉํ•˜๋Š” tow wheeled mobile robot์„ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์–ป๋Š” ๋ชจ๋ธ์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋‚ด์— ๋ชจ๋ธ์˜ ๊ธฐ๋ณธ์ ์ธ ๋ชจ๋ธ ํ‘œํ˜„์— ์ต์ˆ™ํ•ด์ง€๋„๋ก ์—ฐ์Šตํ•œ๋‹ค.

2. Setup your model directory

๋‹น์‹ ์€ ๋‹น์‹ ์˜ ๋ชจ๋ธ์„ ์ƒ์„ฑํ•  ๊ฒƒ ์ด๋‹ค. ๋‹น์‹ ์˜ ๋ชจ๋ธ์€ ๊ฐ€์ œ๋ณด ๋ชจ๋ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํด๋” ๊ตฌ์กฐ์— ๋”ฐ๋ฅธ ํฌ๋งท์˜ ๊ทœ์น™์„ ๋”ฐ๋ผ์•ผ ํ•œ๋‹ค.

  1. ๋ชจ๋ธ ํด๋”๋ฅผ ์ƒ์„ฑํ•ด๋ผ.
$ mkdir -p ~/.gazebo/models/my_robot
  1. ๋ชจ๋ธ config ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด๋ผ.
$ gedit ~/.gazebo/models/my_robot/model.config
  1. ๋‹ค์Œ์˜ ๋‚ด์šฉ์„ ๋ณต์‚ฌํ•ด๋ผ.
    <?xml version="1.0"?>
     <model>
      <name>My Robot</name>
      <version>1.0</version>
      <sdf version='1.4'>model.sdf</sdf>

      <author>
       <name>My Name</name>
       <email>[email protected]</email>
      </author>

      <description>
        My awesome robot.
      </description>
    </model>
  1. model.sdf ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด๋ผ.

    $ gedit ~/.gazebo/models/my_robot/model.sdf

  2. ๋‹ค์Œ์˜ ๋‚ด์šฉ์„ ๋ณต์‚ฌํ•ด๋ผ.

    <?xml version='1.0'?>
    <sdf version='1.4'>
      <model name="my_robot">
      </model>
    </sdf>

3. Build the Model's Structure

์ด๋ฒˆ step์€ ๋‘๊ฐœ์˜ ๋ฐ”ํ€ด๋ฅผ ๊ฐ€์ง„ ์‚ฌ๊ฐํ˜• ๋ฒ ์ด์Šค๋ฅผ ์ƒ์„ฑ ํ•  ๊ฒƒ ์ด๋‹ค. ๊ฐ„๋‹จํžˆ ์‹œ์ž‘ํ•˜๊ณ  step๋“ค์—์„œ ๋ชจ๋ธ์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ ์ค‘์š”ํ•˜๋‹ค. ์ฒซ step์—์„œ ๋ชจ๋ธ์˜ ๊ฐ„๋‹จํ•œ ํ˜•ํƒœ์˜ ๋ ˆ์ด์•„์›ƒ์ด๋‹ค. ์ด๊ฒƒ์„ ํ•˜๊ธฐ์œ„ํ•ด ์šฐ๋ฆฌ์˜ ๋ชจ๋ธ์€ static์ด ๋  ๊ฒƒ์ด๊ณ  ์ด๊ฒƒ์˜ ์˜๋ฏธ๋Š” ๋ฌผ๋ฆฌ์—”์ง„์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋Š” ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋ชจ๋ธ์ด ํ•œ ์žฅ์†Œ์—์„œ ๋จธ๋ฌผ๋Ÿฌ ์žˆ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋˜๊ณ  ์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ๋ชจ๋“  ์š”์†Œ๋“ค์„ ์ ์ ˆํžˆ ์ •๋ ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค.

  1. true์„ model.sdf ํŒŒ์ผ์— ์ถ”๊ฐ€ํ•˜๋ฏ€๋กœ ๋ชจ๋ธ์ด staticํ•˜๊ฒŒ ํ•œ๋‹ค.
    <?xml version='1.0'?>
    <sdf version='1.4'>
      <model name="my_robot">

        <static>true</static>

      </model>
    </sdf>
  1. model.sdf ํŒŒ์ผ์„ ์ˆ˜์ •ํ•˜์—ฌ ์‚ฌ๊ฐํ˜• ๋ฒ ์ด์Šค๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
    <?xml version='1.0'?>
      <sdf version='1.4'>
        <model name="my_robot">
        <static>true</static>

          <link name='chassis'>
            <pose>0 0 .1 0 0 0</pose>

            <collision name='collision'>
              <geometry>
                <box>
                  <size>.4 .2 .1</size>
                </box>
              </geometry>
            </collision>

            <visual name='visual'>
              <geometry>
                <box>
                  <size>.4 .2 .1</size>
                </box>
              </geometry>
            </visual>
          </link>

      </model>
    </sdf>

์—ฌ๊ธฐ์—์„œ ์šฐ๋ฆฌ๋Š” 0.4 x 0.2 x 0.1(m) ํฌ๊ธฐ์˜ ๋ฐ•์Šค๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. collision ์š”์†Œ๋Š” ์ถฉ๋Œ ๊ฐ์ง€ ์—”์ง„์— ์˜ํ•ด ํ˜•ํƒœ๊ฐ€ ๋ช…์‹œ๋œ๋‹ค. visual ์š”์†Œ๋Š” ๋ Œ๋”๋ง ์—”์ง„์— ์œ„ํ•ด ํ˜•ํƒœ๊ฐ€ ๋ช…์‹œ ๋œ๋‹ค. ๋Œ€๊ฐœ์˜ ๊ฒฝ์šฐ์— collision๊ณผ visual ์š”์†Œ๋Š” ๊ฐ™๋‹ค. ํ•˜์ง€๋งŒ ๋ณต์žกํ•œ mesh๋ฅผ ์‚ฌ์šฉํ•˜๋Š” visual ์š”์†Œ์™€ ๋‹จ์ˆœํ•œ ํ˜•ํƒœ์˜ collision์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ผ๋ฐ˜์ ์ด๋‹ค. ์ด๊ฒƒ์€ ์„ฑ๋Šฅ ํ–ฅ์ƒ์— ๋„์›€์„ ์ค„ ๊ฒƒ ์ด๋‹ค.

  1. gazebo๋ฅผ ๋™์ž‘ํ•˜์—ฌ ๋‹น์‹ ์˜ ๋ชจ๋ธ์„ ๋ถˆ๋Ÿฌ์˜ค์ž. ๊ฐ€์ œ๋ณด GUI ์ธํ„ฐํŽ˜์ด์Šค์˜ Insert Model์„ ํ†ตํ•ด ๋‹น์‹ ์˜ ๋ชจ๋ธ์„ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

    $ gazebo

๋‹น์‹ ์€ ํฐ์ƒ‰ ๋ฐ•์Šค๊ฐ€ ์ง€๋ฉด์—์„œ 1๋ฏธํ„ฐ ์ •๋„ ๋– ์žˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

  1. ์ด์ œ ์šฐ๋ฆฌ๋Š” ๋ฐ”ํ€ด๋ฅผ ๋กœ๋ด‡์— ์ถ”๊ฐ€ ํ•  ๊ฒƒ์ด๋‹ค. ๋ฐ”ํ€ด๋Š” ๋งˆ์ฐฐ์„ ๊ฐ€์ง€์ง€ ์•Š๋Š” ๊ตฌ์ด๋‹ค. ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ๋ฐ”ํ€ด๊ฐ€ ์กฐ์ธํŠธ๋ฅผ ๊ฐ€์ง€๋Š” ๋ฐ”ํ€ด๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋‚ซ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ด๊ฒƒ์€ ๋ฌผ๋ฆฌ์—”์ง„์—์„œ ๋” ์ ์€ ๊ตฌ์† ์กฐ๊ฑด์„ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
    <?xml version='1.0'?>
    <sdf version='1.4'>
      <model name="my_robot">
        <static>true</static>
        <link name='chassis'>
          <pose>0 0 .1 0 0 0</pose>
          <collision name='collision'>
            <geometry>
              <box>
                <size>.4 .2 .1</size>
              </box>
            </geometry>
          </collision>

          <visual name='visual'>
            <geometry>
              <box>
                <size>.4 .2 .1</size>
              </box>
            </geometry>
          </visual>

          <collision name='caster_collision'>
            <pose>-0.15 0 -0.05 0 0 0</pose>
            <geometry>
                <sphere>
                <radius>.05</radius>
              </sphere>
            </geometry>

            <surface>
              <friction>
                <ode>
                  <mu>0</mu>
                  <mu2>0</mu2>
                  <slip1>1.0</slip1>
                  <slip2>1.0</slip2>
                </ode>
              </friction>
            </surface>
          </collision>

          <visual name='caster_visual'>
            <pose>-0.15 0 -0.05 0 0 0</pose>
            <geometry>
              <sphere>
                <radius>.05</radius>
              </sphere>
            </geometry>
          </visual>

        </link>
      </model>
    </sdf>

๋‹น์‹ ์˜ ๋ชจ๋ธ์ด ๋กœ๋ด‡์˜ ๋์— ๋ฐ”ํ€ด๊ฐ€ ๋‚˜ํƒ€๋‚˜๋Š”์ง€ ์‹œํ—˜ํ•ด๋ด๋ผ. ๋‹น์‹ ์€ ๊ฐ€์ œ๋ณด๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ๋‹น์‹ ์˜ ์ˆ˜์ •๋œ ๋ชจ๋ธ์„ ๊ฐ€์ œ๋ณด์— ์‚ฝ์ž…ํ•  ๋•Œ ๋งค๋ฒˆ ๋””์Šคํฌ๋กœ ๋ถ€ํ„ฐ ์žฌ๋กœ๋“œ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

  • Tip : ๋ฉ”๋‰ด์ฐฝ์˜ View๋ฅผ ํด๋ฆญํ•˜๊ณ  Collisions๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ถฉ๋Œ ์˜์—ญ์ด ์ฃผํ™ฉ์ƒ‰์œผ๋กœ ํ‘œ์‹œ ๋˜๋Š”๊ฑธ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

5.์ด์ œ ์™ผ์ชฝ ๋ฐ”ํ€ด๋ฅผ ์ถ”๊ฐ€ ํ•ด๋ณด์ž ๋‹ค์Œ๊ณผ ๊ฐ™์ด model.sdfํŒŒ์ผ์„ ์ˆ˜์ •ํ•ด๋ผ.

    <?xml version='1.0'?>
    <sdf version='1.4'>
      <model name="my_robot">
        <static>true</static>
        <link name='chassis'>
          <pose>0 0 .1 0 0 0</pose>
          <collision name='collision'>
            <geometry>
              <box>
                <size>.4 .2 .1</size>
              </box>
            </geometry>
          </collision>

          <visual name='visual'>
            <geometry>
              <box>
                <size>.4 .2 .1</size>
              </box>
            </geometry>
          </visual>

          <collision name='caster_collision'>
            <pose>-0.15 0 -0.05 0 0 0</pose>
            <geometry>
              <sphere>
              <radius>.05</radius>
            </sphere>
          </geometry>

          <surface>
            <friction>
              <ode>
                <mu>0</mu>
                <mu2>0</mu2>
                <slip1>1.0</slip1>
                <slip2>1.0</slip2>
              </ode>
            </friction>
          </surface>
        </collision>

        <visual name='caster_visual'>
          <pose>-0.15 0 -0.05 0 0 0</pose>
          <geometry>
            <sphere>
              <radius>.05</radius>
            </sphere>
          </geometry>
        </visual>
      </link>

      <link name="left_wheel">
        <pose>0.1 0.13 0.1 0 1.5707 1.5707</pose>
        <collision name="collision">
          <geometry>
            <cylinder>
              <radius>.1</radius>
              <length>.05</length>
            </cylinder>
          </geometry>
        </collision>
        <visual name="visual">
          <geometry>
            <cylinder>
              <radius>.1</radius>
              <length>.05</length>
            </cylinder>
          </geometry>
        </visual>
      </link>

      </model>
    </sdf>

๋‹ค์‹œ Gazebo๋ฅผ ์‹คํ–‰ ์‹œํ‚ค๊ณ  ๋‹น์‹ ์˜ ๋กœ๋ด‡ ๋ชจ๋ธ์„ ์‚ฝ์ž…์‹œ์ผœ๋ผ. ์ •ํ™•ํ•œ ์œ„์น˜์— ๋ฐ”ํ€ด๊ฐ€ ๋‚˜ํƒ€๋‚˜๋Š”์ง€ ํ™•์ธํ•ด๋ผ.

6.์šฐ๋ฆฌ๋Š” ์™ผ์ชฝ ๋ฐ”ํ€ด๋ฅผ ๋ณต์‚ฌ ํ•จ์œผ๋กœ์จ ์˜ค๋ฅธ์ชฝ ๋ฐ”ํ€ด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค ๊ทธ๋ฆฌ๊ณ  ๋ฐ”ํ€ด ๋งํฌ์œ„ ์šฐ์น˜๋ฅผ ์กฐ์ • ํ•  ์ˆ˜ ์žˆ๋‹ค.

    <?xml version='1.0'?>
    <sdf version='1.4'>
      <model name="my_robot">
        <static>true</static>
        <link name='chassis'>
          <pose>0 0 .1 0 0 0</pose>
          <collision name='collision'>
            <geometry>
              <box>
                <size>.4 .2 .1</size>
              </box>
            </geometry>
          </collision>

          <visual name='visual'>
            <geometry>
              <box>
                <size>.4 .2 .1</size>
              </box>
            </geometry>
          </visual>

          <collision name='caster_collision'>
            <pose>-0.15 0 -0.05 0 0 0</pose>
            <geometry>
              <sphere>
              <radius>.05</radius>
            </sphere>
          </geometry>

          <surface>
            <friction>
              <ode>
                <mu>0</mu>
                <mu2>0</mu2>
                <slip1>1.0</slip1>
                <slip2>1.0</slip2>
              </ode>
            </friction>
          </surface>
        </collision>

        <visual name='caster_visual'>
          <pose>-0.15 0 -0.05 0 0 0</pose>
          <geometry>
            <sphere>
              <radius>.05</radius>
            </sphere>
          </geometry>
        </visual>
      </link>
      <link name="left_wheel">
        <pose>0.1 0.13 0.1 0 1.5707 1.5707</pose>
        <collision name="collision">
          <geometry>
            <cylinder>
              <radius>.1</radius>
              <length>.05</length>
            </cylinder>
          </geometry>
        </collision>
        <visual name="visual">
          <geometry>
            <cylinder>
              <radius>.1</radius>
              <length>.05</length>
            </cylinder>
          </geometry>
        </visual>
      </link>

      <link name="right_wheel">
        <pose>0.1 -0.13 0.1 0 1.5707 1.5707</pose>
        <collision name="collision">
          <geometry>
            <cylinder>
              <radius>.1</radius>
              <length>.05</length>
            </cylinder>
          </geometry>
        </collision>
        <visual name="visual">
          <geometry>
            <cylinder>
              <radius>.1</radius>
              <length>.05</length>
            </cylinder>
          </geometry>
        </visual>
      </link>

      </model>
    </sdf>

ํ˜„์‹œ์ ๊นŒ์ง€ ๋กœ๋ด‡์€ ํ•˜๋‚˜์˜ ์ƒค์‹œ์— ํ•˜๋‚˜์˜ ๊ตฌ ๋ฐ”ํ€ด์™€ ๋‘๊ฐœ์˜ ํœ ๋ฐ”ํ€ด๋ฅผ ๊ฐ€์ง„ ๋กœ๋ด‡์ด๋‹ค.

  1. <static>์„ false๋กœ ์…‹ํŒ…ํ•˜์—ฌ ๋ชจ๋ธ์„ dynamicํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค. ์™ผ์ชฝ, ์˜ค๋ฅธ์ชฝ ํœ  ๋ฐ”ํ€ด์— hinge ์กฐ์ธํŠธ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
    <?xml version='1.0'?>
    <sdf version='1.4'>
      <model name="my_robot">

        <static>false</static>

        <link name='chassis'>
          <pose>0 0 .1 0 0 0</pose>
          <collision name='collision'>
            <geometry>
              <box>
                <size>.4 .2 .1</size>
              </box>
            </geometry>
          </collision>

          <visual name='visual'>
            <geometry>
              <box>
                <size>.4 .2 .1</size>
              </box>
            </geometry>
          </visual>

          <collision name='caster_collision'>
            <pose>-0.15 0 -0.05 0 0 0</pose>
            <geometry>
              <sphere>
              <radius>.05</radius>
            </sphere>
          </geometry>

          <surface>
            <friction>
              <ode>
                <mu>0</mu>
                <mu2>0</mu2>
                <slip1>1.0</slip1>
                <slip2>1.0</slip2>
              </ode>
            </friction>
          </surface>
        </collision>

        <visual name='caster_visual'>
          <pose>-0.15 0 -0.05 0 0 0</pose>
          <geometry>
            <sphere>
              <radius>.05</radius>
            </sphere>
          </geometry>
        </visual>
      </link>
      <link name="left_wheel">
        <pose>0.1 0.13 0.1 0 1.5707 1.5707</pose>
        <collision name="collision">
          <geometry>
            <cylinder>
              <radius>.1</radius>
              <length>.05</length>
            </cylinder>
          </geometry>
        </collision>
        <visual name="visual">
          <geometry>
            <cylinder>
              <radius>.1</radius>
              <length>.05</length>
            </cylinder>
          </geometry>
        </visual>
      </link>

      <link name="right_wheel">
        <pose>0.1 -0.13 0.1 0 1.5707 1.5707</pose>
        <collision name="collision">
          <geometry>
            <cylinder>
              <radius>.1</radius>
              <length>.05</length>
            </cylinder>
          </geometry>
        </collision>
        <visual name="visual">
          <geometry>
            <cylinder>
              <radius>.1</radius>
              <length>.05</length>
            </cylinder>
          </geometry>
        </visual>
      </link>

      <joint type="revolute" name="left_wheel_hinge">
        <pose>0 0 -0.03 0 0 0</pose>
        <child>left_wheel</child>
        <parent>chassis</parent>
        <axis>
          <xyz>0 1 0</xyz>
        </axis>
      </joint>

      <joint type="revolute" name="right_wheel_hinge">
        <pose>0 0 0.03 0 0 0</pose>
        <child>right_wheel</child>
        <parent>chassis</parent>
        <axis>
          <xyz>0 1 0</xyz>
        </axis>
      </joint>

      </model>
    </sdf>

๋‘๊ฐœ์˜ ์กฐ์ธํŠธ๋Š” y์ถ• 0 1 0 ์— ๋Œ€ํ•˜์—ฌ ํšŒ์ „ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐ ํœ  ๋ฐ”ํ€ด๋Š” ์ƒค์‹œ์— ์—ฐ๊ฒฐ๋œ๋‹ค.

  1. ๊ฐ€์ œ๋ณด๋ฅผ ์‹œ์ž‘ํ•˜๊ณ  ๋‹น์‹ ์˜ ๋ชจ๋ธ์„ ์‚ฝ์ž…ํ•œ๋‹ค. ์Šคํฌ๋ฆฐ ์˜ค๋ฅธ์ชฝ์˜ ์ ๋“ค์„ ํด๋ฆญํ•˜๊ณ  ์™ผ์ชฝ์œผ๋กœ ๊ทธ๊ฒƒ์„ ๋“œ๋ž˜๊ทธํ•˜์—ฌ๋ผ.

  2. ์ƒˆ๋กœ์šด ์ฐฝ์ด ๋‚˜ํƒ€๋‚˜๋ฉฐ ์ด ์ฐฝ์€ ๊ฐ ์กฐ์ธํŠธ์— ๋Œ€ํ•œ ๋‹ค์–‘ํ•œ ์ปจํŠธ๋กค๋Ÿฌ๋“ค์„ ํฌํ•จํ•œ๋‹ค.(Note ๋‹น์‹ ์ด ์ œ์–ดํ•˜๊ธฐ ์›ํ•˜๋Š” ๋ชจ๋ธ์ด ์„ ํƒ๋˜์–ด์žˆ๋Š”์ง€ ํ™•์ธ ํ•œ๋‹ค.)

  3. Force ํƒญ ์•„๋ž˜์— ๊ฐ์กฐ์ธํŠธ์— ์•ฝ 0.1Nm์˜ ํž˜์„ ๊ฐ€ํ•ด๋ผ. ๋กœ๋ด‡์ด ์ฃผ๋ณ€์„ ์›€์ง์ธ๋‹ค.

  4. ์ถ•ํ•˜ํ•ฉ๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ์ด์ œ ๊ธฐ๋ณธ์ ์ธ ๋ชจ๋ฐ”์ผ ๋กœ๋ด‡์„ ๊ฐ€์กŒ์Šต๋‹ˆ๋‹ค.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ