Duan 1 жил өмнө
parent
commit
e44e815feb
7 өөрчлөгдсөн 519 нэмэгдсэн , 524 устгасан
  1. 66 66
      .gitignore
  2. 0 5
      .vscode/settings.json
  3. 19 19
      Makefile
  4. 70 70
      README.md
  5. 217 217
      rb_lidar.c
  6. 86 86
      rb_lidar.h
  7. 61 61
      rblidar.py

+ 66 - 66
.gitignore

@@ -1,66 +1,66 @@
-# Prerequisites
-*.d
-
-# Object files
-*.o
-*.ko
-*.obj
-*.elf
-
-# Linker output
-*.ilk
-*.map
-*.exp
-
-# Precompiled Headers
-*.gch
-*.pch
-
-# Libraries
-*.lib
-*.a
-*.la
-*.lo
-
-# Shared objects (inc. Windows DLLs)
-*.dll
-*.so
-*.so.*
-*.dylib
-
-# Executables
-*.exe
-*.out
-*.app
-*.i*86
-*.x86_64
-*.hex
-
-# Debug files
-*.dSYM/
-*.su
-*.idb
-*.pdb
-
-.vscode/
-*.code-workspace
-
-.history/
-
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
-
-launch.json
-tasks.json
-
-.idea/
-*.iws
-*.iml
-*.ipr
-
-node_modules/
-dist/
-build/
+# Prerequisites
+*.d
+
+# Object files
+*.o
+*.ko
+*.obj
+*.elf
+
+# Linker output
+*.ilk
+*.map
+*.exp
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Libraries
+*.lib
+*.a
+*.la
+*.lo
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+*.su
+*.idb
+*.pdb
+
+.vscode/
+*.code-workspace
+
+.history/
+
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+launch.json
+tasks.json
+
+.idea/
+*.iws
+*.iml
+*.ipr
+
+node_modules/
+dist/
+build/

+ 0 - 5
.vscode/settings.json

@@ -1,5 +0,0 @@
-{
-    "files.associations": {
-        "rb_lidar.h": "c"
-    }
-}

+ 19 - 19
Makefile

@@ -1,19 +1,19 @@
-CC = gcc
-CFLAGS = -Wall -Wextra -fPIC -I.
-
-TARGET = rb_lidar.so
-SOURCES = rb_lidar.c
-OBJECTS = $(SOURCES:.c=.o)
-
-all: $(TARGET)
-
-$(TARGET): $(OBJECTS)
-	$(CC) -shared -o $@ $^ -lpthread
-
-%.o: %.c rb_lidar.h
-	$(CC) $(CFLAGS) -c $< -o $@
-
-clean:
-	rm -f $(OBJECTS) $(TARGET)
-
-.PHONY: all clean
+CC = gcc
+CFLAGS = -Wall -Wextra -fPIC -I.
+
+TARGET = rb_lidar.so
+SOURCES = rb_lidar.c
+OBJECTS = $(SOURCES:.c=.o)
+
+all: $(TARGET)
+
+$(TARGET): $(OBJECTS)
+	$(CC) -shared -o $@ $^ -lpthread
+
+%.o: %.c rb_lidar.h
+	$(CC) $(CFLAGS) -c $< -o $@
+
+clean:
+	rm -f $(OBJECTS) $(TARGET)
+
+.PHONY: all clean

+ 70 - 70
README.md

