Ubuntu 22.04 Server TurtleBot3 Burger를 tmux로 한 번에 실행하기 #2

15) show_status 함수 정의

show_status()
{

show_status() 함수는 현재 TurtleBot3 tmux session이 실행 중인지 확인하고, 실행 중이라면 window 정보를 출력합니다.

함수는 다음과 같이 호출합니다.

show_status

이 함수는 스크립트의 status 명령에서 사용됩니다.

./turtlebot3_tmux.sh status

tmux session 존재 여부 확인
if tmux has-session -t "${SESSION_NAME}" 2>/dev/null; then

tmux has-session 명령은 지정한 session이 존재하는지 확인합니다.

tmux has-session -t "${SESSION_NAME}"

SESSION_NAMEturtlebot3이면 다음 session의 존재 여부를 검사합니다.

tmux has-session -t turtlebot3

session이 존재하면 명령은 성공 종료 코드인 0을 반환합니다.

session이 존재하지 않으면 실패 종료 코드를 반환합니다.

이 종료 코드를 if 조건문에서 사용합니다.

if tmux has-session ...; then

session이 존재할 때는 then 이후 코드가 실행됩니다.

2>/dev/null은 오류 메시지를 화면에 표시하지 않도록 합니다.

2>/dev/null

여기서 숫자 2는 표준 오류 출력을 의미합니다.

/dev/null은 들어온 데이터를 버리는 특수 파일입니다.

따라서 session이 존재하지 않을 때 tmux가 출력하는 오류 메시지를 숨길 수 있습니다.

현재 window 목록 출력
tmux list-windows \
  -t "${SESSION_NAME}" \
  -F '#{window_index}:#{window_name} panes=#{window_panes} active=#{window_active}'

이 명령은 지정한 tmux session에 생성된 모든 window 정보를 출력합니다.

기본 명령은 다음과 같습니다.

tmux list-windows

-t 옵션으로 대상 session을 지정합니다.

-t "${SESSION_NAME}"

-F 옵션은 출력 형식을 지정합니다.

-F '출력 형식'

사용된 형식은 다음과 같습니다.

'#{window_index}:#{window_name} panes=#{window_panes} active=#{window_active}'

각 변수의 의미는 다음과 같습니다.

#{window_index}  window 번호
#{window_name}   window 이름
#{window_panes}  해당 window의 pane 개수
#{window_active} 현재 선택된 window 여부

출력 예시는 다음과 같습니다.

0:bringup panes=1 active=1
1:camera panes=1 active=0
2:audio panes=1 active=0
3:debug panes=4 active=0

첫 번째 줄은 다음 의미입니다.

0:bringup panes=1 active=1
  1. window 번호는 0
  2. window 이름은 bringup
  3. pane은 1개
  4. 현재 활성 window

debug window는 다음과 같이 출력될 수 있습니다.

3:debug panes=4 active=0
  1. window 번호는 3
  2. window 이름은 debug
  3. pane은 4개
  4. 현재 활성 window는 아님

session이 없을 때 메시지 출력
else
  echo "실행 중인 ${SESSION_NAME} 세션이 없습니다."
fi

tmux has-session 검사 결과 session이 없으면 else 부분이 실행됩니다.

출력 예시는 다음과 같습니다.

실행 중인 turtlebot3 세션이 없습니다.

마지막의 fi는 Bash의 if 조건문이 끝났다는 의미입니다.

Bash 조건문 구조는 다음과 같습니다.

if 조건; then
  조건이 참일 때 실행
else
  조건이 거짓일 때 실행
fi

16) 기본 명령값 설정

COMMAND="${1:-start}"

이 코드는 스크립트 실행 시 전달된 첫 번째 인자를 COMMAND 변수에 저장합니다.

Bash에서 $1은 첫 번째 명령행 인자를 의미합니다.

예를 들어 다음과 같이 실행하면:

./turtlebot3_tmux.sh stop

$1에는 stop이 들어갑니다.

따라서 다음과 같이 설정됩니다.

COMMAND=stop

다음과 같이 실행하면:

./turtlebot3_tmux.sh status

COMMAND에는 status가 들어갑니다.

COMMAND=status

