using System.Runtime.InteropServices;
namespace Olei.LidarSensor;
///
/// Data block structure for each measurement point (8 bytes)
/// All data is in little-endian format
///
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct LidarDataBlock
{
///
/// Invalid angle marker
///
public const ushort INVALID_ANGLE = 0xFF00;
///
/// Raw angle value (0~35999)
/// Unit: 0.01°/LSB, range 0° ~ 359.99°
/// Data block is invalid if this value >= 0xFF00
///
public ushort AngleRaw;
///
/// Distance readout data (unsigned integer)
/// Actual distance = readout data × distance scale
///
public ushort DistanceRaw;
///
/// Signal strength (0~65535)
/// Indicates the strength of the received signal
///
public ushort SignalStrength;
///
/// Reserved for future use
///
public ushort Reserved;
///
/// Check if this data block is valid
///
public readonly bool IsValid => AngleRaw < INVALID_ANGLE;
///
/// Get angle in degrees (0.00° ~ 359.99°)
///
public readonly double GetAngleDegrees()
{
return AngleRaw * 0.01;
}
///
/// Get angle in radians
///
public readonly double GetAngleRadians()
{
return AngleRaw * 0.01 * Math.PI / 180.0;
}
///
/// Get actual distance based on distance scale
///
/// Distance scale from header
/// Actual distance in the same unit as distance scale
public readonly double GetDistance(byte distanceScale)
{
return DistanceRaw * distanceScale;
}
///
/// Get X coordinate (distance * cos(angle))
///
/// Distance scale from header
public readonly double GetX(byte distanceScale)
{
double distance = GetDistance(distanceScale);
double angleRad = GetAngleRadians();
return distance * Math.Cos(angleRad);
}
///
/// Get Y coordinate (distance * sin(angle))
///
/// Distance scale from header
public readonly double GetY(byte distanceScale)
{
double distance = GetDistance(distanceScale);
double angleRad = GetAngleRadians();
return distance * Math.Sin(angleRad);
}
}