xacro 파일에서 매크로 정의와 활용은 URDF 파일을 보다 효율적이고 관리 가능하게 만드는 중요한 방법이다. xacro는 XML을 확장하는 기능을 제공하며, 이를 통해 반복적인 구조를 간소화하거나 복잡한 로봇 모델을 매개변수화할 수 있다.

매크로 정의

매크로는 xacro에서 주어진 블록을 재사용 가능한 형태로 정의할 수 있는 방법이다. 매크로를 사용하면 코드의 중복을 줄이고 유지 보수를 쉽게 할 수 있다. 다음은 매크로 정의의 기본적인 형식이다.

<macro name="macro_name" params="param1 param2">
  <!-- 매크로 내용 -->
</macro>

여기서 macro_name은 매크로의 이름이며, params는 매크로에 전달할 매개변수들이다. 매크로는 매개변수를 받아 처리하고, 그 결과를 XML로 생성한다.

매크로 활용

매크로는 재사용이 가능하며, 동일한 구성 요소를 여러 번 정의해야 할 때 특히 유용하다. 예를 들어, 로봇의 여러 조인트에 동일한 형상을 사용하는 경우, 매크로로 해당 형상을 정의한 후 필요할 때마다 호출할 수 있다.

매크로를 호출할 때는 다음과 같은 형식을 사용한다.

<macro_name param1="value1" param2="value2" />

이 예시에서는 매크로에서 정의한 param1, param2에 해당하는 값을 전달하여 매크로를 호출한다.

매개변수와 기본값

매크로는 매개변수를 활용하여 유연하게 사용할 수 있다. 매개변수에는 기본값을 설정할 수 있으며, 필요에 따라 매크로 호출 시 값을 지정하거나 기본값을 사용할 수 있다. 예를 들어, 다음과 같이 기본값을 설정할 수 있다.

<macro name="box_link" params="name color size=1.0">
  <link name="${name}">
    <visual>
      <geometry>
        <box size="${size}${size} ${size}" />
      </geometry>
      <material name="${color}" />
    </visual>
  </link>
</macro>

이 매크로는 box_link라는 이름을 가지며, 세 개의 매개변수를 갖는다. size는 기본값으로 1.0을 가지며, 매크로 호출 시 지정하지 않으면 이 값을 사용한다.

매크로 호출 시, 다음과 같이 매개변수를 지정할 수 있다.

<box_link name="box1" color="red" />
<box_link name="box2" color="blue" size="2.0" />

첫 번째 호출에서는 size 매개변수를 지정하지 않았으므로 기본값인 1.0을 사용하고, 두 번째 호출에서는 size를 2.0으로 지정한다.

변수와 매개변수의 관계

매크로 내에서 사용하는 변수는 외부에서 전달된 매개변수를 바탕으로 설정된다. 수식이나 변수를 사용할 때, xacro는 ${} 구문을 사용하여 변수를 참조한다. 예를 들어, 매개변수를 통해 전달된 값을 기반으로 로봇 링크의 크기나 위치를 설정할 수 있다.

다음과 같은 수식을 통해 매크로 내에서 계산된 값을 변수로 사용할 수 있다.

<macro name="cylinder_link" params="radius height">
  <link name="cylinder">
    <visual>
      <geometry>
        <cylinder radius="${radius}" length="${height}" />
      </geometry>
    </visual>
  </link>
</macro>

이 매크로에서는 radiusheight라는 두 매개변수를 받아 실린더의 크기를 동적으로 결정한다.

수학적 계산 적용

xacro는 수학적 연산을 지원하므로, 변수 간의 관계를 정의할 때 수식을 사용할 수 있다. 예를 들어, 다음과 같은 수식을 사용할 수 있다:

\mathbf{L} = \sqrt{L_x^2 + L_y^2 + L_z^2}

이 수식을 xacro 코드에 적용하려면, ${} 안에서 변수 간의 수학적 연산을 정의할 수 있다.

