Skip to main content
ClaudeWave
Install in Claude Code
Copy
git clone --depth 1 https://github.com/harunkurtdev/ros2-claude-code-template /tmp/nav2_core_interfaces && cp -r /tmp/nav2_core_interfaces/.claude/skills/nav2_core_interfaces ~/.claude/skills/nav2_core_interfaces
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Nav2 Core Plugin Interfaces

Source: `~/nav2_ws/src/navigation2/nav2_core/include/nav2_core/`

## Plugin Base Classes

All Nav2 plugins implement these abstract interfaces. Infrastructure layer implements them; domain/application layers depend on them.

### 1. Controller (Local Planner)

**Header:** `controller.hpp`

```cpp
class Controller {
public:
  virtual void configure(
    const rclcpp_lifecycle::LifecycleNode::WeakPtr &,
    std::string name, std::shared_ptr<tf2_ros::Buffer>,
    std::shared_ptr<nav2_costmap_2d::Costmap2DROS>) = 0;
  virtual void cleanup() = 0;
  virtual void activate() = 0;
  virtual void deactivate() = 0;
  virtual void newPathReceived() {};
  virtual geometry_msgs::msg::TwistStamped computeVelocityCommands(
    const geometry_msgs::msg::PoseStamped & pose,
    const geometry_msgs::msg::Twist & velocity,
    nav2_core::GoalChecker * goal_checker) = 0;
  virtual void cancel() {};
  virtual void setSpeedLimit(const double & speed_limit, const bool & percentage) = 0;
  virtual void reset() {};
};
```

**Implementations:** DWB, MPPI, RegulatedPurePursuit, Graceful, RotationShim

### 2. GlobalPlanner

**Header:** `global_planner.hpp`

```cpp
class GlobalPlanner {
public:
  virtual void configure(
    const rclcpp_lifecycle::LifecycleNode::WeakPtr &,
    std::string name, std::shared_ptr<tf2_ros::Buffer>,
    std::shared_ptr<nav2_costmap_2d::Costmap2DROS>) = 0;
  virtual void cleanup() = 0;
  virtual void activate() = 0;
  virtual void deactivate() = 0;
  virtual nav_msgs::msg::Path createPlan(
    const geometry_msgs::msg::PoseStamped & start,
    const geometry_msgs::msg::PoseStamped & goal) = 0;
};
```

**Implementations:** NavFn, SmacPlanner2D, SmacPlannerHybrid, SmacPlannerLattice, ThetaStar

### 3. Smoother

**Header:** `smoother.hpp`

```cpp
class Smoother {
public:
  virtual void configure(...) = 0;
  virtual void cleanup() = 0;
  virtual void activate() = 0;
  virtual void deactivate() = 0;
  virtual bool smooth(
    nav_msgs::msg::Path & path,
    const nav2_costmap_2d::Costmap2D & costmap) = 0;
};
```

**Implementations:** SimpleSmoother, SavitzkyGolaySmoother, ConstrainedSmoother

### 4. GoalChecker

**Header:** `goal_checker.hpp`

```cpp
class GoalChecker {
public:
  virtual void initialize(...) = 0;
  virtual void reset() = 0;
  virtual bool isGoalReached(
    const geometry_msgs::msg::Pose & query_pose,
    const geometry_msgs::msg::Pose & goal_pose,
    const geometry_msgs::msg::Twist & velocity) = 0;
  virtual bool getTolerances(
    geometry_msgs::msg::Pose & pose_tolerance,
    geometry_msgs::msg::Twist & vel_tolerance) = 0;
};
```

### 5. ProgressChecker

**Header:** `progress_checker.hpp`

```cpp
class ProgressChecker {
public:
  virtual void initialize(...) = 0;
  virtual bool check(const geometry_msgs::msg::PoseStamped & current_pose) = 0;
  virtual void reset() = 0;
};
```

### 6. PathHandler

**Header:** `path_handler.hpp`

```cpp
class PathHandler {
public:
  virtual void initialize(...) = 0;
  virtual void setPlan(const nav_msgs::msg::Path & path) = 0;
  virtual nav_msgs::msg::Path findPlanSegment(...) = 0;
  virtual nav_msgs::msg::Path transformLocalPlan(...) = 0;
  virtual geometry_msgs::msg::PoseStamped getTransformedGoal(...) = 0;
};
```

### 7. Behavior

**Header:** `behavior.hpp`

```cpp
enum class CostmapInfoType { NONE, LOCAL, GLOBAL, BOTH };

class Behavior {
public:
  virtual void configure(...) = 0;
  virtual void cleanup() = 0;
  virtual void activate() = 0;
  virtual void deactivate() = 0;
  virtual CostmapInfoType getResourceInfo() = 0;
};
```

**Implementations:** Spin, BackUp, DriveOnHeading, Wait, AssistedTeleop

### 8. WaypointTaskExecutor

**Header:** `waypoint_task_executor.hpp`

```cpp
class WaypointTaskExecutor {
public:
  virtual void initialize(...) = 0;
  virtual bool processAtWaypoint(
    const geometry_msgs::msg::PoseStamped & current_pose,
    const int & current_waypoint_index) = 0;
};
```

