Examples#
Use the single-rate example when one periodic runnable is sufficient for a function, for example simple signal conditioning or threshold checks with one execution rhythm.
Use the multi-rate example when preprocessing and decision logic should run at different cycle times, for example 10 ms input conditioning and 20 ms output publication.
SpeedHazardDetection (single cyclic runnable)
VehicleSpeedFusion (multi-rate cyclic runnables at 10 ms and 20 ms)
wheel Speed Plausibility Check including error and supervision example
API#
As no final API specification is available yet, these examples should be considered preliminary drafts. They demonstrate the metamodel concepts and shall reuse canonical VSS semantics where possible. Any non-standard catalogue path must be identified as an approved extension.
speed_hazard_detection.cpp
1/********************************************************************************
2* Copyright (c) 2026 ZF Friedrichshafen AG
3*
4* See the NOTICE file(s) distributed with this work for additional
5* information regarding copyright ownership.
6*
7* This program and the accompanying materials are made available under the
8* terms of the Apache License Version 2.0 which is available at
9* https://www.apache.org/licenses/LICENSE-2.0
10*
11* SPDX-License-Identifier: Apache-2.0
12*
13* Contributors:
14* Thomas Pfleiderer - documentation
15* *******************************************************************************
16*/
17
18#include "speed_hazard_detection.hpp"
19#include <algorithm>
20
21namespace autoapiframework {
22namespace speedHazardDetection {
23
24// ============================================================================
25// SpeedHazardDetectionContext Implementation
26// ============================================================================
27
28SpeedHazardDetectionContext::SpeedHazardDetectionContext()
29 : isInitialized(false),
30 previousSpeed(0.0f),
31 previousSpeedTimestamp(0),
32 hazardRequestActive(false),
33 hazardRequestStartTimestamp(0),
34 cycleCounter(0) {
35}
36
37void SpeedHazardDetectionContext::reset() {
38 isInitialized = false;
39 previousSpeed = 0.0f;
40 previousSpeedTimestamp = 0;
41 hazardRequestActive = false;
42 hazardRequestStartTimestamp = 0;
43 cycleCounter = 0;
44}
45
46bool SpeedHazardDetectionContext::getInitializationStatus() const {
47 return isInitialized;
48}
49
50uint32_t SpeedHazardDetectionContext::getCycleCount() const {
51 return cycleCounter;
52}
53
54// ============================================================================
55// SpeedHazardDetection Function Implementation
56// ============================================================================
57
58FunctionResult SpeedHazardDetection::init(
59 SpeedHazardDetectionContext& context,
60 const SpeedHazardDetectionParameters& parameters) {
61
62 // Validate parameters
63 if (parameters.speedHazardForwardThresholdPercent < 0.0f) {
64 return FunctionResult::FAILURE;
65 }
66
67 if (parameters.hazardRequestDurationMs == 0) {
68 return FunctionResult::FAILURE;
69 }
70
71 // Reset context state
72 context.reset();
73
74 // Initialize with safe defaults
75 context.previousSpeed = 0.0f;
76 context.previousSpeedTimestamp = 0;
77 context.hazardRequestActive = false;
78 context.hazardRequestStartTimestamp = 0;
79 context.cycleCounter = 0;
80
81 // Mark as initialized
82 context.isInitialized = true;
83
84 return FunctionResult::SUCCESS;
85}
86
87FunctionResult SpeedHazardDetection::step(
88 SpeedHazardDetectionContext& context,
89 const SpeedHazardDetectionParameters& parameters,
90 const SpeedHazardDetectionInputs& inputs,
91 SpeedHazardDetectionOutputs& outputs) {
92
93 // Check initialization
94 if (!context.isInitialized) {
95 outputs.functionStatus = FunctionResult::NOT_AVAILABLE;
96 outputs.hazardRequest.value = false;
97 outputs.hazardRequest.quality = DataQuality::INVALID;
98 return FunctionResult::NOT_AVAILABLE;
99 }
100
101 // Increment cycle counter
102 context.cycleCounter++;
103
104 // ========================================================================
105 // INPUT VALIDATION
106 // ========================================================================
107
108 // Check vehicle speed data quality
109 if (inputs.vehicleSpeed.quality == DataQuality::INVALID ||
110 inputs.vehicleSpeed.quality == DataQuality::UNINITIALIZED) {
111 outputs.functionStatus = FunctionResult::FAILURE;
112 outputs.hazardRequest.quality = DataQuality::INVALID;
113 return FunctionResult::FAILURE;
114 }
115
116 // Check acceleration data quality
117 if (inputs.accelerationLongitudinal.quality == DataQuality::INVALID ||
118 inputs.accelerationLongitudinal.quality == DataQuality::UNINITIALIZED) {
119 outputs.functionStatus = FunctionResult::FAILURE;
120 outputs.hazardRequest.quality = DataQuality::INVALID;
121 return FunctionResult::FAILURE;
122 }
123
124 // Validate speed range
125 if (inputs.vehicleSpeed.value < 0.0f || inputs.vehicleSpeed.value > 300.0f) {
126 outputs.functionStatus = FunctionResult::FAILURE;
127 outputs.hazardRequest.quality = DataQuality::INVALID;
128 return FunctionResult::FAILURE;
129 }
130
131 // Validate acceleration range
132 if (inputs.accelerationLongitudinal.value < -20.0f ||
133 inputs.accelerationLongitudinal.value > 20.0f) {
134 outputs.functionStatus = FunctionResult::FAILURE;
135 outputs.hazardRequest.quality = DataQuality::INVALID;
136 return FunctionResult::FAILURE;
137 }
138
139 // ========================================================================
140 // SPEED INCREASE DETECTION LOGIC
141 // ========================================================================
142
143 float currentSpeed = inputs.vehicleSpeed.value;
144 float speedIncrease = 0.0f;
145
146 if (context.previousSpeedTimestamp > 0) {
147 // Calculate time delta in seconds
148 uint32_t timeDeltaMs = inputs.vehicleSpeed.updateTimestampMs -
149 context.previousSpeedTimestamp;
150 float timeDeltaS = timeDeltaMs / 1000.0f;
151
152 // Ensure we have a valid time delta (at least 1ms)
153 if (timeDeltaS > 0.0f) {
154 speedIncrease = currentSpeed - context.previousSpeed;
155 }
156 }
157
158 // Calculate relative speed increase in percent
159 float relativeSpeedIncreasePercent = 0.0f;
160 if (context.previousSpeed > 0.1f) { // Avoid division by zero
161 relativeSpeedIncreasePercent =
162 (speedIncrease / context.previousSpeed) * 100.0f;
163 }
164
165 // ========================================================================
166 // HAZARD REQUEST DECISION LOGIC
167 // ========================================================================
168
169 bool shouldActivateHazard = false;
170
171 // Check if acceleration threshold triggers hazard for forward motion
172 if (currentSpeed > 5.0f && // Only when vehicle is actively moving
173 inputs.accelerationLongitudinal.value > 0.0f && // Forward acceleration
174 relativeSpeedIncreasePercent >= parameters.speedHazardForwardThresholdPercent) {
175 shouldActivateHazard = true;
176 }
177
178 // ========================================================================
179 // HAZARD REQUEST LATCHING
180 // ========================================================================
181
182 if (shouldActivateHazard) {
183 // Activate or re-trigger the hazard request
184 context.hazardRequestActive = true;
185 context.hazardRequestStartTimestamp = inputs.vehicleSpeed.updateTimestampMs;
186 }
187
188 // Check if hazard request should remain active based on duration
189 if (context.hazardRequestActive) {
190 uint32_t hazardDurationElapsedMs =
191 inputs.vehicleSpeed.updateTimestampMs - context.hazardRequestStartTimestamp;
192
193 if (hazardDurationElapsedMs >= parameters.hazardRequestDurationMs) {
194 // Hazard request duration has expired
195 context.hazardRequestActive = false;
196 }
197 }
198
199 // ========================================================================
200 // OUTPUT ASSIGNMENT
201 // ========================================================================
202
203 outputs.hazardRequest.value = context.hazardRequestActive;
204 outputs.hazardRequest.quality = DataQuality::VALID;
205 outputs.hazardRequest.updateTimestampMs = inputs.vehicleSpeed.updateTimestampMs;
206 outputs.functionStatus = FunctionResult::SUCCESS;
207
208 // ========================================================================
209 // STATE UPDATE FOR NEXT CYCLE
210 // ========================================================================
211
212 context.previousSpeed = currentSpeed;
213 context.previousSpeedTimestamp = inputs.vehicleSpeed.updateTimestampMs;
214
215 return FunctionResult::SUCCESS;
216}
217
218FunctionResult SpeedHazardDetection::terminate(
219 SpeedHazardDetectionContext& context,
220 SpeedHazardDetectionOutputs& outputs) {
221
222 // Ensure all outputs are in safe state
223 outputs.hazardRequest.value = false;
224 outputs.hazardRequest.quality = DataQuality::VALID;
225 outputs.hazardRequest.updateTimestampMs = 0;
226 outputs.functionStatus = FunctionResult::SUCCESS;
227
228 // Reset internal state
229 context.reset();
230
231 return FunctionResult::SUCCESS;
232}
233
234} // namespace speedHazardDetection
235} // namespace autoapiframework
speed_hazard_detection.hpp
1/********************************************************************************
2* Copyright (c) 2026 ZF Friedrichshafen AG
3*
4* See the NOTICE file(s) distributed with this work for additional
5* information regarding copyright ownership.
6*
7* This program and the accompanying materials are made available under the
8* terms of the Apache License Version 2.0 which is available at
9* https://www.apache.org/licenses/LICENSE-2.0
10*
11* SPDX-License-Identifier: Apache-2.0
12*
13* Contributors:
14* Thomas Pfleiderer - documentation
15* *******************************************************************************
16*/
17
18#ifndef SPEED_HAZARD_DETECTION_HPP
19#define SPEED_HAZARD_DETECTION_HPP
20
21#include <cstdint>
22#include <cstring>
23
24namespace autoapiframework {
25namespace speedHazardDetection {
26
27// ============================================================================
28// ENUMS - Based on Eclipse-autoapiframework-Metamodel v0.4.0
29// ============================================================================
30
31enum class ASIL {
32 QM = 0,
33 A = 1,
34 B = 2,
35 C = 3,
36 D = 4
37};
38
39enum class DataQuality {
40 UNINITIALIZED = 0,
41 INVALID = 1,
42 VALID = 2
43};
44
45enum class RunType {
46 INIT = 0,
47 CYCLIC = 1,
48 EVENT = 2,
49 TERMINATE = 3
50};
51
52enum class ProtectionType {
53 NONE = 0,
54 COMPLEMENT = 1,
55 OTHER = 2
56};
57
58enum class FunctionResult {
59 SUCCESS = 0,
60 FAILURE = 1,
61 NOT_AVAILABLE = 2
62};
63
64// ============================================================================
65// DATA INTERFACE STRUCTURES
66// ============================================================================
67
68/**
69 * @struct VehicleSpeed
70 * @brief Current vehicle speed value.
71 *
72 * VSS Path: Vehicle.Speed
73 * Unit: km/h
74 * Range: [0.0, 300.0]
75 * ASIL: B
76 * Update Period: 10ms
77 */
78struct VehicleSpeed {
79 float value; ///< Speed value in km/h
80 DataQuality quality; ///< Data quality indicator
81 uint32_t updateTimestampMs; ///< Last update timestamp in milliseconds
82
83 VehicleSpeed()
84 : value(0.0f), quality(DataQuality::UNINITIALIZED), updateTimestampMs(0) {}
85
86 VehicleSpeed(float val)
87 : value(val), quality(DataQuality::VALID), updateTimestampMs(0) {}
88};
89
90/**
91 * @struct VehicleAccelerationLongitudinal
92 * @brief Longitudinal acceleration used to detect strong acceleration events.
93 *
94 * VSS Path: Vehicle.Acceleration.Longitudinal
95 * Unit: m/s²
96 * Range: [-20.0, 20.0]
97 * ASIL: B
98 * Update Period: 10ms
99 */
100struct VehicleAccelerationLongitudinal {
101 float value; ///< Acceleration value in m/s²
102 DataQuality quality; ///< Data quality indicator
103 uint32_t updateTimestampMs; ///< Last update timestamp in milliseconds
104
105 VehicleAccelerationLongitudinal()
106 : value(0.0f), quality(DataQuality::UNINITIALIZED), updateTimestampMs(0) {}
107
108 VehicleAccelerationLongitudinal(float val)
109 : value(val), quality(DataQuality::VALID), updateTimestampMs(0) {}
110};
111
112/**
113 * @struct VehicleBodyLightsHazardRequest
114 * @brief Hazard warning lights request signal.
115 *
116 * VSS Path: Vehicle.Body.Lights.Hazard.Request
117 * Unit: boolean
118 * ASIL: B
119 * Update Period: 20ms
120 */
121struct VehicleBodyLightsHazardRequest {
122 bool value; ///< Request status: true = activate hazard lights
123 DataQuality quality; ///< Data quality indicator
124 uint32_t updateTimestampMs; ///< Last update timestamp in milliseconds
125
126 VehicleBodyLightsHazardRequest()
127 : value(false), quality(DataQuality::UNINITIALIZED), updateTimestampMs(0) {}
128
129 VehicleBodyLightsHazardRequest(bool val)
130 : value(val), quality(DataQuality::VALID), updateTimestampMs(0) {}
131};
132
133/**
134 * @struct VehicleSpeedQualifier
135 * @brief Quality qualifier for Vehicle.Speed value.
136 *
137 * VSS Path: Vehicle.Speed.Qualifier
138 * Unit: code (enum-based)
139 * ASIL: QM
140 * Update Period: 10ms
141 */
142struct VehicleSpeedQualifier {
143 uint8_t value; ///< Quality code (0-5)
144 DataQuality quality; ///< Data quality indicator
145 uint32_t updateTimestampMs; ///< Last update timestamp in milliseconds
146
147 VehicleSpeedQualifier()
148 : value(0), quality(DataQuality::UNINITIALIZED), updateTimestampMs(0) {}
149
150 VehicleSpeedQualifier(uint8_t val)
151 : value(val), quality(DataQuality::VALID), updateTimestampMs(0) {}
152};
153
154// ============================================================================
155// PARAMETER STRUCTURES
156// ============================================================================
157
158/**
159 * @struct SpeedHazardDetectionParameters
160 * @brief Configuration parameters for SpeedHazardDetection function.
161 */
162struct SpeedHazardDetectionParameters {
163 /// Relative speed increase threshold in percent for forward acceleration
164 float speedHazardForwardThresholdPercent;
165
166 /// Hold time for hazard request after trigger in milliseconds
167 uint32_t hazardRequestDurationMs;
168
169 SpeedHazardDetectionParameters()
170 : speedHazardForwardThresholdPercent(10.0f),
171 hazardRequestDurationMs(3000) {}
172};
173
174// ============================================================================
175// FUNCTION INPUT/OUTPUT CONTEXT
176// ============================================================================
177
178/**
179 * @struct SpeedHazardDetectionInputs
180 * @brief All input signals for the SpeedHazardDetection function.
181 */
182struct SpeedHazardDetectionInputs {
183 VehicleSpeed vehicleSpeed;
184 VehicleAccelerationLongitudinal accelerationLongitudinal;
185 VehicleSpeedQualifier speedQualifier;
186
187 void reset() {
188 vehicleSpeed = VehicleSpeed();
189 accelerationLongitudinal = VehicleAccelerationLongitudinal();
190 speedQualifier = VehicleSpeedQualifier();
191 }
192};
193
194/**
195 * @struct SpeedHazardDetectionOutputs
196 * @brief All output signals for the SpeedHazardDetection function.
197 */
198struct SpeedHazardDetectionOutputs {
199 VehicleBodyLightsHazardRequest hazardRequest;
200 FunctionResult functionStatus;
201
202 SpeedHazardDetectionOutputs()
203 : hazardRequest(), functionStatus(FunctionResult::SUCCESS) {}
204
205 void reset() {
206 hazardRequest = VehicleBodyLightsHazardRequest();
207 functionStatus = FunctionResult::SUCCESS;
208 }
209};
210
211// ============================================================================
212// FUNCTION CONTEXT / STATE
213// ============================================================================
214
215/**
216 * @class SpeedHazardDetectionContext
217 * @brief Internal state and context for SpeedHazardDetection function.
218 *
219 * This structure maintains all internal state variables required for
220 * the cyclic execution of the speed hazard detection algorithm.
221 */
222class SpeedHazardDetectionContext {
223public:
224 // Initialization state
225 bool isInitialized;
226
227 // Previous cycle state
228 float previousSpeed;
229 uint32_t previousSpeedTimestamp;
230
231 // Hazard request latching state
232 bool hazardRequestActive;
233 uint32_t hazardRequestStartTimestamp;
234
235 // Cycle counter
236 uint32_t cycleCounter;
237
238 /**
239 * @brief Constructor - initializes context with default values.
240 */
241 SpeedHazardDetectionContext();
242
243 /**
244 * @brief Reset context to initial state.
245 */
246 void reset();
247
248 /**
249 * @brief Get initialization status.
250 * @return true if function is initialized, false otherwise
251 */
252 bool getInitializationStatus() const;
253
254 /**
255 * @brief Get current cycle count.
256 * @return Current cycle counter value
257 */
258 uint32_t getCycleCount() const;
259};
260
261// ============================================================================
262// FUNCTION INTERFACE
263// ============================================================================
264
265/**
266 * @class SpeedHazardDetection
267 * @brief Static C++ API for Speed Hazard Detection Function.
268 *
269 * Specification: SpeedHazardDetection v1.0.0
270 * Meta Model: Eclipse-autoapiframework-Metamodel v0.4.0
271 *
272 * Description:
273 * Detects rapid acceleration and requests hazard warning lights if the
274 * configured threshold is exceeded.
275 *
276 * Note:
277 * qualityCode is runtime companion information and is therefore not
278 * represented as a static metadata field in the function specification.
279 */
280class SpeedHazardDetection {
281public:
282 /**
283 * @brief Initialize the Speed Hazard Detection function.
284 *
285 * @param context Reference to the function context
286 * @param parameters Reference to the function parameters
287 * @return FunctionResult indicating success or error status
288 *
289 * Run Type: init
290 * ASIL: B
291 *
292 * Initializes internal states and latched outputs. Must be called once
293 * before the first cyclic execution.
294 */
295 static FunctionResult init(
296 SpeedHazardDetectionContext& context,
297 const SpeedHazardDetectionParameters& parameters
298 );
299
300 /**
301 * @brief Execute one cycle of Speed Hazard Detection.
302 *
303 * @param context Reference to the function context
304 * @param parameters Reference to the function parameters
305 * @param inputs Reference to the input signals
306 * @param outputs Reference to the output signals (will be updated)
307 * @return FunctionResult indicating success or error status
308 *
309 * Run Type: cyclic
310 * ASIL: B
311 * Cycle Time: 20ms
312 *
313 * Evaluates inputs and calculates hazard request output.
314 * The algorithm:
315 * 1. Validates input signal quality
316 * 2. Calculates relative speed increase since last cycle
317 * 3. Compares against configured threshold
318 * 4. Activates hazard request if threshold exceeded
319 * 5. Maintains hazard request latch for configured duration
320 */
321 static FunctionResult step(
322 SpeedHazardDetectionContext& context,
323 const SpeedHazardDetectionParameters& parameters,
324 const SpeedHazardDetectionInputs& inputs,
325 SpeedHazardDetectionOutputs& outputs
326 );
327
328 /**
329 * @brief Terminate the Speed Hazard Detection function.
330 *
331 * @param context Reference to the function context
332 * @param outputs Reference to the output signals (will be updated)
333 * @return FunctionResult indicating success or error status
334 *
335 * Run Type: terminate
336 * ASIL: QM
337 *
338 * Shutdown cleanup for deterministic deactivation. Ensures all
339 * outputs are reset to safe defaults.
340 */
341 static FunctionResult terminate(
342 SpeedHazardDetectionContext& context,
343 SpeedHazardDetectionOutputs& outputs
344 );
345};
346
347} // namespace speedHazardDetection
348} // namespace autoapiframework
349
350#endif // SPEED_HAZARD_DETECTION_HPP