매크로란?

xacro는 XML 매크로 언어로, 복잡한 URDF 파일을 단순화하고 재사용성을 높이기 위해 매크로 기능을 제공한다. 매크로는 특정한 기능이나 반복되는 코드를 정의한 후, 필요할 때마다 호출하여 중복을 줄일 수 있는 구조이다. URDF 모델에서 동일한 링크나 조인트가 반복적으로 등장하는 경우, 이를 매크로로 정의하면 코드의 간결함과 유지보수성을 높일 수 있다.

매크로 정의와 호출

매크로는 <xacro:macro> 태그를 사용하여 정의한다. 정의된 매크로는 필요한 부분에서 <xacro:call> 태그를 통해 호출된다. 매크로는 여러 파라미터를 받을 수 있으며, 파라미터화된 로봇 모델링을 위해 유용하다.

예를 들어, 동일한 형상의 여러 링크를 만들 때, 매크로를 활용하면 다음과 같은 방식으로 간결하게 표현할 수 있다.

<xacro:macro name="link_macro" params="link_name length radius">
  <link name="${link_name}">
    <inertial>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <mass value="1.0"/>
      <inertia ixx="0.1" iyy="0.1" izz="0.1" ixy="0.0" ixz="0.0" iyz="0.0"/>
    </inertial>
    <visual>
      <origin xyz="0 0 ${length/2}" rpy="0 0 0"/>
      <geometry>
        <cylinder radius="${radius}" length="${length}"/>
      </geometry>
      <material name="grey"/>
    </visual>
    <collision>
      <origin xyz="0 0 ${length/2}" rpy="0 0 0"/>
      <geometry>
        <cylinder radius="${radius}" length="${length}"/>
      </geometry>
    </collision>
  </link>
</xacro:macro>

<xacro:link_macro link_name="link1" length="1.0" radius="0.2"/>
<xacro:link_macro link_name="link2" length="1.5" radius="0.2"/>

위 코드는 link_macro라는 매크로를 정의하고, 이를 호출하여 서로 다른 두 링크를 생성한다. 매크로는 반복적인 URDF 코드를 줄이는 데 매우 유용하다.

파라미터화의 중요성

파라미터화를 통해 매크로는 보다 유연해진다. 이는 복잡한 로봇 모델을 구성할 때 유용하며, 특히 다양한 구성 요소들이 동일한 형태로 반복될 때 파라미터를 사용하여 각각의 차이를 정의할 수 있다.

파라미터화된 매크로를 사용하면 각 링크나 조인트의 길이, 각도, 질량 등을 간단히 수정할 수 있으며, 이를 통해 로봇의 여러 부품을 손쉽게 조정할 수 있다. 수식으로 표현하면 다음과 같다.

\text{length} = \mathbf{l}, \quad \text{radius} = \mathbf{r}

위 매크로에서 lengthradius는 파라미터로 사용되며, 이를 통해 다양한 링크를 간단하게 생성할 수 있다.

파라미터 기본값 지정

xacro에서는 파라미터의 기본값을 지정할 수 있다. 이는 매크로 호출 시 특정 파라미터를 생략할 수 있게 해준다. 기본값을 지정하는 방식은 다음과 같다.

<xacro:macro name="example_macro" params="param1:=1.0 param2:=2.0">
  <!-- 매크로 내용 -->
</xacro:macro>

이 경우, param1param2는 매크로 호출 시 생략되더라도 각각 1.0과 2.0의 기본값을 가지게 된다.

수학적 표현과 매크로의 활용

파라미터화는 로봇의 다양한 물리적 특성을 쉽게 정의하고 변경할 수 있도록 한다. 예를 들어, 로봇의 관성 모멘트를 파라미터화하는 경우, 관성 텐서를 다음과 같이 정의할 수 있다.

로봇 링크의 관성 모멘트 \mathbf{I}는 다음과 같은 대칭 행렬로 나타낼 수 있다.

\mathbf{I} = \begin{bmatrix} I_{xx} & I_{xy} & I_{xz} \\ I_{xy} & I_{yy} & I_{yz} \\ I_{xz} & I_{yz} & I_{zz} \end{bmatrix}

이때, 매크로에서 각 링크의 관성 모멘트를 파라미터화하여 다음과 같이 표현할 수 있다.

<xacro:macro name="inertia_macro" params="ixx:=1.0 iyy:=1.0 izz:=1.0 ixy:=0.0 ixz:=0.0 iyz:=0.0">
  <inertial>
    <origin xyz="0 0 0" rpy="0 0 0"/>
    <mass value="1.0"/>
    <inertia ixx="${ixx}" iyy="${iyy}" izz="${izz}" ixy="${ixy}" ixz="${ixz}" iyz="${iyz}"/>
  </inertial>
