Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding the possibility to load both from string and path #74

Merged
merged 9 commits into from
Jul 2, 2024
2 changes: 1 addition & 1 deletion src/adam/casadi/computations.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def __init__(
) -> None:
"""
Args:
urdfstring (str): path of the urdf
urdfstring (str): either path or string of the urdf
joints_name_list (list): list of the actuated joints
root_link (str, optional): the first link. Defaults to 'root_link'.
"""
Expand Down
2 changes: 1 addition & 1 deletion src/adam/jax/computations.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(
) -> None:
"""
Args:
urdfstring (str): path of the urdf
urdfstring (str): either path or string of the urdf
joints_name_list (list): list of the actuated joints
root_link (str, optional): the first link. Defaults to 'root_link'.
"""
Expand Down
44 changes: 37 additions & 7 deletions src/adam/model/std_factories/std_model.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pathlib
from typing import List
import xml.etree.ElementTree as ET

import os
import urdf_parser_py.urdf

from adam.core.spatial_math import SpatialMath
Expand All @@ -23,19 +23,50 @@ def urdf_remove_sensors_tags(xml_string):
return modified_xml_string


def get_xml_string(path: str):
isPath = False
isUrdf = False
# Checking if it is a path or an urdf
if type(path) is not (pathlib.Path):
if os.path.exists(path):
path = pathlib.Path(path)
isPath = True
else:
root = ET.fromstring(path)
robot_el = None
for elem in root.iter():
if elem.tag == "robot":
xml_string = path
isUrdf = True
elif path.exists():
isPath = True

if not (isPath) and not (isUrdf):
raise ValueError(
f"Invalid urdf string: {path}. It is neither a path nor a urdf string"
)

if isPath:
if not (path.exists()):
raise FileExistsError(path)
path = pathlib.Path(path)
with open(path, "r") as xml_file:
xml_string = xml_file.read()
xml_file.close()
return xml_string


class URDFModelFactory(ModelFactory):
"""This factory generates robot elements from urdf_parser_py

Args:
ModelFactory: the Model factory
"""

# TODO: path can be either a path and an urdf-string, leaving path for back compatibility, to be changed to meaningfull name
def __init__(self, path: str, math: SpatialMath):
self.math = math
if type(path) is not pathlib.Path:
path = pathlib.Path(path)
if not path.exists():
raise FileExistsError(path)
xml_string = get_xml_string(path)

# Read URDF, but before passing it to urdf_parser_py get rid of all sensor tags
# sensor tags are valid elements of URDF (see ),
Expand All @@ -44,8 +75,7 @@ def __init__(self, path: str, math: SpatialMath):
# to have a useless and noisy warning, let's remove before hands all the sensor elements,
# that anyhow are not parser by urdf_parser_py or adam
# See https://github.com/ami-iit/ADAM/issues/59
with open(path, "r") as xml_file:
xml_string = xml_file.read()

xml_string_without_sensors_tags = urdf_remove_sensors_tags(xml_string)
self.urdf_desc = urdf_parser_py.urdf.URDF.from_xml_string(
xml_string_without_sensors_tags
Expand Down
2 changes: 1 addition & 1 deletion src/adam/numpy/computations.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __init__(
) -> None:
"""
Args:
urdfstring (str): path of the urdf
urdfstring (str): either path or string of the urdf
joints_name_list (list): list of the actuated joints
root_link (str, optional): the first link. Defaults to 'root_link'.
"""
Expand Down
2 changes: 1 addition & 1 deletion src/adam/parametric/casadi/computations_parametric.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def __init__(
) -> None:
"""
Args:
urdfstring (str): path of the urdf
urdfstring (str): either path or string of the urdf
joints_name_list (list): list of the actuated joints
links_name_list (list): list of the parametrized links
root_link (str, optional): the first link. Defaults to 'root_link'.
Expand Down
2 changes: 1 addition & 1 deletion src/adam/parametric/jax/computations_parametric.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def __init__(
) -> None:
"""
Args:
urdfstring (str): path of the urdf
urdfstring (str): either path or string of the urdf
joints_name_list (list): list of the actuated joints
links_name_list (list): list of parametric links
root_link (str, optional): the first link. Defaults to 'root_link'.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import pathlib
from typing import List
import os

import urdf_parser_py.urdf
from adam.core.spatial_math import SpatialMath
from adam.model import ModelFactory, StdJoint, StdLink, Link, Joint
from adam.model.std_factories.std_model import urdf_remove_sensors_tags
from adam.model.std_factories.std_model import urdf_remove_sensors_tags, get_xml_string
from adam.parametric.model import ParametricJoint, ParametricLink


Expand All @@ -15,6 +16,7 @@ class URDFParametricModelFactory(ModelFactory):
ModelFactory: the Model factory
"""

# TODO: path can be either a path and an urdf-string, leaving path for back compatibility, to be changed to meaningfull name
def __init__(
self,
path: str,
Expand All @@ -24,10 +26,7 @@ def __init__(
densities,
):
self.math = math
if type(path) is not pathlib.Path:
path = pathlib.Path(path)
if not path.exists():
raise FileExistsError(path)
xml_string = get_xml_string(path)
self.links_name_list = links_name_list

# Read URDF, but before passing it to urdf_parser_py get rid of all sensor tags
Expand All @@ -37,9 +36,6 @@ def __init__(
# to have a useless and noisy warning, let's remove before hands all the sensor elements,
# that anyhow are not parser by urdf_parser_py or adam
# See https://github.com/ami-iit/ADAM/issues/59
xml_file = open(path, "r")
xml_string = xml_file.read()
xml_file.close()
xml_string_without_sensors_tags = urdf_remove_sensors_tags(xml_string)

self.urdf_desc = urdf_parser_py.urdf.URDF.from_xml_string(
Expand Down
2 changes: 1 addition & 1 deletion src/adam/parametric/numpy/computations_parametric.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def __init__(
) -> None:
"""
Args:
urdfstring (str): path of the urdf
urdfstring (str): either path or string of the urdf
joints_name_list (list): list of the actuated joints
links_name_list (list): list of parametric links
root_link (str, optional): the first link. Defaults to 'root_link'.
Expand Down
2 changes: 1 addition & 1 deletion src/adam/parametric/pytorch/computations_parametric.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def __init__(
) -> None:
"""
Args:
urdfstring (str): path of the urdf
urdfstring (str): either path or string of the urdf
joints_name_list (list): list of the actuated joints
links_name_list (list): list of parametric links
root_link (str, optional): the first link. Defaults to 'root_link'.
Expand Down
2 changes: 1 addition & 1 deletion src/adam/pytorch/computations.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def __init__(
) -> None:
"""
Args:
urdfstring (str): path of the urdf
urdfstring (str): either path or string of the urdf
joints_name_list (list): list of the actuated joints
root_link (str, optional): the first link. Defaults to 'root_link'.
"""
Expand Down
Loading