Example #1
0
def transition_directions_test():
    """
    unit test for correctness of abstracted transition directions, with:
    
      - uni-directional control authority
      - no disturbance
    """
    modes = []
    modes.append(('normal', 'fly'))
    modes.append(('refuel', 'fly'))
    env_modes, sys_modes = zip(*modes)

    cont_state_space = pc.box2poly([[0., 3.], [0., 2.]])
    pwa_sys = dict()
    pwa_sys[('normal', 'fly')] = hybrid.PwaSysDyn([subsys0()],
                                                  cont_state_space)
    pwa_sys[('refuel', 'fly')] = hybrid.PwaSysDyn([subsys1()],
                                                  cont_state_space)

    switched_dynamics = hybrid.SwitchedSysDyn(
        disc_domain_size=(len(env_modes), len(sys_modes)),
        dynamics=pwa_sys,
        env_labels=env_modes,
        disc_sys_labels=sys_modes,
        cts_ss=cont_state_space)

    cont_props = {}
    cont_props['home'] = pc.box2poly([[0., 1.], [0., 1.]])
    cont_props['lot'] = pc.box2poly([[2., 3.], [1., 2.]])

    ppp = abstract.prop2part(cont_state_space, cont_props)
    ppp, new2old = abstract.part2convex(ppp)

    N = 8
    trans_len = 1

    disc_params = {}
    for mode in modes:
        disc_params[mode] = {'N': N, 'trans_length': trans_len}

    swab = abstract.discretize_switched(ppp,
                                        switched_dynamics,
                                        disc_params,
                                        plot=True,
                                        show_ts=True,
                                        only_adjacent=False)

    ts = swab.modes[('normal', 'fly')].ts
    edges = {(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (1, 2), (1, 4),
             (1, 5), (2, 3), (2, 5), (2, 0), (3, 0), (4, 5), (5, 0)}

    logger.debug(set(ts.edges()).symmetric_difference(edges))
    assert (set(ts.edges()) == edges)

    ts = swab.ts

    assert (set(ts.edges()) == edges)
    for i, j in edges:
        assert (ts[i][j][0]['env_actions'] == 'normal')
        assert (ts[i][j][0]['sys_actions'] == 'fly')
def define_partition(dom):
    p = dict()
    p["a"] = pc.box2poly([[0.0, 10.0], [15.0, 18.0]])
    p["b"] = pc.box2poly([[0.0, 1.0], [0.0, 20.0]])

    ppp = abstract.prop2part(dom, p)
    ppp, new2old_reg = abstract.part2convex(ppp)
    return ppp
Example #3
0
def define_partition(dom):
    p = dict()
    p['a'] = pc.box2poly([[0.0, 10.0], [15.0, 18.0]])
    p['b'] = pc.box2poly([[0.0, 1.0], [0.0, 20.0]])

    ppp = abstract.prop2part(dom, p)
    ppp, new2old_reg = abstract.part2convex(ppp)
    return ppp
    def cont_predicates():
        p = dict()
        p["safe"] = pc.box2poly([[0.5, 3.5], [0.5, 2.5]])

        ppp = abstract.prop2part(dom, p)
        ppp, new2old_reg = abstract.part2convex(ppp)
        ppp.plot()
        return ppp
Example #5
0
    def cont_predicates():
        p = dict()
        p['safe'] = pc.box2poly([[0.5, 3.5], [0.5, 2.5]])

        ppp = abstract.prop2part(dom, p)
        ppp, new2old_reg = abstract.part2convex(ppp)
        ppp.plot()
        return ppp
def build_FTS(index):
    # build test FTS
    # simple test
    if index == 0:
        ts = FTS()
        ts.atomic_propositions.add_from({'a', 'b', 'c', 'd'})
        ts.states.add_from([('q1', {
            'ap': {'a'}
        }), ('q2', {
            'ap': {'a'}
        }), ('q3', {
            'ap': {'b'}
        }), ('q4', {
            'ap': {'b'}
        }), ('q5', {
            'ap': {'b'}
        }), ('q6', {
            'ap': {'c'}
        }), ('q7', {
            'ap': {'d'}
        })])
        ts.transitions.add('q1', 'q3')
        ts.transitions.add('q1', 'q4')
        ts.transitions.add('q3', 'q6')
        ts.transitions.add('q4', 'q6')
        ts.transitions.add('q2', 'q4')
        ts.transitions.add('q2', 'q5')
        ts.transitions.add('q5', 'q7')
        ts.transitions.add('q6', 'q6')
        ts.transitions.add('q7', 'q7')
    # FTS generated by continuous system
    elif index == 1:
        input_bound = 1.0
        cont_state_space = box2poly([[-1, 1], [-1, 1]])
        A = np.array([[0.5, 1.0], [0.75, -1.0]])
        B = np.array([[1, 0.], [0., 1]])
        U = input_bound * np.array([[-1., 1.], [-1., 1.]])
        U = box2poly(U)
        sys_dyn = hybrid.LtiSysDyn(A, B, None, None, U, None, cont_state_space)
        cont_props = {}
        cont_props['a'] = box2poly([[-0.5, 0.5], [-0.5, 0.5]])
        cont_props['b'] = box2poly([[-1, -0.5], [-1, 1]])
        cont_props['c'] = box2poly([[-0.5, 1], [0.5, 1]])
        cont_props['d'] = box2poly([[0.5, 1], [-1, 0.5]])
        cont_props['e'] = box2poly([[-0.5, 0.5], [-1, -0.5]])
        cont_partition = prop2part(cont_state_space, cont_props)
        sys = discretize(cont_partition,
                         sys_dyn,
                         closed_loop=False,
                         conservative=True,
                         trans_length=1,
                         N=1,
                         use_all_horizon=False,
                         min_cell_volume=0.0,
                         abs_tol=1e-7)
        ts = sys.ts
    return ts
Example #7
0
def transition_directions_test():
    """Unit test for correctness of abstracted transition directions, with:

      - uni-directional control authority
      - no disturbance
    """
    modes = list()
    modes.append(('normal', 'fly'))
    modes.append(('refuel', 'fly'))
    env_modes, sys_modes = zip(*modes)
    # dynamics
    cont_state_space = pc.box2poly([[0.0, 3.0], [0.0, 2.0]])
    pwa_sys = dict()
    pwa_sys[('normal', 'fly')] = hybrid.PwaSysDyn([subsys0()],
                                                  cont_state_space)
    pwa_sys[('refuel', 'fly')] = hybrid.PwaSysDyn([subsys1()],
                                                  cont_state_space)
    switched_dynamics = hybrid.SwitchedSysDyn(
        disc_domain_size=(len(env_modes), len(sys_modes)),
        dynamics=pwa_sys,
        env_labels=env_modes,
        disc_sys_labels=sys_modes,
        cts_ss=cont_state_space)
    # propositions
    cont_props = dict()
    cont_props['home'] = pc.box2poly([[0.0, 1.0], [0.0, 1.0]])
    cont_props['lot'] = pc.box2poly([[2.0, 3.0], [1.0, 2.0]])
    # partition
    ppp = abstract.prop2part(cont_state_space, cont_props)
    ppp, new2old = abstract.part2convex(ppp)
    # configure discretization
    N = 8
    trans_len = 1
    disc_params = dict()
    for mode in modes:
        disc_params[mode] = dict(N=N, trans_length=trans_len)
    # discretize
    swab = abstract.discretize_switched(ppp,
                                        switched_dynamics,
                                        disc_params,
                                        plot=True,
                                        show_ts=True,
                                        only_adjacent=False)
    # assertions
    ts = swab.modes[('normal', 'fly')].ts
    edges = {(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (1, 2), (1, 4),
             (1, 5), (2, 3), (2, 5), (2, 0), (3, 0), (4, 5), (5, 0)}
    h = nx.MultiDiGraph()
    h.add_edges_from(edges)
    assert nx.is_isomorphic(ts, h)
    ts = swab.ts
    assert nx.is_isomorphic(ts, h)
    for _, _, d in ts.edges(data=True):
        assert d['env_actions'] == 'normal'
        assert d['sys_actions'] == 'fly'
Example #8
0
def prop2part_test():
    state_space = pc.Polytope.from_box(np.array([[0., 2.],[0., 2.]]))

    cont_props = []
    A = []
    b = []

    A.append(np.array([[1., 0.],
                       [-1., 0.],
                       [0., 1.],
                       [0., -1.]]))
    b.append(np.array([[.5, 0., .5, 0.]]).T)
    cont_props.append(pc.Polytope(A[0], b[0]))

    A.append(np.array([[1., 0.],
                       [-1., 0.],
                       [0., 1.],
                       [0., -1.]]))
    b.append(np.array([[2., -1.5, 2., -1.5]]).T)
    cont_props.append(pc.Polytope(A[1], b[1]))

    cont_props_dict = {"C"+str(i) : pc.Polytope(A[i], b[i]) for i in range(2)}

    mypartition = prop2part(state_space, cont_props_dict)
    print(mypartition)

    ref_adjacency = np.array([[1,0,1],[0,1,1],[1,1,1]])
    assert np.all(mypartition.adj.todense() == ref_adjacency)

    assert len(mypartition.regions) == 3

    for reg in mypartition.regions[0:2]:
        assert len(reg.props) == 1
        assert len(reg) == 1

        assert cont_props_dict == mypartition.prop_regions

    assert len(mypartition.regions[2].props) == 0

    assert len(mypartition.regions[2]) == 3
    dum = state_space.copy()
    for reg in mypartition.regions[0:2]:
        dum = dum.diff(reg)
    assert pc.is_empty(dum.diff(mypartition.regions[2]) )
    assert pc.is_empty(mypartition.regions[2].diff(dum) )

    assert(mypartition.preserves_predicates())

    # invalidate it
    mypartition.regions += [pc.Region([pc.Polytope(A[0], b[0])], {})]
    assert(not mypartition.preserves_predicates())
Example #9
0
def define_dynamics_dual():
    # Continuous state space
    cont_state_space = pc.box2poly([[-1.5, 1.5]])

    # Continuous dynamics
    # (continuous-state, discrete-time)
    A = np.array([[2]])
    B = np.array([[1]])

    # Available control, possible disturbances
    U = np.array([[-2.0, 2.0]])

    # Convert to polyhedral representation
    U = pc.box2poly(U)

    # Construct the LTI system describing the dynamics
    sys_dyn = hybrid.LtiSysDyn(A, B, None, None, U, None, cont_state_space)
    # @dynamics_section_end@

    # @partition_section@
    # Define atomic propositions for relevant regions of state space
    cont_props = {}
    cont_props['a'] = pc.box2poly([[-1.5, -1]])
    cont_props['b'] = pc.box2poly([[-1, 1]])
    cont_props['c'] = pc.box2poly([[1, 1.5]])

    part = []
    part.append(pc.box2poly([[-1.5, -1]]))
    part.append(pc.box2poly([[-1, 1]]))
    part.append(pc.box2poly([[1, 1.5]]))
    part.append(pc.box2poly([[-1, 0.5]]))
    part.append(pc.box2poly([[-0.5, 1]]))
    part.append(pc.box2poly([[-0.5, 0.5]]))
    part.append(pc.box2poly([[-1.25, -1]]))
    part.append(pc.box2poly([[1, 1.25]]))
    # Compute the proposition preserving partition of the continuous state
    # space
    cont_partition = abstract.prop2part(cont_state_space, cont_props)
    return sys_dyn, cont_partition, part
Example #10
0
# Build piecewise affine system from its subsystems
sys_dyn = PwaSysDyn(subsystems, cont_state_space)
if plotting:
    ax = sys_dyn.plot()
    ax.figure.savefig('pwa_sys_dyn.pdf')
# @pwasystem_end@

# Continuous proposition
cont_props = {}
cont_props['home'] = box2poly([[0., 1.], [0., 1.]])
cont_props['lot'] = box2poly([[2., 3.], [1., 2.]])

# Compute the proposition preserving partition
# of the continuous state space
cont_partition = prop2part(cont_state_space, cont_props)
if plotting:
    ax = cont_partition.plot()
    cont_partition.plot_props(ax=ax)
    ax.figure.savefig('spec_ppp.pdf')

disc_dynamics = discretize(cont_partition,
                           sys_dyn,
                           closed_loop=True,
                           N=8,
                           min_cell_volume=0.1,
                           plotit=plotting,
                           save_img=True,
                           cont_props=cont_props)
if plotting:
    ax = disc_dynamics.plot(show_ts=True)
Example #11
0
sys_modes = ('fly', )

pwa_normal = hybrid.PwaSysDyn([cont_dyn_normal], domain=cont_ss)
pwa_refuel = hybrid.PwaSysDyn([cont_dyn_refuel], domain=cont_ss)

dynamics_dict = {('normal', 'fly'): pwa_normal, ('refuel', 'fly'): pwa_refuel}

switched_dynamics = hybrid.SwitchedSysDyn(cts_ss=cont_ss,
                                          disc_domain_size=(len(env_modes),
                                                            len(sys_modes)),
                                          dynamics=dynamics_dict,
                                          env_labels=env_modes,
                                          disc_sys_labels=sys_modes)

## Create convex proposition preserving partition
ppp = abstract.prop2part(cont_ss, cont_props)
ppp, new2old = abstract.part2convex(ppp)

ax = ppp.plot_props()
ax.figure.savefig(imgpath + 'cprops.pdf')

ax = ppp.plot()
ax.figure.savefig(imgpath + 'ppp.pdf')

## Discretize to establish transitions
if os.name == "posix":
    start = os.times()[2]
    logger.info('start time: ' + str(start))
else:
    logger.info(
        'Timing currently only available for POSIX platforms (not Windows)')
Example #12
0
# Convert to polyhedral representation
U = box2poly(U)
W = box2poly(W)

# Construct the LTI system describing the dynamics
sys_dyn = hybrid.LtiSysDyn(A, B, E, None, U, W, cont_state_space)
# @dynamics_section_end@

# @partition_section@
# Define atomic propositions for relevant regions of state space
cont_props = {}
cont_props['home'] = box2poly([[0., 1.], [0., 1.]])
cont_props['lot'] = box2poly([[2., 3.], [1., 2.]])

# Compute the proposition preserving partition of the continuous state space
cont_partition = prop2part(cont_state_space, cont_props)
plot_partition(cont_partition, show=visualize)
# @partition_section_end@

# @discretize_section@
# Given dynamics & proposition-preserving partition, find feasible transitions
disc_dynamics = discretize(
    cont_partition, sys_dyn, closed_loop=True,
    N=8, min_cell_volume=0.1, plotit=visualize
)
# @discretize_section_end@

"""Visualize transitions in continuous domain (optional)"""
plot_partition(disc_dynamics.ppp, disc_dynamics.ts,
               disc_dynamics.ppp2ts, show=visualize)
Example #13
0
def specify_discretize_synthesize():
    """Return PWA partition and controller, dump them to pickle files."""
    # Problem parameters
    input_bound = 1.0
    uncertainty = 0.01

    # Continuous state space
    cont_state_space = box2poly([[0., 3.], [0., 2.]])

    # Continuous dynamics
    A = np.array([[1.0, 0.], [0., 1.0]])
    B = np.array([[0.1, 0.], [0., 0.1]])
    E = np.array([[1., 0.], [0., 1.]])

    # Available control, possible disturbances
    U = input_bound * np.array([[-1., 1.], [-1., 1.]])
    W = uncertainty * np.array([[-1., 1.], [-1., 1.]])

    # Convert to polyhedral representation
    U = box2poly(U)
    W = box2poly(W)

    # Construct the LTI system describing the dynamics
    sys_dyn = hybrid.LtiSysDyn(A, B, E, None, U, W, cont_state_space)

    # Define atomic propositions for relevant regions of state space
    cont_props = {}
    cont_props['home'] = box2poly([[0., 1.], [0., 1.]])
    cont_props['lot'] = box2poly([[2., 3.], [1., 2.]])

    # Compute proposition preserving partition of the continuous state space
    cont_partition = prop2part(cont_state_space, cont_props)

    pwa = discretize(cont_partition,
                     sys_dyn,
                     closed_loop=True,
                     N=8,
                     min_cell_volume=0.1,
                     plotit=False)
    """Specifications"""
    # Environment variables and assumptions
    env_vars = {'park'}
    env_init = set()
    env_prog = '!park'
    env_safe = set()

    # System variables and requirements
    sys_vars = {'X0reach'}
    sys_init = {'X0reach'}
    sys_prog = {'home'}  # []<>home
    sys_safe = {'(X(X0reach) <-> lot) || (X0reach && !park)'}
    sys_prog |= {'X0reach'}

    # Create the specification
    specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe,
                        sys_safe, env_prog, sys_prog)
    specs.qinit = '\A \E'
    specs.moore = False
    specs.plus_one = False
    """Synthesize"""
    ctrl = synth.synthesize(specs,
                            sys=pwa.ts,
                            ignore_sys_init=True,
                            solver='gr1c')

    # store the result for future use
    if len(BUILDDIR) > 0 and not os.path.exists(BUILDDIR):
        os.mkdir(BUILDDIR)
    pickle.dump(ctrl, open(BUILDDIR + 'FSM.p', 'wb'))
    pickle.dump(pwa, open(BUILDDIR + 'AbstractPwa.p', 'wb'))
    return pwa, ctrl
env_modes, sys_modes = zip(*modes)
msg = 'Found:\n'
msg += '\t Environment modes: ' + str(env_modes)
msg += '\t System modes: ' + str(sys_modes)

switched_dynamics = hybrid.SwitchedSysDyn(
    disc_domain_size=(len(env_modes), len(sys_modes)),
    dynamics=sys_dyn,
    env_labels=env_modes,
    disc_sys_labels=sys_modes,
    cts_ss=cont_state_space
)

print(switched_dynamics)

ppp = abstract.prop2part(cont_state_space, cont_props)
ppp, new2old = abstract.part2convex(ppp)

"""Discretize to establish transitions"""
start = time.time()

N = 8
trans_len=1

disc_params = {}
for mode in modes:
    disc_params[mode] = {'N':N, 'trans_length':trans_len}

swab = abstract.multiproc_discretize_switched(
    ppp, switched_dynamics, disc_params,
    plot=True, show_ts=True
Example #15
0
    "----------------------------------\n Define labelling \n----------------------------------"
)

cprops = {}
cprops['inA'] = box2poly([[0, 10], [45, 55], [-5, 5], [-5, 5]])
cprops['inB'] = box2poly([[90, 100], [45, 55], [-5, 5], [-5, 5]])
cprops['inG'] = box2poly([[45, 55], [45, 55], [-5, 5], [-5, 5]])

cprops['inObj1'] = box2poly([[15, 35], [30, 70], [-5, 5], [-5, 5]])
cprops['inObj2'] = box2poly([[65, 85], [30, 70], [-5, 5], [-5, 5]])
#
# cprops["noGas"] = box2poly([[0, 100], [0, 100], [-5, 5], [-5, 5], [0, 10]])
# cprops["gasReserves"] = box2poly([[0, 100], [0, 100], [-5, 5], [-5, 5], [0, 40]])
# cprops["fullGas"] = box2poly([[0, 100], [0, 100], [-5, 5], [-5, 5], [90, 100]])

cpartition = prop2part(X, cprops)
if verbose == 1:
    print("partition before refinement")
    print(cpartition)

# plot_partition(cpartition)

print(
    "---------------------------------\n System partition State Space \n----------------------------------"
)

disc_dynamics = discretize(cpartition,
                           sys_dyn,
                           N=10,
                           min_cell_volume=100,
                           closed_loop=True)  #, conservative=True)
dynamics_dict = {
    ('normal', 'fly') : pwa_normal,
    ('refuel', 'fly') : pwa_refuel
}

switched_dynamics = hybrid.SwitchedSysDyn(
    cts_ss=cont_ss,
    disc_domain_size=(len(env_modes), len(sys_modes)),
    dynamics=dynamics_dict,
    env_labels=env_modes,
    disc_sys_labels=sys_modes
)

"""Create convex proposition preserving partition"""
ppp = abstract.prop2part(cont_ss, cont_props)
ppp, new2old = abstract.part2convex(ppp)

ax = ppp.plot_props()
ax.figure.savefig(imgpath + 'cprops.pdf')

ax = ppp.plot()
ax.figure.savefig(imgpath + 'ppp.pdf')

"""Discretize to establish transitions"""
if os.name == "posix":
    start = os.times()[2]
    logger.info('start time: ' + str(start))
else:
    logger.info('Timing currently only available for POSIX platforms (not Windows)')
def transition_directions_test():
    """
    unit test for correctness of abstracted transition directions, with:
    
      - uni-directional control authority
      - no disturbance
    """
    modes = []
    modes.append(("normal", "fly"))
    modes.append(("refuel", "fly"))
    env_modes, sys_modes = zip(*modes)

    cont_state_space = pc.box2poly([[0.0, 3.0], [0.0, 2.0]])
    pwa_sys = dict()
    pwa_sys[("normal", "fly")] = hybrid.PwaSysDyn([subsys0()], cont_state_space)
    pwa_sys[("refuel", "fly")] = hybrid.PwaSysDyn([subsys1()], cont_state_space)

    switched_dynamics = hybrid.SwitchedSysDyn(
        disc_domain_size=(len(env_modes), len(sys_modes)),
        dynamics=pwa_sys,
        env_labels=env_modes,
        disc_sys_labels=sys_modes,
        cts_ss=cont_state_space,
    )

    cont_props = {}
    cont_props["home"] = pc.box2poly([[0.0, 1.0], [0.0, 1.0]])
    cont_props["lot"] = pc.box2poly([[2.0, 3.0], [1.0, 2.0]])

    ppp = abstract.prop2part(cont_state_space, cont_props)
    ppp, new2old = abstract.part2convex(ppp)

    N = 8
    trans_len = 1

    disc_params = {}
    for mode in modes:
        disc_params[mode] = {"N": N, "trans_length": trans_len}

    swab = abstract.discretize_switched(
        ppp, switched_dynamics, disc_params, plot=True, show_ts=True, only_adjacent=False
    )

    ts = swab.modes[("normal", "fly")].ts
    edges = {
        (0, 0),
        (1, 1),
        (2, 2),
        (3, 3),
        (4, 4),
        (5, 5),
        (1, 2),
        (1, 4),
        (1, 5),
        (2, 3),
        (2, 5),
        (2, 0),
        (3, 0),
        (4, 5),
        (5, 0),
    }

    logger.debug(set(ts.edges()).symmetric_difference(edges))
    assert set(ts.edges()) == edges

    ts = swab.ts

    assert set(ts.edges()) == edges
    for i, j in edges:
        assert ts[i][j][0]["env_actions"] == "normal"
        assert ts[i][j][0]["sys_actions"] == "fly"
def build_FTS(index):
    # build test FTS
    # simple test
    if index == 0:
        ts = FTS()
        ts.atomic_propositions.add_from({'a', 'b', 'c', 'd'})
        ts.states.add_from([('q1', {
            'ap': {'a'}
        }), ('q2', {
            'ap': {'a'}
        }), ('q3', {
            'ap': {'b'}
        }), ('q4', {
            'ap': {'b'}
        }), ('q5', {
            'ap': {'b'}
        }), ('q6', {
            'ap': {'c'}
        }), ('q7', {
            'ap': {'d'}
        })])
        ts.transitions.add('q1', 'q3')
        ts.transitions.add('q1', 'q4')
        ts.transitions.add('q3', 'q6')
        ts.transitions.add('q4', 'q6')
        ts.transitions.add('q2', 'q4')
        ts.transitions.add('q2', 'q5')
        ts.transitions.add('q5', 'q7')
        ts.transitions.add('q6', 'q6')
        ts.transitions.add('q7', 'q7')
    # FTS generated by continuous system
    elif index == 1:
        # Problem parameters
        input_bound = 1.0
        # Continuous state space
        cont_state_space = box2poly([[-1, 1], [-1, 1]])
        # Continuous dynamics
        # (continuous-state, discrete-time)
        A = np.array([[0.5, 1.0], [0.75, -1.0]])
        B = np.array([[1, 0.], [0., 1]])
        # Available control, possible disturbances
        U = input_bound * np.array([[-1., 1.], [-1., 1.]])
        # Convert to polyhedral representation
        U = box2poly(U)
        # Construct the LTI system describing the dynamics
        sys_dyn = hybrid.LtiSysDyn(A, B, None, None, U, None, cont_state_space)
        # @dynamics_section_end@
        # @partition_section@
        # Define atomic propositions for relevant regions of state space
        cont_props = {}
        cont_props['a'] = box2poly([[-0.5, 0.5], [-0.5, 0.5]])
        cont_props['b'] = box2poly([[-1, -0.5], [-1, 1]])
        cont_props['c'] = box2poly([[-0.5, 1], [0.5, 1]])
        cont_props['d'] = box2poly([[0.5, 1], [-1, 0.5]])
        cont_props['e'] = box2poly([[-0.5, 0.5], [-1, -0.5]])
        # Compute the proposition preserving partition of the continuous state space
        cont_partition = prop2part(cont_state_space, cont_props)
        # @partition_section_end@
        # @discretize_section@
        # Given dynamics & proposition-preserving partition, find feasible transitions
        sys = discretize(cont_partition,
                         sys_dyn,
                         closed_loop=False,
                         conservative=True,
                         trans_length=1,
                         N=1,
                         use_all_horizon=False,
                         min_cell_volume=0.0,
                         abs_tol=1e-7)
        ts = sys.ts
    return ts
Example #19
0
def specify_discretize_synthesize():
    """Return PWA partition and controller, dump them to pickle files."""
    # Problem parameters
    input_bound = 1.0
    uncertainty = 0.01

    # Continuous state space
    cont_state_space = box2poly([[0., 3.], [0., 2.]])

    # Continuous dynamics
    A = np.array([[1.0, 0.], [0., 1.0]])
    B = np.array([[0.1, 0.], [0., 0.1]])
    E = np.array([[1., 0.], [0., 1.]])

    # Available control, possible disturbances
    U = input_bound * np.array([[-1., 1.], [-1., 1.]])
    W = uncertainty * np.array([[-1., 1.], [-1., 1.]])

    # Convert to polyhedral representation
    U = box2poly(U)
    W = box2poly(W)

    # Construct the LTI system describing the dynamics
    sys_dyn = hybrid.LtiSysDyn(A, B, E, None, U, W, cont_state_space)

    # Define atomic propositions for relevant regions of state space
    cont_props = {}
    cont_props['home'] = box2poly([[0., 1.], [0., 1.]])
    cont_props['lot'] = box2poly([[2., 3.], [1., 2.]])

    # Compute proposition preserving partition of the continuous state space
    cont_partition = prop2part(cont_state_space, cont_props)

    pwa = discretize(
        cont_partition, sys_dyn, closed_loop=True,
        N=8, min_cell_volume=0.1, plotit=False)

    """Specifications"""
    # Environment variables and assumptions
    env_vars = {'park'}
    env_init = set()
    env_prog = '!park'
    env_safe = set()

    # System variables and requirements
    sys_vars = {'X0reach'}
    sys_init = {'X0reach'}
    sys_prog = {'home'}  # []<>home
    sys_safe = {'(X(X0reach) <-> lot) || (X0reach && !park)'}
    sys_prog |= {'X0reach'}

    # Create the specification
    specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init,
                        env_safe, sys_safe, env_prog, sys_prog)
    specs.qinit = '\A \E'
    specs.moore = False
    specs.plus_one = False

    """Synthesize"""
    ctrl = synth.synthesize(
        specs, sys=pwa.ts, ignore_sys_init=True, solver='gr1c')

    # store the result for future use
    if len(BUILDDIR) > 0 and not os.path.exists(BUILDDIR):
        os.mkdir(BUILDDIR)
    pickle.dump(ctrl, open(BUILDDIR + 'FSM.p', 'wb'))
    pickle.dump(pwa, open(BUILDDIR + 'AbstractPwa.p', 'wb'))
    return pwa, ctrl
