Side Project/ROS2 & LLM Autonomous Robot

[최종 프로젝트] ROS2 기반 RGB-D 객체 탐지 VLM 서비스 로봇

ns4A 2026. 3. 10. 03:38

https://youtu.be/2mRpJeysa7Y

 

 

이번 프로젝트에서는 장면이해, 자율주행, 상황인식, 언어 명령 이해를 하나로 묶은 멀티모달 서비스 로봇 시스템을 구현했다.
단순히 “목표 지점까지 이동하는 로봇”이 아니라, 사용자의 자연어 명령을 이해하고, 객체 탐지를 통해 위험성을 판단하면서 집 안을 이동한 뒤, 카메라로 주변을 확인하고, 그 결과를 다시 사용자에게 전달할 수 있는 형태를 목표로 했다.

예를 들면 이런 식이다.

  • “엔드포인트로 가서 뭐가 보이는지 알려줘”
  • “현관으로 가서 문이 닫혀 있는지 확인해줘”
  • “집으로 다시 돌아와”

이런 요청을 로봇이 받아서,

  1. 어디로 이동해야 하는지 결정하고,
  2. 실제로 자율주행을 수행하고,
  3. 도착 후 현재 장면을 인식하고,
  4. 결과를 텍스트로 보고하는 흐름이다.

겉으로 보기에는 단순한 서비스 로봇처럼 보이지만, 내부적으로는 ROS2 기반 자율주행 파이프라인, RGB-D 기반 인지, 객체 인식/세그멘테이션, Depth 기반 위험 판단, LLM/VLM 기반 명령 처리가 동시에 맞물려 동작한다.

 


프로젝트를 하게 된 이유

 

기존의 자율주행 시스템은 보통 SLAM이나 Nav2를 이용해 지도 위에서 이동하는 데 집중한다. 반대로 비전 기반 모델은 카메라 화면 안에서 물체를 인식하거나 장면을 설명하는 데 강하다.
하지만 실제 서비스 로봇은 이 둘이 분리되어 있으면 부족하다.

예를 들어 로봇이 “현관으로 가서 문이 닫혀 있는지 확인해줘”라는 요청을 받았을 때 필요한 기능은 단순한 이동만이 아니다.

  • 먼저 “현관”이 어떤 목표 위치인지 알아야 하고,
  • 거기까지 안전하게 이동해야 하고,
  • 도착한 후 카메라 화면을 이해해서
  • 문이 열려 있는지 닫혀 있는지 판단한 뒤
  • 다시 사람에게 알려줘야 한다.

즉, 이동 능력과 상황 이해 능력의 결합이 핵심이다.

그래서 이번 프로젝트는 단순한 자율주행 데모가 아니라,
언어 지시 → 계획 생성 → 자율주행 → 장면 이해 → 결과 보고
라는 전체 파이프라인을 완성하는 것을 목표로 삼았다.


프로젝트의 핵심 아이디어

이번 프로젝트의 핵심은 크게 세 가지 축으로 볼 수 있다.

첫째는 자율주행이다.
ROS2 기반으로 SLAM과 Nav2를 사용해 지도 생성, 위치 추정, 목표 지점 이동을 수행한다.

둘째는 멀티모달 인지다.
RGB-D 카메라를 사용해 RGB 영상과 Depth 정보를 함께 활용한다. RGB는 장면 인식과 객체 인식에 사용하고, Depth는 거리 기반 위험 판단에 사용한다.

셋째는 언어 기반 명령 처리다.
LLM을 이용해 사용자의 자연어를 실행 가능한 action sequence로 변환하고, VLM을 이용해 도착 지점에서 카메라 화면을 해석한 뒤 결과를 반환한다.

이 세 축을 하나로 연결하면,
로봇은 더 이상 단순한 “이동 장치”가 아니라,
상황을 이해하며 움직이는 서비스 로봇이 된다.


왜 VD-MKDF와 YOLO11n을 함께 썼는가

이 프로젝트에서 인지 모듈은 처음부터 YOLO만 쓰려고 했던 것은 아니다.
원래 주된 인지 모델로 생각한 것은 내가 논문에서 다뤘던 VD-MKDF 기반 세그멘테이션 모델이었다.

