Posts Tagged with "FTA"

既に発行済みのブログであっても適宜修正・追加することがあります。
We may make changes and additions to blogs already published.
posted by sakurai on February 6, 2025 #943

ChatGPTに前稿のRBDを読ませたところ、次のMARDを取得しました。 TEST.BEDTEST.FTDの3ファイルは同一なので省略します。

TEST.FTL

*Saphire 8.2.9
TEST, TOP =
TOP AND IF_FAIL SM_FAIL
IF_FAIL OR APS_SENSOR TPS_SENSOR FCAN_LINE MAIN_MCU MOTOR_DRV MOTOR THROTTLE
SM_FAIL OR COV_REM SM_PATH
SM_PATH AND COV_90 SM_EXPAND
SM_EXPAND OR DETECT_FAIL CONTROL_FAIL
DETECT_FAIL AND LANE_APS LANE_TPS LANE_DIAG LANE_SUB
LANE_APS OR APS_SENSOR MAIN_MCU
LANE_TPS OR TPS_SENSOR MAIN_MCU
LANE_DIAG OR DRIVER_DIAG MAIN_MCU
LANE_SUB OR SUB_MCU
CONTROL_FAIL OR BLOCK_PAR RELAY_DRV RELAY
BLOCK_PAR AND MAIN_MCU SUB_MCU

TEST.GTD

*Saphire 8.2.9
TEST=
* Name , Description, Project
TOP , TEST , ,TEST
IF_FAIL , IF fail , ,TEST
SM_FAIL , SM fail , ,TEST
SM_PATH , SM coverage path , ,TEST
SM_EXPAND , SM expanded , ,TEST
DETECT_FAIL , detection fail , ,TEST
LANE_APS , lane APS , ,TEST
LANE_TPS , lane TPS , ,TEST
LANE_DIAG , lane DIAG , ,TEST
LANE_SUB , lane SUB , ,TEST
CONTROL_FAIL , control fail , ,TEST
BLOCK_PAR , parallel block , ,TEST

これらをSaphireに取り込んだところ、図943.1のようなFTが自動生成されました。

$$\img[-1.35em]{/images/withinseminar.png}$$

なお、本稿はRAMS 2026に投稿予定のため一部を秘匿していますが、論文公開後の2026年2月頃に開示予定です。


左矢前のブログ 次のブログ右矢

posted by sakurai on February 5, 2025 #942

さてMCSを取ることにより、このアーキテクチャの欠点が見えてきました。

図%%.1
図942.1 MCSのTop 3

積項No.1とNo.2の論理和を取れば、 $$ \mathtt{MAIN\_MCU}\cdot \mathtt{COV\_90}+\mathtt{MAIN\_MCU}\cdot \mathtt{COV\_REM}\\=\mathtt{MAIN\_MCU}\cdot \mathtt{COV\_90}+\mathtt{MAIN\_MCU}\cdot\overline{\mathtt{COV\_90}}\\=\mathtt{MAIN\_MCU} $$

積項No.1とNo.2の割合を加えれば89.04+9.89=99.29。このように、約99%以上のPMHFがメインマイコンとなっており、その理由は先の通りメインマイコンがIFパスとSMパスに存在するため、単一故障で両方のパス共に故障するためです。

これを避けるため、サブマイコンがメインマイコンの故障を検出したらいきなりリレーをオフするようにパスを変更します。

$$\img[-1.35em]{/images/withinseminar.png}$$

図942.2 修正後のアーキテクチャ

なお、本稿はRAMS 2026に投稿予定のため一部を秘匿していますが、論文公開後の2026年2月頃に開示予定です。


左矢前のブログ 次のブログ右矢

Fault treeの自動生成 (24)

posted by sakurai on January 31, 2025 #941

特にSMのパスの論理が分かりにくいので解説します。図941.1は前稿の図940.1のうちSM部を抜き出した図です。

$$\img[-1.35em]{/images/withinseminar.png}$$

図941.1 SM部のRBD

図で見るように、SM部前半の検出手段は次の4つが存在します。

  • APSの情報を受けTPSからのズレをメインマイコンが故障検出
  • TPSの情報を受けAPSからのズレをメインマイコンが故障検出
  • DRIVER_DIAGの故障診断をメインマイコンが故障検出
  • サブマイコンによるメインマイコンの故障検出

RBDで書くとこのように、EGASシステムはいずれの故障が検出されてもORされ、リレーによりモータ電源が遮断される安全なシステムであると言えます。

一方FTでは動作ではなく故障を伝えるので、論理が反転となりORはANDになります。 RBDにおいては動作を

「いずれか一つの故障が検出されたら、モータ電源が遮断される」

と書き、FTでは

「全ての故障が起きた場合のみ、モータ電源が遮断されない」

と故障を書くわけです。つまりSMの動作ではなく、SMの故障について考えなければなりません。従って、図941.2のように、全ての故障検出のAND関係となります。

図%%.2
図941.2 SM検出部のFT

ただしSM部後半の手段のほうはこれと異なり、メインマイコンからリレードライバ経由でリレーが直列になっているため、メインマイコンかリレードライバのいずれかの故障でモータ電源が遮断されないOR関係となります。

