【手把手做ROS2机器人系统开发四】使用C++实现编写简单的发布者和订阅者

使用C++实现编写简单的发布者和订阅者

目录

使用C++实现编写简单的发布者和订阅者

一、程序编写

1、创建代码目录

2、创建软件程序包

3、测试编译

​编辑

4、打印和还原包的环境目录-用于剔除删除的软件包引用

 5、设置系统全局头文件目录

 6、发布者程序编写

7、订阅者代码编写

8、软件包依赖设置

9、设置编译选项

二、程序测试

1、编译程序

2、引用软件包

3、开启两个节点测试


        本章节实现使用C++编写发布者和订阅者程序,主要起到一个模板作用。让大家能够清晰认识如何编写一个发布者和订阅程序。做技术的就不需要多废话,直接上流程和代码,更能说明问题点。

一、程序编写

1、创建代码目录

mkdir src
cd src/

2、创建软件程序包

ros2 pkg create --build-type ament_cmake cpp_pubsub

生成数据如图所示:

3、测试编译

colcon build

 注意事项:操作的目录层次

4、打印和还原包的环境目录-用于剔除删除的软件包引用

printenv  AMENT_PREFIX_PATH CMAKE_PREFIX_PAT
export AMENT_PREFIX_PATH=/opt/ros/humble
export CMAKE_PREFIX_PATH=/opt/ros/humble

 5、设置系统全局头文件目录

/opt/ros/humble/include/
{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",
                "/opt/ros/humble/include/**",
                "/opt/ros/humble/include/std_msgs"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "c17",
            "cppStandard": "gnu++17",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}

 

 6、发布者程序编写

/**
 * @file publisher_member_function.cpp
 * @author gmotion (motion_gui@126.com)
 * @brief 发布者实例程序
 * @version 0.1
 * @date 2022-06-09
 * @copyright gmotion Copyright (c) 2022
 */


#include <chrono>       //处理时间类
#include <functional>   //函数对象
#include <memory>       //内存管理
#include <string>       //字符串

#include <rclcpp/rclcpp.hpp>
#include <std_msgs/msg/string.hpp>

using namespace std::chrono_literals;   //处理时间类

//ROS2 发布节点信息
class MinimalPublisher : public rclcpp::Node
{
public:
    //默认构造函数和析构函数
    MinimalPublisher();
    ~MinimalPublisher();

private:
    rclcpp::TimerBase::SharedPtr timer_ ;
    rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
    size_t count_;
    void timer_callback();
};

//默认构造函数
MinimalPublisher::MinimalPublisher()
: Node("minimal_publisher"),count_(0)
{
    publisher_ = this->create_publisher<std_msgs::msg::String>("topic",10);
    timer_ = this->create_wall_timer(500ms,std::bind(&MinimalPublisher::timer_callback,this));
}

//默认析构函数
MinimalPublisher::~MinimalPublisher()
{

}

//默认回调函数
void MinimalPublisher::timer_callback()
{
    auto message = std_msgs::msg::String();
    message.data = "Hello world,gmotion! =>" + std::to_string(count_ ++ );
    RCLCPP_INFO(this->get_logger(),"Publisher: '%s' ",message.data.c_str());
    publisher_->publish(message); 
}

//主运行程序
int main(int argc,char * argv[])
{
    rclcpp::init(argc,argv);
    rclcpp::spin(std::make_shared<MinimalPublisher>());
    rclcpp::shutdown();
    return 0;
}

7、订阅者代码编写

/**
 * @file subscriber_member_function.cpp
 * @author gmotion (motion_gui@126.com)
 * @brief 订阅者实例程序
 * @version 0.1
 * @date 2022-06-10
 * @copyright Copyright (c) 2022
 */

#include <functional>   //函数对象
#include <memory>       //内存管理
#include <string>       //字符串

#include <rclcpp/rclcpp.hpp>
#include <std_msgs/msg/string.hpp>

using std::placeholders::_1;    //C++占位符

//ROS2 订阅者节点信息
class MinimalSubscriber : public rclcpp::Node
{
public:
    //默认构造函数和析构函数
    MinimalSubscriber();
    ~MinimalSubscriber();

private:
    rclcpp::Subscription<std_msgs::msg::String>::SharedPtr Subscriber_;
    void topic_callback(std_msgs::msg::String::SharedPtr msg);
};

