Initial commit
This commit is contained in:
@@ -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>` và `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)
|
||||
Reference in New Issue
Block a user