cb82ff74c8
Verified the actual PDF cover pages: FMD-91 (ADA259655) and NPRD-91 (ADA242083) carry "© 1991, IIT Research Institute. All Rights Reserved" plus a DoD "distribution unlimited" statement. The distribution statement permits obtaining/reading the document, NOT reproducing its tables in a commercial product — treat like DIN/ISO. The earlier P1 docs wrongly labelled them "public domain" (an unverified research claim). - Correct the licence in fmea_data_sources.go note + mil_std_1629a_fmeca.md + fmd91_nprd_failure_modes.md (read-reference only; tables NOT reproduced). - The bp_iace_fmea_kb collection was deleted from Qdrant (the mislabelled doc removed); methodology docs (MIL-STD/NASA, genuine PD) not re-ingested pending review. The Go methodology module (own scales, MIL-STD-anchored) is unaffected and stays. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
101 lines
4.9 KiB
Go
101 lines
4.9 KiB
Go
package iace
|
||
|
||
// Open, public-domain methodology anchors for the auto-FMEA (P1 of the FMEA
|
||
// build plan). Every scale here is anchored on US-Government PUBLIC-DOMAIN
|
||
// sources — MIL-STD-882E (system-safety severity/probability) and MIL-STD-1629A
|
||
// (FMECA criticality). The 1-10 projection is BreakPilot's OWN scale; NO
|
||
// AIAG-VDA / SAE J1739 / IEC 60812 table is reproduced (those are copyrighted).
|
||
// Failure-rate (λ) and failure-mode-ratio (α) values come later from NPRD-91 /
|
||
// FMD-91 (RAC, public domain). See project_fmea_build_plan / opensource-fmea-sources.
|
||
|
||
// FMEADataSourcesNote is the audit/attribution line for the FMEA methodology.
|
||
const FMEADataSourcesNote = "FMEA-Methodik + Skalen verankert an US-Gov Public Domain " +
|
||
"(MIL-STD-1629A FMECA-Kritikalität, MIL-STD-882E Severity/Probability, NASA RCM, " +
|
||
"MIL-HDBK-217F). Das 1-10-Mapping ist BreakPilot-eigen. FMD-91/NPRD-91 (RAC) sind " +
|
||
"© IITRI „All Rights Reserved\" — nur Lese-Referenz, Tabellen werden NICHT reproduziert. " +
|
||
"KEINE AIAG-VDA/SAE/IEC-Tabelle reproduziert."
|
||
|
||
// FMEASeverityBand maps a MIL-STD-882E Table-I severity CATEGORY to our 1-10 S.
|
||
type FMEASeverityBand struct {
|
||
Category string `json:"category"` // "I".."IV"
|
||
LabelDE string `json:"label_de"`
|
||
Desc string `json:"desc"` // public-domain threshold (injury/$)
|
||
Severity int `json:"severity"` // our 1-10 projection
|
||
}
|
||
|
||
// MILStd882Severity returns the four MIL-STD-882E severity categories, ordered
|
||
// most→least severe, with our 1-10 projection. (882E is US-Gov public domain.)
|
||
func MILStd882Severity() []FMEASeverityBand {
|
||
return []FMEASeverityBand{
|
||
{Category: "I", LabelDE: "Katastrophal", Desc: "Tod, dauerhafte Vollinvalidität oder irreversibler schwerer Umweltschaden", Severity: 10},
|
||
{Category: "II", LabelDE: "Kritisch", Desc: "Dauerhafte Teilinvalidität oder Krankenhausaufenthalt mehrerer Personen", Severity: 7},
|
||
{Category: "III", LabelDE: "Marginal", Desc: "Verletzung/Erkrankung mit Ausfalltag(en)", Severity: 4},
|
||
{Category: "IV", LabelDE: "Vernachlässigbar", Desc: "Geringfügige Verletzung ohne Ausfalltag", Severity: 2},
|
||
}
|
||
}
|
||
|
||
// FMEAOccurrenceBand maps a MIL-STD-882E Table-II probability LEVEL to our 1-10
|
||
// O. LambdaMax is the upper bound (failures per operating hour) we use to bin a
|
||
// computed mode rate; the per-hour calibration is ours, anchored on 882E order.
|
||
type FMEAOccurrenceBand struct {
|
||
Level string `json:"level"` // "A".."F"
|
||
LabelDE string `json:"label_de"`
|
||
LambdaMax float64 `json:"lambda_max"` // inclusive upper bound, /h (0 ⇒ eliminated)
|
||
Occurrence int `json:"occurrence"` // our 1-10 projection
|
||
}
|
||
|
||
// MILStd882Probability returns the six MIL-STD-882E probability levels (individual
|
||
// item), ordered most→least frequent, with our 1-10 projection + a per-hour
|
||
// failure-rate band used by OccurrenceFromRate.
|
||
func MILStd882Probability() []FMEAOccurrenceBand {
|
||
return []FMEAOccurrenceBand{
|
||
{Level: "A", LabelDE: "Häufig", LambdaMax: 1, Occurrence: 10}, // ≥ 1e-1
|
||
{Level: "B", LabelDE: "Wahrscheinlich", LambdaMax: 1e-1, Occurrence: 8}, // 1e-2 .. 1e-1
|
||
{Level: "C", LabelDE: "Gelegentlich", LambdaMax: 1e-2, Occurrence: 6}, // 1e-3 .. 1e-2
|
||
{Level: "D", LabelDE: "Selten", LambdaMax: 1e-3, Occurrence: 4}, // 1e-6 .. 1e-3
|
||
{Level: "E", LabelDE: "Unwahrscheinlich", LambdaMax: 1e-6, Occurrence: 2},
|
||
{Level: "F", LabelDE: "Ausgeschlossen", LambdaMax: 0, Occurrence: 1},
|
||
}
|
||
}
|
||
|
||
// OccurrenceFromRate maps a mode failure rate (λp·α, failures per operating hour)
|
||
// onto the 1-10 occurrence axis via the MIL-STD-882E probability bands. A rate
|
||
// ≤ 0 is "eliminated" (1); anything ≥ 0.1/h saturates at "frequent" (10).
|
||
func OccurrenceFromRate(modeRatePerHour float64) int {
|
||
if modeRatePerHour <= 0 {
|
||
return 1
|
||
}
|
||
bands := MILStd882Probability()
|
||
// bands[0] (A) has the highest threshold; walk most→least frequent and take
|
||
// the first band whose lower edge the rate clears.
|
||
for i := 0; i < len(bands)-1; i++ {
|
||
lowerEdge := bands[i+1].LambdaMax // edge between band i and i+1
|
||
if modeRatePerHour > lowerEdge {
|
||
return bands[i].Occurrence
|
||
}
|
||
}
|
||
return bands[len(bands)-2].Occurrence // E (improbable) for tiny positive rates
|
||
}
|
||
|
||
// SeverityForCategory returns our 1-10 severity for a MIL-STD-882E category
|
||
// ("I".."IV"); 0 if unknown.
|
||
func SeverityForCategory(category string) int {
|
||
for _, b := range MILStd882Severity() {
|
||
if b.Category == category {
|
||
return b.Severity
|
||
}
|
||
}
|
||
return 0
|
||
}
|
||
|
||
// CriticalityCm computes the MIL-STD-1629A modal criticality
|
||
// Cm = λp · α · β · t, where λp = part failure rate (/h), α = failure-mode ratio
|
||
// (fraction of part failures in this mode), β = conditional probability the mode
|
||
// produces the analysed effect, t = operating hours. Fully public-domain method.
|
||
func CriticalityCm(lambdaP, alpha, beta, operatingHours float64) float64 {
|
||
if lambdaP < 0 || alpha < 0 || beta < 0 || operatingHours < 0 {
|
||
return 0
|
||
}
|
||
return lambdaP * alpha * beta * operatingHours
|
||
}
|