Paper [IFAC]: Human Failure Analyses

For the paper Irshad, L., & Hulse, D. (2022). Can Resilience Assessments Inform Early Design Human Factors Decision-making?. IFAC-PapersOnLine, 55(29), 61-66.

Copyright © 2024, United States Government, as represented by the Administrator of the National Aeronautics and Space Administration. All rights reserved.

The “"Fault Model Design tools - fmdtools version 2"” software is licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
from fmdtools.sim.sample import ParameterDomain, ParameterSample, FaultDomain, FaultSample
import fmdtools.analyze as an
import fmdtools.sim.propagate as prop
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['pdf.fonttype'] = 42
import multiprocessing as mp
import scipy.stats as stats


import multiprocessing as mp
from fmdtools_examples.navigating_rover.model_human import RoverHuman, RoverHumanParam, asg_pos
from fmdtools_examples.navigating_rover.model_main import plot_map
mdl = RoverHuman()
g = mdl.as_modelgraph()
fig, ax = g.draw()
../../_images/82493b5a44a3631aeb67b2432331378cd4481aa0d152e08380f6a8d6f873a2a6.png
g.set_exec_order(mdl)
fig, ax = g.draw()
../../_images/ac9dd67b89119b6ea5f11b617d67550a49de80230e8bbf9b5ea021fb9218d01e.png
ag = mdl.fxns['operator'].aa.as_modelgraph()
ag.set_pos(**asg_pos)
fig, ax = ag.draw()
../../_images/6fb720ba268a00b9f866f398feab9e6eb17530ea6fa6edaffbf8296005511196.png
fig.savefig("outputs_paper_ifac_human/action_graph.pdf", format="pdf", bbox_inches = 'tight', pad_inches = 0)
mdl = RoverHuman(p={'linetype': 'sine', 'period': 10, 'amp': 3, 'drive_modes': {'mode_options':'manual'}})
er, hist = prop.nominal(mdl)
fig, ax = plot_map(mdl, hist)
../../_images/b909ae718a6a50ebe578ddce64d3048ea7101ec7a53e8972fb39127d149a699b.png
mdl.fxns['drive'].m
DriveMode(faults=set(), sub_faults=False, fault_stuck={'disturbances': (('s.friction', 10.0),)}, fault_stuck_right={'disturbances': (('s.friction', 3.0), ('s.drift', 0.2))}, fault_stuck_left={'disturbances': (('s.friction', 3.0), ('s.drift', -0.2))}, fault_custom={})
fd_hum = FaultDomain(mdl)
fd_hum.add_all_fxn_modes('operator')
fd_hum
FaultDomain with faults:
 -('roverhuman.fxns.operator.aa.acts.look', 'failed_no_action')
 -('roverhuman.fxns.operator.aa.acts.percieve', 'failed_no_action')
 -('roverhuman.fxns.operator.aa.acts.percieve', 'not_visible')
 -('roverhuman.fxns.operator.aa.acts.percieve', 'wrong_position')
 -('roverhuman.fxns.operator.aa.acts.comprehend', 'failed_no_action')
 -('roverhuman.fxns.operator.aa.acts.project', 'failed_fast')
 -('roverhuman.fxns.operator.aa.acts.project', 'failed_no_action')
 -('roverhuman.fxns.operator.aa.acts.project', 'failed_slow')
 -('roverhuman.fxns.operator.aa.acts.project', 'failed_turn_left')
 -('roverhuman.fxns.operator.aa.acts.project', 'failed_turn_right')
 -...more
fs_hum = FaultSample(fd_hum)
fs_hum.add_fault_phases("start")
fs_hum
FaultSample of scenarios: 
 - roverhuman_fxns_operator_aa_acts_look_failed_no_action_t15p0
 - roverhuman_fxns_operator_aa_acts_percieve_failed_no_action_t15p0
 - roverhuman_fxns_operator_aa_acts_percieve_not_visible_t15p0
 - roverhuman_fxns_operator_aa_acts_percieve_wrong_position_t15p0
 - roverhuman_fxns_operator_aa_acts_comprehend_failed_no_action_t15p0
 - roverhuman_fxns_operator_aa_acts_project_failed_fast_t15p0
 - roverhuman_fxns_operator_aa_acts_project_failed_no_action_t15p0
 - roverhuman_fxns_operator_aa_acts_project_failed_slow_t15p0
 - roverhuman_fxns_operator_aa_acts_project_failed_turn_left_t15p0
 - roverhuman_fxns_operator_aa_acts_project_failed_turn_right_t15p0
 - ... (19 total)
