# 5장 ROS 도구 활용하기

### 1. RQT(QT-based framework for GUI development for ROS)

#### 1. 1 Graph

현재 ROS상의 노드와 메세지간의 정보를 그래프형식으로 보여준다.\


* 터틀심 노드 실행

```
rosrun turtlesim turtlesim_node
```

* 터틀심 원격조종 노드 실행

```
rosrun turtlesim turtle_teleop_key
```

* 노드 그래프 생성

```
rqt_graph
```

\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-nqLy4bKR6c/491b18706902ad4484b3e65cd66f88bee2291be931cb1583cdc2c2c7d3c8ad832de9eba6d62a728448d55a7c3b2f9e2862c9b5fa2a001c7782433fd9db3669e60fd395777d704f23961e7e6de693443481734e5e77210d121b2aab9690a1c3bd2282370a)![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-3w07r4vOSZ/7c441aaf4ae940d513e1e11fad4f351f903e794c024c126113f87c5750cfc22b5ef6b7d6bfabb6f3e4270bd67c171546a93b72628a7db2718e8fa39a14a74c9cb3f4fd5037d9b8b2648ba88b070f76de9ffe25e86d453e5a8543bd172e7a5de0ea7dbe4b)\


#### 2. Plot

메세지의 값에 대해 plot을 그리게 해준다.\


```
rosrun turtlesim turtlesim_node
```

```
rosrun turtlesim turtle_teleop_key
```

* pose 메세지 plotting

```
rqt_plot /turtle1/pose/
```

\
\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-8T_GwxqSGP/30bddbe527c5a07a6d15318a016e5133bee16191e387f6502fcc4b8f8ba3176f9af6bfacc9250f28bb186a598f041ea3246bb47e8c5080662f64be391238703a90008f90a237737cc96a2c9a21bed230acabb9cdfd27eccb60bff6b59e4e5b0e2b1aa18f)터틀심 노드의 pose 메세지 값\
\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-PHeWRx0_I0/5c9db4a2c9f5cc313c1925a769cb0d2ab9068645a14aa57dce0883dc99f3fb1dc349704f4f146daa2f41b34e8c1e6f684cd5da2a35270160b03d4ff9c41bacff185642d306466041eba78206eb983c948629a4cce2e614259e20980ab1f17226c507bfe9)터틀심 노드의 pose - time plot

#### 3. Rosbag

메세지를 기록, 저장, 재생할 수 있게 해준다.\


```
rosrun turtlesim turtlesim_node
```

```
rosrun turtlesim turtle_teleop_key
```

* 원하는 디렉토리에 다음 명령어를 실행하면 rosbag 파일이 기록된다. (ctrl+c로 기록을 종료할 수 있다.)

```
rosbag record -a
```

* rosbag파일의 정보를 보여준다.

```
rosbag info <your bagfile>
```

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-qgF1rErmdD/6482d340d986e7422bf604f8579e06981c5b1dd07b0e9676ea6da500f069eb339470799679dd54f72169435a1ad07d54a9bb642759544c867d3ebb0a7d554b85dcbae95b77dd2ecfb4855d766ed76ebc5fe7ee2d5fef4546ffe3721ec2eebb07fc958e76)

* rosbag 파일을 재생한다.(기록된 메세지를 시간순서대로 퍼블리시한다.)

```
rosbag play <your bagfile>
```

* rosbag 파일을 2배속도로 재생한다.

```
rosbag play -r 2 <your bagfile>
```

* 특정 메세지만 저장할 수 있다.(subset 파일에 저장된다.)

```
rosbag record -O subset /turtle1/cmd_vel /turtle1/pose
```

\
참고자료 : [http://wiki.ros.org/rosbag/Tutorials/Recording%20and%20playing%20back%20data](http://wiki.ros.org/rosbag/Tutorials/Recording%20and%20playing%20back%20data)\


#### 4. Custom plugins

그 외 유용한 RQT plugin\


```
rosrun turtlesim turtlesim_node
```

```
rosrun turtlesim turtle_teleop_key
```

```
rqt
```

* **Easy Message Publisher** : 현재 토픽 리스트에 올라온 토픽 메세지를 GUI상에서 메뉴얼로 퍼블리싱 가능하게 해준다.

\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-mFy1CjmmqW/56fade2538700b90c0031218b6ea6e40c56ade16006dc35e41206fc3d7e8df36aec1c2475ee6654287bf6048e8442e5ffa2c62a6df05f57d482d3d2e8bd83bc1c08ac229b129d98bc6227a2621c4e8ece4bbb5eb67aee6873c9b03faded11becb699b100)\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-3vdBk1rkmo/c86ac8e1516ee1eb9461b6738df94e4210a13f5a37da1534eaf3b72d02d9f432013f78bb8fac789713b92c5d318107c9fd84345552883903002364028c738de6155d6e235053d78928677bc5bf8e2bc965a00dfeb108d9a107cb5a1eb4abdcd6f8ee9463)\
\
\


* **Topic Monitor** :  현재 토픽들의 값과 통신 속도를 실시간으로 모니터링 할 수 있다.

