using Olei.LidarSensor;
namespace Olei.LidarSensor.Examples;
///
/// Example usage of Olei LiDAR Server
/// Demonstrates how to receive and process LiDAR data
///
public class UsageExample
{
public static void BasicExample()
{
// Create server on UDP port 2368 (typical LiDAR port)
using var server = new OleiLidarServer(2368);
// Subscribe to data received event
server.DataReceived += OnDataReceived;
// Subscribe to error event
server.ErrorOccurred += OnError;
// Start receiving data
server.Start();
Console.WriteLine("LiDAR server started. Press any key to stop...");
Console.ReadKey();
// Stop server (also called automatically by Dispose)
server.Stop();
// Print statistics
Console.WriteLine(server.GetStatistics());
}
private static void OnDataReceived(object? sender, LidarDataPacket e)
{
var packet = e;
// Check if header is valid
if (!packet.Header.IsValidFrame)
{
Console.WriteLine("Invalid frame received!");
return;
}
// Check for errors
if (packet.Header.HasError)
{
Console.WriteLine($"LiDAR Error - Motor: {packet.Header.HasMotorFault}, " +
$"Voltage: {packet.Header.HasAbnormalVoltage}, " +
$"Temperature: {packet.Header.HasTemperatureFault}");
}
// Print header info
Console.WriteLine($"Rotation Rate: {packet.Header.RotationRate} rpm, " +
$"Direction: {(packet.Header.IsCounterClockwise ? "CCW" : "CW")}, " +
$"Valid Points: {packet.GetValidDataBlockCount()}");
// Process valid data points
ProcessDataPoints(packet);
// NOTE: Packet is automatically returned to pool after this handler completes
}
private static void ProcessDataPoints(LidarDataPacket packet)
{
byte distanceScale = packet.Header.DistanceScale;
// Method 1: Iterate through all data blocks
for (int i = 0; i < LidarDataPacket.DATA_BLOCK_COUNT; i++)
{
var block = packet.DataBlocks[i];
if (block.IsValid)
{
double angle = block.GetAngleDegrees();
double distance = block.GetDistance(distanceScale);
ushort strength = block.SignalStrength;
// Process data point
// Console.WriteLine($"Angle: {angle:F2}°, Distance: {distance:F2}, Strength: {strength}");
}
}
// Method 2: Use GetValidDataBlocks (cleaner but with slight overhead)
foreach (var block in packet.GetValidDataBlocks())
{
double angle = block.GetAngleDegrees();
double distance = block.GetDistance(distanceScale);
// Process...
}
// Method 3: Get as Cartesian coordinates
foreach (var (x, y) in packet.GetValidCartesianPoints())
{
// Use X, Y coordinates directly
// Console.WriteLine($"X: {x:F2}, Y: {y:F2}");
}
}
private static void OnError(object? sender, LidarErrorEventArgs e)
{
Console.WriteLine($"[ERROR] {e.Message}");
if (e.Exception != null)
{
Console.WriteLine($"Exception: {e.Exception}");
}
}
///
/// Advanced example with custom port and statistics monitoring
///
public static void AdvancedExample()
{
const int port = 2368;
using var server = new OleiLidarServer(port);
int packetCount = 0;
var startTime = DateTime.UtcNow;
server.DataReceived += (sender, e) =>
{
packetCount++;
// Print statistics every 100 packets
if (packetCount % 100 == 0)
{
var elapsed = (DateTime.UtcNow - startTime).TotalSeconds;
double packetsPerSecond = packetCount / elapsed;
Console.WriteLine($"\n=== Statistics ===");
Console.WriteLine($"Packets: {packetCount}");
Console.WriteLine($"Rate: {packetsPerSecond:F2} packets/sec");
Console.WriteLine($"Server: {server.GetStatistics()}");
Console.WriteLine($"Valid Points: {e.GetValidDataBlockCount()}/150");
}
// Packet automatically returned to pool after handler completes
};
server.ErrorOccurred += (sender, e) =>
{
Console.WriteLine($"[ERROR] {e.Message}");
};
server.Start();
Console.WriteLine($"Advanced LiDAR monitoring started on port {port}");
Console.WriteLine("Press any key to stop...");
Console.ReadKey();
server.Stop();
Console.WriteLine("\n=== Final Statistics ===");
Console.WriteLine(server.GetStatistics());
var totalTime = (DateTime.UtcNow - startTime).TotalSeconds;
Console.WriteLine($"Total Time: {totalTime:F2} seconds");
Console.WriteLine($"Average Rate: {packetCount / totalTime:F2} packets/sec");
}
///
/// Example with distance filtering
/// Only process points within certain distance range
///
public static void DistanceFilterExample()
{
const double minDistance = 100.0; // mm
const double maxDistance = 5000.0; // mm
using var server = new OleiLidarServer(2368);
server.DataReceived += (sender, e) =>
{
var packet = e;
byte distanceScale = packet.Header.DistanceScale;
foreach (var block in packet.GetValidDataBlocks())
{
double distance = block.GetDistance(distanceScale);
// Filter by distance
if (distance >= minDistance && distance <= maxDistance)
{
double angle = block.GetAngleDegrees();
Console.WriteLine($"Filtered Point - Angle: {angle:F2}°, Distance: {distance:F2}mm");
}
}
// Packet automatically returned to pool
};
server.Start();
Console.WriteLine($"Distance filter active: {minDistance}-{maxDistance}mm");
Console.WriteLine("Press any key to stop...");
Console.ReadKey();
}
///
/// Example with angle sector filtering
/// Only process points within certain angle range
///
public static void AngleSectorExample()
{
const double minAngle = 45.0; // degrees
const double maxAngle = 135.0; // degrees
using var server = new OleiLidarServer(2368);
server.DataReceived += (sender, e) =>
{
var packet = e;
byte distanceScale = packet.Header.DistanceScale;
foreach (var block in packet.GetValidDataBlocks())
{
double angle = block.GetAngleDegrees();
// Filter by angle
if (angle >= minAngle && angle <= maxAngle)
{
double distance = block.GetDistance(distanceScale);
Console.WriteLine($"Sector Point - Angle: {angle:F2}°, Distance: {distance:F2}mm");
}
}
// Packet automatically returned to pool
};
server.Start();
Console.WriteLine($"Angle sector active: {minAngle}°-{maxAngle}°");
Console.WriteLine("Press any key to stop...");
Console.ReadKey();
}
}