[ROS2 Mastery 13편] URDF(Universal Robot Description Format)란 무엇인가?
안녕하세요! 로봇 공학의 꿈을 안고 자율주행과 시스템 제어를 깊이 있게 연구하고 계신 대학생 및 연구원 여러분. 쿼드(QUAD) 드론연구소의 자료를 바탕으로 진행되는 ‘ROS2 속성 마스터 과정’ 연재 블로그 13편에 오신 것을 진심으로 환영합니다.
지난 2부(8편~12편)에서는 로봇 수학의 핵심인 ‘TF2(좌표 변환 시스템)’를 통해 3차원 공간에서 다수의 로봇 프레임(좌표계)을 다루는 방법을 마스터했습니다. 이제 3부에서는 지금까지 배운 통신(Topic/Service)과 수학(TF2)을 바탕으로, 컴퓨터 시뮬레이션 환경에 구현될 ‘가상의 로봇 몸체’를 직접 설계해 보는 시간을 갖겠습니다.
우리가 로봇의 외형과 관절을 컴퓨터에게 설명할 때 사용하는 언어가 바로 URDF(Universal Robot Description Format)입니다. 이번 13편에서는 URDF의 기본 개념과 구조를 이해하고, 기초적인 XML 코드를 통해 나만의 첫 로봇 모델을 만들어 보는 실습을 진행하겠습니다.

URDF(Universal Robot Description Format)란?
URDF는 로봇의 기구학적 구조(Kinematic structure)와 물리적 특성(Physical properties)을 컴퓨터가 이해할 수 있도록 표현하기 위해 설계된 XML 기반의 표준 파일 형식입니다.
실제 로봇 하드웨어를 제작하기 전, 우리는 가상 환경에서 알고리즘을 테스트해야 합니다. 이때 ROS2 시스템(특히 RViz 시각화 도구나 Gazebo 물리 시뮬레이터)에게 “이 로봇은 바퀴가 2개이고, 몸통은 파란색 원통형이며, 카메라는 몸통 앞쪽 10cm 위치에 달려있어”라는 정보를 알려주어야 합니다. URDF는 로봇의 링크(부품), 조인트(관절), 센서 및 액추에이터를 명확하게 정의하여 이러한 역할을 수행합니다.
URDF 문서를 완벽하게 작성하면, ROS2는 이를 바탕으로 로봇의 제어, 시뮬레이션, 3D 시각화를 완벽하게 지원해 줍니다.
로봇을 이루는 두 가지 핵심 기둥: Link와 Joint
URDF 문서 내에서 로봇은 크게 두 가지 요소로 구성되며, 이들은 부모-자식 트리(Tree) 구조로 엮이게 됩니다.
- 링크 (Link): 로봇을 구성하는 단단한 부품(Rigid body)을 의미합니다. 몸통, 바퀴, 로봇 팔의 마디, 센서 외형 등이 모두 링크에 해당합니다. 링크 태그 내부에는 해당 부품의 시각적 외형(Visual), 물리적 충돌 범위(Collision), 질량 및 관성(Inertial) 정보를 정의합니다.
- 조인트 (Joint): 두 개의 서로 다른 링크를 연결하는 ‘관절’을 의미합니다. 로봇 팔이 꺾이거나 바퀴가 회전하는 물리적 움직임뿐만 아니라, 카메라가 몸통에 고정되어 있는 상태(Fixed) 또한 조인트로 정의합니다.
[연구원을 위한 핵심 인사이트] 연구원 여러분, 이 구조가 어딘가 익숙하지 않으신가요? 앞선 8편과 9편에서 배웠던 TF2 시스템의 프레임(Frame)과 변환(Transform) 구조가, URDF의 링크(Link)와 조인트(Joint) 패턴과 완벽하게 1:1로 매칭됩니다!
ROS2에는 robot_state_publisher라는 아주 똑똑한 노드가 있습니다. 이 노드는 우리가 작성한 URDF 파일을 읽어 들여, 모든 조인트(Joint)의 위치와 각도 정보를 바탕으로 전체 TF2 변환을 자동으로 계산하고 브로드캐스트해 줍니다. 즉, URDF 모델링을 잘 해두면 복잡한 로봇 팔의 역기구학 행렬 계산을 ROS2 시스템이 알아서 처리해 준다는 뜻입니다.
첫 번째 로봇 모델 (단일 형태) 만들기
이론을 바탕으로 가장 단순한 형태의 로봇 모델을 XML 코드로 직접 작성해 보겠습니다. 아래의 코드는 오직 하나의 부품(base_link)만을 가지며, 그 형태가 원통형(Cylinder)인 기초적인 URDF입니다.
작업 공간에 myfirst.urdf라는 파일을 만들고 아래 코드를 작성해 봅니다.
<?xml version="1.0"?>
<robot name="myfirst">
<!-- 첫 번째 부품(Link) 정의 -->
<link name="base_link">
<!-- 시각적 형태(Visual) 정의 -->
<visual>
<geometry>
<!-- 반지름 0.2m, 길이 0.6m의 원통형 지오메트리 -->
<cylinder length="0.6" radius="0.2"/>
</geometry>
</visual>
</link>
</robot>
코드를 영어 문장처럼 읽어보면 이해가 쉽습니다.
- 이 로봇의 이름은
myfirst입니다. - 이 로봇에는
base_link라는 이름의 링크(부품)가 하나 있습니다. - 이 링크의 눈에 보이는 모양(
visual)과 기하학적 형태(geometry)는 길이 0.6m, 반경 0.2m의 원통(cylinder)입니다.