</xacro:macro>

여기서 ixx, iyy, izz, ixy, ixz, iyz 값은 매크로 호출 시 동적으로 설정할 수 있다. 이렇게 매크로로 파라미터화된 관성 텐서를 사용하면 다양한 링크에 대해 손쉽게 물리적 특성을 정의할 수 있다. 수학적으로는 링크의 관성 텐서를 다음과 같이 나타낼 수 있다.

\mathbf{I}_{\text{link}} = \begin{bmatrix} \mathbf{ixx} & \mathbf{ixy} & \mathbf{ixz} \\ \mathbf{ixy} & \mathbf{iyy} & \mathbf{iyz} \\ \mathbf{ixz} & \mathbf{iyz} & \mathbf{izz} \end{bmatrix}

파라미터 범위와 조건문 활용

xacro에서는 파라미터의 범위나 조건에 따라 다른 값을 선택할 수 있는 기능도 제공한다. 예를 들어, 로봇의 특정 조건에 따라 링크의 길이나 반지름을 다르게 설정해야 할 경우, 조건문을 사용할 수 있다. 이는 로봇의 다양한 구성에 대한 유연성을 제공한다.

<xacro:macro name="link_with_condition" params="length:=1.0 radius:=0.1">
  <link name="conditional_link">
    <inertial>
      <mass value="1.0"/>
    </inertial>
    <visual>
      <geometry>
        <cylinder radius="${radius}" length="${length}"/>
      </geometry>
    </visual>
    <collision>
      <geometry>
        <cylinder radius="${radius}" length="${length}"/>
      </geometry>
    </collision>
  </link>
  <xacro:if value="${length > 1.5}">
    <link name="extra_link">
      <visual>
        <geometry>
          <box size="0.5 0.5 0.5"/>
        </geometry>
      </visual>
    </link>
  </xacro:if>
</xacro:macro>

이 예제에서는 length 값이 1.5보다 크면 extra_link라는 추가적인 링크가 생성된다. 이처럼 조건문을 사용하면 로봇의 모델을 상황에 맞게 동적으로 생성할 수 있으며, 이를 통해 복잡한 로봇 모델을 효율적으로 관리할 수 있다.

매크로와 파라미터 활용의 실제 적용

로봇의 멀티 조인트 시스템이나 복잡한 로봇 모델에서는 동일한 형태의 링크나 조인트가 여러 개 존재할 수 있다. 이를 매크로와 파라미터로 정의하면 다음과 같이 모델의 반복성을 줄이면서 코드의 가독성을 높일 수 있다.

예를 들어, 로봇의 팔에 여러 개의 동일한 형태의 링크가 연결되어 있는 경우, 이를 매크로로 정의하여 각 링크의 길이와 각도를 파라미터화할 수 있다. 각 링크의 특성을 매크로에서 파라미터로 전달하면, 단일한 매크로로 복잡한 로봇 팔의 모델을 쉽게 구성할 수 있다.

<xacro:macro name="arm_link" params="length:=1.0 radius:=0.1 joint_angle:=0.0">
  <link name="link_${joint_angle}">
    <inertial>
      <mass value="1.0"/>
    </inertial>
    <visual>
      <geometry>
        <cylinder radius="${radius}" length="${length}"/>
      </geometry>
    </visual>
    <collision>
      <geometry>
        <cylinder radius="${radius}" length="${length}"/>
      </geometry>
    </collision>
  </link>
  <joint name="joint_${joint_angle}" type="revolute">
    <parent link="link_${joint_angle}"/>
    <child link="link_${joint_angle+1}"/>
    <axis xyz="0 1 0"/>
    <limit effort="1.0" velocity="1.0" lower="${joint_angle}" upper="${joint_angle+1}"/>
  </joint>
</xacro:macro>

<xacro:arm_link length="1.2" radius="0.15" joint_angle="0.0"/>
<xacro:arm_link length="1.0" radius="0.1" joint_angle="1.0"/>

이 예제는 로봇 팔의 각 링크와 조인트를 매크로로 정의하고, length, radius, joint_angle과 같은 파라미터를 활용하여 각 링크의 길이와 조인트 각도를 다르게 설정할 수 있도록 한다. 이 방식은 특히 멀티 조인트 로봇 모델을 생성할 때 매우 유용하다.