VD-MKDF는 단순한 detection보다 더 풍부한 정보를 준다.
객체가 어디 있는지만 아는 것이 아니라, 장면 안에서 어떤 영역이 어떤 의미를 가지는지 더 세밀하게 파악할 수 있다. 특히 위험 판단이나 주행 가능한 영역 해석 같은 작업에서는 detection보다 segmentation이 유리한 경우가 많다.

그래서 프로젝트 초반에는 이 세그멘테이션 모델을 실제 로봇에 올려서 끝까지 테스트했다.
다만 실제 로봇 환경에서 돌려보니 예상대로 문제가 있었다.
모델이 무겁다 보니 추론 시간이 길고, 주행 중 실시간 반응성이 떨어졌다.
로봇이 장면을 더 정확히 이해하는 대신, 반응이 느려지는 트레이드오프가 발생한 것이다.

그래서 여기서 한 가지 현실적인 선택을 추가했다.
“무거운 주 모델 하나만 쓰지 말고, 가벼운 보조 모델도 같이 두자.”

그 결과 선택한 것이 YOLO11n이다.

YOLO11n은 detection 기반이라 segmentation처럼 촘촘한 장면 해석은 어렵지만, 훨씬 가볍고 빠르다.
즉 이번 프로젝트에서는 다음과 같은 구조를 가져갔다.

  • VD-MKDF: 주 인지 모델, 더 풍부한 장면 이해
  • YOLO11n: 경량 보조 모델, 빠른 객체 탐지
  • Depth: 거리 기반 위험 판단, 감속/정지 제어

이렇게 하면 하나의 모델에 모든 것을 맡기기보다,
정확성과 실시간성 사이의 균형을 맞출 수 있다.


RGB-D를 왜 중요하게 봤는가

이번 프로젝트에서 카메라는 단순한 RGB 카메라가 아니라 RGB-D 카메라다.
이 점이 생각보다 중요했다.

RGB 영상만 있으면 “무엇이 보이는지”는 어느 정도 알 수 있다.
하지만 실제 로봇 주행에서는 “얼마나 가까운지”가 훨씬 중요할 때가 많다.

예를 들어 사람, 가구, 박스, 벽 같은 물체를 카메라로 봤다고 하자.
RGB만으로는 그 물체가 가까운지 먼지, 지금 당장 멈춰야 하는 거리인지 판단하기 어렵다.
반면 Depth 정보가 있으면, 물체의 존재뿐 아니라 거리를 직접 반영할 수 있다.

이번 프로젝트에서는 이 Depth를 속도 제어와 안전 계층에 사용했다.

즉 단순히 객체를 인식하는 데서 끝나지 않고,

  • 일정 거리 이내에 객체가 들어오면 감속
  • 더 가까워지면 정지

하는 식의 로직을 구현했다.

이 부분은 굉장히 중요했다.
왜냐하면 서비스 로봇은 목적지에 도착하는 것만 중요한 게 아니라,
주행 과정 자체가 안전해야 하기 때문이다.

결국 이번 시스템은 단순한 인지 + 주행의 결합이 아니라,
인지 결과를 실제 주행 안전 제어에 연결한 구조라고 볼 수 있다.


전체 시스템 구성

이번 프로젝트의 전체 흐름은 다음과 같다.

  1. 사용자가 자연어 명령을 /text_command 토픽으로 보낸다.
  2. LLM이 명령을 해석해 action plan을 만든다.
  3. 예를 들어 move('endpoint'), vision('What do you see?'), play_audio() 같은 형태로 계획이 구성된다.
  4. 이동이 필요한 경우 navigation_controller/set_pose 서비스로 목표 위치를 전달한다.
  5. ROS2 SLAM/Nav2 기반으로 로봇이 목표 지점까지 이동한다.
  6. 이동 중에는 RGB와 Depth를 기반으로 위험 판단이 이루어진다.
  7. 도착 후 최신 카메라 프레임을 VLM에 전달해 장면을 해석한다.
  8. 최종 결과를 ~/result 토픽과 로그를 통해 사용자에게 전달한다.

이 전체 흐름은 단순히 여러 모듈을 나열한 것이 아니라,
실제로 행동의 순서와 의미가 연결된 하나의 서비스 파이프라인이다.