:-start는 첫 번째 인자가 없을 경우 사용할 기본값입니다.

"${1:-start}"

따라서 아무 인자 없이 실행하면:

./turtlebot3_tmux.sh

자동으로 다음과 같은 의미가 됩니다.

./turtlebot3_tmux.sh start

즉, 기본 동작은 start입니다.

17) tmux 설치 여부 확인

command -v tmux >/dev/null 2>&1 ||
  fail "tmux가 설치되어 있지 않습니다: sudo apt install -y tmux"

command -v는 특정 명령이 시스템에 설치되어 있는지 확인하는 Bash 명령입니다.

command -v tmux

tmux가 설치되어 있다면 실행 파일 경로가 출력됩니다.

/usr/bin/tmux

스크립트에서는 이 출력이 필요하지 않으므로 다음과 같이 버립니다.

>/dev/null 2>&1

각 부분의 의미는 다음과 같습니다.

>/dev/null   표준 출력 버림
2>&1         표준 오류를 표준 출력과 같은 곳으로 보냄

결국 정상 출력과 오류 출력을 모두 화면에 표시하지 않습니다.

|| 연산자는 앞 명령이 실패했을 때 뒤 명령을 실행한다는 의미입니다.

앞의 명령 || 실패했을 때 실행할 명령

따라서 tmux가 설치되어 있지 않으면 다음 함수가 실행됩니다.

fail "tmux가 설치되어 있지 않습니다: sudo apt install -y tmux"

출력 예시는 다음과 같습니다.

[ERROR] tmux가 설치되어 있지 않습니다: sudo apt install -y tmux

그 후 스크립트가 종료됩니다.

18) case 문으로 사용자 명령 처리

case "${COMMAND}" in

case 문은 COMMAND 변수의 값에 따라 다른 코드를 실행합니다.

처리 가능한 명령은 다음과 같습니다.

start
attach
stop
restart
status

Bash의 case 문 기본 구조는 다음과 같습니다.

case "${변수}" in
  값1)
    명령
    ;;
  값2)
    명령
    ;;
esac

각 항목의 마지막에 있는 ;;는 해당 조건 처리가 끝났다는 뜻입니다.

마지막의 esaccase를 거꾸로 쓴 단어이며, case 문 종료를 의미합니다.

19) start 명령 처리

start)
  if ! tmux has-session -t "${SESSION_NAME}" 2>/dev/null; then
    create_session
  fi

  attach_session
  ;;

사용자가 다음과 같이 실행하면 이 부분이 실행됩니다.

./turtlebot3_tmux.sh start

먼저 기존 session이 있는지 확인합니다.

tmux has-session -t "${SESSION_NAME}"

앞에 있는 !는 조건을 반대로 바꿉니다.

if ! 명령; then

즉, session이 없을 때 조건이 참이 됩니다.

session이 없다면 다음 함수가 실행됩니다.

create_session

이 함수는 bringup, camera, audio, debug window를 새로 생성합니다.

session이 이미 있다면 create_session은 실행하지 않습니다.

이 방식으로 같은 이름의 tmux session이 중복 생성되는 것을 방지합니다.

마지막에는 다음 함수가 실행됩니다.

attach_session

따라서 session이 새로 생성되었든 이미 존재하든 관계없이 최종적으로 해당 session에 접속합니다.

start 명령의 전체 동작은 다음과 같습니다.

session 존재 여부 확인
→ 없으면 새 session 생성
→ 있으면 기존 session 사용
→ session에 접속

20) attach 명령 처리

attach)
  tmux has-session -t "${SESSION_NAME}" 2>/dev/null ||
    fail "실행 중인 ${SESSION_NAME} 세션이 없습니다."

  attach_session
  ;;

사용자가 다음과 같이 실행하면 이 부분이 실행됩니다.

./turtlebot3_tmux.sh attach

먼저 session이 존재하는지 확인합니다.

tmux has-session -t "${SESSION_NAME}"

session이 존재하지 않으면 || 뒤의 fail 함수가 실행됩니다.

fail "실행 중인 ${SESSION_NAME} 세션이 없습니다."

출력 예시는 다음과 같습니다.

