feat: Safety Goals + Drive-Away-Assist + vollst. Traceability
Validate / build-test (macos-latest) (push) Failing after 4s
Validate / build-test (windows-latest) (push) Failing after 17s
Validate / build-test (ubuntu-latest) (push) Successful in 16s
Validate / reports (push) Has been skipped
Release / release (push) Successful in 48s

Neue Layer:
- safety/sg/SG-001..005 als eigene Doorstop-Items (ASIL D/D/A/C/B)
- SYS-Reqs verlinken nach oben auf SG via frontmatter
- Kette ist jetzt: SG -> SYS -> SA, SWE -> SWA -> Code (@arch) + Test (@reqs)

Drive-Away-Assist im Safety Manager:
- SWE-011 (Anfahrabsicht erkennen) implementiert
- SWE-012 (Sicherheits-Check Tuer + Gurt) implementiert
- Neuer State SAFETY_DRIVE_AWAY + safety_mgr_release_requested()
- SafetyInputs erweitert um gas_pedal_percent, gear_in_drive,
  door_closed, seatbelt_fastened
- 5 neue Tests (DRIVE_AWAY armed/blocked/end-conditions)
- Test-Header @reqs erweitert auf SWE-007..012

traceability.py erweitert:
- SG als neuer Top-Level
- Code-Mapping-Check: @arch im Header von src/*.c muss SWA-id matchen
- Test-Mapping-Check: @reqs im Header der Tests muss alle SWE der
  zugehoerigen SWA abdecken
- HTML zeigt 7 Spalten: SG | SYS | SA | SWE | SWA | Code | Test
- 2 zusaetzliche Tabellen: Code->Arch und Test->Reqs

test_apply_controller.c:
- @reqs Header um SWE-005 ergaenzt (war funktional drin, nur Tag fehlte)

Counts:
- 55 doorstop-Items (war 50)
- 46 Unit-Tests (war 41)
- Traceability vollstaendig in beide Richtungen
This commit is contained in:
Stefan Lohmaier
2026-05-12 01:50:12 -07:00
parent 17910835ad
commit c610cc023c
20 changed files with 998 additions and 214 deletions
+54 -8
View File
@@ -1,12 +1,13 @@
/**
* @file safety_manager.c
* @brief Safety Manager — Hill-Hold + Auto-Apply Logik.
* @brief Safety Manager — Hill-Hold, Auto-Apply, Drive-Away-Assist.
*
* @arch SWA-001
* @reqs SWE-007 SWE-008 SWE-009 SWE-010
* @reqs SWE-007 SWE-008 SWE-009 SWE-010 SWE-011 SWE-012
*
* ASIL: D. Diese Komponente entscheidet, wann der Apply Controller eine
* Apply-Anforderung erhaelt (Hill-Hold-Uebergabe, Auto-Apply bei Motor-Aus).
* Apply- oder Release-Anforderung erhaelt (Hill-Hold-Uebergabe, Auto-Apply
* bei Motor-Aus, Drive-Away-Assist).
* Aenderungen erfordern Technical Review mit 2 Approvals.
*/
#include <stddef.h>
@@ -17,6 +18,7 @@ typedef struct {
SafetyState state;
uint16_t ticks_in_state; /* 50ms-Ticks im aktuellen Zustand */
bool apply_requested;
bool release_requested;
} SafetyCtx;
static SafetyCtx s_ctx;
@@ -42,11 +44,30 @@ static bool grade_steep(const SafetyInputs* in)
return g > SAFETY_HILLHOLD_GRADE_PCT;
}
/**
* @reqs SWE-011 (Anfahrabsicht erkennen)
*/
static bool drive_intent(const SafetyInputs* in)
{
return (in->gas_pedal_percent > SAFETY_DRIVE_INTENT_GAS_PCT)
&& in->gear_in_drive
&& in->engine_running;
}
/**
* @reqs SWE-012 (Sicherheits-Check vor Auto-Release)
*/
static bool drive_away_safety_ok(const SafetyInputs* in)
{
return in->door_closed && in->seatbelt_fastened;
}
EpbStatus safety_mgr_init(void)
{
s_ctx.state = SAFETY_IDLE;
s_ctx.ticks_in_state = 0U;
s_ctx.apply_requested = false;
s_ctx.state = SAFETY_IDLE;
s_ctx.ticks_in_state = 0U;
s_ctx.apply_requested = false;
s_ctx.release_requested = false;
return EPB_OK;
}
@@ -60,8 +81,9 @@ void safety_mgr_step_50ms(const SafetyInputs* in)
++s_ctx.ticks_in_state;
}
/* Default: no apply request unless explicitly set below. */
s_ctx.apply_requested = false;
/* Default: no apply/release request unless explicitly set below. */
s_ctx.apply_requested = false;
s_ctx.release_requested = false;
switch (s_ctx.state) {
case SAFETY_IDLE:
@@ -75,6 +97,13 @@ void safety_mgr_step_50ms(const SafetyInputs* in)
&& in->current_state != EPB_STATE_APPLIED
&& in->current_state != EPB_STATE_APPLYING) {
enter(SAFETY_AUTO_APPLY_ARMED);
break;
}
/* @reqs SWE-011 + SWE-012: Drive-Away-Assist */
if (in->current_state == EPB_STATE_APPLIED
&& drive_intent(in) && drive_away_safety_ok(in)) {
s_ctx.release_requested = true;
enter(SAFETY_DRIVE_AWAY);
}
break;
@@ -122,6 +151,18 @@ void safety_mgr_step_50ms(const SafetyInputs* in)
}
break;
case SAFETY_DRIVE_AWAY:
/* Beendet, wenn die Bremse geloest wurde oder Vorbedingungen nicht mehr ok. */
if (in->current_state == EPB_STATE_RELEASED
|| in->current_state == EPB_STATE_RELEASING) {
enter(SAFETY_IDLE);
} else if (!drive_intent(in) || !drive_away_safety_ok(in)) {
enter(SAFETY_IDLE);
} else {
s_ctx.release_requested = true;
}
break;
default:
enter(SAFETY_IDLE);
break;
@@ -133,6 +174,11 @@ bool safety_mgr_apply_requested(void)
return s_ctx.apply_requested;
}
bool safety_mgr_release_requested(void)
{
return s_ctx.release_requested;
}
SafetyState safety_mgr_get_state(void)
{
return s_ctx.state;
+16 -5
View File
@@ -1,20 +1,23 @@
/**
* @file safety_manager.h
* @brief Safety Manager — Hill-Hold + Auto-Apply Logik.
* @brief Safety Manager — Hill-Hold, Auto-Apply, Drive-Away-Assist.
*
* @arch SWA-001
* @reqs SWE-007 SWE-008 SWE-009 SWE-010
* @reqs SWE-007 SWE-008 SWE-009 SWE-010 SWE-011 SWE-012
*
* ASIL: D.
*
* State Machine:
* IDLE --(engine_off & v<0.5)--> AUTO_APPLY_ARMED
* IDLE --(engine_off & v<0.5 & !APPLIED)--> AUTO_APPLY_ARMED
* AUTO_APPLY_ARMED --(40 * 50ms = 2s)--> AUTO_APPLY_TRIGGERED
* AUTO_APPLY_TRIGGERED --(state==APPLIED)--> IDLE
*
* IDLE --(grade>5% & v<0.5 & brake)--> HILL_HOLD_ARMED
* HILL_HOLD_ARMED --(!brake)--> HILL_HOLD_ACTIVE
* HILL_HOLD_ACTIVE --(v>2 km/h | state==APPLIED)--> IDLE
*
* IDLE --(APPLIED & gas>10% & gear_drive & engine & door & belt)--> DRIVE_AWAY
* DRIVE_AWAY --(state==RELEASED|RELEASING)--> IDLE
*/
#ifndef SAFETY_MANAGER_H
#define SAFETY_MANAGER_H
@@ -26,7 +29,8 @@ typedef enum {
SAFETY_HILL_HOLD_ARMED = 1,
SAFETY_HILL_HOLD_ACTIVE = 2,
SAFETY_AUTO_APPLY_ARMED = 3,
SAFETY_AUTO_APPLY_TRIGGERED = 4
SAFETY_AUTO_APPLY_TRIGGERED = 4,
SAFETY_DRIVE_AWAY = 5
} SafetyState;
typedef struct {
@@ -34,7 +38,12 @@ typedef struct {
bool brake_pedal_pressed;
float vehicle_speed_kmh;
float grade_percent;
EpbState current_state; /* aus Apply Controller */
EpbState current_state; /* aus Apply Controller */
/* Drive-Away-Assist Inputs (SWE-011, SWE-012) */
float gas_pedal_percent; /* 0..100 */
bool gear_in_drive; /* Vorwaerts oder Rueckwaerts */
bool door_closed; /* Fahrertuer */
bool seatbelt_fastened; /* Fahrer-Gurt */
} SafetyInputs;
/* Schwellwerte als Konstanten, damit Tests darauf zugreifen koennen. */
@@ -42,10 +51,12 @@ typedef struct {
#define SAFETY_STANDSTILL_KMH 0.5f
#define SAFETY_RELEASE_KMH 2.0f
#define SAFETY_HILLHOLD_GRADE_PCT 5.0f
#define SAFETY_DRIVE_INTENT_GAS_PCT 10.0f /* Gaspedal > 10% = Anfahrabsicht */
EpbStatus safety_mgr_init(void);
void safety_mgr_step_50ms(const SafetyInputs* in);
bool safety_mgr_apply_requested(void);
bool safety_mgr_release_requested(void); /* Drive-Away-Assist */
SafetyState safety_mgr_get_state(void);
#endif /* SAFETY_MANAGER_H */