首页 > 其他分享 >ros2 foxy订阅话题问题

ros2 foxy订阅话题问题

时间:2024-03-23 22:12:13浏览次数:21  
标签:std 订阅 const create foxy _- msg ros2 subscription

代码片段

这部分代码在galactic版本编译是OK的,可在foxy下编译就出了问题

TeleopPanel::TeleopPanel(QWidget* parent) : rviz_common::Panel(parent), playRate_(1.0)
{
    signalPub_ = nh_->create_publisher<std_msgs::msg::Int16>("/pixel/lv/run_signal", 5);
    beginPub_ = nh_->create_publisher<std_msgs::msg::Float32>("/pixel/lv/begin_signal", 5);
    ratePub_ = nh_->create_publisher<std_msgs::msg::Float32>("/pixel/lv/rate_signal", 5);

    currTimeSub_ = nh_->create_subscription<std_msgs::msg::String>("/pixel/lv/current_time", 10, std::bind(&TeleopPanel::CurrTimeSub, this, std::placeholders::_1));
    selectPtSub_ = nh_->create_subscription<sensor_msgs::msg::PointCloud2>("/rviz_selected_points", 10, std::bind(&TeleopPanel::SelectPtSub, this, std::placeholders::_1));

    std::thread t(&TeleopPanel::StartSpin, this);
    t.detach();

    SetPanelLayout();
}

void TeleopPanel::CurrTimeSub(const std_msgs::msg::String& msg)
{
    QString currTime = QString::fromStdString(msg.data);
    currentTimeEditor_->setText(currTime);
}

void TeleopPanel::SelectPtSub(const sensor_msgs::msg::PointCloud2& msg)
{
    const auto ptsNum = msg.width;
    QString ptsNumQStr = QString::fromStdString(std::to_string(ptsNum));
    selectPtsEditor_->setText(ptsNumQStr);
}

出错部分

两个create_subscription调用出错

currTimeSub_ = nh_->create_subscription<std_msgs::msg::String>("/pixel/lv/current_time", 10, std::bind(&TeleopPanel::CurrTimeSub, this, std::placeholders::_1));
selectPtSub_ = nh_->create_subscription<sensor_msgs::msg::PointCloud2>("/rviz_selected_points", 10, std::bind(&TeleopPanel::SelectPtSub, this, std::placeholders::_1));

create_subscription函数原型

std::shared_ptr<SubscriptionT>
  create_subscription(
    const std::string & topic_name,
    const rclcpp::QoS & qos,
    CallbackT && callback,
    const SubscriptionOptionsWithAllocator<AllocatorT> & options =
    SubscriptionOptionsWithAllocator<AllocatorT>(),
    typename MessageMemoryStrategyT::SharedPtr msg_mem_strat = (
      MessageMemoryStrategyT::create_default()
    )
  );

出错内容

下面是其中一部分报错内容

// 报错一
play_panel.cpp:26: error: no match for ‘operator=’ (operand types are ‘rclcpp::Subscription<sensor_msgs::msg::PointCloud2_<std::allocator<void> > >::SharedPtr’ {aka ‘std::shared_ptr<rclcpp::Subscription<sensor_msgs::msg::PointCloud2_<std::allocator<void> > > >’} and ‘std::shared_ptr<rclcpp::Subscription<const sensor_msgs::msg::PointCloud2_<std::allocator<void> >&, std::allocator<void>, rclcpp::message_memory_strategy::MessageMemoryStrategy<const sensor_msgs::msg::PointCloud2_<std::allocator<void> >&, std::allocator<void> > > >’)
   26 |     selectPtSub_ = nh_->create_subscription<sensor_msgs::msg::PointCloud2>("/rviz_selected_points", 10, std::bind(&TeleopPanel::SelectPtSub, this, std::placeholders::_1));
      |                                                                                                                                                                          ^
// 报错二
play_panel.cpp:26:25: error: no matching member function for call to 'create_subscription'
node_impl.hpp:91:7: note: candidate template ignored: substitution failure [with MessageT = sensor_msgs::msg::PointCloud2_<std::allocator<void> >, CallbackT = std::_Bind<void (LidarViewRos2::RvizPlugin::TeleopPanel::*(LidarViewRos2::RvizPlugin::TeleopPanel *, std::_Placeholder<1>))(const sensor_msgs::msg::PointCloud2_<std::allocator<void> > &)>, AllocatorT = std::allocator<void>, CallbackMessageT = const sensor_msgs::msg::PointCloud2_<std::allocator<void> > &, SubscriptionT = rclcpp::Subscription<const sensor_msgs::msg::PointCloud2_<std::allocator<void> > &, std::allocator<void>, rclcpp::message_memory_strategy::MessageMemoryStrategy<const sensor_msgs::msg::PointCloud2_<std::allocator<void> > &, std::allocator<void> > >, MessageMemoryStrategyT = rclcpp::message_memory_strategy::MessageMemoryStrategy<const sensor_msgs::msg::PointCloud2_<std::allocator<void> > &, std::allocator<void> >]

