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
2. Plot
메세지의 값에 대해 plot을 그리게 해준다.
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key
pose 메세지 plotting
rqt_plot /turtle1/pose/
3. Rosbag
메세지를 기록, 저장, 재생할 수 있게 해준다.
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key
원하는 디렉토리에 다음 명령어를 실행하면 rosbag 파일이 기록된다. (ctrl+c로 기록을 종료할 수 있다.)
rosbag record -a
rosbag파일의 정보를 보여준다.
rosbag info <your bagfile>
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
4. Custom plugins
그 외 유용한 RQT plugin
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key
rqt
Easy Message Publisher : 현재 토픽 리스트에 올라온 토픽 메세지를 GUI상에서 메뉴얼로 퍼블리싱 가능하게 해준다.
Topic Monitor : 현재 토픽들의 값과 통신 속도를 실시간으로 모니터링 할 수 있다.
5. Own plugins
자신만의 GUI와 기능을 갖는 plugin을 개발해 RQT상에서 사용할 수 있다. 참고자료 : http://wiki.ros.org/rqt/Tutorials/Writing%20a%20Python%20Plugin
Rviz(ROS-visualization)
1. IMU 센서
2. Kinect
참고자료 : 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
Rviz에 가상의 터틀봇3를 불러온다.
export TURTLEBOT3_MODEL=waffle
roslaunch turtlebot3_fake turtlebot3_fake.launch
터틀봇3 원격 조종 키 실행한다.
export TURTLEBOT3_MODEL=waffle
roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch
rqt_graph
rosrun rqt_tf_tree rqt_tf_tree
rostopic echo /odom
터틀봇3의 오도메트리 실시간 정보
(원격 조종 키를 사용하면 오도메트리를 시각화해서 볼 수 있고 값을 rostopic echo를 통해 실시간으로 확인할 수 있다.)
4. SLAM(Simultaneous Localization And Mapping)
SLAM을 할 때 지도의 작성과정을 시각적으로 보여준다.
가상 환경 불러오기
export TURTLEBOT3_MODEL=waffle
roslaunch turtlebot3_gazebo turtlebot3_world.launch
터틀봇3 SLAM 실행
export TURTLEBOT3_MODEL=waffle
roslaunch turtlebot3_slam turtlebot3_slam.launch
터틀봇3 원격 조종 키
export TURTLEBOT3_MODEL=waffle
roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch
Map 저장
rosrun map_server map_saver -f ~/map
가상 내비게이션 with Gazebo
export TURTLEBOT3_MODEL=waffle
roslaunch turtlebot3_gazebo turtlebot3_world.launch
- map 사
export TURTLEBOT3_MODEL=waffle
roslaunch turtlebot3_navigation turtlebot3_navigation.launch map_file:=$HOME/map.yaml
5. URDF
Unified Robot Description Format : ROS에서 사용되는 로봇 기술(Description) 형식 * URDF(Unified Robot Description Format) vs SDF(Simulation Description Format)
URDF는 하나의 robot 모델에 대해 기술하는 양식. 시뮬레이션 world 상에서 robot의 pose를 결정할 수 없다.
SDF는 world 상에서 여러개의 robot 모델에 대해 pose를 정의할 수 있으며 모델←→센서←→ World 의 관계에 대한 속성 정의도 가능하다.
쉽게 말해 서빙 로봇 서비스가 있는 매장에서 URDF는 서빙 로봇 하나의 도면!, SDF는 매장 전체 시스템의 도면!
Link
link : 모델 상의 하나의 Body(바퀴, 링크, 실린더, 구 등)
visual : link 요소의 시각화 (.dae, .stl 지원)
collision : link 요소 간의 충돌을 확인하기 위한 geometry (.dae, .stl 지원)
inertial : link의 동적 속성 기술(질량, 관성 모멘트 등)
origin : link 모델 중심의 joint로부터의 위치
URDF 작성연습을 위해 시각화는 urdf_tutorial의 launch를 사용한다.
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
새로운 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
물리적 특성(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
URDF Check tool 다운로드
$ sudo apt-get install liburdfdom-tools
URDF 링크 정합성 체크
$ check_urdf mobile_robot.urdf
URDF 링크 관계정보 시각화
$ urdf_to_graphiz mobile_robot.urdf
$ evince mobile_robot.pdf
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 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 씩 포스 입력
모델이 움직이는 모습을 확인 할 수 있음
Last updated