\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-C5EkCsRMPZ/048abe004a9ca5f69ec3d39ca99984ecb53c5c83dce1873feea936760729c539677662c716099ef200d065fbf1e5e067234a4469cc3c56ad9e0f87f8fa68820eb8fd43a107c65334fed5b70eb97acf8f224d6e68b6503175e6512b0870c10dfa546d9e37)\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-O8UH-9oZll/02a9619fac13ea0424b07bcebc488dcfe3d92b3cbc48da3b83c3aeef535a99b8b9eb5f577aca6c96427571819aa3e9359e11a033772b8b2e1e80a92eee9a7ce9b98c56b8e60130f13be200c85dff4b80d874d6c8b9a46ca33fb8831b9a4f7ca81de2753e)\
\


#### 5. Own plugins

자신만의 GUI와 기능을 갖는 plugin을 개발해 RQT상에서 사용할 수 있다.\
참고자료 : [http://wiki.ros.org/rqt/Tutorials/Writing%20a%20Python%20Plugin](http://wiki.ros.org/rqt/Tutorials/Writing%20a%20Python%20Plugin)\


### Rviz(ROS-visualization)

#### 1. IMU 센서

\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-A8c_RpyiFc/e75f42d390af81af9f826b2414c1497f0d04bd3e31da9ddeacaa4b0ef2eb9c97ff1b6f7517c1848a728b0227f02b59389fd75d6fab82f2a7b6ea23eb3b38254b1ba8bf3197ce4a58f94afc8b7dc2a6753c1cf08a8e4078452f7cc95b292fadcc251bb2d5)\
[https://youtu.be/j5v5fKppcQo](https://youtu.be/j5v5fKppcQo)\


#### 2. Kinect

참고자료 : [https://m.blog.naver.com/rmlee/221471760129](https://m.blog.naver.com/rmlee/221471760129) , 이상우님\


#### 3. Simulation

로봇의 오도메트리, TF, 센서 정보 등을 실시간 시각화를 통해 3D 시뮬레이션을 할 수 있다.

```
sudo apt-get install ros-kinetic-joy ros-kinetic-teleop-twist-joy ros-kinetic-teleop-twist-keyboard ros-kinetic-laser-proc ros-kinetic-rgbd-launch ros-kinetic-depthimage-to-laserscan ros-kinetic-rosserial-arduino ros-kinetic-rosserial-python ros-kinetic-rosserial-server ros-kinetic-rosserial-client ros-kinetic-rosserial-msgs ros-kinetic-amcl ros-kinetic-map-server ros-kinetic-move-base ros-kinetic-urdf ros-kinetic-xacro ros-kinetic-compressed-image-transport ros-kinetic-rqt-image-view ros-kinetic-gmapping ros-kinetic-navigation ros-kinetic-interactive-markers
```

```
sudo apt-get install ros-melodic-joy ros-melodic-teleop-twist-joy ros-melodic-teleop-twist-keyboard ros-melodic-laser-proc ros-melodic-rgbd-launch ros-melodic-depthimage-to-laserscan ros-melodic-rosserial-arduino ros-melodic-rosserial-python ros-melodic-rosserial-server ros-melodic-rosserial-client ros-melodic-rosserial-msgs ros-melodic-amcl ros-melodic-map-server ros-melodic-move-base ros-melodic-urdf ros-melodic-xacro ros-melodic-compressed-image-transport ros-melodic-rqt-image-view ros-melodic-gmapping ros-melodic-navigation ros-melodic-interactive-markers
```

```
cd ~/catkin_ws/src/
```

```
git clone https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git
```

```
git clone https://github.com/ROBOTIS-GIT/turtlebot3.git
```

```
git clone https://github.com/ROBOTIS-GIT/turtlebot3_simulations.git
```

```
cd ~/catkin_ws && catkin_make
```

* &#x20;Rviz에 가상의 터틀봇3를 불러온다.

```
export TURTLEBOT3_MODEL=waffle
```

```
roslaunch turtlebot3_fake turtlebot3_fake.launch
```

* 터틀봇3 원격 조종 키 실행한다.

```
export TURTLEBOT3_MODEL=waffle
```

```
roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch
```

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-HjIelJ6Tb_/5bb7f0bc264f3b0a7189018b2af3d99590aba8668ac44d349412eb1e399ae4cd6c70f08bd8f50dd77ef0ba8731dd6bd141ff67637260127306d6b4177e511abb2c273ea38e3b7c0cca51f6f43228eb62dbd4dc593d06ab898071de2d08b48488d5219ed0)

```
rqt_graph
```

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-N9z3lzFPcB/3cd71ba812d7d649da577ba00c96d2f6e9ddbf51a0683a1ea957520c8000382423e7ad3734b460834a9a58cb5670b4aa6e4bb4d18405a175ec42b5083a64df2632a4f79ad57f6dd0222e57301f35d502099a5e18b53d8bb8c49454cfb02e3c2b0c4665d0)터틀봇3의 노드 그래프\
\


```
rosrun rqt_tf_tree rqt_tf_tree
```

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-PNRj-hCTIA/f4e0fc48b0fd7475138b032de6408d22be62f7aa0b4a86862f403165f4b1e41df65edd025db7f7d48fdd88f06746afaba7f5d08544680db1a086a60d87a46a59b8b5428ed206b916bd7f0edc88f2afdfa7f5420c2c7d8eca91836347683525343d82116b)터틀봇3의 TF Tree\
\


