Git Product home page Git Product logo

yourdfpy's Introduction

Build Status Documentation Status Coverage Status PyPI version

yourdfpy

Yet anOther URDF parser for Python. Yup, it's another one. Deal with it.

Yourdfpy is a simpler and easier-to-use library for loading, manipulating, validating, saving, and visualizing URDF files.

Installation

You can install yourdfpy directly from pip:

pip install yourdfpy

Visualization

Once installed, you can visualize a URDF model from the command line:

yourdfpy ./my_description/urdf/robot.urdf

You can use the following keyboard shortcuts to inspect your model:

  • a: Toggle rendered XYZ/RGB axis markers (off, world frame, every frame)
  • w: Toggle wireframe mode (good for looking inside meshes, off by default)
  • c: Toggle back face culling (on by default but in wireframe mode it is sometimes useful to see the back sides)

But why another one?!?

Why are you wasting not only your but also our time? you might ask. Fair point. There are already urdfpy and urdf_parser_py that deal with URDFs. Unfortunately, none of these solutions allow customizable URDF parsing that is fully independent of validation and mesh loading. Dealing with filenames, outdated dependencies, open bug reports, and limited flexibility when it comes to serialization are other disadvantages. As shown in the table below, yourdfpy is the most robust one when it comes to loading URDFs in the wild.

Example URDFs

urdfpy urdf_parser_py yourdfpy
Decouple parsing from validation ✔️
Decouple parsing from loading meshes ✔️ ✔️
Visualize URDF ✔️ ✔️
Forward Kinematics ✔️ ✔️
Robustness test: loading 12 URDF files from here 4/12 6/12 12/12
Avg. loading time per file (w/ mesh loading) 480 ms 370 ms
(w/o mesh loading) 3.2 ms 6.2 ms
Test on 4 URDF files on which urdfpy succeeds 347.5 ms 203 ms
Test on 6 URDF files on which urdf_parser_py succeeds 2.6 ms 3.8 ms
Click to expand code listing that produces the above table entries.
robot_assets = ['robot-assets/urdfs/robots/barret_hand/bhand_model.URDF', 'robot-assets/urdfs/robots/robotiq_gripper/robotiq_arg85_description.URDF', 'robot-assets/urdfs/robots/anymal/anymal.urdf', 'robot-assets/urdfs/robots/franka_panda/panda.urdf', 'robot-assets/urdfs/robots/ginger_robot/gingerurdf.urdf', 'robot-assets/urdfs/robots/halodi/eve_r3.urdf', 'robot-assets/urdfs/robots/kinova/kinova.urdf', 'robot-assets/urdfs/robots/kuka_iiwa/model.urdf', 'robot-assets/urdfs/robots/pr2/pr2.urdf', 'robot-assets/urdfs/robots/ur10/ur10_robot.urdf', 'robot-assets/urdfs/robots/ur5/ur5_gripper.urdf', 'robot-assets/urdfs/robots/yumi/yumi.urdf']

import urdfpy
import urdf_parser_py
import yourdfpy

from functools import partial

def load_urdfs(fnames, load_fn):
    results = {fname: None for fname in fnames}
    for fname in fnames:
        try:
            x = load_fn(fname)
            results[fname] = x
        except:
            print("Problems loading: ", fname)
            pass
    print(sum([1 for x, y in results.items() if y is not None]), "/", len(fnames))
    return results

# parsing success rate
load_urdfs(robot_assets, urdfpy.URDF.load)
load_urdfs(robot_assets, urdf_parser_py.urdf.URDF.load)
load_urdfs(robot_assets, yourdfpy.URDF.load)

# parsing times
%timeit load_urdfs(robot_assets, urdfpy.URDF.load)
%timeit load_urdfs(robot_assets, urdf_parser_py.urdf.URDF.load)
%timeit load_urdfs(robot_assets, yourdfpy.URDF.load)
%timeit load_urdfs(robot_assets, partial(yourdfpy.URDF.load, load_meshes=False, build_scene_graph=False))

# fairer comparison with yourdfpy
urdfpy_fnames = [x for x, y in load_urdfs(robot_assets, urdfpy.URDF.load).items() if y is not None]
%timeit load_urdfs(urdfpy_fnames, yourdfpy.URDF.load)

