URDF와 Xacro는 왜 중요할까? 로봇 구조를 코드로 표현하는 방법
로봇을 ROS 환경에서 다룬다고 하면, 많은 분들이 먼저 센서 데이터나 제어 코드부터 떠올립니다.
그런데 실제로는 그보다 앞서 해결해야 하는 문제가 하나 있습니다.
**“이 로봇이 어떻게 생겼는지 시스템이 알아야 한다”**는 점입니다.
예를 들어 로봇 몸체 위에 카메라가 달려 있고, 아래에는 바퀴가 달려 있고, 앞쪽에는 LiDAR가 달려 있다고 해보겠습니다. 사람은 그림만 봐도 대충 이해할 수 있습니다. 하지만 ROS는 그렇게 동작하지 않습니다. 시스템은 로봇의 각 부분이 어떤 구조로 연결되어 있는지, 서로 상대적인 위치와 방향이 어떤지를 명확하게 알아야 합니다.
그래야만 카메라가 어디에 달려 있는지 알 수 있고, LiDAR가 어느 높이에 있는지 알 수 있고, 바퀴가 어떤 축으로 회전해야 하는지도 알 수 있습니다. 그리고 이런 정보가 있어야 결국 TF도 구성되고, 센서 데이터도 올바르게 해석되고, 시뮬레이션과 내비게이션도 제대로 돌아가게 됩니다.
이 구조를 표현하기 위해 사용하는 대표적인 형식이 URDF(Unified Robot Description Format) 입니다.
URDF란 무엇인가
URDF는 말 그대로 로봇의 구조를 기술하기 위한 형식입니다.
ROS에서는 사실상 표준처럼 쓰이는 로봇 모델링 포맷이라고 생각해도 됩니다.
핵심은 단순합니다.
URDF는 로봇을 하나의 덩어리로 보지 않고, 여러 개의 링크(Link) 와 그것들을 연결하는 조인트(Joint) 로 나누어 표현합니다.
즉, URDF는 이렇게 묻는 형식에 가깝습니다.
- 로봇은 어떤 부품들로 이루어져 있는가
- 각 부품은 서로 어떻게 연결되어 있는가
- 어떤 부분은 고정이고, 어떤 부분은 회전하는가
- 센서는 몸체 어디에 붙어 있는가
- 시뮬레이션에서 충돌은 어떤 형상으로 계산할 것인가
- 물리 계산에는 어떤 질량과 관성을 사용할 것인가
이걸 보고 나면 URDF를 단순히 “로봇 모양 파일”로 보면 안 된다는 점이 분명해집니다.
URDF는 로봇의 구조, 운동, 시각화, 충돌, 물리 속성을 함께 설명하는 설계도에 가깝습니다.
왜 이런 설명 파일이 꼭 필요할까
처음에는 이런 생각이 들 수 있습니다.
“센서 데이터만 잘 읽으면 되는 거 아닌가?”
“굳이 로봇 구조를 따로 기술해야 하나?”
그런데 조금만 생각해보면 바로 이유가 보입니다.
예를 들어 LiDAR가 전방 장애물을 감지했다고 해보겠습니다.
그 값을 base_link 기준으로 바꾸려면, LiDAR가 로봇 몸체 어디에 달려 있는지 알아야 합니다.
카메라가 본 목표물을 로봇 팔 기준으로 바꾸려면, 카메라와 로봇 팔의 상대 위치가 정의되어 있어야 합니다.
바퀴를 굴려 주행하려면, 각 바퀴가 몸체 어느 위치에 붙어 있고 어느 축으로 회전하는지도 알아야 합니다.
즉, 로봇 구조가 기술되어 있지 않으면 센서 데이터와 제어 명령이 서로 연결되지 못합니다.
결국 URDF는 이런 역할을 합니다.
- 로봇 각 부위의 구조를 시스템이 이해하게 합니다.
- 프레임 간 관계를 정의할 기반을 제공합니다.
- TF 트리를 구성할 수 있게 해줍니다.
- 시뮬레이션에서 어떤 형상과 물리를 쓸지 알려줍니다.
- 내비게이션과 센서 해석이 가능한 형태로 로봇을 설명합니다.
다시 말해 URDF는 선택사항이 아니라,
ROS에서 로봇을 “의미 있는 시스템”으로 다루기 위한 기본 전제에 가깝습니다.
URDF의 핵심 구성 1: Link
URDF에서 가장 기본이 되는 요소는 Link 입니다.
Link는 쉽게 말해 로봇의 하나의 물리적 덩어리, 즉 하나의 강체(rigid body)를 의미합니다.
로봇 몸체, 바퀴, 카메라 하우징, 센서 마운트, 로봇 팔의 각 마디 같은 것들이 모두 링크가 될 수 있습니다.
여기서 중요한 포인트는 “하나의 링크는 하나의 강체”라는 점입니다.
즉, 같은 링크로 묶인 부분은 서로 따로 움직이지 않습니다.
움직임을 따로 주고 싶다면 링크를 분리해야 합니다.
예를 들어 로봇 팔이 있다고 해보겠습니다.
상완과 하완이 서로 독립적으로 움직여야 한다면, 이 둘은 각각 다른 링크로 정의되어야 합니다. 만약 둘을 하나의 링크로 묶어버리면 시스템은 그 둘을 하나의 통짜 덩어리로 이해하게 됩니다.
그래서 링크를 정의한다는 것은 단순히 형상을 나누는 일이 아니라,
어디까지를 하나의 움직이지 않는 강체로 볼 것인가를 결정하는 일에 가깝습니다.

