Skip to content

Commit

Permalink
Merge pull request #50 from ami-iit/flferretti-patch-2
Browse files Browse the repository at this point in the history
Refactor SDF handling logic for non-existing string paths
  • Loading branch information
flferretti authored Nov 12, 2024
2 parents b4a89fb + e0cf6ad commit d931d20
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 26 deletions.
45 changes: 19 additions & 26 deletions src/rod/sdf/sdf.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import dataclasses
import os
import pathlib

import mashumaro
Expand Down Expand Up @@ -60,34 +59,28 @@ def load(sdf: pathlib.Path | str, is_urdf: bool | None = None) -> Sdf:
The parsed SDF file.
"""

# Handle the max path length depending on the OS
try:
from ctypes.wintypes import MAX_PATH
except ValueError:
MAX_PATH = os.pathconf("/", "PC_PATH_MAX")

if is_urdf is not None:
sdf_string = sdf
else:
match sdf:
# Case 1: It's a Path object
case pathlib.Path():
sdf_string = sdf.read_text()
is_urdf = sdf.suffix == ".urdf"

# Case 2: It's a string with a path
case str() if len(sdf) <= MAX_PATH and pathlib.Path(sdf).is_file():
sdf_string = pathlib.Path(sdf).read_text(encoding="utf-8")
is_urdf = pathlib.Path(sdf).suffix == ".urdf"
path = pathlib.Path(sdf)

# Case 3: It's an SDF/URDF string
case str():
match sdf:
# Case 1: Handle strings.
case str():
if path.suffix:
# Assuming that if the string has a suffix, it is a path.
sdf_string = pathlib.Path(sdf).read_text(encoding="utf-8")
else:
# Otherwise, it is an SDF string.
sdf_string = sdf
is_urdf = "<robot" in sdf_string

# Case 4: Raise an error for unsupported types
case _:
raise TypeError(f"Unsupported type for 'sdf': {type(sdf)}")
is_urdf = is_urdf if is_urdf is not None else "<robot" in sdf_string

# Case 2: Handle pathlib.Path.
case pathlib.Path():
sdf_string = path.read_text(encoding="utf-8")
is_urdf = is_urdf if is_urdf is not None else path.suffix == ".urdf"

# Case 3: Raise an error for unsupported types.
case _:
raise TypeError(f"Unsupported type for 'sdf': {type(sdf)}")

# Convert SDF to URDF if needed (it requires system executables)
if is_urdf:
Expand Down
22 changes: 22 additions & 0 deletions tests/test_urdf_parsing.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import pathlib

import pytest
import robot_descriptions
import robot_descriptions.loaders.idyntree
Expand Down Expand Up @@ -35,12 +37,32 @@ def test_urdf_parsing(robot: Robot) -> None:
with pytest.raises(RuntimeError):
_ = rod.Sdf.load(sdf=urdf_path.read_text(), is_urdf=False)

# Check that it fails is is_urdf=True and the resource is a non-existing path
with pytest.raises(FileNotFoundError):
_ = rod.Sdf.load(sdf="/non/existing/path.sdf", is_urdf=False)

# Check that it fails is is_urdf=True and the resource is an empty string
with pytest.raises(FileNotFoundError):
_ = rod.Sdf.load(sdf=pathlib.Path("/non/existing/path.sdf"), is_urdf=False)

# The following instead should succeed
_ = rod.Sdf.load(sdf=urdf_path, is_urdf=None)
_ = rod.Sdf.load(sdf=urdf_path, is_urdf=True)
_ = rod.Sdf.load(sdf=str(urdf_path), is_urdf=None)
_ = rod.Sdf.load(sdf=str(urdf_path), is_urdf=True)
_ = rod.Sdf.load(sdf=urdf_path.read_text(), is_urdf=True)
_ = rod.Sdf.load(
sdf="<robot name='minimal_robot'> \
<link name='base_link'/> \
<joint name='base_to_link1' type='continuous'> \
<parent link='base_link'/> \
<child link='link1'/> \
<origin xyz='0 0 1' rpy='0 0 0'/> \
</joint> \
<link name='link1'/> \
</robot> \
"
)

# Load once again the urdf
rod_sdf = rod.Sdf.load(sdf=urdf_path)
Expand Down

0 comments on commit d931d20

Please sign in to comment.