# UDP Packet Parsers Implementation Guide ## Overview This document describes the UDP packet parsers for SICK Safety Scanner scan data. The parsers are based on the C++ reference implementation in `sick_safetyscanners_base`. ## Data Structures Created All data structures have been created in `DataStructures/` folder: 1. **DataHeader.cs** - Header metadata (version, serial numbers, channel, sequence, scan numbers, timestamps, block offsets/sizes) 2. **ScanPoint.cs** - Single scan point (angle, distance, reflectivity, flags) 3. **MeasurementData.cs** - Collection of scan points 4. **DerivedValues.cs** - Configuration of data output (multiplication factor, number of beams, scan time, angles, resolution) 5. **GeneralSystemState.cs** - Device status (run/standby mode, cut-off paths, monitoring cases, errors) 6. **IntrusionDatum.cs** - Single intrusion datum 7. **IntrusionData.cs** - Collection of intrusion data (field interruption) 8. **ApplicationInputs.cs** - Application inputs (local inputs) 9. **ApplicationOutputs.cs** - Application outputs (local outputs) 10. **ApplicationData.cs** - Bundles application inputs and outputs 11. **UdpScanData.cs** - Complete parsed scan data containing all blocks ## Parser Classes Status ### ✅ Completed - **ParseDataHeader.cs** - Fully implemented parser for data header ### ⏳ To Be Implemented The following parsers need to be implemented based on C++ reference: 1. **ParseDerivedValues.cs** - Parse derived values block - Reference: `srcs/refs/sick_safetyscanners_base/src/data_processing/ParseDerivedValues.cpp` - Parse: multiplication factor (offset 0), number of beams (offset 2), scan time (offset 4), start angle (offset 8), angular beam resolution (offset 12), interbeam period (offset 16) - Angle conversion: Use `DerivedValues.AngleResolution = 4194304.0` to convert from sensor units to radians 2. **ParseMeasurementData.cs** - Parse measurement data block - Reference: `srcs/refs/sick_safetyscanners_base/src/data_processing/ParseMeasurementData.cpp` - Parse: number of beams (offset 0), then for each beam: distance (offset 4 + i*4), reflectivity (offset 6 + i*4), status flags (offset 7 + i*4) - Requires DerivedValues for start angle and angular resolution - Status byte bits: bit 0=valid, bit 1=infinite, bit 2=glare, bit 3=reflector, bit 4=contamination, bit 5=contamination_warning 3. **ParseGeneralSystemState.cs** - Parse general system state block - Reference: `srcs/refs/sick_safetyscanners_base/src/data_processing/ParseGeneralSystemState.cpp` - Parse: status bits (offset 0), safe cut-off paths (offset 1-3), non-safe cut-off paths (offset 4-6), reset required paths (offset 7-9), monitoring cases (offset 10-13), errors (offset 15) 4. **ParseIntrusionData.cs** - Parse intrusion data block - Reference: `srcs/refs/sick_safetyscanners_base/src/data_processing/ParseIntrusionData.cpp` - Parse: 24 intrusion datums, each with size (4 bytes) and flags (variable size based on number of scan points) 5. **ParseApplicationData.cs** - Parse application data block - Reference: `srcs/refs/sick_safetyscanners_base/src/data_processing/ParseApplicationData.cpp` - Parse: ApplicationInputs (offsets 0-74) and ApplicationOutputs (offsets 140-259) - Complex parsing of bit fields for inputs/outputs, velocities, monitoring cases, etc. 6. **ParseData.cs** - Main parser that coordinates all sub-parsers - Reference: `srcs/refs/sick_safetyscanners_base/src/data_processing/ParseData.cpp` - Orchestrates parsing of all blocks in order: 1. ParseDataHeader 2. ParseDerivedValues 3. ParseMeasurementData 4. ParseGeneralSystemState 5. ParseIntrusionData 6. ParseApplicationData - Validates packet size and block offsets/sizes ## Implementation Notes ### Endianness - All values are read in **Little Endian** format - Use `ReadWriteHelper.ReadUint8LittleEndian()`, `ReadUint16LittleEndian()`, `ReadUint32LittleEndian()`, `ReadInt32LittleEndian()` ### Angle Conversion - Angles in sensor units need to be divided by `DerivedValues.AngleResolution` (4194304.0) to get radians - Example: `angleRad = sensorAngle / DerivedValues.AngleResolution` ### Packet Structure - UDP packets may be fragmented across multiple UDP packets - Need UDPPacketMerger (similar to TcpPacketMerger) to merge fragmented packets - ParseDataHeader is always at offset 0 - Other blocks start at offsets specified in DataHeader ### Error Handling - Each parser should check if the block is enabled (offset != 0 && size != 0) - Return empty structure if block is not enabled - Validate buffer size before parsing ## Usage in ILidar The `ScanDataEventArgs` now includes: - `RawScanData`: Raw bytes from UDP packet - `ParsedScanData`: Parsed `UdpScanData` structure (if parsing succeeded) This allows consumers to either: 1. Use parsed data directly (recommended) 2. Parse raw data themselves if needed ## Next Steps 1. Implement remaining parser classes 2. Create UDPPacketMerger for handling fragmented UDP packets 3. Integrate parsers into SickLidarDriver 4. Add UDP client support (if not already present)