代码片段

这部分代码在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. Effective Python:简介

    作者:布雷特·斯拉特金 本书的大部分范例代码都遵循Python 3.7版本的语法规范,Python 3.7发布于2018年6月.另外,书里还会给出一些采用Python 3.8语法规范所写的范例,让大家 ...

  2. kong管理界面konga的安装

    kong网关自身的管理界面属于付费的应用,而第三方界面又非常少,konga算是相对比较好的一款了,虽然也有一些问题,但整体的功能还比较全,github仓库为:https://github.com/pa ...

  3. 从 2018 年 Nacos 开源说起

    2018 年夏天 国内微服务开源 领域,迎来了一位新成员.此后,在构建微服务注册中心和配置中心的过程中,国内开发者多了一个可信赖的选项. Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务 ...

  4. 智能logo免费体验|如何让餐饮logo在点评网站上一眼出众?

    ​简介:一个新的餐饮店铺,还没有人知晓,Logo就是这个重要的"门面",所传递的信息让人快速识别,就能产生记忆点,愿意进一步了解,从而为店铺带来流量和收益.如何让你的餐饮店铺log ...

  5. 为了让你在“口袋奇兵”聊遍全球,Serverless 做了什么?

    简介: 江娱互动是一家新兴的游戏企业,自 2018 年成立伊始,江娱互动就面向广阔的全球游戏市场,通过创造有趣的游戏体验,在竞争激烈的游戏市场占得一席之地.仅仅 2 年的时间,江娱互动就凭借 Topw ...

  6. [FAQ] 修改了Dockerfile 之后,运行 docker-compose up --force-recreate 时还是报之前构建时的错误?

      因为 Docker Compose 的 --force-recreate 选项只会强制重新创建容器,而不会重新构建镜像. 因此,如果你修改了Dockerfile,需要确保重新构建新的镜像. 你可以 ...

  7. [FAQ] 阿里云一口价域名购买之后在哪里看

    进入控制台,产品和服务中找到"域名",进去后在左侧菜单有 "已买到的域名". 如图: Link:https://www.cnblogs.com/farwish/ ...

  8. [Go] golang 时间格式化 12小时制 与 24小时制

    timestamp := int64(1591271169) # 12小时制 time.Unix(timestamp, 0).Format("2006-01-02 03:04:05" ...

  9. dotnet 将任意时区的 DateTimeOffset 转换为中国时区时间文本

    本文告诉大家在拿到任意时区的 DateTimeOffset 对象,将 DateTimeOffset 转换为使用中国的 +8 时区表示的时间 在开始之前,需要说明的是,采用 DateTimeOffset ...

  10. VMware最小化安装Centos7.6-无桌面

    目录 安装包工具 新建虚拟机 安装 centos 7.6 系统 终端登陆系统 设置ip地址 关闭防火墙 关闭 SELINUX SELINUX=enforcing 硬盘挂载 桥接上网方式 安装包工具 V ...