163 lines
11 KiB
Markdown
163 lines
11 KiB
Markdown
|
|
---
|
||
|
|
source_files:
|
||
|
|
- DataPRO/EquipmentExchange/CrashDesignerTestSetup.cs
|
||
|
|
generated_at: "2026-04-16T03:44:55.174600+00:00"
|
||
|
|
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||
|
|
schema_version: 1
|
||
|
|
sha256: "75b4cd844b9f7d36"
|
||
|
|
---
|
||
|
|
|
||
|
|
# EquipmentExchange
|
||
|
|
|
||
|
|
## Documentation: `CrashDesignerTestSetup` Module
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 1. Purpose
|
||
|
|
|
||
|
|
This module defines the data model and XML deserialization logic for importing test setup configurations generated by *CrashDesigner* (a proprietary crash testing application). Its primary role is to parse an XML file conforming to a specific schema (with root `<TestSetupDefinition>`) into a strongly-typed object graph (`CrashDesignerTestSetup`), enabling downstream components to access test metadata, channel groupings, and data acquisition (DAQ) hardware configuration in a structured manner. It also provides a utility method (`GetEqxElectricalMethod`) to map equipment bridge types to internal sensor configuration flags used elsewhere in the system.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 2. Public Interface
|
||
|
|
|
||
|
|
#### `CrashDesignerTestSetup` Class
|
||
|
|
|
||
|
|
- **`string Name { get; set; }`**
|
||
|
|
The name of the test setup, extracted from the `Name` attribute of the `<TestSetupDefinition>` XML element.
|
||
|
|
|
||
|
|
- **`static void GetEqxElectricalMethod(string eqxBridge, out bool isProportional, out DTS.Common.Enums.Sensors.SensorConstants.BridgeType bridgeType)`**
|
||
|
|
Maps a string-based equipment bridge identifier (`eqxBridge`) to internal sensor configuration flags.
|
||
|
|
- `isProportional`: `true` for passive bridges (e.g., `FullBridge`, `HalfBridge`, `QuarterBridge`), `false` for active sensors (e.g., `Active`, `ActiveSensor`, `HalfBridgeActive`, `QuarterBridgeActive`).
|
||
|
|
- `bridgeType`: One of `DTS.Common.Enums.Sensors.SensorConstants.BridgeType` (`FullBridge`, `HalfBridge`, `QuarterBridge`, `IEPE`).
|
||
|
|
- Special case: `"PiezoInput"` → `IEPE`, `isProportional = true`.
|
||
|
|
|
||
|
|
- **`static CrashDesignerTestSetup ReadXML(string importFile)`**
|
||
|
|
Loads and deserializes an XML file (`importFile`) into a `CrashDesignerTestSetup` instance.
|
||
|
|
- Requires root element `<TestSetupDefinition>` with `Name` attribute.
|
||
|
|
- Delegates parsing of `<General>`, `<ChannelGroups>`, and `<DataAcquisitionUnit>` sub-elements to respective `ReadXml` methods.
|
||
|
|
- Logs unknown XML elements via `Trace.WriteLine`.
|
||
|
|
|
||
|
|
#### Nested Classes & Methods
|
||
|
|
|
||
|
|
- **`GeneralSection`**
|
||
|
|
- **Properties**: `DateGenerated`, `GeneratorName`, `Description`, `TestType`, `PreTriggerTime`, `PostTriggerTime`, `OutputDataDirectory`, `TestSetupGroup` (string array).
|
||
|
|
- **`void ReadXml(XmlElement root)`**: Parses child elements corresponding to `GeneralSection.Fields` enum values.
|
||
|
|
- `PreTriggerTimeReadout` → `PreTriggerTime`
|
||
|
|
- `PostTriggerTimeReadout` → `PostTriggerTime`
|
||
|
|
- `TestSetupGroup` → appends to internal list (multiple allowed).
|
||
|
|
- Uses invariant culture for numeric/date parsing; logs failures.
|
||
|
|
|
||
|
|
- **`ChannelGroupsSection`**
|
||
|
|
- **`Group[] Groups { get; }`**: Array of `Group` objects.
|
||
|
|
- **`void ReadXml(XmlElement root)`**: Parses `<Group>` child elements.
|
||
|
|
|
||
|
|
- **`Group`**
|
||
|
|
- **Properties**: `Name`, `Id`, `Parent`, `Description`.
|
||
|
|
- **`bool HasProperty(string key)` / `string GetProperty(string key)` / `void SetProperty(string key, string value)`**: Key-value store for arbitrary properties.
|
||
|
|
- **`KnownFormats` enum**: Lists 30+ standardized property keys (e.g., `ISOTitle`, `TestDate`, `CustomerName`, `Velocity`, `Mass`, `ImpactSide`) with `[Description]` attributes matching their XML element names.
|
||
|
|
- **`static Group ReadXml(XmlElement root)`**: Parses `Id`, `Parent` attributes, `<Name>`, `<Description>`, and `<Property Name="..." Value="...">` elements.
|
||
|
|
|
||
|
|
- **`DataAcquisitionSection`**
|
||
|
|
- **`DataAcquisitionUnit[] DataAcquisitionUnits { get; }`**: Array of DAQ units.
|
||
|
|
- **`void ReadXml(XmlElement element)`**: Parses a *single* `<DataAcquisitionUnit>` element (note: despite the name, only one unit is supported per XML file per current implementation).
|
||
|
|
|
||
|
|
- **`DataAcquisitionUnit`**
|
||
|
|
- **Properties**: Extensive hardware metadata (e.g., `Name`, `Type`, `SerialNr`, `Manufacturer`, `SampleFrequencyHz`, `AnalogInputChannelCount`, `Trigger`, `Enabled`, `DataBaseUID`, etc.).
|
||
|
|
- **`TriggerSection Trigger { get; }`**: Nested class with `TriggerMode`, `RecBus`, `T0Bus`, `Filter`.
|
||
|
|
- **`AnalogInChannelSection AnalogChannels { get; }`**: Contains parsed analog input channels.
|
||
|
|
- **`static DataAcquisitionUnit ReadXml(XmlElement root)`**: Parses all DAQ-specific XML elements.
|
||
|
|
- Uses `GetDouble` helper (returns `NaN` on parse failure).
|
||
|
|
- Handles nested `<Trigger>` and `<AnalogInChannel>` elements.
|
||
|
|
|
||
|
|
- **`TriggerSection`**
|
||
|
|
- **`void ReadXml(XmlElement root)`**: Parses `<TriggerMode>`, `<RecBus>`, `<T0Bus>`, `<Filter>` elements.
|
||
|
|
|
||
|
|
- **`AnalogInChannelSection`**
|
||
|
|
- **`AnalogInChannel[] Channels { get; }`**: Array of analog channels.
|
||
|
|
- **`void ReadXml(XmlElement element)`**: Parses a *single* `<AnalogInChannel>` element.
|
||
|
|
|
||
|
|
- **`AnalogInChannel`**
|
||
|
|
- **Properties**: 50+ fields covering channel configuration, sensor details, calibration, and signal conditioning (e.g., `Enabled`, `Id`, `GroupId`, `ChannelName`, `BridgeType`, `Sensitivity`, `ExcitationVoltage`, `OffsetFlag`, `ShuntPosFlag`, `NextCalibrationDate`, `PhysicalUnit`, `Direction`, `InvertFlag`, `CalculatedGain`, `SensorStatusUsable`, `VoltageEngineeringUnit`).
|
||
|
|
- **`static AnalogInChannel ReadXml(XmlElement root)`**: Parses all channel XML elements.
|
||
|
|
- Uses `GetDate` helper (returns `DateTime.MinValue` on parse failure).
|
||
|
|
- **Bug/Quirk**: In `ShuntPosMaxToleranceV` parsing, incorrectly assigns to `ShuntGainPos` instead of `ShuntPosMaxToleranceV` (see *Gotchas*).
|
||
|
|
|
||
|
|
- **`static DateTime GetDate(string text)`**
|
||
|
|
Helper for parsing `DateTime` from XML text (invariant culture, `DateTimeStyles.None`). Returns `DateTime.MinValue` on failure.
|
||
|
|
|
||
|
|
- **`static double GetDouble(string text)`**
|
||
|
|
Helper for parsing `double` from XML text (invariant culture, `NumberStyles.Any`). Returns `double.NaN` on failure.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 3. Invariants
|
||
|
|
|
||
|
|
- **XML Structure**:
|
||
|
|
- Root element must be `<TestSetupDefinition>` with a `Name` attribute.
|
||
|
|
- Valid child elements under `<TestSetupDefinition>` are strictly: `<General>`, `<ChannelGroups>`, `<DataAcquisitionUnit>`. Unknown elements are logged but ignored.
|
||
|
|
- `<General>` supports only elements defined in `GeneralSection.Fields` enum.
|
||
|
|
- `<ChannelGroups>` must contain one or more `<Group>` elements.
|
||
|
|
- `<DataAcquisitionUnit>` must contain exactly one `<DataAcquisitionUnit>` element (per current `ReadXml` implementation).
|
||
|
|
- `<AnalogInChannel>` elements are parsed individually and appended to the channel list.
|
||
|
|
|
||
|
|
- **Data Parsing**:
|
||
|
|
- Numeric/date fields use `CultureInfo.InvariantCulture` for parsing.
|
||
|
|
- Failure to parse numeric/date fields results in default values (`0`, `DateTime.MinValue`, `double.NaN`) and a `Trace.WriteLine` warning.
|
||
|
|
- `Group` properties are stored in a dictionary; unknown keys are preserved.
|
||
|
|
- `AnalogInChannel.Enabled`, `DataConversionEnabled`, etc., default to `false` if attribute/element missing.
|
||
|
|
|
||
|
|
- **Object State**:
|
||
|
|
- `General`, `ChannGroups`, `DataAcquisition` are initialized to non-null instances (via property initializers).
|
||
|
|
- `Group.Groups`, `DataAcquisitionUnits`, `AnalogChannels.Channels` arrays are lazily populated via `ReadXml`.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 4. Dependencies
|
||
|
|
|
||
|
|
- **External Types**:
|
||
|
|
- `System.Xml.XmlDocument`, `System.Xml.XmlElement`, `System.Xml.XmlNode`
|
||
|
|
- `System.ComponentModel.DescriptionAttribute` (used in `Group.KnownFormats`)
|
||
|
|
- `DTS.Common.Enums.Sensors.SensorConstants.BridgeType` (referenced in `GetEqxElectricalMethod`)
|
||
|
|
|
||
|
|
- **Module Dependencies**:
|
||
|
|
- This module *depends on* the `DTS.Common` assembly (for `BridgeType` enum).
|
||
|
|
- *Used by*: Downstream components consuming `CrashDesignerTestSetup` objects (e.g., test execution, DAQ configuration, reporting).
|
||
|
|
- **Notable**: The `DataAcquisitionSection` class has a commented-out property `public DataAcquisitionSection DataAcquisitionUnit { get; set; }`, suggesting a design change or legacy artifact.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 5. Gotchas
|
||
|
|
|
||
|
|
- **Shunt Parsing Bug**:
|
||
|
|
In `AnalogInChannel.ReadXml`, the `ShuntPosMaxToleranceV` case incorrectly assigns to `ShuntGainPos` instead of `ShuntPosMaxToleranceV`:
|
||
|
|
```csharp
|
||
|
|
case "ShuntPosMaxToleranceV": analog.ShuntGainPos = GetDouble(element.InnerText); break; // WRONG!
|
||
|
|
```
|
||
|
|
This will overwrite `ShuntGainPos` and leave `ShuntPosMaxToleranceV` at its default (`0`).
|
||
|
|
**Impact**: Shunt calibration tolerance data may be corrupted.
|
||
|
|
|
||
|
|
- **Single DAQ Unit Assumption**:
|
||
|
|
`DataAcquisitionSection.ReadXml` only processes *one* `<DataAcquisitionUnit>` element (appends to `_units` list once), despite the XML schema potentially supporting multiple. This may cause data loss if the input file contains multiple `<DataAcquisitionUnit>` elements.
|
||
|
|
|
||
|
|
- **Ambiguous `PreTriggerTimeReadout`/`PostTriggerTimeReadout`**:
|
||
|
|
The XML element names (`PreTriggerTimeReadout`, `PostTriggerTimeReadout`) do not match the property names (`PreTriggerTime`, `PostTriggerTime`). This could confuse developers unfamiliar with the enum mapping.
|
||
|
|
|
||
|
|
- **`KnownFormats` Enum Mismatch**:
|
||
|
|
The `KnownFormats` enum uses `[Description]` attributes (e.g., `[Description("ISO Title")]`), but XML parsing for `Group` properties relies on `element.LocalName` matching the enum *name* (e.g., `ISOTitle`), not the description. This is correct per current code but may be error-prone.
|
||
|
|
|
||
|
|
- **`GetEqxElectricalMethod` Behavior**:
|
||
|
|
- `"Active"` and `"ActiveSensor"` both set `isProportional = false`, but the distinction is not documented.
|
||
|
|
- `"PiezoInput"` is the *only* case that sets `bridgeType = IEPE`; other active bridges use `FullBridge`/`HalfBridge`/`QuarterBridge` with `isProportional = false`.
|
||
|
|
|
||
|
|
- **No Validation**:
|
||
|
|
The class performs no semantic validation (e.g., checking `SampleFrequencyHz` is within `MinSampleFrequencyHz`/`MaxSampleFrequencyHz`, or `GroupId` references exist). Invalid data may propagate silently.
|
||
|
|
|
||
|
|
- **Missing `DataAcquisitionUnit` Property**:
|
||
|
|
The commented-out property `public DataAcquisitionSection DataAcquisitionUnit { get; set; }` suggests confusion between `DataAcquisitionSection` (container) and `DataAcquisitionUnit` (item). The current design uses `DataAcquisition.DataAcquisitionUnits` (array), which is correct, but the commented line may indicate historical instability.
|
||
|
|
|
||
|
|
- **No Error Handling for XML Load**:
|
||
|
|
`ReadXML` calls `doc.Load(importFile)` without try/catch. File I/O errors (e.g., missing file, malformed XML) will throw unhandled exceptions.
|
||
|
|
|
||
|
|
- **Culture Sensitivity**:
|
||
|
|
While numeric/date parsing uses invariant culture, string comparisons (e.g., `element.LocalName == "General"`) are case-sensitive and culture-sensitive. XML element names must match *exactly* (e.g., `"General"`, not `"general"`).
|