If you're in a ROS-aware environment or can install it separately, you might look at using xacro
. Then you can define a xacro:macro
.
For example (saving the content below as bathroom.sdf.xacro
):
<?xml version="1.0"?>
<sdf version="1.11">
<world xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- Define the xacro:macro for later use -->
<xacro:macro name="public_bathroom" params="identifier=DEFAULT_ID pose='0 0 0 0 0 0' door_link_pose='0 0 0 0 0 0'">
<include>
<model name="PublicBathroom${identifier}">
<pose>
${pose}
</pose>
<sometag>
</sometag>
<link name="door">
<pose>
${door_link_pose}
</pose>
</link>
</model>
</include>
</xacro:macro>
<!-- Instantiate three different public bathrooms, the last one default -->
<xacro:public_bathroom identifier="A" pose="9.0 3.0 0 0 0 0" door_link_pose="-0.3 -0.05 0 0 0 6.07"/>
<xacro:public_bathroom identifier="B" pose="12.0 3.0 0 0 0 0" door_link_pose="-0.3 -0.05 0 0 0 6.17"/>
<xacro:public_bathroom/>
</world>
</sdf>
<sometag></sometag>
is your common content across all bathrooms.
Running xacro bathroom.sdf.xacro
results in this output:
<?xml version="1.0" ?>
<!-- =================================================================================== -->
<!-- | This document was autogenerated by xacro from bathroom.sdf.xacro | -->
<!-- | EDITING THIS FILE BY HAND IS NOT RECOMMENDED | -->
<!-- =================================================================================== -->
<sdf version="1.11">
<world>
<include>
<model name="PublicBathroomA">
<pose>
9.0 3.0 0 0 0 0
</pose>
<sometag>
</sometag>
<link name="door">
<pose>
-0.3 -0.05 0 0 0 6.07
</pose>
</link>
</model>
</include>
<include>
<model name="PublicBathroomB">
<pose>
12.0 3.0 0 0 0 0
</pose>
<sometag>
</sometag>
<link name="door">
<pose>
-0.3 -0.05 0 0 0 6.17
</pose>
</link>
</model>
</include>
<include>
<model name="PublicBathroomDEFAULT_ID">
<pose>
0 0 0 0 0 0
</pose>
<sometag>
</sometag>
<link name="door">
<pose>
0 0 0 0 0 0
</pose>
</link>
</model>
</include>
</world>
</sdf>
I don't know the details of installing xacro
without ROS and the limitations there.
It seems like there are a couple of relevant recent PRs to allow xacro
to work without ROS, but I haven't tried it:
https://github.com/ros/xacro/pull/329
https://github.com/ros/xacro/pull/340
I ran my example from a ROS 2 Humble environment.