```
rostopic echo /odom
```

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-1MtkMDTl5l/077283cc5f19edfe13fa2afb4d47541cbf0ca6a5f0b566f501a6d46847f5a440fa71bc3fc10c5f9ea8cefd74d9bfcdbfb1fc0bb37fb97498a5eecb4952696f36f7f9b6a9c14569a0fc039133deab8f7b696b2c4a1c2a575a575e2e9fb6302901dc9b6f2c)

터틀봇3의 오도메트리 실시간 정보

(원격 조종 키를 사용하면 오도메트리를 시각화해서 볼 수 있고 값을 rostopic echo를 통해 실시간으로 확인할 수 있다.)\
\


#### 4. SLAM(Simultaneous  Localization And Mapping)

SLAM을 할 때 지도의 작성과정을 시각적으로 보여준다.\


* 가상 환경 불러오기

```
export TURTLEBOT3_MODEL=waffle
```

```
roslaunch turtlebot3_gazebo turtlebot3_world.launch
```

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-P3zfLpb2MR/f094f808626711432f11e732a940f3ca1b6be47c0107e98def60fa86374b141850ed1e677b3bc1c2ed96ec41eb4769ce0c838cad458703879fe14747deffbdec3a9ac3b98480bd5f39ee3be8e690a0f0ff9c46ace0bbd66755ef1e8b3e8ef7d8490c8699)

* 터틀봇3 SLAM 실행

```
export TURTLEBOT3_MODEL=waffle
```

```
roslaunch turtlebot3_slam turtlebot3_slam.launch
```

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-KWJ-cUSzIN/84adb406d57ef2bcc56815ac575b3695504990933f3eeb4ec60042decd76ead8590382c806d813781543f3064a7162d3a7d3f19a2e4bb8188746fd471e42c2b2aa7926428b0b810dc838a3ec824dee6d731d1919211bf135e1c4354da2875fbb5b0fbcc7)

* 터틀봇3 원격 조종 키

```
export TURTLEBOT3_MODEL=waffle
```

```
roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch
```

\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-2jkX0wU7E4/57cadf786dbbc00663010a0d7c4b2e5616db442a1d5fe2865c24a02a13259b29b6cb85c3f668e5082f2c0a0e939760506da9e8fb88a93d683006a502c8599825795f8cdda0b2a0adeeb819fd54edf95f8603c6957df0b62c536f9f66a174317bd91c5977)SLAM이 끝난 뒤 완성된 Map\
\


* Map 저장

```
rosrun map_server map_saver -f ~/map
```

\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-O0jHEsaOnj/fb55961fc8eaf6611f147ef823991af06310e5acdfee8985aaab4dfca3efce67f7bfe88f46ae287cab38e5e491826efdd7f2644090babfef585c30fbb9b419cee5e01c37d7c4a9faa394468bca60c43b249e54aab196ff7ebe01be59f0e369c1d24f8613)저장된 Map



#### 가상 내비게이션 with Gazebo

```
export TURTLEBOT3_MODEL=waffle
```

```
roslaunch turtlebot3_gazebo turtlebot3_world.launch
```

#### &#x20;- map 사

```
export TURTLEBOT3_MODEL=waffle
```

```
roslaunch turtlebot3_navigation turtlebot3_navigation.launch map_file:=$HOME/map.yaml
```

![](https://917233451-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LcW4PzQzrJVLjrT8lUh%2F-LnWX-IeMTe5HZsbAd_G%2F-LnWXIyfAGzWz1G32dAG%2Fimage.png?alt=media\&token=d34b3afb-d0a7-4bad-af89-aaa0401f57c9)

#### &#x20;

#### 5. URDF

Unified Robot Description Format : ROS에서 사용되는 로봇 기술(Description) 형식\
&#xNAN;**\* URDF**(Unified Robot Description Format) **vs SDF(**&#x53;imulation Description Format)

* URDF는 하나의 robot 모델에 대해 기술하는 양식. 시뮬레이션 world 상에서 robot의 pose를 결정할 수 없다.
* SDF는 world 상에서 여러개의 robot 모델에 대해 pose를 정의할 수 있으며 모델←→센서←→ World 의 관계에 대한 속성 정의도 가능하다.

#### 쉽게 말해 서빙 로봇 서비스가 있는 매장에서 **URDF는 서빙 로봇 하나의 도면!,** **SDF는 매장 전체 시스템의 도면!**

\
\
\
**1) URDF turtial 1 - URDF 이해하기**\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-JESV6t9bk4/74f7ada3f312c812ebb5489e40fcd823d4a2e7435a7aec4cf91a90110d404ebd0935090782b15145696e24d817a1fb0f0bd8ef010d9ce7dfd5fb36902064343b78fc78bd3f033a5e8f13d471ce3ac65c15b56c97944ba0f240e7b86ed7ea6667a360cec9)

#### **Link**

\
**link : 모델 상의 하나의 Body(바퀴, 링크, 실린더, 구 등)**

* **visual : link 요소의 시각화 (.dae, .stl 지원)**
* **collision : link 요소 간의 충돌을 확인하기 위한 geometry (.dae, .stl 지원)**
* **inertial : link의 동적 속성 기술(질량, 관성 모멘트 등)**
* **origin : link 모델 중심의 joint로부터의 위치**

