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

相关文章

python常见环境管理工具超全解析

《python常见环境管理工具超全解析》在Python开发中,管理多个项目及其依赖项通常是一个挑战,下面:本文主要介绍python常见环境管理工具的相关资料,文中通过代码介绍的非常详细,需要的朋友... 目录1. conda2. pip3. uvuv 工具自动创建和管理环境的特点4. setup.py5.

全面解析HTML5中Checkbox标签

《全面解析HTML5中Checkbox标签》Checkbox是HTML5中非常重要的表单元素之一,通过合理使用其属性和样式自定义方法,可以为用户提供丰富多样的交互体验,这篇文章给大家介绍HTML5中C... 在html5中,Checkbox(复选框)是一种常用的表单元素,允许用户在一组选项中选择多个项目。本

Python包管理工具核心指令uvx举例详细解析

《Python包管理工具核心指令uvx举例详细解析》:本文主要介绍Python包管理工具核心指令uvx的相关资料,uvx是uv工具链中用于临时运行Python命令行工具的高效执行器,依托Rust实... 目录一、uvx 的定位与核心功能二、uvx 的典型应用场景三、uvx 与传统工具对比四、uvx 的技术实

SpringBoot排查和解决JSON解析错误(400 Bad Request)的方法

《SpringBoot排查和解决JSON解析错误(400BadRequest)的方法》在开发SpringBootRESTfulAPI时,客户端与服务端的数据交互通常使用JSON格式,然而,JSON... 目录问题背景1. 问题描述2. 错误分析解决方案1. 手动重新输入jsON2. 使用工具清理JSON3.

Redis过期删除机制与内存淘汰策略的解析指南

《Redis过期删除机制与内存淘汰策略的解析指南》在使用Redis构建缓存系统时,很多开发者只设置了EXPIRE但却忽略了背后Redis的过期删除机制与内存淘汰策略,下面小编就来和大家详细介绍一下... 目录1、简述2、Redis http://www.chinasem.cn的过期删除策略(Key Expir

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析

《Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析》InstantiationAwareBeanPostProcessor是Spring... 目录一、什么是InstantiationAwareBeanPostProcessor?二、核心方法解

深入解析 Java Future 类及代码示例

《深入解析JavaFuture类及代码示例》JavaFuture是java.util.concurrent包中用于表示异步计算结果的核心接口,下面给大家介绍JavaFuture类及实例代码,感兴... 目录一、Future 类概述二、核心工作机制代码示例执行流程2. 状态机模型3. 核心方法解析行为总结:三

springboot项目中使用JOSN解析库的方法

《springboot项目中使用JOSN解析库的方法》JSON,全程是JavaScriptObjectNotation,是一种轻量级的数据交换格式,本文给大家介绍springboot项目中使用JOSN... 目录一、jsON解析简介二、Spring Boot项目中使用JSON解析1、pom.XML文件引入依

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