Skip to content

Commit 95288fa

Browse files
authored
Fix wrong sign in MassProperties::construct_shifted_inertia_matrix (#334)
1 parent 8c82fb2 commit 95288fa

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
### Fix
2424

2525
- Fix trimesh inertia tensor computation [#331](https://github.com/dimforge/parry/pull/331).
26+
- Fix shifted inertia tensor computation [#334](https://github.com/dimforge/parry/pull/334).
2627

2728
## v0.18.0
2829

src/mass_properties/mass_properties.rs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ impl MassProperties {
202202
let mass = 1.0 / self.inv_mass;
203203
let diag = shift.norm_squared();
204204
let diagm = Matrix3::from_diagonal_element(diag);
205-
matrix + (diagm + shift * shift.transpose()) * mass
205+
matrix + (diagm - shift * shift.transpose()) * mass
206206
} else {
207207
matrix
208208
}
@@ -590,10 +590,68 @@ mod test {
590590
assert_relative_eq!((((m1m2m3 - m1) - m2) - m3).mass(), 0.0, epsilon = 1.0e-6);
591591
}
592592

593+
#[test]
594+
#[cfg(feature = "alloc")]
595+
fn mass_properties_compound() {
596+
use na::Isometry;
597+
598+
use crate::{
599+
math::Vector,
600+
shape::{Compound, Cuboid, SharedShape},
601+
};
602+
603+
// Compute the mass properties of a compound shape made of three 1x1x1 cuboids.
604+
let shape = Cuboid::new(Vector::repeat(0.5));
605+
let mp = shape.mass_properties(1.0);
606+
let iso2 = Isometry::from_parts(Vector::y().into(), Default::default());
607+
let iso3 = Isometry::from_parts((-Vector::y()).into(), Default::default());
608+
609+
// Test sum shifted result through `MassProperties::add`
610+
let sum = [mp, mp.transform_by(&iso2), mp.transform_by(&iso3)]
611+
.into_iter()
612+
.sum::<MassProperties>();
613+
614+
// Test compound through `MassProperties::from_compound`
615+
let compound_shape = Compound::new(vec![
616+
(
617+
Isometry::from_parts(Vector::default().into(), Default::default()),
618+
SharedShape::new(shape),
619+
),
620+
(iso2, SharedShape::new(shape)),
621+
(iso3, SharedShape::new(shape)),
622+
]);
623+
let mp_compound = compound_shape.mass_properties(1.0);
624+
625+
// Check that the mass properties of the compound shape match the mass properties
626+
// of a single 1x3x1 cuboid.
627+
#[cfg(feature = "dim2")]
628+
let expected = Cuboid::new(Vector::new(0.5, 1.5)).mass_properties(1.0);
629+
#[cfg(feature = "dim3")]
630+
let expected = Cuboid::new(Vector::new(0.5, 1.5, 0.5)).mass_properties(1.0);
631+
632+
// Sum shifted
633+
assert_relative_eq!(sum.local_com, expected.local_com, epsilon = 1.0e-6);
634+
assert_relative_eq!(sum.inv_mass, expected.inv_mass, epsilon = 1.0e-6);
635+
assert_relative_eq!(
636+
sum.inv_principal_inertia_sqrt,
637+
expected.inv_principal_inertia_sqrt,
638+
epsilon = 1.0e-6
639+
);
640+
641+
// Compound
642+
assert_relative_eq!(mp_compound.local_com, expected.local_com, epsilon = 1.0e-6);
643+
assert_relative_eq!(mp_compound.inv_mass, expected.inv_mass, epsilon = 1.0e-6);
644+
assert_relative_eq!(
645+
mp_compound.inv_principal_inertia_sqrt,
646+
expected.inv_principal_inertia_sqrt,
647+
epsilon = 1.0e-6
648+
);
649+
}
650+
593651
#[test]
594652
#[cfg(feature = "alloc")]
595653
fn mass_properties_sum_no_nan() {
596-
let mp: MassProperties = [MassProperties::zero()].iter().map(|v| *v).sum();
654+
let mp: MassProperties = [MassProperties::zero()].iter().copied().sum();
597655
assert!(!mp.local_com.x.is_nan() && !mp.local_com.y.is_nan());
598656
#[cfg(feature = "dim3")]
599657
assert!(!mp.local_com.z.is_nan());

0 commit comments

Comments
 (0)