From 58eda3180662561b8c8aa2c21d9fab30b920432c Mon Sep 17 00:00:00 2001 From: Carlotta Date: Thu, 18 Apr 2024 18:31:56 +0200 Subject: [PATCH 1/8] adding the possibility to load both from string and path --- src/adam/casadi/computations.py | 4 +-- src/adam/jax/computations.py | 4 +-- src/adam/model/std_factories/std_model.py | 40 +++++++++++++++++------ src/adam/numpy/computations.py | 2 +- src/adam/pytorch/computations.py | 2 +- 5 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/adam/casadi/computations.py b/src/adam/casadi/computations.py index eab62718..6b3c9836 100644 --- a/src/adam/casadi/computations.py +++ b/src/adam/casadi/computations.py @@ -27,12 +27,12 @@ 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'. """ math = SpatialMath() - factory = URDFModelFactory(path=urdfstring, math=math) + factory = URDFModelFactory(urdf_string=urdfstring, math=math) model = Model.build(factory=factory, joints_name_list=joints_name_list) self.rbdalgos = RBDAlgorithms(model=model, math=math) self.NDoF = self.rbdalgos.NDoF diff --git a/src/adam/jax/computations.py b/src/adam/jax/computations.py index 2f68d092..e49aa8cb 100644 --- a/src/adam/jax/computations.py +++ b/src/adam/jax/computations.py @@ -25,12 +25,12 @@ 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'. """ math = SpatialMath() - factory = URDFModelFactory(path=urdfstring, math=math) + factory = URDFModelFactory(urdf_string=urdfstring, math=math) model = Model.build(factory=factory, joints_name_list=joints_name_list) self.rbdalgos = RBDAlgorithms(model=model, math=math) self.NDoF = self.rbdalgos.NDoF diff --git a/src/adam/model/std_factories/std_model.py b/src/adam/model/std_factories/std_model.py index ffeff713..0555159e 100644 --- a/src/adam/model/std_factories/std_model.py +++ b/src/adam/model/std_factories/std_model.py @@ -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 @@ -30,13 +30,36 @@ class URDFModelFactory(ModelFactory): ModelFactory: the Model factory """ - def __init__(self, path: str, math: SpatialMath): + def __init__(self, urdf_string: str, math: SpatialMath): self.math = math - if type(path) is not pathlib.Path: - path = pathlib.Path(path) - if not path.exists(): - raise FileExistsError(path) - + isPath = False + isUrdf = False + # Checking if it is a path or an urdf + if(type(urdf_string) is not(pathlib.Path)): + if(os.path.exists(urdf_string)): + urdf_string = pathlib.Path(urdf_string) + isPath= True + else: + root = ET.fromstring(urdf_string) + robot_el = None + for elem in root.iter(): + if elem.tag == "robot": + xml_string = urdf_string + isUrdf = True + # raise ValueError(f"Invalid urdf string: {urdf_string}. It is neither a path nor a urdf string") + elif urdf_string.exists(): + isPath = True + + if(not(isPath) and not(isUrdf)): + raise ValueError(f"Invalid urdf string: {urdf_string}. It is neither a path nor a urdf string") + + if(isPath): + if(not(urdf_string.exists())): + raise FileExistsError(path) + urdf_string = pathlib.Path(urdf_string) + xml_file = open(urdf_string, "r") + xml_string = xml_file.read() + xml_file.close() # Read URDF, but before passing it to urdf_parser_py get rid of all sensor tags # sensor tags are valid elements of URDF (see ), # but they are ignored by urdf_parser_py, that complains every time it sees one. @@ -44,9 +67,6 @@ 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 - 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( xml_string_without_sensors_tags diff --git a/src/adam/numpy/computations.py b/src/adam/numpy/computations.py index ad531f08..9893bb60 100644 --- a/src/adam/numpy/computations.py +++ b/src/adam/numpy/computations.py @@ -29,7 +29,7 @@ def __init__( root_link (str, optional): the first link. Defaults to 'root_link'. """ math = SpatialMath() - factory = URDFModelFactory(path=urdfstring, math=math) + factory = URDFModelFactory(urdf_string=urdfstring, math=math) model = Model.build(factory=factory, joints_name_list=joints_name_list) self.rbdalgos = RBDAlgorithms(model=model, math=math) self.NDoF = model.NDoF diff --git a/src/adam/pytorch/computations.py b/src/adam/pytorch/computations.py index e81c48be..ad64cc4d 100644 --- a/src/adam/pytorch/computations.py +++ b/src/adam/pytorch/computations.py @@ -32,7 +32,7 @@ def __init__( root_link (str, optional): the first link. Defaults to 'root_link'. """ math = SpatialMath() - factory = URDFModelFactory(path=urdfstring, math=math) + factory = URDFModelFactory(urdf_string=urdfstring, math=math) model = Model.build(factory=factory, joints_name_list=joints_name_list) self.rbdalgos = RBDAlgorithms(model=model, math=math) self.NDoF = self.rbdalgos.NDoF From ccf061e51d299e464c2237254d9dcc1b08900531 Mon Sep 17 00:00:00 2001 From: Carlotta Date: Thu, 18 Apr 2024 18:38:30 +0200 Subject: [PATCH 2/8] balck formatting --- src/adam/casadi/computations.py | 2 +- src/adam/model/std_factories/std_model.py | 26 ++++++++++--------- .../parametric_factories/parametric_link.py | 4 +-- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/adam/casadi/computations.py b/src/adam/casadi/computations.py index 6b3c9836..ca7a9e8d 100644 --- a/src/adam/casadi/computations.py +++ b/src/adam/casadi/computations.py @@ -27,7 +27,7 @@ def __init__( ) -> None: """ Args: - urdfstring (str): either path or string 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'. """ diff --git a/src/adam/model/std_factories/std_model.py b/src/adam/model/std_factories/std_model.py index 0555159e..11f81e55 100644 --- a/src/adam/model/std_factories/std_model.py +++ b/src/adam/model/std_factories/std_model.py @@ -1,7 +1,7 @@ import pathlib from typing import List import xml.etree.ElementTree as ET -import os +import os import urdf_parser_py.urdf from adam.core.spatial_math import SpatialMath @@ -34,12 +34,12 @@ def __init__(self, urdf_string: str, math: SpatialMath): self.math = math isPath = False isUrdf = False - # Checking if it is a path or an urdf - if(type(urdf_string) is not(pathlib.Path)): - if(os.path.exists(urdf_string)): + # Checking if it is a path or an urdf + if type(urdf_string) is not (pathlib.Path): + if os.path.exists(urdf_string): urdf_string = pathlib.Path(urdf_string) - isPath= True - else: + isPath = True + else: root = ET.fromstring(urdf_string) robot_el = None for elem in root.iter(): @@ -50,16 +50,18 @@ def __init__(self, urdf_string: str, math: SpatialMath): elif urdf_string.exists(): isPath = True - if(not(isPath) and not(isUrdf)): - raise ValueError(f"Invalid urdf string: {urdf_string}. It is neither a path nor a urdf string") - - if(isPath): - if(not(urdf_string.exists())): + if not (isPath) and not (isUrdf): + raise ValueError( + f"Invalid urdf string: {urdf_string}. It is neither a path nor a urdf string" + ) + + if isPath: + if not (urdf_string.exists()): raise FileExistsError(path) urdf_string = pathlib.Path(urdf_string) xml_file = open(urdf_string, "r") xml_string = xml_file.read() - xml_file.close() + xml_file.close() # Read URDF, but before passing it to urdf_parser_py get rid of all sensor tags # sensor tags are valid elements of URDF (see ), # but they are ignored by urdf_parser_py, that complains every time it sees one. diff --git a/src/adam/parametric/model/parametric_factories/parametric_link.py b/src/adam/parametric/model/parametric_factories/parametric_link.py index c9ae02be..cfdf729f 100644 --- a/src/adam/parametric/model/parametric_factories/parametric_link.py +++ b/src/adam/parametric/model/parametric_factories/parametric_link.py @@ -162,7 +162,7 @@ def compute_volume(self, length_multiplier): volume = math.pi * visual_data_new[1] ** 2 * visual_data_new[0] elif self.geometry_type == Geometry.SPHERE: visual_data_new = self.visual_data.radius * length_multiplier - volume = 4 * math.pi * visual_data_new**3 / 3 + volume = 4 * math.pi * visual_data_new ** 3 / 3 return volume, visual_data_new def compute_mass(self): @@ -235,7 +235,7 @@ def compute_inertia_parametric(self): I.izz = I.iyy return I elif self.geometry_type == Geometry.SPHERE: - I.ixx = 2 * self.mass * self.visual_data_new**2 / 5 + I.ixx = 2 * self.mass * self.visual_data_new ** 2 / 5 I.iyy = I.ixx I.izz = I.ixx return I From c2a8fc20d22671a246d66df90d59c8c1e07f23b5 Mon Sep 17 00:00:00 2001 From: Carlotta Date: Mon, 10 Jun 2024 15:03:27 +0200 Subject: [PATCH 3/8] Chang eback to path name for back compatibilty, port modifications to parmatetrci --- src/adam/casadi/computations.py | 2 +- src/adam/jax/computations.py | 2 +- src/adam/model/std_factories/std_model.py | 5 ++--- src/adam/numpy/computations.py | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/adam/casadi/computations.py b/src/adam/casadi/computations.py index ca7a9e8d..58ff04a1 100644 --- a/src/adam/casadi/computations.py +++ b/src/adam/casadi/computations.py @@ -32,7 +32,7 @@ def __init__( root_link (str, optional): the first link. Defaults to 'root_link'. """ math = SpatialMath() - factory = URDFModelFactory(urdf_string=urdfstring, math=math) + factory = URDFModelFactory(path=urdfstring, math=math) model = Model.build(factory=factory, joints_name_list=joints_name_list) self.rbdalgos = RBDAlgorithms(model=model, math=math) self.NDoF = self.rbdalgos.NDoF diff --git a/src/adam/jax/computations.py b/src/adam/jax/computations.py index e49aa8cb..dd374e43 100644 --- a/src/adam/jax/computations.py +++ b/src/adam/jax/computations.py @@ -30,7 +30,7 @@ def __init__( root_link (str, optional): the first link. Defaults to 'root_link'. """ math = SpatialMath() - factory = URDFModelFactory(urdf_string=urdfstring, math=math) + factory = URDFModelFactory(path=urdfstring, math=math) model = Model.build(factory=factory, joints_name_list=joints_name_list) self.rbdalgos = RBDAlgorithms(model=model, math=math) self.NDoF = self.rbdalgos.NDoF diff --git a/src/adam/model/std_factories/std_model.py b/src/adam/model/std_factories/std_model.py index 11f81e55..b849b450 100644 --- a/src/adam/model/std_factories/std_model.py +++ b/src/adam/model/std_factories/std_model.py @@ -29,8 +29,8 @@ class URDFModelFactory(ModelFactory): Args: ModelFactory: the Model factory """ - - def __init__(self, urdf_string: str, math: SpatialMath): + #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 isPath = False isUrdf = False @@ -46,7 +46,6 @@ def __init__(self, urdf_string: str, math: SpatialMath): if elem.tag == "robot": xml_string = urdf_string isUrdf = True - # raise ValueError(f"Invalid urdf string: {urdf_string}. It is neither a path nor a urdf string") elif urdf_string.exists(): isPath = True diff --git a/src/adam/numpy/computations.py b/src/adam/numpy/computations.py index 9893bb60..ad531f08 100644 --- a/src/adam/numpy/computations.py +++ b/src/adam/numpy/computations.py @@ -29,7 +29,7 @@ def __init__( root_link (str, optional): the first link. Defaults to 'root_link'. """ math = SpatialMath() - factory = URDFModelFactory(urdf_string=urdfstring, math=math) + factory = URDFModelFactory(path=urdfstring, math=math) model = Model.build(factory=factory, joints_name_list=joints_name_list) self.rbdalgos = RBDAlgorithms(model=model, math=math) self.NDoF = model.NDoF From 4e10ef46f8cb25b576db5cb64a125864cb686cd4 Mon Sep 17 00:00:00 2001 From: Carlotta Date: Mon, 10 Jun 2024 15:04:56 +0200 Subject: [PATCH 4/8] black formatting --- src/adam/model/std_factories/std_model.py | 3 +- .../parametric_factories/parametric_link.py | 4 +- .../parametric_factories/parametric_model.py | 37 +++++++++++++++---- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/adam/model/std_factories/std_model.py b/src/adam/model/std_factories/std_model.py index b849b450..335d65e6 100644 --- a/src/adam/model/std_factories/std_model.py +++ b/src/adam/model/std_factories/std_model.py @@ -29,7 +29,8 @@ class URDFModelFactory(ModelFactory): 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 + + # 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 isPath = False diff --git a/src/adam/parametric/model/parametric_factories/parametric_link.py b/src/adam/parametric/model/parametric_factories/parametric_link.py index cfdf729f..c9ae02be 100644 --- a/src/adam/parametric/model/parametric_factories/parametric_link.py +++ b/src/adam/parametric/model/parametric_factories/parametric_link.py @@ -162,7 +162,7 @@ def compute_volume(self, length_multiplier): volume = math.pi * visual_data_new[1] ** 2 * visual_data_new[0] elif self.geometry_type == Geometry.SPHERE: visual_data_new = self.visual_data.radius * length_multiplier - volume = 4 * math.pi * visual_data_new ** 3 / 3 + volume = 4 * math.pi * visual_data_new**3 / 3 return volume, visual_data_new def compute_mass(self): @@ -235,7 +235,7 @@ def compute_inertia_parametric(self): I.izz = I.iyy return I elif self.geometry_type == Geometry.SPHERE: - I.ixx = 2 * self.mass * self.visual_data_new ** 2 / 5 + I.ixx = 2 * self.mass * self.visual_data_new**2 / 5 I.iyy = I.ixx I.izz = I.ixx return I diff --git a/src/adam/parametric/model/parametric_factories/parametric_model.py b/src/adam/parametric/model/parametric_factories/parametric_model.py index 5c2a2092..2e0ab4a6 100644 --- a/src/adam/parametric/model/parametric_factories/parametric_model.py +++ b/src/adam/parametric/model/parametric_factories/parametric_model.py @@ -15,6 +15,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, @@ -24,10 +25,35 @@ def __init__( densities, ): self.math = math - if type(path) is not pathlib.Path: - path = pathlib.Path(path) - if not path.exists(): - raise FileExistsError(path) + isPath = False + isUrdf = False + # Checking if it is a path or an urdf + if type(urdf_string) is not (pathlib.Path): + if os.path.exists(urdf_string): + urdf_string = pathlib.Path(urdf_string) + isPath = True + else: + root = ET.fromstring(urdf_string) + robot_el = None + for elem in root.iter(): + if elem.tag == "robot": + xml_string = urdf_string + isUrdf = True + elif urdf_string.exists(): + isPath = True + + if not (isPath) and not (isUrdf): + raise ValueError( + f"Invalid urdf string: {urdf_string}. It is neither a path nor a urdf string" + ) + + if isPath: + if not (urdf_string.exists()): + raise FileExistsError(path) + urdf_string = pathlib.Path(urdf_string) + xml_file = open(urdf_string, "r") + xml_string = xml_file.read() + xml_file.close() self.links_name_list = links_name_list # Read URDF, but before passing it to urdf_parser_py get rid of all sensor tags @@ -37,9 +63,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( From 7ea5b2673330a492cbbe155e87f3f39652295289 Mon Sep 17 00:00:00 2001 From: Carlotta Date: Mon, 10 Jun 2024 15:09:15 +0200 Subject: [PATCH 5/8] fix documentation --- src/adam/numpy/computations.py | 2 +- src/adam/parametric/casadi/computations_parametric.py | 2 +- src/adam/parametric/jax/computations_parametric.py | 2 +- src/adam/parametric/numpy/computations_parametric.py | 2 +- src/adam/parametric/pytorch/computations_parametric.py | 2 +- src/adam/pytorch/computations.py | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/adam/numpy/computations.py b/src/adam/numpy/computations.py index ad531f08..e6483d6e 100644 --- a/src/adam/numpy/computations.py +++ b/src/adam/numpy/computations.py @@ -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'. """ diff --git a/src/adam/parametric/casadi/computations_parametric.py b/src/adam/parametric/casadi/computations_parametric.py index 37459821..a6f44021 100644 --- a/src/adam/parametric/casadi/computations_parametric.py +++ b/src/adam/parametric/casadi/computations_parametric.py @@ -29,7 +29,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'. diff --git a/src/adam/parametric/jax/computations_parametric.py b/src/adam/parametric/jax/computations_parametric.py index 42865f00..2750e194 100644 --- a/src/adam/parametric/jax/computations_parametric.py +++ b/src/adam/parametric/jax/computations_parametric.py @@ -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'. diff --git a/src/adam/parametric/numpy/computations_parametric.py b/src/adam/parametric/numpy/computations_parametric.py index 66c5be91..8e5748d9 100644 --- a/src/adam/parametric/numpy/computations_parametric.py +++ b/src/adam/parametric/numpy/computations_parametric.py @@ -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'. diff --git a/src/adam/parametric/pytorch/computations_parametric.py b/src/adam/parametric/pytorch/computations_parametric.py index 03c2f80b..9472dcd0 100644 --- a/src/adam/parametric/pytorch/computations_parametric.py +++ b/src/adam/parametric/pytorch/computations_parametric.py @@ -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'. diff --git a/src/adam/pytorch/computations.py b/src/adam/pytorch/computations.py index ad64cc4d..1c314bcb 100644 --- a/src/adam/pytorch/computations.py +++ b/src/adam/pytorch/computations.py @@ -27,12 +27,12 @@ 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'. """ math = SpatialMath() - factory = URDFModelFactory(urdf_string=urdfstring, math=math) + factory = URDFModelFactory(path=urdfstring, math=math) model = Model.build(factory=factory, joints_name_list=joints_name_list) self.rbdalgos = RBDAlgorithms(model=model, math=math) self.NDoF = self.rbdalgos.NDoF From 25096abd102937161a46d00950ecceb3bfa849f5 Mon Sep 17 00:00:00 2001 From: Carlotta Date: Mon, 10 Jun 2024 15:14:09 +0200 Subject: [PATCH 6/8] restore path name --- src/adam/model/std_factories/std_model.py | 20 +++++++++---------- .../parametric_factories/parametric_model.py | 20 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/adam/model/std_factories/std_model.py b/src/adam/model/std_factories/std_model.py index 335d65e6..ed379af7 100644 --- a/src/adam/model/std_factories/std_model.py +++ b/src/adam/model/std_factories/std_model.py @@ -36,30 +36,30 @@ def __init__(self, path: str, math: SpatialMath): isPath = False isUrdf = False # Checking if it is a path or an urdf - if type(urdf_string) is not (pathlib.Path): - if os.path.exists(urdf_string): - urdf_string = pathlib.Path(urdf_string) + if type(path) is not (pathlib.Path): + if os.path.exists(path): + path = pathlib.Path(path) isPath = True else: - root = ET.fromstring(urdf_string) + root = ET.fromstring(path) robot_el = None for elem in root.iter(): if elem.tag == "robot": - xml_string = urdf_string + xml_string = path isUrdf = True - elif urdf_string.exists(): + elif path.exists(): isPath = True if not (isPath) and not (isUrdf): raise ValueError( - f"Invalid urdf string: {urdf_string}. It is neither a path nor a urdf string" + f"Invalid urdf string: {path}. It is neither a path nor a urdf string" ) if isPath: - if not (urdf_string.exists()): + if not (path.exists()): raise FileExistsError(path) - urdf_string = pathlib.Path(urdf_string) - xml_file = open(urdf_string, "r") + path = pathlib.Path(path) + xml_file = open(path, "r") xml_string = xml_file.read() xml_file.close() # Read URDF, but before passing it to urdf_parser_py get rid of all sensor tags diff --git a/src/adam/parametric/model/parametric_factories/parametric_model.py b/src/adam/parametric/model/parametric_factories/parametric_model.py index 2e0ab4a6..048ff40e 100644 --- a/src/adam/parametric/model/parametric_factories/parametric_model.py +++ b/src/adam/parametric/model/parametric_factories/parametric_model.py @@ -28,30 +28,30 @@ def __init__( isPath = False isUrdf = False # Checking if it is a path or an urdf - if type(urdf_string) is not (pathlib.Path): - if os.path.exists(urdf_string): - urdf_string = pathlib.Path(urdf_string) + if type(path) is not (pathlib.Path): + if os.path.exists(path): + path = pathlib.Path(path) isPath = True else: - root = ET.fromstring(urdf_string) + root = ET.fromstring(path) robot_el = None for elem in root.iter(): if elem.tag == "robot": - xml_string = urdf_string + xml_string = path isUrdf = True - elif urdf_string.exists(): + elif path.exists(): isPath = True if not (isPath) and not (isUrdf): raise ValueError( - f"Invalid urdf string: {urdf_string}. It is neither a path nor a urdf string" + f"Invalid urdf string: {path}. It is neither a path nor a urdf string" ) if isPath: - if not (urdf_string.exists()): + if not (path.exists()): raise FileExistsError(path) - urdf_string = pathlib.Path(urdf_string) - xml_file = open(urdf_string, "r") + path = pathlib.Path(path) + xml_file = open(path, "r") xml_string = xml_file.read() xml_file.close() self.links_name_list = links_name_list From 8e454ce0f0ba82486c947dbdeedf7cf7ca3c4161 Mon Sep 17 00:00:00 2001 From: Carlotta Date: Mon, 10 Jun 2024 15:17:08 +0200 Subject: [PATCH 7/8] added import os --- .../parametric/model/parametric_factories/parametric_model.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/adam/parametric/model/parametric_factories/parametric_model.py b/src/adam/parametric/model/parametric_factories/parametric_model.py index 048ff40e..de674927 100644 --- a/src/adam/parametric/model/parametric_factories/parametric_model.py +++ b/src/adam/parametric/model/parametric_factories/parametric_model.py @@ -1,5 +1,6 @@ import pathlib from typing import List +import os import urdf_parser_py.urdf from adam.core.spatial_math import SpatialMath From 172661816c0ee6002455da5c56f41d7206e28d11 Mon Sep 17 00:00:00 2001 From: Carlotta Date: Tue, 2 Jul 2024 15:06:25 +0200 Subject: [PATCH 8/8] wrap in a function code for loading xml string and urdf path --- src/adam/model/std_factories/std_model.py | 65 ++++++++++--------- .../parametric_factories/parametric_model.py | 32 +-------- 2 files changed, 37 insertions(+), 60 deletions(-) diff --git a/src/adam/model/std_factories/std_model.py b/src/adam/model/std_factories/std_model.py index ded6bff5..3649a0b1 100644 --- a/src/adam/model/std_factories/std_model.py +++ b/src/adam/model/std_factories/std_model.py @@ -23,6 +23,39 @@ 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 @@ -33,35 +66,8 @@ class URDFModelFactory(ModelFactory): # 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 - 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" - ) + xml_string = get_xml_string(path) - if isPath: - if not (path.exists()): - raise FileExistsError(path) - path = pathlib.Path(path) - xml_file = open(path, "r") - xml_string = xml_file.read() - xml_file.close() # Read URDF, but before passing it to urdf_parser_py get rid of all sensor tags # sensor tags are valid elements of URDF (see ), # but they are ignored by urdf_parser_py, that complains every time it sees one. @@ -69,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 diff --git a/src/adam/parametric/model/parametric_factories/parametric_model.py b/src/adam/parametric/model/parametric_factories/parametric_model.py index de674927..3702735e 100644 --- a/src/adam/parametric/model/parametric_factories/parametric_model.py +++ b/src/adam/parametric/model/parametric_factories/parametric_model.py @@ -5,7 +5,7 @@ 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 @@ -26,35 +26,7 @@ def __init__( densities, ): self.math = math - 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) - xml_file = open(path, "r") - xml_string = xml_file.read() - xml_file.close() + 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