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); } }