로봇에는 모니터도 키보드도 없어서 내 PC에서 원격으로 붙어 작업해요. 그런데 이 환경에서 생기는 문제는 대부분 코드에 에러가 안 남아요. 프로그램이 그냥 없어지거나, 잘 도는 것처럼 보이는데 데이터만 안 들어와요.
증상은 같은데 볼 곳이 달라요
접속이 끊기면 프로그램도 같이 죽어요
로봇이 움직이면 와이파이 신호가 약해지는 구간이 생겨요. 이때 SSH 세션이 끊기는데, 문제는 그 세션에서 띄운 프로그램도 함께 종료된다는 점이에요. 셸이 종료되면 자식 프로세스에 종료 신호가 전달되기 때문이에요.
주행 중이라면 제어 노드가 죽은 채로 로봇이 굴러가요. 로그를 봐도 프로그램이 정상 종료된 것처럼 보이고, 다시 접속하면 아무것도 안 돌고 있어요.
tmux new -s robot # 세션 만들고 그 안에서 노드 실행
tmux attach -t robot # 재접속 후 원래 화면으로메모리가 부족하면 OS가 골라서 죽여요
SBC는 메모리가 작아요. 노드를 여럿 띄우고 rosbag 기록까지 걸면 금방 차요. Linux는 메모리가 바닥나면 OOM Killer를 동작시켜 프로세스를 강제 종료하는데, 선택 기준이 메모리를 많이 쓰는 쪽이에요. 그래서 하필 제일 중요한 노드가 먼저 죽는 경우가 많아요.
dmesg | grep -i "killed process"
# Out of memory: Killed process 1234 (my_node) total-vm:...여기에 이름이 찍혀 있으면 내 코드 문제가 아니라 자원 문제예요. 노드를 나눠 띄우거나, rosbag 기록 항목을 줄이거나, 이미지 같은 큰 메시지의 큐 크기를 줄이는 쪽으로 대응해요.
토픽은 도는데 콜백만 안 불려요
세 번째는 ROS 2 고유의 문제예요. QoS(Quality of Service)의 신뢰성 항목이 두 값을 가져요. RELIABLE은 도착을 보장하려고 재전송하고, BEST_EFFORT는 유실을 허용하는 대신 지연을 줄여요.
ros2 topic list # /scan 이 보여요
ros2 topic hz /scan # 초당 10회로 잘 돌아요
# 그런데 내 노드의 콜백만 한 번도 안 불려요
ros2 topic info /scan --verbose
# Publisher / Subscription 각각의 Reliability 값을 확인해요sub_ = this->create_subscription<sensor_msgs::msg::LaserScan>(
"scan", rclcpp::SensorDataQoS(),
[this](const sensor_msgs::msg::LaserScan& msg) { /* ... */ });세 가지의 공통점
셋 다 내 코드에 에러가 없어요. 컴파일도 되고 실행도 되는데 결과만 안 나와요.
로봇 소프트웨어에서 디버깅이 어려운 이유가 여기에 있어요. 움직이는 중에는 브레이크포인트를 걸 수 없고, 멈추면 그 상태가 사라져요. 그래서 실무에서는 ros2 bag으로 주행을 통째로 기록해두고 나중에 재생하면서 분석한다고 해요. 같은 상황을 몇 번이고 다시 볼 수 있다는 게 무기가 되니까요.
증상만 보면 셋이 거의 구분이 안 되니, 확인하는 명령을 미리 손에 익혀두는 쪽이 나아 보여요.
하드웨어가 두 계층으로 나뉜 이야기는 SBC와 MCU 2계층 구조와 시리얼 경계 처리에 정리해뒀어요.