Exemple #1
0
 def test_correct_lti_construction(self):
     LTI1 = hybrid.LtiSysDyn(A=self.A1,
                             B=self.B1,
                             Uset=self.Uset,
                             domain=self.poly1,
                             time_semantics='discrete',
                             timestep=None)
     LTI2 = hybrid.LtiSysDyn(A=self.A2,
                             B=self.B2,
                             Uset=self.Uset,
                             domain=self.poly2,
                             time_semantics='sampled',
                             timestep=.1)
     LTI3 = hybrid.LtiSysDyn(A=self.A2,
                             B=self.B2,
                             Uset=self.Uset,
                             domain=self.poly1)
     LTI4 = hybrid.LtiSysDyn(A=self.A1,
                             B=self.B2,
                             Uset=self.Uset,
                             domain=self.poly2)
     assert (LTI1.time_semantics == 'discrete')
     assert (LTI2.time_semantics == 'sampled')
     assert (LTI1.timestep is None)
     assert (LTI2.timestep == .1)
     assert (LTI3.time_semantics is None)
     assert (LTI3.timestep is None)
     assert (LTI4.time_semantics is None)
     assert (LTI4.timestep is None)
 def setUp(self):
     self.A1 = np.eye(2)
     self.A2 = np.array([[0, 1], [0, 0]])
     self.B1 = np.array([[0] ,[1]])
     self.B2 = np.array([[1], [0]])
     self.poly1 = pc.Polytope.from_box([[0, 1], [0, 1]])
     self.poly2 = pc.Polytope.from_box([[1, 2], [0, 1]])
     self.total_box = pc.Region(list_poly=[self.poly1, self.poly2])
     self.Uset = pc.Polytope.from_box([[0, 1]])
     self.env_labels = ('hi', 'hello')
     self.sys_labels = ('mode1',)
     self.disc_domain_size = (2, 1)
     self.LTI1 = hybrid.LtiSysDyn(A=self.A1, B=self.B1,
                                  Uset=self.Uset, domain=self.poly1,
                                  time_semantics='sampled', timestep=.1)
     self.LTI2 = hybrid.LtiSysDyn(A=self.A2, B=self.B2,
                                  Uset=self.Uset, domain=self.poly2,
                                  time_semantics='sampled', timestep=.1)
     self.LTI3 = hybrid.LtiSysDyn(A=self.A1, B=self.B1,
                                  Uset=self.Uset, domain=self.poly2,
                                  time_semantics='sampled', timestep=.1)
     self.LTI4 = hybrid.LtiSysDyn(A=self.A2, B=self.B2,
                                  Uset=self.Uset, domain=self.poly1,
                                  time_semantics='sampled', timestep=.1)
     self.PWA1 = hybrid.PwaSysDyn(list_subsys=[self.LTI1, self.LTI2],
                                  domain=self.total_box,
                                  time_semantics='sampled', timestep=.1)
     self.PWA2 = hybrid.PwaSysDyn(list_subsys=[self.LTI3, self.LTI4],
                                  domain=self.total_box,
                                  time_semantics='sampled', timestep=.1)
     self.dynamics1 = {(self.env_labels[0], self.sys_labels[0]): self.PWA1,
                       (self.env_labels[1], self.sys_labels[0]): self.PWA2}
