TIKI-MINI로 시작하는 ROS2 실무
목차

4. 실기기 연동

4.2전원·네트워크 연결

3.9장에서는 같은 네트워크에 있는 두 컴퓨터가 서로의 ROS2 노드를 어떻게 발견하는지 연습했습니다. 이 장은 그 두 대 중 한 대를 TIKI-MINI로 바꿉니다. 새로 배우는 개념은 많지 않고 로봇 쪽 확인 절차와 시간 동기화가 추가됩니다.

구성

  • 로봇 컴퓨터가 드라이버와 컨트롤러를 실행합니다. 모터와 LiDAR가 거기에 연결되어 있기 때문입니다.
  • VM은 명령을 보내고(/cmd_vel) 결과를 봅니다(/odom, /scan, RViz2).
  • 두 컴퓨터는 같은 LAN에 있고, VM 네트워크는 브리지 모드입니다(3.9장).
VM과 로봇의 연결 배치Windows PCVM (Ubuntu 22.04)브리지 모드RViz2, 조종, 명령 입력환경변수ROS_DOMAIN_ID=30ROS_LOCALHOST_ONLY 0TIKI-MINI로봇 컴퓨터ros2_control_noderplidar_node환경변수ROS_DOMAIN_ID=30ROS_LOCALHOST_ONLY 0공유기 또는 AP같은 LANROS_DOMAIN_ID가같아야 서로 발견ssh 접속, /cmd_vel/odom, /scan, /tf
VM은 브리지 모드로 로봇과 같은 LAN에 붙고, ssh와 ROS2 토픽이 이 길로 오갑니다. 두 컴퓨터의 ROS_DOMAIN_ID가 같고 ROS_LOCALHOST_ONLY가 꺼져 있어야(비어 있거나 0) 서로를 발견합니다.

처음 한 번: 시리얼로 접속해 Wi-Fi 설정하기

TIKI-MINI는 Wi-Fi 환경에서 개발하므로 처음 한 번 로봇이 Wi-Fi에 붙어야 합니다. 로봇에는 아직 IP가 없으니 ssh로 들어갈 수 없고, 로봇 컴퓨터의 디버그 포트(USB-C) 를 PC에 연결해 시리얼로 리눅스 셸에 접속합니다. 이 과정은 로봇당 한 번이면 됩니다. 이미 Wi-Fi가 설정된 로봇이라면 건너뛰고 아래 "로봇의 IP 찾기"로 갑니다. PC는 Windows이고 VM이 아니라 Windows에서 하는 작업입니다.

준비물 설치 (제공 자료 02. BSP > 02. H-TIKI-MINI)

  1. 01. 드라이버 폴더의 CDM212364_Setup.exe(FTDI 드라이버)를 실행합니다. 설치 창의 Extract, 다음, 동의함에 체크 후 다음, 마침 순서로 누릅니다. USB 시리얼 장치를 PC가 인식하게 하는 드라이버입니다.
  2. 시리얼 통신 프로그램 MobaXterm Home Edition(Installer edition) v25.0을 https://mobaxterm.mobatek.net/download-home-edition.html에서 받아 압축을 풀고 MobaXterm_installer_25.0.msi를 실행합니다. 설치 창에서 Next, 약관 체크 후 Next, Next, Install, Finish를 누릅니다.

로봇 연결과 포트 확인

  1. 로봇 전원을 켭니다(4.1장). 로봇 컴퓨터의 디버그 포트와 PC를 USB 케이블로 연결합니다. 로봇 컴퓨터는 부팅에 평균 20초가 걸립니다.
  2. Win + R을 누르고 devmgmt.msc를 입력해 장치 관리자를 엽니다. 포트(COM & LPT) 항목에서 로봇이 잡힌 COM 번호를 확인합니다.
장치 관리자의 포트 항목에서 USB Serial Port(COM79)에 번호 표시
  • ① USB Serial Port(COM79): 이 번호를 다음 단계에서 씁니다. 번호는 PC마다 다릅니다.

MobaXterm으로 시리얼 접속