\
\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-vYYxijoTCH/b9a97052937a01e8197499cde75d6de26e3f260250542eb02f7c86abed9b61e67251565410b1f76f283e016dc5c33781204a8cf1101ae0429be81df48c2f102bda9a54585dc0231e9b9e6b2dbd132d502cc931f9a80863ef7d564494f6430d0e0ef29852)**Joint**\
**joint : link간의 구속관계 표현parent/child : link 간 구속관계에서 부모/자식 관계type : 관계의 종류(prismatic, revolute, continuous 등)axis : joint 축의 방향limit : joint의 이동가능 범위 제한origin : joint의 원점으로부터의 위치sensor : plugin을 통해 가상 world로부터의 센서 데이터를 취득material : link의 소재, 색상 등을 결정plugin : 모델을 제어하기 위한 controller 등 다른 플랫폼과 토픽/프레임을 공유하기 위한 수단**\
\


* URDF 작성연습을 위해 시각화는 urdf\_tutorial의 launch를 사용한다. &#x20;

```
git clone https://github.com/ros/urdf_tutorial.git
```

* urdf\_tutorial의 urdf 디렉토리에 다음 파일을 작성한다.

```
gedit mobile_robot.urdf
```

* URDF 기본구조

```
<?xml version="1.0"?>
<robot name="mobile_robot">
<material name="orange">
<color rgba="1 0.5 0.1 1"/>
</material>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
<link name="base_link">
<visual>
<geometry>
<box size="1.5 0.6 0.3"/>
</geometry>
<material name="orange"/>
</visual>
</link>
<link name="caster_wheel">
<visual>
<geometry>
<sphere radius="0.125"/>
</geometry>
<origin rpy="0 0 0" xyz="0 0 0"/>
<material name="white"/>
</visual>
</link>
```

```
```

```
  <joint name="base_to_caster_wheel" type="continuous">
```

```
    <parent link="base_link"/>
```

```
    <child link="caster_wheel"/>
```

```
    <origin xyz="0.5 0 -0.275"/>
```

```
    <axis xyz="0 1 0"/>
```

```
  </joint>
```

```
```

```
```

```
  <link name="right_wheel">
```

```
    <visual>
```

```
      <geometry>
```

```
        <cylinder length="0.2" radius="0.4"/>
```

```
      </geometry>
```

```
      <origin rpy="1.57075 0 0" xyz="0 0 0"/>
```

```
      <material name="white"/>
```

```
    </visual>
```

```
  </link>
```

```
```

```
  <joint name="base_to_right_wheel" type="continuous">
```

```
    <parent link="base_link"/>
```

```
    <child link="right_wheel"/>
```

```
    <origin xyz="-0.3 -0.4 0"/>
```

```
    <axis xyz="0 -1 0"/>
```

```
  </joint>
```

```
```

```
  <link name="left_wheel">
```

```
    <visual>
```

```
      <geometry>
```

```
        <cylinder length="0.2" radius ="0.4"/>
```

```
      </geometry>
```

```
      <origin rpy="1.57075 0 0" xyz="0 0 0"/>
```

```
      <material name="white"/>
```

```
    </visual>
```

```
  </link>
```

```
```

```
  <joint name="base_to_left_wheel" type="continuous">
```

```
    <parent link="base_link"/>
```

```
    <child link="left_wheel"/>
```

```
    <origin xyz="-0.3 0.4 0"/>
```

```
    <axis xyz="0 1 0"/>
```

```
  </joint>
```

```
```

```
</robot>
```

* Rviz에 URDF로 작성한 모델을 시각화한다.

```
$ roslaunch urdf_tutorial display.launch model:=urdf/mobile_robot.urdf
```

\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-it68Mq1tDz/acf6a4f5ee11712f6319fe4f78c2ac7fd1188be8787bf2b40e41ddad8897c9da96a400b399cb6d6286c6200fa6439efd6047638bbfc2d87e220fb4b045847d790413b99f02f2ab47982f500fb3d4c8f82904707a77fb9e03c15ff510ab1feb0c3102ce4a)URDF로 작성한 모바일 로봇 모델\
\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-TkHx6yda0z/4f1695a808e5e325b22f8caa1c59e266b39d20e989a25958f3698e72a3ae58286490ca6073c5c56e319be2339dd9340a8e2c01e18cf7321b082784fab38bb05ca26448b3dcf35717693a7a6c361582e04f70b3ae5db3d07a4c4538d481249b330ffe45a9)Joint 컨트롤러\
\
**2) URDF tutotial 2 - 나의 모델 불러와 Rviz에 시각화하기**\


* 새로운 URDF 작성

```
$ gedit mobile_robot_stl.urdf
```

* stl파일 불러오는 URDF

```
<?xml version="1.0"?>
```

```
<robot name="mobile_robot_stl">
```

```
```

```
  <material name="orange">
```

```
    <color rgba="1 0.5 0.1 1"/>
```

```
  </material>
```

```
```

```
  <link name="base_link">
```

```
    <visual>
```

```
      <origin rpy="1.57075 0 1.57075" xyz="0 0 0"/>
```

```
      <geometry>
```

```
        <mesh filename="package://urdf_tutorial/meshes/ros_test.stl" scale="0.01 0.01 0.01"/>
```

```
      </geometry>
```

```
      <material name="orange"/>
```

```
    </visual>
```

```
  </link>
```

```
```

```
</robot>
```

* 예제 stl파일 가져오기(urdf 디렉토리에 저장)

