init
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/SLICECommands/RealtimeCommands/EndRealtimeMode.cs
|
||||
- DataPRO/SLICECommands/RealtimeCommands/UDPStreamPacket.cs
|
||||
- DataPRO/SLICECommands/RealtimeCommands/StartRealtimeMode.cs
|
||||
- DataPRO/SLICECommands/RealtimeCommands/RealtimeCommandBase.cs
|
||||
- DataPRO/SLICECommands/RealtimeCommands/IGetRealtimeSamples.cs
|
||||
- DataPRO/SLICECommands/RealtimeCommands/GetRealtimeSamplesSLICE6.cs
|
||||
- DataPRO/SLICECommands/RealtimeCommands/GetRealtimeSamplesSLICE2.cs
|
||||
- DataPRO/SLICECommands/RealtimeCommands/RetrieveSingleSample.cs
|
||||
- DataPRO/SLICECommands/RealtimeCommands/GetRealtimeSamplesTSRAIR.cs
|
||||
- DataPRO/SLICECommands/RealtimeCommands/RetrieveSampleAverage.cs
|
||||
- DataPRO/SLICECommands/RealtimeCommands/StartRealtimeStreamingMode.cs
|
||||
- DataPRO/SLICECommands/RealtimeCommands/GetRealtimeSamples.cs
|
||||
- DataPRO/SLICECommands/RealtimeCommands/RealtimeStreamDecoder.cs
|
||||
- DataPRO/SLICECommands/RealtimeCommands/UDPRealtimeByteConverter.cs
|
||||
- DataPRO/SLICECommands/RealtimeCommands/StreamReaderUDP.cs
|
||||
- DataPRO/SLICECommands/RealtimeCommands/StreamConfigUDP.cs
|
||||
generated_at: "2026-04-16T03:55:46.218507+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "775d71b774e90d26"
|
||||
---
|
||||
|
||||
# Realtime Command Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides command classes for controlling and retrieving real-time data from SLICE devices. It implements a family of command classes that inherit from `RealtimeCommandBase` to manage device modes (start/end real-time mode, streaming mode), retrieve sample data (single samples, averages, multi-sample batches), and configure UDP streaming. The module supports multiple device types (SLICE2, SLICE6, TSRAIR) with specialized implementations for data interpretation, and includes infrastructure for decoding raw UDP packets (`RealtimeStreamDecoder`, `UDPRealtimeByteConverter`) and streaming via `StreamReaderUDP`. Its role is to abstract low-level communication protocol details and provide a consistent interface for real-time data acquisition.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Command Classes
|
||||
|
||||
#### `EndRealtimeMode`
|
||||
- **Constructor**: `EndRealtimeMode(ICommunication sock)` / `EndRealtimeMode(ICommunication sock, int timeoutMillisec)`
|
||||
- **Purpose**: Sends command `0x02` (`Commands.EndRealtimeMode`) to terminate real-time mode on the device.
|
||||
|
||||
#### `StartRealtimeMode`
|
||||
- **Constructor**: `StartRealtimeMode(ICommunication sock)` / `StartRealtimeMode(ICommunication sock, int timeoutMillisec)`
|
||||
- **Properties**:
|
||||
- `SupportsMultipleSampleRealtime` (bool): Controls whether the command parameter is 1 byte (true) or 0 bytes (false). Default is `true`.
|
||||
- **Purpose**: Sends command `0x01` (`Commands.StartRealtimeMode`) to enable real-time mode. Presence of a 1-byte parameter signals firmware support for multi-sample real-time.
|
||||
|
||||
#### `RetrieveSingleSample`
|
||||
- **Constructor**: `RetrieveSingleSample(ICommunication sock)` / `RetrieveSingleSample(ICommunication sock, int timeoutMillisec)`
|
||||
- **Properties**:
|
||||
- `Channels` (ushort): Number of channels in `_data`.
|
||||
- `GetChannelData(int zeroBasedChannel)` (short): Returns the single sample for the specified channel.
|
||||
- **Purpose**: Sends command `0x04` (`Commands.RetrieveSingleSample`) and decodes response into signed `short` values. Converts unsigned values >32768 to negative by subtracting 65536.
|
||||
|
||||
#### `RetrieveSampleAverage`
|
||||
- **Constructor**: `RetrieveSampleAverage(ICommunication sock)` / `RetrieveSampleAverage(ICommunication sock, int timeoutMillisec)`
|
||||
- **Properties**:
|
||||
- `Samples` (ushort): Sets number of samples to average in command parameter; gets number of samples used in response.
|
||||
- `Channels` (ushort): Number of channels in `_data`.
|
||||
- `GetChannelData(int zeroBasedChannel)` (short): Returns the averaged sample for the specified channel.
|
||||
- **Purpose**: Sends command `0x05` (`Commands.RetrieveSampleAverage`) with configurable sample count. Decodes response to extract number of samples used and mean values per channel.
|
||||
|
||||
#### `StartRealtimeStreamingMode`
|
||||
- **Constructor**: `StartRealtimeStreamingMode(ICommunication sock, byte[] channelList)` / `StartRealtimeStreamingMode(ICommunication sock, int timeoutMillisec, byte[] channelList)`
|
||||
- **Properties**:
|
||||
- `ChannelList` (byte[]): List of channels to collect data on. Sets command parameter.
|
||||
- **Purpose**: Sends command `0x07` (`Commands.StartRealtimeStreamingMode`) to put firmware into continuous streaming mode.
|
||||
|
||||
#### `StartTimeStampStreamMode`
|
||||
- **Constructor**: `StartTimeStampStreamMode(ICommunication sock)` / `StartTimeStampStreamMode(ICommunication sock, int timeoutMillisec)`
|
||||
- **Properties**:
|
||||
- `SupportsMultipleSampleRealtime` (bool): Controls parameter presence (1 byte if true, 0 if false).
|
||||
- `ParamsToSend` (byte[]): Sets command parameter bytes.
|
||||
- **Purpose**: Sends command `0x09` (`Commands.StartTimeStampStreamMode`) to start IRIG timestamped streaming. Requires minimum protocol version `UDPRealtimeStream`.
|
||||
|
||||
#### `StreamConfigUDPGet`
|
||||
- **Constructor**: `StreamConfigUDPGet(ICommunication sock)` / `StreamConfigUDPGet(ICommunication sock, int timeoutMillisec)`
|
||||
- **Properties**: All get/set properties map to fixed offsets in a 65-byte command/response payload:
|
||||
- `Stream_Profile_Number`, `UdpIpPort`, `TimeChannelID`, `DataChannelID`, `TMNS_*`, `IENAUDP_PortNumber`, `TMNS5-7`.
|
||||
- **Purpose**: Sends command `0x0D` (`Commands.I106StreamConfigGet`) to retrieve UDP streaming configuration.
|
||||
|
||||
#### `StreamConfigUDPSet`
|
||||
- **Constructor**: `StreamConfigUDPSet(ICommunication sock)` / `StreamConfigUDPSet(ICommunication sock, int timeoutMillisec)`
|
||||
- **Properties**: All get/set properties map to fixed offsets in a 74-byte command payload:
|
||||
- `Stream_Profile_Number`, `UdpIpPort`, `Irig106Config0/1`, `TMNS_*`, `IENAUDP_PortNumber`, `TMNS5-7`.
|
||||
- **Purpose**: Sends command `0x0C` (`Commands.I106StreamConfigSet`) to configure UDP streaming.
|
||||
|
||||
### Data Retrieval Classes (Implement `IGetRealtimeSamples`)
|
||||
|
||||
#### `IGetRealtimeSamples` Interface
|
||||
- **Properties**:
|
||||
- `SampleNumber` (ulong): First sample number in the returned batch.
|
||||
- `TimeStamp` (ulong)
|
||||
- `SequenceNumber` (ulong)
|
||||
- `Channels` (ushort): Total channel count.
|
||||
- `SamplesReturned` (int): Number of samples per channel returned.
|
||||
- `LogCommands` (bool): Whether to log command execution (default `false`).
|
||||
- **Methods**:
|
||||
- `GetChannelData(int zeroBasedChannel)` (short[]): Returns all samples for the specified channel.
|
||||
- `SyncExecute()` (void): Executes the command and retrieves samples.
|
||||
|
||||
#### `GetRealtimeSamples` (Base Class)
|
||||
- **Constructor**: `GetRealtimeSamples(ICommunication sock)` / `GetRealtimeSamples(ICommunication sock, int timeoutMillisec, bool bPolling = false)`
|
||||
- **Properties**:
|
||||
- `SampleNumber`, `TimeStamp`, `SequenceNumber`, `Channels`, `SamplesReturned`, `LogCommands` (inherited from interface).
|
||||
- **Purpose**: Base implementation for polling-based sample retrieval. Sends command `0x03` (`Commands.GetRealtimeSamples`) with 1-byte parameter. Decodes response with channel interleaving and applies offset subtraction (`-0x8000`) to convert unsigned to signed.
|
||||
|
||||
#### `GetRealtimeSamplesSLICE6`
|
||||
- **Constructor**: `GetRealtimeSamplesSLICE6(ICommunication sock)` / `GetRealtimeSamplesSLICE6(ICommunication sock, int timeoutMillisec)`
|
||||
- **Purpose**: Specialized implementation for SLICE6 devices. Decodes response data as signed (no conversion needed beyond byte-swapping). No offset adjustment.
|
||||
|
||||
#### `GetRealtimeSamplesSLICE2`
|
||||
- **Constructor**: `GetRealtimeSamplesSLICE2(ICommunication sock)` / `GetRealtimeSamplesSLICE2(ICommunication sock, int timeoutMillisec)`
|
||||
- **Purpose**: Specialized implementation for SLICE2 devices. Converts unsigned data to signed by adding `0x8000` after byte-swapping.
|
||||
|
||||
#### `GetRealtimeSamplesTSRAIR`
|
||||
- **Constructor**: `GetRealtimeSamplesTSRAIR(ICommunication sock)` / `GetRealtimeSamplesTSRAIR(ICommunication sock, int timeoutMillisec)`
|
||||
- **Properties**:
|
||||
- `Timestamps` (List<ulong>): List of timestamps (currently unused in `WholePackage()`).
|
||||
- **Purpose**: Specialized implementation for TSRAIR devices. Decodes unsigned data with byte-swapping but no offset adjustment.
|
||||
|
||||
### UDP Streaming Infrastructure
|
||||
|
||||
#### `UDPStreamPacket`
|
||||
- **Properties**:
|
||||
- `ChannelData` (short[][]): First index = channel, second = sample.
|
||||
- `TimeStamp` (long)
|
||||
- `SampleNumber` (ulong)
|
||||
- `SequenceNumber` (ulong)
|
||||
- `PTPTimesec`, `PTPTimeNsec` (uint)
|
||||
- `PTPSyncStatusError`, `ADCOverflowStatus` (bool)
|
||||
- `PTPTimeString` (string): Concatenation of `PTPTimesec` and `PTPTimeNsec` (zero-padded to 9 digits).
|
||||
- **Purpose**: Data structure for parsed UDP streaming packets.
|
||||
|
||||
#### `RealtimeStreamDecoder`
|
||||
- **Constructor**: `RealtimeStreamDecoder(IReadOnlyList<byte> bytes)`
|
||||
- **Properties**:
|
||||
- `SequenceNumber` (ushort), `TimeStamp` (ulong), `SampleNumber` (ulong), `Channels` (int[]), `RtData` (ushort[])
|
||||
- **Purpose**: Decodes raw UDP packet bytes (SPS format) into structured data. Handles header parsing (byte order reversed), channel mask extraction, and data extraction (byte order preserved). Does not convert to signed values.
|
||||
|
||||
#### `UDPRealtimeByteConverter`
|
||||
- **Constructor**: `UDPRealtimeByteConverter(byte[] bytes)`
|
||||
- **Properties**:
|
||||
- `PacketPattern`, `DataChannelID`, `PacketLength`, `DataLength`, `DataTypeVersion`, `SequenceNumber`, `PacketFlags`, `DataType`, `RelativeTime32`, `RelativeTime16`, `HdrCrc16`, `PtpTimeStampSec`, `PtpTimeStampNsec`, `Hdr2Crc16`, `ChannelMask`, `UdpSampleCount`
|
||||
- `RtData` (ushort[]), `Channels` (uint[]), `SequenceNumberPrev` (byte)
|
||||
- **Purpose**: Parses UDP packet headers and data. Supports `ANALOG_DATA_FORMAT_1` (`0x21`) and `TIME_DATA_PTP` (`0x12`). Converts data by XOR with `0x8000` to produce signed values.
|
||||
|
||||
#### `StreamReaderUDP`
|
||||
- **Constructor**: `StreamReaderUDP(string streamAddress, string hostAddress, UDPStreamProfile uDPStreamType, byte[] channels)`
|
||||
- **Properties**:
|
||||
- `StreamAddress`, `cmdline`, `HostIPAddress`, `UDPStreamType`, `Channels`, `UDPEndpoint`, `UDPSampleNumber`
|
||||
- **Methods**:
|
||||
- `CloseSocket()` (void): Closes UDP socket.
|
||||
- `Read()` (UDPStreamPacket?): Receives one UDP packet and returns parsed `UDPStreamPacket`, or `null` on timeout/error.
|
||||
- **Purpose**: Manages UDP socket binding, multicast membership, and packet reception. Decodes incoming packets using `UDPRealtimeByteConverter` and maps data to configured channels.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Command Type**: All `RealtimeCommandBase` subclasses set `command.Type = CommandPacket.CommandType.Realtime`.
|
||||
- **Command Parameter Initialization**:
|
||||
- `StartRealtimeMode` and `GetRealtimeSamples` always initialize `command.Parameter` to a 1-byte array (even if unused).
|
||||
- `RetrieveSampleAverage` initializes `command.Parameter` to a 2-byte array.
|
||||
- `StreamConfigUDPSet` uses a 74-byte parameter array; `StreamConfigUDPGet` uses 65 bytes.
|
||||
- **Data Byte Order**:
|
||||
- Header fields (e.g., `TimeStamp`, `SampleNumber`, `SequenceNumber`) in `RealtimeStreamDecoder` are received in little-endian byte order and must be reversed for correct interpretation.
|
||||
- Data payload in `RealtimeStreamDecoder` is received in standard little-endian order (no reversal).
|
||||
- `UDPRealtimeByteConverter` reverses header bytes but not data bytes.
|
||||
- **Signed Conversion**:
|
||||
- `RetrieveSingleSample`: Converts unsigned >32768 to signed by subtracting 65536.
|
||||
- `UDPRealtimeByteConverter`: XORs data with `0x8000`.
|
||||
- `GetRealtimeSamplesSLICE2`: Adds `0x8000` after byte-swapping.
|
||||
- `GetRealtimeSamples`: Subtracts `0x8000` after byte-swapping.
|
||||
- `GetRealtimeSamplesSLICE6` and `GetRealtimeSamplesTSRAIR`: No offset adjustment (data is already signed or unsigned as appropriate).
|
||||
- **Channel Data Layout**:
|
||||
- `GetRealtimeSamples`: Interleaved data order per channel group (e.g., for 9 channels: 7,8,9,4,5,6,1,2,3).
|
||||
- `StreamReaderUDP`: Assumes 6 channels total (`numChannels = 6`) regardless of configured channel list; uses modulo arithmetic to map samples to channels.
|
||||
- **UDP Packet Format**:
|
||||
- `RealtimeStreamDecoder`: Header is 34 bytes (`ByteIndex.DataStart = 34`), with payload starting at byte 34.
|
||||
- `UDPRealtimeByteConverter`: Header is 40 bytes (`UDP_BYTE_INDEX.DATA_START = 40`), with payload starting at byte 40.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* this module:
|
||||
- **`DTS.Common.ICommunication`**: Core communication interface (`ICommunication`, `CommandPacket`, `CommandReceiveAction`, `CommandStatus`).
|
||||
- **`DTS.Common.Enums.DASFactory`**: Enums and constants (`DFConstantsAndEnums.CommandStatus`, `ProtocolLimitedCommands`).
|
||||
- **`DTS.Common.Utilities`**: Helper utilities (`ArrayToString`).
|
||||
- **`System.Net`, `System.Net.Sockets`**: For `StreamReaderUDP` socket operations.
|
||||
- **`System.Collections.BitArray`**: Used in `RealtimeStreamDecoder` for channel mask parsing.
|
||||
|
||||
### Dependencies *on* this module:
|
||||
- **`RealtimeCommandBase`** is inherited by all concrete command classes (`StartRealtimeMode`, `EndRealtimeMode`, `RetrieveSingleSample`, etc.).
|
||||
- **`IGetRealtimeSamples`** is implemented by `GetRealtimeSamples` and its subclasses (`GetRealtimeSamplesSLICE6`, `GetRealtimeSamplesSLICE2`, `GetRealtimeSamplesTSRAIR`).
|
||||
- **`StreamReaderUDP`** depends on `UDPRealtimeByteConverter` and `UDPStreamPacket`.
|
||||
- **`RealtimeStreamDecoder`** is a standalone decoder; its usage is inferred from context but not directly referenced in provided files.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Channel Mask Interpretation in `StreamReaderUDP`**: The code assumes 6 channels (`numChannels = 6`) regardless of the `Channels` property, potentially misaligning data if fewer channels are configured.
|
||||
- **`StreamConfigUDPGet.ResponseToString` Bug**: The line `lines.Add(new List<string>() { $"Data Channel ID: {_timechannelid}" });` incorrectly logs `_timechannelid` instead of `_datachannelid`.
|
||||
- **`GetRealtimeSamples.ResponseToString` Bug**: The line `lines.Add(new List<string> { $"Sample number: {ResponseStatus}, Samples returned: {SampleNumber}, Time Stamp returned: {TimeStamp}, Sequence Number returned: {SequenceNumber}" });` uses `ResponseStatus` (undefined) instead of `SampleNumber` in the first placeholder.
|
||||
- **`UDPRealtimeByteConverter` Data Type Handling**: Only supports `ANALOG_DATA_FORMAT_1` (`0x21`); other types (e.g., `TIME_DATA_PTP`, `CGDP_TYPE`) result in `RtData = null`.
|
||||
- **`RealtimeStreamDecoder` Byte Order**: Header fields are reversed, but data payload is *not* reversed—this distinction is critical and explicitly documented in comments.
|
||||
- **`RetrieveSingleSample` Signed Conversion**: Uses `unsignedData[i] > 32768` to decide subtraction, which may misinterpret values exactly at 32768 (should be `>= 32768` for correct two’s complement).
|
||||
- **`StartRealtimeMode` Parameter Behavior**: Setting `SupportsMultipleSampleRealtime = false` clears the parameter array, but the constructor always initializes it to `new byte[1]`—only the setter can clear it after construction.
|
||||
- **`StreamReaderUDP` Timeout**: Socket timeout is hardcoded to 2000ms; no configurable option exists in the provided code.
|
||||
- **`UDPStreamPacket.TimeStamp`**: Always set to `0L` in `StreamReaderUDP.Read()`; the actual timestamp is stored in `PTPTimesec`/`PTPTimeNsec`.
|
||||
- **`UDPRealtimeByteConverter` Channel Mask**: Always assumes all 6 channels are present (`for (var i = 0; i < 6; i++)`), ignoring the `ChannelMask` field.
|
||||
Reference in New Issue
Block a user