Skip to main content
ClaudeWave
Skill200 estrellas del repoactualizado 4d ago

new-component

Scaffold a new ECS component header under include/gz/sim/components/, wire its CMake listing, and (if needed) register it with ComponentFactory for serialization. Trigger when the user asks to add a new component or a per-entity data field.

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/harunkurtdev/ros2-claude-code-template /tmp/new-component && cp -r /tmp/new-component/.claude/skills/new-component ~/.claude/skills/new-component
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.md

# Adding a new component

Components in gz-sim are header-only wrappers around the `Component<>`
template. They live in `include/gz/sim/components/<Name>.hh`.

## Decide first

1. **What's the data type?** A plain struct, a `math::Vector3d`, an
   `std::string`, a `msgs::*`?  Components don't have to be POD but they
   must be copyable.
2. **Does it need serialization?** If users should be able to log/replay
   the component or read it from SDF, you need to give it a
   `Serializer<T>` and register it with `ComponentFactory`.
3. **Is there a Cmd / Reset variant?** If this component represents
   physical state that physics writes, you probably also want
   `<Name>Cmd.hh` (user → physics) and `<Name>Reset.hh` (snapshot for
   `Reset()`).

## Template (no custom serializer)

```cpp
// include/gz/sim/components/Foo.hh
#ifndef GZ_SIM_COMPONENTS_FOO_HH_
#define GZ_SIM_COMPONENTS_FOO_HH_

#include <gz/sim/components/Component.hh>
#include <gz/sim/components/Factory.hh>
#include <gz/sim/config.hh>

namespace gz::sim
{
inline namespace GZ_SIM_VERSION_NAMESPACE {
namespace components
{
  /// \brief One-line description of what this component represents and
  ///        which entities it gets attached to.
  using Foo = Component<double, class FooTag>;
  GZ_SIM_REGISTER_COMPONENT("gz_sim_components.Foo", Foo)
}
}
}

#endif
```

Key points:

* The unique tag `class FooTag` is what prevents two components with the
  same data type from collapsing into one — never skip it.
* `GZ_SIM_REGISTER_COMPONENT(name, type)` is required for *any* component
  that needs to round-trip through `ComponentFactory`.

## Template (custom data type + serializer)

```cpp
#ifndef GZ_SIM_COMPONENTS_BAR_HH_
#define GZ_SIM_COMPONENTS_BAR_HH_

#include <gz/msgs/double.pb.h>
#include <gz/sim/components/Component.hh>
#include <gz/sim/components/Factory.hh>
#include <gz/sim/components/Serialization.hh>
#include <gz/sim/config.hh>

namespace gz::sim
{
inline namespace GZ_SIM_VERSION_NAMESPACE {
namespace components
{
  using BarSerializer = serializers::MsgsDoubleSerializer;
  using Bar = Component<msgs::Double, class BarTag, BarSerializer>;
  GZ_SIM_REGISTER_COMPONENT("gz_sim_components.Bar", Bar)
}
}
}

#endif
```

For brand-new data types, define `Serializer<T>` with
`static std::ostream &Serialize(...)` and
`static std::istream &Deserialize(...)` in
`include/gz/sim/components/Serialization.hh` style and reference it from
the component.

## CMake plumbing

Add the new header to
`include/gz/sim/components/CMakeLists.txt` so it gets installed:

```cmake
set (component_headers
  Actor.hh
  ...
  Foo.hh        # <-- new
  ...
)
```

Headers are picked up automatically by the install logic — just keep the
list alphabetical to match existing style.

## Tests

* Add a small `Foo_TEST.cc` next to the existing component tests under
  `src/components/` if there's non-trivial behaviour (e.g. operator==
  or a custom serializer). Trivial typedef components don't need a
  dedicated test.
* If the component is logged/replayed, add a round-trip test under
  `test/integration/log_system.cc` patterns.

## Migration note

If the component is part of the public API, append a one-line entry to
`Migration.md` under the next-release section so downstream users notice.

## Common mistakes

* Reusing an existing tag class — two components with the same tag are
  the *same* component.
* Forgetting the `GZ_SIM_REGISTER_COMPONENT` macro for a serialized type.
* Adding mutation logic into the component header — components are *data*,
  behaviour belongs in a system.
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.