fs_hum.scenarios()
[SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.look': ['failed_no_action']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.look', fault='failed_no_action', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_look_failed_no_action_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.percieve': ['failed_no_action']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.percieve', fault='failed_no_action', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_percieve_failed_no_action_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.percieve': ['not_visible']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.percieve', fault='not_visible', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_percieve_not_visible_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.percieve': ['wrong_position']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.percieve', fault='wrong_position', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_percieve_wrong_position_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.comprehend': ['failed_no_action']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.comprehend', fault='failed_no_action', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_comprehend_failed_no_action_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.project': ['failed_fast']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.project', fault='failed_fast', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_project_failed_fast_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.project': ['failed_no_action']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.project', fault='failed_no_action', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_project_failed_no_action_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.project': ['failed_slow']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.project', fault='failed_slow', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_project_failed_slow_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.project': ['failed_turn_left']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.project', fault='failed_turn_left', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_project_failed_turn_left_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.project': ['failed_turn_right']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.project', fault='failed_turn_right', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_project_failed_turn_right_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.decide': ['failed_fast']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.decide', fault='failed_fast', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_decide_failed_fast_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.decide': ['failed_no_action']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.decide', fault='failed_no_action', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_decide_failed_no_action_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.decide': ['failed_slow']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.decide', fault='failed_slow', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_decide_failed_slow_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.decide': ['failed_turn_left']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.decide', fault='failed_turn_left', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_decide_failed_turn_left_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.decide': ['failed_turn_right']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.decide', fault='failed_turn_right', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_decide_failed_turn_right_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.reach': ['failed_no_action']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.reach', fault='failed_no_action', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_reach_failed_no_action_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.press': ['failed_left']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.press', fault='failed_left', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_press_failed_left_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.press': ['failed_right']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.press', fault='failed_right', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_press_failed_right_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.operator.aa.acts.press': ['no_press']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.operator.aa.acts.press', fault='no_press', rate=np.float64(1.0), name='roverhuman_fxns_operator_aa_acts_press_no_press_t15p0', time=np.float64(15.0), phase='start')]
ecs, hists = prop.fault_sample(mdl, fs_hum)
SCENARIOS COMPLETE: 100%|██████████| 19/19 [00:06<00:00,  3.09it/s]
fig, ax = plot_map(mdl, hists)
../../_images/382449bf339de4e2e22dedad874c68c9f8d20f62909d902ed503013feb236c3f.png
figs, axs = hists.plot_line('flows.pos.s.vel','flows.pos.s.x', 'flows.pos.s.y',
                            'flows.switch.s.power', 'fxns.power.s.charge', time_slice=[14],
                            title="Rover Response to Human Fault Modes at t=14",
                            indiv_kwargs={'faulty':{'alpha':0.5, 'color':'red'}},
                            ylabels={'flows.pos.s.x':'meters','flows.pos.s.y':'meters', 'flows.ground.s.x':'m/s',
                                   'fxns.power.s.charge': '%'}, xlabel='time (s)',
                            titles={'flows.pos.s.x':'x position','flows.pos.s.y':'y position', 'flows.pos.s.vel':'velocity',
                                   'flows.s.switch': 'on/off switch', 'fxns.power.s.charge': 'state of charge'}, h_padding=0.3)
