Back to Skills

create-example

majiayu000
Updated Today
1 views
58
9
58
View on GitHub
Metageneral

About

This skill helps developers create new ROS2 publish/subscribe examples for the zenoh-ros2-sdk. It guides users through determining example numbers, looking up message definitions, and implementing working publisher/subscriber pairs. Use it when adding examples for new message types like trajectory, sensor, or geometry messages.

Quick Install

Claude Code

Recommended
Plugin CommandRecommended
/plugin add https://github.com/majiayu000/claude-skill-registry
Git CloneAlternative
git clone https://github.com/majiayu000/claude-skill-registry.git ~/.claude/skills/create-example

Copy and paste this command in Claude Code to install this skill

Documentation

Create Example

This skill guides you through creating new publish/subscribe examples for the zenoh-ros2-sdk.

When to Use

  • User wants to add a new example for a message type
  • User wants to create publisher/subscriber for a new ROS2 message
  • Adding support for trajectory, sensor, geometry, or other message types

Project Structure

Examples are in examples/ with numbered filenames:

  • Odd numbers: publishers (e.g., 11_publish_*.py)
  • Even numbers: subscribers (e.g., 12_subscribe_*.py)

1. Determine Next Example Numbers

Check existing examples in examples/ directory. Use the next available odd number for publisher, next even for subscriber.

2. Look Up Message Definition

Find the ROS2 message definition. Key resources:

3. Publisher Template

Create examples/{NN}_publish_{msg_name}.py:

#!/usr/bin/env python3
"""
{NN} - Publish {MessageName} Messages

Demonstrates how to publish {package}/msg/{MessageName} messages to a ROS2 topic.
{Brief description of what this message type is used for.}
"""
import time
import numpy as np

from zenoh_ros2_sdk import ROS2Publisher, get_message_class


def main():
    print("{NN} - Publish {MessageName} Messages")
    print("Publishing to /{topic_name} topic...\n")

    # Get message classes for easy object creation
    Header = get_message_class("std_msgs/msg/Header")
    Time = get_message_class("builtin_interfaces/msg/Time")
    {MessageName} = get_message_class("{package}/msg/{MessageName}")
    # Add nested message classes as needed

    if not all([Header, Time, {MessageName}]):
        print("Error: Failed to get message classes")
        return

    # Create publisher
    pub = ROS2Publisher(
        topic="/{topic_name}",
        msg_type="{package}/msg/{MessageName}"
    )

    try:
        print("Publishing {MessageName} messages...")
        print("Press Ctrl+C to stop\n")

        counter = 0
        while True:
            # Get current time
            now = time.time()
            sec = int(now)
            nanosec = int((now - sec) * 1e9)

            # Create header with timestamp
            header = Header(
                stamp=Time(sec=sec, nanosec=nanosec),
                frame_id="base_link"
            )

            # Create and populate message fields
            # Note: Arrays need to be numpy arrays for proper serialization

            # Publish message - pass fields as kwargs matching message structure
            pub.publish(
                header=header,
                # ... other fields
            )

            print(f"Published {MessageName} {counter}")
            counter += 1
            time.sleep(0.1)  # 10 Hz

    except KeyboardInterrupt:
        print("\nInterrupted by user")
    finally:
        pub.close()
        print("Publisher closed")


if __name__ == "__main__":
    main()

4. Subscriber Template

Create examples/{NN+1}_subscribe_{msg_name}.py:

#!/usr/bin/env python3
"""
{NN+1} - Subscribe to {MessageName} Messages

Demonstrates how to subscribe to a ROS2 topic and receive {package}/msg/{MessageName} messages.
{Brief description of what this message type is used for.}
"""
import time

from zenoh_ros2_sdk import ROS2Subscriber


def main():
    print("{NN+1} - Subscribe to {MessageName} Messages")
    print("Subscribing to /{topic_name} topic...\n")

    message_count = [0]  # Use list to allow modification in nested function

    def on_message(msg):
        """Callback function called when a {MessageName} message is received."""
        message_count[0] += 1

        # Extract information from the message
        timestamp = msg.header.stamp
        frame_id = msg.header.frame_id
        # ... extract other fields

        # Display received data
        print(f"\n--- {MessageName} Message #{message_count[0]} ---")
        print(f"Timestamp: {timestamp.sec}.{timestamp.nanosec:09d}")
        print(f"Frame ID: {frame_id}")
        # ... print other fields

    # Create subscriber
    sub = ROS2Subscriber(
        topic="/{topic_name}",
        msg_type="{package}/msg/{MessageName}",
        callback=on_message
    )

    try:
        print("Waiting for {MessageName} messages... Press Ctrl+C to stop")
        while True:
            time.sleep(0.1)
    except KeyboardInterrupt:
        print("\nInterrupted by user")
    finally:
        sub.close()
        print("Subscriber closed")


if __name__ == "__main__":
    main()

5. Update README

Add entries to examples/README.md:

### [`{NN}_publish_{msg_name}.py`]({NN}_publish_{msg_name}.py)
Demonstrates how to publish `{package}/msg/{MessageName}` messages. {Description}.

**Usage:**
\```bash
python3 examples/{NN}_publish_{msg_name}.py
\```

### [`{NN+1}_subscribe_{msg_name}.py`]({NN+1}_subscribe_{msg_name}.py)
Demonstrates how to subscribe to `{package}/msg/{MessageName}` messages. {Description}.

**Usage:**
\```bash
python3 examples/{NN+1}_subscribe_{msg_name}.py
\```

6. Key Patterns

Arrays

Use numpy arrays for proper CDR serialization:

positions = np.array([0.0, 0.1, 0.2], dtype=np.float64)

Nested Messages

Get nested message classes and construct them:

Point = get_message_class("trajectory_msgs/msg/JointTrajectoryPoint")
Duration = get_message_class("builtin_interfaces/msg/Duration")

point = Point(
    positions=np.array([0.0, 0.1], dtype=np.float64),
    time_from_start=Duration(sec=1, nanosec=0)
)

Common Topic Names

  • /joint_states - JointState
  • /cmd_vel - Twist
  • /joint_trajectory - JointTrajectory
  • /odom - Odometry
  • /tf - TransformStamped

GitHub Repository

majiayu000/claude-skill-registry
Path: skills/create-example

Related Skills

algorithmic-art

Meta

This Claude Skill creates original algorithmic art using p5.js with seeded randomness and interactive parameters. It generates .md files for algorithmic philosophies, plus .html and .js files for interactive generative art implementations. Use it when developers need to create flow fields, particle systems, or other computational art while avoiding copyright issues.

View skill

subagent-driven-development

Development

This skill executes implementation plans by dispatching a fresh subagent for each independent task, with code review between tasks. It enables fast iteration while maintaining quality gates through this review process. Use it when working on mostly independent tasks within the same session to ensure continuous progress with built-in quality checks.

View skill

executing-plans

Design

Use the executing-plans skill when you have a complete implementation plan to execute in controlled batches with review checkpoints. It loads and critically reviews the plan, then executes tasks in small batches (default 3 tasks) while reporting progress between each batch for architect review. This ensures systematic implementation with built-in quality control checkpoints.

View skill

cost-optimization

Other

This Claude Skill helps developers optimize cloud costs through resource rightsizing, tagging strategies, and spending analysis. It provides a framework for reducing cloud expenses and implementing cost governance across AWS, Azure, and GCP. Use it when you need to analyze infrastructure costs, right-size resources, or meet budget constraints.

View skill