[ERROR] 실행 중인 turtlebot3 세션이 없습니다.

session이 존재하면 다음 함수가 실행됩니다.

attach_session

attach는 기존 session에 접속만 하며 새로운 session을 생성하지 않습니다.

따라서 다음 차이가 있습니다.

start   session이 없으면 생성한 후 접속
attach  session이 있을 때만 접속

21) stop 명령 처리

stop)
  if tmux has-session -t "${SESSION_NAME}" 2>/dev/null; then
    tmux kill-session -t "${SESSION_NAME}"
    echo "${SESSION_NAME} 세션을 종료했습니다."
  else
    echo "실행 중인 ${SESSION_NAME} 세션이 없습니다."
  fi
  ;;

사용자가 다음과 같이 실행하면 이 부분이 실행됩니다.

./turtlebot3_tmux.sh stop

먼저 session이 실행 중인지 확인합니다.

tmux has-session -t "${SESSION_NAME}"

session이 존재하면 다음 명령으로 전체 session을 종료합니다.

tmux kill-session -t "${SESSION_NAME}"

TurtleBot3 session을 종료하면 그 안에서 실행 중이던 다음 프로그램도 함께 종료됩니다.

TurtleBot3 bringup
Pi Camera 2 노드
오디오 출력 노드
debug pane 명령

종료 후 다음 메시지를 출력합니다.

echo "${SESSION_NAME} 세션을 종료했습니다."

출력 예시는 다음과 같습니다.

turtlebot3 세션을 종료했습니다.

session이 존재하지 않는 경우에는 오류로 종료하지 않고 안내 메시지만 출력합니다.

실행 중인 turtlebot3 세션이 없습니다.

22) restart 명령 처리

restart)
  tmux kill-session -t "${SESSION_NAME}" 2>/dev/null || true

  create_session
  attach_session
  ;;

사용자가 다음과 같이 실행하면 이 부분이 실행됩니다.

./turtlebot3_tmux.sh restart

먼저 기존 session을 종료합니다.

tmux kill-session -t "${SESSION_NAME}"

session이 없으면 이 명령은 실패할 수 있습니다.

하지만 뒤에 다음 코드가 있습니다.

|| true

true 명령은 항상 성공 종료 코드를 반환합니다.

따라서 기존 session이 없어도 스크립트가 중단되지 않습니다.

이 처리는 스크립트 상단의 다음 설정과 관련이 있습니다.

set -e

set -e가 설정된 상태에서는 일반적인 명령 실패 시 스크립트가 종료됩니다.

하지만 다음과 같이 작성하면 실패를 의도적으로 무시할 수 있습니다.

실패할 수도 있는 명령 || true

기존 session 종료 후 새로운 session을 생성합니다.

create_session

그 다음 생성된 session에 접속합니다.

attach_session

restart 명령의 전체 동작은 다음과 같습니다.

기존 session 종료
→ 새 session 생성
→ 새 session에 접속

스크립트 내용이나 ROS 2 실행 명령을 수정한 후에는 restart 명령을 사용하는 것이 좋습니다.

23) status 명령 처리

status)
  show_status
  ;;

사용자가 다음과 같이 실행하면 이 부분이 실행됩니다.

./turtlebot3_tmux.sh status

앞에서 정의한 show_status 함수가 호출됩니다.

show_status

session이 실행 중이라면 window 목록과 pane 개수를 출력합니다.

0:bringup panes=1 active=1
1:camera panes=1 active=0
2:audio panes=1 active=0
3:debug panes=4 active=0

session이 없다면 다음과 같이 출력됩니다.

실행 중인 turtlebot3 세션이 없습니다.

status 명령은 session에 직접 접속하지 않고 현재 상태만 확인할 때 사용합니다.

24) 잘못된 명령 처리

*)
  echo "사용법: $0 {start|attach|stop|restart|status}" >&2
  exit 2
  ;;

*는 앞에서 정의한 어떤 명령에도 해당하지 않는 경우를 의미합니다.

예를 들어 다음과 같이 잘못된 명령을 입력하면:

./turtlebot3_tmux.sh run

run은 지원하는 명령이 아니므로 * 항목이 실행됩니다.

