ROS开发之如何在同一个节点订阅、处理、发布消息?

news2024/9/21 22:49:51

文章目录

  • 0、引言
  • 1、创建中间特殊文件(含订阅者和发布者)
  • 2、在CMakeLists.txt添加编译规则
  • 3、在launch添加启动项
  • 4、编译运行
  • 5、三维显示

0、引言

  在ROS应用一般会用到发布者和订阅者,若只接收传感器数据,则只实现订阅者就行,但有时需要订阅者部分做简单数据处理后,再发布出去,供其他订阅者接收。以上场景涉及一个中间文件,即既是订阅者,也是发布者的文件,本文查阅现有网络资源,复现现有实现方法,在树莓派中利用二维雷达传感器数据实现数据的订阅,做三维处理后发布,并在上位机虚拟机显示三维点云。相较于【ROS开发之如何将RPLidar数据在RViz中三维显示?】的修改原有代码实现订阅和发布的方式,本文创建了一个中间文件实现订阅和发布。

1、创建中间特殊文件(含订阅者和发布者)

  (1)在node.cpp同级目录下新建中间特殊文件middle_node.cpp;
  在这里插入图片描述

  (2)输入以下代码。

/***
Copyright 2023 cacrle ( cacrle.blog.csdn.net).
***/

#include "ros/ros.h"
#include <ros/package.h>
#include "sensor_msgs/LaserScan.h"
#include "std_srvs/Empty.h"
#include "rplidar.h"
#include <pcl_ros/point_cloud.h>
#include <pcl/point_types.h>
#include <boost/foreach.hpp>

//declare point data formate
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
pcl::PointCloud<pcl::PointXYZ> cloud_msg;

//a changable height
float count_h = 0;
//Avoid redefine
#ifndef DEG2RAD
#define DEG2RAD(x) ((x)*M_PI/180.)
#endif

//declare a publisher
ros::Publisher cloud_pub;

//the callback method, will monitor the topic and receive message
void scanCallback(const sensor_msgs::LaserScan::ConstPtr&amp; scan_msg)
{
    int count = scan_msg->scan_time / scan_msg->time_increment;
    cloud_msg.header.frame_id = "laser";
    cloud_msg.height = 1;
    cloud_msg.width = count;
    cloud_msg.points.resize(cloud_msg.width * cloud_msg.height);

	for(int i = 0; i < count; i++)
    {
        float degree = RAD2DEG(scan_msg->angle_min + scan_msg->angle_increment * i);
        cloud_msg.points[i].x = scan_msg->ranges[i] * cos(DEG2RAD(degree));
        cloud_msg.points[i].y = scan_msg->ranges[i] * sin(DEG2RAD(degree));
        cloud_msg.points[i].z = count_h;
        //print out data to screen
        ROS_INFO("[%f, %f, %f]", cloud_msg.points[i].x ,cloud_msg.points[i].y, cloud_msg.points[i].z);
	}
    count_h += 0.05;
    if(count_h>100)
    {
        count_h = 0;
    }
    //converse ros time to pcl time
    pcl_conversions::toPCL(ros::Time::now(),cloud_msg.header.stamp);
    cloud_pub.publish(cloud_msg);
}

int main(int argc, char **argv)
{
    //initial, "middle_node" is the name of cpp(i.e. midlle_node.cpp)
    ros::init(argc, argv, "middle_node");
    //declare a node
    ros::NodeHandle n;
    //declare a subscirber
    ros::Subscriber sub = n.subscribe<sensor_msgs::LaserScan>("scan", 1000, scanCallback);
    //give publisher a initial value, "point_cloud2" is topic, 1000 is frequency(unit is hz)
    cloud_pub = n.advertise<PointCloud>("point_cloud2",1000);
    //program reach here and stop to next, this code may monitor the scanCallback
    ros::spin();
    return 0;
}

2、在CMakeLists.txt添加编译规则

  在这里插入图片描述

cmake_minimum_required(VERSION 2.8.3)
project(rplidar_ros)