```
$ wget -O ros_test.stl https://github.com/Denhanis/ROS-Study/blob/master/stl/ros_test.stl?raw=true
```

* Rviz로 시각화

```
$ roslaunch urdf_tutorial display.launch model:=urdf/mobile_robot_stl.urdf
```

\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-vBojmcXN3V/96752396af7e029f685be2df8959ba6e095f3a897c125fc2558d6c329b7f4e62371cffe5a29305ea8b3130157d9ac6b6656cfefe8b2a309892730bc09de6b3c3589f0ca77faebd726460e4608bc3d8cb0fbf05ac9e6374bd3bddea9082b776ed7a5111c7)\
\
\
\
**3) URDF tutorial 3 - 3D모델에 물리적 특성 입히기**\
참고자료(관성 텐서 구하기) : [**https://en.wikipedia.org/wiki/List\_of\_moments\_of\_inertia#List\_of\_3D\_inertia\_tensors**](https://en.wikipedia.org/wiki/List_of_moments_of_inertia#List_of_3D_inertia_tensors)\


* 물리적 특성(collision, inertial) 반영된 URDF

```
<?xml version="1.0"?>
```

```
<robot name="mobile_robot">
```

```
```

```
  <material name="orange">
```

```
    <color rgba="1 0.5 0.1 1"/>
```

```
  </material>
```

```
```

```
  <material name="white">
```

```
    <color rgba="1 1 1 1"/>
```

```
  </material>
```

```
```

```
  <link name="base_link">
```

```
    <visual>
```

```
      <geometry>
```

```
        <box size="1.5 0.6 0.3"/>
```

```
      </geometry>
```

```
      <material name="orange"/>
```

```
    </visual>
```

```
    <collision>
```

```
      <geometry>
```

```
        <box size="1.5 0.6 0.3"/>
```

```
      </geometry>
```

```
    </collision>
```

```
    <inertial>
```

```
      <mass value="10"/>
```

```
      <inertia ixx="0.375" ixy="0.0" ixz="0.0" iyy="1.95" iyz="0.0" izz="2.175"/>
```

```
    </inertial>
```

```
  </link>
```

```
```

```
  <link name="caster_wheel">
```

```
    <visual>
```

```
      <geometry>
```

```
        <sphere radius="0.125"/>
```

```
      </geometry>
```

```
      <origin rpy="0 0 0" xyz="0 0 0"/>
```

```
      <material name="white"/>
```

```
    </visual>
```

```
    <collision>
```

```
      <geometry>
```

```
        <sphere radius="0.125"/>
```

```
      </geometry>
```

```
    </collision>
```

```
    <inertial>
```

```
      <mass value="3"/>
```

```
      <inertia ixx="0.01875" ixy="0.0" ixz="0.0" iyy="0.01875" iyz="0.0" izz="0.01875"/>
```

```
    </inertial>
```

```
  </link>
```

```
```

```
  <joint name="base_to_caster_wheel" type="continuous">
```

```
    <parent link="base_link"/>
```

```
    <child link="caster_wheel"/>
```

```
    <origin xyz="0.5 0 -0.275"/>
```

```
    <axis xyz="0 1 0"/>
```

```
  </joint>
```

```
```

```
```

```
  <link name="right_wheel">
```

```
    <visual>
```

```
      <geometry>
```

```
        <cylinder length="0.2" radius="0.4"/>
```

```
      </geometry>
```

```
      <origin rpy="1.57075 0 0" xyz="0 0 0"/>
```

```
      <material name="white"/>
```

```
    </visual>
```

```
    <collision>
```

```
      <geometry>
```

```
        <cylinder length="0.2" radius="0.4"/>
```

```
      </geometry>
```

```
      <origin rpy="1.57075 0 0" xyz="0 0 0"/>
```

```
    </collision>
```

```
    <inertial>
```

```
      <mass value="5"/>
```

```
      <inertia ixx="0.217" ixy="0.0" ixz="0.0" iyy="0.217" iyz="0.0" izz="0.4"/>
```

```
    </inertial>
```

```
  </link>
```

```
```

```
  <joint name="base_to_right_wheel" type="continuous">
```

```
    <parent link="base_link"/>
```

```
    <child link="right_wheel"/>
```

```
    <origin xyz="-0.3 -0.4 0"/>
```

```
    <axis xyz="0 -1 0"/>
```

```
  </joint>
```

```
```

```
  <link name="left_wheel">
```

```
    <visual>
```

```
      <geometry>
```

```
        <cylinder length="0.2" radius ="0.4"/>
```

```
      </geometry>
```

```
      <origin rpy="1.57075 0 0" xyz="0 0 0"/>
```

```
      <material name="white"/>
```

```
    </visual>
```

```
    <collision>
```

```
      <geometry>
```

```
        <cylinder length="0.2" radius="0.4"/>
```

```
      </geometry>
```

```
      <origin rpy="1.57075 0 0" xyz="0 0 0"/>
```

```
    </collision>
```

```
    <inertial>
```

```
      <mass value="5"/>
```

```
      <inertia ixx="0.217" ixy="0.0" ixz="0.0" iyy="0.217" iyz="0.0" izz="0.4"/>
```

```
    </inertial>
```

```
  </link>
```

```
```

```
  <joint name="base_to_left_wheel" type="continuous">
```

```
    <parent link="base_link"/>
```

```
    <child link="left_wheel"/>
```

```
    <origin xyz="-0.3 0.4 0"/>
```

```
    <axis xyz="0 1 0"/>
```

```
  </joint>
```

```
```

```
</robot>
```

* Rviz로 시각화

```
$ roslaunch urdf_tutorial display.launch model:=urdf/mobile_robot.urdf
```

\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-k-p-Wr6peJ/757c03259cd3610a9e5f17134c40e9296fe9e154b7d8ed6356d2ac7636238c51129cfe19c0fbea97d4a4821f8e313f6d424d87e3110dd8e6317f90caa1bf77117a61d574e48daff0e76ec1ebdaa73a8fb6bc86e26b507f6dc084dfe2d41d8b3ffcf087f6)\
\
**4) URDF tutorial 4 - URDF Check**\