//默认构造函数
MinimalSubscriber::MinimalSubscriber()
: Node("minimal_Subscriber")
{
    Subscriber_ = this->create_subscription<std_msgs::msg::String>(
        "topic",10,std::bind(&MinimalSubscriber::topic_callback,this,_1));
}

//默认析构函数
MinimalSubscriber::~MinimalSubscriber()
{

}

//默认回调函数
void MinimalSubscriber::topic_callback(std_msgs::msg::String::SharedPtr msg)
{
    RCLCPP_INFO(this->get_logger(),"Subscriber Read: '%s' ",msg->data.c_str());
}

//主运行程序
int main(int argc,char * argv[])
{
    rclcpp::init(argc,argv);
    rclcpp::spin(std::make_shared<MinimalSubscriber>());
    rclcpp::shutdown();
    return 0;
}

8、软件包依赖设置

src/cpp_pubsub/package.xml
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>cpp_pubsub</name>
  <version>0.0.0</version>
  <description>Examples of minimal publisher/subscriber using rclcpp</description>
  <maintainer email="motion_gui@126.com">Gmotion</maintainer>
  <license>Apache License 2.0</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <depend>rclcpp</depend>
  <depend>std_msgs</depend> 

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

9、设置编译选项

src/cpp_pubsub/CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(cpp_pubsub)

# Default to C99
if(NOT CMAKE_C_STANDARD)
  set(CMAKE_C_STANDARD 99)
endif()

# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 14)
endif()


if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)


add_executable(talker src/publisher_member_function.cpp)
ament_target_dependencies(talker rclcpp std_msgs)

add_executable(listener src/subscriber_member_function.cpp)
ament_target_dependencies(listener rclcpp std_msgs)

install(TARGETS
  talker
  listener
  DESTINATION lib/${PROJECT_NAME})



if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # comment the line when a copyright and license is added to all source files
  set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # comment the line when this package is in a git repo and when
  # a copyright and license is added to all source files
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_package()

二、程序测试

1、编译程序

colcon build

2、引用软件包

. install/setup.bash

3、开启两个节点测试

. install/setup.bash

ros2 run cpp_pubsub talker
. install/setup.bash
ros2 run cpp_pubsub listener

 程序准确执行,达到预期结果。本节实现一个简单的发布者节点和一个订阅者结果。

更多精彩内容,欢迎订阅,敬请阅读下一章内容。谢谢大家的阅读。。。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单ROS topic发布的Python程序示例: ``` python #!/usr/bin/env python import rospy from std_msgs.msg import String def talker(): # 创建一个名为"chatter"的topic,String类型的消息 pub = rospy.Publisher('chatter', String, queue_size=10) # 初始化ROS节点 rospy.init_node('talker', anonymous=True) rate = rospy.Rate(10) # 10hz while not rospy.is_shutdown(): # 发布消息 hello_str = "Hello ROS %s" % rospy.get_time() rospy.loginfo(hello_str) pub.publish(hello_str) rate.sleep() if __name__ == '__main__': try: talker() except rospy.ROSInterruptException: pass ``` 这个程序通过ROS发布了一个名为"chatter"的topic,类型为String。程序中使用rospy.Publisher()函数创建了一个发布者对象,用于发布消息。在while循环中,程序通过pub.publish()函数发布了一个String类型的消息,并休眠一段时间。程序中使用rospy.loginfo()函数输出日志信息。 在运行这个程序之前,需要先确保ROS master已经启动,可以使用以下命令启动ROS master: ``` roscore ``` 然后,运行这个Python程序,使用以下命令: ``` rosrun <package_name> <node_name>.py ``` 其中,<package_name>是程序所在的ROS包的名称,<node_name>是程序的名称。例如,如果这个程序保存在名为"my_ros_package"的ROS包中,程序名称为"my_talker.py",则可以使用以下命令运行程序: ``` rosrun my_ros_package my_talker.py ``` 程序运行后,会在ROS创建一个名为"chatter"的topic,并发布消息。其他的ROS节点可以订阅这个topic,接收发布消息

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值