Tutorial 3: Managing Collision Objects¶
This tutorial covers everything about adding, managing, and debugging collision objects in curobo_ros. You’ll learn how to:
Add different types of obstacles (boxes, spheres, cylinders, meshes)
Manage objects dynamically
Visualize collision checking
Debug collision issues
Use objects with both motion planning and IK
Overview¶
curobo_ros supports dynamic obstacle management. You can add or remove objects at runtime, and the planner will automatically avoid them.
Key Features:
Multiple object types (cuboid, sphere, cylinder, capsule, mesh)
Real-time updates (no restart needed)
Works with both trajectory generation and IK
Voxel-based collision checking (GPU-accelerated)
Visualization in RViz
Prerequisites¶
unified_planner node running
Basic understanding of 3D coordinates and orientations
# Launch the system
ros2 launch curobo_ros gen_traj.launch.py
Object Types¶
curobo_ros supports 5 object types:
Type |
ID |
Description |
Required Dimensions |
|---|---|---|---|
CUBOID |
0 |
Box with width, length, height |
|
SPHERE |
1 |
Ball with radius |
|
CAPSULE |
2 |
Cylinder with hemispherical caps |
|
CYLINDER |
3 |
Cylinder with radius and height |
|
MESH |
4 |
Custom mesh from file |
|
Note: Non-cuboid primitives are handled as their respective cuRobo geometry types. Meshes are voxelized into OBBs for the BLOX collision checker.
Adding Objects¶
1. Adding a Box (Cuboid)¶
ros2 service call /unified_planner/add_object curobo_msgs/srv/AddObject \
"{
name: 'table',
type: 0,
pose: {
position: {x: 0.5, y: 0.0, z: 0.2},
orientation: {w: 1.0, x: 0.0, y: 0.0, z: 0.0}
},
dimensions: {x: 1.0, y: 0.6, z: 0.05},
color: {r: 0.7, g: 0.5, b: 0.3, a: 0.9}
}"
Parameters:
name: Unique identifier (used to remove later)type: 0 for cuboidpose.position: Center of the box (meters)pose.orientation: Quaternion (for cuboids, rotation is supported)dimensions: Size in x, y, z (meters)color: RGBA (0-1 range) for visualization
Response:
success: true
message: "Object 'table' added successfully (1 cuboids, 0 mesh in world)"
2. Adding a Sphere¶
ros2 service call /unified_planner/add_object curobo_msgs/srv/AddObject \
"{
name: 'ball',
type: 1,
pose: {
position: {x: 0.6, y: 0.3, z: 0.4},
orientation: {w: 1.0, x: 0, y: 0, z: 0}
},
dimensions: {x: 0.08, y: 0.08, z: 0.08},
color: {r: 1.0, g: 0.0, b: 0.0, a: 0.8}
}"
Important: For spheres, set x = y = z = radius.
3. Adding a Cylinder¶
ros2 service call /unified_planner/add_object curobo_msgs/srv/AddObject \
"{
name: 'pillar',
type: 3,
pose: {
position: {x: 0.4, y: -0.3, z: 0.25},
orientation: {w: 1.0, x: 0, y: 0, z: 0}
},
dimensions: {x: 0.05, y: 0.05, z: 0.5},
color: {r: 0.5, g: 0.5, b: 0.5, a: 0.9}
}"
Dimensions:
x = y: Radius of cylinderz: Height of cylinder
Note: Cylinder is aligned with Z-axis by default.
4. Adding a Mesh¶
ros2 service call /unified_planner/add_object curobo_msgs/srv/AddObject \
"{
name: 'custom_part',
type: 4,
pose: {
position: {x: 0.5, y: 0.0, z: 0.3},
orientation: {w: 1.0, x: 0, y: 0, z: 0}
},
mesh_file_path: '/path/to/mesh.stl',
dimensions: {x: 1.0, y: 1.0, z: 1.0},
color: {r: 0.0, g: 1.0, b: 1.0, a: 0.8}
}"
Parameters:
mesh_file_path: Absolute path to.stlor.objmesh filedimensions: Scale factors for x, y, z axes (1.0 = original size, 0.01 = 1/100th scale)
Important: Meshes are voxelized into oriented bounding boxes (OBBs) for the BLOX collision checker. Set the OBB cache large enough before adding the mesh (see Tutorial 3: Collision Cache).
Managing Objects¶
List All Objects¶
ros2 service call /unified_planner/get_obstacles std_srvs/srv/Trigger
Response:
success: true
message: "table, ball, pillar, custom_part"
Remove Specific Object¶
ros2 service call /unified_planner/remove_object curobo_msgs/srv/RemoveObject \
"{name: 'ball'}"
Response:
success: true
message: "Object 'ball' removed successfully (sphere)"
Remove All Objects¶
ros2 service call /unified_planner/remove_all_objects std_srvs/srv/Trigger
Response:
success: true
message: "All objects removed successfully (0 cuboids, 0 meshes)"
Disabling Link Collision Spheres¶
You can enable or disable collision spheres for specific robot links at runtime. This is useful to allow the gripper to make contact with an object during grasping, or to ignore self-collision for a specific link during a constrained motion.
All solvers (MotionGen, MPC) share the same kinematics configuration, so a single call immediately affects every active planner.
Disable a link¶
ros2 service call /unified_planner/set_link_collision \
curobo_msgs/srv/SetLinkCollision \
"{link_names: ['link6'], enabled: false}"
Response:
success: true
message: "Collision disabled for ['link6']"
applied_links: ['link6']
unknown_links: []
Disable multiple links¶
ros2 service call /unified_planner/set_link_collision \
curobo_msgs/srv/SetLinkCollision \
"{link_names: ['link5', 'link6'], enabled: false}"
Re-enable links¶
ros2 service call /unified_planner/set_link_collision \
curobo_msgs/srv/SetLinkCollision \
"{link_names: ['link5', 'link6'], enabled: true}"
Notes:
The state persists until an explicit call with the opposite
enabledvalue.Unknown link names are reported in
unknown_linksand ignored.Disabled spheres are hidden from the collision sphere visualization (see below).
Visualizing Collision Checking¶
Robot Collision Spheres¶
The robot is represented as a collection of spheres for collision checking. Publishing is disabled by default to avoid interference during MPC initialization.
Enable publishing:
ros2 service call /unified_planner/set_collision_spheres_enabled \
std_srvs/srv/SetBool "{data: true}"
View collision spheres:
ros2 topic echo /unified_planner/collision_spheres
In RViz:
Add → MarkerArray
Topic:
/unified_planner/collision_spheresYou’ll see red semi-transparent spheres covering the robot
Spheres belonging to disabled links (via set_link_collision) are automatically
hidden from this visualization.
Update rate: 0.5 Hz (twice per second)
Voxel Grid Visualization¶
The environment is discretized into voxels for collision checking. Be carefull, this kind of operation is really GPU demanding and could ask a lot of VRAM.
Get voxel grid:
ros2 service call /unified_planner/get_voxel_grid curobo_msgs/srv/GetVoxelGrid
Response includes:
Voxel grid dimensions
Occupied voxels
Resolution (voxel size)
Collision Distance Checking¶
Check how close the robot is to obstacles:
ros2 service call /unified_planner/get_collision_distance curobo_msgs/srv/GetCollisionDistance
Response:
data: [0.15, 0.23, 0.08, ...] # Distance for each collision sphere
nb_sphere: 13
Interpretation:
Positive values: Distance to nearest obstacle (meters)
Negative values: Penetration depth (collision!)
Large values: Far from obstacles
Use case: Safety monitoring during execution.
Example: Building a Scene¶
Let’s build a complete scene with multiple obstacles:
# 1. Add a table
ros2 service call /unified_planner/add_object curobo_msgs/srv/AddObject \
"{name: 'table', type: 0,
pose: {position: {x: 0.5, y: 0.0, z: 0.15}, orientation: {w: 1.0, x: 0, y: 0, z: 0}},
dimensions: {x: 0.8, y: 1.0, z: 0.05},
color: {r: 0.6, g: 0.4, b: 0.2, a: 0.9}}"
# 2. Add walls
ros2 service call /unified_planner/add_object curobo_msgs/srv/AddObject \
"{name: 'wall_left', type: 0,
pose: {position: {x: 0.5, y: -0.6, z: 0.5}, orientation: {w: 1.0, x: 0, y: 0, z: 0}},
dimensions: {x: 1.5, y: 0.05, z: 1.0},
color: {r: 0.8, g: 0.8, b: 0.8, a: 0.5}}"
ros2 service call /unified_planner/add_object curobo_msgs/srv/AddObject \
"{name: 'wall_right', type: 0,
pose: {position: {x: 0.5, y: 0.6, z: 0.5}, orientation: {w: 1.0, x: 0, y: 0, z: 0}},
dimensions: {x: 1.5, y: 0.05, z: 1.0},
color: {r: 0.8, g: 0.8, b: 0.8, a: 0.5}}"
# 3. Add a hanging obstacle
ros2 service call /unified_planner/add_object curobo_msgs/srv/AddObject \
"{name: 'ceiling_lamp', type: 1,
pose: {position: {x: 0.6, y: 0.2, z: 0.8}, orientation: {w: 1.0, x: 0, y: 0, z: 0}},
dimensions: {x: 0.15, y: 0.15, z: 0.15},
color: {r: 1.0, g: 1.0, b: 0.0, a: 0.7}}"
# 4. Add objects on table
ros2 service call /unified_planner/add_object curobo_msgs/srv/AddObject \
"{name: 'box_on_table', type: 0,
pose: {position: {x: 0.4, y: 0.1, z: 0.25}, orientation: {w: 1.0, x: 0, y: 0, z: 0}},
dimensions: {x: 0.1, y: 0.1, z: 0.15},
color: {r: 0.0, g: 0.5, b: 1.0, a: 0.9}}"
Now plan a trajectory - it will avoid all obstacles!
ros2 service call /unified_planner/generate_trajectory curobo_msgs/srv/TrajectoryGeneration \
"{target_pose: {position: {x: 0.6, y: 0.0, z: 0.5}, orientation: {w: 1.0, x: 0, y: 0, z: 0}}}"
Using IK with Obstacles¶
The IK solver on the unified planner shares the same obstacle world as the trajectory planners. Any object added via add_object is automatically visible to IK — no separate setup needed.
# Add an obstacle
ros2 service call /unified_planner/add_object curobo_msgs/srv/AddObject \
"{name: 'obstacle', type: 0, dimensions: {x: 0.2, y: 0.2, z: 0.2}, \
pose: {position: {x: 0.5, y: 0.0, z: 0.4}, orientation: {w: 1.0}}}"
# Warmup IK (required once)
ros2 service call /unified_planner/warmup_ik curobo_msgs/srv/WarmupIK "{batch_size: 1}"
# Solve IK — will return failure if target collides with the obstacle
ros2 service call /unified_planner/ik curobo_msgs/srv/Ik \
"{pose: {position: {x: 0.5, y: 0.0, z: 0.4}, orientation: {w: 1.0}}}"
See Tutorial 6: IK/FK Services for the full IK workflow.
For the complete service and topic reference, see ROS Interfaces — Collision Management.
Troubleshooting¶
Objects not appearing in RViz¶
Check:
Object was added successfully (check service response)
RViz has MarkerArray display for voxels
Object is within view frustum
Color alpha > 0 (not transparent)
Planning ignores obstacles¶
Possible causes:
Obstacle is outside planning space
voxel_sizeis too large (obstacle falls in “free” voxel)Collision checking disabled (check config)
Solutions:
# Use smaller voxels
ros2 launch curobo_ros gen_traj.launch.py voxel_size:=0.03
# Reload configuration
ros2 service call /unified_planner/update_motion_gen_config std_srvs/srv/Trigger
False collisions¶
Cause: Collision spheres too large or obstacle bounding box too large
Solutions:
Refine robot collision spheres in config file
Use cuboids instead of other shapes (more accurate bounding boxes)
Reduce
collision_activation_distance
Summary¶
You’ve learned:
✅ Adding different object types (cuboid, sphere, cylinder, mesh)
✅ Managing objects dynamically
✅ Disabling collision spheres per link (
set_link_collision)✅ Visualizing collision checking and disabled links
✅ Debugging collision issues
Next Steps¶
Robot Execution - Connect to real robot or emulator
Camera Integration - Detect obstacles automatically with cameras
Parameters Guide - Tune collision checking parameters