Link 안에는 무엇이 들어갈까
링크는 이름만 붙이면 끝나는 것이 아닙니다.
보통 링크 안에는 그 링크를 어떻게 보여주고, 어떻게 충돌시키고, 어떤 물리 특성을 가질지를 함께 정의합니다.
대표적으로 많이 들어가는 요소는 다음과 같습니다.
1) Visual
이건 말 그대로 시각적으로 어떻게 보일지를 정의합니다.
RViz나 Gazebo 같은 환경에서 로봇을 렌더링할 때 사용되는 요소입니다.
즉, 사람이 화면에서 보게 되는 로봇의 외형은 대체로 visual 정보에 의해 정해집니다.
2) Collision
이건 충돌 계산에 사용할 형상을 정의합니다.
여기서 중요한 점은 visual과 collision이 꼭 같을 필요는 없다는 것입니다.
실제로는 로봇 외형이 굉장히 복잡할 수 있습니다.
그런데 충돌 계산까지 복잡한 형상을 그대로 쓰면 비효율적일 수 있습니다. 그래서 충돌용 형상은 더 단순한 박스, 실린더, 근사 메쉬 등으로 따로 정의하는 경우가 많습니다.
즉, 화면에 보이는 모양과 물리적으로 부딪히는 모양은 다를 수 있습니다.
3) Inertial
이건 질량과 관성 같은 동역학 속성을 정의합니다.
시뮬레이션에서 물체가 얼마나 무겁게 움직이고, 회전에 얼마나 저항하는지 같은 정보를 계산할 때 필요합니다.
그래서 링크 하나를 제대로 정의한다는 것은
그 링크의 모양만 적는 것이 아니라,
어떻게 보이고, 어떻게 부딪히고, 어떻게 움직일 것인지를 함께 적는 일입니다.
URDF의 핵심 구성 2: Joint
링크가 로봇의 덩어리라면, Joint는 그 덩어리들을 연결하는 요소입니다.
Joint는 두 링크 사이의 연결 관계를 정의합니다.
그리고 단순히 붙어 있다는 것만 말하는 것이 아니라,
어떤 방식으로 움직일 수 있는지까지 함께 정의합니다.
이게 왜 중요하냐면, 실제 로봇은 모든 부분이 똑같이 움직이지 않기 때문입니다.
- 어떤 부분은 완전히 고정되어 있습니다.
- 어떤 부분은 한 축을 기준으로 계속 회전합니다.
- 어떤 부분은 일정 각도 범위 안에서만 회전합니다.
- 어떤 부분은 한 축을 따라 직선으로 움직입니다.
이런 차이를 표현하는 것이 Joint입니다.
즉, Joint는 단순 연결부가 아니라
로봇의 자유도(DoF)를 정의하는 핵심 요소입니다.
Joint는 부모-자식 관계로 연결된다
URDF에서 조인트는 보통 부모 링크(parent) 와 자식 링크(child) 의 관계로 표현됩니다.
예를 들어 base_link에 카메라가 붙어 있다면,
- 부모 링크: base_link
- 자식 링크: camera_link
같은 식으로 관계를 잡을 수 있습니다.
그리고 이 둘 사이에 조인트를 하나 정의하면서,
자식 링크가 부모 링크 기준으로 어디에 있고, 어떤 방식으로 움직일 수 있는지를 적습니다.
이 구조가 중요한 이유는, 로봇의 전체 형태가 결국 이런 부모-자식 관계를 따라 트리 구조로 형성되기 때문입니다. 그리고 이 구조는 나중에 TF 트리와도 매우 자연스럽게 이어집니다.
즉 URDF는 단순히 부품을 나열하는 것이 아니라,
로봇 전체를 연결 관계가 있는 계층 구조로 표현하는 방식이라고 볼 수 있습니다.