// 报错三
/opt/ros/foxy/include/rclcpp/subscription_factory.hpp:97: error: no matching function for call to ‘rclcpp::AnySubscriptionCallback<const sensor_msgs::msg::PointCloud2_<std::allocator<void> >&, std::allocator<void> >::set(std::_Bind<void (LidarViewRos2::RvizPlugin::TeleopPanel::*(LidarViewRos2::RvizPlugin::TeleopPanel*, std::_Placeholder<1>))(const sensor_msgs::msg::PointCloud2_<std::allocator<void> >&)>)’
   97 |   any_subscription_callback.set(std::forward<CallbackT>(callback));
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~
    
// 报错四
/usr/include/c++/9/ext/new_allocator.h:64: error: forming pointer to reference type ‘const sensor_msgs::msg::PointCloud2_<std::allocator<void> >&’
typedef const _Tp* const_pointer;

其实就是模板函数的原型不匹配导致的,CallbackT的模板参数需要传入指针类型才能正确解参数类型,传入引用类型是不对的

正确写法

只要把CurrTimeSubSelectPtSub两个函数的原型修改一下(入参改成指针)就OK了

void TeleopPanel::CurrTimeSub(const std_msgs::msg::String::SharedPtr msg)
{
    QString currTime = QString::fromStdString(msg->data);
    currentTimeEditor_->setText(currTime);
}

void TeleopPanel::SelectPtSub(const sensor_msgs::msg::PointCloud2::SharedPtr msg)
{
    const auto ptsNum = msg->width;
    QString ptsNumQStr = QString::fromStdString(std::to_string(ptsNum));
    selectPtsEditor_->setText(ptsNumQStr);
}

总结

foxygalactic及后续版本在create_subscription模板函数的实现有区别,移植的时候要注意兼容性,参考issue ros2 add arguments to callback - ROS Answers: Open Source Q&A Forum

标签:std,订阅,const,create,foxy,_-,msg,ros2,subscription
From: https://www.cnblogs.com/hywing/p/18091771

相关文章

  • 实时汇率API查询接口接入方法:支持逐笔报价、批量订阅、历史日K线、周K、月K
    在进行量化回测时,确实需要支持逐笔报价、批量订阅、以及获取历史日K线、周K线、月K线等功能,这些功能对于编写有效的交易策略和分析市场数据至关重要。一般来说,在进行量化回测时,我们可以选择使用专业的量化交易平台或软件,这些平台通常会提供相应的API接口来支持逐笔报价、批量订阅......
  • ros2:手动编译包
    首先需要colcon库支持sudoaptinstallpython3-colcon-common-extensions github上拉个包(这里使用示例程序)gitclonehttps://github.com/ros2/examplessrc/examples-bfoxy其中-bfoxy代表选择foxy版本分支 编译colconbuild 进入包所在目录cd/src/ex......
  • ROS2自定义msg
    在ROS2中,您可以通过编写自己的自定义消息来扩展消息类型。以下是如何创建自定义消息的一般步骤:1.**创建消息文件夹**:在功能包下创建msg的文件夹2.**编写消息文件**:在`msg`文件夹内创建一个`xxx.msg`文件,命名为所需的消息类型,例如`MyCustomMsg.msg`。3.**定义消息结构**:在消......
  • 在线和本地RSS订阅
    在线RSS订阅:https://www.inoreader.com/https://www.qireader.com/FluentReader--本地客户端https://github.com/yang991178/fluent-reader/releases 现在免费版本的Inoreader限制订阅数为100个左右,不升级的话Inoreader作为获取信息更新的价值也就不存在了,是时候放弃Inorea......
  • RSSHub给不支持RSS网站制作RSS订阅源-支持B站,知乎,微博,豆瓣,今日头条
    https://wzfou.com/rsshub/为了更快地搜集整理自己需要的信息,我们经常会用到RSS订阅,但是有一些高质量的网站,例如知乎、B站、微博、豆瓣、TG群组、非死不可、推@特等,官方是不支持使用RSS订阅的。之前我们分享过利用Huginn抓取任意网站RSS和微信公众号更新,不过Huginn架设的难度比较......
  • 探索发布-订阅模式的深度奥秘-实现高效、解耦的系统通信
    ​......
  • 探索发布-订阅模式的深度奥秘-实现高效、解耦的系统通信
    ​......
  • 探索设计模式的魅力:探索发布-订阅模式的深度奥秘-实现高效、解耦的系统通信
    ​......
  • C++发布订阅者模式:实现简单消息传递系统
     概述:这个C++示例演示了发布者-订阅者模式的基本实现。通过`Event`类,发布者`Publisher`发送数据,而订阅者`Subscriber`订阅并处理数据。通过简单的回调机制,实现了组件间松散耦合的消息传递。好的,我将为你提供一个简单的C++实例,演示如何使用发布者-订阅者模式。在这个例......
  • ROS2 自学之接口
    一、什么是接口std_msgs/msg/Stringstd_msgs/msg/UInt32在学习话题的时候,我们就已经接触到了如上两个接口,这两个接口分别是对应了字符串类型和u_int32的接口,所谓接口就是ROS2中提前定义好的一种规范。类似于充电器接口,尽管不同厂家制造的充电器不同,但他们都统一执行一种规......