ROS 学习 (1):publisher和subscriber消息 C++1

本教程详细介绍了如何使用catkin工具创建ROS包,并通过实例演示了如何编写发布者和订阅者节点,实现简单的话题通信。

(1)catkin创建ros package

catkin_creat_pkg test_ros std_msgs roscpp rospy

catkin_make

source ~/devel/setup.bash

(2)编写pubulisher节点talker1.cpp并publisher话题chatter消息String

#include "ros/ros.h"
#include "std_msgs/String.h"

#include <sstream>

int main(int argc, char **argv)
{
    ros::init(argc,argv, "talker1");
    ros::NodeHandle n;
    ros::Publisher chatter_pub=n.advertise<std_msgs::String>("chatter",1000);
    ros::Rate loop_rate(10);

    int count = 0;
    while(ros::ok())
    {
        std_msgs::String msg;
        std::stringstream ss;
        ss << "Hello world!" << count;
        msg.data=ss.str();

        ROS_INFO("%s", msg.data.c_str());

        chatter_pub.publish(msg);
        ros::spinOnce();
        loop_rate.sleep();

        ++count;
    }

    return 0;
}

(3) listener1.cpp用户subscriber话题chatter消息

#include "ros/ros.h"
#include "std_msgs/String.h"

void chattercallback(const std_msgs::String::ConstPtr& msg)
{
    ROS_INFO("I heard:[%s]",msg->data.c_str());
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "listener1");
    ros::NodeHandle n;
    ros::Subscriber sub=n.subscribe("chatter", 1000, chattercallback);
    ros::spin();

    return 0;
}

(4)修改CMakeList.txt文件

## Declare a C++ executable
add_executable(talker1 src/talker1.cpp)
add_executable(listener1 src/listener1.cpp)
## Specify libraries to link a library or executable target against
 target_link_libraries(talker1
   ${catkin_LIBRARIES}
 )
target_link_libraries(listener1
  ${catkin_LIBRARIES}
)
(5)运行节点





ROS2 Humble 中,声明使用多个 `rclcpp::Publisher` `rclcpp::Subscriber` 对象需要通过 `rclcpp::Node` 类来实现。ROS2 使用 `rclcpp`(ROS Client Library for C++)作为客户端库,提供了对 ROS 话题、服务、参数等的接口支持[^2]。多个发布者订阅者可以通过在节点中多次调用 `create_publisher` `create_subscription` 方法实现。 ### 声明多个 PublisherROS2 中,可以通过 `create_publisher` 创建多个发布者对象。每个发布者对象对应一个话题,并可以发布不同类型的消息。例如: ```cpp #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" #include "geometry_msgs/msg/point.hpp" class MultiPublisherNode : public rclcpp::Node { public: MultiPublisherNode() : Node("multi_publisher_node") { // 创建第一个发布者,发布字符串消息到 "topic1" 话题 publisher1_ = this->create_publisher<std_msgs::msg::String>("topic1", 10); // 创建第二个发布者,发布点坐标消息到 "topic2" 话题 publisher2_ = this->create_publisher<geometry_msgs::msg::Point>("topic2", 10); } void publish_messages() { std_msgs::msg::String msg1; msg1.data = "Hello from topic1"; publisher1_->publish(msg1); geometry_msgs::msg::Point msg2; msg2.x = 1.0; msg2.y = 2.0; msg2.z = 3.0; publisher2_->publish(msg2); } private: rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher1_; rclcpp::Publisher<geometry_msgs::msg::Point>::SharedPtr publisher2_; }; ``` ### 声明多个 Subscriber 多个订阅者可以通过多次调用 `create_subscription` 方法实现。每个订阅者可以订阅不同类型的消息,并绑定不同的回调函数。例如: ```cpp #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" #include "geometry_msgs/msg/point.hpp" class MultiSubscriberNode : public rclcpp::Node { public: MultiSubscriberNode() : Node("multi_subscriber_node") { // 订阅 "topic1" 话题并绑定到 callback1 subscription1_ = this->create_subscription<std_msgs::msg::String>( "topic1", 10, [this](const std_msgs::msg::String::SharedPtr msg) { callback1(msg); }); // 订阅 "topic2" 话题并绑定到 callback2 subscription2_ = this->create_subscription<geometry_msgs::msg::Point>( "topic2", 10, [this](const geometry_msgs::msg::Point::SharedPtr msg) { callback2(msg); }); } private: void callback1(const std_msgs::msg::String::SharedPtr msg) { RCLCPP_INFO(this->get_logger(), "Received from topic1: '%s'", msg->data.c_str()); } void callback2(const geometry_msgs::msg::Point::SharedPtr msg) { RCLCPP_INFO(this->get_logger(), "Received from topic2: x=%.2f, y=%.2f, z=%.2f", msg->x, msg->y, msg->z); } rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription1_; rclcpp::Subscription<geometry_msgs::msg::Point>::SharedPtr subscription2_; }; ``` ### 完整示例 以下是一个完整的 ROS2 节点示例,展示了多个发布者订阅者的使用: ```cpp #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" #include "geometry_msgs/msg/point.hpp" class MultiPubSubNode : public rclcpp::Node { public: MultiPubSubNode() : Node("multi_pub_sub_node") { // 创建发布者 publisher1_ = this->create_publisher<std_msgs::msg::String>("topic1", 10); publisher2_ = this->create_publisher<geometry_msgs::msg::Point>("topic2", 10); // 创建订阅者 subscription1_ = this->create_subscription<std_msgs::msg::String>( "topic1", 10, [this](const std_msgs::msg::String::SharedPtr msg) { callback1(msg); }); subscription2_ = this->create_subscription<geometry_msgs::msg::Point>( "topic2", 10, [this](const geometry_msgs::msg::Point::SharedPtr msg) { callback2(msg); }); // 定时发布消息 timer_ = this->create_wall_timer( std::chrono::seconds(1), [this]() { this->timer_callback(); }); } private: void callback1(const std_msgs::msg::String::SharedPtr msg) { RCLCPP_INFO(this->get_logger(), "Received from topic1: '%s'", msg->data.c_str()); } void callback2(const geometry_msgs::msg::Point::SharedPtr msg) { RCLCPP_INFO(this->get_logger(), "Received from topic2: x=%.2f, y=%.2f, z=%.2f", msg->x, msg->y, msg->z); } void timer_callback() { std_msgs::msg::String msg1; msg1.data = "Hello from topic1"; publisher1_->publish(msg1); geometry_msgs::msg::Point msg2; msg2.x = 1.0; msg2.y = 2.0; msg2.z = 3.0; publisher2_->publish(msg2); } rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher1_; rclcpp::Publisher<geometry_msgs::msg::Point>::SharedPtr publisher2_; rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription1_; rclcpp::Subscription<geometry_msgs::msg::Point>::SharedPtr subscription2_; rclcpp::TimerBase::SharedPtr timer_; }; int main(int argc, char *argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<MultiPubSubNode>()); rclcpp::shutdown(); return 0; } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值