ROS中使用VLP16激光雷达获取点云数据

news2024/11/24 3:54:19

ROS中使用VLP16激光雷达获取点云数据

个人博客地址

本文测试环境为:Ubuntu20.04 ROS Noetic


需要将激光雷达与PC连接,然后在设置=>网络=>有线中将IPv4改为手动,并且地址为192.168.1.100,子网掩码为255.255.255.0,点击应用。然后在浏览器输入192.168.1.201,如果成功进入配置界面则表示连接成功。

安装VLP驱动

cd catkin_ws/src
git clone https://github.com/ros-drivers/velodyne.git

继续执行下面命令。如果在执行第二条命令的时候报错了,需要根据终端的提示安装一些包或者可以看看这篇文章点我

cd ..
rosdep install --from-paths src --ignore-src --rosdistro noetic -y
catkin_make

报错处理:

如果catkin_make命令找不到,就需要看安装ROS依赖最后source脚本部分有没有完成。

编译中间如果出现找不到文件的报错,大概率是没有安装对应的包。

例如出现“Could NOT find image_transport (missing: image_transport_DIR)”错误,那就需要在终端输入sudo apt install ros-noetic-image-transport.

如果遇到“Could NOT find PY_em (missing: PY_EM)”错误,就需要运行catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python3

报错参考文章:

ROS报错:-- Could NOT find PY_em (missing: PY_EM)

ROS报错:Command ‘catkin_make‘ not found

【ROS】解决rosdep无法更新、缺少依赖问题

可视化测试

运行rosrun找不到命令的话,可以使用sudo apt install ros-noetic-rosbash安装。

sudo apt-get install ros-noetic-rviz

在终端输入下面命令,这个命令会一直运行,可以用Ctrl+C结束。要在catkin_velodyne目录下运行。

roslaunch velodyne_pointcloud VLP16_points.launch

运行后会出现一个窗口,将其左上角Fixed Framemap修改为velodyne。如果是运行rosrun rviz rviz -f velodyne命令话就不用做这一步了。

在这里插入图片描述

再点击左下角的Add,在弹出的窗口中选择By topic,再选择PointCloud2,最后点击OK

在这里插入图片描述

之后就可以在右侧看到可视化点云了。

在这里插入图片描述

录制和播放点云

在终端运行下面命令可以录制点云,点云记录会默认生成在运行目录。可以使用Crtl+C结束录制。

rosbag record out /velodyne_points

在终端运行下面命令可以播放点云,第一个参数填写要播放的点云记录。可以在rviz中看到播放的结果。按空格键可以暂停播放。

rosbag play 2023-03-28-22-49-58.bag

但是如果是在一直可视化显示点云的rviz下播放记录会出现重叠现象,看起来非常不舒服,因此最好是再重新开一个rviz窗口进行播放。

在终端输入roscore命令,然后再重新开一个终端输入rosrun rviz rviz -f velodyne命令。

点击左下角的Add,在弹出的窗口中选择PointCloud2,最后点击OK

在这里插入图片描述

点开左侧的PointCloud2,将Topic的内容改为*/velodyne_points*

在这里插入图片描述

之后在终端中输入播放命令rosbag play 2023-03-28-22-49-58.bag,就可以在该窗口的右侧看到播放画面了。

将bag文件转化成pcd文件

录制点云会生成bag文件,可以将该文件记录的每一帧点云转换成pcd格式并保存下来。

首先在终端中输入roscore命令