Exemple #3
0
    def test_correct_pwa_construction(self):
        # Putting pwa together successfully, without time overwrite
        LTI1 = hybrid.LtiSysDyn(A=self.A1,
                                B=self.B1,
                                Uset=self.Uset,
                                domain=self.poly1,
                                time_semantics='sampled',
                                timestep=.1)
        LTI2 = hybrid.LtiSysDyn(A=self.A2,
                                B=self.B2,
                                Uset=self.Uset,
                                domain=self.poly2,
                                time_semantics='sampled',
                                timestep=.1)
        LTI3 = hybrid.LtiSysDyn(A=self.A2,
                                B=self.B2,
                                Uset=self.Uset,
                                domain=self.poly1)
        LTI4 = hybrid.LtiSysDyn(A=self.A1,
                                B=self.B2,
                                Uset=self.Uset,
                                domain=self.poly2)
        PWA1 = hybrid.PwaSysDyn(list_subsys=[LTI3, LTI4],
                                domain=self.total_box,
                                overwrite_time=False)

        # Putting pwa together successfully, with time overwrite
        PWA2 = hybrid.PwaSysDyn(list_subsys=[LTI1, LTI2],
                                domain=self.total_box,
                                time_semantics='sampled',
                                timestep=.1,
                                overwrite_time=True)
 def test_pwa_invalid_semantics(self):
     LTI1 = hybrid.LtiSysDyn(A=self.A1, B=self.B1,
                             Uset=self.Uset, domain=self.poly1,
                             time_semantics='sampled', timestep=.1)
     LTI2 = hybrid.LtiSysDyn(A=self.A2, B=self.B2,
                             Uset=self.Uset, domain=self.poly2,
                             time_semantics='sampled', timestep=.1)
     PWA = hybrid.PwaSysDyn(list_subsys=[LTI1, LTI2], domain=self.total_box,
                            time_semantics='hello')
 def test_pwa_difftseman_from_subsys(self):
     """LtiSysDyn subsystems time semantics do not match that of PwaSysDyn"""
     LTI1 = hybrid.LtiSysDyn(A=self.A1, B=self.B1,
                             Uset=self.Uset, domain=self.poly1,
                             time_semantics='sampled', timestep=.1)
     LTI2 = hybrid.LtiSysDyn(A=self.A2, B=self.B2,
                             Uset=self.Uset, domain=self.poly2,
                             time_semantics='sampled', timestep=.1)
     PWA = hybrid.PwaSysDyn(list_subsys=[LTI1, LTI2], domain=self.total_box,
                            time_semantics='discrete', overwrite_time=False)
 def test_pwa_difftstep_among_subsys(self):
     """Different timesteps among LtiSysDyn subsystems of PwaSysDyn"""
     LTI1 = hybrid.LtiSysDyn(A=self.A1, B=self.B1,
                             Uset=self.Uset, domain=self.poly1,
                             time_semantics='sampled', timestep=.1)
     LTI2 = hybrid.LtiSysDyn(A=self.A2, B=self.B2,
                             Uset=self.Uset, domain=self.poly2,
                             time_semantics='sampled', timestep=.2)
     PWA = hybrid.PwaSysDyn(list_subsys=[LTI1, LTI2], domain=self.total_box,
                            time_semantics='sampled', timestep=.1,
                            overwrite_time=False)
Exemple #7
0
def _import_ltisys(node):
    A = _import_xml(node.findall('A')[0])
    B = _import_xml(node.findall('B')[0])
    E = _import_xml(node.findall('E')[0])
    K = _import_xml(node.findall('K')[0])
    Uset = node.findall('Uset')
    Wset = node.findall('Wset')
    domain = node.findall('domain')

    if not Uset:
        Uset = None
    else:
        Uset = _import_xml(Uset[0])
    if not Wset:
        Wset = None
    else:
        Wset = _import_xml(Wset[0])
    if not domain:
        domain = None
    else:
        domain = _import_xml(domain[0])

    return hybrid.LtiSysDyn(A=A,
                            B=B,
                            E=E,
                            K=K,
                            Uset=Uset,
                            Wset=Wset,
                            domain=domain)
Exemple #8
0
 def test_lti_invalid_semantics(self):
     LTI = hybrid.LtiSysDyn(A=self.A1,
                            B=self.B1,
                            Uset=self.Uset,
                            domain=self.poly1,
                            time_semantics='hello',
                            timestep=.1)
Exemple #9
0
 def test_nonpositive_timestep(self):
     LTI = hybrid.LtiSysDyn(A=self.A1,
                            B=self.B1,
                            Uset=self.Uset,
                            domain=self.poly1,
                            time_semantics='sampled',
                            timestep=0)
Exemple #10
0
def drifting_dynamics(dom):
    A = np.array([[1.0, 0.0], [0.0, 1.0]])
    B = np.array([[1.0], [0.0]])
    U = pc.box2poly([[0.0, 1.0]])
    K = np.array([[1.0], [0.0]])
    sys = hybrid.LtiSysDyn(A, B, None, K, U, None, dom)
    return sys