* URDF Check tool 다운로드

```
$ sudo apt-get install liburdfdom-tools
```

* URDF 링크 정합성 체크

```
$ check_urdf mobile_robot.urdf
```

\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-TtBoRib23l/d078263008dd5c05005a71ea4161234ada96438249a7549208c48012e3537b68ce92b95a7e46e4ccce340180edf50fc99a47ac1f685ed67dc712f4084bec7eb9fef729c53a084ce39e9c23eee8c57b469d38971b356a3da12afd241eaf4fda364a879154)URDF 링크 관계정보\
\


* URDF 링크 관계정보 시각화

```
$ urdf_to_graphiz mobile_robot.urdf 
```

```
$ evince mobile_robot.pdf
```

\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-6-GsxJVEn0/ba5e7f43571643e3e9bdcf034544f2e9dd2907c1241c2c5c7eb9cd0356247e7dab13c2adf144542a78dcedf273af508e4a9b536f83e4efb5c94e51c035b81fff22bac6403b3055d77823643c0786240fd60e7358c75d45424709b5995b0579f41c921982)URDF 링크 관계정보 pdf로 저장\
\
![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-3cvDlzUcYD/f4caa65817b8b1b8031eb43f7e156b186904f1aef69b123b727843059ee5125480bb8ffc6226ec65e142afdf3aed3830d360c518d8913a75bad4bc042e33c6a79d7ab483699c0f326f9acb2e16f5f303953ccba4e5fdf1dfae9e2e0df35461c6c0e42f51)URDF 링크 관계정보 시각화\
\
\
**5) URDF tutorial 4 - Xacro 이용하여 URDF 쉽게 작성하기**\


* Xacro(XML Macro)를 사용한 URDF 작성

```
<?xml version="1.0"?>
```

```
<robot name="mobile_robot" xmlns:xacro="http://ros.org/wiki/xacro">
```

```
```

```
  <xacro:property name="body_width" value="0.6" />
```

```
  <xacro:property name="body_height" value="1.5" />
```

```
  <xacro:property name="body_depth" value="0.3" />
```

```
  <xacro:property name="caster_radius" value="0.125" />
```

```
  <xacro:property name="wheel_radius" value="0.4" />
```

```
  <xacro:property name="wheel_length" value="0.2" />
```

```
  <xacro:property name="pi" value="3.1415" />
```

```
```

```
  <xacro:macro name="default_inertial" params="mass">
```

```
    <inertial>
```

```
      <mass value="${mass}" />
```

```
      <inertia ixx="0.375" ixy="0.0" ixz="0.0" iyy="1.95" iyz="0.0" izz="2.175"/>
```

```
    </inertial>
```

```
  </xacro:macro>
```

```
```

```
  <xacro:macro name="y_axis_joint">
```

```
    <axis xyz="0 1 0"/>
```

```
  </xacro:macro>
```

```
```

```
  <material name="orange">
```

```
    <color rgba="1 0.5 0.1 1"/>
```

```
  </material>
```

```
```

```
  <material name="white">
```

```
    <color rgba="1 1 1 1"/>
```

```
  </material>
```

```
```

```
```

```
  <link name="base_link">
```

```
    <visual>
```

```
      <geometry>
```

```
        <box size="${body_height} ${body_width} ${body_depth}"/>
```

```
      </geometry>
```

```
      <material name="orange"/>
```

```
    </visual>
```

```
    <collision>
```

```
      <geometry>
```

```
        <box size="${body_height} ${body_width} ${body_depth}"/>
```

```
      </geometry>
```

```
    </collision>
```

```
    <xacro:default_inertial mass="10"/>
```

```
  </link>
```

```
```

```
  <link name="caster_wheel">
```

```
    <visual>
```

```
      <geometry>
```

```
        <sphere radius="${caster_radius}"/>
```

```
      </geometry>
```

```
      <origin rpy="0 0 0" xyz="0 0 0"/>
```

```
      <material name="white"/>
```

```
    </visual>
```

```
    <collision>
```

```
      <geometry>
```

```
        <sphere radius="${caster_radius}"/>
```

```
      </geometry>
```

```
    </collision>
```

```
    <inertial>
```

```
      <mass value="3"/>
```

```
      <inertia ixx="0.01875" ixy="0.0" ixz="0.0" iyy="0.01875" iyz="0.0" izz="0.01875"/>
```

```
    </inertial>
```

```
  </link>
```

```
```

```
  <joint name="base_to_caster_wheel" type="continuous">
```

