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
예제 #2
0
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
예제 #3
0
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"
예제 #4
0
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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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
예제 #8
0
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)
예제 #9
0
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]])
예제 #10
0
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
예제 #11
0
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"
예제 #12
0
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()
예제 #13
0
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
예제 #14
0
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)
예제 #15
0
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
예제 #16
0
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
예제 #17
0
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]
예제 #18
0
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
예제 #19
0
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)
예제 #20
0
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
예제 #21
0
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]])
예제 #22
0
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]])
예제 #23
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]
예제 #24
0
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
예제 #25
0
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
예제 #26
0
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
예제 #27
0
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
예제 #29
0
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
예제 #30
0
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