<macro name="compute_length" params="Lx Ly Lz">
  <property name="L" value="$(arg Lx) *$(arg Lx) + $(arg Ly) *$(arg Ly) + $(arg Lz) *$(arg Lz)" />
</macro>

이처럼 xacro는 단순한 수식뿐만 아니라 매개변수를 바탕으로 한 복잡한 계산도 지원한다.

조건문 사용

xacro는 조건문을 지원하여 특정 조건에 따라 매크로의 동작을 변경할 수 있다. 조건문을 통해 로봇의 다양한 구성 요소를 선택적으로 생성하거나, 매개변수에 따라 다르게 처리할 수 있다. 기본적인 조건문 사용법은 다음과 같다.

<xacro:if value="${condition}">
  <!-- 조건이 참일 때 실행되는 부분 -->
</xacro:if>

<xacro:unless value="${condition}">
  <!-- 조건이 거짓일 때 실행되는 부분 -->
</xacro:unless>

여기서 ${condition}은 참 또는 거짓으로 평가될 수 있는 표현식이다. 예를 들어, 특정 매개변수에 따라 로봇 모델의 링크를 생성할지 여부를 결정할 수 있다.

다음은 조건문을 사용한 예제이다.

<macro name="create_link" params="create size">
  <xacro:if value="${create}">
    <link name="link1">
      <visual>
        <geometry>
          <box size="${size}${size} ${size}" />
        </geometry>
      </visual>
    </link>
  </xacro:if>
</macro>

이 예제에서 create라는 매개변수는 참이면 링크가 생성되고, 거짓이면 링크가 생성되지 않는다. 이를 호출할 때는 다음과 같이 사용할 수 있다.

<create_link create="true" size="1.0" />
<create_link create="false" size="1.0" />

첫 번째 호출에서는 링크가 생성되지만, 두 번째 호출에서는 create가 거짓이므로 링크가 생성되지 않는다.

반복문 사용

xacro는 반복문을 통해 동일한 작업을 여러 번 반복할 수 있다. 이를 통해 로봇의 다수 조인트나 반복되는 구조를 효율적으로 생성할 수 있다. 반복문은 xacro:for 구문을 사용하여 정의한다.

다음은 반복문을 사용하는 예제이다.

<xacro:for each="i" in="0 1 2 3 4">
  <link name="link_${i}">
    <visual>
      <geometry>
        <box size="1.0 1.0 1.0" />
      </geometry>
    </visual>
  </link>
</xacro:for>

이 반복문은 5개의 링크를 생성하며, 각각의 링크는 link_0, link_1, ..., link_4와 같은 이름을 가진다. 반복문을 사용함으로써 코드의 중복을 피하고, 유지 보수를 더욱 용이하게 할 수 있다.

매크로 중첩 사용

매크로는 중첩되어 사용될 수 있다. 즉, 한 매크로 내에서 다른 매크로를 호출할 수 있으며, 이를 통해 복잡한 로봇 모델을 간결하게 작성할 수 있다. 중첩된 매크로는 작은 단위의 기능을 여러 개 결합하여 로봇의 복잡한 구성을 만들 때 유용하다.

예를 들어, 다음과 같이 두 개의 매크로를 중첩하여 사용할 수 있다.

<macro name="wheel" params="radius width">
  <link name="wheel">
    <visual>
      <geometry>
        <cylinder radius="${radius}" length="${width}" />
      </geometry>
    </visual>
  </link>
</macro>

<macro name="robot_with_wheels" params="wheel_radius wheel_width">
  <link name="body">
    <visual>
      <geometry>
        <box size="1.0 1.0 1.0" />
      </geometry>
    </visual>
  </link>
  <wheel radius="${wheel_radius}" width="${wheel_width}" />
  <wheel radius="${wheel_radius}" width="${wheel_width}" />
</macro>

이 매크로는 먼저 wheel 매크로를 정의하고, robot_with_wheels 매크로 내에서 이를 두 번 호출하여 로봇의 바퀴를 추가한다. 중첩된 매크로를 통해 코드를 더욱 재사용 가능하고 모듈화할 수 있다.