def test_redundant_invariants(): 'test removing of redundant invariants' ha = HybridAutomaton() mode = ha.new_mode('mode') # dynamics: x' = 1, y' = 1, a' = 0 mode.set_dynamics([[0, 0, 1], [0, 0, 1], [0, 0, 0]]) # invariant: x <= 2.5 mode.set_invariant([[1, 0, 0]], [2.5]) # initial set has x0 = [0, 1] init_lpi = lputil.from_box([(0, 1), (0, 1), (1, 1)], mode) init_list = [StateSet(init_lpi, mode)] # settings, step size = 0.1 settings = HylaaSettings(0.1, 5.0) settings.stdout = HylaaSettings.STDOUT_NONE settings.plot.plot_mode = PlotSettings.PLOT_NONE result = Core(ha, settings).run(init_list) # check last cur_state to ensure redundant constraints were not added assert result.last_cur_state.lpi.get_num_rows() == 3 + 2*3 + 1 # 3 for basis matrix, 2*3 for initial constraints
def run_hylaa(): 'Runs hylaa with the given settings' ha = define_ha() settings = define_settings() tuples = [] # tuples.append((HylaaSettings.APPROX_NONE, "tmpc1_x_z.mp4")) tuples.append((HylaaSettings.APPROX_NONE, "tmpc1_x_y.png")) # tuples.append((HylaaSettings.APPROX_CHULL, "tmpc_chull1.png")) # tuples.append((HylaaSettings.APPROX_LGG, "approx_lgg.png")) p1_box = [[0.4, 5], [-0.2, 0.5], [-0.2, 0.5]] p1mode = ha.new_mode('p1mode') p1_lpi = lputil.from_box(p1_box, p1mode) p1_ah_polytope = convert_lpi_to_ah_polytope(p1_lpi=p1_lpi, dims=len(p1_box)) # print(P1_lpi) # P1_poly_con_matrix = [[-1, 0, 0], [1, 0, 0], [0, -1, 0], [0, 1, 0], [0, 0, -1], [0, 0, 1]] # P1_poly_rhs = [-0.4, 5, 0.2, 0.5, 0.2, 0.5] # P1_poly_types = [3, 3, 3, 3, 3, 3] # P1_poly = Polytope(con_matrix=P1_poly_con_matrix, rhs=P1_poly_rhs, con_types=P1_poly_types) # P1_lpi = P1_poly for model, filename in tuples: settings.approx_model, settings.plot.filename = model, filename init_states = make_init(ha) print(f"\nMaking {filename}...") Core(ha, settings).run(init_states, p1_ah_polytope)
def plot_hylaa(abortmin, abortmax, stepsize=1.0, aggregation='deagg', axis_limits=None, filename='out.png'): 'run hylaa a single time' ha = make_automaton(abortmin, abortmax) init_states = make_init(ha) settings = make_settings(stepsize, aggregation, axis_limits, filename) print(f"running {aggregation} with step {stepsize}") result = Core(ha, settings).run(init_states) safe = not result.has_concrete_error if aggregation == 'agg': safe = not result.has_aggregated_error secs = result.top_level_timer.total_secs print(f"finished in {secs} secs") return [safe, secs]
def test_zero_dynamics(): 'test a system with zero dynamic (only should process one frame)' ha = HybridAutomaton() # with time and affine variable mode = ha.new_mode('mode') mode.set_dynamics([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]) # initial set init_lpi = lputil.from_box([(-5, -5), (0, 1), (0, 0), (1, 1)], mode) init_list = [StateSet(init_lpi, mode)] # settings settings = HylaaSettings(math.pi/4, 20*math.pi) settings.stdout = HylaaSettings.STDOUT_VERBOSE settings.plot.plot_mode = PlotSettings.PLOT_NONE core = Core(ha, settings) core.setup(init_list) core.do_step() # pop core.do_step() # propagate and remove assert core.aggdag.get_cur_state() is None, "cur state should be none, since mode dynamics were zero"
def run_hylaa(self, predictions): self.ha = None self.predictions = None self.modeList = [] self.initialState = None self.ha = HybridAutomaton() self.predictions = predictions self.graphPredictions() self.make_automaton() initialBox = self.make_init(self.predictions[0][0]) core = Core(self.ha, self.settings) profile.runctx( 'resultprof = self.run_hylaa_profile(initialBox, core)', globals(), locals(), filename= "/home/nvidia/f1racing/f110_ws/src/ppcm/reachability/scripts/profiler/prof/out_tmp.prof" ) result = locals()['resultprof'] #result = core.run(initialBox) reachsets = [ result.plot_data.get_verts_list(mode)[0] for mode in self.modeList ] return reachsets
def hylaa_single(abortmin, abortmax, stepsize=1.0, aggregation='deagg'): 'run hylaa a single time' r = (abortmax - abortmin) / 2.0 print(f"Running hylaa with r={r}, stepsize={stepsize}, {aggregation}... ", end='') ha = make_automaton(abortmin, abortmax) init_states = make_init(ha) settings = make_settings(abortmin, abortmax, stepsize, aggregation) result = Core(ha, settings).run(init_states) safe = "unsafe" if result.has_concrete_error else "safe" if aggregation == 'agg': safe = "unsafe" if result.has_aggregated_error else "safe" secs = result.top_level_timer.total_secs rv = [safe, secs] print(rv) return rv
def test_init_outside_invariant(): 'test when initial state is outside of the mode invariant' ha = HybridAutomaton() mode = ha.new_mode('mode') mode.set_dynamics([[0, 0, 1], [0, 0, 1], [0, 0, 0]]) # x' = 1, y' = 1, a' = 0 # x <= 2.5 mode.set_invariant([[1, 0, 0]], [2.5]) # initial set, x = [3, 4] init_lpi = lputil.from_box([(3, 4), (0, 1), (1, 1)], mode) init_list = [StateSet(init_lpi, mode)] # transition to error if x >= 10 error = ha.new_mode('error') trans = ha.new_transition(mode, error) trans.set_guard([[-1., 0, 0],], [-10]) # settings settings = HylaaSettings(1.0, 5.0) settings.stdout = HylaaSettings.STDOUT_VERBOSE try: Core(ha, settings).run(init_list) assert False, "running with initial state outside of invariant did not raise RuntimeError" except RuntimeError: pass
def run_hylaa(): 'runs hylaa' ha = define_ha() init = define_init_states(ha) settings = define_settings() result = Core(ha, settings).run(init)
def run_hylaa(): 'Runs hylaa with the given settings' ha = define_ha() settings = define_settings() init_states = make_init(ha) Core(ha, settings).run(init_states)
def test_agg_with_reset(): 'test the aggregation of states with a reset' # m1 dynamics: x' == 1, y' == 0, x0: [-3, -2], y0: [0, 1], step: 1.0 # m1 invariant: x + y <= 0 # m1 -> m2 guard: x + y >= 0 and y <= 0.5, reset = [[0, -1, 0], [1, 0, 0]] (x' = -y, y' = x, remove a) # m2 dynamics: x' == 0, y' == 0 # time bound: 4 # expected result: last state is line (not box!) from (0, 0) to (-0.5, -0.5) ha = HybridAutomaton() # mode one: x' = 1, y' = 0, a' = 0 m1 = ha.new_mode('m1') m1.set_dynamics([[0, 0, 1], [0, 0, 0], [0, 0, 0]]) # mode two: x' = 0, y' = 1 m2 = ha.new_mode('m2') m2.set_dynamics([[0, 0], [0, 0]]) # invariant: x + y <= 0 m1.set_invariant([[1, 1, 0]], [0]) # guard: x + y == 0 & y <= 0.5 trans1 = ha.new_transition(m1, m2, 'trans1') trans1.set_guard([[-1, -1, 0], [1, 1, 0], [0, 1, 0]], [0, 0, 0.5]) #trans1.set_reset(np.identity(3)[:2]) trans1.set_reset(np.array([[0, -1, 0], [1, 0, 0]], dtype=float)) # initial set has x0 = [-3, -2], y = [0, 1], a = 1 init_lpi = lputil.from_box([(-3, -2), (0, 1), (1, 1)], m1) init_list = [StateSet(init_lpi, m1)] # settings, step size = 1.0 settings = HylaaSettings(1.0, 4.0) settings.stdout = HylaaSettings.STDOUT_NONE settings.plot.plot_mode = PlotSettings.PLOT_NONE # use agg_box settings.aggstrat.agg_type = Aggregated.AGG_BOX core = Core(ha, settings) result = core.run(init_list) lpi = result.last_cur_state.lpi # 2 basis matrix rows, 4 init constraints rows, 6 rows from guard conditions (2 from each) assert lpi.get_num_rows() == 2 + 4 + 6 verts = result.last_cur_state.verts(core.plotman) assert len(verts) == 3 assert np.allclose(verts[0], verts[-1]) assert pair_almost_in((0, 0), verts) assert pair_almost_in((-0.5, -0.5), verts)
def run_hylaa(): 'Runs hylaa with the given settings' unsafe_box = [[0.7, 1.3], [-2, -1]] ha = define_ha(unsafe_box) settings = define_settings(unsafe_box) init_states = make_init(ha) Core(ha, settings).run(init_states)
def run_hylaa(): 'main entry point' ha = make_automaton() init_states = make_init(ha) settings = make_settings() Core(ha, settings).run(init_states)
def test_transition(): 'test a discrete transition' ha = HybridAutomaton() # mode one: x' = 1, t' = 1, a' = 0 m1 = ha.new_mode('m1') m1.set_dynamics([[0, 0, 1], [0, 0, 1], [0, 0, 0]]) # mode two: x' = -1, t' = 1, a' = 0 m2 = ha.new_mode('m2') m2.set_dynamics([[0, 0, -1], [0, 0, 1], [0, 0, 0]]) # invariant: t <= 2.5 m1.set_invariant([[0, 1, 0]], [2.5]) # guard: t >= 2.5 trans1 = ha.new_transition(m1, m2, 'trans1') trans1.set_guard([[0, -1, 0]], [-2.5]) # error t >= 4.5 error = ha.new_mode('error') trans2 = ha.new_transition(m2, error, "to_error") trans2.set_guard([[0, -1, 0]], [-4.5]) # initial set has x0 = [0, 1], t = [0, 0.2], a = 1 init_lpi = lputil.from_box([(0, 1), (0, 0.2), (1, 1)], m1) init_list = [StateSet(init_lpi, m1)] # settings, step size = 1.0 settings = HylaaSettings(1.0, 10.0) settings.stdout = HylaaSettings.STDOUT_VERBOSE settings.plot.plot_mode = PlotSettings.PLOT_NONE settings.plot.store_plot_result = True result = Core(ha, settings).run(init_list) ce = result.counterexample assert len(ce) == 2 assert ce[0].mode.name == 'm1' assert ce[0].outgoing_transition.name == 'trans1' assert ce[1].mode.name == 'm2' assert ce[1].outgoing_transition.name == 'to_error' assert ce[1].start[0] + 1e-9 >= 3.0 assert ce[1].end[0] - 1e-9 <= 2.0 polys = [obj[0] for obj in result.plot_data.mode_to_obj_list[0]['m1']] assert len(polys) == 4 polys = [obj[0] for obj in result.plot_data.mode_to_obj_list[0]['m2']] assert len(polys) == 3 assert result.last_cur_state.cur_steps_since_start[0] == 5
def test_agg_to_more_vars(): 'test the aggregation of states with a reset to a mode with new variables' ha = HybridAutomaton() # mode one: x' = 1, a' = 0 m1 = ha.new_mode('m1') m1.set_dynamics([[0, 1], [0, 0]]) # mode two: x' = 0, a' = 0, y' == 1 m2 = ha.new_mode('m2') m2.set_dynamics([[0, 0, 0], [0, 0, 0], [0, 1, 0]]) # invariant: x <= 3.0 m1.set_invariant([[1, 0]], [3.0]) # guard: True trans1 = ha.new_transition(m1, m2, 'trans1') trans1.set_guard_true() reset_mat = [[1, 0], [0, 1], [0, 0]] reset_minkowski = [[0], [0], [1]] reset_minkowski_constraints = [[1], [-1]] reset_minkowski_rhs = [3, -3] # y0 == 3 trans1.set_reset(reset_mat, reset_minkowski, reset_minkowski_constraints, reset_minkowski_rhs) # initial set has x0 = [0, 1], a = 1 init_lpi = lputil.from_box([(0, 1), (1, 1)], m1) init_list = [StateSet(init_lpi, m1)] # settings, step size = 1.0 settings = HylaaSettings(1.0, 4.0) settings.stdout = HylaaSettings.STDOUT_DEBUG settings.plot.plot_mode = PlotSettings.PLOT_NONE settings.plot.store_plot_result = True settings.plot.xdim_dir = 0 settings.plot.ydim_dir = {'m1': 1, 'm2': 2} result = Core(ha, settings).run(init_list) polys = [obj[0] for obj in result.plot_data.mode_to_obj_list[0]['m1']] # 4 steps because invariant is allowed to be false for the final step assert 4 <= len(polys) <= 5, "expected invariant to become false after 4/5 steps" assert_verts_is_box(polys[0], [[0, 1], [1, 1]]) assert_verts_is_box(polys[1], [[1, 2], [1, 1]]) assert_verts_is_box(polys[2], [[2, 3], [1, 1]]) assert_verts_is_box(polys[3], [[3, 4], [1, 1]]) polys = [obj[0] for obj in result.plot_data.mode_to_obj_list[0]['m2']] assert_verts_is_box(polys[0], [[1, 4], [3, 3]]) assert_verts_is_box(polys[1], [[1, 4], [4, 4]])
def run_hylaa(): 'main entry point' safe = True for passive_time in [120]: #range(5, 265, 5): print(passive_time) ha = make_automaton(safe, passive_time) init_states = make_init(ha) settings = make_settings(safe, passive_time) Core(ha, settings).run(init_states)
def run_hylaa(): 'main entry point' unsafe_box = [[5.1, 5.9], [4.1, 4.9]] ha = make_automaton(unsafe_box) init_states = make_init(ha) settings = make_settings(unsafe_box) Core(ha, settings).run(init_states)
def run_hylaa(): 'runs hylaa, returning a HylaaResult object' ha = define_ha() init = define_init_states(ha) settings = define_settings() core = Core(ha, settings) result = core.run(init) #core.aggdag.show() return result
def run_hylaa(): 'main entry point' safe = True ha = make_automaton(safe) init_states = make_init(ha) settings = make_settings(safe) Core(ha, settings).run(init_states)
def video_hylaa(abortmin, abortmax, stepsize=1.0): 'run hylaa a single time' ha = make_automaton(abortmin, abortmax) init_states = make_init(ha) settings = make_settings(stepsize, 'deagg') result = Core(ha, settings).run(init_states) safe = not result.has_concrete_error assert safe
def run_hylaa(is_sim=False): 'main entry point' theta_deg = 36 maxi = 60 ha = make_automaton(theta_deg, maxi) box = [(-0.017, -0.016), (-0.005, 0.005), (0, 0), (0, 0), (0, 0), (1.0, 1.0)] settings = make_settings(theta_deg, box) if not is_sim: result = Core(ha, settings).run(make_init(ha, box)) if result.counterexample: print(f"counterexample start: {result.counterexample[0].start}") else: init_mode = ha.modes['move_free'] settings.aggstrat.sim_avoid_modes.append('meshed') settings.plot.sim_line_width = 1.0 settings.plot.filename = "gearbox_sim.png" Core(ha, settings, seed=2).simulate(init_mode, box, 100)
def test_stateset_bad_init(): 'test constructing a stateset with a basis matrix that is not the identity (should raise error)' # this is from an issue reported by Mojtaba Zarei ha = HybridAutomaton() mode = ha.new_mode('mode') mode.set_dynamics([[0, 1], [-1, 0]]) # initial set init_lpi = lputil.from_box([(-5, -5), (0, 1)], mode) init_list = [StateSet(init_lpi, mode)] # settings settings = HylaaSettings(math.pi/4, math.pi) settings.stdout = HylaaSettings.STDOUT_NONE settings.plot.store_plot_result = True settings.plot.plot_mode = PlotSettings.PLOT_NONE core = Core(ha, settings) result = core.run(init_list) # use last result stateset = result.last_cur_state mode = stateset.mode lpi = stateset.lpi try: init_states = [StateSet(lpi, mode)] settings = HylaaSettings(0.1, 0.1) core = Core(ha, settings) result = core.run(init_states) assert False, "assertion should be raised if init basis matrix is not identity" except RuntimeError: pass
def test_ha(): 'test for the harmonic oscillator example with line initial set (from ARCH 2018 paper)' ha = HybridAutomaton() # with time and affine variable mode = ha.new_mode('mode') mode.set_dynamics([[0, 1, 0, 0], [-1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 0, 0]]) error = ha.new_mode('error') trans1 = ha.new_transition(mode, error) trans1.set_guard([[1., 0, 0, 0], [-1., 0, 0, 0]], [4.0, -4.0]) # initial set init_lpi = lputil.from_box([(-5, -5), (0, 1), (0, 0), (1, 1)], mode) init_list = [StateSet(init_lpi, mode)] # settings settings = HylaaSettings(math.pi/4, 2*math.pi) settings.stdout = HylaaSettings.STDOUT_VERBOSE settings.plot.store_plot_result = True settings.plot.plot_mode = PlotSettings.PLOT_NONE core = Core(ha, settings) result = core.run(init_list) assert result.has_concrete_error ce = result.counterexample[0] # [-5.0, 0.6568542494923828, 0.0, 1.0] -> [4.0, 3.0710678118654737, 2.356194490192345, 1.0] assert ce.mode == mode assert np.allclose(ce.start, np.array([-5, 0.65685, 0, 1], dtype=float)) assert np.allclose(ce.end, np.array([4, 3.07106, 2.35619, 1], dtype=float)) # check the reachable state (should always have x <= 3.5) obj_list = result.plot_data.mode_to_obj_list[0][mode.name] for obj in obj_list: verts = obj[0] for vert in verts: x, _ = vert assert x <= 4.9
def run_hylaa(): 'Runs hylaa with the given settings' ha = define_ha() settings = define_settings() tuples = [] tuples.append((HylaaSettings.APPROX_NONE, "approx_none.png")) # tuples.append((HylaaSettings.APPROX_CHULL, "approx_chull.png")) # tuples.append((HylaaSettings.APPROX_LGG, "approx_lgg.png")) for model, filename in tuples: settings.approx_model, settings.plot.filename = model, filename init_states = make_init(ha) print(f"\nMaking {filename}...") Core(ha, settings).run(init_states)
def run_hylaa(tmax=0.1, step=0.001): 'main entry point' theta_deg = 36 maxi = 60 ha = make_automaton(theta_deg, maxi) box = [(-0.017, -0.016), (-0.005, 0.005), (0, 0), (0, 0), (0, 0), (1.0, 1.0)] settings = make_settings(theta_deg, box, tmax, step) # settings for tiem measurements settings.plot.plot_mode = PlotSettings.PLOT_NONE settings.plot.filename = "gearbox.png" settings.stdout = HylaaSettings.STDOUT_NORMAL settings.skip_zero_dynamics_modes = True settings.aggstrat.deaggregate = True # use deaggregation settings.aggstrat.deagg_preference = Aggregated.DEAGG_ROOT_FIRST settings.aggstrat.agg_type = Aggregated.AGG_BOX #settings.aggstrat = Unaggregated() # leaves-first: 17.6, 52 deaggs # root-first: 11.2, 35 deaggs # most states: 16.1, 49 deaggs # # box agg: 10.2, 38 deaggs # chull-agg: timeout # full-agg: timeout # spaceex: timeout # # unaggregated: 18 sec; a bit surprising it can finish # the comparison is more interesting with step=0.0001, for this, we'll want to enable re-aggregation... # this requires more experimentation / implementation so we omit this result until we can investigate it further result = Core(ha, settings).run(make_init(ha, box)) # print stats Timers.print_stats_recursive(result.top_level_timer, 0, None) if result.counterexample: print(f"counterexample start: {result.counterexample[0].start}")
def test_unaggregation(): 'test an unaggregated discrete transition' ha = HybridAutomaton() # mode one: x' = 1, t' = 1, a' = 0 m1 = ha.new_mode('m1') m1.set_dynamics([[0, 0, 1], [0, 0, 1], [0, 0, 0]]) # mode two: x' = -1, t' = 1, a' = 0 m2 = ha.new_mode('m2') m2.set_dynamics([[0, 0, -1], [0, 0, 1], [0, 0, 0]]) # invariant: t <= 2.5 m1.set_invariant([[0, 1, 0]], [2.5]) # guard: t >= 0.5 trans1 = ha.new_transition(m1, m2, 'trans1') trans1.set_guard([[0, -1, 0]], [-0.5]) # error x >= 4.5 error = ha.new_mode('error') trans2 = ha.new_transition(m2, error, "to_error") trans2.set_guard([[-1, 0, 0]], [-4.5]) # initial set has x0 = [0, 0.2], t = [0, 0.2], a = 1 init_lpi = lputil.from_box([(0, 0.2), (0, 0.2), (1, 1)], m1) init_list = [StateSet(init_lpi, m1)] # settings, step size = 1.0 settings = HylaaSettings(1.0, 10.0) settings.stdout = HylaaSettings.STDOUT_DEBUG settings.plot.store_plot_result = True settings.plot.plot_mode = PlotSettings.PLOT_NONE settings.aggstrat = aggstrat.Unaggregated() result = Core(ha, settings).run(init_list) # expected no exception # m2 should be reachable polys = [obj[0] for obj in result.plot_data.mode_to_obj_list[0]['m2']] assert len(polys) > 15
def run_hylaa(self, predictions): self.ha = None self.predictions = None self.modeList = [] self.initialState = None self.ha = HybridAutomaton() self.predictions = predictions self.graphPredictions() self.make_automaton() initialBox = self.make_init(self.predictions[0][0]) core = Core(self.ha, self.settings) result = core.run(initialBox) reachsets = [ result.plot_data.get_verts_list(mode)[0] for mode in self.modeList ] return reachsets
def test_agg_no_counterexample(): 'test that aggregation to error does not create a counterexample' # m1 dynamics: x' == 1, y' == 0, x0, y0: [0, 1], step: 1.0 # m1 invariant: x <= 3 # m1 -> m2 guard: True # m2 dynamics: x' == 0, y' == 1 # m2 -> error: y >= 3 ha = HybridAutomaton() # mode one: x' = 1, y' = 0, a' = 0 m1 = ha.new_mode('m1') m1.set_dynamics([[0, 0, 1], [0, 0, 0], [0, 0, 0]]) # mode two: x' = 0, y' = 1, a' = 0 m2 = ha.new_mode('m2') m2.set_dynamics([[0, 0, 0], [0, 0, 1], [0, 0, 0]]) # invariant: x <= 3.0 m1.set_invariant([[1, 0, 0]], [3.0]) # guard: True trans1 = ha.new_transition(m1, m2, 'trans1') trans1.set_guard_true() error = ha.new_mode('error') trans2 = ha.new_transition(m2, error, 'trans2') trans2.set_guard([[0, -1, 0]], [-3]) # y >= 3 # initial set has x0 = [0, 1], t = [0, 1], a = 1 init_lpi = lputil.from_box([(0, 1), (0, 1), (1, 1)], m1) init_list = [StateSet(init_lpi, m1)] # settings, step size = 1.0 settings = HylaaSettings(1.0, 10.0) settings.stdout = HylaaSettings.STDOUT_DEBUG settings.plot.plot_mode = PlotSettings.PLOT_NONE result = Core(ha, settings).run(init_list) assert not result.counterexample
def test_over_time_range(): 'test plotting over time with aggergation (time range)' ha = HybridAutomaton() mode_a = ha.new_mode('A') mode_b = ha.new_mode('B') # dynamics: x' = a, a' = 0 mode_a.set_dynamics([[0, 1], [0, 0]]) mode_b.set_dynamics([[0, 1], [0, 0]]) # invariant: x <= 2.5 mode_a.set_invariant([[1, 0]], [2.5]) trans1 = ha.new_transition(mode_a, mode_b, 'first') trans1.set_guard_true() # initial set has x0 = [0, 0] init_lpi = lputil.from_box([(0, 0), (1, 1)], mode_a) init_list = [StateSet(init_lpi, mode_a)] # settings, step size = 1.0 settings = HylaaSettings(1.0, 4.0) settings.stdout = HylaaSettings.STDOUT_DEBUG settings.process_urgent_guards = True settings.plot.plot_mode = PlotSettings.PLOT_NONE settings.plot.store_plot_result = True settings.plot.xdim_dir = None settings.plot.ydim_dir = 0 result = Core(ha, settings).run(init_list) polys = [obj[0] for obj in result.plot_data.mode_to_obj_list[0][mode_b.name]] # expected with aggegregation: [0, 2.5] -> [1, 3.5] -> [2, 4.5] -> [3, 5.5] -> [4, 6.5] # 4 steps because invariant is allowed to be false for the final step assert len(polys) == 5, "expected invariant to become false after 5 steps" for i in range(5): assert_verts_is_box(polys[i], [[i, i + 3.0], [i, i + 3.0]])
def test_plot_over_time(): 'test doing a plot over time' ha = HybridAutomaton() mode = ha.new_mode('mode') mode.set_dynamics([[0, 1], [-1, 0]]) # initial set init_lpi = lputil.from_box([(-5, -4), (0, 1)], mode) init_list = [StateSet(init_lpi, mode)] # settings settings = HylaaSettings(math.pi/4, math.pi) settings.stdout = HylaaSettings.STDOUT_VERBOSE settings.plot.store_plot_result = True settings.plot.plot_mode = PlotSettings.PLOT_NONE settings.plot.ydim_dir = None # y dimension will be time result = Core(ha, settings).run(init_list) assert not result.has_aggregated_error and not result.has_concrete_error # check the reachable state # we would expect at the end that x = [4, 5], t = pi obj_list = result.plot_data.mode_to_obj_list[0][mode.name] for vert in obj_list[0][0]: x, y = vert assert abs(y) < 1e-6, "initial poly time is wrong" assert abs(-5 - x) < 1e-6 or abs(-4 - x) < 1e-6 for vert in obj_list[-1][0]: x, y = vert assert abs(math.pi - y) < 1e-6, "final poly time is wrong" assert abs(5 - x) < 1e-6 or abs(4 - x) < 1e-6
def test_init_unsat(): 'initial region unsat with multiple invariant conditions' ha = HybridAutomaton() mode = ha.new_mode('A') mode.set_dynamics(np.identity(2)) mode.set_invariant([[1, 0], [1, 0]], [2, 3]) # x <= 2 and x <= 3 # initial set lpi1 = lputil.from_box([(10, 11), (0, 1)], mode) lpi2 = lputil.from_box([(0, 1), (0, 1)], mode) init_list = [StateSet(lpi1, mode), StateSet(lpi2, mode)] # settings settings = HylaaSettings(1, 5) settings.stdout = HylaaSettings.STDOUT_VERBOSE settings.plot.plot_mode = PlotSettings.PLOT_NONE core = Core(ha, settings) core.run(init_list) # expect no exception during running