using Sick.SafetyScanners.DataStructures; using Sick.SafetyScanners.Helpers; namespace Sick.SafetyScanners.DataProcessing; /// /// Parser for FieldGeometryData response from COLA2 variable command /// Thread-safe implementation /// public sealed class ParseFieldGeometryData { private const double StartAngleDegrees = -47.5; // Defined start angle in degrees in SICK coordinates /// /// Parses the field geometry data from a TCP sequence (COLA2 response) /// Matches: ParseFieldGeometryData::parseTCPSequence in C++ /// public FieldData ParseTcpSequence(PacketBuffer buffer) { var span = buffer.GetBufferSpan(); uint arrayLength = ReadArrayLength(span); var geometryDistance = new List((int)arrayLength); for (uint i = 0; i < arrayLength; i++) { geometryDistance.Add(ReadArrayElement(span, i)); } // Values are persistent for scanners double res = (275.0 / arrayLength); return new FieldData { IsValid = true, BeamDistances = geometryDistance, StartAngle = (StartAngleDegrees * Math.PI / 180.0), AngularBeamResolution = (res * Math.PI / 180.0) }; } private uint ReadArrayLength(ReadOnlySpan span) { return ReadWriteHelper.ReadUint32LittleEndian(span, 4); } private ushort ReadArrayElement(ReadOnlySpan span, uint elemNumber) { return ReadWriteHelper.ReadUint16LittleEndian(span, 8 + (int)(elemNumber * 2)); } }