Exemple #11
0
 def test_timestep_wrong_type(self):
     LTI = hybrid.LtiSysDyn(A=self.A1,
                            B=self.B1,
                            Uset=self.Uset,
                            domain=self.poly1,
                            time_semantics='sampled',
                            timestep='.1')
def switched_system_test():
    subsystems = []
    
    # subsystem 0
    A = np.eye(2)
    B = np.eye(2)
    
    Uset = pc.box2poly([[0.0, 1.0], [0.0, 1.0]])
    domain0 = pc.box2poly([[0.0, 2.0], [0.0, 2.0]])
    
    subsystems += [hybrid.LtiSysDyn(A, B, Uset=Uset, domain=domain0)]
    
    # subsystem 1
    domain1 = pc.box2poly([[2.0, 4.0], [0.0, 2.0]])
    
    subsystems += [hybrid.LtiSysDyn(A, B, Uset=Uset, domain=domain1)]
    
    # PWA system
    domain = domain0.union(domain1)
    pwa = hybrid.PwaSysDyn(subsystems, domain)
    
    # Switched system (mode dynamics the same, just testing code)
    dom = (2, 2)
    dyn = {
        ('a', 'c'):pwa,
        ('a', 'd'):pwa,
        ('b', 'c'):pwa,
    }
    env_labels = ['a', 'b']
    sys_labels = ['c', 'd']
    
    hyb = hybrid.SwitchedSysDyn(
        disc_domain_size=dom,
        dynamics=dyn,
        cts_ss=domain,
        env_labels=env_labels,
        disc_sys_labels=sys_labels
    )
    
    print(hyb)
    
    assert(hyb.disc_domain_size == dom)
    assert(hyb.dynamics == dyn)
    assert(hyb.env_labels == env_labels)
    assert(hyb.disc_sys_labels == sys_labels)
    assert(hyb.cts_ss == domain)
Exemple #13
0
 def test_disctime_errtstep(self):
     """Discrete time semantics yet given timestep"""
     LTI = hybrid.LtiSysDyn(A=self.A1,
                            B=self.B1,
                            Uset=self.Uset,
                            domain=self.poly1,
                            time_semantics='discrete',
                            timestep=.1)
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
def subsys1():
    dom = pc.box2poly([[0., 3.], [0., 2.]])

    A = np.eye(2)
    B = np.eye(2)

    U = pc.box2poly([[0., 0.], [-1., 0.]])
    U.scale(input_bound)

    sys_dyn = hybrid.LtiSysDyn(A, B, Uset=U, domain=dom)

    return sys_dyn
def define_dynamics(dom):
    A = np.eye(2)

    B = np.array([[1.0, -1.0], [0.0, +1.0]])

    U = pc.box2poly([[0.0, 3.0], [-3.0, 3.0]])

    E = np.array([[0.0], [-1.0]])

    W = pc.box2poly([[-1.0, 1.0]])
    W.scale(0.4)

    K = np.array([[0.0], [-0.4]])

    sys = hybrid.LtiSysDyn(A, B, E, K, U, W, dom)
    return sys
Exemple #17
0
def subsys1(h):
    A = np.array([[0.9948, 0.], [0., 1.1052]])
    B = np.array([[-1.1052, 0.], [0., 1.1052]])
    E = np.array([[1, 0], [0, 1]])

    U = box2poly([[-1., 1.], [-1., 1.]])
    U.scale(input_bound)

    W = box2poly([[-1., 1.], [-1., 1.]])
    W.scale(uncertainty)

    dom = box2poly([[0., 3.], [0., h]])

    sys_dyn = hybrid.LtiSysDyn(A, B, E, None, U, W, dom)

    return sys_dyn
Exemple #18
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
Exemple #19
0
                                     np.array([0, 0, 2 * fuel_consumption]))

## Dynamics
A = np.eye(2)
B = np.array([[-1], [1]])
E = np.array([[0], [1]])
K1 = np.array([[0.], [-fuel_consumption]])
K2 = np.array([[refill_rate], [-fuel_consumption]])
U1 = pc.Polytope(np.array([[1, 0, 0], [-1, 0, 0], [1, -1, 0]]),
                 np.array([input_ub, -input_lb, 0]))