자주 쓰는 Joint 타입은 무엇이 있을까
URDF에서 자주 등장하는 조인트 타입은 몇 가지로 정리할 수 있습니다.
이 부분은 단순 암기보다, 어떤 기계적 움직임을 표현하려는가로 이해하는 편이 좋습니다.
fixed
두 링크가 서로 상대적으로 움직이지 않는 경우입니다.
예를 들어 로봇 몸체에 고정된 카메라나 LiDAR 같은 센서는 보통 fixed joint로 연결합니다.
즉, 좌표계는 다를 수 있어도 물리적인 관계는 변하지 않는 구조입니다.
continuous
한 축을 기준으로 무한히 회전할 수 있는 조인트입니다.
대표적으로 바퀴가 여기에 해당합니다.
360도를 넘어서 계속 회전할 수 있기 때문에 바퀴 표현에 잘 맞습니다.
revolute
이것도 회전 조인트이긴 하지만, 회전 각도 제한이 있는 형태입니다.
문 경첩, 로봇 팔 관절, 손가락 관절 같은 경우를 떠올리면 이해가 쉽습니다. 특정 각도 범위 안에서만 움직일 수 있습니다.
prismatic
한 축을 따라 직선으로 이동하는 조인트입니다.
슬라이딩 구조나 선형 액추에이터 같은 것을 표현할 때 사용합니다.
planar
평면 안에서 움직이는 구조를 표현할 때 사용합니다.
즉 x, y 이동과 회전을 함께 가질 수 있는 형태입니다.
이 타입들을 보면 결국 URDF는 “붙어 있다/안 붙어 있다” 수준을 넘어서,
그 연결부가 어떤 자유도를 가지는지까지 모델링하는 형식이라는 점이 드러납니다.
URDF만으로는 조금 불편한 이유
여기까지 보면 URDF가 꽤 강력해 보입니다.
실제로도 그렇습니다. 그런데 로봇 구조가 조금만 복잡해져도 불편한 점이 생깁니다.
가장 큰 문제는 반복입니다.
예를 들어 바퀴가 4개 달린 로봇이 있다고 해보겠습니다.
왼쪽 앞바퀴, 오른쪽 앞바퀴, 왼쪽 뒤바퀴, 오른쪽 뒤바퀴는 구조가 굉장히 비슷합니다.
그런데 순수 URDF로 작성하면 비슷한 XML 블록을 거의 복붙하듯 여러 번 써야 할 가능성이 큽니다.
또 어떤 로봇은 모델이 두 종류일 수도 있습니다.
예를 들어 바퀴 배치가 다른 두 버전을 지원해야 하거나, 같은 센서 구조를 여러 번 재사용해야 할 수도 있습니다.
이럴 때 URDF만으로는 관리가 점점 불편해집니다.
바로 이 문제를 해결하기 위해 많이 쓰는 것이 Xacro입니다.
Xacro는 무엇인가
Xacro는 쉽게 말해 URDF를 더 효율적으로 작성하기 위한 XML 매크로 언어입니다.
핵심은 “반복을 줄이고, 재사용성을 높인다”는 점입니다.
Xacro를 사용하면 다음과 같은 것이 가능해집니다.
- 반복되는 코드를 매크로처럼 묶어 재사용
- 숫자 계산 같은 간단한 수학적 연산
- 조건문을 통한 선택적 구조 포함
- 변수(property) 정의
- 다른 파일 include
즉, Xacro는 URDF를 대체한다기보다,
URDF를 더 편하게 생성하기 위한 상위 도구라고 이해하는 편이 좋습니다.
결국 실제 워크플로우에서는 보통 Xacro로 로봇 구조를 작성하고,
그 결과가 확장되어 URDF 형태로 사용되는 경우가 많습니다.
Xacro가 특히 유용한 이유
Xacro의 장점은 단순히 “코드를 짧게 쓴다”에서 끝나지 않습니다.
실제로는 로봇 모델을 유지보수 가능한 구조로 만들 수 있다는 점이 더 중요합니다.
예를 들어 바퀴 네 개가 거의 같은 구조라면,
하나의 매크로를 정의해두고 위치값만 바꿔가며 재사용할 수 있습니다.
또 로봇이 두 가지 하드웨어 버전을 가진다면,
조건문을 이용해 어떤 모델일 때는 A 구조를, 다른 모델일 때는 B 구조를 포함하도록 만들 수 있습니다.
센서 설정, 관성 행렬, 공통 부품 같은 것도 파일로 분리해 include할 수 있으니, 프로젝트가 커질수록 훨씬 관리하기 쉬워집니다.
즉, Xacro는 단지 편의 문법이 아니라
실제 로봇 프로젝트에서 구조를 깔끔하게 유지하게 해주는 도구입니다.

