本文是在假设可以将雷达系统、ROS和PCL可以结合用的条件下写的,这里主要是在前文的基础上结合了获取实时的时间,并将时间写成 hour_minute_second_mincond.pcd格式,比如"13_20_15_33.pcd",表示13时20分15秒33微秒获取的点云数据,pcd是文件的后缀。
读取雷达的点云数据的方法可以参我写的另一篇博文11.2 PCL从ROS获取激光雷达的点云数据及处理-优快云博客
下面直接直接写实时存取点云数据的C++代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <sstream>
#include <ctime>
#include <time.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <cstdlib>
#include <ros/ros.h>
#include <pcl/point_cloud.h>
#include <pcl_conversions/pcl_conversions.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl/io/pcd_io.h>
//using namespace std;
void cloudCB(const sensor_msgs::PointCloud2 &input)
{
pcl::PointCloud<pcl::PointXYZ> cloud;
pcl::fromROSMsg(input, cloud);
//pcl::io::savePCDFileASCII ("write_pcd_test.pcd", cloud);
while (1)
{
time_t t = time(nullptr); // 获取1970年到现在的毫秒数
struct tm* now = localtime(&t); // 把毫秒转换为日期时间的结构体
std::stringstream timeStr;
// 以下依次把年月日的数据加入到字符串中
timeStr << now->tm_hour << "_";
timeStr << now->tm_min << "_";
timeStr << now->tm_sec<< "_";
struct timeval time;
/* 获取时间,理论到us */
gettimeofday(&time, NULL);
//printf("s: %ld, ms: %ld\n", time.tv_sec, (time.tv_sec*1000 + time.tv_usec/1000));
timeStr <<time.tv_usec/1000 << ".pcd";
std::string strs=timeStr.str();
std::cout << strs <<std::endl;
std::string oldName, newName;
//oldName = "/home/rpdzkj/lidar_workspace/src/chapter10_tutorials/write_pcd_test.pcd";
newName = "/home/rpdzkj/lidar_workspace/src/chapter10_tutorials/data/";
newName+=strs;
//rename(oldName.c_str(), newName.c_str());
pcl::io::savePCDFileASCII (newName, cloud);
usleep(300000); }//延时 usleep:微秒 sleep:秒
}
int main(int argc, char *argv[])
{
ros::init (argc, argv, "pcd_write");
ros::NodeHandle nh;
ros::Subscriber bat_sub = nh.subscribe("/livox/lidar", 10,cloudCB);
ros::spin();
return 0;
}
思路也比较简单,就是先获取实时时间再将时间写成"13_20_15_33.pcd"格式,再用前面的博文写的保存点云数据的方法,将保持路径由实时时间传参即可。这里我们就可以实时循环保存pcd文件了。
保存文件的效果如下:(每0.3秒保存一张图片)