U2 = pc.Polytope(np.array([[1, 0, 0], [-1, 0, 0], [1, -1, 0]]),
                 np.array([input_ub, -input_lb, refill_rate]))
W = pc.Polytope(np.array([[1], [-1]]), np.array([disturbance, disturbance]))

# Normal operation dynamics
cont_dyn_normal = hybrid.LtiSysDyn(A, B, E, K1, U1, W, domain=cont_ss)

# Aerial refueling mode dynamics
cont_dyn_refuel = hybrid.LtiSysDyn(A, B, E, K2, U2, W, domain=cont_ss)

## Switched Dynamics
env_modes = ('normal', 'refuel')
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),
Exemple #20
0
# 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)
# @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) if show else None
# @partition_section_end@

# @discretize_section@
# Given dynamics & proposition-preserving partition, find feasible transitions
Exemple #21
0
def load_lti(A, B, K, domainA, domainB, UsetA, UsetB):
    domain = polytope.Polytope(domainA, domainB)
    Uset = polytope.Polytope(UsetA, UsetB)

    lti = hybrid.LtiSysDyn(A=A, B=B, K=K, domain=domain, Uset=Uset)
    return lti
Exemple #22
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
Exemple #23
0
A = np.array([[1., 0, 2., 0], [0, 1., 0, 2], [0, 0, 0.5, 0], [0, 0, 0, 0.5]])
B = np.array([[0, 0], [0, 0], [5, 0], [0, 5]])
E = np.array([[1., 0, 0, 0], [0, 1., 0, 0], [0, 0, 1., 0], [0, 0, 0, 1.]])
# $x^+=Ax+Bu+E W$

# Size of the sets
X = box2poly([[0, 100.], [0, 100.], [-5, 5.], [-5, 5.]])
U = box2poly(input_bound * np.array([[-1, 1.], [-1, 1.]]))
W = box2poly(disturbance_bound *
             np.array([[-0.5, 0.5], [-0.5, 0.5], [-0.1, 0.1], [-0.1, 0.1]]))
print(
    "----------------------------------\n Define system\n----------------------------------"
)
# Intermezzo polytope tutorial
#  https://github.com/tulip-control/polytope/blob/master/doc/tutorial.md
sys_dyn = hybrid.LtiSysDyn(A, B, E, None, U, W, X)

print(str(sys_dyn))

print(
    "----------------------------------\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]])
#
Exemple #24
0
K_heat = np.array([[0.], [0.01]])
K_cool = np.array([[0.], [-0.01]])
K_on = np.array([[0.], [0.]])

B_zero = np.array([[0., 0.], [0., 0.]])

cont_state_space = box2poly([[15., 24.], [15., 24.]])
cont_props = {}
cont_props['LOW'] = box2poly([[17., 19.], [20., 22.]])
cont_props['HIGH'] = box2poly([[21., 22.], [20., 22.]])
cont_props['OUTSIDE'] = box2poly([[24., 25.], [24., 25.]])
orig_props = set(cont_props)
out = []
out.append(box2poly([[24., 25.], [24., 25.]]))

sdyn_off = hybrid.LtiSysDyn(A_off, B_zero, None, K_off, None, None,
                            cont_state_space)
sdyn_heat = hybrid.LtiSysDyn(A_heat, B_zero, None, K_heat, None, None,
                             cont_state_space)
sdyn_cool = hybrid.LtiSysDyn(A_cool, B_zero, None, K_cool, None, None,
                             cont_state_space)
sdyn_on = hybrid.LtiSysDyn(A_on, B_zero, None, K_on, None, None,
                           cont_state_space)

pwa_off = hybrid.PwaSysDyn(
    list_subsys=[sdyn_off],
    domain=cont_state_space)  #,time_semantics='sampled',timestep=0.1)
pwa_heat = hybrid.PwaSysDyn(list_subsys=[sdyn_heat], domain=cont_state_space)
pwa_cool = hybrid.PwaSysDyn(list_subsys=[sdyn_cool], domain=cont_state_space)
pwa_on = hybrid.PwaSysDyn(list_subsys=[sdyn_on], domain=cont_state_space)

#print pwa_off
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
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)