[Simulation] World & 모델 만들기

Yujin-Shim·2023년 6월 22일
0

simulation

목록 보기
2/10

World 만들기

패키지 생성

cd ~/sim_ws/src
catkin_create_pkg studying_gazebo rospy urdf
cd ~/sim_ws
catkin build
gazebo (안되면 roslaunch robot_description empty_world.launch)

GUI 상에서 insert하는 방법

UI 상에서 Map을 만드는 것이 가장 쉽다.
Insert 탭에서 다양한 것들을 추가할 수 있다.
save를 통해 world를 저장할 수 있다.

.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>
  • 아래서 한 git clone을 안했다면 모델이 없어서 실행이 안될 수 있음.

.
.
.

Gazebo 빨리 끄는 법 😊

cd
gedit ~/.bashrc
(.bashrc 파일이 열리면 맨 아래 alias를 추가해주자)
alias killgzb='killall -9 gazebo & killall -9 gzserver & killall -9 gzclient'
이후 부터는 terminal에 killgzb만 치면 빠르게 gazebo를 종료할 수 있다.

/

Gazebo Models

Gazebo Models Database

모델 데이터베이스 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)

.
.

Models directory 구조

  • model.config (this file includes name, version, description, dependency ...)
  • model.sdf (this file includes structure, physical informations ...)
    • pose ( X Y Z R P Y) : world에 배치될 때 위치
    • static (true or false) : true면 외부의 힘에 의해 움직이지 않음
    • link
      • inertial : 질량과 관성 행렬 정의 -> 이를 이용해 object의 물리적반응 계산
      • collision : 물리엔진이 외부와의 충돌을 계산할 때 고려하는 치수
      • visual : 시뮬레이션에서 볼 수 있는 모양을 정의(대체로 collision과 동일)

.
.
.
.

빈 world 만들기

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>

.
.
.

나만의 모델 만들기

  • 간단한 tutorial이므로 material이나 texture는 사용하지 않겠습니당
  • 박스 모델을 만들어 봅시다🔰
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

Mission(1)

위에서 만든 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이 일어나는 것을 확인할 수 있다.

.
.
.

Digital Elevation Models

지표면을 그래픽으로 표현한 모델 - 카메라나 라이다 정보로 생성할 수 있음

DEM world 만들기

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>

.
.
.

Model population

-> object를 무작위로 / 지정된 패턴으로 배치할 수 있다. (하나씩 배치할 필요 없음)
.

Population 기본 구문

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

.

world를 만들어주자

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가 나온다.

.
.
.

Mission(3)

  • 40m X 40m의 벽으로 둘러싸기
  • 벽돌안에 constriction_barrel 모델을 무작위로 배치
  • construction_barrel의 배치는 30mx30m 공간으로 제한

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

미션 결과이다!

0개의 댓글