Code Monkey home page Code Monkey logo

urdfpy's Introduction

Urdfpy

Build Status Documentation Status Coverage Status PyPI version

Urdfpy is a simple and easy-to-use library for loading, manipulating, saving, and visualizing URDF files.

Extensive API documentation is provided here.

GIF of Viewer GIF of Viewer

Installation

You can install urdfpy directly from pip.

pip install urdfpy

User Guide

Please see the user guide here for more information.

urdfpy's People

Contributors

janusmaple avatar mmatl 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  avatar

urdfpy's Issues

How to visualize paths along with URDF?

I have a use case where I need to visualize the robot end-effector task space trajectory and also some cube shaped objects in the environment. How would one go about doing this when visualizing a robot with urdfpy?

Networkx should not be fixed to 2.2 in the setup.py

When installing urdfpy using pip, (I tried both from pypi and cloning the repo), an error occurs when loading and showing a URDF file.
I ran the code:

import urdfpy

robot = urdfpy.URDf.load("ur5e/ur5e.urdf")
robot.show()

And received the error:

ImportError: cannot import name 'gcd' from 'fractions'

It seems the issue that the setup.py file requires that networkx==2.2, but that version doesn't support the functions used in the library, and therefore needs to be upgraded after installing the library.
I believe the networkx version requirement can be removed from the setup.py file.
(This was tested with Python version 3.9.12 and version 3.10.6 with same results)

Use in Ikpy

Hey @mmatl,

I'm the maintainer of an inverse kinematics library, IKPy, which provides inverse kinematics to robots defined from URDF files.

I've been wanting to add full 3D visualization to my URDFs using PyRender for a long time.
And i found today this library which perfectly fits my need, and which is from the same maintainer as PyRender

So, FYI, I'm going to use your lib as a dependency of IKPy, this looks great!

How do I merge two URDFs?

Hello!
I would like to merge robotic arm URDF with selected gripper URDF using your library. How can I do that?

Error when reading a URDF file

I am trying to read a URDF file, but I get this error: ValueError: Missing required attribute effort when parsing an object of type JointLimit.

The contents of the urdf file are below:

<?xml version="1.0" ?> <robot name="partnet_3a910cc1f575b08339d3717288022c20"> <link name="base"/> <link name="link_0"> <visual name="drawer_front-23"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-50.obj"/> </geometry> </visual> <visual name="drawer_front-24"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-48.obj"/> </geometry> </visual> <visual name="drawer_side-25"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-52.obj"/> </geometry> </visual> <visual name="drawer_side-26"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-49.obj"/> </geometry> </visual> <visual name="drawer_back-27"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-53.obj"/> </geometry> </visual> <visual name="drawer_bottom-28"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-51.obj"/> </geometry> </visual> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-50.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-48.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-52.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-49.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-53.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-51.obj"/> </geometry> </collision> </link> <joint name="joint_0" type="prismatic"> <origin xyz="0 0 0"/> <axis xyz="0 0 1"/> <child link="link_0"/> <parent link="link_3"/> <limit lower="0" upper="0.5"/> </joint> <link name="link_1"> <visual name="drawer_front-16"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-67.obj"/> </geometry> </visual> <visual name="drawer_front-17"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-66.obj"/> </geometry> </visual> <visual name="drawer_side-18"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-62.obj"/> </geometry> </visual> <visual name="drawer_side-19"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-65.obj"/> </geometry> </visual> <visual name="drawer_back-20"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-64.obj"/> </geometry> </visual> <visual name="drawer_bottom-21"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-63.obj"/> </geometry> </visual> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-67.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-66.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-62.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-65.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-64.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-63.obj"/> </geometry> </collision> </link> <joint name="joint_1" type="prismatic"> <origin xyz="0 0 0"/> <axis xyz="0 0 1"/> <child link="link_1"/> <parent link="link_3"/> <limit lower="0" upper="0.5"/> </joint> <link name="link_2"> <visual name="drawer_side-9"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-59.obj"/> </geometry> </visual> <visual name="drawer_side-10"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-56.obj"/> </geometry> </visual> <visual name="drawer_back-11"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-60.obj"/> </geometry> </visual> <visual name="drawer_bottom-12"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-58.obj"/> </geometry> </visual> <visual name="drawer_front-13"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-57.obj"/> </geometry> </visual> <visual name="drawer_front-14"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-55.obj"/> </geometry> </visual> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-59.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-56.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-60.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-58.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-57.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-55.obj"/> </geometry> </collision> </link> <joint name="joint_2" type="prismatic"> <origin xyz="0 0 0"/> <axis xyz="0 0 1"/> <child link="link_2"/> <parent link="link_3"/> <limit lower="0" upper="0.5"/> </joint> <link name="link_3"> <visual name="shelf-43"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-22.obj"/> </geometry> </visual> <visual name="shelf-43"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-16.obj"/> </geometry> </visual> <visual name="shelf-43"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-18.obj"/> </geometry> </visual> <visual name="shelf-43"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-20.obj"/> </geometry> </visual> <visual name="shelf-43"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-21.obj"/> </geometry> </visual> <visual name="shelf-43"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-23.obj"/> </geometry> </visual> <visual name="shelf-43"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-17.obj"/> </geometry> </visual> <visual name="shelf-43"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-19.obj"/> </geometry> </visual> <visual name="countertop-44"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-42.obj"/> </geometry> </visual> <visual name="base_side_panel-38"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-38.obj"/> </geometry> </visual> <visual name="base_side_panel-39"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-32.obj"/> </geometry> </visual> <visual name="base_side_panel-40"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-36.obj"/> </geometry> </visual> <visual name="base_side_panel-41"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-5.obj"/> </geometry> </visual> <visual name="frame_horizontal_bar-51"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-13.obj"/> </geometry> </visual> <visual name="frame_horizontal_bar-52"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-12.obj"/> </geometry> </visual> <visual name="frame_horizontal_bar-53"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-15.obj"/> </geometry> </visual> <visual name="frame_horizontal_bar-54"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-14.obj"/> </geometry> </visual> <visual name="frame_horizontal_bar-55"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-39.obj"/> </geometry> </visual> <visual name="frame_horizontal_bar-56"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-45.obj"/> </geometry> </visual> <visual name="frame_horizontal_bar-57"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-40.obj"/> </geometry> </visual> <visual name="frame_horizontal_bar-58"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-6.obj"/> </geometry> </visual> <visual name="vertical_side_panel-59"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-41.obj"/> </geometry> </visual> <visual name="vertical_side_panel-60"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-43.obj"/> </geometry> </visual> <visual name="back_panel-61"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-37.obj"/> </geometry> </visual> <visual name="vertical_side_panel-62"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-44.obj"/> </geometry> </visual> <visual name="vertical_side_panel-63"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-28.obj"/> </geometry> </visual> <visual name="vertical_side_panel-64"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-24.obj"/> </geometry> </visual> <visual name="vertical_divider_panel-65"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-9.obj"/> </geometry> </visual> <visual name="vertical_divider_panel-66"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-10.obj"/> </geometry> </visual> <visual name="bottom_panel-67"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-1.obj"/> </geometry> </visual> <visual name="bottom_panel-67"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-46.obj"/> </geometry> </visual> <visual name="bottom_panel-67"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-3.obj"/> </geometry> </visual> <visual name="vertical_divider_panel-68"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-34.obj"/> </geometry> </visual> <visual name="vertical_divider_panel-69"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-4.obj"/> </geometry> </visual> <visual name="vertical_divider_panel-69"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-29.obj"/> </geometry> </visual> <visual name="vertical_divider_panel-69"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-27.obj"/> </geometry> </visual> <visual name="vertical_divider_panel-70"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-8.obj"/> </geometry> </visual> <visual name="vertical_divider_panel-70"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-33.obj"/> </geometry> </visual> <visual name="vertical_divider_panel-70"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-2.obj"/> </geometry> </visual> <visual name="vertical_divider_panel-71"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-26.obj"/> </geometry> </visual> <visual name="back_panel-72"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-31.obj"/> </geometry> </visual> <visual name="frame_horizontal_bar-73"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-7.obj"/> </geometry> </visual> <visual name="frame_horizontal_bar-74"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-30.obj"/> </geometry> </visual> <visual name="frame_horizontal_bar-75"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-35.obj"/> </geometry> </visual> <visual name="frame_horizontal_bar-76"> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-25.obj"/> </geometry> </visual> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-22.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-16.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-18.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-20.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-21.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-23.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-17.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-19.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-42.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-38.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-32.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-36.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-5.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-13.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-12.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-15.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-14.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-39.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-45.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-40.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-6.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-41.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-43.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-37.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-44.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-28.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-24.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-9.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-10.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-1.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-46.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-3.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-34.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-4.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-29.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-27.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-8.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-33.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-2.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-26.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-31.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-7.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-30.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-35.obj"/> </geometry> </collision> <collision> <origin xyz="0 0 0"/> <geometry> <mesh filename="textured_objs/original-25.obj"/> </geometry> </collision> </link> <joint name="joint_3" type="fixed"> <origin rpy="1.570796326794897 0 -1.570796326794897" xyz="0 0 0"/> <child link="link_3"/> <parent link="base"/> </joint> </robot>

