Giter Site home page Giter Site logo

urdf-rs's Introduction

urdf-rs

Build Status crates.io docs discord

URDF parser for Rust.

Only link and joint are supported.

Example

You can access urdf elements like below example.

let urdf_robot = urdf_rs::read_file("sample.urdf").unwrap();
let links = urdf_robot.links;
println!("{:?}", links[0].visual[0].origin.xyz);
let joints = urdf_robot.joints;
println!("{:?}", joints[0].origin.xyz);

OpenRR Community

Here is a discord server for OpenRR users and developers.

urdf-rs's People

Contributors

andrewjschoen avatar dependabot[bot] avatar jafarabdi avatar kaaatsu32329 avatar luca-della-vedova avatar neachdainn avatar otl avatar patrvanh avatar repi avatar taiki-e avatar tgolsson avatar wschella 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

Watchers

 avatar  avatar  avatar  avatar  avatar

urdf-rs's Issues

Sort collision and visual in link

Currently, if there are link has visual, collision, visual... it causes duplicate error. We already solved this problem by sorting the element like here.

[Feature Request] JointLimit should be inferred to be unlimited if a urdf has no explicitely defined JointLimit.

Looking at deserialize.rs

#[derive(Debug, YaDeserialize, YaSerialize, Default, Clone)]
pub struct JointLimit {
    #[yaserde(attribute)]
    pub lower: f64,
    #[yaserde(attribute)]
    pub upper: f64,
    #[yaserde(attribute)]
    pub effort: f64,
    #[yaserde(attribute)]
    pub velocity: f64,
}

f64 defaults to 0.0, this means the max lower and upper bound is inferred to be 0.0. This means, if a urdf has no explicitely defined joint limit, urdf-rs defaults to the joint not being able to move at all

I think Default for JointLimit should be changed to the below to fix that.

impl Default for JointLimit {
    fn default() -> Self {
        Self {
            lower: f64::MIN,
            upper: f64::MAX,
            effort: f64::MAX,
            velocity: f64::MAX,
        }
    }
}

[BUG] If <origin> is below <geometry> in a urdf file, then <origin> doesn't load.

E.G: the below code will cause right_leg have its origin set to xyz = [0, 0, 0] and rpy = [0, 0, 0], even though it is a valid xml that does not error when loaded by urdf_rs

invalid

<?xml version="1.0"?>
<robot name="origins">
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.6" radius="0.2"/>
      </geometry>
    </visual>
  </link>

  <link name="right_leg">
    <visual>
      <geometry>
        <box size="0.6 0.1 0.2"/>
      </geometry>
      <origin rpy="0 1.57075 0" xyz="0 0 -0.3"/>
    </visual>
  </link>

  <joint name="base_to_right_leg" type="fixed">
    <parent link="base_link"/>
    <child link="right_leg"/>
    <origin xyz="0 -0.22 0.25"/>
  </joint>

</robot>

valid

<?xml version="1.0"?>
<robot name="origins">
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.6" radius="0.2"/>
      </geometry>
    </visual>
  </link>

  <link name="right_leg">
    <visual>
      <origin rpy="0 1.57075 0" xyz="0 0 -0.3"/>
      <geometry>
        <box size="0.6 0.1 0.2"/>
      </geometry>
    </visual>
  </link>

  <joint name="base_to_right_leg" type="fixed">
    <parent link="base_link"/>
    <child link="right_leg"/>
    <origin xyz="0 -0.22 0.25"/>
  </joint>

</robot>

Bad namespace

I'm trying to view a urdf file made by the OnShape importer, and I'm getting this:

Error: Urdf(UrdfError(Other("bad namespace for robot, found http://www.ros.org")))

What should the namespace be and can the importer be changed to issue a warning instead?

Improve xacro error

When xacro failed, urdf-viz says only

Error: Urdf(UrdfError(Command("faild to xacro")))

It should return everything xacro says.

SDFormat

The URDF and SDF file formats are very similar in a lot of ways - any start to an sdformat parser would likely be a fork from this work (case in point).

Would you be willing to accept contributions to add SDF parsing alongside URDF parsing to help maximise code-reuse?

write_to_string exports with "Robot" tag instead of "robot"

The write_to_string function uses uppercase "Robot" tag. This can't be used directly by Rviz (and probably other ROS tools) without converting to lowercase "robot" tag.

Simple work around:

urdf_rs::write_to_string(&urdf)?.replace("<Robot", "<robot").replace("</Robot", "</robot")

Color in material doesn't seem to parse.

Using this test urdf:

let urdf = r#"<robot name="test">"
  <joint name="j1" type="fixed">
    <parent link="l1"/>
    <child link="l2"/>
  </joint>
  <joint name="j2" type="fixed">
    <parent link="l1"/>
    <child link="l2"/>
  </joint>
  <link name="l1">
    <visual>
      <geometry>
        <sphere radius="1.349"/>
      </geometry>
      <material name="">
        <color rgba="1.0 0.65 0.0 0.01" />
      </material>
    </visual>
    <inertial>
      <mass value="8.4396"/>
      <inertia ixx="0.087" ixy="0.14" ixz="0.912" iyy="0.763" iyz="0.0012" izz="0.908"/>
    </inertial>
  </link>
  <link name="l2">
    <visual>
      <geometry>
        <cylinder radius="3.349" length="7.5490"/>
      </geometry>
      <material name="red ish">
        <color rgba="1 0.0001 0.0 1" />
      </material>
    </visual>
  </link>
</robot>"#;

I parse calling your read_from_string function, the color value is always a None. Here is a debug output of each of the visual objects after the parse:

&l.visual = [
    Visual {
        name: Some(
            "",
        ),
        origin: Pose {
            xyz: Vec3(
                [
                    0.0,
                    0.0,
                    0.0,
                ],
            ),
            rpy: Vec3(
                [
                    0.0,
                    0.0,
                    0.0,
                ],
            ),
        },
        geometry: Sphere {
            radius: 1.349,
        },
        material: Some(
            Material {
                name: "",
                color: None,
                texture: None,
            },
        ),
    },
]
&l.visual = [
    Visual {
        name: Some(
            "red ish",
        ),
        origin: Pose {
            xyz: Vec3(
                [
                    0.0,
                    0.0,
                    0.0,
                ],
            ),
            rpy: Vec3(
                [
                    0.0,
                    0.0,
                    0.0,
                ],
            ),
        },
        geometry: Cylinder {
            radius: 3.349,
            length: 7.549,
        },
        material: Some(
            Material {
                name: "",
                color: None,
                texture: None,
            },
        ),
    },
]

Consider moving away from yaserde

We have switched to yaserde from serde-xml-rs in #64. However, many bugs have been introduced since then, some of which have not yet been fixed.

I'm no longer happy with continuing to use this difficult-to-use crate.
I'm considering moving away from it, at least on deserialization.

Candidates for alternatives in my mind are serde-xml-rs, which was used previously, and roxmltree, which is currently used in mesh-loader. We should not use anything we have no experience with or are not familiar with, like yaserde.
Both support deserialization only; as for serialization, we can continue to use yaserde, or we can consider replacing it with our own. Anyway, it is important to fix deserialization, which obviously has correctness problems.

FYI @luca-della-vedova

`Option` type for optional tags

Currently, any optional URDF tags are represented by providing default values. Unfortunately, this makes it difficult to distinguish between times when the URDF is using the tag but has default values versus it just being a default value.

An example of this would be the safety controller: there is currently no way to distinguish if there are safety limits present or not. Ignoring safety values, even if the default, is likely bad form and potentially physically dangerous.

Rust error from {argument}

error: there is no argument named s
--> /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/urdf-rs-0.6.3/src/deserialize.rs:134:49
|
134 | "failed to parse float array in {s}"
| ^^^

error: there is no argument named s
--> /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/urdf-rs-0.6.3/src/deserialize.rs:162:49
|
162 | "failed to parse float array in {s}"
| ^^^

error: there is no argument named s
--> /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/urdf-rs-0.6.3/src/deserialize.rs:181:49
|
181 | "failed to parse float array in {s}"
| ^^^

error: there is no argument named new_elm
--> /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/urdf-rs-0.6.3/src/funcs.rs:27:17
|
27 | Ok(format!("{new_elm}"))
| ^^^^^^^^^

Is there an easy way to resolve this beyond without having to modify code or forking the repo?

Inertial Data ignored

This was initially found from within the k library, but basically the inertial data seems to be ignored on input to the read_from_string function. For example, with the URDF example provided in this repo, the initial link has the following specification:

<link name="root">
    <inertial>
      <origin xyz="0 0 0.5" rpy="0 0 0"/>
      <mass value="1"/>
      <inertia ixx="100"  ixy="0"  ixz="0" iyy="100" iyz="0" izz="100" />
    </inertial>
    <visual>
      <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
      <geometry>
        <box size="0.2 0.2 0.4" />
      </geometry>
      <material name="Cyan">
        <color rgba="1.0 1.0 1.0 1.0"/>
      </material>
    </visual>
    <collision>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <geometry>
        <cylinder radius="1" length="0.5"/>
      </geometry>
    </collision>
  </link>

However, when loaded, it has the following parsed data:

Link { 
    name: "root_body", 
    inertial: Inertial { 
        origin: Pose { 
            xyz: [0.0, 0.0, 0.0], 
            rpy: [0.0, 0.0, 0.0] 
        }, 
        mass: Mass { 
            value: 0.0 
        }, 
        inertia: Inertia { 
            ixx: 0.0, ixy: 0.0, ixz: 0.0, iyy: 0.0, iyz: 0.0, izz: 0.0 
        } 
    },
    ...
}

This leads to functions like center_of_mass failing.

Edit: Confirming this, I added a check in the test function:

assert_eq!(robot.links[0].inertial.mass.value, 1.0);

And it fails as expected:

running 2 tests
test funcs::it_works ... FAILED
test utils::it_works ... ok

failures:

---- funcs::it_works stdout ----
thread 'funcs::it_works' panicked at 'assertion failed: `(left == right)`
  left: `0.0`,
 right: `1.0`', src/funcs.rs:186:5

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.