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 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 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 define_ha(limit): '''make the hybrid automaton and return it''' ha = HybridAutomaton() mode = ha.new_mode('mode') dynamics = loadmat('build.mat') a_matrix = dynamics['A'] b_matrix = csc_matrix(dynamics['B']) mode.set_dynamics(csr_matrix(a_matrix)) # 0.8 <= u1 <= 1.0 u_mat = [[1.0], [-1.0]] u_rhs = [1.0, -0.8] mode.set_inputs(b_matrix, u_mat, u_rhs) error = ha.new_mode('error') y1 = dynamics['C'][0] mat = csr_matrix(y1, dtype=float) trans1 = ha.new_transition(mode, error) rhs = np.array([-limit], dtype=float) # safe trans1.set_guard(mat, rhs) # y3 >= limit return ha
def define_ha(): '''make the hybrid automaton''' ha = HybridAutomaton(discrete=True) a_matrix = [[1, T_const, -T_const], [0, 1, 0], [0, 0, 1]] a_matrix_inv = np.linalg.inv(a_matrix) b_mat = [[0.5 * T_const * T_const, -0.5 * T_const * T_const], [T_const, 0], [0, T_const]] # b_mat = [[0.5*T_const*T_const, -0.5*T_const*T_const, 1], [T_const, 0, 1], [0, T_const, 1]] a_inv_b_mat = -1 * np.matmul(a_matrix_inv, b_mat) # print(a_inv_b_mat) b_constraints = [[1, 0], [-1, 0], [0, 1], [0, -1]] b_rhs = [0.26, 0.46, 0.26, 0.47] # b_constraints = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]] # b_rhs = [0.26, 0.46, 0.26, 0.47, 0.005, 0.005] mode = ha.new_mode('mode') mode.set_dynamics(a_matrix_inv) mode.set_inputs(a_inv_b_mat, b_constraints, b_rhs) # error = ha.new_mode('error') # # trans1 = ha.new_transition(mode, error) # trans1.set_guard([[-0, -1, -0], ], [-0.8, ]) return ha
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 make_automaton(): 'make the hybrid automaton' ha = HybridAutomaton() # mode one: x' = y + u1, y' = -x + u2, c' = 1, a' = 0 m1 = ha.new_mode('m1') m1.set_dynamics([[0, 1, 0, 0], [-1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 0, 0]]) b_mat = [[1, 0], [0, 1], [0, 0], [0, 0]] b_constraints = [[1, 0], [-1, 0], [0, 1], [0, -1]] b_rhs = [0.5, 0.5, 0.5, 0.5] m1.set_inputs(b_mat, b_constraints, b_rhs) # mode two: x' = -y, y' = x, a' = 0 m2 = ha.new_mode('m2') m2.set_dynamics([[0, -1], [1, 0]]) # m1 invariant: c <= pi/2 m1.set_invariant([[0, 0, 1, 0]], [math.pi / 2]) # guard: c >= pi/2 trans = ha.new_transition(m1, m2) trans.set_guard([[0, 0, -1, 0]], [-math.pi / 2]) # Assign the reset to the transition # y *= -1, also the reset is what is used to change the number of system variables (m1 has four vars, m2 has two) reset_csr = [[1, 0, 0, 0], [0, -1, 0, 0]] # no minkowski sum terms trans.set_reset(reset_csr) return ha
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 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 define_ha(): '''make the hybrid automaton''' ha = HybridAutomaton() # dynamics: x' = y, y' = -x a_matrix = np.array([[0, 1], [-1, 0]], dtype=float) a_csr = csr_matrix(a_matrix, dtype=float) mode = ha.new_mode('mode') mode.set_dynamics(a_csr) return ha
def test_chull_one_step_inputs(): 'test convex hull with one-step lpi for a system with inputs (bug where current vars was not set correctly)' mode = HybridAutomaton().new_mode('mode_name') step_size = math.pi/4 a_mat = np.array([[0, 1], [-1, 0]], dtype=float) b_mat = [[1], [0]] b_constraints = [[1], [-1]] b_rhs = [0.2, 0.2] mode.set_dynamics(a_mat) mode.set_inputs(b_mat, b_constraints, b_rhs) mode.init_time_elapse(step_size) box = [[-5, -4], [0.0, 1.0]] lpi = lputil.from_box(box, mode) lpi_one_step = lpi.clone() bm, ie_mat = mode.time_elapse.get_basis_matrix(1) lputil.set_basis_matrix(lpi_one_step, bm) lputil.add_input_effects_matrix(lpi_one_step, ie_mat, mode) lpi_list = [lpi, lpi_one_step] chull_lpi = lputil.aggregate_chull(lpi_list, mode) # 2 current vars and 2 total input effect vars, so expected to be 4 from the end assert chull_lpi.cur_vars_offset == chull_lpi.get_num_cols() - 4, "cur_vars in wrong place"
def test_guard_strengthening(): 'simple 2-mode, 2-guard, 2d system with 1st guard A->B is x <= 2, 2nd guard A->B is y <= 2, and inv(B) is y <= 2' ha = HybridAutomaton() mode_a = ha.new_mode('A') mode_a.set_dynamics(np.identity(2)) mode_b = ha.new_mode('B') mode_b.set_dynamics(np.identity(2)) mode_b.set_invariant([[0, 1]], [2]) trans1 = ha.new_transition(mode_a, mode_b, 'first') trans1.set_guard([[1, 0]], [2]) trans2 = ha.new_transition(mode_a, mode_b, 'second') trans2.set_guard([[0, 1]], [2]) ha.do_guard_strengthening() # trans1 should now have 2 conditions assert (trans1.guard_csr.toarray() == np.array([[1, 0], [0, 1]], dtype=float)).all() assert (trans1.guard_rhs == np.array([2, 2], dtype=float)).all() # trans2 should still have 1 condition since invariant was redundant assert (trans2.guard_csr.toarray() == np.array([[0, 1]], dtype=float)).all()
def make_automaton(): 'make the hybrid automaton' ha = HybridAutomaton() # mode one: x' = 2, y' = 1, a' = 0 m1 = ha.new_mode('m1') m1.set_dynamics([[0, 0, 2], [0, 0, 1], [0, 0, 0]]) # mode two: x' = 1, y' = 1, a' = 0 m2 = ha.new_mode('m2') m2.set_dynamics([[0, 0, 1], [0, 0, 1], [0, 0, 0]]) # invariant: x <= 9.9 m1.set_invariant([[1, 0, 0]], [9.9]) # guard: x >= 9.9 trans = ha.new_transition(m1, m2, 'transition_name') trans.set_guard([[-1, 0, 0]], [-9.9]) # Assign the reset to the transition: # # def set_reset(self, reset_csr=None, reset_minkowski_csr=None, reset_minkowski_constraints_csr=None, # reset_minkowski_constraints_rhs=None): # '''resets are of the form x' = Rx + My, Cy <= rhs, where y are fresh variables # the reset_minowski variables can be None if no new variables are needed. If unassigned, the identity # reset is assumed # # x' are the new variables # x are the old variables # reset_csr is R # reset_minkowski_csr is M # reset_minkowski_constraints_csr is C # reset_minkowski_constraints_rhs is rhs # ''' # we want the reset to set x' := [0, 1], y' := y - 10 reset_csr = [[0, 0, 0], [0, 1, 0], [0, 0, 1]] # two new minkowski variables, y0 = [0, 1], y1 = [-10, -10] minkowski_csr = [[1, 0], [0, 1], [0, 0]] constraints_csr = [[1, 0], [-1, 0], [0, 1], [0, -1]] constraints_rhs = [1, 0, -10, 10] trans.set_reset(reset_csr, minkowski_csr, constraints_csr, constraints_rhs) return ha
def test_add_curtime_constraints(): 'tests add_curtime_constraints' lpi = lputil.from_box([[-5, -4], [0, 1]], HybridAutomaton().new_mode('mode_name')) # new constraint to be added, x <= 3.14, y <= 10 csr_constraint = csr_matrix(np.array([[1, 0], [0, 1]], dtype=float)) rhs = np.array([3.14, 10], dtype=float) lputil.add_curtime_constraints(lpi, csr_constraint, rhs) mat = lpi.get_full_constraints() vec = lpi.get_rhs() types = lpi.get_types() expected_mat = np.array([\ [1, 0, -1, 0], \ [0, 1, 0, -1], \ [-1, 0, 0, 0], \ [1, 0, 0, 0], \ [0, -1, 0, 0], \ [0, 1, 0, 0], \ [0, 0, 1, 0], \ [0, 0, 0, 1]], dtype=float) expected_vec = np.array([0, 0, 5, -4, 0, 1, 3.14, 10], dtype=float) fx = glpk.GLP_FX up = glpk.GLP_UP expected_types = [fx, fx, up, up, up, up, up, up] assert np.allclose(vec, expected_vec) assert types == expected_types assert np.allclose(mat.toarray(), expected_mat)
def test_from_box(): 'tests from_box' lpi = lputil.from_box([[-5, -4], [0, 1]], HybridAutomaton().new_mode('mode_name')) assert lpi.basis_mat_pos == (0, 0) assert lpi.dims == 2 mat = lpi.get_full_constraints() types = lpi.get_types() rhs = lpi.get_rhs() names = lpi.get_names() expected_mat = np.array([\ [1, 0, -1, 0], \ [0, 1, 0, -1], \ [-1, 0, 0, 0], \ [1, 0, 0, 0], \ [0, -1, 0, 0], \ [0, 1, 0, 0]], dtype=float) expected_vec = np.array([0, 0, 5, -4, 0, 1], dtype=float) fx = glpk.GLP_FX up = glpk.GLP_UP expected_types = [fx, fx, up, up, up, up] expected_names = ["m0_i0", "m0_i1", "m0_c0", "m0_c1"] assert np.allclose(rhs, expected_vec) assert types == expected_types assert np.allclose(mat.toarray(), expected_mat) assert names == expected_names
def define_ha(): '''make the hybrid automaton''' ha = HybridAutomaton(discrete=False) a_matrix = [[0, 1], [-1, 0]] b_mat = [[1], [0]] b_constraints = [[1], [-1]] b_rhs = [0.2, 0.2] mode = ha.new_mode('mode') mode.set_dynamics(a_matrix) mode.set_inputs(b_mat, b_constraints, b_rhs) return ha
def test_add_init_constraint(): 'tests add_init_constraint on the harmonic oscillator example' lpi = lputil.from_box([[-5, -4], [0, 1]], HybridAutomaton().new_mode('mode_name')) # update basis matrix basis_mat = np.array([[0, 1], [-1, 0]], dtype=float) lputil.set_basis_matrix(lpi, basis_mat) # minimize y should give 4.0 miny = lpi.minimize([0, 1], columns=[lpi.cur_vars_offset + 1])[0] assert abs(miny - 4.0) < 1e-6 # add constraint: y >= 4.5 direction = np.array([0, -1], dtype=float) new_row = lputil.add_init_constraint(lpi, direction, -4.5) assert new_row == 6, "new constraint should have been added in row index 6" # minimize y should give 4.5 miny = lpi.minimize([0, 1], columns=[lpi.cur_vars_offset + 1])[0] assert abs(miny - 4.5) < 1e-6 # check verts() verts = lpplot.get_verts(lpi) assert len(verts) == 5 assert [0.0, 5.0] in verts assert [1.0, 5.0] in verts assert [0.0, 4.5] in verts assert [1.0, 4.5] in verts assert verts[0] == verts[-1]
def test_get_box_center(): 'test get_box_center' lpi = lputil.from_box([[-5, -4], [0, 1]], HybridAutomaton().new_mode('mode_name')) pt = lputil.get_box_center(lpi) assert len(pt) == 2 assert abs(pt[0] - (-4.5)) < 1e-4 assert abs(pt[1] - (0.5)) < 1e-4 basis = np.array([[0, 1], [-1, 0]], dtype=float) lputil.set_basis_matrix(lpi, basis) pt = lputil.get_box_center(lpi) assert len(pt) == 2 assert abs(pt[0] - (0.5)) < 1e-4 assert abs(pt[1] - (4.5)) < 1e-4 # try it rotated 1/4 around the circle a_mat = np.array([[0, 1], [-1, 0]], dtype=float) bm = expm(a_mat * math.pi / 4) lputil.set_basis_matrix(lpi, bm) expected = np.dot(bm, np.array([[-4.5], [0.5]], dtype=float)) pt = lputil.get_box_center(lpi) assert len(pt) == 2 assert abs(pt[0] - expected[0][0]) < 1e-4 assert abs(pt[1] - expected[1][0]) < 1e-4
def test_set_basis_matrix(): 'tests lputil set_basis_matrix on harmonic oscillator example' lpi = lputil.from_box([[-5, -4], [0, 1]], HybridAutomaton().new_mode('mode_name')) basis = np.array([[0, 1], [-1, 0]], dtype=float) lputil.set_basis_matrix(lpi, basis) assert np.allclose(lputil.get_basis_matrix(lpi), basis) mat, vec = lpi.get_full_constraints(), lpi.get_rhs() expected_mat = np.array([\ [0, 1, -1, 0], \ [-1, 0, 0, -1], \ [-1, 0, 0, 0], \ [1, 0, 0, 0], \ [0, -1, 0, 0], \ [0, 1, 0, 0]], dtype=float) expected_vec = np.array([0, 0, 5, -4, 0, 1], dtype=float) assert np.allclose(vec, expected_vec) assert np.allclose(mat.toarray(), expected_mat)
def make_automaton(): 'make the hybrid automaton' ha = HybridAutomaton('Hylaa Output (hylaa_check.py)') # mode one: x' = y + u1, y' = -x + + u1 + u2 # u1 in [-0.5, 0.5], u2 in [-1, 0] m1 = ha.new_mode('m1') m1.set_dynamics([[0, 1], [-1, 0]]) b_mat = [[1, 0], [1, 1]] b_constraints = [[1, 0], [-1, 0], [0, 1], [0, -1]] b_rhs = [0.5, 0.5, 0, 1] m1.set_inputs(b_mat, b_constraints, b_rhs) return ha
def test_box_aggregate3(): 'tests box aggregation with 3 boxes' mode = HybridAutomaton().new_mode('mode_name') lpi1 = lputil.from_box([[-2, -1], [-0.5, 0.5]], mode) lpi2 = lpi1.clone() lpi3 = lpi1.clone() basis2 = np.array([[0, 1], [-1, 0]], dtype=float) lputil.set_basis_matrix(lpi2, basis2) basis3 = np.array([[-1, 0], [0, -1]], dtype=float) lputil.set_basis_matrix(lpi3, basis3) plot_vecs = lpplot.make_plot_vecs(256, offset=0.1) # use an offset to prevent LP dir from being aligned with axis # bounds for lpi1 should be [[-2, -1], [-0.5, 0.5]] verts = lpplot.get_verts(lpi1, plot_vecs=plot_vecs) assert_verts_is_box(verts, [[-2, -1], [-0.5, 0.5]]) # bounds for lpi2 should be [[-0.5, 0.5], [1, 2]] verts = lpplot.get_verts(lpi2, plot_vecs=plot_vecs) assert_verts_is_box(verts, [[-0.5, 0.5], [1, 2]]) # bounds for lpi3 should be [[2, 1], [-0.5, 0.5]] verts = lpplot.get_verts(lpi3, plot_vecs=plot_vecs) assert_verts_is_box(verts, [[2, 1], [-0.5, 0.5]]) # box aggregation, bounds should be [[-2, 2], [-0.5, 2]] agg_dirs = np.identity(2) lpi = lputil.aggregate([lpi1, lpi2, lpi3], agg_dirs, mode) verts = lpplot.get_verts(lpi, plot_vecs=plot_vecs) assert_verts_is_box(verts, [[-2, 2], [-0.5, 2]])
def test_box_aggregate2(): 'tests box aggregation' mode = HybridAutomaton().new_mode('mode_name') lpi1 = lputil.from_box([[0, 1], [0, 1]], mode) lpi2 = lputil.from_box([[1, 2], [1, 2]], mode) agg_dirs = np.identity(2) # box aggregation lpi = lputil.aggregate([lpi1, lpi2], agg_dirs, mode) verts = lpplot.get_verts(lpi) assert_verts_is_box(verts, [[0, 2], [0, 2]]) # test setting basis matrix after aggregation lputil.set_basis_matrix(lpi, np.identity(2)) verts = lpplot.get_verts(lpi) assert_verts_is_box(verts, [[0, 2], [0, 2]]) lputil.set_basis_matrix(lpi, -1 * np.identity(2)) verts = lpplot.get_verts(lpi) assert_verts_is_box(verts, [[-2, 0], [-2, 0]])
def test_rotated_aggregate(): 'tests rotated aggregation' mode = HybridAutomaton().new_mode('mode_name') lpi1 = lputil.from_box([[0, 1], [0, 1]], mode) lpi2 = lputil.from_box([[1, 2], [1, 2]], mode) sq2 = math.sqrt(2) / 2.0 agg_dirs = np.array([[sq2, sq2], [sq2, -sq2]], dtype=float) lpi = lputil.aggregate([lpi1, lpi2], agg_dirs, mode) assert lputil.is_point_in_lpi([0, 0], lpi) assert lputil.is_point_in_lpi([2, 2], lpi) assert lputil.is_point_in_lpi([1, 2], lpi) assert lputil.is_point_in_lpi([2, 1], lpi) assert lputil.is_point_in_lpi([0, 1], lpi) assert lputil.is_point_in_lpi([1, 0], lpi) verts = lpplot.get_verts(lpi) assert len(verts) == 5 for p in [(0.5, -0.5), (-0.5, 0.5), (2.5, 1.5), (1.5, 2.5)]: assert pair_almost_in(p, verts) assert verts[0] == verts[-1]
def test_aggregate_self(): ''' test aggregation on an identical set. ''' mode = HybridAutomaton().new_mode('mode_name') lpi1 = lputil.from_box([[-2, -1], [-10, 20], [100, 200]], mode) lpi2 = lputil.from_box([[-2, -1], [-10, 20], [100, 200]], mode) agg_dirs = np.identity(3) # box aggregation lpi = lputil.aggregate([lpi1, lpi2], agg_dirs, mode) assert lpi.is_feasible() verts = lpplot.get_verts(lpi, xdim=0, ydim=1) assert_verts_is_box(verts, [[-2, -1], [-10, 20]]) verts = lpplot.get_verts(lpi, xdim=0, ydim=2) assert_verts_is_box(verts, [[-2, -1], [100, 200]]) # make sure no extra variables in lp names = lpi.get_names() expected_names = ["m0_i0", "m0_i1", "m0_i2", "m0_c0", "m0_c1", "m0_c2"] assert names == expected_names assert lpi.get_num_rows() == 3 + 3*2
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 define_ha(unsafe_box): '''make the hybrid automaton''' ha = HybridAutomaton() # dynamics: x' = y, y' = -x, t' == a a_mat = [[0, 1, 0, 0], [-1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 0, 0]] one = ha.new_mode('one') one.set_dynamics(a_mat) one.set_invariant([[0, 0, 1, 0]], [math.pi - 1e-6]) # t <= pi two = ha.new_mode('two') two.set_dynamics([[0, 0, 0, 0], [0, 0, 0, -1], [0, 0, 0, 1], [0, 0, 0, 0]]) two.set_invariant([[0, -1, 0, 0]], [3]) # y >= -3 t = ha.new_transition(one, two) t.set_guard_true() error = ha.new_mode('error') t = ha.new_transition(two, error) unsafe_rhs = [ -unsafe_box[0][0], unsafe_box[0][1], -unsafe_box[1][0], unsafe_box[1][1] ] t.set_guard([[-1, 0, 0, 0], [1, 0, 0, 0], [0, -1, 0, 0], [0, 1, 0, 0]], unsafe_rhs) return ha
def test_verts(): 'tests verts' lpi = lputil.from_box([[-5, -4], [0, 1]], HybridAutomaton().new_mode('mode_name')) plot_vecs = lpplot.make_plot_vecs(4, offset=(math.pi / 4.0)) verts = lpplot.get_verts(lpi, plot_vecs=plot_vecs) assert_verts_is_box(verts, [(-5, -4), (0, 1)])
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 define_ha(): '''make the hybrid automaton''' ha = HybridAutomaton(discrete=True) # dynamics: x' = y, y' = -x a_matrix = np.array([[0.96065997, 0.1947354], [-0.1947354, 0.96065997]], dtype=float) a_csr = csr_matrix(a_matrix, dtype=float) b_mat = [[1, 0], [0, 1]] b_constraints = [[1, 0], [-1, 0], [0, 1], [0, -1]] b_rhs = [0.39340481, -0.39340481, -0.03933961, 0.03933961] mode = ha.new_mode('mode') mode.set_dynamics(a_csr) mode.set_inputs(b_mat, b_constraints, b_rhs, allow_constants=True) return ha
def make_automaton(unsafe_box): 'make the hybrid automaton' ha = HybridAutomaton('Deaggregation Example') # x' = 2 m1 = ha.new_mode('mode0_right') m1.set_dynamics([[0, 0, 2], [0, 0, 0], [0, 0, 0]]) m1.set_invariant([[1, 0, 0]], [3.5]) # x <= 3.5 # y' == 2 m2 = ha.new_mode('mode1_up') m2.set_dynamics([[0, 0, 0], [0, 0, 2], [0, 0, 0]]) m2.set_invariant([0., 1., 0], [3.5]) # y <= 3.5 # x' == 2 m3 = ha.new_mode('mode2_right') m3.set_dynamics([[0, 0, 2], [0, 0, -0], [0, 0, 0]]) m3.set_invariant([1., 0, 0], [7]) # x <= 7 t = ha.new_transition(m1, m2) t.set_guard_true() t = ha.new_transition(m2, m3) t.set_guard_true() error = ha.new_mode('error') t = ha.new_transition(m3, error) unsafe_rhs = [ -unsafe_box[0][0], unsafe_box[0][1], -unsafe_box[1][0], unsafe_box[1][1] ] # x >= 1.1 x <= 1.9, y >= 2.7, y <= 4.3 t.set_guard([[-1, 0, 0], [1, 0, 0], [0, -1, 0], [0, 1, 0]], unsafe_rhs) t = ha.new_transition(m2, error) # x >= 1.1 x <= 1.9, y >= 2.7, y <= 4.3 t.set_guard([[-1, 0, 0], [1, 0, 0], [0, -1, 0], [0, 1, 0]], unsafe_rhs) return ha