Package: rod
RObot Description processorThe ultimate Python tool for RObot Descriptions processing.ROD is yet another library to operate on robot descriptions based on theSDFormatspecification.Why SDFormat?Among the many existing robot description formats, SDFormat provides a well-defined and maintainedversioned specificationthat controls the available fields and their content.Open Roboticsalready provides the C++ librarygazebosim/sdformatwith initial support ofPython bindings.
However, C++ dependencies in pure-Python projects are typically quite complicated to handle and maintain.
Here ROD comes to rescue.URDF, thanks to native ROS support, is historically the most popular robot description used by the community.
The main problem of URDF is that it is not a specification, and developers of URDF descriptions might produce models and parsers that do not comply to any standard.
Luckily, URDF models can be easily converted to SDF[^urdf_to_sdf].
If the URDF model is not compliant, the process errors with clear messages.
Furthermore, modern versions of the converter produce a SDF description with standardizedpose semantics,
that greatly simplifies the life of downstream developers that do not have to guess the reference frame or pose elements.
Last but not least, the pose semantics also makes SDF aware of the concept offramethat URDF is missing.FeaturesOut-of-the-box support of SDFormat specifications≥ 1.7Serialization and deserialization support of SDF filesIn-memory layout based ondataclassesSyntax highlighting and auto-completionSupport of programmatic creation of SDF files from Python APIsTransitive support of URDF through conversion to SDF[^urdf_to_sdf]Type validation of elements and attributesAutomatic check of missing required elementsBased onFatal1ty/mashumarofor great serialization and deserialization performanceSupport of exporting the in-memory model description to URDF[^urdf_to_sdf]: Conversion can be done either usingign sdfincluded in Ignition Gazebo Fortress, orgz sdfincluded in Gazebo Sim starting from Garden.InstallationYou can install the project withpypa/pip, preferably in avirtual environment:pipinstallgit+https://github.com/ami-iit/rodExamplesSerialize and deserialize SDF filesimportpathlibfromrodimportSdf# Supported SDF resourcessdf_resource_1="/path/to/file.sdf"sdf_resource_2=pathlib.Path(sdf_resource_1)sdf_resource_3=sdf_resource_2.read_text()# Deserialize SDF resourcessdf_1=Sdf.load(sdf=sdf_resource_1)sdf_2=Sdf.load(sdf=sdf_resource_2)sdf_3=Sdf.load(sdf=sdf_resource_3)# Serialize in-memory Sdf objectprint(sdf_3.serialize(pretty=True))Create SDF models programmaticallyfromrodimportAxis,Inertia,Inertial,Joint,Limit,Link,Model,Sdf,Xyzsdf=Sdf(version="1.7",model=Model(name="my_model",link=[Link(name="base_link",inertial=Inertial(mass=1.0,inertia=Inertia())),Link(name="my_link",inertial=Inertial(mass=0.5,inertia=Inertia())),],joint=Joint(name="base_to_my_link",type="revolute",parent="base_link",child="my_link",axis=Axis(xyz=Xyz(xyz=[0,0,1]),limit=Limit(lower=-3.13,upper=3.14)),),),)print(sdf.serialize(pretty=True))<?xml version="1.0" encoding="utf-8"?><sdfversion="1.7"><modelname="my_model"><linkname="base_link"><inertial><mass>1.0</mass><inertia><ixx>1.0</ixx><iyy>1.0</iyy><izz>1.0</izz><ixy>0.0</ixy><ixz>0.0</ixz><iyz>0.0</iyz></inertia></inertial></link><linkname="my_link"><inertial><mass>0.5</mass><inertia><ixx>1.0</ixx><iyy>1.0</iyy><izz>1.0</izz><ixy>0.0</ixy><ixz>0.0</ixz><iyz>0.0</iyz></inertia></inertial></link><jointname="base_to_my_link"type="revolute"><parent>base_link</parent><child>my_link</child><axis><xyz>001</xyz><limit><lower>-3.13</lower><upper>3.14</upper></limit></axis></joint></model></sdf>Exporting SDF to URDF# Generate first the 'sdf' object with the collapsed code# of the section 'Create SDF models programmatically'.fromrod.urdf.exporterimportUrdfExporterurdf_string=UrdfExporter.sdf_to_urdf_string(sdf=sdf,pretty=True,gazebo_preserve_fixed_joints=True,)print(urdf_string)<?xml version="1.0" encoding="utf-8"?><robotname="my_model"><linkname="base_link"><inertial><originxyz="0.0 0.0 0.0"rpy="0.0 0.0 0.0"/><massvalue="1.0"/><inertiaixx="1.0"ixy="0.0"ixz="0.0"iyy="1.0"iyz="0.0"izz="1.0"/></inertial></link><linkname="my_link"><inertial><originxyz="0.0 0.0 0.0"rpy="0.0 0.0 0.0"/><massvalue="0.5"/><inertiaixx="1.0"ixy="0.0"ixz="0.0"iyy="1.0"iyz="0.0"izz="1.0"/></inertial></link><jointname="base_to_my_link"type="revolute"><originxyz="0.0 0.0 0.0"rpy="0.0 0.0 0.0"/><parentlink="base_link"/><childlink="my_link"/><axisxyz="0 0 1"/><limiteffort="3.4028235e+38"velocity="3.4028235e+38"lower="-3.13"upper="3.14"/></joint></robot>Similar projectshttps://github.com/gazebosim/sdformathttps://github.com/mmatl/urdfpyhttps://github.com/clemense/yourdfpyhttps://github.com/ros/urdf_parser_pyhttps://github.com/FirefoxMetzger/python-sdformat/ContributingPull requests are welcome.
For major changes, please open an issue first to discuss what you would like to change.Maintainers@diegoferigoLicenseBSD3