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::EMPTYSelf-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

rust
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 checked

The 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

rust
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

rust
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

rust
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.

API reference