시스템 아키텍처

이 프로젝트를 한 장으로 표현하면 아래와 같은 구조다.

 

RGB-D 카메라에서 들어온 영상이 VD-MKDF(혹은 YOLO)로도 들어가고, VLM으로도 들어가며, Depth는 따로 위험 판단과 속도 제어에 사용된다.

동시에 자율주행 쪽에서는 LiDAR, IMU, Odometry가 SLAM과 Nav2를 통해 지도와 위치를 형성하고,
이 정보가 다시 행동 실행과 상황 인식 컨텍스트로 연결된다.

 

실제 소프트웨어 구조

구현은 ROS2 노드를 중심으로 구성했다.

주요 노드는 다음과 같다.

  • smart_home_assistant_text
    사용자의 자연어 명령을 받아 LLM/VLM과 연결하고, action plan을 순차 실행하는 핵심 노드
  • navigation_controller
    목표 위치를 Nav2에 전달하고 도착 여부를 피드백하는 제어 노드
  • ascamera
    RGB-D 카메라 입력을 publish하는 센서 노드
  • slam_toolbox / amcl / nav2_*
    지도 생성, localization, 경로 계획 및 제어 담당
  • YOLO 또는 VD-MKDF 기반 인지 노드
    RGB 토픽을 받아 객체 또는 장면 정보를 추출

이 구조에서 중요한 점은, 각 모듈이 카메라 장치를 직접 열기보다는 이미 publish된 이미지 토픽을 subscribe하는 형태라는 것이다.
그래서 하나의 카메라 publisher를 중심으로 여러 인지 모듈을 동시에 붙일 수 있었다.


자연어 명령을 어떻게 처리했는가

이번 프로젝트의 재미있는 부분 중 하나는 LLM을 단순 대화용으로 쓴 것이 아니라,
실행 가능한 action plan 생성기로 썼다는 점이다.

사용자의 명령이 들어오면, LLM은 그것을 다음과 같은 형식의 JSON으로 변환한다.

{
  "action": ["move('endpoint')", "vision('What do you see?')", "play_audio()"],
  "response": "엔드포인트로 이동한 뒤 주변을 확인해 알려드릴게요."
}

 

이렇게 하면 자연어의 자유로움은 유지하면서도,
실행기 입장에서는 action string만 순차적으로 파싱해 실행하면 된다.

즉 이번 프로젝트에서 LLM의 역할은 대답하는 모델이라기보다,
사용자 의도를 로봇 행동으로 번역하는 planner에 가깝다.


VLM은 어떻게 활용했는가

VLM은 목표 지점 도착 후의 상황 인식에 사용했다.
즉 이동과 도착까지는 Nav2와 주행 계층이 담당하고,
도착한 후 “지금 뭐가 보이는가” 혹은 “문이 닫혀 있는가” 같은 질문은 VLM이 처리한다.

이때 최신 RGB 프레임을 JPEG로 인코딩해 data URL 형태로 전달하고,
사용자의 질문과 함께 모델에 입력한다.

이 구조 덕분에 단순한 물체 탐지 이상의 질의도 가능해졌다.

  • “지금 화면에 뭐가 보여?”
  • “문이 닫혀 있어?”
  • “책상 위에 물건이 있니?”
  • “앞에 사람이 보이니?”

즉 detection이나 segmentation이 저수준 시각 정보를 준다면,
VLM은 그 위에서 언어적 의미 해석을 담당한다.


자율주행과 상황인식을 어떻게 연결했는가

이번 프로젝트에서 가장 중요했던 설계 포인트는
“인지 결과를 실제 주행 판단에 연결하는 것” 이었다.

객체를 잘 인식하는 것만으로는 부족하다.
로봇은 결국 움직이는 시스템이기 때문에, 인지 결과가 이동 속도와 정지 판단으로 이어져야 한다.

그래서 RGB 기반 인지와 더불어, Depth 기반 거리 판단을 안전 계층으로 분리했다.
구체적으로는 다음과 같은 흐름이다.

  • 전방 객체를 인식한다.
  • Depth 영상에서 해당 방향의 거리를 확인한다.
  • 위험 임계값보다 가깝다면 감속한다.
  • 더 가깝다면 정지한다.