再开启一个终端输入下面的命令。output.bag为要处理的bag文件;*pcd/*为最终pcd文件的输出目录

rosrun pcl_ros bag_to_pcd output.bag /velodyne_points pcd/

python获取实时点云数据并保存成pcd文件

使用python获取VLP16返回的实时点云数据,并把每一帧数据保存成pcd文件。下面介绍两种方式:

方式一:

#!/usr/bin/env python

import rospy
from sensor_msgs.msg import PointCloud2
import sensor_msgs.point_cloud2 as pc2


counts = 0
def callback(data):
    global counts
    counts += 1
    gen = pc2.read_points(data, skip_nans=True)
    cloud = []
    for p in gen:
        # p是元组类型,代表一个点云数据,一共有6个元素,分别为x, y, z, intensity, ring, time
        cloud.append([p[0], p[1], p[2]])
    # pcd_name = str(counts) + ".pcd"
    with open('output.pcd', 'w') as f:
        f.write('# .PCD v.7 - Point Cloud Data file format\n')
        f.write('VERSION .7\n')
        f.write('FIELDS x y z\n')
        f.write('SIZE 4 4 4\n')
        f.write('TYPE F F F\n')
        f.write('COUNT 1 1 1\n')
        f.write('WIDTH %d\n' % len(cloud))
        f.write('HEIGHT 1\n')
        f.write('VIEWPOINT 0 0 0 1 0 0 0\n')
        f.write('POINTS %d\n' % len(cloud))
        f.write('DATA ascii\n')
        for p in cloud:
            f.write('%f %f %f\n' % (p[0], p[1], p[2]))
    print(counts)


def listener():
    rospy.init_node('velodyne_listener', anonymous=True)
    rospy.Subscriber('/velodyne_points', PointCloud2, callback)
    rospy.spin()

if __name__ == '__main__':
    listener()

方式二:

import rospy
from sensor_msgs.msg import PointCloud2
import sensor_msgs.point_cloud2 as pc2


counts = 0
def callback(data):
    global counts
    counts += 1
    # cloud_list是列表类型,其存放着每个点云数据
    # 每个点云数据是sensor_msgs.point_cloud2.Point类型,共有6个元素,分别为x, y, z, intensity, ring, time
    cloud_list = pc2.read_points_list(data, skip_nans=True)
    # pcd_name = str(counts) + ".pcd"
    with open('output_list.pcd', 'w') as f:
        f.write('# .PCD v.7 - Point Cloud Data file format\n')
        f.write('VERSION .7\n')
        f.write('FIELDS x y z\n')
        f.write('SIZE 4 4 4\n')
        f.write('TYPE F F F\n')
        f.write('COUNT 1 1 1\n')
        f.write('WIDTH %d\n' % len(cloud_list))
        f.write('HEIGHT 1\n')
        f.write('VIEWPOINT 0 0 0 1 0 0 0\n')
        f.write('POINTS %d\n' % len(cloud_list))
        f.write('DATA ascii\n')
        for i in range(len(cloud_list)):
            f.write('%f %f %f\n' % (cloud_list[i][0], cloud_list[i][1], cloud_list[i][2]))
    print(counts)


def listener():
    rospy.init_node('velodyne_listener', anonymous=True)
    rospy.Subscriber('/velodyne_points', PointCloud2, callback)
    rospy.spin()

if __name__ == '__main__':
    listener()

实时可视化激光雷达点云数据

from sensor_msgs.msg import PointCloud2
import sensor_msgs.point_cloud2 as pc2
import numpy as np
import open3d as o3d
import rospy
import cv2


# 按下B结束运行
def key_callback(vis):
    global stop_flag
    stop_flag = True
    print("Stop")


if __name__ == '__main__':
    # 创建可视化窗口和点云
    vis = o3d.visualization.VisualizerWithKeyCallback()
    vis.create_window(width=1080, height=720)
    vis_render = vis.get_render_option()
    vis_render.background_color = (0, 0, 0)
    vis.register_key_callback(ord('B'), key_callback)
    pcd = o3d.geometry.PointCloud()

    # 标记
    add_flag = False    # 首次vis.add标记
    stop_flag = False    # 停止标记

    # 初始化ros节点
    rospy.init_node('velodyne_listener', anonymous=True)

    while not stop_flag:      
        # 等待一次消息
        data = rospy.wait_for_message('/velodyne_points', PointCloud2, timeout=None)
        gen = pc2.read_points(data, skip_nans=True)
        cloud = []
        for p in gen:
            cloud.append([p[0], p[1], p[2], p[3]])
        points = np.array(cloud).astype(np.float32)
        # 提取xyz,暂时不需要强度
        points_xyz = points[:, :3]

        pcd.points = o3d.utility.Vector3dVector(points_xyz)
        if not add_flag:
            vis.add_geometry(pcd)
            add_flag = True
        vis.update_geometry(pcd)
        vis.poll_events()
        vis.update_renderer()
    vis.destroy_window()

在这里使用的是rospy.wait_for_message用于接收一次消息,该函数会返回接收到的消息。可以设置timeout=rospy.Duration(1),代表超时时间为1秒钟。如果在1秒内没有收到消息,则函数会返回None。

如果使用rospy.spin的话,程序运行到这行代码就会卡死,不会往下执行其他代码,所以在实时可视化的时候不能使用。

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

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

相关文章

leetcode61. 旋转链表(java)

旋转链表 leetcode61. 旋转链表题目描述 解题思路代码演示链表专题 leetcode61. 旋转链表 Leetcode链接: https://leetcode.cn/problems/rotate-list/ 题目描述 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。 示例…

浅析 xml 数据格式文件

浅析 xml 数据格式文件 xml ( Extensible Markup Language ) 全称 -> 可拓展的标记语言; xml文件的主要用途:xml文件主要用于数据的 传输 和 存储,并不是展示; xml标签与html的区别:节点的标签使用方式和 html 十分…

【产品经理】企业的产品增长之路

英特尔前CEO安迪格鲁夫有本书叫做《Only the Paranoid Survive》,全文的中心思想是警示他人,要居安思危,唯有打破常规,不拘泥于现状才能生存。 一、为何企业都在关注增长? 1. 诺基亚的贱卖 13年市值曾位居全球上市公…

HNU-操作系统OS-作业1(4-9章)

这份文件是OS_homework_1 by计科2102 wolf 202108010XXX 文档设置了目录,可以通过目录快速跳转至答案部分。 第四章 4.1用以下标志运行程序:./process-run.py -l 5:100,5:100。CPU 利用率(CPU 使用时间的百分比)应该是多少?为什么你知道这一点?利用 -c 标记查看你…

Spring中如何获取Bean方法上的自定义注解

文章目录 背景描述场景复现问题追踪解决方案扩展思考 背景描述 项目中需要扫描出来所有 标注了自定义注解A的Service里面标注了自定义注解B的方法 来做后续处理。 基本的思路就是通过Spring提供的ApplicationContext#getBeansWithAnnotation反射 来实现。 但是,随…

【Spring】核心与设计思想

哈喽,哈喽,大家好~ 我是你们的老朋友:保护小周ღ 谈起Java 圈子里的框架,最年长最耀眼的莫过于 Spring 框架啦,如今已成为最流行、最广泛使用的Java开发框架之一。不知道大家有没有在使用 Spring 框架的时候思考过这…

11111111111

def cosine_similarity(vector_a, vector_b): “”" 计算两个向量之间的余弦相似度 :param vector_a: 向量 a :param vector_b: 向量 b :return: distance “”" vector_a np.mat(vector_a) vector_b np.mat(vector_b) num float(vector_a * vector_b.T) denom n…

华为OD机试真题 Java 实现【预定酒店】【2022Q4 100分】

一、题目描述 放暑假了,小明决定到某旅游景点游玩,他在网上搜索到了各种价位的酒店(长度为n的 数组A),他的心理价位是x元,请帮他筛选出k个最接近x元的酒店 (n>=k>0) ,并由低到高打印酒店的价格。 二、输入描述 第一行: n,k,x 第二行: A[o] A[1] A[2]…A[n-1] 三…

djiango orm简单实现增删改查

目录 一、配置数据库1.1 在settings.py文件中找到DATABASES ,配置数据库连接,这里用的是mysql 二、切换操作数据库的模块三、 创建一个app并注册3.1创建一个app3.2 注册app 三、在app1定义模型类四、迁移数据库,使用以下命令,生成…

Android修改aar并重新打包

目录 一.修改 aar 需要用到的工具(就一个工具,使用方式非常简单,别担心) 二.修改 aar 代码层业务逻辑 三.修改 aar layout 布局文件 四.附上recyclerview aar修改工程源码 一.修改 aar 需要用到的工具(就一个工具&…

MKS SERVO4257D 闭环步进电机_系列8 CAN通讯示例

第1部分 产品介绍 MKS SERVO 28D/35D/42D/57D 系列闭环步进电机是创客基地为满足市场需求而自主研发的一款产品。具备脉冲接口和RS485/CAN串行接口,支持MODBUS-RTU通讯协议,内置高效FOC矢量算法,采用高精度编码器,通过位置反馈&a…

AD19操作注意事项及信息

直接在PCB编辑界面添加差分对(差分布线) 1.PCB边界界面Panels菜单调出PCB界面 2.选择框中信息,点击添加差分对即可,然后利用交互式差分对布线命令进行布线操作。(前提设置好差分布线规则) 过孔&#xff1a…

7年经验之谈 —— 如何进行渗透测试以提高软件安全性?

对于各种规模的企业和组织来说,软件安全是一个至关重要的问题。随着网络攻击越来越复杂,软件中的漏洞越来越多,确保你的软件安全比以往任何时候都更重要。提高软件安全性的一个有效方法是渗透测试(penetration testing&#xff09…

6月9号软件资讯更新合集....

Vivaldi 6.1 发布,可绕过微软限制使用 Bing Chat 最新版本的 Vivaldi 可在桌面端伪装成 Edge,使其用户受益,并为工作空间和标签增加了更多的功能。 支持微软 Bing Chat Vivaldi 是建立在 Chromium 开源项目之上的。它与 Edge 和 Chrome 使用…

Android kotlin序列化之Parcelable详解与使用(二)

一、介绍 注解序列化篇:Android kotlin序列化之Parcelize详解与使用_蜗牛、Z的博客-CSDN博客 通过上一篇注解序列化,我们已了解的kotlin的序列化比Java复杂了很多。而且有好多问题,注解虽好,但是存在一些问题。 一般在大型商业…

【Flutter】如何更改 Flutter 应用的启动图标

文章目录 一、前言二、什么是启动图标三、为什么我们需要更改启动图标四、如何更改启动图标五、注意事项六、总结 一、前言 欢迎来到 Flutter 的世界!在这篇文章中,我们将探索 Flutter 的一些基础知识。但是,你知道吗?这只是冰山…

爬虫一般怎么解决加密问题?

① 对于网页端来说通常加密的算法是写在 js 代码里的,所以首先你要对 js 语言有所了解。 至少知道 js 基础的内容,其次找到对应 js 加密代码,然后找出关键的函数。 把 js 代码在 node.js 环境进行调试,最后在 Python 环境下利用…

Goby 漏洞发布|maxView Storage Manager 系统 dynamiccontent.properties.xhtml 远程代码执行漏洞

漏洞名称:maxView Storage Manager 系统 dynamiccontent.properties.xhtml 远程代码执行漏洞 English Name:maxView Storage Manager dynamiccontent.properties.xhtml RCE CVSS core: 9.8 影响资产数:1465 漏洞描述: maxVie…

C++debug-centos-ubuntu-vscode

1.centos下安装VSCODE 在linux系统(centOS7)中安装VSCode(Visual Studio Code)_centos vscode安装_沈醉不知的博客-CSDN博客 pacman -S code2.ubuntu下安装VSCODE 与windows下一样。 3.windows 调试 下载安装vscode cmake https://cmake.org/download GDB:UNIX及UNIX-…

php7.4生产环境压力测试CPU占用100%解决方案

最近开发了一个项目,客户要求压力测试,测试时发现并发量大时php-fpm占用cpu一直100%,调整了php的最大进程数pm.max_children,优化了程序效果不明显。后面使用了opcache,cpu使用率一下降到20%左右。 什么是opcache?下面…