LiDAR-Velodyne激光雷达pcap文件解析

2024-02-14 23:38

本文主要是介绍LiDAR-Velodyne激光雷达pcap文件解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

       在使用velodyne的时候,PCAP数据解析比较麻烦,为此写了一点代码来专门解析PCAP文件,将PCAP格式数据转为XYZ格式的点云数据,写完之后发现其实代码也不多,更轻量级了,代码如下:

// readpcap.cpp : 定义控制台应用程序的入口点。
//
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_WARNINGS
#include "pcap.h"
#include "stdio.h"
#include "math.h"
#include<stdlib.h>
#include<conio.h>
#include "velodyneptk.h"
#define LINE_LEN 16int Azimuth_[12];				//原始值
float Azimuth_Value_[12];
int Distance_[12][32];			//原始值
float Distance_Value_[12][32];
int Atten_[12][32];		//原始值
Usefulmessage UsefulData;
int framecount;
int frameint;
//计算时间戳函数
float Timeoffsetvec[384];
float lasersinvec[384];
float lasercosvec[384];
void Timeoffsetfun()
{for (int i = 0; i < 24; i++){for (int j = 0; j < 16; j++){Timeoffsetvec[i * 16 + j] = i*55.296 + j*2.304;lasersinvec[i * 16 + j] = LASER_SIN[j];lasercosvec[i * 16 + j] = LASER_COS[j];}}
}void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *);//byte转int  Azimuth
int bytes2ToInt(byte* bytes)
{int addr = bytes[0] & 0xFF;addr |= (bytes[1]<<8 & 0xFF00);return addr;
}int bytes1ToInt(byte* bytes)
{int addr = bytes[0] & 0xFF;return addr;
}//byte转int  Azimuth
long int bytes4ToInt(byte* bytes)
{long int addr = bytes[0] & 0xFF;addr |= (bytes[1] << 8 & 0xFF00);addr |= ((bytes[2] << 16) & 0xFF0000);addr |= ((bytes[3] << 24) & 0xFF000000);return addr;
}float stamptimecount = 0;
void UDPtoXYZfun(Usefulmessage data);
void UDPtoXYZfunALL(Usefulmessage data);
errno_t err;int _tmain(int argc, _TCHAR* argv[])
{pcap_t *fp;char errbuf[PCAP_ERRBUF_SIZE];Usefulmessage UsefulData;Timeoffsetfun();framecount = 0;fp = pcap_open_offline("1.pcap",errbuf);pcap_loop(fp, 0, dispatcher_handler, NULL);pcap_close(fp);return 0;
}void dispatcher_handler(u_char *temp1,const struct pcap_pkthdr *header,const u_char *pkt_data)
{u_int it = 0;(VOID*)temp1;//保存数据char fn[20];PointXYZ point;FILE *fp;long int ustime = header->ts.tv_usec;printf("%ld:%ld (%ld)\n", header->ts.tv_sec, header->ts.tv_usec, header->len);if (header->len==1248){byte timestampl[4];byte factoryl[2];byte lo[1248];memcpy(&lo, pkt_data, 1248);memcpy(×tampl, pkt_data + 42 + 12 * 100, 4);memcpy(&factoryl, pkt_data + 42 + 12 * 100 + 4, 2);//float fValuet = *((float*)×tampl); //系统时间int fValue1 = *((float*)&factoryl[0]);long int fValue = bytes4ToInt(timestampl);if (stamptimecount == 0){stamptimecount = fValue;}if ((fValue - stamptimecount) >= 100000){stamptimecount = fValue;frameint++;}/保存数据sprintf_s(fn, "%05d.txt", frameint);//err  = fopen_s( &stream, "crt_fopen_s.c", "r" )) !=0if ((fp = fopen(fn, "a")) == NULL){printf("Create File failure 1");fclose(fp);//exit(1);}//read databyte datal[12][100];int packet_size = 100;int azimuth;float distance;int passway;for (int i = 0; i < 12; i++){memcpy(&datal[i], pkt_data + 42 + i * 100, packet_size);BYTE b[2];BYTE b1[1];memcpy(&b, pkt_data + 42 + i * 100 + 2, 2);azimuth = bytes2ToInt(b);UsefulData.JIAODU_[i] = azimuth;UsefulData.JIAODU2_[i] = azimuth*0.01;UsefulData.Timesec = header->ts.tv_sec;//printf("%f\n", UsefulData.JIAODU2_[i]);UsefulData.TimeStamp = fValue;for (int j = 0; j < 32; j++){memcpy(&b, pkt_data + 42 + i * 100 + 4 + j * 3, 2);memcpy(&b1, pkt_data + 42 + i * 100 + 4 + j * 3 + 2, 1);distance = float(bytes2ToInt(b))*0.002f;passway = bytes1ToInt(b1);if (distance<0.05){UsefulData.JULI_[i][j] = 0;UsefulData.PointPos[i][j] = i * 32 + j;//printf("%d  ", UsefulData.PointPos[i][j]);}else{UsefulData.JULI_[i][j] = distance;UsefulData.PointPos[i][j] = i * 32 + j;}UsefulData.PASSEGEWAY_[i][j] = passway;UsefulData.TimeOffset[i][j] = Timeoffsetvec[i * 32 + j] + header->ts.tv_usec;  //时间戳UsefulData.SIN_[i][j] = lasersinvec[i * 32 + j];UsefulData.COS_[i][j] = lasercosvec[i * 32 + j];//	printf("%f ", UsefulData.PASSEGEWAY_[i][j]);}}//经度赋值for (int i1 = 0; i1 < 12; i1++){for (int k = 0; k < 32; k++){if (k < 16){UsefulData.Azimuth[i1][k] = UsefulData.JIAODU2_[i1];// +LASER_vert_correction[k];}else if (k >= 16){if (i1 < 11)//前11帧{if (UsefulData.JIAODU2_[i1 + 1] < UsefulData.JIAODU2_[i1]){UsefulData.JIAODU2_[i1 + 1] += 360.0;float azimuth2 = UsefulData.JIAODU2_[i1] + (UsefulData.JIAODU2_[i1 + 1] - UsefulData.JIAODU2_[i1]) / 2.0;if (azimuth2 > 360)// 角度变化了{azimuth2 -= 360;UsefulData.Azimuth[i1][k] = azimuth2;// +LASER_vert_correction[k - 16];}else{UsefulData.Azimuth[i1][k] = azimuth2;// +LASER_vert_correction[k - 16];}}else{float azimuth4 = UsefulData.JIAODU2_[i1] + (UsefulData.JIAODU2_[i1 + 1] - UsefulData.JIAODU2_[i1]) / 2.0;UsefulData.Azimuth[i1][k] = azimuth4;// +LASER_vert_correction[k - 16}}else if (i1 == 11)//最后一帧{float azimuth3 = UsefulData.JIAODU2_[i1] + 0.2;if (azimuth3 > 360){azimuth3 -= 360;}else{}UsefulData.Azimuth[i1][k] = azimuth3;//;+LASER_vert_correction[k - 16];}}point.x = UsefulData.JULI_[i1][k] * UsefulData.COS_[i1][k] * sin(UsefulData.Azimuth[i1][k] / 180.0*3.1415926);point.y = UsefulData.JULI_[i1][k] * UsefulData.COS_[i1][k] * cos(UsefulData.Azimuth[i1][k] / 180.0*3.1415926);point.z = UsefulData.JULI_[i1][k] * UsefulData.SIN_[i1][k];point.r = UsefulData.PASSEGEWAY_[i1][k];point.tus = UsefulData.TimeOffset[i1][k];point.tsec = UsefulData.Timesec;if ((point.x == 0) && (point.y == 0) && (point.z == 0) || (UsefulData.JULI_[i1][k] <= 0.05)){}else{//X  Y  Z  Azimuth Distance Laser_ID fprintf(fp, "%f %f %f %f %f %d ", point.x, point.y, point.z, UsefulData.Azimuth[i1][k], UsefulData.JULI_[i1][k], UsefulData.PointPos[i1][k] % 16);fprintf(fp, "%f %f %ld %ld\n ", UsefulData.PASSEGEWAY_[i1][k], point.tus,  header->ts.tv_sec,ustime);}}}fclose(fp);}printf("\n\n");
}void UDPtoXYZfunALL(Usefulmessage data)
{PointXYZ point[384];FILE *fp;if ((fp = fopen("all.txt", "a")) == NULL){printf("Create File failure");//getch();exit(1);}for (int i = 0; i < 12; i++){for (int j = 0; j < 32; j++){point[i * 32 + j].x = data.JULI_[i][j] * data.COS_[i][j] * sin(data.Azimuth[i][j] / 180.0*3.1415926);point[i * 32 + j].y = data.JULI_[i][j] * data.COS_[i][j] * cos(data.Azimuth[i][j] / 180.0*3.1415926);point[i * 32 + j].z = data.JULI_[i][j] * data.SIN_[i][j];point[i * 32 + j].r = data.PASSEGEWAY_[i][j];point[i * 32 + j].tus = data.TimeOffset[i][j];point[i * 32 + j].tsec = data.Timesec;if ((point[i * 32 + j].x == 0) && (point[i * 32 + j].y == 0) && (point[i * 32 + j].z == 0) || (data.JULI_[i][j] <= 0.05)){}else{//X  Y  Z  Azimuth Distance Laser_ID fprintf(fp, "%f %f %f %f %f %d ", point[i * 32 + j].x, point[i * 32 + j].y, point[i * 32 + j].z, data.Azimuth[i][j], data.JULI_[i][j], data.PointPos[i][j] % 16);fprintf(fp, "%f %f %f %f \n ", data.PASSEGEWAY_[i][j], point[i * 32 + j].tus, data.TimeStamp, data.Timesec);//fprintf(fp, "%f %f %f \n", point[i * 32 + j].x, point[i * 32 + j].y, point[i * 32 + j].z);}}}fclose(fp);
}void UDPtoXYZfun(Usefulmessage data)
{PointXYZ point[384];FILE *fp;if ((fp = fopen("my.txt", "a")) == NULL){printf("Create File failure");//getch();exit(1);}	for (int i = 0; i < 12; i++){for (int j = 0; j < 32; j++){point[i * 32 + j].x = data.JULI_[i][j]*data.COS_[i][j]*sin(data.Azimuth[i][j]/180.0*3.1415926);point[i * 32 + j].y = data.JULI_[i][j]*data.COS_[i][j]*cos(data.Azimuth[i][j]/180.0*3.1415926);point[i * 32 + j].z = data.JULI_[i][j] * data.SIN_[i][j];point[i * 32 + j].r = data.PASSEGEWAY_[i][j];point[i * 32 + j].tus = data.TimeOffset[i][j];point[i * 32 + j].tsec = data.Timesec;if ((point[i * 32 + j].x == 0) && (point[i * 32 + j].y == 0) && (point[i * 32 + j].z == 0)||(data.JULI_[i][j]<=0.05)){}else{//fprintf(fp, "%f %f %f %f %f %d\n", point[i * 32 + j].x, point[i * 32 + j].y, point[i * 32 + j].z,data.Azimuth[i][j],data.JULI_[i][j],data.PointPos[i][j]%16);fprintf(fp, "%f %f %f \n", point[i * 32 + j].x, point[i * 32 + j].y, point[i * 32 + j].z);}}}fclose(fp);
}


这篇关于LiDAR-Velodyne激光雷达pcap文件解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/709895

相关文章

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

Golang HashMap实现原理解析

《GolangHashMap实现原理解析》HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持高效的插入、查找和删除操作,:本文主要介绍GolangH... 目录HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

Python利用ElementTree实现快速解析XML文件

《Python利用ElementTree实现快速解析XML文件》ElementTree是Python标准库的一部分,而且是Python标准库中用于解析和操作XML数据的模块,下面小编就来和大家详细讲讲... 目录一、XML文件解析到底有多重要二、ElementTree快速入门1. 加载XML的两种方式2.

Java的栈与队列实现代码解析

《Java的栈与队列实现代码解析》栈是常见的线性数据结构,栈的特点是以先进后出的形式,后进先出,先进后出,分为栈底和栈顶,栈应用于内存的分配,表达式求值,存储临时的数据和方法的调用等,本文给大家介绍J... 目录栈的概念(Stack)栈的实现代码队列(Queue)模拟实现队列(双链表实现)循环队列(循环数组

java解析jwt中的payload的用法

《java解析jwt中的payload的用法》:本文主要介绍java解析jwt中的payload的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java解析jwt中的payload1. 使用 jjwt 库步骤 1:添加依赖步骤 2:解析 JWT2. 使用 N

Python中__init__方法使用的深度解析

《Python中__init__方法使用的深度解析》在Python的面向对象编程(OOP)体系中,__init__方法如同建造房屋时的奠基仪式——它定义了对象诞生时的初始状态,下面我们就来深入了解下_... 目录一、__init__的基因图谱二、初始化过程的魔法时刻继承链中的初始化顺序self参数的奥秘默认

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Java字符串处理全解析(String、StringBuilder与StringBuffer)

《Java字符串处理全解析(String、StringBuilder与StringBuffer)》:本文主要介绍Java字符串处理全解析(String、StringBuilder与StringBu... 目录Java字符串处理全解析:String、StringBuilder与StringBuffer一、St