이 모델을 RViz 시각화 도구로 띄워보면 한 가지 특이한 점을 발견할 수 있습니다. 시각적 요소(Cylinder)는 기본적으로 자기 지오메트리의 정중앙을 원점(Origin)으로 삼기 때문에, 원통의 딱 절반(0.3m)이 바닥 그리드(Grid) 아래로 파묻혀서 나타나게 됩니다.
여러 개의 링크(Link)를 조인트(Joint)로 연결하기
부품이 하나인 로봇은 없습니다. 이번에는 몸통(base_link) 옆에 다리(right_leg) 역할을 하는 박스(Box) 형태의 링크를 하나 더 추가하고, 두 부품을 조인트(Joint)로 연결해 보겠습니다.
<?xml version="1.0"?>
<robot name="multipleshapes">
<!-- 1. 몸통 (원통형) -->
<link name="base_link">
<visual>
<geometry>
<cylinder length="0.6" radius="0.2"/>
</geometry>
</visual>
</link>
<!-- 2. 오른쪽 다리 (박스형) -->
<link name="right_leg">
<visual>
<geometry>
<box size="0.6 0.1 0.2"/>
</geometry>
<!-- 시각적 원점(Origin) 오프셋 조정 -->
<origin rpy="0 1.57075 0" xyz="0 0 -0.3"/>
</visual>
</link>
<!-- 3. 조인트 (몸통과 다리를 연결) -->
<joint name="base_to_right_leg" type="fixed">
<parent link="base_link"/>
<child link="right_leg"/>
<!-- 다리가 몸통에 붙는 위치(Origin) 지정 -->
<origin xyz="0 -0.22 0.25"/>
</joint>
</robot>
[코드 심층 분석: Origin(원점)의 마법]
로봇 수학을 연구하시는 분들이라면 위 코드의 <origin> 태그를 주의 깊게 살펴보셔야 합니다.
- 조인트의 Origin (<joint> 내부): 다리(
right_leg)를 몸통(base_link)의 어디에 붙일 것인가를 결정합니다. 조인트의 원점은 항상 부모 링크(Parent)의 기준 프레임을 중심으로 정의됩니다. 위 코드에서는xyz="0 -0.22 0.25"를 주었습니다. 즉, 다리의 조인트가 몸통 중앙에서 Y축(오른쪽)으로 -0.22m, Z축(위쪽)으로 0.25m 위치에 고정된다는 뜻입니다. - 시각적 요소의 Origin (<visual> 내부): 그렇다면 다리 박스 객체는 조인트가 있는 위치에 정중앙이 꽂히게 됩니다. 하지만 우리는 다리가 몸통 위쪽에 매달려 아래로 뻗기를 원합니다. 따라서 박스 지오메트리 자체를 Z축 방향으로 -0.3m 만큼 아래로 끌어내리는 오프셋(
xyz="0 0 -0.3")을 주었습니다. 또한 다리가 세로로 길게 서 있도록 Y축을 기준으로 90도(약 1.57075 라디안) 회전시키는rpy="0 1.57075 0"(Roll, Pitch, Yaw) 속성을 적용했습니다.
URDF에서 트리는 항상 부모-자식 구조이므로 다리의 위치는 결국 최상위 부모인 base_link의 위치에 종속되어 움직이게 됩니다.