사용법을 출력합니다.

echo "사용법: $0 {start|attach|stop|restart|status}" >&2

$0은 현재 실행 중인 스크립트 이름입니다.

출력 예시는 다음과 같습니다.

사용법: ./turtlebot3_tmux.sh {start|attach|stop|restart|status}

>&2는 메시지를 표준 출력이 아니라 표준 오류로 출력한다는 의미입니다.

이후 다음 명령으로 스크립트를 종료합니다.

exit 2

종료 코드 2는 일반적으로 잘못된 사용법이나 잘못된 인자를 나타낼 때 사용합니다.

25) case 문 종료

esac

esaccase 문이 끝났다는 의미입니다.

전체 구조는 다음과 같습니다.

case "${COMMAND}" in
  start)
    ...
    ;;
  attach)
    ...
    ;;
  stop)
    ...
    ;;
  restart)
    ...
    ;;
  status)
    ...
    ;;
  *)
    ...
    ;;
esac

26) 각 명령의 동작 정리

start

./turtlebot3_tmux.sh start

동작은 다음과 같습니다.

session이 없으면 생성
session이 있으면 그대로 사용
마지막에 session 접속

attach

./turtlebot3_tmux.sh attach

동작은 다음과 같습니다.

실행 중인 기존 session에 접속
session이 없으면 오류 출력

stop

./turtlebot3_tmux.sh stop

동작은 다음과 같습니다.

실행 중인 session과 내부 ROS 2 노드를 모두 종료

restart

./turtlebot3_tmux.sh restart

동작은 다음과 같습니다.

기존 session 종료
새 session 생성
새 session 접속

status

./turtlebot3_tmux.sh status

동작은 다음과 같습니다.

session과 window 상태만 출력

10. TurtleBot3 전체 실행

TurtleBot3에 SSH로 접속합니다.

ssh sjyong@192.168.200.28

스크립트를 실행합니다.

~/turtlebot3_tmux/turtlebot3_tmux.sh start

처음 실행하면 turtlebot3 session과 네 개의 window가 생성됩니다.

기존 session이 이미 실행 중이면 새로운 session을 중복 생성하지 않고 기존 session에 접속합니다.

window 목록은 다음 키로 확인합니다.

Ctrl+b
w

기본 tmux 설정에서는 일반적으로 다음 번호로 생성됩니다.

0: bringup
1: camera
2: audio
3: debug

사용자 tmux 설정에서 시작 번호를 변경한 경우 번호가 다를 수 있습니다. 이 경우 Ctrl+b, w를 사용하거나 다음 명령으로 확인합니다.

~/turtlebot3_tmux/turtlebot3_tmux.sh status

출력 예시는 다음과 같습니다.

0:bringup panes=1 active=1
1:camera panes=1 active=0
2:audio panes=1 active=0
3:debug panes=4 active=0

11. SSH 연결을 끊어도 노드 유지하기

ROS 2 노드를 종료하지 않고 tmux 화면에서 빠져나옵니다.

Ctrl+b
d

이후 SSH 연결을 종료합니다.

exit

tmux session 안의 ROS 2 노드는 계속 실행됩니다.

다시 TurtleBot3에 SSH로 접속합니다.

ssh sjyong@192.168.200.28

기존 session에 다시 접속합니다.

~/turtlebot3_tmux/turtlebot3_tmux.sh attach

다음 명령을 사용해도 같습니다.

tmux attach-session -t turtlebot3

12. 전체 종료와 재시작

전체 TurtleBot3 tmux session을 종료합니다.

~/turtlebot3_tmux/turtlebot3_tmux.sh stop

이 명령을 실행하면 다음 노드가 모두 종료됩니다.

  1. TurtleBot3 bringup
  2. Pi Camera 2
  3. 오디오 출력 노드
  4. debug window의 모니터링 명령

직접 tmux 명령으로 종료할 수도 있습니다.

tmux kill-session -t turtlebot3

전체 session을 새로 생성하고 다시 실행합니다.

~/turtlebot3_tmux/turtlebot3_tmux.sh restart

설정이나 실행 명령을 수정한 후에는 restart를 사용하는 것이 가장 확실합니다.

