# 1.创建 ROS 2 C++ 包

ros2 pkg create --build-type ament_cmake cmd_vel --dependencies rclcpp geometry_msgs

# 2.建文件

touch cmd_vel.cpp
#include "rclcpp/rclcpp.hpp"
#include "geometry_msgs/msg/twist.hpp"
#include <chrono>
#include <thread>

using namespace std::chrono_literals;

class CmdVelPublisher : public rclcpp::Node
{
public:
    CmdVelPublisher()
    : Node("cmd_vel_publisher")
    {
        publisher_ = this->create_publisher<geometry_msgs::msg::Twist>("/cmd_vel", 10);
        RCLCPP_INFO(this->get_logger(), "启动 cmd_vel 控制节点");

        move_forward(1.0, 3);
        turn_left(0.5, 2);
        turn_right(0.5, 2);
        stop();
    }

private:
    rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr publisher_;

    void publish_for_duration(const geometry_msgs::msg::Twist & msg, double duration_sec)
    {
        auto start = now();
        rclcpp::Rate rate(10);
        while ((now() - start).seconds() < duration_sec) {
            publisher_->publish(msg);
            rate.sleep();
        }
    }

    void move_forward(double speed, double duration)
    {
        geometry_msgs::msg::Twist msg;
        msg.linear.x = speed;
        msg.angular.z = 0.0;
        RCLCPP_INFO(this->get_logger(), "前进 %.1f 秒", duration);
        publish_for_duration(msg, duration);
    }

    void turn_left(double angular_speed, double duration)
    {
        geometry_msgs::msg::Twist msg;
        msg.linear.x = 0.0;
        msg.angular.z = angular_speed;
        RCLCPP_INFO(this->get_logger(), "左转 %.1f 秒", duration);
        publish_for_duration(msg, duration);
    }

    void turn_right(double angular_speed, double duration)
    {
        geometry_msgs::msg::Twist msg;
        msg.linear.x = 0.0;
        msg.angular.z = -angular_speed;
        RCLCPP_INFO(this->get_logger(), "右转 %.1f 秒", duration);
        publish_for_duration(msg, duration);
    }

    void stop()
    {
        geometry_msgs::msg::Twist msg;
        RCLCPP_INFO(this->get_logger(), "停止");
        publisher_->publish(msg);
    }
};

int main(int argc, char * argv[])
{
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<CmdVelPublisher>());
    rclcpp::shutdown();
    return 0;
}

# 3.改camkelist

add_executable(cmd_vel src/cmd_vel.cpp)
ament_target_dependencies(cmd_vel rclcpp geometry_msgs)
install(TARGETS cmd_vel DESTINATION lib/${PROJECT_NAME})

# 4.编译

colcon build --packages-select cmd_vel//包名
source install/setup.bash

# 5.加launch(注意缩进)

 cmd_vel_node = Node(
        package='cmd_vel',
        executable='cmd_vel',
        name='cmd_vel',
        output='screen'
    )