../../_images/ab896e5e835084535f8718f37d4e33714c748bdc8983c21e1594f1c98b74d25b.png
fig.savefig("outputs_paper_ifac_human/rover_fault_behavior.pdf", format="pdf", bbox_inches = 'tight', pad_inches = 0)
from fmdtools_examples.navigating_rover.model_degradation import PSFDegradationShort, PSFShortParams
pd_deg = ParameterDomain(PSFShortParams)
pd_deg.add_constant('stress_param', 0.0)
pd_deg.add_variable('experience', var_lim=(1.0, 5.0))
pd_deg(2,2)
PSFShortParams(experience=2.0, stress_param=0.0, fatigue_param=1.0)
ps_deg = ParameterSample(pd_deg)
ps_deg.add_variable_ranges(replicates = 10)
ps_deg.scenarios()
[ParameterScenario(sequence={}, times=(), p={'experience': np.float64(1.0), 'stress_param': 0.0}, r={'seed': np.uint32(724269981)}, sp={}, prob=0.02, inputparams={0: np.float64(1.0)}, rangeid='', name='rep0_range_0'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(1.0), 'stress_param': 0.0}, r={'seed': np.uint32(3105616893)}, sp={}, prob=0.02, inputparams={0: np.float64(1.0)}, rangeid='', name='rep1_range_1'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(1.0), 'stress_param': 0.0}, r={'seed': np.uint32(2833239588)}, sp={}, prob=0.02, inputparams={0: np.float64(1.0)}, rangeid='', name='rep2_range_2'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(1.0), 'stress_param': 0.0}, r={'seed': np.uint32(2767900790)}, sp={}, prob=0.02, inputparams={0: np.float64(1.0)}, rangeid='', name='rep3_range_3'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(1.0), 'stress_param': 0.0}, r={'seed': np.uint32(592103820)}, sp={}, prob=0.02, inputparams={0: np.float64(1.0)}, rangeid='', name='rep4_range_4'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(1.0), 'stress_param': 0.0}, r={'seed': np.uint32(3547666947)}, sp={}, prob=0.02, inputparams={0: np.float64(1.0)}, rangeid='', name='rep5_range_5'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(1.0), 'stress_param': 0.0}, r={'seed': np.uint32(2138197673)}, sp={}, prob=0.02, inputparams={0: np.float64(1.0)}, rangeid='', name='rep6_range_6'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(1.0), 'stress_param': 0.0}, r={'seed': np.uint32(3798284825)}, sp={}, prob=0.02, inputparams={0: np.float64(1.0)}, rangeid='', name='rep7_range_7'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(1.0), 'stress_param': 0.0}, r={'seed': np.uint32(3339996354)}, sp={}, prob=0.02, inputparams={0: np.float64(1.0)}, rangeid='', name='rep8_range_8'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(1.0), 'stress_param': 0.0}, r={'seed': np.uint32(1213578067)}, sp={}, prob=0.02, inputparams={0: np.float64(1.0)}, rangeid='', name='rep9_range_9'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(2.0), 'stress_param': 0.0}, r={'seed': np.uint32(724269981)}, sp={}, prob=0.02, inputparams={0: np.float64(2.0)}, rangeid='', name='rep0_range_10'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(2.0), 'stress_param': 0.0}, r={'seed': np.uint32(3105616893)}, sp={}, prob=0.02, inputparams={0: np.float64(2.0)}, rangeid='', name='rep1_range_11'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(2.0), 'stress_param': 0.0}, r={'seed': np.uint32(2833239588)}, sp={}, prob=0.02, inputparams={0: np.float64(2.0)}, rangeid='', name='rep2_range_12'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(2.0), 'stress_param': 0.0}, r={'seed': np.uint32(2767900790)}, sp={}, prob=0.02, inputparams={0: np.float64(2.0)}, rangeid='', name='rep3_range_13'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(2.0), 'stress_param': 0.0}, r={'seed': np.uint32(592103820)}, sp={}, prob=0.02, inputparams={0: np.float64(2.0)}, rangeid='', name='rep4_range_14'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(2.0), 'stress_param': 0.0}, r={'seed': np.uint32(3547666947)}, sp={}, prob=0.02, inputparams={0: np.float64(2.0)}, rangeid='', name='rep5_range_15'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(2.0), 'stress_param': 0.0}, r={'seed': np.uint32(2138197673)}, sp={}, prob=0.02, inputparams={0: np.float64(2.0)}, rangeid='', name='rep6_range_16'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(2.0), 'stress_param': 0.0}, r={'seed': np.uint32(3798284825)}, sp={}, prob=0.02, inputparams={0: np.float64(2.0)}, rangeid='', name='rep7_range_17'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(2.0), 'stress_param': 0.0}, r={'seed': np.uint32(3339996354)}, sp={}, prob=0.02, inputparams={0: np.float64(2.0)}, rangeid='', name='rep8_range_18'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(2.0), 'stress_param': 0.0}, r={'seed': np.uint32(1213578067)}, sp={}, prob=0.02, inputparams={0: np.float64(2.0)}, rangeid='', name='rep9_range_19'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(3.0), 'stress_param': 0.0}, r={'seed': np.uint32(724269981)}, sp={}, prob=0.02, inputparams={0: np.float64(3.0)}, rangeid='', name='rep0_range_20'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(3.0), 'stress_param': 0.0}, r={'seed': np.uint32(3105616893)}, sp={}, prob=0.02, inputparams={0: np.float64(3.0)}, rangeid='', name='rep1_range_21'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(3.0), 'stress_param': 0.0}, r={'seed': np.uint32(2833239588)}, sp={}, prob=0.02, inputparams={0: np.float64(3.0)}, rangeid='', name='rep2_range_22'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(3.0), 'stress_param': 0.0}, r={'seed': np.uint32(2767900790)}, sp={}, prob=0.02, inputparams={0: np.float64(3.0)}, rangeid='', name='rep3_range_23'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(3.0), 'stress_param': 0.0}, r={'seed': np.uint32(592103820)}, sp={}, prob=0.02, inputparams={0: np.float64(3.0)}, rangeid='', name='rep4_range_24'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(3.0), 'stress_param': 0.0}, r={'seed': np.uint32(3547666947)}, sp={}, prob=0.02, inputparams={0: np.float64(3.0)}, rangeid='', name='rep5_range_25'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(3.0), 'stress_param': 0.0}, r={'seed': np.uint32(2138197673)}, sp={}, prob=0.02, inputparams={0: np.float64(3.0)}, rangeid='', name='rep6_range_26'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(3.0), 'stress_param': 0.0}, r={'seed': np.uint32(3798284825)}, sp={}, prob=0.02, inputparams={0: np.float64(3.0)}, rangeid='', name='rep7_range_27'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(3.0), 'stress_param': 0.0}, r={'seed': np.uint32(3339996354)}, sp={}, prob=0.02, inputparams={0: np.float64(3.0)}, rangeid='', name='rep8_range_28'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(3.0), 'stress_param': 0.0}, r={'seed': np.uint32(1213578067)}, sp={}, prob=0.02, inputparams={0: np.float64(3.0)}, rangeid='', name='rep9_range_29'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(4.0), 'stress_param': 0.0}, r={'seed': np.uint32(724269981)}, sp={}, prob=0.02, inputparams={0: np.float64(4.0)}, rangeid='', name='rep0_range_30'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(4.0), 'stress_param': 0.0}, r={'seed': np.uint32(3105616893)}, sp={}, prob=0.02, inputparams={0: np.float64(4.0)}, rangeid='', name='rep1_range_31'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(4.0), 'stress_param': 0.0}, r={'seed': np.uint32(2833239588)}, sp={}, prob=0.02, inputparams={0: np.float64(4.0)}, rangeid='', name='rep2_range_32'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(4.0), 'stress_param': 0.0}, r={'seed': np.uint32(2767900790)}, sp={}, prob=0.02, inputparams={0: np.float64(4.0)}, rangeid='', name='rep3_range_33'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(4.0), 'stress_param': 0.0}, r={'seed': np.uint32(592103820)}, sp={}, prob=0.02, inputparams={0: np.float64(4.0)}, rangeid='', name='rep4_range_34'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(4.0), 'stress_param': 0.0}, r={'seed': np.uint32(3547666947)}, sp={}, prob=0.02, inputparams={0: np.float64(4.0)}, rangeid='', name='rep5_range_35'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(4.0), 'stress_param': 0.0}, r={'seed': np.uint32(2138197673)}, sp={}, prob=0.02, inputparams={0: np.float64(4.0)}, rangeid='', name='rep6_range_36'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(4.0), 'stress_param': 0.0}, r={'seed': np.uint32(3798284825)}, sp={}, prob=0.02, inputparams={0: np.float64(4.0)}, rangeid='', name='rep7_range_37'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(4.0), 'stress_param': 0.0}, r={'seed': np.uint32(3339996354)}, sp={}, prob=0.02, inputparams={0: np.float64(4.0)}, rangeid='', name='rep8_range_38'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(4.0), 'stress_param': 0.0}, r={'seed': np.uint32(1213578067)}, sp={}, prob=0.02, inputparams={0: np.float64(4.0)}, rangeid='', name='rep9_range_39'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(5.0), 'stress_param': 0.0}, r={'seed': np.uint32(724269981)}, sp={}, prob=0.02, inputparams={0: np.float64(5.0)}, rangeid='', name='rep0_range_40'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(5.0), 'stress_param': 0.0}, r={'seed': np.uint32(3105616893)}, sp={}, prob=0.02, inputparams={0: np.float64(5.0)}, rangeid='', name='rep1_range_41'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(5.0), 'stress_param': 0.0}, r={'seed': np.uint32(2833239588)}, sp={}, prob=0.02, inputparams={0: np.float64(5.0)}, rangeid='', name='rep2_range_42'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(5.0), 'stress_param': 0.0}, r={'seed': np.uint32(2767900790)}, sp={}, prob=0.02, inputparams={0: np.float64(5.0)}, rangeid='', name='rep3_range_43'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(5.0), 'stress_param': 0.0}, r={'seed': np.uint32(592103820)}, sp={}, prob=0.02, inputparams={0: np.float64(5.0)}, rangeid='', name='rep4_range_44'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(5.0), 'stress_param': 0.0}, r={'seed': np.uint32(3547666947)}, sp={}, prob=0.02, inputparams={0: np.float64(5.0)}, rangeid='', name='rep5_range_45'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(5.0), 'stress_param': 0.0}, r={'seed': np.uint32(2138197673)}, sp={}, prob=0.02, inputparams={0: np.float64(5.0)}, rangeid='', name='rep6_range_46'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(5.0), 'stress_param': 0.0}, r={'seed': np.uint32(3798284825)}, sp={}, prob=0.02, inputparams={0: np.float64(5.0)}, rangeid='', name='rep7_range_47'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(5.0), 'stress_param': 0.0}, r={'seed': np.uint32(3339996354)}, sp={}, prob=0.02, inputparams={0: np.float64(5.0)}, rangeid='', name='rep8_range_48'),
 ParameterScenario(sequence={}, times=(), p={'experience': np.float64(5.0), 'stress_param': 0.0}, r={'seed': np.uint32(1213578067)}, sp={}, prob=0.02, inputparams={0: np.float64(5.0)}, rangeid='', name='rep9_range_49')]
