代码片段

这部分代码在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

ros2 foxy订阅话题问题的更多相关文章

  1. 在ROS下编写自己的节点来订阅话题(C++)

    参考 http://blog.csdn.net/u013453604/article/details/49102957     的博客,其实这些内容和 <开源机器人操作系统> 这本书差不多 ...

  2. ROS开发--在订阅话题的回调函数中发布话题

    处理激光数据时,需要将处理后的激光数据再发布,需要保持一致的频率,所以必须在回调函数中发布激光数据信息. 代码参考:https://blog.csdn.net/heyijia0327/article/ ...

  3. ROS2学习之旅(14)——编写简单的发布者和订阅者(C++)

    节点是通过ROS Graph进行通信的可执行进程.在本文中,节点将通过话题以字符串消息的形式相互传递信息.这里使用的例子是一个简单的"talker"和"listener& ...

  4. ROS2学习之旅(1)——初识ROS2

    本系列用来记录ROS2的学习过程,有错误或者不合理的地方请大家指正.由于博主具有ROS1的学习经历,会添加一些与ROS1的一些对比,当然这对于ROS2本身的学习内容没有丝毫影响,欢迎大家积极与我在评论 ...

  5. ubuntu 20.04 安装 ros1 和ros2

    ubuntu  选择Hong Kong 源 1. ROS1安装 添加 sources.list(设置你的电脑可以从 packages.ros.org 接收软件.) sudo sh -c '. /etc ...

  6. 使用Python发送、订阅消息

    使用Python发送.订阅消息 使用插件 paho-mqtt 官方文档:http://shaocheng.li/post/blog/2017-05-23 Paho 是一个开源的 MQTT 客户端项目, ...

  7. Ubuntu 20.04下源码编译安装ROS 2 Foxy Fitzroy

    ROS 2 Foxy Fitzroy(以下简称Foxy)于2020年6月5日正式发布了,是LTS版本,支持到2023年5月.本文主要根据官方的编译安装教程[1]完成,并记录编译过程中遇到的问题. 1. ...

  8. [转]RoboWare Studio的使用和发布器/订阅器的编写与测试

    原文地址:https://blog.csdn.net/han_l/article/details/77772352,转载主要方便随时查阅,如有版权要求,请及时联系. 开始ROS学习之前,先按照官网教程 ...

  9. 机器人操作系统(ROS)教程4:ROS的框架【转】

    转自:http://www.arduino.cn/thread-11351-1-1.html 在进行ROS的代码开发前,有必要了解一些ROS的概念.首先,ROS的系统代码分为两部分:main和univ ...

  10. Apache Kafka:下一代分布式消息系统

    [http://www.infoq.com/cn/articles/apache-kafka/]分布式发布-订阅消息系统. Kafka是一种快速.可扩展的.设计内在就是分布式的,分区的和可复制的提交日 ...

随机推荐

  1. xml转voc数据集(含分享数据集)

    数据集的链接:行人检测数据集voc数据集(100张) 原始图片和.xml数据目录结构如下: . └── data ├── 003002_0.jpg ├── 003002_0.xml ├── 00300 ...

  2. requests模块发送post请求,flask开启服务接收请求,python

    request模块部分 import requests import json if __name__ == '__main__': url = 'http://127.0.0.1:5000' dat ...

  3. 力扣29(java)-两数相除(中等)

    题目: 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 整数除 ...

  4. 动态尺寸模型优化实践之Shape Constraint IR Part II

    简介: 在本系列分享中我们将介绍BladeDISC在动态shape语义下做性能优化的一些实践和思考.本次分享的是我们最近开展的有关shape constraint IR的工作,Part II 中我们将 ...

  5. 走进RDS|说说关系型数据库与Serverless

    ​简介:看到如今Serverless在云计算行业喷薄欲出的态势,像极了<星星之火,可以燎原>中的描述:虽然不能预测未来的发展和变化,但对于云计算来说这是个相对确定的方向.本文将和大家说说关 ...

  6. 如何使用Delta Lake构建批流一体数据仓库

    ​简介:Delta Lake是一个开源存储层,它为数据湖带来了可靠性.Delta Lake提供了ACID事务.可扩展的元数据处理,并统一了流式处理和批处理数据处理.Delta-Lake运行在现有数据湖 ...

  7. Java 定时任务技术趋势

    ​简介:定时任务是每个业务常见的需求,比如每分钟扫描超时支付的订单,每小时清理一次数据库历史数据,每天统计前一天的数据并生成报表等等. 作者:黄晓萌(学仁) Java 中自带的解决方案 使用 Time ...

  8. Spring Boot Serverless 实战 | Serverless 应用的监控与调试

    ​简介:Spring Boot 是基于 Java Spring 框架的套件,它预装了 Spring 的一系列组件,让开发者只需要很少的配置就可以创建独立运行的应用程序.在云原生的环境中,有大量的平台可 ...

  9. [Contract] Solidity 合约发布到测试网 ropsten 的作用

    当我们本地完成了一系列测试以后,接下来就是准备上线了. 关于合约部署可以参考这篇:Solidity 合约使用 truffle 部署到测试网和主网 你可能有一个疑问,在上主网之前,先上测试网的作用是什么 ...

  10. WPF 由于系统颜色配置 Mscms 组件损坏启动失败

    本文记录 WPF 应用程序,因为系统的颜色配置 Mscms.dll 组件损坏导致应用加载图片失败,从而启动失败的原因和解决方法 在 WPF 应用加载图片时,将会调用到系统的 Mscms.dll 组件. ...