색상(Material)과 실제 외형(Mesh) 입히기
로봇이 모두 똑같은 칙칙한 회색일 필요는 없습니다! <material> 태그를 사용하면 모델에 아름다운 색상을 부여할 수 있습니다.
<!-- 파란색 재질 정의 -->
<material name="blue">
<color rgba="0 0 0.8 1"/>
</material>
<link name="base_link">
<visual>
<geometry>
<cylinder length="0.6" radius="0.2"/>
</geometry>
<!-- 정의한 파란색 재질을 몸통에 적용 -->
<material name="blue"/>
</visual>
</link>
- rgba 속성: Red, Green, Blue, Alpha(투명도) 채널을 의미하며, 0부터 1 사이의 값으로 정의됩니다. 위 코드에서는 파란색(B)을 0.8로, 투명도(A)를 1(불투명)로 설정하여 선명한 파란색 몸통을 만들었습니다.
실무 연구원을 위한 고급 팁: Mesh 파일 연동
현장에서는 단순한 원통이나 상자 대신, 솔리드웍스(SolidWorks)나 퓨전360(Fusion360) 같은 3D CAD 프로그램에서 설계한 복잡한 기구물 도면을 그대로 불러와 시뮬레이션에 사용합니다. 이때 지오메트리 태그 안에 <mesh> 속성을 사용합니다.
<link name="robot_head">
<visual>
<geometry>
<!-- 외부 CAD 3D 모델(DAE, STL 파일) 불러오기 -->
<mesh filename="package://urdf_tutorial/meshes/head.dae"/>
</geometry>
</visual>
</link>filename="package://..."표기법은 ROS2 시스템 내에서 특정 패키지 디렉토리에 저장된 외부 3D 메시(Mesh) 파일(주로.stl또는.dae확장자)의 경로를 지정하는 표준 방법입니다. DAE 파일 형식의 경우 파일 자체에 색상 데이터가 포함되어 있어 별도로 material 태그를 지정할 필요가 없는 장점이 있습니다.
마무리하며
이번 13편에서는 로봇의 컴퓨터 시뮬레이션과 시각화를 위한 뼈대, URDF(Universal Robot Description Format)의 개념과 XML 작성법을 기초부터 학습했습니다. Link(부품)와 Joint(관절)의 부모-자식 트리 구조가 결국 우리가 앞서 배운 TF2 시스템과 완벽하게 연결된다는 놀라운 통찰을 얻으셨을 것입니다.
오늘 만든 로봇은 관절 타입이 type="fixed"로 고정된, 마네킹과 같은 로봇이었습니다. 다음 [ROS2 Mastery 14편]에서는 고정된 관절 대신 연속으로 회전하는 바퀴(Continuous)나 꺾이는 로봇 팔(Revolute) 등 다양한 관절 속성을 적용하여 로봇을 역동적으로 움직이게 만드는 방법, 그리고 벽을 통과하지 않게 하는 물리적 충돌(Collision) 속성에 대해 심도 있게 다뤄보겠습니다.
로봇 공학의 시각적 세계, 로봇 모델링에 첫발을 내디딘 대학생 및 연구원 여러분을 쿼드 드론연구소가 진심으로 응원합니다. 다음 편에서 더욱 흥미로운 실습으로 찾아뵙겠습니다!

작성자: 에이든(Aiden), 쿼드(QUAD) 드론연구소 마케팅팀
기고일: 2026.06.13