結果として、SM部の前半のANDと後半のORを組み合わせると図941.3のようになります。これも手で構成したのではなく、ChatGPT により自動生成されたものです。 $$\img[-1.35em]{/images/withinseminar.png}$$

図941.3 SM部のFT

なお、本稿はRAMS 2026に投稿予定のため一部を秘匿していますが、論文公開後の2026年2月頃に開示予定です。


左矢前のブログ 次のブログ右矢

Fault treeの自動生成 (23)

posted by sakurai on January 30, 2025 #940

図940.1にSaphireで取得したMCSを示します。

図%%.1
図940.1 生成されたFTのMCS

Saphireで生成したcut setの表に対してPMHFの欄を追加し、かつ故障率の項を黄色で塗っています。#7~10のように黄色行が2段になっている積項はDPFを表します。万一DPF項が大きければ2nd SMの効果も加えなければなりませんが、割合の欄がいずれも0.01%未満なことからわかるように、DPFが全体に占める割合は非常に小さいことが多く、通常は2nd SMの効果は不要です。今後はこのような単項で0.01%未満の積項はMCS表から省略します。

さて、このMCSを分析します。

#1, #2の論理式を加えて見ると、次のようにMAIN_MCUはSMにより全く保護されていないことがわかります。

$$ \mathtt{MAIN\_MCU}\cdot \mathtt{COV\_90}+\mathtt{MAIN\_MCU}\cdot \mathtt{COV\_REM}\\=\mathtt{MAIN\_MCU}\cdot \mathtt{COV\_90}+\mathtt{MAIN\_MCU}\cdot\overline{\mathtt{COV\_90}}\\=\mathtt{MAIN\_MCU} $$

#1はSMが故障しているため保護されない場合であり、#2はSMが動作していても保護されない場合です。いずれにしてもSMにより保護されていません。

#2は通常のSMの動作であるものの、#1はIFとSMの両方のパスが故障しているので、これはいわゆるCCFでSMの効果を無効にします。

ちなみにこれは論理圧縮であるため、Saphireで実施しても良さそうですが、やってくれません。$\mathtt{COV\_90}$と$\mathtt{COV\_REM}$は$\mathtt{DC}$と$\mathtt{1-DC}$の関係にあるのですが、それぞれのイベントが無関係だからかと思い、$\mathtt{COV\_90}$と$\overline{\mathtt{COV\_90}}$にしても同じでした。

図940.2に#1のパストレース図を示します。

$$\img[-1.35em]{/images/withinseminar.png}$$

図940.2 MAIN_MCUからのパストレース#1

図940.3に#2のパストレース図を示します。

$$\img[-1.35em]{/images/withinseminar.png}$$

図940.3 MAIN_MCUからのパストレース#2

なお、本稿はRAMS 2026に投稿予定のため一部を秘匿していますが、論文公開後の2026年2月頃に開示予定です。


左矢前のブログ 次のブログ右矢

Fault treeの自動生成 (22)

posted by sakurai on January 29, 2025 #939

一連のスレッドですがタイトルは以前の記事から引き継いでいます。

それではEGASアーキテクチャのブロック図を図939.1に示すので、MARDを提供して下さい。

$$\img[-1.35em]{/images/withinseminar.png}$$

図939.1 RBD

図939.1を読み取ったChatGPTの生成したMARDファイルを以下に示します。

TEST.BED

*Saphire 8.2.9
TEST =
* Name , Descriptions , Project
APS_SENSOR , APS sensor (1FIT) , TEST
TPS_SENSOR , TPS sensor (1FIT) , TEST
FCAN_LINE , FCAN line (10FIT) , TEST
MAIN_MCU , Main MCU (200FIT) , TEST
MOTOR_DRV , Motor driver (10FIT) , TEST
DRIVER_DIAG , Driver DIAG (1FIT) , TEST
SUB_MCU , Sub MCU (150FIT) , TEST
RELAY_DRV , Relay driver (10FIT) , TEST
COV_REM , SM leftover (1-DC=10%) , TEST
COV_90 , SM coverage (DC=90%) , TEST

TEST.BEI

*Saphire 8.2.9
TEST =
* Name ,FdT,UdC,UdT,UdValue, Prob, Lambda, Tau, Mission, Init,PF,UdValue2,Calc. Prob,Freq,Analysis Type,Phase Type,Project
APS_SENSOR ,3, , , , ,1.0E-009, ,1.0E+004, , , ,1.0E-005, ,RANDOM,CD,TEST
TPS_SENSOR ,3, , , , ,1.0E-009, ,1.0E+004, , , ,1.0E-005, ,RANDOM,CD,TEST
FCAN_LINE ,3, , , , ,1.0E-008, ,1.0E+004, , , ,1.0E-004, ,RANDOM,CD,TEST
MAIN_MCU ,3, , , , ,2.0E-007, ,1.0E+004, , , ,2.0E-003, ,RANDOM,CD,TEST
MOTOR_DRV ,3, , , , ,1.0E-008, ,1.0E+004, , , ,1.0E-004, ,RANDOM,CD,TEST
DRIVER_DIAG ,3, , , , ,1.0E-009, ,1.0E+004, , , ,1.0E-005, ,RANDOM,CD,TEST
SUB_MCU ,3, , , , ,1.5E-007, ,1.0E+004, , , ,1.5E-003, ,RANDOM,CD,TEST
RELAY_DRV ,3, , , , ,1.0E-008, ,1.0E+004, , , ,1.0E-004, ,RANDOM,CD,TEST
COV_REM ,1, , , ,1.0E-001, , , , , , ,1.0E-001, ,RANDOM,CD,TEST
COV_90 ,1, , , ,9.0E-001, , , , , , ,9.0E-001, ,RANDOM,CD,TEST