```
    <parent link="base_link"/>
```

```
    <child link="caster_wheel"/>
```

```
    <origin xyz="0.5 0 -0.275"/>
```

```
    <xacro:y_axis_joint/>
```

```
  </joint>
```

```
```

```
```

```
  <xacro:macro name="wheel" params="prefix suffix mass reflect">
```

```
```

```
  <link name="${prefix}_wheel">
```

```
    <visual>
```

```
      <geometry>
```

```
        <cylinder length="${wheel_length}" radius="${wheel_radius}"/>
```

```
      </geometry>
```

```
      <origin rpy="${pi/2} 0 0" xyz="0 0 0"/>
```

```
      <material name="white"/>
```

```
    </visual>
```

```
    <collision>
```

```
      <geometry>
```

```
        <cylinder length="${wheel_length+0.1}" radius="${wheel_radius+0.1}"/>
```

```
      </geometry>
```

```
      <origin rpy="${pi/2} 0 0" xyz="0 0 0"/>
```

```
    </collision>
```

```
    <inertial>
```

```
      <mass value="${mass}"/>
```

```
      <inertia ixx="${mass*(3*wheel_radius*wheel_radius+wheel_length*wheel_length)/12}" ixy="0.0" ixz="0.0" iyy="${mass*(3*wheel_radius*wheel_radius+wheel_length*wheel_length)/12}" iyz="0.0" izz="${0.5*mass*wheel_radius*wheel_radius}"/>
```

```
    </inertial>
```

```
  </link>
```

```
```

```
  <joint name="${suffix}_to_${prefix}_wheel" type="continuous">
```

```
    <parent link="${suffix}_link"/>
```

```
    <child link="${prefix}_wheel"/>
```

```
    <origin xyz="-0.3 ${0.4*reflect} 0"/>
```

```
    <xacro:y_axis_joint/>
```

```
  </joint>
```

```
```

```
  </xacro:macro>
```

```
```

```
  <xacro:wheel prefix="right" suffix="base" mass="5" reflect="-1"/>
```

```
  <xacro:wheel prefix="left" suffix="base" mass="5" reflect="1"/>
```

```
```

```
</robot>
```

* Xacro 실행하기 위해 반드시 추가해야하는 Command

```
<launch>
```

```
```

```
  <arg name="model" default="$(find urdf_tutorial)/urdf/01-myfirst.urdf"/>
```

```
  <arg name="gui" default="true" />
```

```
  <arg name="rvizconfig" default="$(find urdf_tutorial)/rviz/urdf.rviz" />
```

```
```

```
  <param name="robot_description" command="$(find xacro)/xacro --inorder $(arg model)" />
```

```
  <param name="use_gui" value="$(arg gui)"/>
```

```
```

```
  <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
```

```
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
```

```
  <node name="rviz" pkg="rviz" type="rviz" args="-d $(arg rvizconfig)" required="true" />
```

```
```

```
</launch>
```

```
$ roslaunch urdf_tutorial display.launch model:=urdf/mobile_robot.urdf.xacro
```

\
\
\
**6. URDF tutorial 7 - SDF Converter**\


```
$ gz sdf --print my_urdf.urdf > my_sdf.sdf
```

#### 6. manipulator (TBU)

### Gazebo

#### ~~1. URDF로 만든 3D 모델 Gazebo에 불러오기~~

URDF를 Gazebo 환경으로 불러오기 위해선 다음과 같은 작업이 필요하다.1) Gazebo plugin 추가2) 몇 가지 추가 정보 URDF에 입력(joint limit, transmission 정보, 물리 계수)3) Controller configuration 작성4) Launch file 작성\
\
\
**1) Gazebo plugin 추가**\


* **URDF 마지막 부분에 다음의 gazebo plugin 추가**

```
  <gazebo>
```

```
    <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
```

```
      <robotNamespace>/</robotNamespace>
```

```
    </plugin>
```

```
  </gazebo>
```

\
\
**2) 몇 가지 추가 정보 URDF에 입력(joint limit, transmission 정보, 물리 계수)**\
\


* **joints 수정 및 transmission 추가**

```
  <joint name="head_swivel" type="continuous">
```

```
    <parent link="base_link"/>
```

```
    <child link="head"/>
```

```
    <axis xyz="0 0 1"/>
```

```
    <origin xyz="0 0 ${bodylen/2}"/>
```

```
    <limit effort="30" velocity="1.0"/>
```

```
  </joint>
```

```
```

```
  <transmission name="head_swivel_trans">
```

```
    <type>transmission_interface/SimpleTransmission</type>
```

```
    <actuator name="$head_swivel_motor">
```

```
      <mechanicalReduction>1</mechanicalReduction>
```

```
    </actuator>
```

```
    <joint name="head_swivel">
```

```
      <hardwareInterface>PositionJointInterface</hardwareInterface>
```

```
    </joint>
```

```
  </transmission>
```

```
```

```
   <gazebo reference="${prefix}_${suffix}_wheel">
```

```
     <mu1 value="200.0"/>
```

```
     <mu2 value="100.0"/>
```

```
     <kp value="10000000.0" />
```

```
     <kd value="1.0" />
```

```
     <material>Gazebo/Grey</material>
```

```
   </gazebo>
```

* **최종 수정된 URDF**

\
**3) Controller configuration 작성**\


