Package: xmacro
xmacroxmacrois a simple tool to define and parse XML macro. it's inspired byros/xacrowhich is an XML macro language desiged forurdf.xmacrolooks like a simplified version ofros/xacro, it's simpler, but it works well both forurdfandsdf. in addition it's flexible, and also easy to use.xmacrois independent of ROS, you could install it bypip.XML namespace isn't used inxmacro, there are some reserved tags:xmacro_include,xmacro_define_value,xmacro_define_block,xmacro_block.it provides python api so that we could parse xml file in ROS2 launch file.xmacro4sdf:xmacrowith some specific functions forsdf(pre-defined common macro,xmacro_includepath parser formodel://).xmacro4urdf:xmacrowith some specific functions forurdf(pre-defined common macro,xmacro_includepath parser forpackage://).UsageInstallation# install by pippipinstallxmacro# install from source codegitclonehttps://github.com/gezp/xmacro.gitcdxmacro&&sudopython3setup.pyinstallexamples# some examples in folder test/xmacroxmacrotest_xmacro_block.xml.xmacro>test_xmacro_block.xmlXMLMacro FeaturesValue macroBlock macroMath expressionsIncludePython APIValue macroValue macro are named values that can be inserted anywhere into the XML documentexcept<xmacro_define_block>block.xmacro definition<!--definition of properties --><xmacro_define_valuename="radius"value="4.3"/><!--use of properties--><circlediameter="${2 * radius}"/>generated xml<circlediameter="8.6"/>Block macroDefine block macros with the macro tag<xmacro_define_block>, then specify the macro name and a list of parameters. The list of parameters should be whitespace separated.The usage of block macros is to define<xmacro_block>which will be replaced with corresponding<xmacro_define_block>block.xmacro definition<!--definition of macro--><xmacro_define_valuename="mass"value="0.2"/><xmacro_define_blockname="box_inertia"params="m x y z"><mass>${m}</mass><inertia><ixx>${m*(y*y+z*z)/12}</ixx><ixy>0</ixy><ixz>0</ixz><iyy>${m*(x*x+z*z)/12}</iyy><iyz>0</iyz><izz>${m*(x*x+z*z)/12}</izz></inertia></xmacro_define_block><!--use of macro--><inertial><pose>000.02000</pose><xmacro_blockname="box_inertia"m="${mass}"x="0.3"y="0.1"z="0.2"/></inertial>generated xml<inertial><pose>000.02000</pose><mass>0.2</mass><inertia><ixx>0.0008333333333333335</ixx><ixy>0</ixy><ixz>0</ixz><iyy>0.002166666666666667</iyy><iyz>0</iyz><izz>0.002166666666666667</izz></inertia></inertial>only support simple parameters (string and number), and block parameters isn't supported.it's supported to use otherxmacro_blockinxmacro_define_blockwhich is recursive definition (the max nesting level is 5).condition blocka example here (you could find more examples intest/xmacro/test_xmacro_condition.xml.xmacro)<!--use of macro--><inertial><pose>000.02000</pose><xmacro_blockname="box_inertia"m="${mass}"x="0.3"y="0.1"z="0.2"condition="${mass==0.2}"/></inertial>theconditioncan beTrue,False,1,0, we can also use math expression to define condition, but operator<and>isn't supported in math expression.ifconditionisFalseor0, thexmacro_blockwou't be loaded.conditionis reserved attribute of<xmacro_block>, soconditioncan't be used asparamsof<xmacro_define_block>.Math expressionswithin dollared-braces${xxxx}, you can also write simple math expressions.refer to examples ofValue macroandBlock macroit's implemented by callingeval()in python, so it's unsafe for some cases.Including other xmacro filesYou can include other xmacro files by using the<xmacro_include>tag.it will include the xmcaro definition with tag<xmacro_define_value>and macros with tag<xmacro_define_block>.<xmacro_includeuri="file://simple_car/model.sdf.xmacro"/>The uri forfilemeans to open the file directly.it try to open the file with relative pathsimple_car/model.sdf.xmacro.you can also try to open file with absolute path/simple_car/model.sdf.xmacrowith urifile:///simple_car/model.sdf.xmacro.<xmacro_include>supports to include  recursively.Python APIyou can usexmacroin python easilyfromxmacro.xmacroimportXMLMacroxmacro=XMLMacro()#case1 parse from filexmacro.set_xml_file(inputfile)xmacro.generate()xmacro.to_file(outputfile)#case2 parse from xml stringxmacro.set_xml_string(xml_str)xmacro.generate()xmacro.to_file(outputfile)#case3 generate to stringxmacro.set_xml_file(inputfile)xmacro.generate()xmacro.to_string()#case4 custom macro valuexmacro.set_xml_file(inputfile)# use custom dictionary to overwrite global macro value defined by <xmacro_define_value>kv={"rplidar_a2_h":0.8}xmacro.generate(kv)xmacro.to_file(outputfile)XMLMacro4sdf Featurespre-defined common.sdf.xmacro<!--macro defination:inertia--><xmacro_define_blockname="inertia_cylinder"params="m r l"><xmacro_define_blockname="inertia_box"params="m x y z"><xmacro_define_blockname="inertia_sphere"params="m r"><!--macro defination:geometry--><xmacro_define_blockname="geometry_cylinder"params="r l"><xmacro_define_blockname="geometry_box"params="x y z"><xmacro_define_blockname="geometry_sphere"params="r"><xmacro_define_blockname="geometry_mesh"params="uri"><!--macro defination:visual_collision_with_mesh--><xmacro_define_blockname="visual_collision_with_mesh"params="prefix uri">examples# some examples in folder test/sdfxmacro4sdfmodel.sdf.xmacro>model.sdfXMLMacro4urdf Featurespre-defined common.urdf.xmacro<!--macro defination:inertia--><xmacro_define_blockname="inertia_cylinder"params="m r l"><xmacro_define_blockname="inertia_box"params="m x y z"><xmacro_define_blockname="inertia_sphere"params="m r"><!--macro defination:geometry--><xmacro_define_blockname="geometry_cylinder"params="r l"><xmacro_define_blockname="geometry_box"params="x y z"><xmacro_define_blockname="geometry_sphere"params="r"><xmacro_define_blockname="geometry_mesh"params="uri">examples# some examples in folder test/urdfxmacro4urdfrobot.urdf.xmacro>robot.urdfMaintainer and Licensemaintainer : Zhenpeng Ge,zhenpeng.ge@qq.comxmacrois provided under MIT License.