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
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
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
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'
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())
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
# 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)
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)')
# 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)
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
"----------------------------------\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
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
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)