13. 개별 노드 재시작

전체 session을 종료하지 않고 특정 노드만 재시작할 수 있습니다.

카메라를 재시작하는 경우 다음 순서로 이동합니다.

Ctrl+b
1

카메라 노드를 종료합니다.

Ctrl+c

현재 pane이 종료된 상태로 남아 있으면 pane을 다시 생성하거나 tmux session 전체를 재시작할 수 있습니다.

가장 단순하고 확실한 방법은 다음 명령입니다.

~/turtlebot3_tmux/turtlebot3_tmux.sh restart

개발 중에 특정 window만 자주 재시작해야 한다면 해당 window에서 Ctrl+b, &로 window를 종료한 후 새 window를 추가할 수도 있습니다.

14. 원격 PC의 ROS 2 환경 설정

TurtleBot3에서 tmux 스크립트를 실행한 후 원격 PC에서 ROS 2 토픽을 확인하려면 양쪽의 DDS 설정이 맞아야 합니다.

원격 PC에서 ROS 2 환경을 적용합니다.

source /opt/ros/humble/setup.bash
source ~/turtlebot3_ws/install/setup.bash

TurtleBot3와 같은 Domain ID를 설정합니다.

export ROS_DOMAIN_ID=200

같은 RMW 구현체를 설정합니다.

export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp

원격 PC의 네트워크 인터페이스를 확인합니다.

ip route show default

예를 들어 원격 PC가 Wi-Fi의 wlp2s0를 사용한다면 다음 설정 파일을 만듭니다.

cat > /tmp/remote_pc_cyclonedds.xml <<'XML'
<CycloneDDS>
  <Domain id="any">
    <General>
      <NetworkInterfaceAddress>wlp2s0</NetworkInterfaceAddress>
      <AllowMulticast>default</AllowMulticast>
    </General>
  </Domain>
</CycloneDDS>
XML

환경 변수를 지정합니다.

export CYCLONEDDS_URI=file:///tmp/remote_pc_cyclonedds.xml

원격 PC에서는 원격 PC의 실제 인터페이스 이름을 사용해야 합니다. TurtleBot3가 wlan0을 사용한다고 해서 원격 PC도 반드시 wlan0인 것은 아닙니다.

기존 ROS 2 daemon이 다른 Domain ID나 RMW 설정으로 실행되었을 수 있으므로 daemon을 재시작합니다.

ros2 daemon stop
ros2 daemon start

현재 환경을 확인합니다.

echo "$ROS_DOMAIN_ID"
echo "$RMW_IMPLEMENTATION"
echo "$CYCLONEDDS_URI"

15. 원격 PC에서 토픽 확인

원격 PC에서 노드 목록을 확인합니다.

ros2 node list

토픽 목록을 확인합니다.

ros2 topic list

다음과 같은 TurtleBot3 관련 토픽이 확인되어야 합니다.

/scan
/odom
/tf
/tf_static
/cmd_vel
/joint_states
/battery_state

카메라 토픽은 설치한 카메라 드라이버 설정에 따라 이름이 달라질 수 있습니다.

ros2 topic list | grep -E 'camera|image'

Odometry 메시지를 한 번 확인합니다.

ros2 topic echo /odom --once

LiDAR 데이터를 한 번 확인합니다.

ros2 topic echo /scan --once --qos-reliability best_effort

LiDAR 발행 주기를 확인합니다.

ros2 topic hz /scan

카메라 발행 주기를 확인합니다.

ros2 topic hz /camera/image_raw

TurtleBot3와 원격 PC 사이의 통신이 정상이라면 메시지 수신 주기가 계속 출력됩니다.

16. 원격 PC에서 rqt로 카메라 확인

원격 PC에서 rqt image view를 실행합니다.

ros2 run rqt_image_view rqt_image_view

또는 다음 명령을 사용할 수 있습니다.

rqt_image_view

영상 선택 목록에서 실제 카메라 토픽을 선택합니다.

예시는 다음과 같습니다.

/camera/image_raw
/image_raw
/camera/image

정확한 이름은 다음 명령으로 확인합니다.

ros2 topic list | grep image