* **urdf\_tutorial 디렉토리에 config 디렉토리를 생성하여 controller config 문서 생성(.yaml)**

```
$ mkdir config
```

```
```

```
$ touch /config/joints.yaml
```

```
$ touch /config/caster.yaml
```

```
$ touch /config/diffdrive.yaml
```

* **joints.yaml**

```
type: "joint_state_controller/JointStateController"
```

```
publish_rate: 50
```

* **caster.yaml**

```
type: "position_controllers/JointPositionController"
```

```
joint: head_swivel
```

* **diffdrive.yaml**

```
  type: "diff_drive_controller/DiffDriveController"
```

```
  publish_rate: 50
```

```
```

```
  left_wheel: ['left_front_wheel_joint', 'left_back_wheel_joint']
```

```
  right_wheel: ['right_front_wheel_joint', 'right_back_wheel_joint']
```

```
```

```
  wheel_separation: 0.44
```

```
```

```
  # Odometry covariances for the encoder output of the robot. These values should
```

```
  # be tuned to your robot's sample odometry data, but these values are a good place
```

```
  # to start
```

```
  pose_covariance_diagonal: [0.001, 0.001, 0.001, 0.001, 0.001, 0.03]
```

```
  twist_covariance_diagonal: [0.001, 0.001, 0.001, 0.001, 0.001, 0.03]
```

```
```

```
  # Top level frame (link) of the robot description
```

```
  base_frame_id: base_link
```

```
```

```
  # Velocity and acceleration limits for the robot
```

```
  linear:
```

```
    x:
```

```
      has_velocity_limits    : true
```

```
      max_velocity           : 0.2   # m/s
```

```
      has_acceleration_limits: true
```

```
      max_acceleration       : 0.6   # m/s^2
```

```
  angular:
```

```
    z:
```

```
      has_velocity_limits    : true
```

```
      max_velocity           : 2.0   # rad/s
```

```
      has_acceleration_limits: true
```

```
      max_acceleration       : 6.0   # rad/s^2
```

\
\
\
**4) Launch file 작성**\


* **gazebo\_launch를 이용하기 위해 해당 launch파일을 urdf\_tutorial/launch로 가져오기**

```
$ wget -O gazebo.launch https://github.com/ros/urdf_sim_tutorial/blob/master/launch/gazebo.launch?raw=true
```

* **우리가 만든 모델을 Gazebo와 Rviz에서 사용하기 위한 launch 파일 작성**

```
$ gedit mobile_robot.launch
```

```
sudo apt install ros-kinetic-gazebo-ros-control
```

#### 2. SDF로 만든 3D 모델 Gazebo에 불러오기

[https://github.com/modulabs/gazebo-tutorial/wiki/Make-a-Mobile-Robot](https://github.com/modulabs/gazebo-tutorial/wiki/Make-a-Mobile-Robot)\
SDF를 Gazebo 환경으로 불러오기 위해선 다음과 같은 작업이 필요하다.1) 모델 directory 설정2) 모델의 구조 생성3) Gazebo에서 모델 불러오기\
\
**1) 모델 directory 설정**\


* 모델 폴더를 생성

```
$ mkdir -p ~/.gazebo/models/my_robot
```

* 모델 config 파일을 생성

```
$ gedit ~/.gazebo/models/my_robot/model.config
```

* config 파일에 다음 코드를 작성

```
    <?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>me@my.email</email>
```

```
      </author>
```

```
```

```
      <description>
```

```
        My awesome robot.
```

```
      </description>
```

```
    </model>
```

* SDF 파일을 생성

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

* SDF 파일에 다음 코드를 작성

```
    <?xml version='1.0'?>
```

```
    <sdf version='1.4'>
```

```
      <model name="my_robot">
```

```
      </model>
```

```
    </sdf>
```

\
\
\
**2) 모델의 구조 생성**\


* SDF 파일을 실행

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

* 모델의 static을 설정
* static이 true이면 물리엔진의 영향을 받지 않고   false이면 물리엔진의 영향을 받음

```
    <?xml version='1.0'?>
```

```
    <sdf version='1.4'>
```

```
      <model name="my_robot">
```

```
```

```
        <static>true</static>
```

```
```

```
      </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>
```

* 모델에 구 형상의 바퀴 추가

```
    <?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>
```

* 모델에 왼쪽 바퀴 추가

```
    <?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>
```

* 모델의 왼쪽 바퀴를 오른쪽으로 복사

```
    <?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>
```

* static을 false로 설정, 왼쪽, 오른쪽 바퀴에 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>
```

\
\
**3) Gazebo에서 모델 불러오기**\


* Gazebo 실행

```
$ gazebo
```

* 모델  Insert
  * Gazebo 실행 후  GUI 인터페이스 왼쪽 상단의 Insert 탭 클릭
  * 'My Robot' 모델 클릭
  * 메인 화면에서 모델을 배치할 위치에 마우스를 위치시키고 클릭
* 모델 작동 테스트
  * 화면 오른쪽 작은 점 3개 버튼을 클릭한 상태로 마우스를 왼쪽으로 이동시켜 Joints 탭 활성화
  * 'left\_wheel\_hinge'와 'right\_wheel\_hinge'를 각각 0.1N 씩 포스 입력
  * 모델이 움직이는 모습을 확인 할 수 있음