deg_mdl = PSFDegradationShort()
ec_psf_short, hist_psf_short = prop.parameter_sample(deg_mdl, ps_deg, run_stochastic=True)
SCENARIOS COMPLETE: 100%|██████████| 50/50 [00:00<00:00, 602.28it/s]
hist_psf_short.keys()
dict_keys(['rep0_range_0.s.fatigue', 'rep0_range_0.s.stress', 'rep0_range_0.s.experience', 'rep0_range_0.r.s.fatigue_param', 'rep0_range_0.r.probdens', 'rep0_range_0.time', 'rep1_range_1.s.fatigue', 'rep1_range_1.s.stress', 'rep1_range_1.s.experience', 'rep1_range_1.r.s.fatigue_param', 'rep1_range_1.r.probdens', 'rep1_range_1.time', 'rep2_range_2.s.fatigue', 'rep2_range_2.s.stress', 'rep2_range_2.s.experience', 'rep2_range_2.r.s.fatigue_param', 'rep2_range_2.r.probdens', 'rep2_range_2.time', 'rep3_range_3.s.fatigue', 'rep3_range_3.s.stress', 'rep3_range_3.s.experience', 'rep3_range_3.r.s.fatigue_param', 'rep3_range_3.r.probdens', 'rep3_range_3.time', 'rep4_range_4.s.fatigue', 'rep4_range_4.s.stress', 'rep4_range_4.s.experience', 'rep4_range_4.r.s.fatigue_param', 'rep4_range_4.r.probdens', 'rep4_range_4.time', 'rep5_range_5.s.fatigue', 'rep5_range_5.s.stress', 'rep5_range_5.s.experience', 'rep5_range_5.r.s.fatigue_param', 'rep5_range_5.r.probdens', 'rep5_range_5.time', 'rep6_range_6.s.fatigue', 'rep6_range_6.s.stress', 'rep6_range_6.s.experience', 'rep6_range_6.r.s.fatigue_param', 'rep6_range_6.r.probdens', 'rep6_range_6.time', 'rep7_range_7.s.fatigue', 'rep7_range_7.s.stress', 'rep7_range_7.s.experience', 'rep7_range_7.r.s.fatigue_param', 'rep7_range_7.r.probdens', 'rep7_range_7.time', 'rep8_range_8.s.fatigue', 'rep8_range_8.s.stress', 'rep8_range_8.s.experience', 'rep8_range_8.r.s.fatigue_param', 'rep8_range_8.r.probdens', 'rep8_range_8.time', 'rep9_range_9.s.fatigue', 'rep9_range_9.s.stress', 'rep9_range_9.s.experience', 'rep9_range_9.r.s.fatigue_param', 'rep9_range_9.r.probdens', 'rep9_range_9.time', 'rep0_range_10.s.fatigue', 'rep0_range_10.s.stress', 'rep0_range_10.s.experience', 'rep0_range_10.r.s.fatigue_param', 'rep0_range_10.r.probdens', 'rep0_range_10.time', 'rep1_range_11.s.fatigue', 'rep1_range_11.s.stress', 'rep1_range_11.s.experience', 'rep1_range_11.r.s.fatigue_param', 'rep1_range_11.r.probdens', 'rep1_range_11.time', 'rep2_range_12.s.fatigue', 'rep2_range_12.s.stress', 'rep2_range_12.s.experience', 'rep2_range_12.r.s.fatigue_param', 'rep2_range_12.r.probdens', 'rep2_range_12.time', 'rep3_range_13.s.fatigue', 'rep3_range_13.s.stress', 'rep3_range_13.s.experience', 'rep3_range_13.r.s.fatigue_param', 'rep3_range_13.r.probdens', 'rep3_range_13.time', 'rep4_range_14.s.fatigue', 'rep4_range_14.s.stress', 'rep4_range_14.s.experience', 'rep4_range_14.r.s.fatigue_param', 'rep4_range_14.r.probdens', 'rep4_range_14.time', 'rep5_range_15.s.fatigue', 'rep5_range_15.s.stress', 'rep5_range_15.s.experience', 'rep5_range_15.r.s.fatigue_param', 'rep5_range_15.r.probdens', 'rep5_range_15.time', 'rep6_range_16.s.fatigue', 'rep6_range_16.s.stress', 'rep6_range_16.s.experience', 'rep6_range_16.r.s.fatigue_param', 'rep6_range_16.r.probdens', 'rep6_range_16.time', 'rep7_range_17.s.fatigue', 'rep7_range_17.s.stress', 'rep7_range_17.s.experience', 'rep7_range_17.r.s.fatigue_param', 'rep7_range_17.r.probdens', 'rep7_range_17.time', 'rep8_range_18.s.fatigue', 'rep8_range_18.s.stress', 'rep8_range_18.s.experience', 'rep8_range_18.r.s.fatigue_param', 'rep8_range_18.r.probdens', 'rep8_range_18.time', 'rep9_range_19.s.fatigue', 'rep9_range_19.s.stress', 'rep9_range_19.s.experience', 'rep9_range_19.r.s.fatigue_param', 'rep9_range_19.r.probdens', 'rep9_range_19.time', 'rep0_range_20.s.fatigue', 'rep0_range_20.s.stress', 'rep0_range_20.s.experience', 'rep0_range_20.r.s.fatigue_param', 'rep0_range_20.r.probdens', 'rep0_range_20.time', 'rep1_range_21.s.fatigue', 'rep1_range_21.s.stress', 'rep1_range_21.s.experience', 'rep1_range_21.r.s.fatigue_param', 'rep1_range_21.r.probdens', 'rep1_range_21.time', 'rep2_range_22.s.fatigue', 'rep2_range_22.s.stress', 'rep2_range_22.s.experience', 'rep2_range_22.r.s.fatigue_param', 'rep2_range_22.r.probdens', 'rep2_range_22.time', 'rep3_range_23.s.fatigue', 'rep3_range_23.s.stress', 'rep3_range_23.s.experience', 'rep3_range_23.r.s.fatigue_param', 'rep3_range_23.r.probdens', 'rep3_range_23.time', 'rep4_range_24.s.fatigue', 'rep4_range_24.s.stress', 'rep4_range_24.s.experience', 'rep4_range_24.r.s.fatigue_param', 'rep4_range_24.r.probdens', 'rep4_range_24.time', 'rep5_range_25.s.fatigue', 'rep5_range_25.s.stress', 'rep5_range_25.s.experience', 'rep5_range_25.r.s.fatigue_param', 'rep5_range_25.r.probdens', 'rep5_range_25.time', 'rep6_range_26.s.fatigue', 'rep6_range_26.s.stress', 'rep6_range_26.s.experience', 'rep6_range_26.r.s.fatigue_param', 'rep6_range_26.r.probdens', 'rep6_range_26.time', 'rep7_range_27.s.fatigue', 'rep7_range_27.s.stress', 'rep7_range_27.s.experience', 'rep7_range_27.r.s.fatigue_param', 'rep7_range_27.r.probdens', 'rep7_range_27.time', 'rep8_range_28.s.fatigue', 'rep8_range_28.s.stress', 'rep8_range_28.s.experience', 'rep8_range_28.r.s.fatigue_param', 'rep8_range_28.r.probdens', 'rep8_range_28.time', 'rep9_range_29.s.fatigue', 'rep9_range_29.s.stress', 'rep9_range_29.s.experience', 'rep9_range_29.r.s.fatigue_param', 'rep9_range_29.r.probdens', 'rep9_range_29.time', 'rep0_range_30.s.fatigue', 'rep0_range_30.s.stress', 'rep0_range_30.s.experience', 'rep0_range_30.r.s.fatigue_param', 'rep0_range_30.r.probdens', 'rep0_range_30.time', 'rep1_range_31.s.fatigue', 'rep1_range_31.s.stress', 'rep1_range_31.s.experience', 'rep1_range_31.r.s.fatigue_param', 'rep1_range_31.r.probdens', 'rep1_range_31.time', 'rep2_range_32.s.fatigue', 'rep2_range_32.s.stress', 'rep2_range_32.s.experience', 'rep2_range_32.r.s.fatigue_param', 'rep2_range_32.r.probdens', 'rep2_range_32.time', 'rep3_range_33.s.fatigue', 'rep3_range_33.s.stress', 'rep3_range_33.s.experience', 'rep3_range_33.r.s.fatigue_param', 'rep3_range_33.r.probdens', 'rep3_range_33.time', 'rep4_range_34.s.fatigue', 'rep4_range_34.s.stress', 'rep4_range_34.s.experience', 'rep4_range_34.r.s.fatigue_param', 'rep4_range_34.r.probdens', 'rep4_range_34.time', 'rep5_range_35.s.fatigue', 'rep5_range_35.s.stress', 'rep5_range_35.s.experience', 'rep5_range_35.r.s.fatigue_param', 'rep5_range_35.r.probdens', 'rep5_range_35.time', 'rep6_range_36.s.fatigue', 'rep6_range_36.s.stress', 'rep6_range_36.s.experience', 'rep6_range_36.r.s.fatigue_param', 'rep6_range_36.r.probdens', 'rep6_range_36.time', 'rep7_range_37.s.fatigue', 'rep7_range_37.s.stress', 'rep7_range_37.s.experience', 'rep7_range_37.r.s.fatigue_param', 'rep7_range_37.r.probdens', 'rep7_range_37.time', 'rep8_range_38.s.fatigue', 'rep8_range_38.s.stress', 'rep8_range_38.s.experience', 'rep8_range_38.r.s.fatigue_param', 'rep8_range_38.r.probdens', 'rep8_range_38.time', 'rep9_range_39.s.fatigue', 'rep9_range_39.s.stress', 'rep9_range_39.s.experience', 'rep9_range_39.r.s.fatigue_param', 'rep9_range_39.r.probdens', 'rep9_range_39.time', 'rep0_range_40.s.fatigue', 'rep0_range_40.s.stress', 'rep0_range_40.s.experience', 'rep0_range_40.r.s.fatigue_param', 'rep0_range_40.r.probdens', 'rep0_range_40.time', 'rep1_range_41.s.fatigue', 'rep1_range_41.s.stress', 'rep1_range_41.s.experience', 'rep1_range_41.r.s.fatigue_param', 'rep1_range_41.r.probdens', 'rep1_range_41.time', 'rep2_range_42.s.fatigue', 'rep2_range_42.s.stress', 'rep2_range_42.s.experience', 'rep2_range_42.r.s.fatigue_param', 'rep2_range_42.r.probdens', 'rep2_range_42.time', 'rep3_range_43.s.fatigue', 'rep3_range_43.s.stress', 'rep3_range_43.s.experience', 'rep3_range_43.r.s.fatigue_param', 'rep3_range_43.r.probdens', 'rep3_range_43.time', 'rep4_range_44.s.fatigue', 'rep4_range_44.s.stress', 'rep4_range_44.s.experience', 'rep4_range_44.r.s.fatigue_param', 'rep4_range_44.r.probdens', 'rep4_range_44.time', 'rep5_range_45.s.fatigue', 'rep5_range_45.s.stress', 'rep5_range_45.s.experience', 'rep5_range_45.r.s.fatigue_param', 'rep5_range_45.r.probdens', 'rep5_range_45.time', 'rep6_range_46.s.fatigue', 'rep6_range_46.s.stress', 'rep6_range_46.s.experience', 'rep6_range_46.r.s.fatigue_param', 'rep6_range_46.r.probdens', 'rep6_range_46.time', 'rep7_range_47.s.fatigue', 'rep7_range_47.s.stress', 'rep7_range_47.s.experience', 'rep7_range_47.r.s.fatigue_param', 'rep7_range_47.r.probdens', 'rep7_range_47.time', 'rep8_range_48.s.fatigue', 'rep8_range_48.s.stress', 'rep8_range_48.s.experience', 'rep8_range_48.r.s.fatigue_param', 'rep8_range_48.r.probdens', 'rep8_range_48.time', 'rep9_range_49.s.fatigue', 'rep9_range_49.s.stress', 'rep9_range_49.s.experience', 'rep9_range_49.r.s.fatigue_param', 'rep9_range_49.r.probdens', 'rep9_range_49.time'])
fig, axs = hist_psf_short.plot_line('s.fatigue', 's.stress', aggregation='mean_bound', xlabel="time (hours)",
                           ylabels={'s.fatigue': 'level','s.stress': 'level (%)'}, h_padding=0.3,
                           titles={'s.fatigue': 'fatigue', 's.stress': 'stress'})
