# Olei.LidarSensor - Project Summary ## Tổng Quan Project này cung cấp một thư viện C# hiệu suất cao để nhận và phân giải dữ liệu từ Olei LiDAR Sensor (LR-1F / LR-1BS) qua giao thức UDP/IP. **Target Framework**: .NET 10.0 ## Cấu Trúc Project ### Core Classes (Mã Nguồn Chính) #### 1. [LidarHeader.cs](LidarHeader.cs) - **Mục đích**: Định nghĩa cấu trúc header của gói tin (40 bytes) - **Kiểu**: `struct` với `StructLayout(LayoutKind.Sequential, Pack = 1)` - **Chức năng chính**: - Lưu trữ thông tin frame ID, protocol version, distance scale - Rotation rate và direction - Error status (motor, voltage, temperature) - Timestamp và NTP timestamp - Safe zone status - **Highlights**: Helper properties để dễ dàng truy cập thông tin (IsValidFrame, HasError, etc.) #### 2. [LidarDataBlock.cs](LidarDataBlock.cs) - **Mục đích**: Định nghĩa cấu trúc data block cho mỗi điểm đo (8 bytes) - **Kiểu**: `struct` với `StructLayout(LayoutKind.Sequential, Pack = 1)` - **Chức năng chính**: - Lưu trữ angle (0-35999 = 0°-359.99°) - Distance readout data - Signal strength (0-65535) - Validation (IsValid) - **Highlights**: Methods chuyển đổi sang degrees/radians và Cartesian coordinates (X, Y) #### 3. [LidarDataPacket.cs](LidarDataPacket.cs) - **Mục đích**: Chứa toàn bộ gói tin LiDAR (1240 bytes) - **Kiểu**: `class` (sealed) - **Chức năng chính**: - Chứa 1 header + 150 data blocks - Methods để iterate và filter valid data points - Conversion sang Cartesian coordinates - **Highlights**: IEnumerable-based methods cho easy iteration #### 4. [LidarPacketParser.cs](LidarPacketParser.cs) - **Mục đích**: Phân giải gói tin UDP thô thành LidarDataPacket - **Kiểu**: `static class` - **Chức năng chính**: - Zero-allocation parsing sử dụng `Span` và `ReadOnlySpan` - Fast struct deserialization với `MemoryMarshal.Read()` - Quick validation methods - **Highlights**: Tối ưu hiệu suất, không allocation memory khi parse #### 5. [OleiLidarServer.cs](OleiLidarServer.cs) ⭐ **MAIN CLASS** - **Mục đích**: Server UDP để nhận và xử lý dữ liệu LiDAR - **Kiểu**: `sealed class`, implements `IDisposable` - **Chức năng chính**: - Dedicated receive thread với high priority - Buffer pooling (ArrayPool) - Packet pooling (ConcurrentBag) - Event-based callbacks (DataReceived, ErrorOccurred) - Statistics tracking - **Highlights**: - High performance: > 1000 packets/sec - Low latency: < 1ms per packet - Thread-safe operations - Minimal GC pressure ### Documentation Files #### 6. [README.md](README.md) - Tài liệu gốc về giao thức truyền thông của LiDAR sensor - Định nghĩa format gói tin 1240 bytes - Cấu trúc header và data blocks - **Nguồn**: Tài liệu từ nhà sản xuất Olei #### 7. [USAGE_EXAMPLE.cs](USAGE_EXAMPLE.cs) - Examples về cách sử dụng thư viện - Bao gồm: - Basic usage - Advanced monitoring với statistics - Distance filtering - Angle sector filtering - **Hướng dẫn**: Copy/paste examples để bắt đầu nhanh #### 8. [IMPLEMENTATION_NOTES.md](IMPLEMENTATION_NOTES.md) - Chi tiết về implementation - Giải thích các tối ưu hiệu suất: - Buffer pooling - Packet pooling - Zero-allocation parsing - Thread optimization - Struct vs Class decisions - Performance characteristics - Best practices #### 9. [ARCHITECTURE.md](ARCHITECTURE.md) - Kiến trúc hệ thống với ASCII diagrams - Data flow diagrams - Class diagrams - Threading model - Memory management strategy - Error recovery strategy #### 10. [PROJECT_SUMMARY.md](PROJECT_SUMMARY.md) (file này) - Tổng quan toàn bộ project - Quick reference cho các file ## Quick Start ### 1. Thêm Reference ```bash dotnet add reference path/to/Olei.LidarSensor.csproj ``` ### 2. Sử dụng cơ bản ```csharp using Olei.LidarSensor; // Create server using var server = new OleiLidarServer(2368); // Subscribe to data server.DataReceived += (sender, e) => { var packet = e.Packet; foreach (var block in packet.GetValidDataBlocks()) { double angle = block.GetAngleDegrees(); double distance = block.GetDistance(packet.Header.DistanceScale); // Process data... } // Packet is automatically returned to pool after handler completes // No need to call ReturnPacketToPool manually! }; // Start receiving server.Start(); // ... your application logic ... // Stop (or dispose) server.Stop(); ``` ## Key Features ### ✅ High Performance - Dedicated thread với `ThreadPriority.AboveNormal` - Zero-allocation parsing với `Span` - Buffer và packet pooling - Target: > 1000 packets/sec, < 1ms latency ### ✅ Memory Efficient - ArrayPool cho buffers - ConcurrentBag cho packet reuse với **atomic counter tracking** - **Race-condition free** pool management - Minimal GC pressure - Constant memory usage sau warm-up - Accurate pool size monitoring ### ✅ Thread Safe - Thread-safe operations - Interlocked counters - ConcurrentBag pooling - Proper locking cho start/stop ### ✅ Easy to Use - Event-based API - Simple start/stop methods - Rich data access methods - Comprehensive examples ### ✅ Robust - Error handling at all levels - Hardware error detection - Statistics tracking - Proper resource disposal ## Performance Targets | Metric | Target | Notes | |--------|--------|-------| | Throughput | > 1000 packets/sec | Typical LiDAR rate: 10-20 Hz | | Latency | < 1ms | Per packet processing | | Memory | Flat after warm-up | Thanks to pooling | | GC | Minimal Gen0 | Near-zero allocations | | CPU | Low overhead | Efficient parsing | ## Packet Format Quick Reference ``` Total: 1240 bytes ├─ Header: 40 bytes │ ├─ Frame ID (4B): 0xFEF0010F │ ├─ Protocol (2B): 0x0200 │ ├─ Distance Scale (1B) │ ├─ Brand/Type/Version info │ ├─ Timestamp (4B) │ ├─ Rotation Rate (2B) │ ├─ Error Status (1B) │ └─ NTP Timestamp (4B) │ └─ Data Blocks: 1200 bytes (150 × 8) └─ Each block (8B): ├─ Angle (2B): 0-35999 = 0°-359.99° ├─ Distance (2B): raw × scale ├─ Strength (2B): 0-65535 └─ Reserved (2B) ``` ## Build & Test ### Build ```bash cd srcs/RobotNet10/RobotApp/Communication/Olei.LidarSensor dotnet build ``` ### Test với simulator Nếu không có hardware, có thể test với UDP packet simulator: ```csharp using System.Net.Sockets; var client = new UdpClient(); byte[] testData = CreateTestPacket(); // Tạo gói tin test client.Send(testData, testData.Length, "localhost", 2368); ``` ## Dependencies - .NET 10.0 - System.Buffers (ArrayPool) - System.Collections.Concurrent (ConcurrentBag) - System.Net.Sockets (UdpClient) - System.Runtime.InteropServices (MemoryMarshal) Tất cả đều là built-in .NET libraries, không cần thêm NuGet packages. ## API Reference ### OleiLidarServer **Constructor:** ```csharp public OleiLidarServer(int port) ``` **Methods:** ```csharp public void Start() public void Stop() public string GetStatistics() public void ResetStatistics() public void Dispose() ``` **Events:** ```csharp public event EventHandler DataReceived public event EventHandler ErrorOccurred ``` **Properties:** ```csharp public bool IsRunning { get; } public long TotalPacketsReceived { get; } public long TotalPacketsParsed { get; } public long TotalParseErrors { get; } public long TotalPacketsCreated { get; } // NEW: Track allocations public long CurrentPoolSize { get; } // NEW: Current pool size ``` ## Best Practices 1. **Don't store packet references** - Packet tự động được trả về pool sau event handler: ```csharp // ❌ DON'T DO THIS LidarDataPacket? storedPacket = null; server.DataReceived += (sender, e) => { storedPacket = e.Packet; // WRONG! Packet will be reused }; // ✅ DO THIS server.DataReceived += (sender, e) => { // Process immediately var data = e.Packet.GetValidPoints().ToList(); // Copy data if needed }; ``` 2. **Process quickly** - Event handler chạy trên receive thread, tránh blocking operations 3. **Subscribe to ErrorOccurred** để monitor issues: ```csharp server.ErrorOccurred += (sender, e) => { Console.WriteLine($"Error: {e.Message}"); }; ``` 4. **Use statistics** để track health: ```csharp Console.WriteLine(server.GetStatistics()); ``` 5. **Dispose properly** để cleanup resources: ```csharp using var server = new OleiLidarServer(port); // hoặc server.Dispose(); ``` ## Troubleshooting ### Không nhận được data - Check firewall settings cho UDP port - Verify LiDAR IP configuration - Check network connectivity - Monitor ErrorOccurred events ### High parse errors - Check network quality (packet corruption) - Verify LiDAR firmware version - Check if multiple clients receiving same port ### High memory usage - Ensure packets are returned to pool - Check if event handlers are accumulating packets - Monitor GC with performance counters ### Low throughput - Check thread priority - Monitor CPU usage - Verify network bandwidth - Check event handler performance ## Future Enhancements - [ ] Async/Await support - [ ] Packet recording to file - [ ] Packet replay from file - [ ] Built-in filtering (distance, angle, strength) - [ ] Real-time visualization support - [ ] Multi-sensor support - [ ] Configurable threading model - [ ] Performance metrics API - [ ] Unit tests - [ ] Integration tests ## Support & Contact Project này là một phần của **RobotNet10**. Để report issues hoặc request features, vui lòng liên hệ team development. ## License Internal project - RobotNet10 --- **Version**: 1.0 **Last Updated**: 2026-02-07 **Target Framework**: .NET 10.0 **Protocol Version**: v2.1 (Olei LiDAR)