Example #20
0
env_modes, sys_modes = zip(*modes)
msg = 'Found:\n'
msg += '\t Environment modes: ' + str(env_modes)
msg += '\t System modes: ' + str(sys_modes)

switched_dynamics = hybrid.SwitchedSysDyn(
    disc_domain_size=(len(env_modes), len(sys_modes)),
    dynamics=sys_dyn,
    env_labels=env_modes,
    disc_sys_labels=sys_modes,
    cts_ss=cont_state_space
)

print(switched_dynamics)

ppp = abstract.prop2part(cont_state_space, cont_props)
ppp, new2old = abstract.part2convex(ppp)

"""Discretize to establish transitions"""
start = time.time()

N = 8
trans_len=1

disc_params = {}
for mode in modes:
    disc_params[mode] = {'N':N, 'trans_length':trans_len}

swab = abstract.multiproc_discretize_switched(
    ppp, switched_dynamics, disc_params,
    plot=True, show_ts=True
Example #21
0
def test_find_controller_non_convex():
    """Test that it is enough that one polytope in the target region is
     reachable"""
    # Continuous state space
    cont_state_space = pc.box2poly([[0., 1.], [0., 2.]])

    # System dynamics (continuous state, discrete time): simple double integrator
    # but no reversing.
    h = 1.0
    A = np.array([[1.0, h], [0., 1.0]])
    B = np.array([[h**2 / 2.0], [h]])
    E = None

    # Available control, no disturbances. Can brake or accelerate.
    U = pc.box2poly(np.array([[-1., 1.]]))
    W = None

    # Construct the LTI system describing the dynamics
    sys_dyn = hybrid.LtiSysDyn(A, B, E, None, U, W, cont_state_space)

    # Define atomic propositions for relevant regions of state space
    cont_props = dict()
    cont_props['target'] = pc.box2poly([[0., 1.], [0., 2.]])

    # Compute the proposition preserving partition of the continuous state space
    # noinspection PyTypeChecker
    cont_partition = abstract.prop2part(cont_state_space, cont_props)

    # Abstraction
    disc_dynamics = abstract.discretize(cont_partition,
                                        sys_dyn,
                                        closed_loop=False,
                                        conservative=True,
                                        N=1,
                                        min_cell_volume=0.01,
                                        plotit=False,
                                        simu_type='bi',
                                        trans_length=1)

    # Setup a start point and a target point in a region that are problematic
    c_start_state = np.array([0.5, 0.0])
    c_end_desired = np.array([1.0, 2.0])
    # Find the discrete states of the start state and the target region
    d_start_state = abstract.find_discrete_state(c_start_state,
                                                 disc_dynamics.ppp)
    d_end_state = abstract.find_discrete_state(c_end_desired,
                                               disc_dynamics.ppp)
    # Try to find a control policy
    u = abstract.find_controller.get_input(x0=c_start_state,
                                           ssys=sys_dyn,
                                           abstraction=disc_dynamics,
                                           start=d_start_state,
                                           end=d_end_state,
                                           ord=1,
                                           mid_weight=5)
    assert 0.5 <= u <= 1.0, "u was " + str(u)
    # Try to find a control policy in the other direction and ascertain
    # an error is thrown
    assert_raises(Exception,
                  abstract.find_controller.get_input,
                  x0=c_end_desired,
                  ssys=sys_dyn,
                  abstraction=disc_dynamics,
                  start=d_end_state,
                  end=d_start_state,
                  ord=1,
                  mid_weight=5)