# fairer comparison with urdf_parser_py
urdfparser_fnames = [x for x, y in load_urdfs(robot_assets, urdf_parser_py.urdf.URDF.from_xml_file).items() if y is not None]
%timeit load_urdfs(urdfparser_fnames, functools.partial(yourdfpy.URDF.load, load_meshes=False, build_scene_graph=False))

yourdfpy's People

Contributors

clemense avatar skylion007 avatar stephane-caron avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

yourdfpy's Issues

Issue with FK in the presence of <mimic> joint tags

For example, for a Franka Panda robot: https://github.com/caelan/pybullet-planning/blob/b280cfc578479309a15a5e4023a1bacf29eb25ee/models/franka_description/robots/panda_arm_hand.urdf#L222

Note that the error disappears when I remove the tag

File "/home/caelan/Programs/SRL/srl/venv/lib/python3.7/site-packages/yourdfpy/urdf.py", line 776, in load return URDF(robot=URDF._parse_robot(xml_element=xml_root), **kwargs) File "/home/caelan/Programs/SRL/srl/venv/lib/python3.7/site-packages/yourdfpy/urdf.py", line 440, in __init__ force_single_geometry_per_link=force_mesh, File "/home/caelan/Programs/SRL/srl/venv/lib/python3.7/site-packages/yourdfpy/urdf.py", line 1077, in _create_scene matrix, _ = self._forward_kinematics_joint(j) File "/home/caelan/Programs/SRL/srl/venv/lib/python3.7/site-packages/yourdfpy/urdf.py", line 837, in _forward_kinematics_joint self._cfg[mimic_joint_index] * joint.mimic.multiplier IndexError: index 9 is out of bounds for axis 0 with size 8

ValueError on some models when meshes fail to load

For instance on this model, yourdf yields the error below.

This is probably because the scene is empty when meshes are not found. (One symptom is that self._scene.bounds_corners is empty, thus its extents and scale cannot be computed.) If that's the case yourdf could report a more explicit error to users.

