cd ~/sim_ws/src
catkin_create_pkg studying_gazebo rospy urdf
cd ~/sim_ws
catkin build
gazebo (안되면 roslaunch robot_description empty_world.launch)
UI 상에서 Map을 만드는 것이 가장 쉽다.
Insert 탭에서 다양한 것들을 추가할 수 있다.
save를 통해 world를 저장할 수 있다.
.world 파일에 직접 추가하는 방법도 있다.
code /usr/share/gazebo-9/worlds/empty.world
gazebo 버전이 달라 위처럼 쳐서 안될 수도 있다.
그럴때는 empty_world.launch 파일을 켜서 insert 탭에 들어가면 경로를 확인해볼 수 있다.
(* insert 탭에 경로는 사전 설정되어있음)
.
.
<empty.world> 파일에 직접 추가하기
<?xml version="1.0" ?>
<sdf version="1.5">
<world name="default">
<!-- A global light source -->
<include>
<uri>model://sun</uri>
</include>
<!-- A ground plane -->
<include>
<uri>model://ground_plane</uri>
</include>
<!--add ambulance and construction_barrel-->
<include>
<pose>-6.0 -1.0 0 0 -0 0 </pose>
<url>model://ambulance</url>
</include>
<include>
<pose>-5.5 -5.5 0 0 -0 0 </pose>
<url>model://construction_barrel</url>
</include>
</world>
</sdf>
.
.
.
Gazebo 빨리 끄는 법 😊
cd
gedit ~/.bashrc
(.bashrc 파일이 열리면 맨 아래 alias를 추가해주자)
alias killgzb='killall -9 gazebo & killall -9 gzserver & killall -9 gzclient'
이후 부터는 terminal에 killgzb만 치면 빠르게 gazebo를 종료할 수 있다.
/
모델 데이터베이스 Github : github.com/osrf/gazebo_models
cd
cd ./download
git clone http://github.com/osrf/gazebo_models
다운로드 폴더에 위 git를 clone한 후 /.gazebo/models 폴더에 model 파일들을 옮겨준다.
(+ <ctrl+h>를 누르면 히든 폴더들을 볼 수 있다.)
(+ models 폴더가 없다면 당황하지 말고 그냥 만들면 된다. mkdir models)
.
.
.
.
.
.
mkdir ~/sim_ws/src/studying_gazebo/launch/
mkdir ~/sim_ws/src/studying_gazebo/worlds/
touch ~/sim_ws/src/studying_gazebo/launch/empty_world.launch
code ~/sim_ws/src/studying_gazebo/launch/empty_world.launch
<empty_world.launch> 파일
<launch>
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="paused" value="false"/>
<arg name="use_sim_time" value="true"/>
<arg name="gui" value="true"/>
<arg name="headless" value="false"/>
<arg name="debug" value="false"/>
</include>
</launch>
.
.
.
cd ~/sim_ws/src/studying_gazebo
mkdir -p models/box_model
cd models/box_model
touch model.config
touch model.sdf
<model.config>
<?xml version="1.0"?>
<model>
<name>Box Model</name>
<version>1.0</version>
<sdf version="1.6">model.sdf</sdf>
<author>
<name>yujin</name>
<email>aaa@gmail.com</email>
</author>
<description>
A simple box model
</description>
</model>
<model.sdf>
<?xml version='1.0'?>
<sdf version="1.4">
<model name="box_model">
<pose>0 0 0.5 0 0 0</pose>
<static>false</static>
<link name="link">
<inertial>
<mass>1.0</mass>
<inertia>
<ixx>0.083</ixx>
<ixy>0.0</ixy>
<ixz>0.0</ixz>
<iyy>0.083</iyy>
<iyz>0.0</iyz>
<izz>0.083</izz>
</inertia>
</inertial>
<collision name="collision">
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</collision>
<visual name="visual1">
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</visual>
</link>
</model>
</sdf>
위와 같이 모델을 만들었다면 Gazebo에서 불러올 수 있도록 경로 설정을 해줘야 한다.
Gazebo insert 탭에 들어가서 add path에 우리가 만든 폴더를 추가해주면 된다.
roslaunch robot_description empty_world.launch
위에서 만든 box model을 수정하여
visual은 설정되어 있지만 collision은 막혀있는 모델 만들기
2개의 visual 태그 사용
collision을 설정하지 않으면 물리엔진상의 계산을 받지 않게 된다.
정확히 뭐가 달라지는 건지 직접 해보자!
model.sdf파일에 collision을 설정하지 않은 원통을 하나 만들어 박스위에 둬보자보자
<model.sdf>
<?xml version='1.0'?>
<sdf version="1.4">
<model name="box_model">
<pose>0 0 0.5 0 0 0</pose>
<static>false</static>
<link name="link">
<inertial>
<mass>1.0</mass>
<inertia>
<ixx>0.083</ixx>
<ixy>0.0</ixy>
<ixz>0.0</ixz>
<iyy>0.083</iyy>
<iyz>0.0</iyz>
<izz>0.083</izz>
</inertia>
</inertial>
<collision name="collision">
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</collision>
<visual name="visual1">
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</visual>
<visual name="visual2">
<pose>0 0 1 0 0 0</pose>
<geometry>
<cylinder radius="0.25" length="1.5"/>
</geometry>
</visual>
</link>
</model>
</sdf>
Gazebo UI 상에서 view >> collision을 선택하면 collision 영역이 주황색으로 나타난다.
cylinder는 collision을 설정하지 않았으므로 주황색 영역이 없다.
visual2 인 cylinder는 collision을 설정해주지 않았다.
따라서 보이는 영상처럼
충돌의 상황에서 계산에 사용될 요소를 설정해주지 않은 것이므로 cylinder는 관통하고 box에서는 collision이 일어나는 것을 확인할 수 있다.
.
.
.
지표면을 그래픽으로 표현한 모델 - 카메라나 라이다 정보로 생성할 수 있음
touch ~/sim_ws/src/studying_gazebo/worlds/dem.world
cd ~/sim_ws/src/studying_gazebo/worlds
wget http://github.com/osrf/gazebo_tutorials/raw/master/dem/files/mtsthelens_before.zip
unzip mtsthelens_before.zip
rm mtsthelens_before.zip
<dem.world>
<?xml version="1.0" ?>
<sdf version="1.4">
<world name="default">
<!-- A global light source -->
<include>
<uri>model://sun</uri>
</include>
<model name="heightmap">
<static>true</static>
<link name="link">
<collision name="collision">
<geometry>
<heightmap>
<uri>/home/yujin/sim_ws/src/studying_gazebo/worlds/30.1.1.1282760.dem</uri>
<size>75 75 25</size>
<pos>0 0 0</pos>
</heightmap>
</geometry>
</collision>
<visual name="visual_abcedf">
<geometry>
<heightmap>
<texture>
<diffuse>file://media/materials/textures/dirt_diffusespecular.png</diffuse>
<normal>file://media/materials/textures/flat_normal.png</normal>
<size>1</size>
</texture>
<texture>
<diffuse>file://media/materials/textures/grass_diffusespecular.png</diffuse>
<normal>file://media/materials/textures/flat_normal.png</normal>
<size>1</size>
</texture>
<texture>
<diffuse>file://media/materials/textures/fungus_diffusespecular.png</diffuse>
<normal>file://media/materials/textures/flat_normal.png</normal>
<size>1</size>
</texture>
<blend>
<min_height>2</min_height>
<fade_dist>5</fade_dist>
</blend>
<blend>
<min_height>4</min_height>
<fade_dist>5</fade_dist>
</blend>
<uri>/home/shin/sim_ws/src/studying_gazebo/worlds/30.1.1.1282760.dem</uri>
<size>75 75 25</size>
<pos>0 0 0</pos>
</heightmap>
</geometry>
</visual>
</link>
</model>
</world>
</sdf>
<dem.launch>
<launch>
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(find studying_gazebo)/worlds/dem.world"/>
<arg name="paused" value="false"/>
<arg name="use_sim_time" value="true"/>
<arg name="gui" value="true"/>
<arg name="headless" value="false"/>
<arg name="debug" value="false"/>
</include>
</launch>
.
.
.
-> object를 무작위로 / 지정된 패턴으로 배치할 수 있다. (하나씩 배치할 필요 없음)
.
<population name=""> - population 이름 설정
<model>
<include> - 다른 리소스나 파일 include
</include>
</model>
<pose></pose> - 시뮬레이션에서 object 초기 위치
<box></box> - object가 배치될 영역 설정 (box or cylinder)
<model_count></model_count> - object를 몇개 둘지
<distribution> - 배치방법 결정
distribution : random, uniform, grid, linear-x, linear-y, linear-z
<type></type>
</distribution>
</population>
.
touch ~/sim_ws/src/studying_gazebo/worlds/population.world
touch ~/sim_ws/src/studying_gazebo/launch/population.launch
<population.world>
<?xml version="1.0" ?>
<sdf version="1.5">
<world name="default">
<!-- A global light source -->
<include>
<uri>model://sun</uri>
</include>
<!-- A ground plane -->
<include>
<uri>model://ground_plane</uri>
</include>
<!-- Testing the automatic population of objects -->
<population name="barriers_population">
<model name="jersey_barrier_1">
<include>
<static>false</static>
<uri>model://jersey_barrier</uri>
</include>
</model>
<pose>0 0 0.3 0 0 0</pose>
<box>
<size>12 12 0.01</size>
</box>
<model_count>3</model_count>
<distribution>
<type>linear-x</type>
</distribution>
</population>
<!-- Testing the automatic population of objects -->
<population name="bookshelf_population">
<model name="bookshelf">
<include>
<static>false</static>
<uri>model://bookshelf</uri>
</include>
</model>
<pose>0 8 0.3 0 0 0</pose>
<box>
<size>6 6 0.01</size>
</box>
<model_count>4</model_count>
<distribution>
<type>linear-y</type>
</distribution>
</population>
</world>
</sdf>
.
population 태그를 보면 bookshelf에서 model_count가 4, distribution이 linear-y이다.
선형 y축으로 bookshelf가 4개 생성된다는 뜻이다.
.
distribution : random, uniform, grid, linear-x, linear-y, linear-z
.
.
<population.launch>
<launch>
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(find studying_gazebo)/worlds/population.world"/>
<arg name="paused" value="false"/>
<arg name="use_sim_time" value="true"/>
<arg name="gui" value="true"/>
<arg name="headless" value="false"/>
<arg name="debug" value="false"/>
</include>
</launch>
.
.
launch 파일을 실행하면 아래와 같이
y축으로 정렬된 bookshelf와 x축으로 정렬된 barrier가 나온다.
.
.
.
<population.world>
<?xml version="1.0" ?>
<sdf version="1.5">
<world name="default">
<!-- A global light source -->
<include>
<uri>model://sun</uri>
</include>
<!-- A ground plane -->
<include>
<uri>model://ground_plane</uri>
</include>
<!-- +X barriers -->
<population name="barriers_population">
<model name="jersey_barrier_1">
<include>
<static>true</static>
<uri>model://jersey_barrier</uri>
</include>
</model>
<pose>0 19 0.3 0 0 0</pose>
<box>
<size>40 40 0.01</size>
</box>
<model_count>10</model_count>
<distribution>
<type>linear-x</type>
</distribution>
</population>
<!-- -X barriers -->
<population name="barriers_population">
<model name="jersey_barrier_2">
<include>
<static>true</static>
<uri>model://jersey_barrier</uri>
</include>
</model>
<pose>0 -21.5 0.3 0 0 0</pose>
<box>
<size>40 40 0.01</size>
</box>
<model_count>10</model_count>
<distribution>
<type>linear-x</type>
</distribution>
</population>
<!-- +Y barriers -->
<population name="barriers_population">
<model name="jersey_barrier_3">
<include>
<static>true</static>
<uri>model://jersey_barrier</uri>
<pose>0 0 0 0 0 1.57</pose>
</include>
</model>
<pose>19 0 0.3 0 0 0</pose>
<box>
<size>40 40 0.01</size>
</box>
<model_count>10</model_count>
<distribution>
<type>linear-y</type>
</distribution>
</population>
<!-- -Y barriers -->
<population name="barriers_population">
<model name="jersey_barrier_4">
<include>
<static>true</static>
<uri>model://jersey_barrier</uri>
<pose>0 0 0 0 0 1.57</pose>
</include>
</model>
<pose>-21.5 0 0.3 0 0 0</pose>
<box>
<size>40 40 0.01</size>
</box>
<model_count>10</model_count>
<distribution>
<type>linear-y</type>
</distribution>
</population>
<!-- random models population -->
<population name="construction_barrel_population">
<model name="construction_barrel">
<include>
<static>false</static>
<uri>model://construction_barrel</uri>
</include>
</model>
<pose>0 0 0.2 0 0 0</pose>
<box>
<size>30 30 0.01</size>
</box>
<model_count>100</model_count>
<distribution>
<type>random</type>
</distribution>
</population>
</world>
</sdf>
미션 결과이다!