공부#Robotics#자율주행/(ROS2)Path Planning

ROS2로 turtlebot3 제어하기 3장. Nav2 이해하기와 파이썬 환경설정

BrainKimDu 2023. 6. 3. 00:02

이번 글은 별도의 참고자료가 존재하지 않고, 참고하는 블로그가 있는 경우 바로 다음에 표시를 하고 지나가도록 하겠습니다.


다시 실행해보면?

ros2 launch turtlebot3_gazebo turtlebot3_duworld.launch.py
ros2 launch turtlebot3_navigation2 navigation2.launch.py use_sim_time:=True map:=$HOME/map.yaml

이전 시간에 Nav2로 로봇을 이동시켜보고 끝났습니다. 조금이나마 path planning에서 도움이 되고자 nav2에서의 여러 파라미터들에 대해 설명을 하고자합니다.

 다시 실행을 해보면 다음과 같은 그림이 나왔습니다.

맵에서 볼 때 벽은 다음처럼 검정색으로 표시가 되는데

벽 주변으로 연한 분홍색의 무언가가 생성되어 있는 것을 확인할 수 있습니다.

그리고 로봇 주변으로 엄청나게 진한 분홍색이면서 파란색인 무언가가 생성된 것도 확인할 수 있습니다. 뭘까요?

앞에서 전역경로생성과 지역경로생성에 대한 이야기를 잠시 했었습니다. 그러면 로봇 주변의 상황은 지역경로 생성을 위한 부분이고, 맵에 표시가 되어 있는 부분은 전역경로생성에 필요한 부분입니다.

여기서 등장하는 개념이 cost map (충돌영역)입니다. 그래서 전역충돌영역(global cost map)과 지역충돌영역(local cost map) 두 가지가 현재 보여지고 있는 상황입니다.

cost map이 맞는지 collision region이 맞는지 모르겠습니다. 조금더 알아보고 수정하겠습니다. 아마 cost map 맞는 표현인거 같습니다.

 

충돌영역이라고 하니까 그러면 이 부분으로 안가겠네요?

네 맞습니다.

로봇을 한 번 충돌영역안으로 집어 넣어보겠습니다.

 충돌영역으로 이동을 하고 다음 이동 명령을 다른 충돌영역으로 지정하면

다음처럼 로봇은 혼란상태에 빠져버립니다.

다음처럼 우리가 보기에는 충돌할거 같진 않아보이는데, 로봇은 충돌영역에 빠져있기 때문에 움직이지 못합니다. 조금만 더 깊게 이야기 하면

도달할 수 있는 범위를 0으로 표시하고 도달할 수 없는 범위를 1로 표시한다고 가정을 해봅시다.

0 0 0 1 1
0 0 0 1 1 1
0 0 0 1 1 1
0 0 0 0 이부분 0
0 0 0 0 0 0

로봇은 값이 비싸기 때문에 벽과 부딪혀서 고장이 나면 안됩니다. 그렇기 때문에 벽 주변을 1로 설정해서 도달하지 못하게 설정했습니다.

그러면 우리가 이부분 으로 이동시킨다고 해봅시다.로봇은 가다가 멈추겠지만 급브레이크를 밟는게 아니기 때문에 어쩔 수 없이 밀리는 경우가 생깁니다. 그러면 로봇은

0 0 0 1 1
0 0 0 1 로봇 1
0 0 0 1 1 1
0 0 0 0 이부분 0
0 0 0 0 0 0

충돌영역으로 들어갑니다. 하지만 현재 로봇 주변의 값은 1이기 때문에 Nav2로  빠져나오는 것은 어렵습니다. 여러 대안으로 직접 조종해서 빠져나오게 하는 등의 알고리즘 처리를 할 수 있습니다.

 

다시 돌아와서 전역충돌영역은 Map 파일만을 참고해서 만들게 됩니다. 그래서 

맵이 불러와지고 로봇의 위치가 파악이 되면 전역충돌영역이 먼저 나타나게 됩니다. 

지역 충돌영역은 로봇이 움직일때마다 계산을 진행하게 됩니다.

그래서 가제보상과 다르게 로봇의 위치를 지정하면 다음과 같습니다.

다음으로 보시는 것처럼 지역충돌영역은 로봇의 현재위치를 참고해서 만들어지기 때문에 현재 보고있는 방향과 위치에 맞춰서 화면에 표시되게 됩니다.

 

충돌영역의 파라미터를 조정하면 손쉽게 변경이 가능하다

보통은 로봇명_navigation2 패키지를 참고하면 됩니다. 보통의 로봇들이 모두 navigation2 패키지를 가지고 다니는지는 모르겠습니다. 

우리는 turtlebot3 패키지를 사용하고 있으니 다음의 패키지에서 파일을 찾아봅시다. 

다음의 파일을 참고하면 됩니다. 저는 버거를 쓰지만 waffle을 쓰시는 분은 waffle을 건들면 됩니다. 두가지 파라미터를 수정해야합니다.