Can you folks, @mmatl @JanusMaple, point out a solution to this issue? Thanks.

networkx is out of date

Can you update to the current library?

ERROR: urdfpy 0.0.18 has requirement networkx==2.2, but you'll have networkx 2.4 which is incompatible.

Trying to access the `meshes` attribute of `Cylinder` throws an error.

If g = Cylinder(1.0, 2.0) and you try to access the g.meshes field then it throws the following error

File "/usr/local/lib/python3.6/dist-packages/urdfpy/urdf.py", line 398, in meshes
    if len(self._meshes) == 0:
TypeError: object of type 'NoneType' has no len()

This is because self._meshes got initialize to self._meshes = None on this line instead of self._meshes = [] like in the other primitive types, e.g. Box. Should be a simple fix to just set self._meshes = [] in the Cylinder constructor.

Support for <deformable>

Recently, Bullet C++ and PyBullet have started supporting the <deformable> tag in URDF files following this commit, see this file for a use example. I'm not sure of how it would integrate with pyrender though.

I recently used this package to make a rigid-body URDF using a sliced-up version of hand mesh I have, and it would be nice to use it again to make a URDF with a soft body mesh.

ValueError: File type: dae not supported

Hi! I am glad you are using code sharing, but I encountered a problem in the use.

from urdfpy import URDF
robot = URDF.load('/home/zt/urdf_ws/urdfpy/tests/data/ur5/ur5.urdf')

File "/home/zt/.local/lib/python3.6/site-packages/trimesh/exchange/load.py", line 155, in load
file_type)
ValueError: File type: dae not supported

Failure to display urdf visualization

Hi,

Thanks for the effort you guys put into making urdfpy.
I am getting errors for the following code sample executing on Python 3. I installed urdfpy into my python3 environment.


from urdfpy import URDF
robot = URDF.load('ur5/ur5.urdf')

robot.show(cfg={'shoulder_lift_joint':-2.0, 'elbow_joint':2.0})

Error:
urdf_test_error

I made certain that the 'robot' variable gets a value from the URDF.load() function.
I'd greatly appreciate your thoughts on how to fix this.

ValueError: string is not a file:

im trying to load in a urdf file into some simple code which is
from urdfpy import URDF robot= URDF.load("C:/Users/(put computer name here)/Desktop/python code/v2 robot arm - Copy/urdf/v2 robot arm - Copy.urdf")

but when i run it i get this error

ValueError: string is not a file: C:/Users/(put computer name here)/Desktop/python code/v2 robot arm - Copy/urdf\package://v2 robot arm - Copy/meshes/base_link.STL
how do i fix this?

urdfpy seems not handle the <visual> tag properly

It seems that urdfpy is not handling the <origin> tag inside the <visual> tag properly.
Whenever the <origin> tag has non-zero entries it seems that this information is ignored/not handled.
Has someone made the same or similar observations?

Support for 'spherical' joint type

I think the "spherical" joint type is not part of the standard URDF spec.

However, the Bullet simulator and its Python API support this joint type along with others such as revolute, but does not support floating although they should be functionally the same for rotation with fixed joint position.

Here is an example of this joint type being used in the PyBullet examples. I think I have a (naive) patch for this where 'spherical' is just an alias for 'floating'.

Axis import problems

In some urdf files axis coordinate might be [0.0, 0.0, 0.0], which would cause runtime error for the code in line 2169urdf.py: "value = value / np.linalg.norm(value)".
Thus, it would be better if there is a conditional statement that if math.isclose(np.linalg.norm(value), 0.0), then value = np.array([1.0, 0.0, 0.0], dtype=np.float64).

collision_trimesh_fk doesn't have the updated vertex positions

I was trying to get the vertex positions of the meshes after performing forward kinematics on the robot (say, when the joint positions are set, the vertices of the meshes had have to be updated with respect to the base frame). I used the UR robot which is a part of this repository as an example and here is my implementation.
from urdfpy import URDF

    class Kinematics:
        def __init__(self, urdf):
            self.urdf = urdf
            self.robot = URDF.load(self.urdf)
            self.fk = self.robot.collision_trimesh_fk()
    
        def setjntpos(self, jntpos):
            assert(len(jntpos)==len(self.robot.actuated_joints))
            config = {}
            for index in range(len(self.robot.actuated_joints)):
                config[self.robot.actuated_joints[index].name] = jntpos[index]
            self.fk  = self.robot.collision_trimesh_fk(cfg=config)
            return config
    
        def getrobotvertices(self, config):
            for i in range(len(list(self.fk.keys()))):
                print(list(self.fk.keys())[i].vertices)
            
    kinematics = Kinematics('robots/ur5/ur5.urdf')
    cfg = kinematics.setjntpos([0.0, -2.0, 2.0, 0.0, 1.0, 0.0])
    kinematics.getrobotvertices(cfg)

The positions of the vertices are not being updated. Is this the right way to use the collision_trimesh_fk API?

Generating cylinder meshes

return self._mesh

The cylinder mesh creation is faulty in the current release version. Some of the bits reference self._meshes as being None but now they should be empty lists. Also, on line 402 it tries to return self._mesh instead of self._meshes.

Apologies for not making a proper pull request, it's not easy for me to do that in my current situation. Great library by the way, much appreciated.

Below is what I have changed the cylinder stuff to and it appears to work.

`class Cylinder(URDFType):
"""A cylinder whose center is at the local origin.

Parameters
----------
radius : float
    The radius of the cylinder in meters.
length : float
    The length of the cylinder in meters.
"""

_ATTRIBS = {
    'radius': (float, True),
    'length': (float, True),
}
_TAG = 'cylinder'

def __init__(self, radius, length):
    self.radius = radius
    self.length = length
    self._meshes = []

@property
def radius(self):
    """float : The radius of the cylinder in meters.
    """
    return self._radius

@radius.setter
def radius(self, value):
    self._radius = float(value)
    self._meshes = []

@property
def length(self):
    """float : The length of the cylinder in meters.
    """
    return self._length

@length.setter
def length(self, value):
    self._length = float(value)
    self._meshes = []

@property
def meshes(self):
    """list of :class:`~trimesh.base.Trimesh` : The triangular meshes
    that represent this object.
    """
    if len(self._meshes) == 0:
        self._meshes = [trimesh.creation.cylinder(
            radius=self.radius, height=self.length
        )]
    return self._meshes

def copy(self, prefix='', scale=None):
    """Create a deep copy with the prefix applied to all names.

    Parameters
    ----------
    prefix : str
        A prefix to apply to all names.

    Returns
    -------
    :class:`.Cylinder`
        A deep copy.
    """
    if scale is None:
        scale = 1.0
    if isinstance(scale, (list, np.ndarray)):
        if scale[0] != scale[1]:
            raise ValueError('Cannot rescale cylinder geometry with asymmetry in x/y')
        c = Cylinder(
            radius=self.radius * scale[0],
            length=self.length * scale[2],
        )
    else:
        c = Cylinder(
            radius=self.radius * scale,
            length=self.length * scale,
        )
    return c`

Use of specific classname instead of cls when loading from xml

Hi,

I'm using urdfpy for some deep learning tasks and wrote a hacky extension that uses Pytorch tensors instead of numpy arrays. In order to do this, I extended the classes in urdfpy and only replaced the relevant methods. While doing that, I noticed that a lot of the classes have a _from_xml classmethod, but at the end of the method, they end up instantiating with the specific class instead of the cls variable. I ended up having to override all of these methods so that I could instantiate my subclass.

I'm happy to make a PR to change this, but I wanted to know: is there any reason why it's written the way it currently is?

As an example: https://github.com/mmatl/urdfpy/blob/master/urdfpy/urdf.py#L1145

Does this support primitives?

I just started to work with this an made a simple urdf with 4 links. I am using simple cylinders for the geometry:

<visual>
        <geometry>
            <cylinder length="52" radius="1"/>
        </geometry>
</visual>

however when I run it, I get the following error:

Traceback (most recent call last):
  File "./test.py", line 33, in <module>
    robot.show(cfg=config)
  File "/Users/kevin/pyvenv/cv/lib/python3.7/site-packages/urdfpy/urdf.py", line 3540, in show
    fk = self.visual_trimesh_fk(cfg=cfg)
  File "/Users/kevin/pyvenv/cv/lib/python3.7/site-packages/urdfpy/urdf.py", line 3197, in visual_trimesh_fk
    for mesh in visual.geometry.meshes:
  File "/Users/kevin/pyvenv/cv/lib/python3.7/site-packages/urdfpy/urdf.py", line 734, in meshes
    return self.geometry.meshes
  File "/Users/kevin/pyvenv/cv/lib/python3.7/site-packages/urdfpy/urdf.py", line 396, in meshes
    if len(self._meshes) == 0:
TypeError: object of type 'NoneType' has no len()

I am using python 3.7 on macOS 10.15 and just installed urdfpy

Python

#!/usr/bin/env python

from urdfpy import URDF
from math import pi

def deg2rad(x):
    return x*pi/180

robot = URDF.load("kevin.urdf")

config = {
    "joint1": deg2rad(45),
    "joint2": deg2rad(45),
    "joint3": deg2rad(90),
    "joint4": deg2rad(-45)
}

fk = robot.link_fk(cfg=config)

for k in robot.links:
    print('-'*25)
    print(k.name)
    print(fk[k])

for j in robot.joints:
    print('-'*25)
    print('{}: {} to {}'.format(j.name, j.parent, j.child))
    # print(j.name)
    # print(dir(j))
    # print(j.origin)
    # print(dir(j.origin))

robot.show(cfg=config)

urdf

<?xml version="1.0"?>
  <robot name="quad">
    <material name="red">
      <color rgba="1 0 0 1" />
    </material>

    <link name="body">
    <visual>
        <geometry>
            <cylinder length="10" radius="0.5"/>
        </geometry>
        <material name="red"/>
    </visual>
    </link>

    <link name="coxa">
    <visual>
        <geometry>
            <cylinder length="52" radius="1"/>
        </geometry>
    </visual>
    </link>

    <link name="femur">
    <visual>
        <geometry>
            <cylinder length="89" radius="1"/>
        </geometry>
    </visual>
    </link>

    <link name="tibia">
    <visual>
        <geometry>
            <cylinder length="90" radius="1"/>
        </geometry>
    </visual>
    </link>

    <link name="tarsus">
    <visual>
        <geometry>
            <cylinder length="95" radius="1"/>
        </geometry>
    </visual>
    </link>
    <link name="foot"/>

    <joint name="joint1" type="revolute">
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <parent link="body"/>
      <child link="coxa"/>
      <axis xyz="0 0 1.0"/>
      <limit effort="150.0" lower="-6.28318530718" upper="6.28318530718" velocity="3.15"/>
    </joint>

    <joint name="joint2" type="revolute">
      <origin xyz="52 0 0" rpy="-1.570796 0 0"/>
      <parent link="coxa"/>
      <child link="femur"/>
      <axis xyz="0 0 1.0"/>
      <limit effort="150.0" lower="-6.28318530718" upper="6.28318530718" velocity="3.15"/>
    </joint>

    <joint name="joint3" type="revolute">
      <origin xyz="89 0 0" rpy="0 0 0"/>
      <parent link="femur"/>
      <child link="tibia"/>
      <axis xyz="0 0 1.0"/>
      <limit effort="150.0" lower="-6.28318530718" upper="6.28318530718" velocity="3.15"/>
    </joint>

    <joint name="joint4" type="revolute">
      <origin xyz="90 0 0" rpy="0 0 0"/>
      <parent link="tibia"/>
      <child link="tarsus"/>
      <axis xyz="0 0 1.0"/>
      <limit effort="150.0" lower="-6.28318530718" upper="6.28318530718" velocity="3.15"/>
    </joint>

    <joint name="joint5" type="fixed">
      <origin xyz="95 0 0" rpy="0 0 0"/>
      <parent link="tarsus"/>
      <child link="foot"/>
      <axis xyz="0 0 1.0"/>
      <limit effort="150.0" lower="-6.28318530718" upper="6.28318530718" velocity="3.15"/>
    </joint>

  </robot>

face_normals all zero, ignoring! message and no visualization

Hi!

I was trying to visualize a human hand with which I am working with.

I made the URDF and make the paths to the meshes relative as indicated. But when loading the model I am getting this messages for all the joints I believe:

face_normals all zero, ignoring!
face_normals all zero, ignoring!
face_normals all zero, ignoring!
face_normals all zero, ignoring!
face_normals all zero, ignoring!
face_normals all zero, ignoring!

And then when I try to visualize I get a crash error that tells me very little:

Traceback (most recent call last):
  File "urdfpy-test.py", line 23, in <module>
    u.show(cfg=cfg)
  File "/......//site-packages/urdfpy/urdf.py", line 3572, in show
    pyrender.Viewer(scene, use_raymond_lighting=True)
  File "/......//site-packages/pyrender/viewer.py", line 347, in __init__
    self._init_and_start_app()
  File "/......//site-packages/pyrender/viewer.py", line 997, in _init_and_start_app
    height=self._viewport_size[1])
  File "/......//site-packages/pyglet/window/xlib/__init__.py", line 173, in __init__
    super(XlibWindow, self).__init__(*args, **kwargs)
  File "/......//site-packages/pyglet/window/__init__.py", line 606, in __init__
    context = config.create_context(gl.current_context)
  File "/......//site-packages/pyglet/gl/xlib.py", line 204, in create_context
    return XlibContextARB(self, share)
  File "/......//site-packages/pyglet/gl/xlib.py", line 314, in __init__
    super(XlibContext13, self).__init__(config, share)
  File "/......//site-packages/pyglet/gl/xlib.py", line 218, in __init__
    raise gl.ContextException('Could not create GL context')
pyglet.gl.ContextException: Could not create GL context

I think the second part might have something to do with OpenGL, however can you explain to me the first messages please.

Announcement: friendly mantainance fork at https://github.com/fishbotics/urchin/

Hello everyone! I am helping mantain a library (https://github.com/icub-tech-iit/urdf-modifiers) that depends on urdfpy, and I am the mantainer of the urdfpy recipe on conda-forge. Unfortunatly, it is currently difficult to urdfpy with pip due to incompatibility with recent versions of Python and numpy (see #23 and #24).

Due to the lack of response from urdfpy mantainers, I created a friendly mantainance fork of this library at https://github.com/ami-iit/murdfpy/, with the latest fixes from @johannespitz and @fishbotics integrated (thanks a lot!), and I released it and made it available on PyPI: https://pypi.org/project/murdfpy/ Actually, after opening this issue I switched to use/help https://github.com/fishbotics/urchin/ .

The slight change of name was made to be able to upload the package to PyPI, but the API is exactly the same, to use you just need to change urdfpy to murdfpy, i.e. from urdfpy import URDF to from murdfpy import URDF.

If the urdfpy mantainers come back to mantain the library, I will be happy to take the friendly fork down, but as long as there is no reply from them, feel free to use it.

`np.int` was a deprecated alias for the builtin `int`.

Hey,
not working with recent NumPy versions >= 1.20!

from urdfpy import URDF

results in:

module 'numpy' has no attribute 'int'.
`np.int` was a deprecated alias for the builtin `int`. To avoid this error in existing code, use `int` by itself.
Doing this will not modify any behavior and is safe. When replacing `np.int`, you may wish to use e.g. `np.int64` or `np.int32` to specify the precision.
If you wish to review your current use, check the release note link for additional information.

Any plans on switching to builtin int?

regards

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.