$ yourdfpy ./finger_edu.urdf
[2022-04-12 09:00:52] WARNING:yourdfpy.urdf:Unable to resolve filename: package://example-robot-data/robots/finger_edu_description/meshes/base_back.stl
[2022-04-12 09:00:52] WARNING:yourdfpy.urdf:Can't find package://example-robot-data/robots/finger_edu_description/meshes/base_back.stl
[2022-04-12 09:00:52] WARNING:yourdfpy.urdf:Unable to resolve filename: package://example-robot-data/robots/finger_edu_description/meshes/base_front.stl
[2022-04-12 09:00:52] WARNING:yourdfpy.urdf:Can't find package://example-robot-data/robots/finger_edu_description/meshes/base_front.stl
[2022-04-12 09:00:52] WARNING:yourdfpy.urdf:Unable to resolve filename: package://example-robot-data/robots/finger_edu_description/meshes/base_side_left.stl
[2022-04-12 09:00:52] WARNING:yourdfpy.urdf:Can't find package://example-robot-data/robots/finger_edu_description/meshes/base_side_left.stl
[2022-04-12 09:00:52] WARNING:yourdfpy.urdf:Unable to resolve filename: package://example-robot-data/robots/finger_edu_description/meshes/base_top.stl
[2022-04-12 09:00:52] WARNING:yourdfpy.urdf:Can't find package://example-robot-data/robots/finger_edu_description/meshes/base_top.stl
[2022-04-12 09:00:52] WARNING:yourdfpy.urdf:Unable to resolve filename: package://example-robot-data/robots/finger_edu_description/meshes/upper_link.stl
[2022-04-12 09:00:52] WARNING:yourdfpy.urdf:Can't find package://example-robot-data/robots/finger_edu_description/meshes/upper_link.stl
[2022-04-12 09:00:52] WARNING:yourdfpy.urdf:Unable to resolve filename: package://example-robot-data/robots/finger_edu_description/meshes/middle_link.stl
[2022-04-12 09:00:52] WARNING:yourdfpy.urdf:Can't find package://example-robot-data/robots/finger_edu_description/meshes/middle_link.stl
[2022-04-12 09:00:52] WARNING:yourdfpy.urdf:Unable to resolve filename: package://example-robot-data/robots/finger_edu_description/meshes/lower_link.stl
[2022-04-12 09:00:52] WARNING:yourdfpy.urdf:Can't find package://example-robot-data/robots/finger_edu_description/meshes/lower_link.stl
Traceback (most recent call last):
  File "/home/nelson/.local/bin/yourdfpy", line 8, in <module>
    sys.exit(run())
  File "/home/nelson/.local/lib/python3.8/site-packages/yourdfpy/viz.py", line 106, in run
    main(sys.argv[1:])
  File "/home/nelson/.local/lib/python3.8/site-packages/yourdfpy/viz.py", line 98, in main
    urdf_model.show(collision_geometry=args.collision)
  File "/home/nelson/.local/lib/python3.8/site-packages/yourdfpy/urdf.py", line 663, in show
    self._scene.show()
  File "/home/nelson/.local/lib/python3.8/site-packages/trimesh/scene/scene.py", line 1105, in show
    return SceneViewer(self, **kwargs)
  File "/home/nelson/.local/lib/python3.8/site-packages/trimesh/viewer/windowed.py", line 107, in __init__
    [0, 0, scene.scale / 1000 if self.offset_lines else 0])
  File "/home/nelson/.local/lib/python3.8/site-packages/trimesh/caching.py", line 109, in get_cached
    value = function(*args, **kwargs)
  File "/home/nelson/.local/lib/python3.8/site-packages/trimesh/scene/scene.py", line 384, in scale
    scale = (self.extents ** 2).sum() ** .5
  File "/home/nelson/.local/lib/python3.8/site-packages/trimesh/caching.py", line 109, in get_cached
    value = function(*args, **kwargs)
  File "/home/nelson/.local/lib/python3.8/site-packages/trimesh/scene/scene.py", line 372, in extents
    return np.diff(self.bounds, axis=0).reshape(-1)
  File "<__array_function__ internals>", line 5, in diff
  File "/home/nelson/.local/lib/python3.8/site-packages/numpy/lib/function_base.py", line 1258, in diff
    raise ValueError("diff requires input that is at least one dimensional")
ValueError: diff requires input that is at least one dimensional

Mesh scaling linter error

My linter reports an undefined name in _link_mesh:

    def _link_mesh(self, link, collision_geometry=True):
        # ...
        for g in geometries:
            for m in g.geometry.meshes:
                # ...
                    if g.geometry.mesh.scale is not None:
                        S[:3, :3] = np.diag(c.geometry.mesh.scale)  # undefined c?

This would trigger a NameError on a URDF with a scaled mesh.

Path to hands of Eve R3 URDF not found

The path to the hand meshes of the Eve R3 URDF (one of those shown in the README) is not found:

yourdfpy /path/to/halodi-robot-models/eve_r3_description/urdf/eve_r3.urdf
...
Unable to resolve filename: package://qb_hand_description/meshes/ph_distal.obj
Can't find package://qb_hand_description/meshes/ph_distal.obj

The directory qb_hand_description is actually in the halodi-robot-models repository, so I'm not sure why yourdfpy doesn't find it.

Illustration

Mesh not loaded properly (this issue):

Mesh loaded properly (how it should be):

Further observations

  • Meshes load successfully when running yourdfpy eve_r3_description/urdf/eve_r3.urdf from the root of halodi-robot-models
  • Meshes don't load when running yourdfpy halodi-robot-models/eve_r3_description/urdf/eve_r3.urdf from a directory containing halodi-robot-models
  • The directory structure of halodi-robot-models is:
halodi-robot-models
├── eve_r3_description
│   ├── meshes
│   └── urdf
├── gradle-production.properties
├── gradle.properties
├── gradle-release.properties
├── halodi-robot-models-unity-support
├── qb_hand_description
│   ├── meshes
├── robotiq_2f_85_gripper_visualization
└── robotiq_hand-e

Apply visual colors

If I understand correctly, visual materials are currently read and written but not rendered. Loading e.g. the Upkie URDF we get the dark "ninja" version:

upkie-ninja