MobaXterm 위쪽 도구 모음의 Session 버튼에 번호 표시
  1. MobaXterm을 열고 ① 위쪽 Session을 누릅니다.
Session settings 창에서 Serial 선택, 시리얼 포트, 속도, OK 버튼에 번호 표시
  1. ① Serial을 고릅니다.
  2. ② Serial port에서 장치 관리자에서 확인한 COM 번호(예: COM79)를 고릅니다.
  3. ③ Speed (bps) 는 115200으로 설정합니다.
  4. ④ OK를 누릅니다.
시리얼 접속 후 Ubuntu 22.04.5 LTS tiki ttyS0 로그인 프롬프트에 번호 표시
  1. ① 부팅이 끝났다면 tiki login: 프롬프트가 나옵니다. 아무 응답이 없으면 순서대로 확인합니다. 부팅 중인지(평균 20초), 부팅이 끝난 뒤에 접속했다면 Enter 키를 눌러 봅니다, OS가 들어 있는 SD 카드가 꽂혀 있는지 봅니다.
  2. 사용자 이름에 tiki를 입력하고 Enter, 비밀번호에 12345678을 입력하고 Enter를 누릅니다. 비밀번호는 입력해도 화면에 보이지 않습니다. Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 5.15.0-1070-raspi aarch64) 같은 안내가 나오고 tiki@tiki:~$ 프롬프트가 보이면 로그인된 것입니다.

Wi-Fi 연결

  1. Wi-Fi를 검색하고 목록을 봅니다. 관리자 권한이 필요해 sudo를 씁니다.
sudo nmcli device wifi rescan
sudo nmcli device wifi list
  1. 목록에서 연결할 Wi-Fi의 SSID를 확인하고 연결합니다. --ask를 붙이면 비밀번호를 물어보며, 입력해도 화면에 보이지 않습니다. 아래 iotap은 예시 이름이고 내 환경의 SSID로 바꿉니다.
sudo nmcli dev wifi connect "iotap" --ask

Device 'wlan0' successfully activated with ...가 나오면 연결된 것입니다.

  1. 받은 IP를 확인합니다.
ifconfig

wlan0 항목의 inet 값이 로봇의 IP입니다(예: 192.168.79.10). 이 주소로 이후 ssh 접속과 ROS2 통신을 합니다. 개발 PC와 VM도 같은 Wi-Fi 망에 있어야 합니다. 공유기나 휴대폰 핫스팟을 권장합니다. 로봇의 eth0은 랜선을 꽂지 않으면 UP 아닌 상태로 보입니다. 연결을 마쳤으면 시리얼 접속은 더 쓰지 않습니다.

로봇의 IP 찾기

IP는 로봇이 공유기에서 받은 주소입니다. 아래 중 가능한 방법을 고릅니다.

로봇에 터미널이 열려 있다면 로봇에서 실행합니다.

hostname -I
ip -br address

로봇에 접근할 수 없다면 공유기 관리 화면의 연결 기기 목록에서 로봇의 이름이나 MAC 주소를 찾습니다. VM에서는 같은 대역의 장치에 한 번이라도 ping을 보낸 뒤 이웃 목록을 봅니다.

ip neigh

로봇은 호스트 이름(mDNS, tiki.local)으로는 접속되지 않습니다. 위 방법으로 찾은 IP로 접속하세요.

ping과 ssh

VM에서 확인합니다. <로봇 IP>는 앞에서 찾은 주소입니다.

ping -c 3 <로봇 IP>
ssh <사용자>@<로봇 IP>

처음 접속하면 "continue connecting"을 묻습니다. 로봇이 맞다면 yes를 입력하고 비밀번호를 넣습니다. 접속이 되면 프롬프트가 로봇의 것으로 바뀝니다. 로봇의 ros2 환경은 4.3장에서 점검하고 여기서는 로그인까지만 확인합니다. exit를 입력하면 접속이 끝납니다.