영상이 표시되지 않으면 다음 항목을 확인합니다.

  1. TurtleBot3의 camera window에 오류가 없는지 확인
  2. 양쪽 ROS_DOMAIN_ID가 200인지 확인
  3. 양쪽 RMW_IMPLEMENTATION이 같은지 확인
  4. 양쪽 CYCLONEDDS_URI의 인터페이스가 올바른지 확인
  5. Wi-Fi 공유기의 AP isolation 또는 client isolation 기능 확인
  6. Ubuntu 방화벽 확인
  7. 카메라 토픽 이름 확인
  8. 카메라 토픽 QoS 확인

방화벽 상태를 확인합니다.

sudo ufw status

테스트 목적으로 방화벽을 잠시 비활성화할 수 있습니다.

sudo ufw disable

테스트가 끝난 후 필요한 통신 규칙을 구성하고 다시 활성화하는 것이 안전합니다.

17. 원격 PC에서 rqt_graph 확인

ROS 2 노드와 토픽의 연결 구조를 확인합니다.

rqt_graph

다음 연결을 확인합니다.

  1. TurtleBot3 bringup 노드가 /odom을 발행하는지 확인
  2. LiDAR 노드가 /scan을 발행하는지 확인
  3. 카메라 노드가 영상 토픽을 발행하는지 확인
  4. 로봇 베이스 노드가 /cmd_vel을 구독하는지 확인
  5. TF 관련 노드가 /tf/tf_static을 발행하는지 확인

토픽의 publisher와 subscriber를 자세히 확인하려면 다음 명령을 사용합니다.

ros2 topic info /scan -v
ros2 topic info /odom -v
ros2 topic info /cmd_vel -v

18. 원격 PC에서 SLAM 실행

SLAM을 실행하기 전에 TurtleBot3의 tmux session에서 다음 항목이 정상이어야 합니다.

  1. bringup window 정상
  2. /scan 발행 정상
  3. /odom 발행 정상
  4. /tf 발행 정상
  5. 원격 PC에서 토픽 검색 가능

원격 PC에서 환경을 적용합니다.

source /opt/ros/humble/setup.bash
source ~/turtlebot3_ws/install/setup.bash

export ROS_DOMAIN_ID=200
export TURTLEBOT3_MODEL=burger
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export CYCLONEDDS_URI=file:///tmp/remote_pc_cyclonedds.xml

지원되는 launch 인수를 먼저 확인할 수 있습니다.

ros2 launch turtlebot3_cartographer \
  cartographer.launch.py \
  --show-args

Cartographer SLAM을 실행합니다.

ros2 launch turtlebot3_cartographer \
  cartographer.launch.py \
  use_sim_time:=False

별도의 터미널에서 키보드 조종 노드를 실행합니다.

source /opt/ros/humble/setup.bash
source ~/turtlebot3_ws/install/setup.bash

export ROS_DOMAIN_ID=200
export TURTLEBOT3_MODEL=burger
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export CYCLONEDDS_URI=file:///tmp/remote_pc_cyclonedds.xml

ros2 run turtlebot3_teleop teleop_keyboard

로봇을 천천히 이동시키면서 RViz2에서 지도가 생성되는지 확인합니다.

SLAM이 정상이라면 다음 항목이 확인되어야 합니다.

  1. RViz2에 LaserScan 표시
  2. 로봇 모델 또는 TF 표시
  3. 로봇 이동에 따라 지도 확장
  4. /map 토픽 발행
  5. map → odom → base_footprint TF 연결

TF 구조를 확인합니다.

ros2 run tf2_tools view_frames

지도를 저장합니다.

ros2 run nav2_map_server map_saver_cli \
  -f "${HOME}/map"

정상 저장되면 다음 파일이 생성됩니다.

~/map.yaml
~/map.pgm

19. 원격 PC에서 Nav2 실행

Nav2를 실행하기 전에 사용 가능한 지도 파일을 확인합니다.

ls -l ~/map.yaml ~/map.pgm

SLAM 프로세스를 종료합니다.

SLAM과 Nav2의 AMCL 기반 localization을 동시에 실행하면 map → odom TF 발행이 충돌할 수 있으므로 일반적인 지도 기반 Navigation에서는 Cartographer를 먼저 종료해야 합니다.