TEST.FTD

TEST =
* Name , Description, SubTree, Alternate, Project
TOP , TEST , , , TEST

TEST.FTL

TEST, TOP =
TOP AND IF_FAIL SM_FAIL
IF_FAIL OR APS_SENSOR TPS_SENSOR FCAN_LINE MAIN_MCU MOTOR_DRV
SM_FAIL OR COV_REM SM_PATH
SM_PATH AND COV_90 SM_EXPAND
SM_EXPAND OR DETECT_FAIL CTRL_FAIL
DETECT_FAIL AND APS_SENSOR TPS_SENSOR DRIVER_DIAG SUB_MCU
CTRL_FAIL OR MAIN_MCU RELAY_DRV

TEST.GTD

TEST=
* Name , Description, Project
TOP , TEST , ,TEST
IF_FAIL , IF fail , ,TEST
SM_FAIL , SM fail , ,TEST
SM_PATH , coverage path , ,TEST
SM_EXPAND , SM expand , ,TEST
DETECT_FAIL , detection fail , ,TEST
CTRL_FAIL , control fail , ,TEST

図939.2にこれらのMARDをSpahireにロードし生成したFTを示します。

$$\img[-1.35em]{/images/withinseminar.png}$$

図939.2 生成されたFT

なお、本稿はRAMS 2026に投稿予定のため一部を秘匿していますが、論文公開後の2026年2月頃に開示予定です。


左矢前のブログ 次のブログ右矢

Fault treeの自動生成 (21)

posted by sakurai on January 20, 2025 #932

次に、IFやSMを単一エレメントではなく複数エレメントのグループとします。これは実際には基本形のFTに対してIFやSMの部分はBEではなくサブツリーが配置されるため、その処理を行わせるためのAIに対する学習となります。

図%%.1
図932.1 RBD

図932.1を読み取ったChatGPTの生成したMARDファイルを以下に示します。

TEST.BED

*Saphire 8.2.9
TEST =
* Name , Descriptions , Project
A , A fault (20FIT) , TEST
B , B fault (40FIT) , TEST
D , D fault (5FIT) , TEST
E , E fault (10FIT) , TEST
SM_IF_COVREM , SM_IF coverage leftover (1-DC=40%) , TEST
SM_IF_COV , SM_IF coverage (DC=60%) , TEST

TEST.BEI

*Saphire 8.2.9
TEST =
* Name ,FdT,UdC,UdT,UdValue, Prob, Lambda, Tau, Mission, Init,PF,UdValue2,Calc. Prob,Freq,Analysis Type,Phase Type,Project
A ,3, , , , ,2.0E-008, ,1.0E+005, , , ,2.0E-003, ,RANDOM,CD,TEST
B ,3, , , , ,4.0E-008, ,1.0E+005, , , ,4.0E-003, ,RANDOM,CD,TEST
D ,3, , , , ,5.0E-009, ,1.0E+005, , , ,5.0E-004, ,RANDOM,CD,TEST
E ,3, , , , ,1.0E-008, ,1.0E+005, , , ,1.0E-003, ,RANDOM,CD,TEST
SM_IF_COVREM ,1, , , ,4.0E-001, , , , , , ,4.0E-001, ,RANDOM,CD,TEST
SM_IF_COV ,1, , , ,6.0E-001, , , , , , ,6.0E-001, ,RANDOM,CD,TEST

TEST.FTD

TEST =
* Name , Description, SubTree, Alternate, Project
TOP , TEST , , , TEST

TEST.FTL

TEST, TOP =
TOP AND IF SM_IF
IF OR A B
SM_IF OR SM_IF_COVREM DPF
DPF AND SM_IF_COV SM_IF_GROUP
SM_IF_GROUP OR D E

TEST.GTD

TEST=
* Name , Description, Project
TOP , TEST , ,TEST
IF , IF Subtree , ,TEST
SM_IF , SM_IF , ,TEST
DPF , DPF , ,TEST
SM_IF_GROUP , SM_IF Subtree , ,TEST

図932.2にこれらのMARDをSpahireにロードし生成したFTを示します。

$$\img[-1.35em]{/images/withinseminar.png}$$

図932.2 生成されたFT

図932.3にSaphireで取得したMCSを示します。

図%%.3
図932.3 生成されたFTのMCS

Saphireで生成したcut setの表に対してPMHFの欄を追加し、かつ故障率の項を黄色で塗っています。これによりSPF/RFかDPFかが容易に理解されます。

なお、本稿はRAMS 2026に投稿予定のため一部を秘匿していますが、論文公開後の2026年2月頃に開示予定です。


左矢前のブログ 次のブログ右矢

Fault treeの自動生成 (20)

posted by sakurai on January 17, 2025 #931

