3. 개발 PC 환경
3.8RViz로 시각화와 디버깅
2.5장, 2.10장, 2.11장에서 TF, 지도, 스캔 이야기가 나왔고 4.7장에서는 실기기로 지도를 만듭니다. 그 자리마다 "RViz에서 확인한다"는 문장이 있었습니다. 이 장은 그 RViz를 직접 다루는 방법과, 화면이 비어 있을 때 원인을 찾는 순서를 정리합니다.
1. RViz2는 무엇인가
RViz2는 ROS2 시스템의 데이터를 3D 화면에 그려 주는 시각화 도구입니다. 시뮬레이터가 아닙니다. 로봇을 움직이거나 센서 값을 만들어 내지 않습니다. 다른 노드가 발행한 토픽을 구독해서 그림으로 바꿔 보여 줄 뿐입니다.
이 차이가 디버깅의 출발점입니다. RViz2에 로봇이 안 보인다면 RViz2가 고장 난 것이 아니라, 그릴 데이터가 안 오고 있거나 데이터를 받아서 그리는 조건이 맞지 않는 것입니다. 그래서 RViz2 문제는 대부분 ros2 topic과 TF 명령으로 원인이 드러납니다.
Gazebo 같은 물리 시뮬레이터는 데이터를 만드는 쪽이고 RViz2는 그 데이터를 보는 쪽입니다. 실기기를 쓸 때도 RViz2는 그대로 쓰이고 센서 값의 출처만 달라집니다.
2. 실행과 화면 구성
터미널에서 실행합니다. 두 방식은 같은 프로그램입니다.
rviz2
ros2 run rviz2 rviz2
화면은 다섯 부분으로 나뉩니다. 처음 켜면 창이 화면 전체를 덮습니다.
- ① Fixed Frame: 기본값은
map - ② Global Status: TF가 없어서 주황색 경고가 떠 있습니다.
- ③ Add: 디스플레이를 추가하는 버튼
- ④ 도구 모음의
2D Pose Estimate,2D Goal Pose,Publish Point - ⑤ 오른쪽 Views 패널: 카메라 방식(Orbit)과 시점 값
각 영역의 역할은 아래 표와 같습니다.
| 영역 | 내용 |
|---|---|
| 가운데 3D 화면 | 디스플레이가 그린 결과. 마우스 왼쪽 드래그는 회전, 가운데(휠) 드래그는 이동, 휠은 확대·축소 |
| 왼쪽 Displays 패널 | 표시 항목(디스플레이)의 목록. 맨 위 Global Options에 Fixed Frame이 있음 |
| 아래쪽 Add 버튼 | 디스플레이를 새로 추가. By display type과 By topic 탭이 있음 |
| 위쪽 도구 모음 | Interact, Move Camera, Select, Measure, 2D Pose Estimate, 2D Goal Pose, Publish Point |
| 오른쪽 Views 패널 | 카메라 방식(Orbit 등)과 시점 |
도구 모음의 세 도구는 클릭한 결과를 토픽으로 발행합니다. 2D Pose Estimate는 /initialpose, 2D Goal Pose는 /goal_pose, Publish Point는 /clicked_point입니다. 4.7장의 내비게이션 실습에서 초기 자세와 목표를 찍는 것이 이 도구입니다. 이름은 3.11장의 tiki_description.rviz 파일에서 확인한 것입니다.
VM에서는 3D 화면이 느리거나 검을 수 있습니다. 3.2장의 3D 가속 절을 먼저 확인하고, 그래도 느리면 디스플레이를 필요한 것만 켜 둡니다. 화면이 깨지는 정도는 디스플레이를 줄이면 나아지는 일이 많습니다.
3. Fixed Frame
RViz2는 서로 다른 프레임에서 오는 데이터를 하나의 좌표계에 겹쳐 그립니다. 그 기준이 Fixed Frame입니다. 왼쪽 Displays 패널의 Global Options에서 정합니다.
규칙은 두 가지입니다.
- Fixed Frame은 지금 TF에 실제로 존재하는 프레임 이름이어야 합니다. 없는 이름이면 오류입니다.
- 데이터는 자기 프레임에서 Fixed Frame까지 변환이 이어져야 그려집니다. 변환이 끊긴 데이터는 사라집니다.
RViz2의 기본 Fixed Frame은 map입니다. 로봇 모델만 보고 싶을 때는 base_link나 base_footprint처럼 로봇에 붙은 프레임으로 바꿉니다. 지도와 스캔을 함께 볼 때는 map을 씁니다. 프레임 사이의 이어짐은 이렇게 생깁니다.
이 체인의 각 구간을 누가 발행하는지는 앞 장에서 다뤘습니다. map에서 odom은 SLAM이나 AMCL이 발행합니다(2.10장, 2.12장). odom에서 base_footprint는 TIKI-MINI의 diff_controller가 오도메트리와 함께 발행합니다(enable_odom_tf: true). 그 아래 base_link와 laser는 robot_state_publisher가 URDF에서 읽어 발행합니다(2.5장). 어느 하나라도 빠지면 그 아래 프레임은 map 기준으로 그려지지 않습니다.
4. 주요 디스플레이
Add 버튼에서 디스플레이 종류를 고르면 Displays 패널에 항목이 생깁니다. 항목을 펼치면 Topic과 옵션이 나옵니다. 자주 쓰는 것은 이렇습니다.
| 디스플레이 | 보여 주는 것 | 토픽과 메시지 | 처음 확인할 것 |
|---|---|---|---|
| TF | 프레임의 축과 부모-자식 관계 | /tf, /tf_static | Show Names를 켜서 이름 읽기, Frame Timeout |
| RobotModel | URDF의 모양 | /robot_description(Description Topic) | Description Topic 값, Durability |
| LaserScan | 2D LiDAR 점 | /scan, sensor_msgs/msg/LaserScan | Topic, Size, Reliability |
| Map | 점유 격자 지도 | /map, nav_msgs/msg/OccupancyGrid | Durability(Transient Local) |
| Path | 계획한 경로 | nav_msgs/msg/Path | Topic 이름 |
| Pose | 위치와 방향 화살표 하나 | geometry_msgs/msg/PoseStamped | header.frame_id |
| Marker | 코드에서 그린 도형 | visualization_msgs/msg/Marker | Topic 이름, frame_id, ns와 id |
디스플레이 이름 옆 체크박스로 끄고 켭니다. 이름 앞에 작은 상태 아이콘과 색이 붙습니다. 뜻은 이렇습니다.
| 상태 | 뜻 |
|---|---|
| Ok | 데이터를 받아서 그리는 중 |
| Warn | 그리지만 문제가 있음. 메시지를 읽을 것 |
| Error | 그릴 수 없음. 펼쳐서 이유 문구를 읽을 것 |
| Disabled | 체크가 꺼져 있음 |
문제가 생기면 먼저 이 상태 문구를 읽는 습관이 중요합니다. 화면이 비어 있는 이유가 대부분 문구에 적혀 있습니다. 이 문구는 7절의 체크리스트에서 단서로 씁니다.
By topic 탭은 지금 발행되고 있는 토픽 중 RViz2가 그릴 수 있는 것만 골라서 보여 줍니다. 원하는 토픽이 이 목록에 없다면 그 토픽을 발행하는 쪽의 문제일 가능성이 큽니다.
5. 설정 저장과 불러오기
디스플레이와 Fixed Frame, 카메라 시점을 하나하나 다시 맞추기는 번거롭습니다. 설정을 .rviz 파일로 저장합니다.
- File 메뉴의 Save Config As로 이름을 정해 저장하고 Ctrl+S로 덮어씁니다.
- File 메뉴의 Open Config로 불러옵니다.
- 시작할 때 지정하려면
rviz2 -d <파일 경로>를 씁니다.
rviz2 -d ~/my_view.rviz
설정 파일 이름을 지정하지 않고 종료할 때 저장하면 ~/.rviz2/default.rviz가 갱신되고, 다음에 rviz2만 실행해도 이 설정이 열립니다. 상황이 바뀌어 화면이 이상하면 이 파일 이름을 바꿔 두면 초기 상태로 시작합니다.
TIKI-MINI 패키지는 모델 확인용 설정 tiki_description.rviz를 갖고 있고 런치 파일이 -d로 불러옵니다(8절). 4.7장의 Nav2는 nav2_bringup에 들어 있는 기본 설정을 씁니다.
6. 실습: TF를 직접 만들고 일부러 깨뜨리기
로봇 없이 RViz2의 동작을 확인합니다. Tilix 세 칸을 씁니다. 먼저 칸 1에서 RViz2만 켭니다.
rviz2
Displays 패널을 보면 Global Options 안의 Fixed Frame이 map이고, 그 아래 Global Status에 주황색 경고가 떠 있습니다(위 그림 ①, ②). 펼치면 Fixed Frame 항목에 No tf data.로 시작하는 문구가 보입니다. 아직 TF를 발행하는 노드가 없으니 당연한 결과입니다. 이 VM의 RViz2에서는 이때 Error가 아니라 Warn으로 표시되었습니다. 문구는 버전에 따라 다를 수 있습니다.
칸 2와 칸 3에서 TF 두 개를 발행합니다. 첫 번째는 map과 base_link 사이, 두 번째는 base_link와 laser 사이입니다. 두 번째는 2.5장의 라이다처럼 z로 올리고 yaw를 180도로 돌렸습니다.
ros2 run tf2_ros static_transform_publisher --x 1.0 --y 0 --z 0 --yaw 0 --pitch 0 --roll 0 --frame-id map --child-frame-id base_link
이 명령은 계속 실행되므로 칸 3에서 이어서 합니다.
ros2 run tf2_ros static_transform_publisher --x 0 --y 0 --z 0.2 --yaw 3.14159 --pitch 0 --roll 0 --frame-id base_link --child-frame-id laser
옵션 이름이 맞지 않는다는 오류가 나면 ros2 run tf2_ros static_transform_publisher --help로 이 버전의 옵션을 확인하세요. OVA에서는 위 옵션이 그대로 동작했습니다.
- ① 칸 2:
map에서base_link로 가는 TF를 발행하는 명령 - ② 칸 2 출력:
from 'map' to 'base_link', 이동 값1.0, 0, 0 - ③ 칸 3:
base_link에서laser로 가는 TF를 발행하는 명령 - ④ 칸 3 출력:
from 'base_link' to 'laser', 이동 값 z0.2와 회전 값
RViz2로 돌아와(독의 RViz 아이콘을 누르면 앞으로 나옵니다) Global Status가 Ok로 바뀌었는지 봅니다. 왼쪽 아래 Add를 눌러 TF를 추가합니다.
- ①
By display type(종류로 찾기)과By topic(토픽으로 찾기) 탭 - ② 목록에서
TF: 목록이 길어서 스크롤을 내려야 보입니다. - ③ 화면에 표시될 이름. 비워 두면 종류 이름이 들어갑니다.
- ④
OK
TF 항목을 펼쳐 Show Names를 켭니다. 3D 화면은 휠을 굴려 확대하면 보기 좋습니다. 이 VM에서는 휠을 아래로 굴리면 확대되었습니다. map, base_link, laser 세 프레임의 축이 보입니다.
- ① Global Status가 초록색 Ok로 바뀜
- ②
Show Names체크: 프레임 이름이 글자로 나옵니다. - ③
map프레임의 축 - ④
base_link와laser: 1.0 떨어진 곳에 겹쳐 있고laser이름이 위(z 0.2)에 붙어 있습니다.
base_link는 map에서 x로 1 떨어져 있고, laser는 그 위 0.2에 있으며 축이 반대로 돌아 있습니다.
일부러 깨뜨려 보기
Fixed Frame을 일부러 틀리게 바꿉니다. Global Options의 Fixed Frame 칸을 더블클릭해 map 대신 mapp처럼 없는 이름을 적고 Enter를 누르세요. 상태가 바뀝니다.
- ① 없는 이름
mapp을 넣은 Fixed Frame - ② Global Status가 빨간 Error로 바뀌고
Frame [mapp] does not exist라는 문구가 나옵니다. - ③ 아래쪽 설명 칸에도
Global Status: Error가 표시됩니다.
이 VM에서는 TF 디스플레이의 축이 지워지지 않고 그대로 남아 있었습니다. 축이 남아 있어도 오류입니다. 화면 모양이 아니라 상태 표시가 판단 기준이므로 반드시 Global Status를 보세요. Pose나 LaserScan처럼 Fixed Frame으로 좌표를 바꿔야 그려지는 디스플레이는 이 상태에서 그려지지 않습니다.
- Global Status가 어떤 색으로 바뀌었는지 확인합니다.
- 펼쳐서 문구를 읽습니다. 문구에
mapp이라는 이름과 존재하지 않는다는 뜻이 보입니다. - 터미널에서
ros2 run tf2_ros tf2_echo map laser를 실행해, 프레임이 실제로 있는 이름은map인 것을 확인합니다. - Fixed Frame을
map으로 돌려 놓으면 Global Status가 다시 Ok가 됩니다.
같은 방식으로 base_link와 laser로도 바꿔 보세요. 이 체인 안의 이름이면 어느 것으로 바꿔도 오류가 없고 화면의 기준만 달라집니다. 나중에 로봇이 움직이면 이 차이가 중요합니다. 기준을 map으로 두면 로봇이 움직이고, base_link로 두면 로봇이 가만히 있고 세상이 움직입니다.
선택: Pose 디스플레이
새 터미널을 열어 위치 하나를 발행합니다. 이 명령은 map 기준의 점을 계속 발행합니다.
ros2 topic pub -r 1 /my_pose geometry_msgs/msg/PoseStamped "{header: {frame_id: map}, pose: {position: {x: 2.0, y: 1.0, z: 0.0}, orientation: {w: 1.0}}}"
RViz2에서 Add, By display type, Pose를 고르고 Topic을 /my_pose로 지정합니다. x=2, y=1 위치에 화살표가 나타납니다. frame_id를 base_link로 바꿔서 다시 발행하면 위치가 어떻게 달라지는지 확인해 보세요. 같은 좌표값이라도 기준 프레임이 다르면 그려지는 곳이 달라집니다.
모든 실습을 마치면 실행 중인 칸에서 Ctrl+C로 노드를 끕니다.
7. 아무것도 안 보일 때
디스플레이는 데이터가 오고 프레임 이름, QoS, 시간이 모두 맞아야 그려집니다. 화면이 비어 있을 때는 아래 순서대로 위에서부터 점검합니다. 앞 단계를 확인하지 않고 뒤 단계로 가면 헤맵니다.
- 디스플레이 상태 문구 읽기. 펼쳐서 Error와 Warn의 문구를 먼저 읽습니다. 4절에서 정리한 상태 표가 이 단계입니다.
- 토픽 확인. 터미널에서
ros2 topic list로 토픽이 있는지,ros2 topic hz /scan이나ros2 topic echo --once /scan으로 값이 오는지 봅니다. 값이 안 오면 RViz2 문제가 아니라 발행하는 쪽 문제입니다. - Fixed Frame. 이름이 실제 TF에 있는지, 3절의 규칙대로 데이터의 프레임과 이어지는지 봅니다.
- TF 구조 확인. 아래 명령으로 끊긴 곳을 찾습니다.
- QoS. 토픽의 발행자와 구독자(RViz2의 디스플레이)가 서로 받을 수 있는 설정인지 봅니다.
- 시간. 시뮬레이션 시각(
use_sim_time)을 쓰는 시스템인지 확인합니다.
TF 확인 도구
런치나 노드를 켜 둔 상태에서 터미널 하나를 더 열어 실행합니다.
ros2 run tf2_tools view_frames
ros2 run tf2_ros tf2_echo base_footprint laser
6절의 두 TF 발행자(map→base_link→laser)가 켜져 있는 상태에서 실행한 결과입니다.
- ① 명령. 파일이 현재 폴더에 만들어지므로
/tmp로 이동해서 실행했습니다. - ② 5초 동안 TF를 듣고
frames.pdf를 만든다는 로그 - ③ 만들어진
frames_<날짜_시각>.pdf와.gv파일
view_frames는 몇 초 동안 TF를 듣고 frames_<날짜_시각>.pdf와 .gv 파일을 현재 폴더에 만듭니다. PDF를 만들 때 Graphviz가 필요하므로 없으면 sudo apt install graphviz를 먼저 하세요. PDF를 열어 프레임이 하나의 트리로 이어져 있는지 확인합니다. 트리가 둘로 쪼개져 있으면 그 사이를 이어 주는 발행자가 없는 것입니다. 이 방법은 2.5장에서도 썼습니다.
- ①
tf2_echo map laser:map에서 본laser - ②
Translation:[1.000, 0.000, 0.200]. 6절에서 준 x 1.0과 z 0.2가 합쳐진 값입니다. - ③
RPY (degree)의180.000: 6절에서 준 yaw 3.14159(약 180도)입니다.
tf2_echo <기준> <대상>은 기준 프레임에서 본 대상 프레임의 위치와 자세를 계속 출력합니다. 변환이 없으면 변환이 없다는 취지의 경고가 반복됩니다. 두 프레임 사이가 이어져 있는지를 가장 빠르게 가리는 명령입니다.
QoS 맞추기
QoS 문제는 데이터가 분명히 발행되는데 RViz2에만 안 보일 때 의심합니다. 1.8장에서 본 것처럼 발행자와 구독자의 설정이 서로 맞아야 데이터가 전달됩니다. 토픽의 현재 설정은 이렇게 봅니다.
ros2 topic info /map --verbose
발행자와 구독자마다 Reliability와 Durability 같은 항목이 나옵니다. 아래는 6절의 /my_pose에 같은 명령을 실행한 화면입니다.
- ①
--verbose를 붙이면 발행자와 구독자의 QoS가 함께 나옵니다. - ②
Publisher count: 1 - ③ 발행자의 QoS:
RELIABLE,TRANSIENT_LOCAL - ④
Subscription count: 0: 아직 구독하는 쪽이 없습니다. RViz2에 디스플레이를 추가하면 1이 됩니다.
자주 만나는 경우는 이렇습니다.
| 디스플레이 | 증상 | 조정 |
|---|---|---|
| Map | /map이 한참 뒤에도 안 보임 | Map 항목의 Topic을 펼쳐 Durability Policy를 Transient Local로 변경 |
| LaserScan | 연결은 됐는데 점이 안 보이거나 끊김 | Reliability Policy를 Best Effort로 변경 (4.7장과 같은 설정) |
| RobotModel | 모델이 안 나오고 문구에 description이 없다고 나옴 | Description Topic의 Durability를 Transient Local로 변경 |
지도는 한 번 발행한 뒤 구독자가 늦게 붙어도 마지막 지도를 받아야 하므로 보통 Transient Local로 발행합니다. 구독하는 쪽이 Volatile이면 이미 지나간 지도를 받지 못하므로 다음 갱신 때까지 화면이 비어 있을 수 있습니다. 2.11장과 4.7장에서도 같은 이유로 이 설정을 확인했습니다. 로봇 모델도 시작할 때 한 번만 발행되므로 같은 일이 생길 수 있습니다. 위 표의 항목은 일반적으로 알려진 증상이고, 이 교재에서 직접 VM으로 확인한 것은 아닙니다. 화면이 표와 다르면 그대로 기록해 두세요.
시간
시뮬레이터를 쓰는 시스템에서는 노드들이 /clock 토픽의 시각을 쓰는 경우가 있습니다(use_sim_time, 2.9장). 이때 RViz2만 컴퓨터 시각을 쓰면 TF의 시각과 어긋나서 변환을 찾지 못합니다. 문구는 보통 시각이 너무 오래됐거나 미래라는 취지의 경고입니다. 이 경우 RViz2도 같은 시각을 쓰도록 실행합니다.
ros2 run rviz2 rviz2 --ros-args -p use_sim_time:=true
반대로 시뮬레이션이 아닌 실기기에서 use_sim_time:=true로 켜 두면 /clock이 없으니 시간이 흐르지 않아 TF가 멈춘 것처럼 보입니다. 실기기에서는 꺼 둡니다(TIKI-MINI의 nav2_params.yaml도 모든 노드가 use_sim_time: False입니다).
한 장으로 정리하기
| 증상 | 가장 먼저 볼 곳 | 명령 |
|---|---|---|
| Global Status가 Error | Fixed Frame 이름 | ros2 run tf2_ros tf2_echo <기준> <대상> |
| 특정 디스플레이만 Error | 그 디스플레이의 상태 문구 | 펼쳐서 읽기 |
| 문구는 없는데 비어 있음 | 데이터가 오는지 | ros2 topic hz, ros2 topic echo --once |
| 데이터는 오는데 안 보임 | QoS | ros2 topic info <토픽> --verbose |
| 일부 프레임만 안 보임 | TF 트리가 끊겼는지 | ros2 run tf2_tools view_frames |
| 프레임이 깜빡이거나 사라짐 | 발행 주기, Frame Timeout, 시각 | TF 디스플레이 옵션, use_sim_time |
8. TIKI-MINI 모델 띄우기 (실기기 연결 후)
OVA의 VM에는 tiki_description이 없습니다. 로봇 컴퓨터가 이 패키지를 실행해 /robot_description과 /tf를 발행하고, VM의 RViz2는 그 토픽을 받아서 그립니다(3.1장, 3.11장). 그래서 이 절의 런치 명령은 로봇에서 실행하는 것이고, VM에서는 RViz2만 켜 두면 됩니다. 실기기를 연결하는 4부에서 따라 해 볼 수 있도록 로봇 쪽 동작을 정리합니다. 2.5장의 명령을 RViz2 관점에서 다시 보는 내용입니다.
# 로봇 컴퓨터에서 실행 (VM에는 이 패키지가 없습니다)
ros2 launch tiki_description tiki_description.launch.py rviz:=true
이 런치 파일은 인자 세 개를 선언합니다. rviz는 기본 false이고 rviz:=true를 줘야 RViz2가 열립니다. rsp는 기본 true로 robot_state_publisher를 실행합니다. RViz2는 tiki_description.rviz 설정으로 열립니다. 이 설정은 Fixed Frame이 base_footprint이고 Grid, RobotModel, TF 디스플레이가 켜져 있습니다.
확인할 것은 두 가지입니다.
- RobotModel의 Description Topic이
/robot_description입니다.robot_state_publisher가 URDF를 이 토픽으로 발행합니다. 설정 파일의 Durability는 Volatile입니다. RViz2가 모델이 발행된 뒤에 뜨면 모델을 못 받아 비어 있을 수 있는데, 이때가 7절의 QoS 표에서 RobotModel을 조정하는 경우입니다. - TF 트리는
base_footprint,base_link,back_side,lidar_mount,lidar_bottom,laser가 이어져 있어야 합니다(URDF의 링크 이름). 바퀴 링크는/joint_states를 발행하는 노드가 없으면 TF가 만들어지지 않습니다.ros2 run joint_state_publisher_gui joint_state_publisher_gui를 다른 터미널에서 실행하면 슬라이더로 바퀴를 돌릴 수 있습니다(2.5장). 여기서 프레임이 안 보이면 7절의 순서를 그대로 적용합니다. 상태 문구를 읽고,view_frames로 트리를 보고, Fixed Frame을base_footprint나base_link로 맞추고, 필요하면 RobotModel의 Durability를 바꿉니다.
실기기에서 지도를 만들 때는 4.7장이 이 장의 내용을 그대로 씁니다. Fixed Frame을 map으로 두고 Map(토픽 /map), LaserScan(토픽 /scan), TF를 추가합니다. slam.yaml의 map_update_interval: 5.0 때문에 지도는 5초에 한 번씩 갱신되므로(2.10장), 처음 몇 초 동안 지도가 비어 있다고 서둘러 설정을 바꾸지 마세요. map 프레임이 목록에 아직 없으면 SLAM이 첫 스캔을 처리하기 전입니다.
9. 브라우저의 가상 RViz로 연습하기
VM이 없어도 브라우저 안의 가상 RViz2로 앞에서 본 조작을 해 볼 수 있습니다. VM에서 RViz2를 쓰기 전후에 해도 좋습니다. 창 모양과 색, 패널 배치, 상태 문구를 RViz2에 최대한 맞췄고, 3D 화면은 실제처럼 Orbit 시점으로 돌려 볼 수 있습니다. 화면이 넓어야 해서 전체 화면 창으로 열립니다.
에뮬레이터가 2.11장의 지도 만들기 코드를 40초(가상 시간) 돌리는 동안의 /tf, /scan, /map이 들어옵니다. 창을 열면 설정 파일 default.rviz를 막 연 상태라서 Grid만 있습니다. 보고 싶은 것은 직접 추가해야 합니다. 이 점이 실제 RViz2와 같습니다.
가상 RViz2
RViz2와 같은 창 모양(메뉴, 도구 막대, Displays, Views, Time 패널)에서 Fixed Frame을 바꾸고, 표시를 추가하고, QoS를 맞춰 보세요. 에뮬레이터가 40초 동안 지도를 만드는 동안의 /tf, /scan, /map이 들어옵니다. 넓은 화면이 필요해서 전체 화면 창으로 열립니다.
Esc 키나 오른쪽 위 닫기 단추로 닫습니다. 너비 1000px 이상의 화면을 권장합니다.
가상 RViz2에서 되는 것은 다음과 같습니다.
- 메뉴
File에서default.rviz와tiki_description.rviz불러오기,Panels에서 패널 켜고 끄기 - 도구 막대: Move Camera(왼쪽 끌기로 회전, 가운데 끌기나 Shift로 이동, 오른쪽 끌기나 휠로 확대), Focus Camera, 2D Pose Estimate, 2D Goal Pose, Publish Point
- Displays 패널: Fixed Frame 입력, 표시 추가(Add), 복제, 삭제, 이름 바꾸기, 속성 편집, 상태(Status) 표시
- 표시 종류: Axes, Grid, LaserScan, Map, RobotModel, TF
- Views 패널: Orbit과 TopDownOrtho, Target Frame, Distance, Yaw, Pitch 편집, Zero 단추
- 아래 시뮬레이션 줄: 재생과 일시정지, 시간 이동, 속도
해 볼 것
Add를 눌러TF를 추가합니다. 프레임 이름과 부모를 잇는 노란 선이 보입니다.map과odom은 이 예제에서 같은 자리이고, 나머지는 로봇 위에 겹쳐 있습니다. Frames를 펼쳐 이름을 켜고 끄면서 확인하세요.RobotModel을 추가하고 Description Topic을/robot_description으로 고릅니다. 로봇이 나타나고 바퀴가 돕니다. Description Topic 왼쪽 화살표를 펼치면 Durability Policy가 있습니다. 기본은Transient Local이고Volatile로 바꾸면 Error가 됩니다.robot_state_publisher는/robot_description을 시작할 때 한 번만 보내므로, 나중에 켠 RViz가 Volatile로 구독하면 받을 방법이 없습니다.File에서tiki_description.rviz를 열면 이 설정이 저장된 채로 열립니다.LaserScan을 추가하고 Topic을/scan으로 고릅니다. 하얀 점이 거의 안 보이면 Size (m)를 0.05로 키웁니다. Topic을 펼쳐 Reliability Policy를Reliable로 바꾸면 Warn이 되고 점이 사라집니다. 이 예제의/scan발행자는 Best Effort로 보내서, Reliable로 구독하면 QoS가 맞지 않습니다.Map을 추가하고 Topic을/map으로 고릅니다. 지도가 자라는 것을 재생해서 보세요. Topic을 펼쳐 Durability Policy를Transient Local로 바꾸면 Warn이 되고 지도가 사라집니다. 이 예제의/map발행자는 기본값 Volatile이라서, 구독하는 쪽이 더 까다로운 설정을 요구하면 연결되지 않습니다. 실제slam_toolbox나map_server는/map을 Transient Local로 발행하므로 거기서는 Transient Local로 구독해야 늦게 켜도 지도를 받습니다.- Global Options의 Fixed Frame 칸에
world를 입력하고 Enter를 누릅니다. Global Status가 Error가 되고 모든 표시가 Error로 바뀝니다. 7절의 "아무것도 안 보일 때" 첫 항목이 이 경우입니다.base_footprint로 바꾸면 로봇이 화면 가운데 고정되고 세상이 돕니다.map으로 되돌리세요. - 도구 막대의
2D Goal Pose를 고르고 3D 화면에서 눌러 끌어 방향을 정합니다. 아래 검은 창에ros2 topic echo /goal_pose로 본 것과 같은 메시지가 나옵니다. 메시지의frame_id가 Fixed Frame 이름이라는 점을 확인하세요. 이 화면에서는 로봇이 움직이지 않습니다. - Views 패널에서 Type을
TopDownOrtho로 바꿔 x가 위쪽, y가 왼쪽인 위에서 내려다본 시점을 봅니다. Target Frame을base_footprint로 바꾸면 Fixed Frame은 그대로 두고 시점만 로봇을 따라갑니다.
한눈에 정리
- RViz2는 토픽을 구독해서 그리는 시각화 도구다. 데이터를 만들지 않으므로 안 보이면 데이터와 설정부터 의심한다.
- 실행은
rviz2나ros2 run rviz2 rviz2다. 설정은.rviz파일로 저장하고rviz2 -d <파일>로 연다. - Fixed Frame은 TF에 실제로 있는 이름이어야 하고 데이터의 프레임과 변환이 이어져야 그려진다.
- 자주 쓰는 디스플레이는 TF, RobotModel(
/robot_description), LaserScan(/scan), Map(/map), Path, Pose, Marker다. - 비어 있으면 상태 문구, 토픽 도착, Fixed Frame, TF 트리, QoS, 시간 순서로 점검한다.
/map은 Transient Local,/scan은 Best Effort로 맞추는 경우가 많고ros2 topic info <토픽> --verbose로 설정을 본다.- TF 확인은
ros2 run tf2_tools view_frames와ros2 run tf2_ros tf2_echo <기준> <대상>이다. - TIKI-MINI의
tiki_description.launch.py는rviz:=true일 때만 RViz2를 연다.
확인 문제
Q1. rviz2를 켰더니 Global Status가 Error이고 화면이 비어 있습니다. 로봇 노드는 정상으로 실행 중입니다. 가장 먼저 볼 것은?
Global Status를 펼쳐 문구를 읽고 Fixed Frame 이름이 지금 TF에 있는지 확인합니다. 기본값 map은 SLAM이나 AMCL이 map 프레임을 발행하기 전에는 없습니다. ros2 run tf2_tools view_frames로 프레임 목록을 보고 존재하는 이름(예: base_footprint)으로 바꾸면 오류가 사라집니다.
Q2. 터미널에서 ros2 topic echo --once /map 은 값이 나오는데 RViz2의 Map 디스플레이는 비어 있습니다. 의심할 설정은?
QoS입니다. /map은 마지막 지도를 보관해 두는 Transient Local로 발행되는 경우가 많은데, Map 디스플레이의 Durability가 Volatile이면 이미 발행된 지도를 받지 못합니다. Map 항목의 Topic을 펼쳐 Durability Policy를 Transient Local로 바꾸고, ros2 topic info /map --verbose로 발행자의 설정을 확인합니다.
Q3. Fixed Frame을 map에서 base_link로 바꿨더니 로봇이 움직이지 않고 지도가 움직입니다. 고장인가요?
고장이 아닙니다. Fixed Frame은 화면의 고정 기준이라서 base_link로 두면 로봇이 항상 같은 자리에 있고 나머지 세상이 반대로 움직여 보입니다. 지도 위에서 로봇의 이동을 보려면 Fixed Frame을 map으로 두어야 합니다.
다음 장
다음 장(3.9장)에서는 VM의 네트워크 모드와 ROS_DOMAIN_ID를 설정해, VM과 다른 컴퓨터 또는 로봇이 토픽을 주고받게 합니다. 실기기에서 RViz2를 VM에 띄우려면 이 네트워크 설정이 먼저 맞아야 합니다.