../../_images/572d1e969c58c12452f2a5930db331c0b4da91c7eae27314c72d766e7cfdca45.png
fig.savefig("outputs_paper_ifac_human/degraded_PSFs.pdf", format="pdf", bbox_inches = 'tight', pad_inches = 0)
RoverHumanParam().psfs
PSFParam(fatigue=0.0, stress=0.0)
from fmdtools.sim.sample import ParameterHistSample
pd_psf = ParameterDomain(RoverHumanParam)
pd_psf.add_variables('psfs.fatigue', 'psfs.stress')
phs = ParameterHistSample(hist_psf_short, 's.fatigue', 's.stress', paramdomain=pd_psf)
# phs.add_hist_times('default', 1, ts=(0, 10, 1))
phs.add_hist_groups(ts=(0, 10, 1), reps=5)
# phs.add_hist_scenario(rep=4, t=1)
len(phs.scenarios())
50
ec_hum, hist_hum = prop.parameter_sample(mdl, phs)
SCENARIOS COMPLETE: 100%|██████████| 50/50 [00:25<00:00,  1.94it/s]
from fmdtools.analyze.tabulate import NominalEnvelope
na = NominalEnvelope(phs, ec_hum, 'at_finish', 'p.psfs.fatigue', 'p.psfs.stress')
fig, ax = na.as_plot()
../../_images/26bac03f2af42c6a4a02c7694331b28a9c3b6d32920549dbc1c69136937d4853.png
na = NominalEnvelope(phs, ec_hum, 'at_finish', 'inputparams.t', 'inputparams.rep')
fig, ax = na.as_plot()
../../_images/2e4f135a2ea149cf19ec41d9209925c871b5f941fdfba4fcbef3163561b42ac2.png
fig.savefig("outputs_paper_ifac_human/nominal_PSF_completions.pdf", format="pdf", bbox_inches = 'tight', pad_inches = 0)
from fmdtools.sim.sample import SampleApproach
sa = SampleApproach(mdl)
sa.add_faultdomains(**{'drive': (('all_fxn_modes', 'drive'), {})})
sa.add_faultsamples(**{'drive': (('fault_phases', 'drive', 'start'), {})})
sa.scenarios()
[SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.drive': ['custom']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.drive', fault='custom', rate=np.float64(1.0), name='roverhuman_fxns_drive_custom_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.drive': ['elec_open']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.drive', fault='elec_open', rate=np.float64(1.0), name='roverhuman_fxns_drive_elec_open_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.drive': ['stuck']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.drive', fault='stuck', rate=np.float64(1.0), name='roverhuman_fxns_drive_stuck_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.drive': ['stuck_left']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.drive', fault='stuck_left', rate=np.float64(1.0), name='roverhuman_fxns_drive_stuck_left_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.drive': ['stuck_right']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.drive', fault='stuck_right', rate=np.float64(1.0), name='roverhuman_fxns_drive_stuck_right_t15p0', time=np.float64(15.0), phase='start')]
f_ecs, f_hists, apps = prop.nested_sample(mdl, phs,
                                          faultdomains={'drive': (('all_fxn_modes', 'drive'), {})},
                                          faultsamples={'drive': (('fault_phases', 'drive', 'start'), {})})