前稿のExcelの整形マクロはChatGPTにより作成して貰ったものですが、備忘のため貼り付けておきます。

Option Explicit

Sub SampleMacro_Final()

    Dim ws As Worksheet
    Set ws = ActiveSheet  ' カレントシート

    '----------------------------------------------------------------------
    ' (A) まず、B列削除「前」のシートで C列(5行目以降)の最終行を求める
    '     ここをレコードの最終行とする。
    '----------------------------------------------------------------------
    Dim lastRow As Long
    With ws
        lastRow = .Cells(.Rows.Count, "C").End(xlUp).Row
    End With

    If lastRow < 5 Then
        MsgBox "C列の5行目以降にデータがありません。処理を中断します。"
        Exit Sub
    End If

    '----------------------------------------------------------------------
    ' (1) A6:A(lastRow) を数値化
    '----------------------------------------------------------------------
    With ws.Range("A6:A" & lastRow)
        .NumberFormat = "General"
        .Value = .Value
    End With

    '----------------------------------------------------------------------
    ' (2) B列を削除
    '----------------------------------------------------------------------
    ws.Columns("B").Delete

    '----------------------------------------------------------------------
    ' (3) B5:B(lastRow) → 旧C列 の内容を数値化
    '----------------------------------------------------------------------
    With ws.Range("B5:B" & lastRow)
        .NumberFormat = "General"
        .Value = .Value
    End With

    '----------------------------------------------------------------------
    ' (4) C5:C(lastRow) → 旧D列 の内容を数値化
    '----------------------------------------------------------------------
    With ws.Range("C5:C" & lastRow)
        .NumberFormat = "General"
        .Value = .Value
    End With

    '----------------------------------------------------------------------
    ' (5) グリッド線のチェックを外す
    '----------------------------------------------------------------------
    ActiveWindow.DisplayGridlines = False

    '----------------------------------------------------------------------
    ' (6) A4:F4 に罫線 & グレー15% & 中央揃え ほか見出し設定
    '     - ボールド解除(.Font.Bold = False)
    '     - B4セルを"Prob" に
    '     - F4セルに「PMHF」+改行+「[FIT]」
    '----------------------------------------------------------------------
    With ws.Range("A4:F4")
        .Borders.LineStyle = xlContinuous
        .Borders.Weight = xlThin
        .Borders(xlInsideVertical).LineStyle = xlContinuous
        .Borders(xlInsideVertical).Weight = xlThin
        .Borders(xlInsideHorizontal).LineStyle = xlContinuous
        .Borders(xlInsideHorizontal).Weight = xlThin
        .Interior.ColorIndex = 15
        .HorizontalAlignment = xlCenter         ' 横方向を中央揃え
        .VerticalAlignment = xlVAlignCenter     ' 縦方向を中央揃え
        .Font.Bold = False                      ' ★ボールドを外す
    End With

    ' ★ B4セルを"Prob"に
    ws.Range("B4").Value = "Prob"

    ' ★ F4セルは改行入りで"PMHF\n[FIT]"
    ws.Range("F4").Value = "PMHF" & Chr(10) & "[FIT]"
    ws.Range("F4").WrapText = True

    '----------------------------------------------------------------------
    ' (7) A5:F5 を罫線(背景は標準)、揃えはあとでまとめる
    '----------------------------------------------------------------------
    With ws.Range("A5:F5")
        .Borders.LineStyle = xlContinuous
        .Borders.Weight = xlThin
        .Borders(xlInsideVertical).LineStyle = xlContinuous
        .Borders(xlInsideVertical).Weight = xlThin
        .Borders(xlInsideHorizontal).LineStyle = xlContinuous
        .Borders(xlInsideHorizontal).Weight = xlThin
    End With

    '----------------------------------------------------------------------
    ' A列が "total" or 数値 → F列に =B列/1E4*1E9 (小数点1桁表示)
    ' 対象は 行5~lastRow
    '----------------------------------------------------------------------
    Dim r As Long
    Dim valA As Variant
    For r = 5 To lastRow
        valA = ws.Range("A" & r).Value
        If LCase(valA) = "total" Or (IsNumeric(valA) And Not IsEmpty(valA)) Then
            ws.Range("F" & r).Formula = "=B" & r & "/1E4*1E9"
            ws.Range("F" & r).NumberFormat = "0.0"
        End If
    Next r

    '----------------------------------------------------------------------
    ' (8)~(10) グループごとに "外枠のみ" 罫線 → 行6~lastRow
    '----------------------------------------------------------------------
    Dim i As Long, j As Long
    Dim dataA As Variant, dataD As Variant
    Dim foundRow As Long

    i = 6
    Do While i <= lastRow
        dataA = ws.Range("A" & i).Value
        dataD = ws.Range("D" & i).Value  ' 旧E列→新D列

        ' 終了条件: AもDも空 or i>lastRow
        If (IsEmpty(dataA) Or dataA = "") And (IsEmpty(dataD) Or dataD = "") Then
            Exit Do
        End If

        foundRow = 0
        For j = i + 1 To lastRow + 1
            If j > lastRow Then
                foundRow = lastRow + 1
                Exit For
            End If

            Dim tmpA As Variant, tmpD As Variant
            tmpA = ws.Range("A" & j).Value
            tmpD = ws.Range("D" & j).Value

            If (IsEmpty(tmpA) Or tmpA = "") And (IsEmpty(tmpD) Or tmpD = "") Then
                foundRow = j
                Exit For
            End If
            If (IsNumeric(tmpA) And Not IsEmpty(tmpA)) Or (IsEmpty(tmpD) Or tmpD = "") Then
                foundRow = j
                Exit For
            End If
        Next j

        If foundRow = 0 Then
            Exit Do
        End If

        ' グループ外枠のみ罫線
        Call SetOuterBorders(ws.Range(ws.Cells(i, "A"), ws.Cells(foundRow - 1, "F")))

        i = foundRow
    Loop

    '----------------------------------------------------------------------
    ' (11)~(15) 相当: A6:F(lastRow) に最終的な罫線(外枠+縦罫線)
    '----------------------------------------------------------------------
    Call SetOuterBorders(ws.Range("A6:F" & lastRow))
    Call SetInsideVerticalBorders(ws.Range("A6:F" & lastRow))

    '----------------------------------------------------------------------
    ' D1結合対策(任意)
    '----------------------------------------------------------------------
    ws.Range("D1").MergeArea.ClearContents
    With ws.Range("A1:E1")
        .Merge
        .HorizontalAlignment = xlLeft
    End With

    '----------------------------------------------------------------------
    ' E列の色付け
    '----------------------------------------------------------------------
    Dim valE As Variant
    Dim strE As String
    For r = 5 To lastRow

        valA = ws.Range("A" & r).Value
        Dim strA As String
        strA = Replace(Replace(Replace(CStr(valA), vbCr, ""), vbLf, ""), " ", "")
        strA = Trim(strA)
        
        If LCase(strA) = "total" Or (IsNumeric(strA) And strA <> "") Then
            ws.Range("E" & r).Interior.ColorIndex = xlNone
        Else
            valE = ws.Range("E" & r).Value
            strE = Replace(Replace(Replace(CStr(valE), vbCr, ""), vbLf, ""), " ", "")
            strE = Replace(strE, Chr(160), "")
            strE = Trim(strE)
            
            Dim chkE As String
            chkE = LCase(strE)
            
            If Right(chkE, 1) = ")" Then
                chkE = Left(chkE, Len(chkE) - 1)
            End If
            
            If chkE = "" Then
                ws.Range("E" & r).Interior.ColorIndex = xlNone
            ElseIf Right(chkE, 3) = "fit" Then
                ws.Range("E" & r).Interior.Color = RGB(249, 241, 227)
            ElseIf Right(chkE, 1) = "%" Then
                ws.Range("E" & r).Interior.ColorIndex = xlNone
            Else
                ws.Range("E" & r).Interior.ColorIndex = 45
            End If
        End If
    Next r
    
    '----------------------------------------------------------------------
    ' ★ もともとD5にあった括弧を削除(最終的にはD4になる)
    '----------------------------------------------------------------------
    Dim tmpStr As String, p As Long
    tmpStr = ws.Range("D5").Value
    p = InStr(tmpStr, "(")
    If p > 0 Then
        tmpStr = Trim(Left(tmpStr, p - 1))
        ws.Range("D5").Value = tmpStr
    End If

    '----------------------------------------------------------------------
    ' 行2を削除 → D5 が D4 に繰り上がる
    '----------------------------------------------------------------------
    ws.Rows(2).Delete
    lastRow = lastRow - 1

    '----------------------------------------------------------------------
    ' 列オートフィット & 横位置調整
    '   見出し行(A4:F4) → 実際は A3:F3 になる
    '   データ行(A5:F...) → 実際は A4:F...
    '----------------------------------------------------------------------
    ws.Range("A3:F" & lastRow).Columns.AutoFit
    
    With ws.Range("A4:A" & lastRow): .HorizontalAlignment = xlRight: End With
    With ws.Range("B4:B" & lastRow): .HorizontalAlignment = xlRight: End With
    With ws.Range("C4:C" & lastRow): .HorizontalAlignment = xlRight: End With
    With ws.Range("D4:D" & lastRow): .HorizontalAlignment = xlLeft:  End With
    With ws.Range("E4:E" & lastRow): .HorizontalAlignment = xlLeft:  End With
    With ws.Range("F4:F" & lastRow): .HorizontalAlignment = xlRight: End With

    MsgBox "処理が完了しました。最終行は " & lastRow

