Collision · repose-collision
Checking configurations
A check places the robot at a configuration and compares its shapes against itself and an environment. You choose between a full report and a fast yes/no.
The environment: CuCollisionEnv
A borrowed, zero-copy view of everything outside the robot's own model:
CuCollisionEnv::EMPTY | Self-collision only. |
CuCollisionEnv::new(&obstacles) | Anonymous world-frame obstacles from a slice of shapes. |
.with_attached(&attached) | Adds shapes attached to robot frames, such as a held part. |
.with_exclusions(&exclusions) | Adds stable-ID pair exclusions for attached shapes. |
scene.collision_env() | The obstacles and attached shapes of a planning scene, with their IDs, without copying. |
Full report
let mut report = CuCollisionReport::<16>::default();
model.check_configuration(&chain, &q, &env, &mut report)?;
if !report.is_collision_free() {
for c in report.as_slice() {
// c.kind: SelfCollision | EnvironmentCollision
// c.link_index: robot shape, c.partner_index: shape or obstacle index
// c.signed_distance: negative = penetration
}
}
let clearance = report.min_signed_distance(); // closest pair, +inf if nothing was checkedThe report is cleared first and holds up to MAX_CONTACTS contacts. total_contacts() counts every contact, including those that didn't fit, so you can tell when the report was truncated.
check_frames does the same from link frames you already computed, which saves an FK pass when you have them.
Fast predicate
let ok = model.is_configuration_collision_free(&chain, &q, &env)?;Returns false at the first violation and also when q is outside joint limits. Planners use this form. Err still means invalid input: a malformed environment or wrong units.
Segments
let ok = model.is_segment_collision_free(&chain, &q_a, &q_b, CuJointResolution::default(), &env)?;Checks the straight joint-space line from q_a to q_b by sampling: the number of samples is chosen so that no joint moves more than the resolution (0.08 rad / 1 cm by default) between two samples. This is how planners check edges. It is discrete, not a swept-volume guarantee, so choose the resolution with your thinnest obstacle and longest lever arm in mind: at 0.08 rad, a point 1 m from the joint moves 8 cm between samples.
Validation is part of every check
Before any distance is computed, the environment is validated against the model: attached shapes must reference existing frames, exclusions must reference IDs present in the environment and valid robot shape indices. An invalid environment is an Err, never a silently skipped check.
Pre-flight pattern
for (i, q) in program_configurations.iter().enumerate() {
if !chain.is_within_limits(q) {
return Err(CuError::from(format!("step {i}: outside joint limits")));
}
model.check_configuration(&chain, q, &scene.collision_env(), &mut report)?;
if !report.is_collision_free() {
return Err(CuError::from(format!("step {i}: collision, clearance {:?}", report.min_signed_distance())));
}
}This is what the robot-app template does before it moves anything: every step is solved and checked, and if one fails, nothing moves.