URDF와 TF는 어떻게 연결될까
여기서 중요한 연결고리가 하나 있습니다.
앞선 글에서 TF는 여러 좌표계를 연결하는 체계라고 했습니다.
그런데 그 프레임들이 어떤 구조로 연결되어 있는지는 어디서 올까요?
바로 URDF가 그 기반을 제공합니다.
예를 들어 base_link에 camera_link가 fixed joint로 연결되어 있다면,
이건 곧 “카메라 프레임은 로봇 몸체 기준으로 이 위치와 방향에 고정되어 있다”는 뜻입니다.
LiDAR나 IMU도 마찬가지입니다.
즉, URDF에 정의된 링크와 조인트 구조는 결국
프레임 간 상대 관계를 표현하는 TF 구조의 뼈대가 됩니다.
물론 실제로 모든 TF가 URDF만으로 해결되는 것은 아닙니다.
로봇의 주행처럼 시간에 따라 변하는 관계는 /tf를 통해 동적으로 업데이트되어야 합니다.
하지만 적어도 로봇의 물리적 구조, 즉 센서와 몸체, 바퀴와 몸체 같은 고정된 관계는 URDF 정의가 매우 중요한 출발점이 됩니다.
그래서 URDF를 잘못 작성하면 어떤 일이 생길까요?
- 센서 위치가 잘못 해석될 수 있습니다.
- TF 트리가 어긋날 수 있습니다.
- 장애물 위치가 몸체 기준과 어긋날 수 있습니다.
- 시뮬레이션 충돌이 이상하게 보일 수 있습니다.
- 내비게이션이 실제 구조와 다른 크기로 판단할 수 있습니다.
즉, URDF는 보기 좋은 모델 파일이 아니라
로봇 전체 좌표 해석과 동작의 출발점입니다.
실제로는 어떻게 이해하면 좋을까
이쯤 되면 URDF와 Xacro를 너무 복잡하게 느낄 수도 있습니다.
그런데 처음에는 아주 단순하게 이해해도 괜찮습니다.
URDF/Xacro를 볼 때는 먼저 이 순서로 보면 좋습니다.
- 이 로봇에는 어떤 링크들이 있는가
- 어떤 링크가 부모이고 어떤 링크가 자식인가
- 각 조인트는 fixed인지, continuous인지, revolute인지
- 센서들은 base_link 기준 어디에 붙어 있는가
- 이 구조가 TF로 어떻게 이어질까
이 다섯 가지만 따라가도 훨씬 덜 복잡하게 보입니다.
처음부터 모든 XML 태그를 외우려 하기보다는,
“이 파일이 결국 로봇의 구조를 설명하는 설계도다”라는 관점으로 보면 훨씬 이해가 쉽습니다.
그리고 실제 프로젝트를 보다 보면,
결국 많이 보게 되는 것은
바퀴 위치, 센서 위치, base_link 기준 관계, 조인트 타입, collision 형상 같은 것들입니다.
즉, 문법 전체를 외우는 것보다 구조를 읽는 능력이 훨씬 중요합니다.
정리해보면
이번 글에서는 URDF와 Xacro가 왜 중요한지 정리해봤습니다.
URDF는 로봇을 여러 개의 링크와 조인트로 나누어,
그 구조와 움직임, 시각화, 충돌, 물리 속성을 표현하는 형식입니다.
그리고 이 정보는 단순한 모델링을 넘어, TF 구성, 센서 해석, 시뮬레이션, 내비게이션까지 이어지는 기반이 됩니다.
또한 Xacro는 URDF를 더 효율적으로 작성하기 위한 도구입니다.
반복되는 구조를 줄이고, 변수와 조건문, include를 활용해 실제 프로젝트에서 훨씬 관리하기 쉬운 형태로 로봇 모델을 만들 수 있게 해줍니다.
결국 핵심은 이것입니다.
로봇이 어떻게 생겼는지 시스템이 이해해야,
센서도 움직임도 좌표계도 비로소 하나의 구조로 연결된다.
이 지점을 이해하면, 왜 URDF와 Xacro가 단순 설정 파일이 아니라 로봇 시스템의 중요한 기반인지 훨씬 자연스럽게 받아들일 수 있습니다.
'Study Archives > Robotics' 카테고리의 다른 글
| Nav2(Path Planning) (1) | 2026.04.10 |
|---|---|
| [SLAM의 이해 ⑤] Mapping과 Localization (0) | 2026.04.10 |
| [SLAM의 이해 ③] TF와 좌표 변환 (0) | 2026.04.10 |
| [SLAM의 이해 ②] 좌표계와 프레임 (0) | 2026.04.10 |
| [SLAM의 이해 ①] SLAM 개요 (0) | 2026.04.10 |