End Sub

'------------------------------------------------------------------------------
' 外枠だけ罫線を付ける
'------------------------------------------------------------------------------
Private Sub SetOuterBorders(rng As Range)
    With rng
        With .Borders(xlEdgeLeft)
            .LineStyle = xlContinuous
            .Weight = xlThin
        End With
        With .Borders(xlEdgeTop)
            .LineStyle = xlContinuous
            .Weight = xlThin
        End With
        With .Borders(xlEdgeRight)
            .LineStyle = xlContinuous
            .Weight = xlThin
        End With
        With .Borders(xlEdgeBottom)
            .LineStyle = xlContinuous
            .Weight = xlThin
        End With
    End With
End Sub

'------------------------------------------------------------------------------
' 縦の内側線だけ
'------------------------------------------------------------------------------
Private Sub SetInsideVerticalBorders(rng As Range)
    With rng.Borders(xlInsideVertical)
        .LineStyle = xlContinuous
        .Weight = xlThin
    End With
End Sub

ChatGPT の回答は必ずしも正しいとは限りません。重要な情報は確認するようにしてください。

なお、本稿はRAMS 2026に投稿予定のため一部を秘匿していますが、論文公開後の2026年2月頃に開示予定です。


左矢前のブログ 次のブログ右矢

Fault treeの自動生成 (19)