@@ -1,70 +1,70 @@
-# LakiBeam SDK - Linux C/Python Hybrid programming radar data interface
-
-## Project profile
-
-LakiBeam SDK is a Linux-based cross-language (C/Python) radar data receiving and processing library designed for real-time radar data acquisition and processing.
-
-## Characteristics
-
-- Low-level implementation of C language in pure Linux environment
-
-- Python dynamic library call mechanism
-
-- UDP receives network data in real time
-
-- Multi-threaded data processing
-
-- Dual buffer design to improve data throughput
-
-## Environmental dependence
-
-- Linux
-- GCC compiler
-- Python 3.x
-
-## Dependency library
-
-- ctypes
-- numpy
-- matplotlib
-
-### Installing
-
-You can install ctypes、numpy and matplotlib using `pip`:
-
-```sh
-$ pip install ctypes numpy matplotlib
-```
-
-Or for Python 3:
-```sh
-$ sudo pip3 install ctypes numpy matplotlib
-```
-
-## Compile and build
-
-### Makefile
-
-The project provides makefiles to simplify the compilation and build process:
-
-# Common command
-make                # 编译C库
-make clean          # 清理编译产生的文件
-python3 rblidar.py  # 编译Python接口测试  
-
-## Troubleshooting
-· Ensure all dependencies are installed
-· Check library path and permissions
-· Verify network configuration for UDP communication
-
-## Usage example
-
-from rblidar import RBLidar
-
-def data_callback(data, length):
-    print(f"Received data, length: {length}")
-
-lidar = RBLidar("192.168.8.1", 2368, frame_callback=data_callback)
-
-
-
+# LakiBeam SDK - Linux C/Python Hybrid programming radar data interface
+
+## Project profile
+
+LakiBeam SDK is a Linux-based cross-language (C/Python) radar data receiving and processing library designed for real-time radar data acquisition and processing.
+
+## Characteristics
+
+- Low-level implementation of C language in pure Linux environment
+
+- Python dynamic library call mechanism
+
+- UDP receives network data in real time
+
+- Multi-threaded data processing
+
+- Dual buffer design to improve data throughput
+
+## Environmental dependence
+
+- Linux
+- GCC compiler
+- Python 3.x
+
+## Dependency library
+
+- ctypes
+- numpy
+- matplotlib
+
+### Installing
+
+You can install ctypes、numpy and matplotlib using `pip`:
+
+```sh
+$ pip install ctypes numpy matplotlib
+```
+
+Or for Python 3:
+```sh
+$ sudo pip3 install ctypes numpy matplotlib
+```
+
+## Compile and build
+
+### Makefile
+
+The project provides makefiles to simplify the compilation and build process:
+
+# Common command
+make                # 编译C库
+make clean          # 清理编译产生的文件
+python3 rblidar.py  # 编译Python接口测试  
+
+## Troubleshooting
+· Ensure all dependencies are installed
+· Check library path and permissions
+· Verify network configuration for UDP communication
+
+## Usage example
+
+from rblidar import RBLidar
+
+def data_callback(data, length):
+    print(f"Received data, length: {length}")
+
+lidar = RBLidar("192.168.8.1", 2368, frame_callback=data_callback)
+
+
+

+ 217 - 217
rb_lidar.c

@@ -1,217 +1,217 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <pthread.h>
-
-#include "rb_lidar.h"
-
-#define BUFFER_SIZE 1024
-
-// UDP接收线程
-void *udp_listener(void *arg)
-{
-	RBLidar *lidar = (RBLidar *)arg;
-	int sockfd;
-	struct sockaddr_in server_addr, client_addr;
-	socklen_t addr_len = sizeof(client_addr);
-	udp_packet_t udp_packet_temp;
-	uint32_t timestamp_last = 0;
-	uint32_t timestamp_div = 1;
-
-	// 创建UDP套接字
-	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
-	if (sockfd < 0)
-	{
-		perror("socket");
-		return NULL;
-	}
-
-	// 设置服务器地址
-	memset(&server_addr, 0, sizeof(server_addr));
-	server_addr.sin_family = AF_INET;
-	inet_pton(AF_INET, lidar->ip, &server_addr.sin_addr);
-	server_addr.sin_port = htons(lidar->port);
-
-	// 绑定套接字
-	if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
-	{
-		perror("bind");
-		close(sockfd);
-		return NULL;
-	}
-
-	printf("Listening for UDP packets on %s:%d...\n", lidar->ip, lidar->port);
-
-	// 接收数据
-	while (1)
-	{
-		int len = recvfrom(sockfd, (char *)&udp_packet_temp, UDP_BUF_SIZE, 0, (struct sockaddr *)&client_addr, &addr_len);
-		if (len < 0)
-		{
-			perror("recvfrom");
-			continue;
-		}
-
-		// 使用双缓冲机制
-		pthread_mutex_lock(&lidar->mutex);
-
-		uint32_t timestamp_current = udp_packet_temp.timestamp;
-
-		if(timestamp_current == 0)
-		{
-			timestamp_current = timestamp_last;
-		}
-		else
-		{
-			timestamp_div = (timestamp_current - timestamp_last) / CONFIG_UDP_BLOCKS;
-			timestamp_last = timestamp_current;
-		}
-
-		// 将接收到的UDP包中的子包存入当前缓冲区
-		for (int i = 0; i < CONFIG_UDP_BLOCKS; i++)
-		{
-			sub_packet_t *sub_packet = &udp_packet_temp.sub_packet[i];
-
-			// 检查azimuth是否为0
-			if (sub_packet->azimuth != 0xffff)
-			{
-			// 将子包存入当前缓冲区
-			memcpy(&lidar->buffer[lidar->current][lidar->valid_count[lidar->current]], sub_packet, sizeof(sub_packet_t));
-            lidar->timestamps[lidar->current][lidar->valid_count[lidar->current]] = timestamp_current + i * timestamp_div;
-            // lidar->timestamps[lidar->current][lidar->valid_count[lidar->current]] = timestamp_current;
-
-			// 统计有效数据
-			lidar->valid_count[lidar->current]++;
-			}
-
-			// 检查azimuth是否为0
-			if (sub_packet->azimuth == 0)
-			{
-				// 切换到下一个缓冲区并通知处理线程
-				lidar->current = (lidar->current + 1) % 2; // 切换缓冲区
-
-				lidar->valid_count[lidar->current] = 0;
-				memcpy(&lidar->buffer[lidar->current][lidar->valid_count[lidar->current]], sub_packet, sizeof(sub_packet_t));
-                lidar->timestamps[lidar->current][lidar->valid_count[lidar->current]] = timestamp_current + i * timestamp_div; // 增加i
-				lidar->valid_count[lidar->current]++;
-
-				pthread_cond_signal(&lidar->cond); // 通知处理线程
-			}
-		}
-
-		pthread_mutex_unlock(&lidar->mutex);
-	}
-
-	close(sockfd);
-	return NULL;
-}
-
-// 组包线程
-void *packet_processor(void *arg)
-{
-	RBLidar *lidar = (RBLidar *)arg;
-
-	// 处理数据
-	while (1)
-	{
-		pthread_mutex_lock(&lidar->mutex);
-		pthread_cond_wait(&lidar->cond, &lidar->mutex); // 等待数据
-
-		// 处理当前缓冲区数据
-		int next_index = (lidar->current + 1) % 2;	// 获取上一缓冲区索引
-		int count = lidar->valid_count[next_index]; // 获取有效数据的数量
-
-        // 创建临时缓冲区以存储点数据
-        point_data_t temp_buffer[BUFFER_SIZE * CONFIG_BLOCK_COUNT]; // 假设 BUFFER_SIZE 足够大
-		int temp_count = 0;
-
-		// 处理当前缓冲区中的每个有效子包
-		for (int i = 0; i < count - 1; i++)
-		{
-			sub_packet_t *sub_packet = &lidar->buffer[next_index][i];
-
-            int start_angle = sub_packet->azimuth % 36000;
-            int end_angle = lidar->buffer[next_index][i + 1].azimuth % 36000; // 获取下一个子包的 azimuth
-
-            // 计算角度增量
-            int div_angle;
-            if (end_angle >= start_angle)
-            {
-                div_angle = (end_angle - start_angle) / CONFIG_BLOCK_COUNT;
-            }
-            else
-            {
-                div_angle = (36000 - start_angle + end_angle) / CONFIG_BLOCK_COUNT;
-            }
-			
-			 // 计算时间间隔
-            uint32_t start_time = lidar->timestamps[next_index][i]; // 从时间戳数组中获取当前子包的时间戳
-            uint32_t end_time = lidar->timestamps[next_index][i + 1]; // 获取下一个子包的时间戳
-            uint32_t div_time = (end_time - start_time) / CONFIG_BLOCK_COUNT; // 计算时间间隔make
-			//printf("Start Time: %u, End Time: %u, Div Time: %u\n", start_time, end_time, div_time);
-            // 填充点数据
-				for (int j = 0; j < CONFIG_BLOCK_COUNT; j++) {
-					point_data_t point_data;
-					point_data.azimuth = (start_angle + j * div_angle) % 36000;
-					point_data.dist = sub_packet->point[j].dist_0;
-					point_data.rssi = sub_packet->point[j].rssi_0;
-					
-					point_data.timestamp = start_time + j * div_time;
-					// point_data.timestamp = start_time;
-					// 将填充的点数据添加到临时缓冲区
-					temp_buffer[temp_count++] = point_data;
-				}
-				
-		}
-
-		// 调用回调函数
-		lidar->callback((void*)temp_buffer, sizeof(point_data_t) * temp_count);
-
-		// // 重置当前缓冲区
-		// memset(lidar->buffer[next_index], 0, sizeof(sub_packet_t) * BUFFER_SIZE);
-		// lidar->valid_count[next_index] = 0; // 重置有效数据计数
-
-		pthread_mutex_unlock(&lidar->mutex);
-	}
-	return NULL;
-}
-
-// 创建RBLidar实例
-RBLidar *rblidar_create(const char *ip, int port, callback_t callback)
-{
-	RBLidar *lidar = (RBLidar *)malloc(sizeof(RBLidar));
-	lidar->ip = strdup(ip);
-	lidar->port = port;
-	lidar->callback = callback;
-
-	lidar->current = 0;
-	pthread_mutex_init(&lidar->mutex, NULL);
-	pthread_cond_init(&lidar->cond, NULL);
-
-	// 创建接收线程
-	pthread_t listener_thread;
-	pthread_create(&listener_thread, NULL, udp_listener, lidar);
-	pthread_detach(listener_thread); // 让线程在结束时自动回收资源
-
-	// 创建组包线程
-	pthread_t processor_thread;
-	pthread_create(&processor_thread, NULL, packet_processor, lidar);
-	pthread_detach(processor_thread);
-
-	return lidar;
-}
-
-// 释放RBLidar实例
-void rblidar_destroy(RBLidar *lidar)
-{
-	for (int i = 0; i < 2; i++)
-	{
-		free(lidar->buffer[i]);
-	}
-	pthread_mutex_destroy(&lidar->mutex);
-	pthread_cond_destroy(&lidar->cond);
-	free(lidar->ip);
-	free(lidar);
-}
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include "rb_lidar.h"
+
+#define BUFFER_SIZE 1024
+
+// UDP接收线程
+void *udp_listener(void *arg)
+{
+	RBLidar *lidar = (RBLidar *)arg;
+	int sockfd;
+	struct sockaddr_in server_addr, client_addr;
+	socklen_t addr_len = sizeof(client_addr);
+	udp_packet_t udp_packet_temp;
+	uint32_t timestamp_last = 0;
+	uint32_t timestamp_div = 1;
+
+	// 创建UDP套接字
+	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sockfd < 0)
+	{
+		perror("socket");
+		return NULL;
+	}
+
+	// 设置服务器地址
+	memset(&server_addr, 0, sizeof(server_addr));
+	server_addr.sin_family = AF_INET;
+	inet_pton(AF_INET, lidar->ip, &server_addr.sin_addr);
+	server_addr.sin_port = htons(lidar->port);
+
+	// 绑定套接字
+	if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
+	{
+		perror("bind");
+		close(sockfd);
+		return NULL;
+	}
+
+	printf("Listening for UDP packets on %s:%d...\n", lidar->ip, lidar->port);
+
+	// 接收数据
+	while (1)
+	{
+		int len = recvfrom(sockfd, (char *)&udp_packet_temp, UDP_BUF_SIZE, 0, (struct sockaddr *)&client_addr, &addr_len);
+		if (len < 0)
+		{
+			perror("recvfrom");
+			continue;
+		}
+
+		// 使用双缓冲机制
+		pthread_mutex_lock(&lidar->mutex);
+
+		uint32_t timestamp_current = udp_packet_temp.timestamp;
+
+		if(timestamp_current == 0)
+		{
+			timestamp_current = timestamp_last;
+		}
+		else
+		{
+			timestamp_div = (timestamp_current - timestamp_last) / CONFIG_UDP_BLOCKS;
+			timestamp_last = timestamp_current;
+		}
+
+		// 将接收到的UDP包中的子包存入当前缓冲区
+		for (int i = 0; i < CONFIG_UDP_BLOCKS; i++)
+		{
+			sub_packet_t *sub_packet = &udp_packet_temp.sub_packet[i];
+
+			// 检查azimuth是否为0
+			if (sub_packet->azimuth != 0xffff)
+			{
+			// 将子包存入当前缓冲区
+			memcpy(&lidar->buffer[lidar->current][lidar->valid_count[lidar->current]], sub_packet, sizeof(sub_packet_t));
+            lidar->timestamps[lidar->current][lidar->valid_count[lidar->current]] = timestamp_current + i * timestamp_div;
+            // lidar->timestamps[lidar->current][lidar->valid_count[lidar->current]] = timestamp_current;
+
+			// 统计有效数据
+			lidar->valid_count[lidar->current]++;
+			}
+
+			// 检查azimuth是否为0
+			if (sub_packet->azimuth == 0)
+			{
+				// 切换到下一个缓冲区并通知处理线程
+				lidar->current = (lidar->current + 1) % 2; // 切换缓冲区
+
+				lidar->valid_count[lidar->current] = 0;
+				memcpy(&lidar->buffer[lidar->current][lidar->valid_count[lidar->current]], sub_packet, sizeof(sub_packet_t));
+                lidar->timestamps[lidar->current][lidar->valid_count[lidar->current]] = timestamp_current + i * timestamp_div; // 增加i
+				lidar->valid_count[lidar->current]++;
+
+				pthread_cond_signal(&lidar->cond); // 通知处理线程
+			}
+		}
+
+		pthread_mutex_unlock(&lidar->mutex);
+	}
+
+	close(sockfd);
+	return NULL;
+}
+
+// 组包线程
+void *packet_processor(void *arg)
+{
+	RBLidar *lidar = (RBLidar *)arg;
+
+	// 处理数据
+	while (1)
+	{
+		pthread_mutex_lock(&lidar->mutex);
+		pthread_cond_wait(&lidar->cond, &lidar->mutex); // 等待数据
+
+		// 处理当前缓冲区数据
+		int next_index = (lidar->current + 1) % 2;	// 获取上一缓冲区索引
+		int count = lidar->valid_count[next_index]; // 获取有效数据的数量
+
+        // 创建临时缓冲区以存储点数据
+        point_data_t temp_buffer[BUFFER_SIZE * CONFIG_BLOCK_COUNT]; // 假设 BUFFER_SIZE 足够大
+		int temp_count = 0;
+
+		// 处理当前缓冲区中的每个有效子包
+		for (int i = 0; i < count - 1; i++)
+		{
+			sub_packet_t *sub_packet = &lidar->buffer[next_index][i];
+
+            int start_angle = sub_packet->azimuth % 36000;
+            int end_angle = lidar->buffer[next_index][i + 1].azimuth % 36000; // 获取下一个子包的 azimuth
+
+            // 计算角度增量
+            int div_angle;
+            if (end_angle >= start_angle)
+            {
+                div_angle = (end_angle - start_angle) / CONFIG_BLOCK_COUNT;
+            }
+            else
+            {
+                div_angle = (36000 - start_angle + end_angle) / CONFIG_BLOCK_COUNT;
+            }
+			
+			 // 计算时间间隔
+            uint32_t start_time = lidar->timestamps[next_index][i]; // 从时间戳数组中获取当前子包的时间戳
+            uint32_t end_time = lidar->timestamps[next_index][i + 1]; // 获取下一个子包的时间戳
+            uint32_t div_time = (end_time - start_time) / CONFIG_BLOCK_COUNT; // 计算时间间隔make
+			//printf("Start Time: %u, End Time: %u, Div Time: %u\n", start_time, end_time, div_time);
+            // 填充点数据
+				for (int j = 0; j < CONFIG_BLOCK_COUNT; j++) {
+					point_data_t point_data;
+					point_data.azimuth = (start_angle + j * div_angle) % 36000;
+					point_data.dist = sub_packet->point[j].dist_0;
+					point_data.rssi = sub_packet->point[j].rssi_0;
+					
+					point_data.timestamp = start_time + j * div_time;
+					// point_data.timestamp = start_time;
+					// 将填充的点数据添加到临时缓冲区
+					temp_buffer[temp_count++] = point_data;
+				}
+				
+		}
+
+		// 调用回调函数
+		lidar->callback((void*)temp_buffer, sizeof(point_data_t) * temp_count);
+
+		// // 重置当前缓冲区
+		// memset(lidar->buffer[next_index], 0, sizeof(sub_packet_t) * BUFFER_SIZE);
+		// lidar->valid_count[next_index] = 0; // 重置有效数据计数
+
+		pthread_mutex_unlock(&lidar->mutex);
+	}
+	return NULL;
+}
+
+// 创建RBLidar实例
+RBLidar *rblidar_create(const char *ip, int port, callback_t callback)
+{
+	RBLidar *lidar = (RBLidar *)malloc(sizeof(RBLidar));
+	lidar->ip = strdup(ip);
+	lidar->port = port;
+	lidar->callback = callback;
+
+	lidar->current = 0;
+	pthread_mutex_init(&lidar->mutex, NULL);
+	pthread_cond_init(&lidar->cond, NULL);
+
+	// 创建接收线程
+	pthread_t listener_thread;
+	pthread_create(&listener_thread, NULL, udp_listener, lidar);
+	pthread_detach(listener_thread); // 让线程在结束时自动回收资源
+
+	// 创建组包线程
+	pthread_t processor_thread;
+	pthread_create(&processor_thread, NULL, packet_processor, lidar);
+	pthread_detach(processor_thread);
+
+	return lidar;
+}
+
+// 释放RBLidar实例
+void rblidar_destroy(RBLidar *lidar)
+{
+	for (int i = 0; i < 2; i++)
+	{
+		free(lidar->buffer[i]);
+	}
+	pthread_mutex_destroy(&lidar->mutex);
+	pthread_cond_destroy(&lidar->cond);
+	free(lidar->ip);
+	free(lidar);
+}

+ 86 - 86
rb_lidar.h

@@ -1,86 +1,86 @@
-#ifndef RB_LIDAR_H
-#define RB_LIDAR_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>  // 包含标准整数类型
-#include <pthread.h> // 用于线程支持
-
-typedef void (*callback_t)(const char* data, int length);
-
-// 配置常量
-#define CONFIG_BLOCK_COUNT    (16)   
-#define CONFIG_UDP_BLOCKS     (12)   
-#define FRAME_POINT_COUNT     (3600) 
-#define CONFIG_DEGREE_MAX  (36000)
-#define SUBPKT_BUF_COUNT	(300)   
-
-#define UDP_BUF_SIZE		(1206)
-
-// 结构体对齐设置
-#pragma pack(push)
-#pragma pack(1)
-
-// 原始点数据结构
-typedef struct {
-    uint16_t dist_0; // 第一个距离
-    uint8_t rssi_0;  // 第一个RSSI值
-    uint16_t dist_1; // 第二个距离
-    uint8_t rssi_1;  // 第二个RSSI值
-} raw_point_t;
-
-// 子包结构
-typedef struct {
-    uint16_t header; // 子包头
-    uint16_t azimuth; // 方位角
-    raw_point_t point[CONFIG_BLOCK_COUNT]; // 点数据数组
-} sub_packet_t;
-
-// UDP包结构
-typedef struct {
-    sub_packet_t sub_packet[CONFIG_UDP_BLOCKS]; // 子包数组
-    uint32_t timestamp; // 时间戳
-    uint16_t factory_byte; // 工厂字节
-} udp_packet_t;
-
-// 点数据结构
-typedef struct {
-    uint16_t azimuth; // 方位角
-    uint16_t dist; // 距离
-    uint16_t rssi; // RSSI值
-    uint32_t timestamp; // 时间戳
-} point_data_t;
-
-// 帧数据结构
-typedef struct {
-    point_data_t pointcloud[FRAME_POINT_COUNT]; // 深度数据点云
-} frame_data_t;
-
-#pragma pack(pop)
-
-// RBLidar 结构体
-typedef struct {
-    char* ip;
-    int port;
-    callback_t callback;
-    sub_packet_t buffer[2][SUBPKT_BUF_COUNT]; // 双缓冲区
-    uint32_t timestamps[2][SUBPKT_BUF_COUNT];//存储时间戳的数组
-    int current;     // 当前缓冲区索引
-    int valid_count[2]; // 每个缓冲区中有效数据的数量
-    pthread_mutex_t mutex;
-    pthread_cond_t cond;
-} RBLidar;
-
-// 创建 RBLidar 实例
-RBLidar* rblidar_create(const char* ip, int port, callback_t callback);
-
-// 释放 RBLidar 实例
-void rblidar_destroy(RBLidar* lidar);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // RB_LIDAR_H
+#ifndef RB_LIDAR_H
+#define RB_LIDAR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>  // 包含标准整数类型
+#include <pthread.h> // 用于线程支持
+
+typedef void (*callback_t)(const char* data, int length);
+
+// 配置常量
+#define CONFIG_BLOCK_COUNT    (16)   
+#define CONFIG_UDP_BLOCKS     (12)   
+#define FRAME_POINT_COUNT     (3600) 
+#define CONFIG_DEGREE_MAX  (36000)
+#define SUBPKT_BUF_COUNT	(300)   
+
+#define UDP_BUF_SIZE		(1206)
+
+// 结构体对齐设置
+#pragma pack(push)
+#pragma pack(1)
+
+// 原始点数据结构
+typedef struct {
+    uint16_t dist_0; // 第一个距离
+    uint8_t rssi_0;  // 第一个RSSI值
+    uint16_t dist_1; // 第二个距离
+    uint8_t rssi_1;  // 第二个RSSI值
+} raw_point_t;
+
+// 子包结构
+typedef struct {
+    uint16_t header; // 子包头
+    uint16_t azimuth; // 方位角
+    raw_point_t point[CONFIG_BLOCK_COUNT]; // 点数据数组
+} sub_packet_t;
+
+// UDP包结构
+typedef struct {
+    sub_packet_t sub_packet[CONFIG_UDP_BLOCKS]; // 子包数组
+    uint32_t timestamp; // 时间戳
+    uint16_t factory_byte; // 工厂字节
+} udp_packet_t;
+
+// 点数据结构
+typedef struct {
+    uint16_t azimuth; // 方位角
+    uint16_t dist; // 距离
+    uint16_t rssi; // RSSI值
+    uint32_t timestamp; // 时间戳
+} point_data_t;
+
+// 帧数据结构
+typedef struct {
+    point_data_t pointcloud[FRAME_POINT_COUNT]; // 深度数据点云
+} frame_data_t;
+
+#pragma pack(pop)
+
+// RBLidar 结构体
+typedef struct {
+    char* ip;
+    int port;
+    callback_t callback;
+    sub_packet_t buffer[2][SUBPKT_BUF_COUNT]; // 双缓冲区
+    uint32_t timestamps[2][SUBPKT_BUF_COUNT];//存储时间戳的数组
+    int current;     // 当前缓冲区索引
+    int valid_count[2]; // 每个缓冲区中有效数据的数量
+    pthread_mutex_t mutex;
+    pthread_cond_t cond;
+} RBLidar;
+
+// 创建 RBLidar 实例
+RBLidar* rblidar_create(const char* ip, int port, callback_t callback);
+
+// 释放 RBLidar 实例
+void rblidar_destroy(RBLidar* lidar);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // RB_LIDAR_H

+ 61 - 61
rblidar.py

@@ -1,61 +1,61 @@
-import ctypes
-import logging
-import numpy as np
-import matplotlib.pyplot as plt
-
-class point_data_t(ctypes.Structure):
-    _pack_ = 1  # Set alignment to 1 byte
-    _fields_ = [
-        ("azimuth", ctypes.c_uint16),
-        ("dist", ctypes.c_uint16),
-        ("rssi", ctypes.c_uint16),
-        ("timestamp", ctypes.c_uint32)
-    ]
-
-# Create a corresponding numpy dtype for the structure
-point_dtype = np.dtype([
-    ('azimuth', np.uint16),
-    ('dist', np.uint16),
-    ('rssi', np.uint16),
-    ('timestamp', np.uint32)
-])
-
-rblidar_lib = ctypes.CDLL('./rb_lidar.so')  
-
-CALLBACK_TYPE = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_int)
-
-class RBLidar:
-    def __init__(self, ip: str, port: int, frame_callback=None):
-        logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s: %(message)s')
-
-        self.frame_callback = frame_callback
-        self.callback = CALLBACK_TYPE(self._callback_wrapper)
-
-        # Create the lidar instance
-        self.lidar = rblidar_lib.rblidar_create(ip.encode('utf-8'), port, self.callback)
-
-    def _callback_wrapper(self, data, length):
-        # Convert the received data into a byte buffer
-        byte_data = ctypes.string_at(data, length)
-
-        # Create a NumPy array from the byte data
-        point_data_array = np.frombuffer(byte_data, dtype=point_dtype)
-
-        # If a NumPy callback is provided, call it
-        if self.frame_callback is not None:
-            self.frame_callback(point_data_array)
-
-    def __del__(self):
-        rblidar_lib.rblidar_destroy(self.lidar)
-
-if __name__ == "__main__":
-    def my_frame_callback(point_data_array):
-        for point in point_data_array:
-            logging.info(f"Azimuth: {point['azimuth']}, Distance: {point['dist']}, RSSI: {point['rssi']}, Timestamp: {point['timestamp']}")
-
-    lidar = RBLidar("192.168.8.1", 2368, frame_callback=my_frame_callback) 
-    try:
-        while True:
-            pass 
-    except KeyboardInterrupt:
-        logging.info("Stopping...")
+import ctypes
+import logging
+import numpy as np
+import matplotlib.pyplot as plt
+
+class point_data_t(ctypes.Structure):
+    _pack_ = 1  # Set alignment to 1 byte
+    _fields_ = [
+        ("azimuth", ctypes.c_uint16),
+        ("dist", ctypes.c_uint16),
+        ("rssi", ctypes.c_uint16),
+        ("timestamp", ctypes.c_uint32)
+    ]
+
+# Create a corresponding numpy dtype for the structure
+point_dtype = np.dtype([
+    ('azimuth', np.uint16),
+    ('dist', np.uint16),
+    ('rssi', np.uint16),
+    ('timestamp', np.uint32)
+])
+
+rblidar_lib = ctypes.CDLL('./rb_lidar.so')  
+
+CALLBACK_TYPE = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_int)
+
+class RBLidar:
+    def __init__(self, ip: str, port: int, frame_callback=None):
+        logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s: %(message)s')
+
+        self.frame_callback = frame_callback
+        self.callback = CALLBACK_TYPE(self._callback_wrapper)
+
+        # Create the lidar instance
+        self.lidar = rblidar_lib.rblidar_create(ip.encode('utf-8'), port, self.callback)
+
+    def _callback_wrapper(self, data, length):
+        # Convert the received data into a byte buffer
+        byte_data = ctypes.string_at(data, length)
+
+        # Create a NumPy array from the byte data
+        point_data_array = np.frombuffer(byte_data, dtype=point_dtype)
+
+        # If a NumPy callback is provided, call it
+        if self.frame_callback is not None:
+            self.frame_callback(point_data_array)
+
+    def __del__(self):
+        rblidar_lib.rblidar_destroy(self.lidar)
+
+if __name__ == "__main__":
+    def my_frame_callback(point_data_array):
+        for point in point_data_array:
+            logging.info(f"Azimuth: {point['azimuth']}, Distance: {point['dist']}, RSSI: {point['rssi']}, Timestamp: {point['timestamp']}")
+
+    lidar = RBLidar("192.168.8.1", 2368, frame_callback=my_frame_callback) 
+    try:
+        while True:
+            pass 
+    except KeyboardInterrupt:
+        logging.info("Stopping...")