원격 PC에서 Nav2 launch 인수를 확인합니다.

ros2 launch turtlebot3_navigation2 \
  navigation2.launch.py \
  --show-args

Nav2를 실행합니다.

ros2 launch turtlebot3_navigation2 \
  navigation2.launch.py \
  use_sim_time:=False \
  map:="${HOME}/maps/my_map.yaml"

RViz2에서 다음 순서로 확인합니다.

  1. 2D Pose Estimate로 로봇의 초기 위치 지정
  2. LaserScan과 지도 정합 상태 확인
  3. Nav2 Goal 또는 2D Goal Pose로 목표 위치 지정
  4. 경로가 생성되는지 확인
  5. TurtleBot3가 경로를 따라 움직이는지 확인
  6. 장애물 앞에서 감속하거나 회피하는지 확인

Nav2 관련 노드를 확인합니다.

ros2 node list | grep -E \
  'amcl|planner|controller|behavior|bt_navigator|map_server'

Nav2 action을 확인합니다.

ros2 action list

대표적인 Navigation action을 확인합니다.

ros2 action info /navigate_to_pose

TurtleBot3가 움직이지 않으면 /cmd_vel 연결을 확인합니다.

ros2 topic info /cmd_vel -v

Nav2 controller가 publisher로 표시되고 TurtleBot3 베이스 노드가 subscriber로 표시되어야 합니다.

20. 원격 PC에서 정상 실행 판단 기준

다음 항목이 모두 확인되면 TurtleBot3 tmux 구성이 정상적으로 실행된 것입니다.

  1. TurtleBot3에서 tmux lsturtlebot3 session 표시
  2. bringup, camera, audio, debug 네 개 window 표시
  3. 원격 PC의 ros2 node list에서 TurtleBot3 노드 검색
  4. /scan 메시지 수신
  5. /odom 메시지 수신
  6. /tf/tf_static 수신
  7. rqt image view에서 Pi Camera 2 영상 표시
  8. SLAM에서 지도 생성
  9. Nav2에서 지도 로드
  10. Nav2 Goal 지정 후 경로 생성

21. 스크립트에 새 window를 추가하는 방법

새 기능을 영구적으로 추가하려면 create_session() 함수 안에 tmux new-window 명령을 추가합니다.

예를 들어 배터리 상태 확인 window를 추가합니다.

tmux new-window \
  -t "${SESSION_NAME}" \
  -n battery \
  "$(ros_shell 'ros2 topic echo /battery_state; exec bash -i')"

추가 위치는 debug window 생성 코드 이후와 select-window 이전이 적절합니다.

teleoperation window를 추가하는 예입니다.

tmux new-window \
  -t "${SESSION_NAME}" \
  -n teleop \
  "$(ros_shell 'exec ros2 run turtlebot3_teleop teleop_keyboard')"

Nav2 상태 확인 window를 추가하는 예입니다.

tmux new-window \
  -t "${SESSION_NAME}" \
  -n nav_debug \
  "$(ros_shell "watch -n 2 -t 'ros2 node list | grep -E \"amcl|planner|controller|navigator\"'")"

수정한 후 Bash 문법을 검사합니다.

bash -n ~/turtlebot3_tmux/turtlebot3_tmux.sh

전체 session을 재시작합니다.

~/turtlebot3_tmux/turtlebot3_tmux.sh restart

22. debug window에 pane을 추가하는 방법

debug window에 카메라 주기 확인 pane을 추가하려면 다음 코드를 create_session() 함수에 추가합니다.

tmux split-window \
  -t "${SESSION_NAME}:debug" \
  "$(ros_shell 'ros2 topic hz /camera/image_raw; exec bash -i')"

pane 추가 후 다음 명령을 다시 실행해야 합니다.

tmux select-layout -t "${SESSION_NAME}:debug" tiled

tiled 레이아웃은 pane 수에 맞춰 화면을 자동으로 균등 분할합니다.

배터리 모니터 pane을 추가하는 예입니다.

tmux split-window \
  -t "${SESSION_NAME}:debug" \
  "$(ros_shell 'ros2 topic echo /battery_state; exec bash -i')"

