1. xacro란?
매크로(macro)란 여러 개의 명령을 묶어 하나의 명령으로 만들어 여러 개의 명령을 수행하거나, 반복적인 작업에서 하나의 매크로 명령만으로 효과적인 작업을 수행 할 수 있습니다.
xacro는 XML + macro의 합성어로써 XML에서 매크로를 사용할 수 있습니다. URDF를 만드는데 XML로도 가능하지만 xacro를 사용하면 좀 더 쉽게 로봇 모델을 만들 수 있습니다.
2. 속성(Property)와 속성 블럭(Property Blocks)
속성(property)는 XML 문서 어디에나 올 수 있습니다. 속성과 속성 블럭은 <xacro:property> 태그(tag)를 사용하여 값을 정의 합니다. 속성은 달러와 대괄호(${}) 안에 속성 이름을 통해서 사용을 합니다.
<xacro:property name="the_radius" value="2.1" />
<xacro:property name="the_length" value="4.5" />
<geometry type="cylinder" radius="${the_radius}" length="${the_length}" />
속성 블럭(property block)은 속성과 같이 <xacro:property> 태그를 사용해서 정의를 하고 사용은 <xacro:insert_block> 태그를 통해서 사용을 합니다.
<xacro:property name="red_material">
<material name="red">
<color rgba="1.0 0.0 0.0 1.0"/>
</material>
</xacro:property>
위는 속성 블럭을 정의한 것이고 아래는 블럭 정의를 사용한 예 입니다.
<xacro:insert_block name="red_material" />
3. 수학 함수
XML로 urdf를 표현할 때 가장 부족한 것이 수학 함수나 수학 상수 값을 사용할 수 없는 점입니다. xacro에서는 속성과 같이 달러와 대괄호(${})안에 수학 함수나 수학 상수를 사용할 수 있습니다. 사용할 수 있는 수학 함수는 파이썬(Python) 수학 모듈의 함수와 상수 입니다.
상수 (constant)
- pi : 원주율로써 3.141592...
- e : 자연로그 값으로써 2.718281...
- tau : 원주와 반지름의 비율인 2pi에 해당하는 상수 값으로써 6.283185...
- inf : 부동 소수점 양의 무한대 값 입니다.
- nan : Not a Number를 뜻 합니다.
함수 (function)
수학 함수 중에 기본이 되는 함수입니다.
- fabs(x) : x의 절대값을 반환 합니다.
- pow(x, y) : 거듭제곱의 값을 구합니다.
- sqrt(x) : x의 제곱근을 반환 합니다.
다음은 삼각 함수 입니다.
- acos(x) : x의 아크 코사인(arc cosine)을 라디안으로 반환합니다. 결과는0과 pi 사이입니다.
- asin(x) : x의 아크 사인(arc sine)을 라디안으로 반환합니다. 결과는 -pi/2와 pi/2 사이입니다.
- atan(x) : x의아크 탄젠트(arc tangent)를 라디안으로 반환합니다. 결과는 -pi/2와 pi/2 사이입니다.
- atan2(y, x) : atan(y/x)를 라디안으로 반환합니다. 결과는 -pi와 pi 사이입니다.
- cos(x) : x 라디안의 코사인(cosine)을 반환합니다.
- sin(x) : x 라디안의 사인(sine)을 반환합니다.
- tan(x) : x 라디안의 탄젠트(tangent)를 반환합니다.
다음은 각도 변환 함수 입니다.
- degrees(x) : 각도 x를 라디안에서 도(degree)로 변환합니다.
- radians(x) : 각도 x를 도(degree)에서 라디안으로 변환합니다.
다음은 수학함수를 사용한 예 입니다.
<xacro:property name="circle_revolute_upper" value="${pi/2}"/>
<xacro:property name="circle_revolute_upper" value="${radians(180)}"/>
<origin xyz="0.0 0.0 ${height/2+joint_height}" rpy="0.0 0.0 0.0"/>
4. 조건부 블럭
조건부 블럭(Conditional Blocks)은 변수의 참(true, 1), 거짓(false, 0)에 따라서 다르게 정의를 할 수 있습니다. 다음은 180도 서보모터와 360도 서보모터 일 때 다르게 정의하는 예 입니다.
<xacro:property name="servo_180" value="1"/>
<xacro:if value="${servo_180 == 1}">
<xacro:property name="circle_revolute_lower" value="${-pi/2}"/>
<xacro:property name="circle_revolute_upper" value="${pi/2}"/>
</xacro:if>
<xacro:unless value="${servo_180 == 1}">
<xacro:property name="circle_revolute_lower" value="${-radians(180)}"/>
<xacro:property name="circle_revolute_upper" value="${radians(180)}"/>
</xacro:unless>
위 예에서 servo_180의 값이 1이면 180도 서보모터이고 servo_180의 값이 1이 아니면 360도 서보모터입니다. 위의 조건식 ${servo_180 == 1}의 결과는 true(참)이거나 1이 되어야 하고 false(거짓)이거나 0의 값이 되어야 합니다. 그 결과 값이 그 외의 값이 되면 오류 입니다.
다음은 속성(property)에 배열을 사용할 수 있습니다. 배열로 선언은 다음과 같습니다.
<xacro:property name="servo_revolute_type" value="${[1,2,3]}"/>
<xacro:if value="${1 in servo_revolute_type}">
</xacro:if>
<xacro:if value="${2 in servo_revolute_type}">
</xacro:if>
<xacro:if value="${3 in servo_revolute_type}">
</xacro:if>
<xacro:if value="${4 in servo_revolute_type}">
</xacro:if>
위 예에서 1,2,3은 참(true)이고 ${4 in servo_revolute_type}은 거짓이 됩니다.
다음은 C언어의 switch()문과 같은 형태로 사용을 하는 예 입니다.
<xacro:property name="servo_revolute_type" value="${[1]}"/>
<xacro:if value="${1 in servo_revolute_type}">
<xacro:property name="revolute_lower" value="${0}"/>
<xacro:property name="revolute_upper" value="${-pi/2}"/>
</xacro:if>
<xacro:if value="${2 in servo_revolute_type}">
<xacro:property name="revolute_lower" value="${pi/2}"/>
<xacro:property name="revolute_upper" value="${-pi/2}"/>
</xacro:if>
<xacro:if value="${3 in servo_revolute_type}">
<xacro:property name="revolute_lower" value="${pi}"/>
<xacro:property name="revolute_upper" value="${-pi}"/>
</xacro:if>
5. 매크로(macro)
매크로(macro)는 속성 블럭(property block)과 같이 XML문을 대치 합니다. 차이점은 속성 블럭은 인자(parameter)를 받을 수 없으나 매크로는 인자를 받을 수 있습니다. C언어의 함수와 유사 합니다. 다음은 suffix라는 인자 한 개를 받는 예 입니다.
<xacro:macro name="link_box_macro" params="suffix">
<link name="link_${suffix}">
<xacro:insert_block name="link_inertial_box" />
<xacro:insert_block name="link_visual_box" />
<xacro:insert_block name="link_collision_box" />
</link>
</xacro:macro>
위 매크로(macro)는 URDF에서 링크(link, 몸체)를 정의하는 매크로로써 사용은 다음과 같습니다.
<xacro:link_box_macro suffix="1" />
매크로의 인자(parameter)는 여러 개를 받을 수 있으며, 기본값(default value)를 추가하여 정의를 하면 호출할 때 해당 인자를 생략 할 수 있습니다.
다음과 같이 인자 axis에 axis:='0.0 0.0 1.0' 형식으로 정의를 하며, 기본값은 '0.0 0.0 1.0' 됩니다. 기본 값에는 속성(property)와 같이 ${}로 줄 수있고, 수학 함수나 상수 값도 줄 수 있습니다.
<xacro:macro name="revolute_circle_joint_macro" params="suffix parent child axis:='0.0 0.0 1.0'">
<joint name="joint_${suffix}" type="revolute">
<origin xyz="0.0 0.0 ${joint_height+height}" rpy="0.0 0.0 0.0"/>
<parent link="${parent}"/>
<child link="${child}"/>
<axis xyz="${axis}"/>
<limit lower="${circle_revolute_lower}" upper="${circle_revolute_upper}" effort="30" velocity="1"/>
</joint>
</xacro:macro>
당연한 이야기지만, 호출할 때 axis 값을 포함해서 사용할 수도 있고, 생략을 하게 되면 기본값으로 대치가 됩니다. 다음은 위 매크로를 사용하는 예 입니다.
<xacro:revolute_circle_joint_macro suffix="1" parent="base_link" child="link_1" />
6. 디버깅 및 URDF 문법 검사
URDF 파일의 문법이 맞는지는 check_urdf 유틸리티를 통해서 할 수 있습니다. 이 문서에서는 xacro urdf 파일이기 때문에 check_urdf 유틸리티로 문법 검사를 하기 전에 xacro 유틸리티를 통해서 xacro urdf를 순수한 urdf로 변환을 한 후에 check_urdf로 검사를 해야 합니다. xacro 유틸리티를 통해 urdf로 변환을 하면 실제 적용된 값을 확인할 수 있습니다. 다음과 같이 한 번에 URDF 문법 검사를 할 수 있습니다.
$ xacro model.urdf > tmp.urdf && check_urdf tmp.urdf && rm tmp.urdf |
xacro wiki 페이지는 http://wiki.ros.org/xacro 입니다.
'로봇 이야기 > ros2' 카테고리의 다른 글
기구학 (Kinematics) 이란? (0) | 2023.01.03 |
---|---|
매니퓰레이터(manipulator) URDF 모델링 (0) | 2022.12.31 |
URDF(Unified Robot Description Format)란? (0) | 2022.12.13 |
ROS2 URDF 시뮬레이션(simulation) workspace 만들기 (0) | 2022.12.13 |
ROS2 설치 - foxy (0) | 2022.12.13 |
댓글