ROS2로 turtlebot3 제어하기 2장. MAP 만들기
이번 글은 별도의 참고자료가 존재하지 않고, 참고하는 블로그가 있는 경우 바로 다음에 표시를 하고 지나가도록 하겠습니다.
이번 장까지 사전 자료 제작이라고 생각하면 됩니다.
GAZEBO 실행하고 맵 만들기
이상적인 맵을 하나 만들고자 합니다. 맵을 어떻게 만들던 자유입니다. 맵을 좀 크게 정사각형 모양으로 만들면 좋을 것입니다. ROS설치가 완료되었다면 터미널 상에 gazebo 를 입력합니다.
gazebo를 입력하면 다음처럼 시뮬레이터가 실행될 것입니다.
그러면 왼쪽에 보시면 Edit 버튼을 누르고 난 후에 building Editor를 누르면됩니다. 그러면 다음처럼 화면이 나올 것입니다.
위의 그림에 여러분이 원하는대로 벽을 설치하면 됩니다.
대충 이런식으로 만들고 저장하시면 됩니다.
그냥 하얀색 도화지 위에 그림을 그리듯이 만드시면 됩니다. 다 만들었다 싶으면 File에서 save를 해주시면 world 파일이 만들어지는 것을 보실 수 있을 겁니다. 그리고 만들 때 주의할 점이라면 바닥에 타일들이 보이실 겁니다. 그 칸 밖으로 벽이 넘어가지 않게 주의해주세요. 위에서는 맵을 꽉채워서 했는데, 오차가 많이 누적됩니다. 그러니 맵을 조금 축소해주세요.
여튼 두 파일이 만들어질 것입니다. 일단 이건 크게 중요한게 아니고, 나중에 날려먹었을 경우에 다시 할 파일입니다. 빌드 에디터를 안심하고 종료하면
gazebo에 다음처럼 map이 보일 것입니다. 여기서 다시 저장하면 world파일이 만들어집니다. 이 파일을 사용해야합니다. 왼쪽 위에 파일에서 world를 저장합니다. 꼭 확장자명을 .world로 만들어주어야합니다.
대충 저장을 완료했다면 이제 turtlebot3를 이 안으로 소환할 수 있습니다.
방금 만든 맵에 Turtlebot3 소환하기
방금 만든 맵에 Turtlebot3를 소환해봅시다. 아마 이전 글을 참고하셨다면 다음처럼 4개의 패키지가 다운로드 되어있어야합니다.
방금 만들었던 world파일을 turtlebot3_simulations 패키지 내부의 turtlebot3_gazebo 폴더의 worlds폴더에 넣습니다. 이제 빌드를 하고 나서 실행을 해봅시다.
turtlebot의 경우에는 world를 터미널상에서 지정하는 방식이 아니라 launch 파일을 하나 만들어주어야하는 것 같습니다. turtlebot_gazebo 패키지 내부에 가면
launch 폴더 내부로 들어갑니다.
turtlebot3에서는 맵이 만들어질 때마다 launch 파일을 하나 작성해주어야하는 것으로 보입니다. 적장히 아무 파일이나 하나 복사를 해줍시다.
파일 이름을 저는 turtlebot3_duworld.launch.py로 하겠습니다. 그리고 내부 코드를 조금 뜯어주어야합니다.
39번 줄을 다음처럼 수정합니다. 만드신 map의 이름으로 하시면 될 것입니다.
저장을 진행하면 turtlebot3 환경을 불러와준 다음에 colcon build를 진행합니다.
대충 완료되면 다음의 명령어로 방금 만들었던 맵을 실행해볼 수 있습니다. 다음의 명령어를 입력합니다.
ros2 launch turtlebot3_gazebo turtlebot3_duworld.launch.py
잘 실행되는 것을 확인할 수 있습니다. 이 과정이 완료되면 일단 SLAM을 통해서 주변 맵을 따주어야합니다. 다음을 따라서 진행하시면 됩니다.
그러나 현재의 문제는 터틀봇이 갇혀버렸습니다. 스폰위치에 대한 문제입니다. launch파일을 조금 더 수정해주어야합니다.
뭔가 이 부분이 수상합니다. 좌표값이 x방향으로 -2 만큼 움직이고, y방향으로 -0.5만큼 움직인 위치라고 합니다.
뭔가 그럴듯 합니다. 그러면 저는 초록색지점과 분홍인가요? 저 지점을 스타팅 포인트로 잡고 싶습니다. x는 0으로 y는 -5로 지정하고 저장하겠습니다.
다시 실행하면 위치가 조정되어 있을 것입니다. 빌드를 하고 다시 실행해봅니다.
위치가 성공적으로 조정되었으니 다음 단계로 넘어갑시다.
SLAM 알고리즘을 통해서 map을 만듭니다.
SLAM이라 함은 simultaneous localization and mapping의 약자로 간단하게 생각해서 동시에 로봇이 자신의 위치를 인지하면서 그와 동시에 맵을 만든다 라고 생각하면됩니다.
좀 더 깊게 들어가면 이전 시간에 확인했던 전역경로생성과 지역경로생성을 위한 지도를 만드는 과정이라 생각하면 되지만, 조금 다른 개념으로는 정밀지도라는 개념이 추가됩니다.
방금 만들었던 맵에 대한 정밀한 지도를 얻는다고 생각하시면 됩니다.
개념 설명을 추가하자면 라이다 센서는 360도 방향으로 레이저를 쏩니다. 이 레이저가 반사된 시간을 측정하면 주변의 장애물을 인식할 수 있습니다.
이 센싱 정보를 가지고 SLAM 알고리즘을 사용하면 map을 얻을 수 있습니다. 이 과정은 복잡해서 SLAM만을 연구하는 석박들도 존재합니다.
이제 SLAM 알고리즘을 이용해서 MAP을 만들겠습니다. 터미널은 3개가 필요합니다.. 3개가 모두 ROS환경과 turtlebot환경을 불러오는 것을 잊지 마세요.
ros2 launch turtlebot3_gazebo turtlebot3_duworld.launch.py
ros2 launch turtlebot3_cartographer cartographer.launch.py use_sim_time:=True
ros2 run turtlebot3_teleop teleop_keyboard
SLAM에는 google의 cartographer라는 알고리즘이 사용됩니다. 대충 맨위의 명령어는 turtlebot3를 방금 만들었던 맵에 소환하면서 gazebo를 실행한 것이고,
두 번째는 SLAM 알고리즘을 실행하면서 이에 대한 툴? 인 Rviz가 실행된 모습입니다.
세 번째는 결국 SLAM을 이용해 map파일을 만들고자 한다면, 로봇이 모든 구역을 방문해야합니다. 그러므로 로봇을 직접움직여서 맵을 점점 밝히게 됩니다.
처음엔 이렇지만
터틀봇을 이동하면 점차 맵이 넓어지는 것을 알 수 있습니다.
여튼 다시 돌아와서 Rviz에서 보면 빨간색점으로 표시된 부분이 라이다의 입력값들입니다. 벽에 부딪히고 다시 돌아와서 저 지점에 뭔가가 있어 라고 온 것이죠.. 여튼 SLAM을 계속 진행합시다.
wasdx의 키로 터틀봇을 움직일 수 있습니다.
대충 이정도로 그려졌다면 맵을 저장합시다. 다음의 명령어를 입력합니다.
ros2 run nav2_map_server map_saver_cli -f ~/map
그러면 맵이 저장된 것을 알 수 있습니다.
그러면 다음과 같은 맵파일이 만들어집니다만.. 이걸 가지고 로봇을 움직이는데에는 문제없으나, cartographer는 저렇게 애매한 부분을 남기는 군요.. 흰부분이 살짝 문제가 될 수도 있습니다. 그러니 이걸 지우고 갑시다.
이를 해결하기 위해서는 리눅스에서는 이미지 편집 파일이 필요합니다. 이름이 약간 한국적인 이름이였는데 잠시만요..
아 맞아 김프를 다운로드 받으시면 됩니다. 김프가 pgm파일의 수정을 지원합니다.
sudo apt-get update
sudo add-apt-repository ppa:otto-kesselgulasch/gimp-edge
sudo apt-get update
sudo apt install gimp
대충 색을 픽업하고 그려줍니다.
깔끔해졌습니다. 이제 이를 다시 저장합니다. 그냥 저장으로는 pgm으로 저장이 안됩니다. 다음을 따라 진행합니다
File -> Export As 로 가서 pgm으로 저장합니다. raw를 고릅니다.
그러면 이쁜 우리맵을 얻습니다. 이 맵을 가지고 작업을 진행합시다. 우선 이 맵이 정상 작동하는지 확인을 해보아야합니다. 이 맵 파일을 다음의 위치로 넣습니다.
이쁘게 잘 만들어졌습니다. 뿌듯하네요.. 이 파일은 혹시모르니 깃헙에 백업을 해두었습니다. 나중에 하나의 프로젝트가 완성이 되면 그때 깃헙 링크를 올리도록 하겠습니다. 하나만 더 보고 갑시다. navigation이 잘 동작하는지
Nav2 패키지를 이용해 자율주행을 해보자.
저는 그냥 네브2라고 읽습니다. 간단하게 설명해서 ROS에서 자율주행을 실현해주는 패키지입니다. A* 알고리즘을 기반으로 만들어져있습니다. 이에 대한 세세한 내용은 뒤에 나올 글에서 집중적으로 다뤄보도록 합시다.
그냥 잘 된다 이정도만 확인해봅시다. 터미널이 2개 필요하고, map파일은 일단 home에 위치시켜둡시다.
ros2 launch turtlebot3_gazebo turtlebot3_duworld.launch.py
ros2 launch turtlebot3_navigation2 navigation2.launch.py use_sim_time:=True map:=$HOME/map.yaml
실행하면 다음과 같은 화면이 나옵니다.
문제는 현재 위치를 잡지 못합니다. 그러니 지정을 해줍시다. 현재 로봇의 위치를 2D pose estimation을 통해서 지정해줍시다.
화살표 방향을 맞게 지정해주면 다음처럼 화면이 나오게 됩니다. 이제 진행을 합시다. Nav2 goal을 통해 최대한 하얀색 배경인 곳으로 이동명령을 내려봅시다.
그럼 로봇이 움직이기 시작합니다.
잘움직입니다. 이게 Nav2입니다.
목표지점에 도착하면 다음처럼 도착했음을 알리게 됩니다. 이에 대한 자세한 이야기는 다음 글에서 진행을 하도록 합니다. 우리는 Nav2의 도움없이 path planning을 시키는 것을 목표로 합니다.
한가지 주의할 점이라면 실제로봇은 SLAM에서 왠지 모를 오차가 많이 누적됩니다. 터틀봇3의 실물을 만져보지는 않았지만 맵이 넓어지면 넓어질 수록 오차는 커집니다. 그래서 map 파일을 이미지 편집툴로 수정하는게 나쁜짓?은 절대 아닙니다