원클릭으로
xacro-conversion
Convert URDF files to Xacro format with macros for reusable components like wheels, sensors, and repeated geometry
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Convert URDF files to Xacro format with macros for reusable components like wheels, sensors, and repeated geometry
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use this skill when modifying OpenSCAD files where the user wants to use the customizer features (parameter parsing, UI generation, and conversion to STL/SVG/GLB with parameter overrides).
Use this skill when modifying OpenSCAD files (*.scad)
Use when creating URDF or Xacro files which require non-trivial geometry
Discover, recommend, and install OpenSCAD libraries for your projects. Use when: needing geometry functions, seeking existing modules before creating, managing library dependencies, or exploring what libraries are available in your workspace.
Core URDF/Xacro syntax, joint types, kinematic structures, and URDF validation for robot descriptions
Guide for creating appropriate geometry in URDF files - basic shapes vs OpenSCAD vs mesh files
| name | xacro-conversion |
| description | Convert URDF files to Xacro format with macros for reusable components like wheels, sensors, and repeated geometry |
This skill guides the process of converting URDF files to Xacro format and creating reusable macros for repeated geometry.
Use this skill when you notice:
Converting URDF to Xacro can be disruptive because:
.urdf to .xacroAlways ask: "I can convert this to Xacro with macros for [components]. This will make it more maintainable but requires renaming the file. Would you like me to proceed?"
Look for repeated patterns:
Example of duplication:
<!-- Four nearly identical wheel definitions -->
<link name="left_front_wheel">
<visual>
<geometry><cylinder radius="0.1" length="0.05"/></geometry>
</visual>
</link>
<link name="right_front_wheel">
<visual>
<geometry><cylinder radius="0.1" length="0.05"/></geometry>
</visual>
</link>
<!-- ... and two more identical wheels -->
Identify what varies between instances:
Macro design principles:
File structure:
<?xml version="1.0"?>
<robot name="robot_name" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- Properties (constants) -->
<xacro:property name="wheel_radius" value="0.1"/>
<xacro:property name="wheel_length" value="0.05"/>
<!-- Macros -->
<xacro:macro name="component_name" params="param1 param2 ...">
<!-- Macro content -->
</xacro:macro>
<!-- Main robot structure -->
<link name="base_link">
<!-- ... -->
</link>
<!-- Use macros -->
<xacro:component_name param1="value1" param2="value2"/>
</robot>
Basic wheel macro example:
<xacro:macro name="wheel" params="prefix reflect">
<link name="${prefix}_wheel">
<visual>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_length}"/>
</geometry>
<material name="black">
<color rgba="0.1 0.1 0.1 1"/>
</material>
</visual>
<collision>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_length}"/>
</geometry>
</collision>
</link>
<joint name="base_to_${prefix}_wheel" type="continuous">
<parent link="base_link"/>
<child link="${prefix}_wheel"/>
<origin xyz="0 ${reflect * wheel_offset_y} 0" rpy="0 1.5708 0"/>
<axis xyz="0 0 1"/>
</joint>
</xacro:macro>
<!-- Replace four wheel definitions with four macro calls -->
<xacro:wheel prefix="left_front" reflect="1"/>
<xacro:wheel prefix="right_front" reflect="-1"/>
<xacro:wheel prefix="left_rear" reflect="1"/>
<xacro:wheel prefix="right_rear" reflect="-1"/>
robot.urdf → robot.urdf.xacro or robot.xacroParameters:
prefix - Name prefix (left/right, front/rear)x_pos, y_pos - Position coordinatesreflect - Mirror multiplier for symmetry<xacro:macro name="wheel" params="prefix x_pos y_pos">
<link name="${prefix}_wheel">
<visual>
<geometry>
<cylinder radius="0.1" length="0.05"/>
</geometry>
</visual>
</link>
<joint name="base_to_${prefix}_wheel" type="continuous">
<parent link="base_link"/>
<child link="${prefix}_wheel"/>
<origin xyz="${x_pos} ${y_pos} 0" rpy="0 1.5708 0"/>
<axis xyz="0 0 1"/>
</joint>
</xacro:macro>
<!-- Usage -->
<xacro:wheel prefix="left_front" x_pos="0.3" y_pos="0.2"/>
<xacro:wheel prefix="right_front" x_pos="0.3" y_pos="-0.2"/>
Parameters:
prefix - Leg identifier (fl, fr, rl, rr)x_pos, y_pos - Hip positionleg_length, foot_length - Segment lengths<xacro:macro name="leg" params="prefix x_pos y_pos">
<!-- Hip link -->
<link name="${prefix}_hip">
<visual>
<geometry><sphere radius="0.05"/></geometry>
</visual>
</link>
<!-- Upper leg link -->
<link name="${prefix}_upper_leg">
<visual>
<geometry><cylinder radius="0.02" length="0.3"/></geometry>
</visual>
</link>
<!-- Lower leg link -->
<link name="${prefix}_lower_leg">
<visual>
<geometry><cylinder radius="0.015" length="0.3"/></geometry>
</visual>
</link>
<!-- Joints connecting segments -->
<joint name="base_to_${prefix}_hip" type="revolute">
<parent link="base_link"/>
<child link="${prefix}_hip"/>
<origin xyz="${x_pos} ${y_pos} 0"/>
<axis xyz="1 0 0"/>
<limit lower="-0.5" upper="0.5" effort="10" velocity="1"/>
</joint>
<joint name="${prefix}_hip_to_upper" type="revolute">
<parent link="${prefix}_hip"/>
<child link="${prefix}_upper_leg"/>
<origin xyz="0 0 -0.15" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
<limit lower="-1.57" upper="1.57" effort="10" velocity="1"/>
</joint>
<joint name="${prefix}_upper_to_lower" type="revolute">
<parent link="${prefix}_upper_leg"/>
<child link="${prefix}_lower_leg"/>
<origin xyz="0 0 -0.3" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
<limit lower="-1.57" upper="1.57" effort="10" velocity="1"/>
</joint>
</xacro:macro>
Parameters:
name - Sensor identifierparent - Parent link namexyz, rpy - Mounting position and orientationmesh_file - Optional mesh file path<xacro:macro name="camera_mount" params="name parent x y z roll pitch yaw">
<link name="${name}_link">
<visual>
<geometry>
<box size="0.05 0.05 0.03"/>
</geometry>
<material name="camera_gray">
<color rgba="0.5 0.5 0.5 1"/>
</material>
</visual>
</link>
<joint name="${parent}_to_${name}" type="fixed">
<parent link="${parent}"/>
<child link="${name}_link"/>
<origin xyz="${x} ${y} ${z}" rpy="${roll} ${pitch} ${yaw}"/>
</joint>
</xacro:macro>
<!-- Usage -->
<xacro:camera_mount name="front_camera" parent="base_link"
x="0.3" y="0" z="0.1"
roll="0" pitch="0" yaw="0"/>
Define once, use everywhere:
<xacro:property name="wheel_radius" value="0.1"/>
<xacro:property name="wheel_length" value="0.05"/>
<xacro:property name="base_width" value="0.4"/>
<xacro:property name="pi" value="3.14159265"/>
<!-- Use in geometry -->
<cylinder radius="${wheel_radius}" length="${wheel_length}"/>
Xacro supports math in ${}:
<xacro:property name="wheel_offset" value="0.15"/>
<!-- Calculate positions -->
<origin xyz="0 ${wheel_offset + 0.05} 0"/>
<origin xyz="0 ${-wheel_offset} 0"/>
<origin xyz="0 0 ${wheel_radius / 2}"/>
<xacro:macro name="leg" params="prefix has_foot:=true">
<link name="${prefix}_leg">
<!-- ... -->
</link>
<xacro:if value="${has_foot}">
<link name="${prefix}_foot">
<!-- ... -->
</link>
</xacro:if>
</xacro:macro>
Split large robots into modular files:
<!-- main_robot.urdf.xacro -->
<?xml version="1.0"?>
<robot name="modular_robot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- Include macro libraries -->
<xacro:include filename="$(find my_robot)/urdf/wheel_macros.xacro"/>
<xacro:include filename="$(find my_robot)/urdf/sensor_macros.xacro"/>
<!-- Use included macros -->
<xacro:wheel prefix="left" reflect="1"/>
<xacro:camera_mount name="front" parent="base_link"/>
</robot>
User has this URDF:
<robot name="quad_bot">
<link name="base_link">...</link>
<!-- Four identical wheels, only position differs -->
<link name="lf_wheel"><visual><geometry><cylinder radius="0.08" length="0.04"/></geometry></visual></link>
<joint name="base_to_lf" type="continuous">...</joint>
<link name="rf_wheel"><visual><geometry><cylinder radius="0.08" length="0.04"/></geometry></visual></link>
<joint name="base_to_rf" type="continuous">...</joint>
<link name="lr_wheel"><visual><geometry><cylinder radius="0.08" length="0.04"/></geometry></visual></link>
<joint name="base_to_lr" type="continuous">...</joint>
<link name="rr_wheel"><visual><geometry><cylinder radius="0.08" length="0.04"/></geometry></visual></link>
<joint name="base_to_rr" type="continuous">...</joint>
</robot>
Agent response:
I notice you have four identical wheels that differ only in position.
This would be much cleaner as a Xacro macro.
Converting to Xacro will:
- Reduce file from ~200 lines to ~80 lines
- Make wheel parameters easy to change (single definition)
- Rename file from .urdf to .xacro
Would you like me to convert this to Xacro?
After user approval:
<?xml version="1.0"?>
<robot name="quad_bot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:property name="wheel_radius" value="0.08"/>
<xacro:property name="wheel_length" value="0.04"/>
<xacro:macro name="wheel" params="prefix x_reflect y_reflect">
<link name="${prefix}_wheel">
<visual>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_length}"/>
</geometry>
</visual>
</link>
<joint name="base_to_${prefix}" type="continuous">
<parent link="base_link"/>
<child link="${prefix}_wheel"/>
<origin xyz="${x_reflect * 0.3} ${y_reflect * 0.25} 0" rpy="0 1.5708 0"/>
<axis xyz="0 0 1"/>
</joint>
</xacro:macro>
<link name="base_link">...</link>
<xacro:wheel prefix="lf" x_reflect="1" y_reflect="1"/>
<xacro:wheel prefix="rf" x_reflect="1" y_reflect="-1"/>
<xacro:wheel prefix="lr" x_reflect="-1" y_reflect="1"/>
<xacro:wheel prefix="rr" x_reflect="-1" y_reflect="-1"/>
</robot>
❌ Don't:
✅ Do: