Initial commit

This commit is contained in:
2026-07-03 16:37:12 +07:00
commit 63b8c1ea8b
1931 changed files with 640587 additions and 0 deletions

View File

@@ -0,0 +1,367 @@
# 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<byte>``ReadOnlySpan<byte>`
- Fast struct deserialization với `MemoryMarshal.Read<T>()`
- 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<byte>)
- 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<byte>`
- 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<LidarDataPacketEventArgs> DataReceived
public event EventHandler<LidarErrorEventArgs> 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)