SCENARIOS COMPLETE:  12%|█▏        | 6/50 [00:16<02:01,  2.75s/it]C:\Users\dhulse\Documents\GitHub\fmdtools\src\fmdtools\sim\propagate.py:688: UserWarning: Faults found during the nominal run {'comprehend.failed_no_action': Fault(prob=1.0, cost=0.0, phases=(), disturbances=(), units='sim')}
  warnings.warn("Faults found during the nominal run " + str(endfaults))
SCENARIOS COMPLETE:  18%|█▊        | 9/50 [00:29<02:39,  3.90s/it]C:\Users\dhulse\Documents\GitHub\fmdtools\src\fmdtools\sim\propagate.py:688: UserWarning: Faults found during the nominal run {'percieve.failed_no_action': Fault(prob=1.0, cost=0.0, phases=(), disturbances=(), units='sim')}
  warnings.warn("Faults found during the nominal run " + str(endfaults))
SCENARIOS COMPLETE: 100%|██████████| 50/50 [02:53<00:00,  3.47s/it]
apps['hist_0'].get_scen_groups()
{(): ['roverhuman_fxns_drive_custom_t15p0',
  'roverhuman_fxns_drive_elec_open_t15p0',
  'roverhuman_fxns_drive_stuck_t15p0',
  'roverhuman_fxns_drive_stuck_left_t15p0',
  'roverhuman_fxns_drive_stuck_right_t15p0']}
apps['hist_2'].faultsamples['drive'].scenarios()
[SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.drive': ['custom']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.drive', fault='custom', rate=np.float64(1.0), name='roverhuman_fxns_drive_custom_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.drive': ['elec_open']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.drive', fault='elec_open', rate=np.float64(1.0), name='roverhuman_fxns_drive_elec_open_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.drive': ['stuck']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.drive', fault='stuck', rate=np.float64(1.0), name='roverhuman_fxns_drive_stuck_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.drive': ['stuck_left']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.drive', fault='stuck_left', rate=np.float64(1.0), name='roverhuman_fxns_drive_stuck_left_t15p0', time=np.float64(15.0), phase='start'),
 SingleFaultScenario(sequence={15.0: Injection(faults={'roverhuman.fxns.drive': ['stuck_right']}, disturbances={})}, times=(np.float64(15.0),), function='roverhuman.fxns.drive', fault='stuck_right', rate=np.float64(1.0), name='roverhuman_fxns_drive_stuck_right_t15p0', time=np.float64(15.0), phase='start')]
from fmdtools.analyze.tabulate import NestedComparison
nc = NestedComparison(f_ecs, phs, ['inputparams.t'], apps, ['fault'], metrics=['end_dist', 'tot_deviation'])
nc.sort_by_factor('fault')
nc.sort_by_factor('inputparams.t')
nc.as_table()
end_dist tot_deviation
1 stuck_left 24.035598 0.310888
0 stuck_left 24.035598 0.310888
2 stuck_left 24.035598 0.310888
5 stuck_left 24.035598 0.310888
4 stuck_left 24.035598 0.310888
3 stuck_left 24.035598 0.310888
4 stuck_right 24.415309 0.216505
0 stuck_right 24.415309 0.216505
2 stuck_right 24.415309 0.216505
1 stuck_right 24.415309 0.216505
3 stuck_right 24.415309 0.216505
5 stuck_right 24.415309 0.216505
1 elec_open 25.401902 0.118596
stuck 11.448310 0.118596
0 elec_open 25.401902 0.118596
custom 0.000000 0.118596
1 custom 0.000000 0.118596
0 stuck 11.448310 0.118596
3 stuck 11.448310 0.118596
elec_open 25.401902 0.118596
custom 0.000000 0.118596
2 stuck 11.448310 0.118596
custom 0.000000 0.118596
elec_open 25.401902 0.118596
4 elec_open 25.401902 0.118596
custom 0.000000 0.118596
5 custom 0.000000 0.118596
4 stuck 11.448310 0.118596
5 stuck 11.448310 0.118596
elec_open 25.401902 0.118596
6 custom 28.917244 0.000000
elec_open 28.917244 0.000000
stuck 28.917244 0.000000
stuck_left 28.917244 0.000000
stuck_right 28.917244 0.000000
7 custom 28.917244 0.000000
elec_open 28.917244 0.000000
stuck 28.917244 0.000000
stuck_left 28.917244 0.000000
stuck_right 28.917244 0.000000
8 custom 28.917244 0.000000
elec_open 28.917244 0.000000
stuck 28.917244 0.000000
stuck_left 28.917244 0.000000
stuck_right 28.917244 0.000000
9 custom 28.917244 0.000000
elec_open 28.917244 0.000000
stuck 28.917244 0.000000
stuck_left 28.917244 0.000000
stuck_right 28.917244 0.000000
fig, axs = nc.as_plots('end_dist', 'tot_deviation', figsize = (8, 4))
../../_images/6cbbb2b9bad5a22675743be46a89ca732a5de26a79b342e5f388d0328bba8944.png