posted by sakurai on January 16, 2025 #930

ChatGPTにRBDを示してFTを生成させます。まず基本形のRBDを図930.1に示します。

図%%.1
図930.1 RBD

ここでは2nd SMは省略しています。その理由はワーストケース評価を行いたいためです。冗長系ではRFがほとんど存在しないため、2nd SMの効果が大きく見えてきますが、このような非冗長系においては1st SMの効果であるRFが支配的であり、経験からはRFは95%以上となる場合が多いと考えます。

図930.1を読み取ったChatGPTの生成したMARDファイルを以下に示します。

TEST.BED

*Saphire 8.2.9
TEST =
* Name , Descriptions , Project
IF_FAULT , IF fault(10FIT) , TEST
SM_FAULT , SM_IF fault(20FIT) , TEST
SM_IF_COVREM , SM_IF coverage leftover(1-DC=10%) , TEST
SM_IF_COV , SM_IF coverage(DC=90%) , TEST

TEST.BEI

*Saphire 8.2.9
TEST =
* Name ,FdT,UdC,UdT,UdValue, Prob, Lambda, Tau, Mission, Init,PF,UdValue2,Calc. Prob,Freq,Analysis Type,Phase Type,Project
IF_FAULT ,3, , , , ,1.0E-008, ,1.0E+005, , , ,1.0E-003, ,RANDOM,CD,TEST
SM_FAULT ,3, , , , ,2.0E-008, ,1.0E+005, , , ,2.0E-003, ,RANDOM,CD,TEST
SM_IF_COVREM ,1, , , ,1.0E-001, , , , , , ,1.0E-001, ,RANDOM,CD,TEST
SM_IF_COV ,1, , , ,9.0E-001, , , , , , ,9.0E-001, ,RANDOM,CD,TEST

TEST.FTD

TEST =
* Name , Description, SubTree, Alternate, Project
TOP , TEST , , , TEST

TEST.FTL

TEST, TOP =
TOP AND IF_FAULT SM_IF
SM_IF OR SM_IF_COVREM DPF
DPF AND SM_IF_COV SM_FAULT

TEST.GTD

TEST=
* Name , Description, Project
TOP , TEST , ,TEST
SM_IF , SM_IF gate , ,TEST
DPF , coverage partial path , ,TEST

図930.2にこれらのMARDをSpahireにロードし生成したFTを示します。

$$\img[-1.35em]{/images/withinseminar.png}$$

比較のために前記事に掲載した基本形のFT図$\dagger$を示します。

図%%.3
図929.1 生成されたFT

図930.3にSaphireで取得したMCSを示します。予想どおりRFが98%以上であり、DPFは2%未満となりました。

図%%.3
図930.3 生成されたFTのMCS

Saphireで生成したcut setの表に対してPMHFの欄を追加し、かつ故障率の項を黄色で塗っています。これによりSPF/RFかDPFかが容易に理解されます。

なお、本稿はRAMS 2026に投稿予定のため一部を秘匿していますが、論文公開後の2026年2月頃に開示予定です。


$\dagger$ S. Atsushi, "A Framework for Performing Quantitative Fault Tree Analyses for Subsystems with Periodic Repairs," 2021 Annual Reliability and Maintainability Symposium (RAMS), Orlando, FL, USA, 2021, pp. 1-6.


左矢前のブログ 次のブログ右矢

Fault treeの自動生成 (18)

posted by sakurai on January 15, 2025 #929

Fault Treeの構成

PMHF式に準拠してFault Tree (FT)を構成します。まず基礎となるFTは図929.1のとおりです。このFT構成法は弊社の$\dagger$過去論文に依るものです。これは後で示すPMHF式を再現するように構成しています。

図%%.1
図929.1 FTの構成

次に対応するPMHF式を示します。前記FTの構成法にはMethod 1, 2, 3と3種あり、それぞれ以下のような特徴があります。

  • Method 1: 2nd SMが無いものとする。もっとも単純なツリーであり、真値よりもPMHFは大となるため、初期にワーストケースを見るのに都合が良い。 $$ M_\text{PMHF}=(1-K_\text{IF,RF})\lambda_\text{IF}+K_\text{IF,RF}\lambda_\text{IF}\lambda_\text{SM} $$
  • Method 2: 2nd SMのカバレージ$K_\text{SM,MPF}$の効果を加えたもの。ただし、真値よりも次のMethod 3で加わる効果が入っていない分だけPMHFが小さく算出されることが問題。ただしこの誤差は$K_\text{SM,MPF}$が小さい時または$\tau$が小さい時は無視できる。 $$ M_\text{PMHF}=(1-K_\text{IF,RF})\lambda_\text{IF}+K_\text{IF,RF}\lambda_\text{IF}\lambda_\text{SM}\color{red}{\left((1-K_\text{SM,MPF})T_\text{lifetime}\right)} $$
  • Method 3: Method 2の効果に加えて、2nd SMの定期検査周期間$\tau$内の不検出効果を加える。PMHFとしては真値であるが、加えた不検出効果は、$K_\text{SM,MPF}$が小さい時または$\tau$が小さい時は無視できる。 $$ M_\text{PMHF}=(1-K_\text{IF,RF})\lambda_\text{IF}+K_\text{IF,RF}\lambda_\text{IF}\lambda_\text{SM}\left((1-K_\text{SM,MPF})T_\text{lifetime}\color{red}{+K_\text{SM,MPF}\tau}\right) $$