매번 비밀번호를 치기 싫다면 키 인증을 씁니다. 아래는 일반적인 방법으로, VM에서 키를 만든 뒤 공개키를 로봇에 복사합니다.

ssh-keygen -t ed25519
ssh-copy-id <사용자>@<로봇 IP>

로봇 터미널 두 개(launch 실행용과 상태 확인용)가 필요한 경우가 많으니 VM에서 터미널 탭을 여러 개 열어 각각 ssh로 접속해 두면 편합니다.

ROS_DOMAIN_ID 맞추기

3.9장과 1.8장의 규칙이 그대로 적용됩니다. 같은 번호끼리만 서로를 발견하고, 교실에서는 조마다 다른 번호를 씁니다. Humble 공식 문서의 권장 범위는 0~101입니다. 이 장에서는 번호를 30으로 두고 예를 듭니다.

번호는 노드를 시작한 터미널의 환경변수로 정해집니다. 로봇의 launch를 실행할 ssh 터미널과 VM의 모든 터미널에서 같은 값을 써야 합니다. 로봇의 ~/.bashrc에도 넣어 두면 ssh로 새로 접속할 때마다 적용됩니다.

echo "export ROS_DOMAIN_ID=30" >> ~/.bashrc
source ~/.bashrc
echo $ROS_DOMAIN_ID

로봇을 여러 대 쓰는 교실이라면 번호표를 한 장 만들어 로봇과 조의 번호를 짝지어 두세요. 로봇 한 대에 다른 조의 VM이 같은 번호로 붙으면 그 조의 /cmd_vel이 내 로봇을 움직입니다.

노드 발견 시험

3.9장의 talker/listener 시험을 로봇과 VM으로 다시 합니다. 전체 절차는 반복하지 않고 달라지는 점만 적습니다.

  1. 두 컴퓨터의 ROS_DOMAIN_ID를 같은 값으로, 새 터미널에서 확인합니다.
  2. 로봇에서 ros2 run demo_nodes_py talker, VM에서 ros2 run demo_nodes_py listener를 실행하고 I heard가 나오는지 봅니다. (demo_nodes_cpp 쪽도 같은 방식입니다.)
  3. 방향을 바꿔 VM에서 talker, 로봇에서 listener를 실행합니다. 한쪽 방향만 되는 경우가 실제로 있으므로 양쪽을 다 봅니다.

로봇에서 ros2 run demo_nodes_py talker, VM에서 ros2 run demo_nodes_py listener를 실행하면(도메인 ID 1) 두 쪽에 같은 Hello World 로그가 나옵니다. 아래는 그 화면입니다. VM의 칸 2에서 export ROS_DOMAIN_ID=1을 한 뒤 rqt_graph를 열었습니다.

VM에서 listener 로그와 rqt_graph. 도메인 ID 설정 줄, listener 출력, talker에서 listener로 가는 그래프에 번호 표시
  • ① 새 터미널 칸에서 export ROS_DOMAIN_ID=1 후 rqt_graph를 실행합니다. ROS_DOMAIN_ID는 터미널을 새로 만들 때마다 필요합니다. ~/.bashrc에 등록해 두면 편합니다.
  • ② 칸 1의 listener가 I heard: [Hello World: ...]를 출력합니다. 메시지가 로봇에서 왔다는 뜻입니다.
  • ③ rqt_graph에 /talker에서 /chatter 토픽을 거쳐 /listener로 이어지는 그림이 나옵니다. 그림이 기대와 다르면 새로고침 버튼을 누릅니다.

안 될 때는 3.9장의 순서(ros2 multicast, 도메인 ID, ROS_LOCALHOST_ONLY, 방화벽)를 그대로 따릅니다.

ROS_LOCALHOST_ONLY 함정

ROS_LOCALHOST_ONLY=1은 ROS2 통신을 자기 컴퓨터 안에 가둡니다. Humble의 환경 설정 문서에 있는 변수이고, 교실에서 여러 사람이 섞이지 않게 하려는 용도로 소개됩니다. 로봇과 통신할 때는 반드시 꺼야 합니다.

