Skip to content

Commit dc401f5

Browse files
committed
Add new test of UrdfExporter
1 parent 22d1dd6 commit dc401f5

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed

tests/test_urdf_exporter.py

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import idyntree.bindings as idt
2+
import numpy as np
3+
import numpy.typing as npt
4+
import pytest
5+
from utils_models import ModelFactory, Robot
6+
7+
import rod
8+
import rod.urdf.exporter
9+
10+
11+
@pytest.mark.parametrize(
12+
"robot",
13+
[
14+
Robot.iCub,
15+
Robot.DoublePendulum,
16+
Robot.Cassie,
17+
Robot.Ur10,
18+
Robot.AtlasV4,
19+
Robot.Ergocub,
20+
],
21+
)
22+
def test_urdf_exporter(robot: Robot) -> None:
23+
"""Test exporting URDF files."""
24+
25+
# Get the path to the URDF.
26+
original_urdf_path = ModelFactory.get_model_description(robot=robot)
27+
28+
# Load the URDF (it gets converted to SDF internally).
29+
sdf = rod.Sdf.load(sdf=original_urdf_path, is_urdf=True)
30+
31+
# Export the URDF from the in-memory SDF-based description.
32+
exported_urdf_string = rod.urdf.exporter.UrdfExporter().to_urdf_string(sdf=sdf)
33+
34+
# Create two model loaders.
35+
mdl_loader_original = idt.ModelLoader()
36+
mdl_loader_exported = idt.ModelLoader()
37+
38+
# Get the joint serialization from ROD.
39+
joint_names = [j.name for j in sdf.model.joints() if j.type != "fixed"]
40+
41+
# Load the original URDF.
42+
assert mdl_loader_original.loadReducedModelFromString(
43+
original_urdf_path.read_text(), joint_names
44+
)
45+
46+
# Load the exported URDF.
47+
assert mdl_loader_exported.loadReducedModelFromString(
48+
exported_urdf_string, joint_names
49+
)
50+
51+
# Create two KinDynComputations objects, one for the original URDF and
52+
# one for the exported URDF.
53+
kin_dyn_original = idt.KinDynComputations()
54+
kin_dyn_exported = idt.KinDynComputations()
55+
56+
# Load the two robot models in the KinDynComputations objects.
57+
assert kin_dyn_original.loadRobotModel(mdl_loader_original.model())
58+
assert kin_dyn_exported.loadRobotModel(mdl_loader_exported.model())
59+
60+
# Get all the links and frames from the original URDF.
61+
all_original_frames = [
62+
kin_dyn_original.getFrameName(i)
63+
for i in range(
64+
kin_dyn_original.getNrOfLinks(), kin_dyn_original.getNrOfFrames()
65+
)
66+
]
67+
68+
all_exported_frames = [
69+
kin_dyn_exported.getFrameName(i)
70+
for i in range(
71+
kin_dyn_exported.getNrOfLinks(), kin_dyn_exported.getNrOfFrames()
72+
)
73+
]
74+
75+
# =================================
76+
# Test that kinematics is preserved
77+
# =================================
78+
79+
def get_frame_transform(
80+
kin_dyn: idt.KinDynComputations, frame_name: str
81+
) -> npt.NDArray:
82+
83+
frame_idx = kin_dyn.getFrameIndex(frame_name)
84+
assert frame_idx >= 0, frame_name
85+
86+
if frame_name == kin_dyn.getFloatingBase():
87+
H_idt = kin_dyn.getWorldBaseTransform()
88+
else:
89+
H_idt = kin_dyn.getWorldTransform(frame_name)
90+
91+
H = np.eye(4)
92+
H[0:3, 3] = H_idt.getPosition().toNumPy()
93+
H[0:3, 0:3] = H_idt.getRotation().toNumPy()
94+
95+
return H
96+
97+
for frame in set(all_original_frames).intersection(all_exported_frames):
98+
99+
W_H_F_original = get_frame_transform(kin_dyn=kin_dyn_original, frame_name=frame)
100+
W_H_F_exported = get_frame_transform(kin_dyn=kin_dyn_exported, frame_name=frame)
101+
102+
assert W_H_F_exported == pytest.approx(W_H_F_original, abs=1e-6), (
103+
frame,
104+
W_H_F_original,
105+
W_H_F_exported,
106+
np.abs(W_H_F_original - W_H_F_exported),
107+
)
108+
109+
# ===============================
110+
# Test that dynamics is preserved
111+
# ===============================
112+
113+
mass_original = kin_dyn_original.model().getTotalMass()
114+
mass_exported = kin_dyn_exported.model().getTotalMass()
115+
assert mass_exported == pytest.approx(mass_original, abs=1e-6)
116+
117+
locked_inertia_original = (
118+
kin_dyn_original.getRobotLockedInertia().asMatrix().toNumPy()
119+
)
120+
121+
locked_inertia_exported = (
122+
kin_dyn_exported.getRobotLockedInertia().asMatrix().toNumPy()
123+
)
124+
125+
assert locked_inertia_exported == pytest.approx(locked_inertia_original, abs=1e-6)

0 commit comments

Comments
 (0)