### 9. BehaviorTreeNavigator

**Header:** `behavior_tree_navigator.hpp`

Template class for BT-based navigation action plugins. Contains:
- `FeedbackUtils` struct (robot_frame, global_frame, transform_tolerance, tf)
- `NavigatorMuxer` (ensures single active navigator)
- `BehaviorTreeNavigator<ActionT>` (template with BT lifecycle)

## Exception Classes

### Controller Exceptions (`controller_exceptions.hpp`)
- `ControllerException`, `InvalidController`, `ControllerTFError`
- `FailedToMakeProgress`, `PatienceExceeded`, `InvalidPath`
- `NoValidControl`, `ControllerTimedOut`

### Planner Exceptions (`planner_exceptions.hpp`)
- `PlannerException`, `InvalidPlanner`, `StartOccupied`, `GoalOccupied`
- `StartOutsideMapBounds`, `GoalOutsideMapBounds`
- `NoValidPathCouldBeFound`, `PlannerTimedOut`, `PlannerTFError`
- `NoViapointsGiven`, `PlannerCancelled`

### Smoother Exceptions (`smoother_exceptions.hpp`)
- `SmootherException`, `InvalidSmoother`, `InvalidPath`
- `SmootherTimedOut`, `SmoothedPathInCollision`, `FailedToSmoothPath`

### Route Exceptions (`route_exceptions.hpp`)
- `RouteException`, `OperationFailed`, `NoValidRouteCouldBeFound`
- `TimedOut`, `RouteTFError`, `NoValidGraph`
- `IndeterminantNodesOnGraph`, `InvalidEdgeScorerUse`

## Creating a Custom Plugin

### Custom Controller Example (C++)

```cpp
#include "nav2_core/controller.hpp"

namespace my_controller {

class MyController : public nav2_core::Controller {
public:
  void configure(
    const rclcpp_lifecycle::LifecycleNode::WeakPtr & parent,
    std::string name,
    std::shared_ptr<tf2_ros::Buffer> tf,
    std::shared_ptr<nav2_costmap_2d::Costmap2DROS> costmap_ros) override
  {
    // Initialize from parameters
  }

  geometry_msgs::msg::TwistStamped computeVelocityCommands(
    const geometry_msgs::msg::PoseStamped & pose,
    const geometry_msgs::msg::Twist & velocity,
    nav2_core::GoalChecker * goal_checker) override
  {
    // Compute and return velocity command
  }

  void setSpeedLimit(const double & speed_limit, const bool & percentage) override {}
  voi
behaviortree-reviewerSubagent

Use proactively before opening a PR that adds or changes BehaviorTree.CPP nodes or BehaviorTree.ROS2 wrappers (RosActionNode/RosServiceNode/RosTopicPub/SubNode, TreeExecutionServer). Reviews a diff against BT.CPP v4 conventions — node base-class choice, non-blocking ticks, ports/blackboard typing, factory/plugin registration, XML v4, and the ROS 2 wrapper contract. Returns a punch list with file:line anchors, not a rewrite.

clean-arch-architectSubagent

Use when a design decision touches Clean Architecture boundaries in a ROS 2 project — which layer a new behaviour belongs to, whether a port belongs in domain or application, whether a new node should be lifecycle-managed, whether to compose nodes or split packages. Returns an architectural recommendation with trade-offs, not implementation.

ecs-architectSubagent

Use when a design decision touches the gz-sim ECS — where new state should live, which system phase should write it, how to avoid coupling, whether to add a component vs. a member variable, whether a new system should be split or merged with an existing one. Returns an architectural recommendation with trade-offs, not implementation.

gz-style-reviewerSubagent

Use proactively before opening any gz-sim PR. Reviews a diff against the project's C++17 style, ECS conventions, plugin registration patterns, CMake structure, test placement, Migration.md / Changelog.md expectations, and pre-commit configuration. Returns a punch list, not a rewrite.

ros2-controllers-reviewerSubagent

Use proactively before opening a PR that adds or changes a ros2_control controller, broadcaster, or hardware component (incl. URDF <ros2_control> bringup). Reviews a diff against ros2_controllers / ros2_control_demos conventions — controller & hardware lifecycle, command/state interface configuration, real-time safety of update()/read()/write(), generate_parameter_library usage, pluginlib registration, chainable-controller correctness, URDF wiring, and tests. Returns a punch list with file:line anchors, not a rewrite.

ros2-style-reviewerSubagent

Use proactively before opening any ROS 2 / Nav 2 PR. Reviews a diff against this template's Clean Architecture, ROS 2 communication, lifecycle, testing, and Nav 2 plugin conventions. Returns a punch list with file:line anchors, not a rewrite.

vda5050-reviewerSubagent

Use proactively before opening a PR that touches a VDA 5050 connector / fleet bridge. Reviews a diff against VDA 5050 v3.0.0 protocol compliance (topics, QoS, header rules, base/horizon, action state machine, schema validation) and the template's Clean Architecture for the MQTT↔Nav 2 bridge. Returns a punch list with file:line anchors, not a rewrite.

buildSlash Command

Build the colcon workspace (optionally a single package) and report the outcome.