Method 3の係数の効果を3Dグラフに表すと図929.2のような形になります。

$$\img[-1.35em]{/images/withinseminar.png}$$

記事#927で述べたように、$K_\text{MPF}$が小さいか$\tau$が小さい場合にはこの効果は無視できます。

なお、本稿はRAMS 2027に投稿予定のため一部を秘匿していますが、論文公開後の2027年2月頃に開示予定です。


$\dagger$ S. Atsushi, "A Framework for Performing Quantitative Fault Tree Analyses for Subsystems with Periodic Repairs," 2021 Annual Reliability and Maintainability Symposium (RAMS), Orlando, FL, USA, 2021, pp. 1-6.


左矢前のブログ 次のブログ右矢

Fault treeの自動生成 (17)

posted by sakurai on January 14, 2025 #928

Method3での新旧係数比較

昔の記事の表217.1にMethod3での手作業の係数がまとめてありますが、これとChatGPTによる係数の割り当てを比較します。

まずChatGPTにカットセットの旧の表(表217.2)と新の表(表925.1)を見せ、old.txtとnew.txtを作成してもらいました。

old.txt

C4,M1,M2
C2,M2,SC1
C2,M1,SC2
C1,SC1,SC2
C1,SA1,SA2
C2,M2,MCU1
C2,M1,MCU2
C1,MCU2,SC1
C1,MCU1,SC2
C5,I2,M1
C5,I1,M2
C1,MCU1,MCU2
C3,I2,SC1
C3,I1,SC2
C7,I1,I2
C3,I2,MCU1
C3,I1,MCU2
C8,I2,P1
C8,I1,P2
C6,M2,P1
C6,M1,P2
C4,P2,SC1
C4,P1,SC2
C9,P1,P2
C4,MCU2,P1
C4,MCU1,P2
C2,D2,M1
C2,D1,M2
C1,D2,SC1
C1,D1,SC2
C1,D2,MCU1
C1,D1,MCU2
C3,D2,I1
C3,D1,I2
C3,CA2,SA1
C3,CA1,SA2
C4,D2,P1
C4,D1,P2
C1,D1,D2
C7,CA1,CA2

new.txt

C12,M1,M2
C17,M2,SC1
C17,M1,SC2
C15,SC1,SC2
C15,SA1,SA2
C17,M2,MCU1
C17,M1,MCU2
C15,MCU2,SC1
C15,MCU1,SC2
C19,I2,M1
C19,I1,M2
C15,MCU1,MCU2
C16,I2,SC1
C16,I1,SC2
C18,I1,I2
C16,I2,MCU1
C16,I1,MCU2
C13,I2,P1
C13,I1,P2
C14,M2,P1
C14,M1,P2
C12,P2,SC1
C12,P1,SC2
C11,P1,P2
C12,MCU2,P1
C12,MCU1,P2
C17,D2,M1
C17,D1,M2
C15,D2,SC1
C15,D1,SC2
C15,D2,MCU1
C15,D1,MCU2
C16,D2,I1
C16,D1,I2
C16,CA2,SA1
C16,CA1,SA2
C12,D2,P1
C12,D1,P2
C15,D1,D2
C18,CA1,CA2

さらにそれを比較するプログラムを作成してもらいました。

#!/usr/bin/env python3
import sys
import csv
from collections import defaultdict

"""
Usage:
  python transform_coverage.py old.txt new.txt

Where:
  old.txt, new.txt each line looks like:
    C4,M1,M2
    C1,SA1,SA2
  etc.

We parse the first token as coverage name (e.g. 'C4'),
the rest as element names (e.g. 'M1','M2').
We store them in a dictionary keyed by the sorted tuple of elements.

Then we produce a transform table:
  old_coverage -> new_coverage
for each matching element-tuple.
If multiple old coverages map to the same new coverage or vice versa,
we show those collisions or many-to-many relationships explicitly.
"""

def parse_cutset_file(filename):
    """
    Parse lines like "C4,M1,M2" into:
      coverage='C4'
      elements=('M1','M2')  # sorted
    We'll store coverage -> set of element_tuples
    We'll also store element_tuple -> coverage
    Returns (coverage2sets, element2cov)
    """
    coverage2sets = defaultdict(set)   # coverage -> { (el1,el2,...) , ... }
    element2cov = {}
    with open(filename, "r", encoding="utf-8") as f:
        for line in f:
            line=line.strip()
            if not line or line.startswith("#"):
                continue
            # split by comma
            parts = [x.strip() for x in line.split(",")]
            coverage = parts[0]
            elements = parts[1:]
            # sort elements so (M1,M2) == (M2,M1)
            sorted_e = tuple(sorted(elements))
            coverage2sets[coverage].add(sorted_e)
            element2cov[sorted_e] = coverage
    return coverage2sets, element2cov

