rapier
rapier copied to clipboard
Panic in simulation with rigid bodies of small mass
In my simulation I create rigid bodies with small radius, rigid bodies start free falling, and when body reaches some distance from origin I remove it from simulation. I expect this simulation to be stable, but at some values of rigid body radius (mass?) and distance limit, simulation panics with error:
step 1413, max d 1001.3681, rb count 285, c count 285
step 1416, max d 1001.3681, rb count 285, c count 285
step 1419, max d 1001.3681, rb count 285, c count 285
thread 'main' panicked at 'assertion failed: proxy.aabb.maxs[dim] >= self.min_bound', /rapier2d-0.11.1/src/geometry/broad_phase_multi_sap/sap_axis.rs:55:13
code for reproducing issue (panics at about step 1400 for me):
[dependencies]
rapier2d = "0.11"
use rapier2d::prelude::*;
fn main() {
let mut physics_pipeline = PhysicsPipeline::new();
let gravity = vector![0.0, -9.8];
let integration_parameters = IntegrationParameters::default();
let mut island_manager = IslandManager::new();
let mut broad_phase = BroadPhase::new();
let mut narrow_phase = NarrowPhase::new();
let mut rigid_body_set = RigidBodySet::new();
let mut collider_set = ColliderSet::new();
let mut joint_set = JointSet::new();
let mut ccd_solver = CCDSolver::new();
let mut handles = vec![];
let mut step_count: usize = 0;
loop {
let h = rigid_body_set.insert(
RigidBodyBuilder::new_dynamic()
.translation(vector![0.0, 0.0])
.build(),
);
// rb will have mass 0.0003
collider_set.insert_with_parent(
// increasing radius will make simulation stable
ColliderBuilder::ball(0.01).build(),
h,
&mut rigid_body_set,
);
handles.push(h);
for _ in 0..3 {
let physics_hooks = ();
let event_handler = ();
physics_pipeline.step(
&gravity,
&integration_parameters,
&mut island_manager,
&mut broad_phase,
&mut narrow_phase,
&mut rigid_body_set,
&mut collider_set,
&mut joint_set,
&mut ccd_solver,
&physics_hooks,
&event_handler,
);
step_count += 1;
}
let mut max_distance: f32 = 0.0;
let mut keep_handles = vec![];
for h in handles {
let rb = rigid_body_set.get(h).unwrap();
max_distance = max_distance.max(rb.translation().norm());
// with lower distance limit, simulation becomes more stable
if rb.translation().norm() > 1000.0 {
rigid_body_set.remove(
h,
&mut &mut island_manager,
&mut &mut collider_set,
&mut &mut joint_set,
);
} else {
keep_handles.push(h);
}
}
handles = keep_handles;
println!(
"step {}, max d {}, rb count {}, c count {}",
step_count,
max_distance,
rigid_body_set.len(),
collider_set.len()
);
}
}
I believe it's independent of mass: the same assert triggers at the same iteration even if I increase the density to some very high number. It appears to be more related to the small size of the collider, as the bounding boxes are wrong. The assert triggers because of a small difference in the boundaries, but I do not understand the code well enough to diagnose why.
Maybe some accumulation of rounding error when the boxes get updated when you remove them? The boundary you set for deletion (1000.0) is 5 orders of magnitude larger than the radius of the balls, so it seems reasonable that this might be the case.
Using the provided test code, I am not able to reproduce this issue with the latest version of Rapier. Closing as fixed, but please reopen with a new test case if the problem still happens.