TF 확인 pane을 추가하는 예입니다.

tmux split-window \
  -t "${SESSION_NAME}:debug" \
  "$(ros_shell "watch -n 2 -t 'ros2 run tf2_ros tf2_echo odom base_footprint 2>/dev/null'")"

pane이 너무 많아지면 각 화면이 작아지므로 자주 확인하는 정보만 debug window에 배치하는 것이 좋습니다.

23. 실행 중 임시 window 추가

스크립트를 수정하지 않고 실행 중인 tmux에 임시 window를 추가할 수 있습니다.

tmux 내부에서 다음 키를 누릅니다.

Ctrl+b
c

새로 생성된 window에서는 ROS 2 환경이 자동으로 source되지 않습니다. 직접 다음 명령을 실행해야 합니다.

source /opt/ros/humble/setup.bash
source ~/turtlebot3_ws/install/setup.bash
source ~/rgb_led_ws/install/setup.bash

export ROS_DOMAIN_ID=200
export LDS_MODEL=LDS-03
export TURTLEBOT3_MODEL=burger
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export CYCLONEDDS_URI=file:///tmp/turtlebot3_cyclonedds_${USER}.xml

이후 필요한 명령을 실행합니다.

ros2 topic echo /battery_state

외부 SSH 터미널에서 실행 중인 session에 window를 추가할 수도 있습니다.

tmux new-window \
  -t turtlebot3 \
  -n temporary

생성된 window로 이동합니다.

tmux select-window \
  -t turtlebot3:temporary

임시 window는 session을 종료하면 함께 사라집니다.

24. 실행 중 임시 pane 추가

현재 window를 좌우로 분할합니다.

Ctrl+b
%

현재 window를 상하로 분할합니다.

Ctrl+b
"

pane 사이를 이동합니다.

Ctrl+b
방향키

현재 pane을 종료합니다.

exit

임시 pane에도 ROS 2 환경을 직접 적용해야 합니다.

source /opt/ros/humble/setup.bash
source ~/turtlebot3_ws/install/setup.bash
source ~/rgb_led_ws/install/setup.bash

export ROS_DOMAIN_ID=200
export LDS_MODEL=LDS-03
export TURTLEBOT3_MODEL=burger
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export CYCLONEDDS_URI=file:///tmp/turtlebot3_cyclonedds_${USER}.xml

25. 실제 운용 순서

TurtleBot3의 전원을 켭니다.

TurtleBot3에 SSH로 접속합니다.

ssh sjyong@192.168.200.28

필요하면 네트워크 인터페이스를 지정합니다.

export ROS_NETWORK_INTERFACE=wlan0

TurtleBot3 전체 노드를 실행합니다.

~/turtlebot3_tmux/turtlebot3_tmux.sh start

각 window의 로그를 확인합니다.

bringup
camera
audio
debug

정상 실행을 확인한 후 tmux에서 빠져나옵니다.

Ctrl+b
d

원격 PC에서 ROS 2 환경과 DDS 환경을 적용합니다.

source /opt/ros/humble/setup.bash
source ~/turtlebot3_ws/install/setup.bash

export ROS_DOMAIN_ID=200
export TURTLEBOT3_MODEL=burger
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export CYCLONEDDS_URI=file:///tmp/remote_pc_cyclonedds.xml

노드와 토픽을 확인합니다.

ros2 node list
ros2 topic list
ros2 topic echo /odom --once
ros2 topic hz /scan --qos-reliability best_effort

카메라 영상을 확인합니다.

rqt_image_view

SLAM을 실행합니다.

ros2 launch turtlebot3_cartographer \
  cartographer.launch.py \
  use_sim_time:=False

지도를 저장합니다.

ros2 run nav2_map_server map_saver_cli \
  -f "${HOME}/map"

SLAM을 종료한 후 Nav2를 실행합니다.

ros2 launch turtlebot3_navigation2 \
  navigation2.launch.py \
  use_sim_time:=False \
  map:="${HOME}/map.yaml"

작업이 끝나면 TurtleBot3의 tmux session을 종료합니다.

~/turtlebot3_tmux/turtlebot3_tmux.sh stop

Leave a Comment