def main(oldfile, newfile):
    old_cov2sets, old_elem2cov = parse_cutset_file(oldfile)
    new_cov2sets, new_elem2cov = parse_cutset_file(newfile)

    # We'll create a transform table: oldCov -> newCov
    # by checking each element tuple in old
    # and see what coverage is assigned in new.
    transform_map = defaultdict(set)  
    # key=oldCoverageName, value=set of newCoverageNames
    # Because it's possible multiple new coverages appear.

    # Also track if some old coverage references multiple distinct new coverage
    # or vice versa.

    # all element tuples from old
    for etuple, oldcov in old_elem2cov.items():
        if etuple in new_elem2cov:
            newcov = new_elem2cov[etuple]
            transform_map[oldcov].add(newcov)
        else:
            # no match in new => discrepancy
            transform_map[oldcov].add("NO_MATCH_IN_NEW")

    # Now produce a nice table
    print("=== Coverage transform table ===")
    for oldcov in sorted(transform_map.keys()):
        newcovs = transform_map[oldcov]
        if len(newcovs)==1:
            single = list(newcovs)[0]
            if single=="NO_MATCH_IN_NEW":
                print(f"{oldcov} => [NO MATCH in NEW file!]")
            else:
                print(f"{oldcov} => {single}")
        else:
            # multiple new coverages
            nclist = ",".join(sorted(newcovs))
            print(f"{oldcov} => {{{nclist}}}  # multiple new coverage found for same old coverage")

    print()
    print("=== Reverse check: new coverage => old coverage ===")
    # We'll do similarly in reverse
    # create new_elem2cov from parse => done
    # but we want coverage -> set of element tuples
    rev_map = defaultdict(set)  # new-> old coverage
    for etuple, newcov in new_elem2cov.items():
        if etuple in old_elem2cov:
            oldcov = old_elem2cov[etuple]
            rev_map[newcov].add(oldcov)
        else:
            rev_map[newcov].add("NO_MATCH_IN_OLD")

    for newcov in sorted(rev_map.keys()):
        oldcovs = rev_map[newcov]
        if len(oldcovs)==1:
            single = list(oldcovs)[0]
            if single=="NO_MATCH_IN_OLD":
                print(f"{newcov} => [NO MATCH in OLD file!]")
            else:
                print(f"{newcov} => {single}")
        else:
            # multiple old coverage
            oclist = ",".join(sorted(oldcovs))
            print(f"{newcov} => {{{oclist}}}  # multiple old coverage found for same new coverage")

    print()
    print("=== Detailed mismatch check (cutset by cutset) ===")
    # We'll unify the union of all element tuples
    all_etups = set(list(old_elem2cov.keys())+ list(new_elem2cov.keys()))
    for et in sorted(all_etups):
        ocov = old_elem2cov.get(et,"-")
        ncov = new_elem2cov.get(et,"-")
        elements_str = ",".join(et)
        print(f"Cutset({elements_str}): old={ocov} , new={ncov}")

if __name__=="__main__":
    if len(sys.argv)<3:
        print("Usage: python transform_coverage.py old.txt new.txt")
        sys.exit(0)
    oldfile=sys.argv[1]
    newfile=sys.argv[2]
    main(oldfile,newfile)

ChatGPT の回答は必ずしも正しいとは限りません。重要な情報は確認するようにしてください。

次に以下のコマンドにより、新旧の対応を表示します。

\$ python transform_cov.py old.txt new.txt | head -10 | tail -9

この出力は

C1 => C15
C2 => C17
C3 => C16
C4 => C12
C5 => C19
C6 => C14
C7 => C18
C8 => C13
C9 => C11

となるので、これを表にまとめます。新係数C??の値は直接MARD中のBEIファイルから拾いました。

表928.1
定数記号 定数値 定数記号 定数値
C1 0.2280772 C15 0.2280772
C2 0.2287720 C17 0.2287720
C3 0.2310880 C16 0.2310880
C4 0.2357200 C12 0.2357200
C5 0.2588800 C19 0.2588800
C6 0.3052000 C14 0.3052000
C7 0.3515200 C18 0.3515200
C8 0.5368000 C13 0.5368000
C9 1.0000000 C11 1.0000000

係数名の振り方は異なるものの、係数値とそのエレメントペアへの割り当ては完全に一致していることが確認できました。数値自体も旧のC1~9は表217.1を用いています。

割り当て係数が全く同じであるにも関わらず昔の記事今の記事の頂上侵害確率が、旧$8.32\color{red}{1}\cdot 10^{-4}\Rightarrow$新$8.32\color{red}{4}\cdot 10^{-4}$、及びPMHFにおいて、旧$55.4\color{red}{7}\Rightarrow$新$55.4\color{red}{9}$が若干異なるのは、Saphireの版数の違いと考えられます。旧は2020年版、新は2024年版です。

なお、本稿はRAMS 2027に投稿予定のため一部を秘匿していますが、論文公開後の2027年2月頃に開示予定です。


左矢前のブログ 次のブログ右矢


ページ: