feat: more urdf loader improvements
This commit is contained in:
committed by
Sébastien Crozet
parent
98e32b7f3c
commit
cfddaa3c46
@@ -9,6 +9,7 @@ stl = ["rapier-stl"]
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
anyhow = "1"
|
||||
bitflags = "2"
|
||||
# NOTE: we are not using the (more recent) urdf-rs crate because of https://github.com/openrr/urdf-rs/issues/94
|
||||
xurdf = "0.2"
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ use rapier3d::{
|
||||
},
|
||||
geometry::{
|
||||
Collider, ColliderBuilder, ColliderHandle, ColliderSet, MeshConverter, SharedShape,
|
||||
TriMeshFlags,
|
||||
},
|
||||
math::{Isometry, Point, Real, Vector},
|
||||
na,
|
||||
@@ -15,6 +16,15 @@ use std::collections::HashMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
use xurdf::{Collision, Geometry, Inertial, Joint, Pose, Robot};
|
||||
|
||||
bitflags::bitflags! {
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct UrdfMultibodyOptions: u8 {
|
||||
const JOINTS_ARE_KINEMATIC = 0b0001;
|
||||
const DISABLE_SELF_CONTACTS = 0b0010;
|
||||
}
|
||||
}
|
||||
|
||||
pub type LinkId = usize;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -24,6 +34,7 @@ pub struct UrdfLoaderOptions {
|
||||
pub apply_imported_mass_props: bool,
|
||||
pub enable_joint_collisions: bool,
|
||||
pub make_roots_fixed: bool,
|
||||
pub trimesh_flags: TriMeshFlags,
|
||||
pub shift: Isometry<Real>,
|
||||
pub collider_blueprint: ColliderBuilder,
|
||||
pub rigid_body_blueprint: RigidBodyBuilder,
|
||||
@@ -37,6 +48,7 @@ impl Default for UrdfLoaderOptions {
|
||||
apply_imported_mass_props: true,
|
||||
enable_joint_collisions: false,
|
||||
make_roots_fixed: false,
|
||||
trimesh_flags: TriMeshFlags::all(),
|
||||
shift: Isometry::identity(),
|
||||
collider_blueprint: ColliderBuilder::ball(0.0).density(0.0),
|
||||
rigid_body_blueprint: RigidBodyBuilder::dynamic(),
|
||||
@@ -77,6 +89,15 @@ pub struct UrdfRobot {
|
||||
pub joints: Vec<UrdfJoint>,
|
||||
}
|
||||
|
||||
impl UrdfRobot {
|
||||
pub fn append_transform(&mut self, transform: &Isometry<Real>) {
|
||||
for link in &mut self.links {
|
||||
link.body
|
||||
.set_position(transform * link.body.position(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UrdfJointHandle<JointHandle> {
|
||||
pub joint: JointHandle,
|
||||
pub link1: RigidBodyHandle,
|
||||
@@ -237,6 +258,7 @@ impl UrdfRobot {
|
||||
rigid_body_set: &mut RigidBodySet,
|
||||
collider_set: &mut ColliderSet,
|
||||
joint_set: &mut MultibodyJointSet,
|
||||
multibody_options: UrdfMultibodyOptions,
|
||||
) -> UrdfRobotHandles<Option<MultibodyJointHandle>> {
|
||||
let links: Vec<_> = self
|
||||
.links
|
||||
@@ -257,7 +279,20 @@ impl UrdfRobot {
|
||||
.map(|joint| {
|
||||
let link1 = links[joint.link1].body;
|
||||
let link2 = links[joint.link2].body;
|
||||
let joint = joint_set.insert(link1, link2, joint.joint, false);
|
||||
let joint =
|
||||
if multibody_options.contains(UrdfMultibodyOptions::JOINTS_ARE_KINEMATIC) {
|
||||
joint_set.insert_kinematic(link1, link2, joint.joint, false)
|
||||
} else {
|
||||
joint_set.insert(link1, link2, joint.joint, false)
|
||||
};
|
||||
|
||||
if let Some(joint) = joint {
|
||||
let (multibody, _) = joint_set.get_mut(joint).unwrap_or_else(|| unreachable!());
|
||||
multibody.set_self_contacts_enabled(
|
||||
!multibody_options.contains(UrdfMultibodyOptions::DISABLE_SELF_CONTACTS),
|
||||
);
|
||||
}
|
||||
|
||||
UrdfJointHandle {
|
||||
joint,
|
||||
link1,
|
||||
@@ -304,7 +339,7 @@ fn urdf_to_collider(
|
||||
) -> Option<Collider> {
|
||||
let mut builder = options.collider_blueprint.clone();
|
||||
let mut shape_transform = Isometry::identity();
|
||||
let shape = match &geometry {
|
||||
let mut shape = match &geometry {
|
||||
Geometry::Box { size } => SharedShape::cuboid(
|
||||
size[0] as Real / 2.0,
|
||||
size[1] as Real / 2.0,
|
||||
@@ -326,7 +361,11 @@ fn urdf_to_collider(
|
||||
#[cfg(feature = "stl")]
|
||||
Some("stl") | Some("STL") => {
|
||||
let full_path = mesh_dir.map(|dir| dir.join(filename)).unwrap_or_default();
|
||||
match rapier_stl::load_from_path(&full_path, MeshConverter::TriMesh, scale) {
|
||||
match rapier_stl::load_from_path(
|
||||
&full_path,
|
||||
MeshConverter::TriMeshWithFlags(options.trimesh_flags),
|
||||
scale,
|
||||
) {
|
||||
Ok(stl_shape) => {
|
||||
shape_transform = stl_shape.pose;
|
||||
stl_shape.shape
|
||||
|
||||
@@ -89,6 +89,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
link_id,
|
||||
&options,
|
||||
&Isometry::from(target_point),
|
||||
|_| true,
|
||||
&mut displacements,
|
||||
);
|
||||
multibody.apply_displacements(displacements.as_slice());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use rapier3d::prelude::*;
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier_urdf::{UrdfLoaderOptions, UrdfRobot};
|
||||
use rapier_urdf::{UrdfLoaderOptions, UrdfMultibodyOptions, UrdfRobot};
|
||||
use std::path::Path;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
@@ -17,28 +18,28 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
let options = UrdfLoaderOptions {
|
||||
create_colliders_from_visual_shapes: true,
|
||||
create_colliders_from_collision_shapes: false,
|
||||
apply_imported_mass_props: false,
|
||||
make_roots_fixed: true,
|
||||
// Z-up to Y-up.
|
||||
shift: Isometry::rotation(Vector::x() * std::f32::consts::FRAC_PI_2),
|
||||
rigid_body_blueprint: RigidBodyBuilder::default().gravity_scale(1.0),
|
||||
collider_blueprint: ColliderBuilder::default()
|
||||
.density(1.0)
|
||||
.active_collision_types(ActiveCollisionTypes::empty()),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let (mut robot, _) =
|
||||
UrdfRobot::from_file("assets/3d/T12/urdf/T12.URDF", options, None).unwrap();
|
||||
// let (mut robot, _) = UrdfRobot::from_file("assets/3d/sample.urdf", options).unwrap();
|
||||
|
||||
// robot.insert_using_impulse_joints(&mut bodies, &mut colliders, &mut impulse_joints);
|
||||
robot.insert_using_multibody_joints(&mut bodies, &mut colliders, &mut multibody_joints);
|
||||
|
||||
testbed.add_callback(move |mut graphics, physics, _, state| {
|
||||
for (_, body) in physics.bodies.iter() {
|
||||
println!("pose: {:?}", body.position());
|
||||
}
|
||||
});
|
||||
// The robot can be inserted using impulse joints.
|
||||
// (We clone because we want to insert the same robot once more afterward.)
|
||||
robot
|
||||
.clone()
|
||||
.insert_using_impulse_joints(&mut bodies, &mut colliders, &mut impulse_joints);
|
||||
// Insert the robot a second time, but using multibody joints this time.
|
||||
robot.append_transform(&Isometry::translation(10.0, 0.0, 0.0));
|
||||
robot.insert_using_multibody_joints(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut multibody_joints,
|
||||
UrdfMultibodyOptions::DISABLE_SELF_CONTACTS,
|
||||
);
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
|
||||
Reference in New Issue
Block a user