ros2话题的发布者和订阅者——ubuntu20.04+自定义话题接口类型

话题的发布者

  1. 导入消息类型,ros自带的消息类型在std_msgs/msg/下面,有string等类型
  2. 定义一个类,里面声明一个发布者话题的共享指针,指针标注发布的数据类型
  3. 在构造函数中使用create_publisher创建声明的这个发布者对象,也可以在声明时创建对象。
  • 声明一个发布者的类(发布者对象、发布数据的函数)
#include "rclcpp/rclcpp.hpp"
// 1. 导入消息类型
#include "std_msgs/msg/string.hpp"

// 定义一个有发布者的类,里面包含发布者对象
class publisher: public rclcpp::Node
{
private:
  // 2.声明一个发布者用于发布消息,这里只是定义,也可以在这里对其进行初始化,我这里在构造函数里面进行初始化
  // 发布者名称为pub_er,用共性指针声明对象,<std_msgs::msg::String>表示要发布的数据类型
  rclcpp::Publisher<std_msgs::msg::String>::SharedPtr pub_er; 
public:
  // 定义一个发布话题的函数,声明类对象调用该函数发布数据。
  publisher(std::string name);
  ~publisher();
  
  void publish_data();
};
publisher::publisher(std::string name):Node(name)
{
    //发布者的构造函数
  RCLCPP_INFO(this->get_logger(),"create publisher");

  // 3. 创造一个发布者
  // 使用create_publisher这个函数创建发布者对象,并声明一下他的发布的数据类型
  // 两个参数,一个是发布的话题名称,参数是队列长度,暂时填一个数字10
  pub_er = this->create_publisher<std_msgs::msg::String>("topic_name",10);

}
// 析构函数,该函数在释放对象后调用,或者按CTRL+C后调用
publisher::~publisher()
{RCLCPP_INFO(this->get_logger(),"delete publisher");}

// 调用该函数,使用发布者把数据发布出去
void publisher::publish_data()
{
  // 声明一个存储数据的对象
  std_msgs::msg::String text_data;
  // 向对象中存储数据要调用该数据类型对象的data
  text_data.data="abcdefg";
  pub_er->publish(text_data);
}

  • 主函数调用发布者独享
int main(int argc, char ** argv)
{
  rclcpp::init(argc,argv);
  // 声明一个节点对象,该节点的类型是我们是声明的 发布者类
  auto node = std::make_shared<publisher>("my_publishr");
  while(1)
  {
    sleep(3);
    node->publish_data();
  }
  rclcpp::spin(node);
  rclcpp::shutdown();
}

话题的订阅者

  • 声明一个订阅者的类
// 创建一个订阅者的类
class subscriber : public rclcpp::Node
{
private:
  // 声明一个话题的订阅者,发布者为sub_er
  // clcpp::Subscription是一个模板类,要订阅的话题类型为std_msgs::msg::String
  rclcpp::Subscription<std_msgs::msg::String>::SharedPtr sub_er;
  // 声明一个订阅者的回调函数,回调函数用于当我们接收到发布者的数据后做的反应
  // 参数是一个共享指针,指针的类型就是发布者发布的类型
  void callback(const std_msgs::msg::String::SharedPtr publish_data)
  {
    //收到数据后的处理逻辑
    // 这里只是把订阅到的数据打印输出一下
    RCLCPP_INFO(this->get_logger(),"data:%s",publish_data->data.c_str());
  }
public:
  subscriber(std::string name);
  ~subscriber();
};

subscriber::subscriber(std::string name):Node(name)
{
  //订阅者的构造函数
  RCLCPP_INFO(this->get_logger(),"create subscriber");

  //构造函数里面创建订阅者
  //使用create_subscription这个来给声明的订阅者来创建一个实体
  //create_subscriptionde第一个参数是:订阅的话题名称,第二个参数是队列长度
  //成员函数不能只用当做参数进行回调,成员函数需要一个对象来调用,可以使用bind
  sub_er = this->create_subscription<std_msgs::msg::String>("topic_name",10,std::bind(&subscriber::callback,this,_1));
}

subscriber::~subscriber()
{ RCLCPP_INFO(this->get_logger(),"delete subscriber"); }
  • 主函数声明这个订阅者对象
int main(int argc, char ** argv)
{
  rclcpp::init(argc,argv);
  auto node = std::make_shared<subscriber>("my_subscriber");
  rclcpp::spin(node);
  rclcpp::shutdown();
}

自定义话题的接口类型

  1. 在包的src的同级目录下,不是工程目录的src同级目录下创建msg文件夹

  2. 在msg文件夹下创建Xxx.msg文件(文件首字母大写,不能包含_下划线等符号

  3. 在Xxx.msg文件中添加消息类型

  4. 在CmakeList.txt文件和package.xml文件中添加依赖、msg文件的目录

  5. 创建一个msg文件,文件名为Novel.msg

# 添加一个string类型和图片类型
# 调用原有的string类型
string content

# 调用以后的图片类型
sensor_msgs/Image image

# 数组的话直接在数据类型后面加数组的中括号,例如:
# string[] content

  1. 修改CMakeLists.txt文件

主要是添加依赖(find_package和rosidl_generate_interfaces)

# 添加我们要引入数据类型的依赖包
find_package(sensor_msgs REQUIRED) # sensor_msgs/Image
# 自定义数据类型还需要一个rosidl_default_generators
find_package(rosidl_default_generators REQUIRED)

# 自定义数据类型还需要添加一个rosidl_generate_interfaces
rosidl_generate_interfaces(${PROJECT_NAME} 
    "msg/Novel.msg"  #这里是指明msg文件的目录和名称
    DEPENDENCIES sensor_msgs) # 这里需要填上这个类型所需的依赖
  1. 修改package.xml文件
  <depend>sensor_msgs</depend> <!-- 这个是数据类型的依赖 -->
  <!-- 下面三项是需要添加的东西 -->
  <buildtool_depend>rosidl_default_generators</buildtool_depend>
  <exec_depend>rosidl_default_runtime</exec_depend>
  <member_of_group>rosidl_interface_packages</member_of_group>

将自定义的话题引入到程序中

  • 代码中引入头文件和声明一个订阅者
// 引入自定义话题接口的头文件
// 表示在ros2_publisher包或目录下的msg目录下,文件名为Novel
#include <ros2_publisher/msg/Novel.hpp>

  // 定义一个自定义话题数据类型的对象
  ros2_publisher::msg::Novel publish_data_interface;
  // 声明一个自定义数据类型的发布者
  rclcpp::Publisher<ros2_publisher::msg::Novel>::SharedPtr  num_publisher=this->create_publisher<ros2_publisher::msg::Novel>("topic_name",20);

  • 修改CMakeLists.txt文件
添加自定义数据类型的包依赖
find_package(ros2_publisher REQUIRED)

在ament_target_dependencies中添加包依赖名
ament_target_dependencies(
  my_publisher
  "std_msgs"
  "rclcpp"
  ros2_publisher
)
  • 修改package.xml文件
添加定义数据类型的包
  <depend>ros2_publisher</depend>
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值