Trimesh can render materials so getting them to yourdfpy is a matter of plugging the right info. Here is for instance a draft PR to do so (opening the issue here to keep track):

upkie-colored-chassis

Is there an interest to render colors (eventually materials) in yourdfpy?

CLI URDF Validation

It would be nice if the package also installed an executable script that could be used to validate URDFs (and return a non-zero exit code for unparsable URDFs). If it did this, it would make it easy to include as an automated CLI check to validate if the URDF is properly formatted.

Poetry support

First, thanks for this repository. I have used urdfpy for a while now, but it is so inactive that bugs are no longer fixed. Therefore, I am looking for an alternative. You might add this to the advantages of this repository over urdfpy.

Are you planning to use poetry for package managing? It is quite handy as it directly creates the virtual environment with all the dependencies and it will allow to quickly generate a CI sometime in the future?

If you want that, let me know and I could create the corresponding PR for that:)

object picking feature, nice to have

It will be nice to have the object-picking functionality ( using raycast and returning the position vector/normal vector for that specific position )It can be useful in case you decide to use the viewer to augment the scene ( let's say... select the position/where you want to apply some external force... or selecting the joint for which you want to change its corresponding DOF etc )

XML error with lxml 5.0.0 and libxml 2.12

Mentioning here an XML error that hits yourdfpy since lxml 5.0.0 when loading the Go1 description from https://github.com/unitreerobotics/unitree_ros/tree/master/robots/go1_description/urdf

2024-01-02T10:08:46.0517945Z   File "/home/runner/work/robot_descriptions.py/robot_descriptions.py/.tox/loader-yourdfpy/lib/python3.8/site-packages/collada/__init__.py", line 210, in __init__
2024-01-02T10:08:46.0519697Z     self.xmlnode = ElementTree.ElementTree(element=None,
2024-01-02T10:08:46.0520666Z   File "src/lxml/etree.pyx", line 3183, in lxml.etree.ElementTree
2024-01-02T10:08:46.0521806Z   File "src/lxml/parser.pxi", line 1955, in lxml.etree._parseDocument
2024-01-02T10:08:46.0522961Z   File "src/lxml/parser.pxi", line 1975, in lxml.etree._parseMemoryDocument
2024-01-02T10:08:46.0524057Z   File "src/lxml/parser.pxi", line 1862, in lxml.etree._parseDoc
2024-01-02T10:08:46.0525564Z   File "src/lxml/parser.pxi", line 1145, in lxml.etree._BaseParser._parseDoc
2024-01-02T10:08:46.0526850Z   File "src/lxml/parser.pxi", line 618, in lxml.etree._ParserContext._handleParseResultDoc
2024-01-02T10:08:46.0528089Z   File "src/lxml/parser.pxi", line 728, in lxml.etree._handleParseResult
2024-01-02T10:08:46.0529191Z   File "src/lxml/parser.pxi", line 657, in lxml.etree._raiseParseError
2024-01-02T10:08:46.0529995Z   File "<string>", line 83
2024-01-02T10:08:46.0530832Z lxml.etree.XMLSyntaxError: xmlSAX2Characters: huge text node, line 83, column 10000427

Reproduction instructions in this thread.

This error coincides with the release of lxml 5.0.0. Feedback from lxml maintainers in https://bugs.launchpad.net/lxml/+bug/2047826 suggests it is caused by an update of libxml to 2.12 (formerly 2.10 with lxml < 5.0.0).

I don't know if this behavior is triggered by a decision in yourdfpy or pycollada, but in case the latter holds this issue is also reported in the pycollada issue tracker.

Meshes from other packages not found

URDF files can load meshes from different packages. Let's take the following situation:

root/
    art/
        meshes/
            beautiful.stl
    robots/
        humanoid/
            robot.urdf

Here robot.urdf can contain a mesh tag like:

    <mesh filename="package://art/meshes/beautiful.stl" />

This should be valid, but if we go to the root/ directory and run yourdfpy robots/humanoid/robot.urdf the STL mesh won't load properly.

Why?

The filename_handler_magic is called with arguments ("package://art/meshes/beautiful.stl", "robots/humanoid").

  • What if should do: return "art/meshes/beautiful.stl"
  • What it currently does: return "package://art/meshes/beautiful.stl"

If we unroll its execution, it currently checks for the following paths, does not find the STL file there, issues a warning and returns its first input unchanged.

  • robots/humanoid/meshes/beautiful.stl
  • robots/meshes/beautiful.stl
  • meshes/beautiful.stl

dae format not supported

I've tried to reproduce your tests but, for some reason, it doesn't work out of the box.

You are mentioning this repo: https://github.com/ankurhanda/robot-assets as robots test input.

The problem is that some of the robots are using ".dae" format for geometry which "trimesh" doesn't accept as input. I guess you didn't change manually the mesh geometry format for those robots, right?

CrazyFlie2 COLLADA mesh not loaded properly

I'm not sure whether the issue comes from yourdfpy or one of its dependencies, but the CrazyFlie2 URDF does not load properly.

The URDF has a single Collada mesh, here it is loaded by Blender (left) and yourdfpy 0.0.52 (right):

image

In yourdfpy, three out of four propellers are missing.

[viz] Configuration argument is not implemented

In viz.py the parser defines

    parser.add_argument(
        "-c",
        "--configuration",
        nargs="+",
        type=float,
        help="Configuration of the visualized URDF model.",
    )

but this argument seems not to be used for now.

KeyError while loading PR2 description

  • yourdfpy version 0.0.52

A KeyError pops out when trying to open the pr2_simplified.urdf description from Drake:

$ yourdfpy examples/pr2/models/pr2_description/urdf/pr2_simplified.urdf                                                                                           ✔ 
Traceback (most recent call last):
  File "~/.local/bin/yourdfpy", line 8, in <module>
    sys.exit(run())
  File "~/.local/lib/python3.8/site-packages/yourdfpy/viz.py", line 198, in run
    main(sys.argv[1:])
  File "~/.local/lib/python3.8/site-packages/yourdfpy/viz.py", line 187, in main
    urdf_model.show(
  File "~/.local/lib/python3.8/site-packages/yourdfpy/urdf.py", line 859, in show
    elif len(self._scene.bounds_corners) < 1:
  File "~/.local/lib/python3.8/site-packages/trimesh/caching.py", line 109, in get_cached
    value = function(*args, **kwargs)
  File "~/.local/lib/python3.8/site-packages/trimesh/scene/scene.py", line 330, in bounds_corners
    transform, geometry_name = self.graph[node_name]
  File "~/.local/lib/python3.8/site-packages/trimesh/scene/transforms.py", line 471, in __getitem__
    return self.get(key)
  File "~/.local/lib/python3.8/site-packages/trimesh/scene/transforms.py", line 145, in get
    matrices = [edge_data[(u, v)]['matrix'] for u, v in
  File "~/.local/lib/python3.8/site-packages/trimesh/scene/transforms.py", line 145, in <listcomp>
    matrices = [edge_data[(u, v)]['matrix'] for u, v in
KeyError: 'matrix'

(The model from the git repository tries to load .obj meshes, while they are in fact .stl. This error remains even after replacing all occurrences of .obj by .stl in the file.)

Getting a chain between 2 links is not available

The current implementation is nice and all but it misses an important feature if you are interested in building the corresponding dynamical model.

The workaround is to do it manually using the list of the joints that contains all the necessary information ( the adjoint links for each joint ) for building a tree but I imagine, this functionality should be available out of the bat like it is available in urdf_parser_py ( ) : "get_chain(root, tip)" In that sense, I think it will be also easier if each link will also have a list of the joints which are to be found in the local coordinates...

Independent axis scaling

Some URDFs, like the TALOS robot description, use [1 -1 1] axis scales to flip meshes. Here is how the model looks with yourdfpy: the robot's right leg is flipped, warnings in the terminal explain why:

image

Would it be possible for yourdfpy to support that part of the standard?

'TextureVisuals' object has no attribute 'face_colors'

Happens when loading this model:

$ yourdfpy example-robot-data/robots/kinova_description/robots/kinova.urdf         ✔ 
Traceback (most recent call last):
  File "/home/nelson/.local/bin/yourdfpy", line 8, in <module>
    sys.exit(run())
  File "/home/nelson/.local/lib/python3.8/site-packages/yourdfpy/viz.py", line 106, in run
    main(sys.argv[1:])
  File "/home/nelson/.local/lib/python3.8/site-packages/yourdfpy/viz.py", line 97, in main
    urdf_model = URDF.load(args.input)
  File "/home/nelson/.local/lib/python3.8/site-packages/yourdfpy/urdf.py", line 788, in load
    return URDF(robot=URDF._parse_robot(xml_element=xml_root), **kwargs)
  File "/home/nelson/.local/lib/python3.8/site-packages/yourdfpy/urdf.py", line 444, in __init__
    self._scene = self._create_scene(
  File "/home/nelson/.local/lib/python3.8/site-packages/yourdfpy/urdf.py", line 1129, in _create_scene
    self._add_geometries_to_scene(
  File "/home/nelson/.local/lib/python3.8/site-packages/yourdfpy/urdf.py", line 1095, in _add_geometries_to_scene
    apply_visual_color(geom, v)
  File "/home/nelson/.local/lib/python3.8/site-packages/yourdfpy/urdf.py", line 241, in apply_visual_color
    geom.visual.face_colors[:] = [
AttributeError: 'TextureVisuals' object has no attribute 'face_colors'

This issue was introduced in #6 Should be readily fixable with an extra check.

AttributeError: module 'numpy' has no attribute 'float'

Loading a URDF with numpy>=1.24.0 fails because np.float was deprecated and has disappeared:

$ python
Python 3.9.15 | packaged by conda-forge | (main, Nov 22 2022, 15:55:03) 
[GCC 10.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import yourdfpy
>>> yourdfpy.URDF.load(".../any.urdf")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/.../.micromamba/envs/yourdfpy-test/lib/python3.9/site-packages/yourdfpy/urdf.py", line 989, in load
    return URDF(robot=URDF._parse_robot(xml_element=xml_root), **kwargs)
  File "/.../.micromamba/envs/yourdfpy-test/lib/python3.9/site-packages/yourdfpy/urdf.py", line 2154, in _parse_robot
    robot.links.append(URDF._parse_link(l))
  File "/.../.micromamba/envs/yourdfpy-test/lib/python3.9/site-packages/yourdfpy/urdf.py", line 1951, in _parse_link
    link.visuals.append(URDF._parse_visual(v))
  File "/.../.micromamba/envs/yourdfpy-test/lib/python3.9/site-packages/yourdfpy/urdf.py", line 1819, in _parse_visual
    visual.geometry = URDF._parse_geometry(xml_element.find("geometry"))
  File "/.../.micromamba/envs/yourdfpy-test/lib/python3.9/site-packages/yourdfpy/urdf.py", line 1683, in _parse_geometry
    geometry.box = URDF._parse_box(xml_element[0])
  File "/.../.micromamba/envs/yourdfpy-test/lib/python3.9/site-packages/yourdfpy/urdf.py", line 1621, in _parse_box
    return Box(size=np.array(xml_element.attrib["size"].split(), dtype=np.float))
  File "/.../.micromamba/envs/yourdfpy-test/lib/python3.9/site-packages/numpy/__init__.py", line 284, in __getattr__
    raise AttributeError("module {!r} has no attribute "
AttributeError: module 'numpy' has no attribute 'float'

Apply visual textures

Visual colors are currently supported but not their textures.

See #7 for some previous discussion.

video/gif/snapshots capture feature, nice to have :)

It will be nice if you can make it, out-of-the-box, video/image capturing. I've checked, and this can be done using "trimesh"... but it will be nice to have this functionality, directly as part of the interface of this library.
( e.g. like it is done in this viewer: https://pypi.org/project/panda3d-viewer/ I've tried to use it but, unfortunately, it's tightly connected with Linux through some dependencies which make it unusable for me... )

ValueError: setting an array element with a sequence

After upgrading NumPy and SciPy to respectively 1.24.4 and 1.10.1 I started to get the following error when trying to load a robot URDF:

Traceback (most recent call last):
  File "load_in_yourdfpy.py", line 36, in <module>
    robot = load_robot_description(f"{args.name}_description")
  File "/home/user/src/robot_descriptions.py/examples/robot_descriptions/loaders/yourdfpy.py", line 58, in load_robot_description
    return yourdfpy.URDF.load(module.URDF_PATH, mesh_dir=module.PACKAGE_PATH)
  File "/home/user/.local/lib/python3.8/site-packages/yourdfpy/urdf.py", line 989, in load
    return URDF(robot=URDF._parse_robot(xml_element=xml_root), **kwargs)
  File "/home/user/.local/lib/python3.8/site-packages/yourdfpy/urdf.py", line 641, in __init__
    self._scene = self._create_scene(
  File "/home/user/.local/lib/python3.8/site-packages/yourdfpy/urdf.py", line 1321, in _create_scene
    matrix, _ = self._forward_kinematics_joint(j)
  File "/home/user/.local/lib/python3.8/site-packages/yourdfpy/urdf.py", line 1072, in _forward_kinematics_joint
    matrix = origin @ tra.rotation_matrix(q, joint.axis)
  File "/home/user/.local/lib/python3.8/site-packages/trimesh/transformations.py", line 361, in rotation_matrix
    M = np.diag([cosa, cosa, cosa, 1.0])
  File "<__array_function__ internals>", line 200, in diag
  File "/home/user/.local/lib/python3.8/site-packages/numpy/lib/twodim_base.py", line 295, in diag
    v = asanyarray(v)
ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (4,) + inhomogeneous part.

The issue stems from urdf.py where:

matrix = origin @ tra.rotation_matrix(q, joint.axis)

Won't work well by asanyarray (as per the new requirements) if q is a one-dimensional array, which can happen here. I'll suggest a fix in a PR.

bug calling callback

When you define your "callback" function the desired behavior is to get it triggered once every "callback_period" times.
What happens instead is that it also gets triggered by any control applied in the window ( e.g. mouse pressed, key pressed, etc ) hence, the "callback" function gets activated more times than it should be.

urdf_path = "robot-assets/urdfs/robots/franka_panda/panda.urdf"


class Viewer(viewer.windowed.SceneViewer):
    def __init__(self, scene, callback, callback_period, start_loop, profile):
        super().__init__(scene,
                         callback=callback,
                         callback_period=callback_period,
                         start_loop=start_loop,
                         profile=profile)

Scene=yourdfpy.URDF.load(
    urdf_path,
    load_meshes=True,
    #load_collision_meshes=True,
    #build_collision_scene_graph=True,
    build_scene_graph=True
)

def updateScene(scene):
    cfg = Scene.cfg
    cfg[1]=cfg[1]+3.14/32
    Scene.update_cfg(cfg)
    scene = Scene.scene
    pass

view = Viewer(Scene.scene,
              callback=updateScene,
              callback_period=5,
              start_loop=True,
              profile=False)

Add `load_from_string`

Description: In some applications, as opposed to having a URDF file, one has the URDF as a string. it would be helpful to have a URDF.load_from_string method to handle such scenarios.

Sample Use Case: A common use case with MoveIt2 is to have the robot model as a xacro file, then convert the xacro file to a URDF string, and then pass that string as a parameter to move_group node. As a result, one can easily get the URDF string by calling the get parameter service. However, yourdfpy does not provide a way to load that string.

Workaround: I have currently worked around this with by adding the following code to my class. However, it is non-ideal because we are accessing a private member of the URDF class outside of the class. So it would be better to add the capability to the library itself.

from lxml import etree
from yourdfpy import URDF

parser = etree.XMLParser(remove_blank_text=True)
xml_root = etree.fromstring(urdf_str, parser=parser)
model = URDF(robot=URDF._parse_robot(xml_element=xml_root))

file paths parsing not consistent

Currently, this project works well under Linux but not under Windows.

This is due to the fact that the separators are mixed into the parsing process. If the urdf file contains Linux separators "/" to define paths one will end up mixing Linux sep. with windows since in the current implementation os.path.sep is used, which in this case it's going to return \\.

Can you advise an easy fix at this point?

multiple urdf robots loaded

What is the correct approach when you want to load multiple urdf robots as part of the same scene/viewer? Currently, it doesn't seem possible ( using proper channels ) and if that is the case it will be a nice feature.

(use case: let's say you want to do optimal control and you want to render the final state of the robot too, using some transparency or a different color )

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.