이렇게 하면 로봇은 단순히 “목표점으로 가는 기계”가 아니라,
주변 상황을 고려하며 이동하는 시스템이 된다.


구현하면서 겪은 현실적인 문제들

실제로 프로젝트를 진행하면서 가장 많이 부딪힌 문제는
오히려 “모델 정확도”보다 실시간성, 토픽 연결, 시스템 안정성 쪽이었다.

1. 무거운 모델의 추론 지연

VD-MKDF는 분명 더 풍부한 장면 정보를 주지만, 실제 로봇에 올리면 지연이 커졌다.
이 때문에 경량 모델인 YOLO11n을 병행 사용하게 되었다.

2. ROS2 네트워크와 환경 차이

MentorPi, VNC, VM, Host PC가 섞이면서 토픽이 보였다 안 보였다 하는 문제를 겪었다.
특히 실제 로봇 쪽에서 센서와 주행이 돌고, VM 쪽에서 RViz와 시각화를 담당하는 구조에서는
환경 차이가 그대로 문제로 드러났다.

3. TF와 시간축 문제

Nav2, costmap, AMCL, LiDAR를 같이 돌리다 보면
transform cache와 센서 timestamp가 맞지 않아 메시지가 드롭되는 경우가 있었다.
이 부분은 단순히 코드만 고친다고 해결되지 않고, 시스템 시간과 TF 파이프라인을 함께 봐야 했다.

4. LLM/VLM API의 불안정성

OpenRouter 기반 무료 모델을 사용하다 보니,

  • content: null
  • finish_reason: length
  • 429 rate limit

같은 문제를 자주 마주쳤다.
즉 실제 시스템에서는 모델 성능뿐 아니라 API 안정성과 응답 형식도 큰 변수였다.

이 부분은 단순히 모델을 바꾸는 것뿐 아니라,

  • 짧은 프롬프트 설계
  • JSON only 강제
  • 재시도 로직
  • 빈 응답 방어 코드

같은 엔지니어링 보완이 반드시 필요했다.


이 프로젝트의 의미

이 프로젝트의 의미는 단순히 Nav2 실습이나 VLM 데모에 그치는 것이 아닌  서로 다른 기술을 하나의 실제 로봇 행동 파이프라인으로 통합했다는 점에 있다.

  • SLAM과 Nav2로 공간을 이해하고,
  • VD-MKDF와 YOLO11n으로 장면을 인식하고,
  • Depth로 거리 위험을 판단하고,
  • LLM과 VLM으로 명령과 상황을 언어적으로 해석한다.

그리고 이 모든 것이 최종적으로는
“로봇이 사용자의 말대로 안전하게 움직이고, 도착 후 상황을 설명하는 행동”으로 이어진다.

즉 이 프로젝트는 단순한 개별 기술 구현이 아니라,
멀티모달 인지와 자율주행을 서비스 로봇 형태로 통합한 시스템 실험이라고 볼 수 있다.


마무리

서비스 로봇은 단순히 잘 움직이는 네비게이션”하나만으로는 완성되지 않는다. 실제로는 인지, 주행, 안전, 언어 인터페이스, 시스템 안정성까지 모두 연결되어야 한다.

 

특히 이번 프로젝트에서는 무거운 세그멘테이션 모델과 가벼운 detection 모델을 병행하면서, 정확도와 실시간성 사이에서 어떤 균형이 필요한지 직접 체감할 수 있었다. 또한 RGB만이 아니라 Depth를 함께 활용해 위험 판단을 주행 제어에 연결하면서, 인지 결과를 실제 로봇 행동으로 이어주는 구조가 얼마나 중요한지도 확인할 수 있었다.

 

앞으로는 이 구조를 더 확장해서, 단순한 이동 후 보고를 넘어서 주행 중 동적 위험 회피, 상황 기반 행동 수정, 더 강건한 언어 기반 태스크 수행으로 발전시켜볼 수 있을 것 같다.

'Side Project > ROS2 & LLM Autonomous Robot' 카테고리의 다른 글

ROS 2 디버깅  (0) 2026.02.11
모바일 로봇 구동 방식  (0) 2026.01.29
MentorPi 개발 환경 구성하기  (0) 2026.01.29