이 변수가 자주 문제를 일으키는 이유는 켜 둔 곳을 잊기 때문입니다. 확인할 곳은 네 군데입니다.

  • VM의 새 터미널에서 printenv | grep ROS_LOCALHOST_ONLY
  • VM의 ~/.bashrc
  • 로봇의 ssh 터미널에서 같은 명령
  • 로봇의 ~/.bashrc

한쪽만 켜져 있어도 그쪽 노드는 바깥에 보이지 않습니다. 전부 비어 있거나 ROS_LOCALHOST_ONLY=0이어야 정상입니다(Humble의 setup.bash가 0을 채워 줍니다). 1이 나오면 unset ROS_LOCALHOST_ONLY로 끄고 .bashrc의 export 줄도 지운 뒤 새 터미널에서 다시 확인합니다.

시간 동기화

로봇 컴퓨터와 VM은 각자 자기 시계를 씁니다. ROS2 메시지의 헤더에는 시각이 들어 있고 TF는 "그 시각의 변환"을 찾습니다. 두 컴퓨터의 시계가 다르면 다음 문제가 생깁니다.

  • 로봇이 보낸 /scan의 시각이 VM의 시계보다 미래이거나 한참 과거이면 RViz2가 TF를 찾지 못하고 스캔을 표시하지 않습니다.
  • Nav2 설정의 transform_tolerance는 행동 서버 0.1 s, DWB 컨트롤러 0.2 s, AMCL 1.0 s입니다. 두 컴퓨터의 시계 차이가 이 정도이면 변환 조회가 실패할 수 있습니다.

그래서 두 컴퓨터를 같은 시간원에 맞춥니다. 먼저 상태부터 봅니다.

timedatectl

System clock synchronized: yes와 NTP service: active가 나오면 NTP로 동기화되는 중입니다. Ubuntu 22.04는 기본으로 systemd-timesyncd가 이 일을 합니다. 두 시계가 얼마나 어긋났는지 대략 비교하려면 VM에서 아래를 실행합니다. 값 두 개의 차이에는 ssh 지연(보통 수십 ms)이 섞여 있습니다.

date +%s.%N; ssh <사용자>@<로봇 IP> 'date +%s.%N'

차이가 1초 안팎이거나 더 크면 동기화가 안 된 것입니다. 인터넷에 연결된 환경이라면 sudo timedatectl set-ntp true로 NTP를 켭니다. 더 정밀한 동기화가 필요하거나 인터넷이 없는 교실이라면 chrony를 쓰는 방법이 있습니다. 한 컴퓨터는 서버로, 다른 컴퓨터는 클라이언트로 설정합니다. 일반적인 절차입니다.

sudo apt install chrony
chronyc tracking
chronyc sources

chronyc tracking의 System time 줄이 현재 오프셋입니다. 가상머신은 일시정지했다가 재개하면 그 직후에 시계가 자주 어긋납니다. VM에서는 실습 시작 때마다 확인하세요.

방화벽

방화벽이 켜져 있으면 ROS2가 쓰는 UDP 통신이 막힐 수 있습니다. 양쪽에서 확인합니다.

sudo ufw status

Status: inactive이면 방화벽은 원인이 아닙니다. active라면 규칙을 확인하고 교육용 네트워크 정책에 따라 처리하세요. 규칙을 임의로 열기 전에 강사에게 물어보는 편이 안전합니다.

문제 해결표