set(RPLIDAR_SDK_PATH "./sdk/")

FILE(GLOB RPLIDAR_SDK_SRC
"${RPLIDAR_SDK_PATH}/src/arch/linux/*.cpp"
"${RPLIDAR_SDK_PATH}/src/hal/*.cpp"
"${RPLIDAR_SDK_PATH}/src/*.cpp"
)
find_package(catkin REQUIRED COMPONENTS
roscpp
rosconsole
sensor_msgs
)

include_directories(
${RPLIDAR_SDK_PATH}/include
${RPLIDAR_SDK_PATH}/src
${catkin_INCLUDE_DIRS}
/usr/include/pcl-1.7
/usr/include/eigen3
)

catkin_package()
add_executable(rplidarNode src/node.cpp ${RPLIDAR_SDK_SRC})
target_link_libraries(rplidarNode ${catkin_LIBRARIES})

add_executable(rplidarNodeClient src/client.cpp)
target_link_libraries(rplidarNodeClient ${catkin_LIBRARIES})

add_executable(middle_node src/middle_node.cpp)
target_link_libraries(middle_node ${catkin_LIBRARIES})

install(TARGETS rplidarNode rplidarNodeClient
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

install(DIRECTORY launch rviz sdk
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
USE_SOURCE_PERMISSIONS
)

3、在launch添加启动项

  在这里插入图片描述

<launch>
<node name="rplidarNode"          pkg="rplidar_ros"  type="rplidarNode" output="screen">
<param name="serial_port"         type="string" value="/dev/ttyUSB0"/>
<param name="serial_baudrate"     type="int"    value="115200"/><!--A1/A2 -->
<!--param name="serial_baudrate"     type="int"    value="256000"--><!--A3 -->
<param name="frame_id"            type="string" value="laser"/>
<param name="inverted"            type="bool"   value="false"/>
<param name="angle_compensate"    type="bool"   value="true"/>
</node>

<node name="middle_node"          pkg="rplidar_ros"  type="middle_node" output="screen"/>
</launch>

4、编译运行

cd ~/catkin_ws

catkin_make
或
catkin_make_isolated

source devel/setup.bash
或
source devel_isolated/setup.bash

roslaunch rplidar_ros rplidar.launch

  在这里插入图片描述

5、三维显示

  (1)RViz参数设置;
  在这里插入图片描述

  (2)显示结果。
  在这里插入图片描述

参考资料:
[1] cacrle. ROS如何进行开发?; 2023-04-10 [accessed 2023-04-13].
[2] cacrle. ROS开发之如何使用发布者、订阅者和话题消息?; 2023-04-12 [accessed 2023-04-13].
[3] cacrle. ROS开发之如何制作launch启动文件?; 2023-04-11 [accessed 2023-04-13].
[4] cacrle. ROS开发之如何使用RPLidar A1二维激光雷达?; 2023-04-11 [accessed 2023-04-13].
[5] cacrle. ROS开发之如何将树莓派采集的雷达、IMU数据在虚拟机rviz中显示?; 2023-04-12 [accessed 2023-04-13].
[6] cacrle. ROS开发之如何将RPLidar数据在RViz中三维显示?; 2023-04-12 [accessed 2023-04-13].
[7] cacrle. Windows与Linux 之间如何进行文件共享?; 2023-03-27 [accessed 2023-04-13].
[8] 十年前与现在. ros-同时订阅与发布; 2020-08-07 [accessed 2023-04-13].
[9] 白巧克力亦唯心. ROS 基础: 在同一个节点里订阅和发布消息; 2015-05-07 [accessed 2023-04-13].
[10] cyliujc. ros同时接收多话题并发布; 2017-12-04 [accessed 2023-04-13].
[11] 小萌是个球. ros::spin() 和 ros::spinOnce() 区别及详解 ; 2016-10-01 [accessed 2023-04-13].

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/416783.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

客户服务 KPI是什么

当企业着手改进其客户服务计划时&#xff0c;必须以可衡量的方式进行。因为如果我们为了改进而改进&#xff0c;没有衡量&#xff0c;我们就永远无法真正知道我们做得有多好&#xff01;如果您的公司已准备好升级其客户服务计划&#xff0c;这里有 12种方法可以衡量和跟踪您的客…

大学生问AI

大学生问AI写在最前面2&#xff0c;描述你在学习工作中碰到的最高级的 AI 是什么&#xff1f;1&#xff0c;你人生中第一次接触到 “人工智能” 的概念和产品是什么&#xff1f; 让你觉得 “人类做得东西的确有智能”&#xff1f;3&#xff0c;你听说过最近的 GPT&#xff0c;n…

Qt5.12實戰之Linux靜態庫與動態庫多文件生成a與so文件並調用

1.編輯並輸入內容到test.cpp與test2.cpp test.cpp #include <stdio.h> int func() {return 888; } test2.cpp #include <stdio.h> int func2() {return 999; } 將test.cpp與test2.cpp編譯成目標文件&#xff1a; g -c test.cpp test2.cpp 一次性生成目標文件…

阅读提升内在美

最近&#xff0c;想在内在美上提升自己&#xff0c;想把玩游戏的时间腾给阅读。不想只是善良&#xff0c;更希望自己拥有智慧拥有力量&#xff0c;更自信更热爱生活。 本篇博文会日日更新&#xff0c;也当作鼓励我继续阅读坚持阅读的动力和监督。 Z-Library 图书馆 分享一个…

LeetCode 1041. 困于环中的机器人

原题链接&#xff1a;1041. 困于环中的机器人 在无限的平面上&#xff0c;机器人最初位于 (0, 0) 处&#xff0c;面朝北方。注意: 北方向 是y轴的正方向。南方向 是y轴的负方向。东方向 是x轴的正方向。西方向 是x轴的负方向。 机器人可以接受下列三条指令之一&#xff1a; …

测试专家须精通Locust

目前随着AI人工智能越来越火&#xff0c;Python 编写的程序越来越多&#xff0c;更多的协议&#xff0c;更多的复杂应用。 所以Locust 是高级性能测试工程师和测试专家&#xff0c;必备技术之一&#xff0c;因为你不可能避免公司中使用python.编写接口或者程序。 在互联网公司…

C#|调用C/C++动态库

参考&#xff1a;C#总结&#xff08;四&#xff09;调用C动态库&#xff08;https://www.shuzhiduo.com/A/A2dmV49qze/&#xff09; 文章目录C#加载C动态库C#加载C#动态库涉及到的概念知识&#xff1a;托管DLL和非托管DLL的区别&#xff08;https://www.tinymind.net.cn/articl…

利用 ELK 处理 Percona 审计日志

Percona Server为 MySQL 数据库服务器进行了改进&#xff0c;在功能和性能上较 MySQL 有着很显著的提升。该版本提升了在高负载情况下的 InnoDB 的性能、为 DBA 提供一些非常有用的性能诊断工具&#xff1b;另外有更多的参数和命令来控制服务器行为 前提 1、有强烈的审计需求。…

网站建设常用的cms建站系统推荐

国内网站建设市场参差不齐&#xff0c;建站公司多如牛毛&#xff0c;网站价格便宜的几百&#xff0c;贵的几十万&#xff0c;作为外行&#xff0c;很难去选择&#xff0c;国内大部分网站建设公司都是营销公司&#xff0c;完全没有底层技术框架的开发能力&#xff0c;90%以上的网…

srs流媒体服务安装和使用

简介 SRS(Simple Realtime Server)是一个简单高效的实时视频服务器&#xff0c;支持RTMP、WebRTC、HLS、HTTP-FLV、SRT等多种实时流媒体协议。 官网&#xff1a;https://ossrs.net/lts/zh-cn/ 编译安装 使用ubuntu系统作为例子&#xff0c;最好是20版本。 1、克隆项目代码 …

2023.4.12

文章目录一&#xff1a;try catch处理异常1&#xff1a;原理&#xff1a;2&#xff1a;catch中如何处理异常**3&#xff1a;try-catch-finally**4&#xff1a;多重catch5&#xff1a;异常的分类6&#xff1a;throw和throws的区别7&#xff1a;练习题8&#xff1a;重载和重写的异…

Python后端架构演进

做了3年的后端开发, 经历一款SaaS产品从0到10(还没有到100, 哈哈哈)的过程, 3年间后端的架构逐步演变, 在微服务的实践过程中遇到的问题也越来越多, 在这里总结下. 产品是一款服务于人力资源的SaaS在线服务, 面向HR有Web Android/iOS 小程序多个客户端, 后端采用RESTful风格AP…

表id自增的方法

数据库主键id自增的方法&#xff0c;列举了几种如下 一、数据库自增&#xff08;部分数据库支持&#xff09; 创建表的时候设置id自增即可&#xff0c;或者后期修改表id自增 # mysql 语法 create table your_table_name(id bigint(20) not null auto_increment primary key …

Android技术分享 | 一行代码实现屏幕、声音采集

之前发布过一行代码实现安卓屏幕采集编码&#xff0c;并介绍了如何屏幕采集编码并进行了封装&#xff0c;简单的调用即可实现MediaProjection权限申请、H264硬编码、错误处理等功能。本文将介绍新增的功能&#xff0c;还是只需一行代码即可实现屏幕、声音采集。 一行代码实现屏…

【原创】万字长文讲解AI绘画基本技术原理

作者&#xff1a;黑夜路人 时间&#xff1a;2023年4月12日 AIGC是什么 AIGC - AI Generated Content &#xff08;AI生成内容&#xff09;&#xff0c;对应我们的过去的主要是 UGC&#xff08;User Generated Content&#xff09;和 PGC&#xff08;Professional user Generat…

c语言数据结构——树形结构之树和二叉树

前言 二叉树有什么用&#xff1f; 二叉树应用非常广泛。 在操作系统源程序中&#xff0c;树和森林被用来构造文件系统。我们看到的window和linux等文件管理系统都是树型结构。在编译系统中&#xff0c;如C编译器源代码中&#xff0c;二叉树的中序遍历形式被用来存放C 语言中的…

如何从阿里云盘下载大文件到自己的电脑或者租赁的服务器中?

首先进入阿里云盘的github项目处&#xff0c;里面有详细的说明&#xff0c;入口&#xff1a;https://github.com/tickstep/aliyunpan Ubuntu挂载阿里云盘作为自己的硬盘 如果你是Ubuntu系统的话&#xff0c;直接在使用apt命令在电脑安装阿里云盘即可&#xff0c;命令如下&…

Oracle基础部分二(伪列/表、单个函数、空值处理、行列转换、分析函数、集合运算)

Oracle基础部分二&#xff08;伪列/表、单个函数、空值处理、行列转换、分析函数、集合运算&#xff09;1 伪列、伪表1.1 伪列1.2 伪表2 单个函数2.1 常用字符串函数2.1.1 length() 询指定字符的长度2.1.2 substr() 用于截取字符串2.1.3 concat() 用于字符串拼接2.2 常用数值函…

生成树端口选举

所有交换机运行RSTP,SW1优先级4096,SW2优先级4096,SW3优先级8192,SW1的G0/0/1、G0/0/2接口通过手动模式加入Eth-Trunk 1,SW1的G0/0/3、G0/0/4接口通过手动模式加入Eth-Trunk 2,SW2的G0/0/1、G0/0/2接口通过手动模式加入Eth-Trunk 1,SW3的G0/0/1、G0/0/2接口通过手动模式…

【Unity VR开发】结合VRTK4.0:攀爬功能

语录&#xff1a; 不要因为开心消失了而感到难过&#xff0c;宇宙正在努力为你准备下一场惊喜&#xff0c;你要给宇宙一点时间。 前言&#xff1a; 攀爬是虚拟现实中一种有趣的运动&#xff0c;可以使用定制的可交互预制体轻松创建这种机制来处理攀爬动作&#xff0c;以及处理用…