local_costmap의 cost_scaling_factor와 inflation_radius 그리고 global_costmap의 cost_scaling_factor와 inflation_radius입니다. 

이 값을 작게 수정하면 됩니다.

이 값을 한 번 0.5, 1.0 이렇게 수정을 해보도록 하겠습니다. 글로벌은 cost를 1.5 radius를 0.5로 설정해봅시다. 

그러면 빌드하고 다시 실행해봅니다.

수정 후와

수정 전입니다.

비교를 해봤을 때 많이 달라진 것을 알 수 있습니다. 충돌영역을 조정하는 것은 결국 벽에 더 가깝게 다가간다는 이야기입니다. 이를 완전히 줄이는 경우는 좁은 길을 지나가는 것이 아니고서는 조심해야합니다.

 

Map 파일을 한 번 살펴볼까요?

map.yam 파일을 보면 다음처럼 나와 있는 것을 볼 수 있습니다. 3가지만 집중해서 보면 됩니다.

image는 map.pgm 이전 시간에 만들었던 map파일을 가리킵니다. origin은 riviz상에서 위치를 어디로 지정할 생각이냐? (원점입니다.) 그냥 간단하게 이 부분은 나중에 다시 설명하겠습니다.

resolution의 값이 정말 중요한 값입니다. 일단 0.05입니다. 이 부분이 가장 중요합니다. 이 것은 바로 다음에 설명하도록 하겠습니다.

 

이미지 처리를 위한 파이썬 환경 구축하기

우선 ipynb파일을 만질 수 있는 환경이여야 합니다. 가상환경이 필요합니다. 다음을 따라할 수 있도록 합니다. 정말 간략하게 설명합니다. 

일단 우분투 22.04 기준입니다. 만약 20.04라면 파이썬은 3.8버전을 받아야합니다.

sudo apt install python3-pip
pip3 install --upgrade pip
python3 --version

우선 version에 맞게 다운로드 하면 됩니다. 22.04버전이라면 아래의 명령어를 입력합니다.

sudo apt -y install python3.10-venv

20.04라면 아래의 명령어를 입력합니다. 

sudo apt -y install python3.8-venv

다음은 가상환경을 구축하는 과정입니다.

cd
mkdir venv
python3 -m venv venv/pathplanning

다음의 명령어는 가상환경으로 접속하는 명령어입니다.

source ~/venv/pathplanning/bin/activate

다음처럼 앞에 가상환경으로 접속되었음이 나와야합니다. 그러면 여기서 필요한 파일을 다운로드 해주면 됩니다.

sudo apt install -y jupyter-core
pip install pandas matplotlib numpy scikit-learn jupyter opencv-python

다음을 통해서 사용할 모듈을 다운로드 받아옵시다. 실행은 jupyter notebook을 사용하건 VScode를 사용하건 편한대로 진행하면 됩니다.

저는 VScode에서 진행하도록 하겠습니다. image_processing.ipynb 라는 이름으로 파일을 하나 만들겠습니다.

VScode에서는 추가 라이브러리를 설치해주어야합니다. 

여기서 python과 jupyter를 다운받아주시면 됩니다. 그리고 image_processing.ipynb에서 오른쪽에 보면 select Kernel 이 있습니다 여기서 아까 만들었던 가상환경을 연결해줍니다.

가장 중요한건 opencv가 불러와지는지 입니다. 불러와지면 파이썬 환경 설정은 끝납니다.

여기서 한 번 끊어가고 싶은데, 글을 길게 씁시다.

 

전역경로 생성하기

전역경로 생성에 대한 아이디어는 결국 map파일을 보고 알 수 있습니다.

이 파일을 보면 벽으로 막혀서 못가는 위치는 색이 다른 것을 알 수 있습니다. 그리고 우리가 도달할 수 있는 범위는 흰색의 영역입니다.

위에서 잠깐 언급이 나왔었습니다. 갈 수 있는 영역은 0이고, 갈 수 없는 영역은 1로 표시가 된다고.. 

0 0 0 1 1 1
0 0 0 1 1 1
0 0 0 1 1 1
0 0 0 0 0 0
0 0 0 0 0 0

그러면 다음의 경우를 생각할 수 있을 겁니다.

목적지 0 0 1 1
0 0 0 1 1 1
0 0 0 1 1 1
0 0 0 0 0 0
0 0 0 0 0 출발지

여기서 경로탐색 알고리즘을 적용하면 되지 않을까요? 다음처럼 숫자 2로 표시하는 겁니다.

목적지 0 0 1 1
2 0 0 1 1 1
2 0 0 1 1 1
2 0 0 0 0 0
2 2 2 2 2 출발지

그리고 로봇은 2의 경로를 따라 움직이면 됩니다. 이를 진행하는 건 다음 글에서 진행하도록 합시다.