증상원인 후보확인
로봇 IP로 ping이 안 됨VM이 NAT 모드, 서로 다른 대역, 공유기의 기기 간 차단ip a로 두 IP의 대역 비교, VM 어댑터 모드, 유선으로 시험
ping은 되는데 ssh가 거부됨로봇의 ssh 서버가 꺼짐, 방화벽로봇의 ssh 서비스 상태, ufw status
ssh에서 Permission denied계정이나 비밀번호가 다름로봇 계정의 사용자 이름과 비밀번호를 다시 입력
ssh가 멈추거나 시간 초과IP가 틀렸거나 중간 장비가 차단로봇 IP 재확인, 공유기 설정
두 컴퓨터의 ros2 node list가 서로 안 보임ROS_DOMAIN_ID 불일치양쪽 echo $ROS_DOMAIN_ID, 새 터미널
같은 번호인데도 안 보임ROS_LOCALHOST_ONLY=1, 멀티캐스트 차단, 방화벽printenv, ros2 multicast, ufw status
한쪽 방향만 보임멀티캐스트 일부 차단, 방화벽talker/listener를 서로 바꿔 시험
토픽은 보이는데 데이터가 안 옴QoS 불일치, 네트워크 품질ros2 topic info 토픽 -v, 로봇에서 ros2 topic hz와 비교
RViz2에서 스캔이나 로봇이 안 보이고 TF 경고시계 불일치, 프레임 이름timedatectl, 두 컴퓨터의 date 비교
연결이 가끔 끊김Wi-Fi 불안정, VM의 Wi-Fi 브리지유선 또는 전용 공유기로 교체

단계별 점검 도우미

문제가 생기면 아래 흐름을 위에서부터 따라가 보세요. 예와 아니오로 답하면 다음에 볼 곳을 알려 줍니다.

로봇 전원이 켜져 있고 부팅이 끝난 뒤 네트워크에 접속했습니까?

한눈에 정리

  1. VM은 브리지 모드, 로봇과 같은 LAN에 둔다. IP는 로봇에서 확인한다.
  2. 확인 순서는 ping -c 3 <로봇 IP>, ssh <사용자>@<로봇 IP>, ROS_DOMAIN_ID, 노드 발견 순서다.
  3. ROS_DOMAIN_ID는 로봇의 launch 터미널과 VM의 모든 터미널에서 같아야 한다. 교실에서는 조마다 다른 번호(0~101)를 쓴다.
  4. 노드 발견은 talker/listener를 양방향으로 시험하고, 안 되면 ros2 multicast로 간다.
  5. ROS_LOCALHOST_ONLY는 두 컴퓨터와 두 .bashrc 모두에서 비어 있거나 0이어야 한다. 1이면 안 된다.
  6. 두 컴퓨터의 시계가 맞아야 TF와 Nav2가 동작한다. timedatectl로 확인하고 필요하면 NTP나 chrony를 쓴다.

확인 문제

Q1. ssh 접속은 되는데 VM에서 로봇의 토픽이 보이지 않습니다. 가장 먼저 비교할 두 가지는?

두 컴퓨터에서 echo $ROS_DOMAIN_ID로 번호가 같은지, printenv | grep ROS_LOCALHOST_ONLY가 비어 있거나 0인지입니다. 로봇 쪽은 launch를 실행한 터미널의 환경변수가 기준이므로, 바꾼 뒤에는 launch를 다시 시작합니다.

Q2. 시계가 어긋난 두 컴퓨터에서 RViz2가 LaserScan을 표시하지 않는 이유는?

RViz2는 스캔 메시지의 시각을 기준으로 TF 변환을 찾습니다. 그런데 로봇의 시계와 VM의 시계가 다르면 그 시각의 변환이 없거나 아직 오지 않은 시각으로 보입니다. 두 컴퓨터를 같은 시간원에 맞추면 해결됩니다.

Q3. 교실에서 두 조가 우연히 같은 ROS_DOMAIN_ID를 쓰고 있습니다. 어떤 위험이 있습니까?

다른 조의 노드와 토픽이 서로 보이고 한 조가 보낸 /cmd_vel이 다른 조의 로봇을 움직일 수 있습니다. 로봇이 예상 밖으로 움직이므로 안전 문제이기도 합니다. 조마다 번호를 다르게 배정합니다.

다음 장

4.3장에서는 로봇 컴퓨터에 미리 설치된 ROS2 Humble과 TIKI-MINI 패키지, 시리얼 장치를 확인합니다. 시작 전에 ssh로 접속해 printenv | grep ROS와 ls ~로 로봇이 현재 어떤 상태인지 먼저 읽어 두세요.