Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Source: `~/nav2_ws/src/navigation2/`
.claude/skills/harunkurtdev-nav2-server-nodes/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 98% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 35% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 63% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 60% | 0% |
| case-16 | ✗→✓ | ▲ Improved | 20% | 0% |
Source: ~/nav2_ws/src/navigation2/
Package: nav2_lifecycle_manager Purpose: Orchestrate lifecycle transitions of all Nav2 nodes
Manages state machine: UNCONFIGURED → INACTIVE → ACTIVE → FINALIZED Uses bond connections for health monitoring. Auto-reconnects on failure.
yamllifecycle_manager: ros__parameters: autostart: true bond_timeout: 4.0 bond_heartbeat_period: 0.5 service_timeout: 5.0 attempt_respawn_reconnection: true node_names: - "map_server" - "amcl" - "controller_server" - "planner_server" - "smoother_server" - "behavior_server" - "bt_navigator" - "waypoint_follower" - "velocity_smoother" - "collision_monitor"
manage_nodes (nav2_msgs/ManageLifecycleNodes)Package: nav2_velocity_smoother Purpose: Apply acceleration/deceleration limits to velocity commands
cmd_vel (from controller)cmd_vel_smoothedyamlvelocity_smoother: ros__parameters: smoothing_frequency: 20.0 scale_velocities: false feedback: "OPEN_LOOP" # or "CLOSED_LOOP" (uses odom) max_velocity: [0.26, 0.0, 1.0] # [vx, vy, wz] min_velocity: [-0.26, 0.0, -1.0] max_accel: [2.5, 0.0, 3.2] max_decel: [-2.5, 0.0, -3.2] deadband_velocity: [0.0, 0.0, 0.0] velocity_timeout: 1.0 odom_topic: "odom" odom_duration: 0.1
Package: nav2_collision_monitor Purpose: Real-time collision avoidance between controller and hardware
Intercepts cmd_vel → applies safety actions → outputs safe cmd_vel. Monitors configurable polygons/circles around robot.
Action Types: | Type | Behavior | |------|----------| | stop | Zero velocity on detection | | slowdown | Reduce velocity by factor | | limit | Cap max velocity | | approach | Slow proportionally to distance |
Polygon Sources:
Polygon - Static polygon shapeCircle - Circular zoneVelocityPolygon - Dynamic polygon based on current velocityData Sources:
Scan - LaserScanPointCloud - PointCloud2Range - Single range sensorCostmap - Costmap datayamlcollision_monitor: ros__parameters: cmd_vel_in_topic: "cmd_vel_smoothed" cmd_vel_out_topic: "cmd_vel" transform_tolerance: 0.5 source_timeout: 5.0 stop_pub_timeout: 2.0 polygons: ["FootprintApproach"] FootprintApproach: type: "polygon" action_type: "approach" footprint_topic: "/local_costmap/published_footprint" time_before_collision: 2.0 simulation_time_step: 0.02 max_points: 5 enabled: true observation_sources: ["scan"] scan: type: "scan" topic: "/scan"
Separate node (CollisionDetector) that only detects, doesn't modify commands. Publishes CollisionDetectorState.
Package: nav2_smoother Action: SmoothPath Purpose: Host path smoother plugins
| Plugin | Package | Algorithm | |--------|---------|-----------| | SimpleSmoother | nav2_smoother | Basic iterative smoothing | | SavitzkyGolaySmoother | nav2_smoother | Savitzky-Golay filter | | ConstrainedSmoother | nav2_constrained_smoother | Convex optimization with constraints |
yamlsmoother_server: ros__parameters: smoother_plugins: ["simple_smoother"] simple_smoother: plugin: "nav2_smoother::SimpleSmoother" tolerance: 1.0e-10 max_its: 1000 do_refinement: true
yamlconstrained_smoother: plugin: "nav2_constrained_smoother::ConstrainedSmoother" tolerance: 1.0e-10 max_its: 1000 enforce_path_inversion: true # For lattice planner do_refinement: true w_smooth: 0.3 w_data: 0.2
Package: nav2_waypoint_follower Actions: FollowWaypoints, FollowGPSWaypoints Purpose: Sequential navigation through ordered waypoints
Uses NavigateToPose action internally for each waypoint. Supports plugin-based task execution at each waypoint.
yamlwaypoint_follower: ros__parameters: loop_rate: 20 stop_on_failure: true waypoint_task_executor_plugin: "wait_at_waypoint" wait_at_waypoint: plugin: "nav2_waypoint_follower::WaitAtWaypoint" enabled: true waypoint_pause_duration: 200 # ms
Package: nav2_docking Actions: DockRobot, UndockRobot Purpose: Autonomous charging dock approach/departure
yamldocking_server: ros__parameters: dock_plugins: ["simple_charging_dock"] simple_charging_dock: plugin: "opennav_docking::SimpleChargingDock" docking_threshold: 0.05 staging_x_offset: -0.7 use_external_detection_pose: true docks: ["home_dock"] home_dock: type: "simple_charging_dock" frame: "map" dock_pose: [0.0, 0.0, 0.0] controller: use_collision_detection: true k_phi: 3.0 k_delta: 2.0 v_linear_min: 0.15 v_linear_max: 0.25 filter_coef: 0.1 detection_timeout: 10.0 max_retries: 3
Package: nav2_following Action: FollowObject Purpose: Track and follow dynamic targets
Similar to docking but for moving targets. Subscribes to target pose topic, applies filtering, controls approach.
yamlfollowing_server: ros__parameters: fixed_frame: "odom" base_frame: "base_link" filter_coef: 0.1 detection_timeout: 5.0 odom_topic: "/odom" controller: use_collision_detection: false k_phi: 3.0 k_delta: 2.0
Package: nav2_simple_commander Class: BasicNavigator Purpose: High-level Python API for Nav2
pythonfrom nav2_simple_commander.robot_navigator import BasicNavigator navigator = BasicNavigator() # Initialization navigator.setInitialPose(initial_pose) navigator.waitUntilNav2Active() # Navigation navigator.goToPose(goal_pose) navigator.goThroughPoses(poses) navigator.followWaypoints(waypoints) navigator.followPath(path) # Recovery navigator.spin(spin_dist=1.57) navigator.backup(backup_dist=0.15, backup_speed=0.025) # Docking navigator.dockRobot(dock_id="home_dock") navigator.undockRobot(dock_type="simple_charging_dock") # Planning only path = navigator.getPath(start, goal, planner_id="GridBased") smoothed = navigator.smoothPath(path, smoother_id="simple_smoother") # Status navigator.isTaskComplete() # Returns True when done result = navigator.getResult() # TaskResult enum feedback = navigator.getFeedback() # Costmap navigator.clearAllCostmaps() navigator.clearLocalCostmap() navigator.clearGlobalCostmap() # Lifecycle navigator.lifecycleStartup() navigator.lifecycleShutdown()
pythonclass TaskResult(Enum): UNKNOWN = 0 SUCCEEDED = 1 CANCELED = 2 FAILED = 3
Package: nav2_loopback_sim Purpose: Lightweight sim without physics (for testing Nav2)
Accepts cmd_vel, publishes:
/odomodom → base_linkyamlloopback_simulator: ros__parameters: update_duration: 0.02 base_frame_id: "base_link" odom_frame_id: "odom" map_frame_id: "map" scan_frame_id: "base_scan" publish_map_odom_tf: true publish_clock: true
cmd_vel flow:
Controller Server → Velocity Smoother → Collision Monitor → Hardware
Localization flow:
/scan + /map → AMCL → map→odom TF
Planning flow:
Goal → BT Navigator → Planner Server → Smoother Server → Controller Server
Costmap flow:
/scan + /map → Costmap Layers → Combined Costmap → Planner/Controller| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-02 | fail→pass | 15,877 | 16,673 | +5% | 1 | 1 | 0% | 3,104 | 6,136 | +98% | 0 | 0 | — |
case-17 | pass→pass | 10,338 | 5,747 | -44% | 1 | 1 | 0% | 1,971 | 3,648 | +85% | 0 | 0 | — |
case-07 | pass→pass | 6,761 | 2,794 | -59% | 1 | 1 | 0% | 1,189 | 3,080 | +159% | 0 | 0 | — |
case-01 | fail→pass | 16,170 | 8,998 | -44% | 1 | 1 | 0% | 3,353 | 4,536 | +35% | 0 | 0 | — |
case-03 | pass→pass | 14,816 | 8,516 | -43% | 1 | 1 | 0% | 2,854 | 4,552 | +59% | 0 | 0 | — |
case-04 | pass→pass | 10,695 | 5,095 | -52% | 1 | 1 | 0% | 1,980 | 3,636 | +84% | 0 | 0 | — |
case-05 | pass→pass | 5,584 | 2,039 | -63% | 1 | 1 | 0% | 1,011 | 2,955 | +192% | 0 | 0 | — |
case-06 | pass→pass | 9,071 | 4,493 | -50% | 1 | 1 | 0% | 1,860 | 3,542 | +90% | 0 | 0 | — |
case-08 | pass→pass | 6,872 | 4,508 | -34% | 1 | 1 | 0% | 1,165 | 3,414 | +193% | 0 | 0 | — |
case-09 | fail→pass | 11,106 | 2,787 | -75% | 1 | 1 | 0% | 1,881 | 3,066 | +63% | 0 | 0 | — |
case-10 | pass→pass | 5,201 | 3,045 | -41% | 1 | 1 | 0% | 1,057 | 3,202 | +203% | 0 | 0 | — |
case-11 | fail→pass | 17,346 | 10,315 | -41% | 1 | 1 | 0% | 2,776 | 4,453 | +60% | 0 | 0 | — |
case-16 | fail→pass | 15,879 | 2,983 | -81% | 1 | 1 | 0% | 2,617 | 3,143 | +20% | 0 | 0 | — |
case-12 | pass→pass | 4,936 | 2,702 | -45% | 1 | 1 | 0% | 840 | 3,021 | +260% | 0 | 0 | — |
case-13 | pass→pass | 4,380 | 2,563 | -41% | 1 | 1 | 0% | 778 | 3,120 | +301% | 0 | 0 | — |
case-14 | fail→pass | 13,354 | 2,850 | -79% | 1 | 1 | 0% | 2,343 | 3,135 | +34% | 0 | 0 | — |
case-15 | fail→pass | 14,441 | 3,110 | -78% | 1 | 1 | 0% | 2,305 | 3,092 | +34% | 0 | 0 | — |
case-18 | pass→pass | 4,920 | 2,888 | -41% | 1 | 1 | 0% | 849 | 3,138 | +270% | 0 | 0 | — |
case-19 | fail→pass | 10,820 | 3,621 | -67% | 1 | 1 | 0% | 1,782 | 3,225 | +81% | 0 | 0 | — |
case-20 | pass→pass | 16,165 | 9,118 | -44% | 1 | 1 | 0% | 2,873 | 4,376 | +52% | 0 | 0 | — |
case-21 | fail→fail | 18,741 | 20,648 | +10% | 1 | 1 | 0% | 3,463 | 6,491 | +87% | 0 | 0 | — |
case-22 | fail→fail | 16,957 | 9,901 | -42% | 1 | 1 | 0% | 2,991 | 4,483 | +50% | 0 | 0 | — |
case-23 | fail→fail | 15,356 | 16,542 | +8% | 1 | 1 | 0% | 2,736 | 5,596 | +105% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +35 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.