Tutorial 1: Your First Trajectory¶
Difficulty: Beginner · Time: ~20 min · Prerequisites: Installation complete
You will plan a motion from the command line, read the response, preview it in RViz, and execute it on the emulated robot.
1. Start the system¶
In the container:
ros2 launch curobo_ros gen_traj.launch.py robot:=emulator world_file:=$(ros2 pkg prefix curobo_ros)/share/curobo_ros/config/floor_world.yml
robot:=emulator runs the Doosan M1013 kinematics without hardware. The world_file adds a floor — without it the world is completely empty and the planner will happily swing the arm below the base.
Wait for warmup (25–35 s). The node is ready when:
ros2 param get /unified_planner node_is_available
# Boolean value is: True
Open a second shell in the container for the commands below:
docker exec -it curobo_ampere_dev bash
source /home/ros2_ws/install/setup.bash
2. Know your workspace¶
The default robot is a Doosan M1013: 6 DOF, ~1.3 m reach, base frame base_0. A comfortable target zone for this tutorial:
x: 0.3 to 0.9 m (in front of the robot)
y: −0.5 to 0.5 m
z: 0.1 to 0.8 m (above the base)
Orientation is a quaternion in the base frame. {x: 0, y: 1, z: 0, w: 0} points the tool straight down — a good default for tabletop poses.
3. Generate a trajectory¶
ros2 service call /unified_planner/generate_trajectory curobo_msgs/srv/TrajectoryGeneration \
"{target_pose: {position: {x: 0.5, y: 0.2, z: 0.4}, orientation: {x: 0.0, y: 1.0, z: 0.0, w: 0.0}}}"
A successful response looks like:
success: True
message: '...'
trajectory: [<sensor_msgs/JointState with position and velocity>, ...]
dt: 0.025
The trajectory field is an array of JointState waypoints; dt is the time step between them (the interpolation_dt parameter). In RViz, the translucent preview robot replays the plan — nothing has moved yet.
Things to try:
an unreachable pose (
x: 2.0) →success: Falsewith an IK error inmessage;different orientations — e.g.
{x: 0, y: 0, z: 0, w: 1}(tool pointing up along +z).
4. Execute it¶
Planning and execution are separate. Execution goes through the execute_trajectory action; on the emulator the “robot” is simulated, so this is always safe:
ros2 action send_goal /unified_planner/execute_trajectory curobo_msgs/action/SendTrajectory \
"{target_pose: {position: {x: 0.5, y: 0.2, z: 0.4}, orientation: {x: 0.0, y: 1.0, z: 0.0, w: 0.0}}}" --feedback
Because the goal matches the plan you just generated (and allow_cached defaults to true), the action reuses the cached trajectory instead of re-planning, then streams it. Feedback shows state: EXECUTING and step_progression climbing from 0 to 1; the main RViz robot follows.
You can also skip step 3 entirely — the action plans by itself when there is no cached trajectory.
5. Add an obstacle and re-plan¶
ros2 service call /unified_planner/add_object curobo_msgs/srv/AddObject \
"{type: 0, name: 'table', pose: {position: {x: 0.6, y: 0.0, z: 0.1}, orientation: {w: 1.0}}, \
dimensions: {x: 0.8, y: 1.0, z: 0.05}, color: {r: 0.5, g: 0.3, b: 0.1, a: 1.0}}"
This adds a 0.8 × 1.0 × 0.05 m tabletop centred 0.6 m in front of the base at z = 0.1 m (dimensions are full extents for a cuboid). It appears in RViz via the /unified_planner/scene_obstacles markers. Re-run the generate_trajectory call from step 3: the new plan curves around the table.
List and clean up:
ros2 service call /unified_planner/get_obstacles std_srvs/srv/Trigger
ros2 service call /unified_planner/remove_object curobo_msgs/srv/RemoveObject "{name: 'table'}"
Obstacle types, dimension semantics, meshes, and attachment are covered in Tutorial 3.
6. Tune a parameter¶
Two examples that illustrate the two kinds of parameters (full list in the Parameters Guide):
# Plan-time: takes effect on the next request, no rebuild
ros2 param set /unified_planner max_attempts 3
# Build-time: requires a solver rebuild (~20 s, blocking)
ros2 param set /unified_planner voxel_size 0.03
ros2 service call /unified_planner/update_motion_gen_config std_srvs/srv/Trigger
Common issues¶
Symptom |
Likely cause |
Fix |
|---|---|---|
|
Pose out of reach or in collision |
Bring the target into the zone from step 2; check obstacles |
Service call hangs forever |
Node still warming up |
Wait for |
Plan goes through an obstacle you see in RViz |
Marker ≠ collision world |
Confirm with |
First plan after switching planners is slow |
CUDA graph re-capture |
Expected — subsequent plans are fast |
Next steps¶
Tutorial 4: Robot Execution — run it on a real robot
RViz Plugin — the same workflow with mouse and panels