コード例 #1
0
def rci(A, B, X, U, W, eta=0.001, q=1):
    n, m = A.shape[0], B.shape[1]
    W = pp.zonotope(x=np.zeros((n, 1)), G=W.G * eta)
    program = MP.MathematicalProgram()
    q += n
    program = MP.MathematicalProgram()
    phi = program.NewContinuousVariables(n, q, 'phi')
    theta = program.NewContinuousVariables(m, q, 'theta')
    alpha = program.NewContinuousVariables(1, 'alpha')
    beta = program.NewContinuousVariables(2, 'beta')
    program.AddBoundingBoxConstraint(0, 1, alpha)
    program.AddBoundingBoxConstraint(0, 10, beta)
    K = np.hstack(((np.dot(A, phi) + np.dot(B, theta))[:, n:], W.G))
    program.AddLinearConstraint(np.equal(K, phi, dtype='object').flatten())
    inbody = pp.zonotope(x=np.zeros((n, 1)),
                         G=(np.dot(A, phi) + np.dot(B, theta))[:, 0:n])
    _W = pp.to_AH_polytope(W)
    _W.P.h = _W.P.h * alpha
    _X = pp.to_AH_polytope(X)
    _X.P.h = _X.P.h * beta[0]
    _U = pp.to_AH_polytope(U)
    _U.P.h = _U.P.h * beta[1]
    pp.subset(program, inbody, circumbody=_W)
    pp.subset(program, pp.zonotope(x=np.zeros((n, 1)), G=phi), circumbody=_X)
    pp.subset(program, pp.zonotope(x=np.zeros((n, 1)), G=theta), circumbody=_U)
    program.AddLinearCost(beta[0])
    program.AddLinearConstraint(beta[0] <= 1 - alpha[0])
    program.AddLinearConstraint(beta[1] <= 1 - alpha[0])
    program.AddLinearConstraint(beta[0] >= beta[1])
    result = gurobi_solver.Solve(program, None, None)
    if result.is_success():
        print("sucsess")
        print("betas are", result.GetSolution(beta))
        beta_1_n = result.GetSolution(beta)[0]
        beta_2_n = result.GetSolution(beta)[1]
        alpha_n = result.GetSolution(alpha)[0]
        phi_n = result.GetSolution(phi)
        theta_n = result.GetSolution(theta)
        Omega = pp.zonotope(x=np.zeros((2, 1)),
                            G=phi_n / beta_1_n,
                            color='red')
        pp.visualize(
            [X, Omega],
            title='Robust control invariant set $\mathcal{X}$ (red) \n \
        inside safe set $\mathbb{X}$ (green)',
            figsize=(6, 6),
            a=0.02)
        print("alpha was", alpha_n)
        omega_U = theta_n / beta_2_n
        print(omega_U)
        print('sum_omega=', np.sum(np.abs(omega_U), 1)[0])
        return Omega
    else:
        print("failure")
コード例 #2
0
def decompose(zonotope, dimensions):
    """
    @author: kasra
    Decompising a given set into bunch of fewer dimensional sets such that 
    the Cartesian product of those sets is a subset of the given set.
    """

    assert (sum(dimensions) == len(
        zonotope.G)), "ValueError: sum of the given dimensions has \
                                                to be equal to the dimension of the input set"

    #number_of_sets = len(dimensions)

    prog = MP.MathematicalProgram()

    #defining varibales
    x_i = [prog.NewContinuousVariables(i) for i in dimensions]
    G_i = [prog.NewContinuousVariables(i, i)
           for i in dimensions]  #non-symmetric G_i
    #G_i = [prog.NewSymmetricContinuousVariables(i) for i in dimensions ]               #symmentric G_i

    #inbody_zonotope
    inbody_x = np.concatenate(x_i)
    inbody_G = block_diag(*G_i)
    inbody_zonotope = pp.zonotope(inbody_G, inbody_x)

    #Defining Constraints
    prog.AddPositiveSemidefiniteConstraint(inbody_G)
    pp.subset(prog, inbody_zonotope, zonotope)
    # ASSUMPTION for PSD of inbody_G
    # ASSUMPTION for SYMMENTRICITY of G_i

    #Defining the cost function
    prog.AddMaximizeLogDeterminantSymmetricMatrixCost(inbody_G)

    #Solving
    result = MP.Solve(prog)

    print(f"Is optimization successful? {result.is_success()}")
    print(f"Solution to x_i: {result.GetSolution(x_i[0])}")
    print(f"Solution to G_i: {result.GetSolution(G_i[0])}")
    print(f"optimal cost: {result.get_optimal_cost()}")
    print('solver is: ', result.get_solver_id().name())

    x_i_result = [result.GetSolution(x_i[i]) for i in range(len(dimensions))]
    G_i_result = [result.GetSolution(G_i[i]) for i in range(len(dimensions))]
    list_zon = [
        pp.zonotope(G=G_i_result[i], x=x_i_result[i])
        for i in range(len(dimensions))
    ]

    return list_zon
コード例 #3
0
def extend(mysystem,
           start,
           T,
           list_of_nodes,
           H_rep=True,
           N_H=500,
           tol_H=1e-5,
           color=None):
    if type(color) == type(None):
        color = (np.random.random(), np.random.random(), np.random.random())
    else:
        color = color
    x, u, mu, G, theta = polytopic_trajectory(mysystem, start, T,
                                              list_of_nodes)
    Z = {t: pp.zonotope(x=x[t], G=G[t], color=color) for t in range(T + 1)}
    funnel = [None] * T
    H_funnel = [None] * T
    for t in range(T):
        funnel[t] = pp.convex_hull(Z[t], Z[t + 1])
        funnel[t].color = color
        if H_rep:
            H_funnel[t] = pp.ray_shooting_hyperplanes(funnel[t],
                                                      N=N_H,
                                                      tol=tol_H)
    # fig,ax=plt.subplots()
    # mu[T,'free'],mu[T,'contact']=1,1
    # ax.plot( [x[t][0] for t in range(T+1)] , [x[t][2] for t in range(T+1)] )
    # ax.plot( [x[t][0] for t in range(T+1) if mu[t,'free']==0] , \
    #          [x[t][2] for t in range(T) if mu[t,'free']==0],'o',\
    #          color='red')
    # ax.plot( [x[t][0] for t in range(T+1) if mu[t,'free']==1] , \
    #          [x[t][2] for t in range(T+1) if mu[t,'free']==1],'o',\
    #          color='blue')
    # pp.visualize([Omega]+[funnel[t] for t in range(T)],ax=ax,fig=fig,a=0.01,alpha=0.99,tuple_of_projection_dimensions=(0,2))
    return funnel, H_funnel, x, mu, G
コード例 #4
0
def pca_order_reduction(zonotope, desired_order=1):
    """
    PCA method for zonotope order reduction
    inputs: input zonotope , order of the output zonotope
    output: zonotope

    Based on Kopetzki, Anna-Kathrin, Bastian Schürmann, and Matthias Althoff.
    "Methods for order reduction of zonotopes."
    2017 IEEE 56th Annual Conference on Decision and Control (CDC). IEEE, 2017.
    """
    assert (
        type(zonotope) == pp.zonotope
    ), "TypeError: The first argument need to be from \"zonotope\" class in pypolycontain package "
    assert (
        type(desired_order) == int or type(desired_order) == float
    ), "TypeError: The second argument need to be a number greater than 1. \n \
                                                                            It is the order of the reduced zonotpe which equal to the number of \
                                                                                columns over the space dimension."

    assert (
        desired_order >= 1
    ), "desired order of the outcome zonotope needs to be greater or equal to 1"

    x = np.array(zonotope.x)
    G = np.array(zonotope.G)

    dimension, numberofcolumns = G.shape
    desired_numberofcolumns = round(desired_order * dimension)

    if numberofcolumns <= desired_numberofcolumns:
        return zonotope

    G_reduced, G_untouched = sorting_generator(G, desired_numberofcolumns)
    X = np.concatenate((G_reduced, -G_reduced), axis=1).T
    covariance = np.dot(X.T, X)
    U, _, _ = np.linalg.svd(covariance)
    interval_hull = boxing_order_reduction(
        pp.zonotope(np.dot(U.T, G_reduced), x)).G
    G_pca = np.dot(U, interval_hull)

    if type(G_untouched) == np.ndarray:
        return pp.zonotope(np.concatenate((G_pca, G_untouched), axis=1), x)
    elif G_untouched == None:
        return pp.zonotope(G_pca, x)
コード例 #5
0
def boxing_order_reduction(zonotope, desired_order=1):
    """
    boxing method for zonotope order reduction
    inputs: input zonotope , order of the output zonotope
    output: zonotope

    Based on Kopetzki, Anna-Kathrin, Bastian Schurmann, and Matthias Althoff.
    "Methods for order reduction of zonotopes."
    2017 IEEE 56th Annual Conference on Decision and Control (CDC). IEEE, 2017.
    """
    assert (
        type(zonotope) == pp.zonotope
    ), "TypeError: The first argument need to be from \"zonotope\" class in pypolycontain package "
    assert (
        type(desired_order) == int or type(desired_order) == float
    ), "TypeError: The second argument need to be a number greater than 1. \n \
                                                                            It is the order of the reduced zonotpe which equal to the number of \
                                                                                columns over the space dimension."

    assert (
        desired_order >= 1
    ), "desired order of the outcome zonotope needs to be greater or equal to 1"

    x = np.array(zonotope.x)
    G = np.array(zonotope.G)

    dimension, numberofcolumns = G.shape
    desired_numberofcolumns = round(desired_order * dimension)

    if numberofcolumns <= desired_numberofcolumns:
        return zonotope

    elif dimension == desired_numberofcolumns:
        G_box = np.diag(np.sum(abs(G), axis=1))
        return pp.zonotope(G=G_box, x=x)

    else:
        G_reduced, G_untouched = sorting_generator(G, desired_numberofcolumns)
        G_box = np.concatenate(
            (np.diag(np.sum(abs(G_reduced), axis=1)), G_untouched), axis=1)
        return pp.zonotope(G=G_box, x=x)
コード例 #6
0
def translate(t, P):
    """
    Shifts the polytope by t vector
    """
    assert t.shape[0] == P.n  # Dimension match
    if P.type == 'AH_polytope':
        return pp.AH_polytope(t=t + P.t, T=P.T, P=P.P)
    elif P.type == 'zonotope':
        return pp.zonotope(x=t + P.x, G=P.G)
    elif P.type == "H_polytope":
        return pp.H_polytope(H=P.H, h=P.h + np.dot(P.H, t))
    else:
        return ValueError('Polytope type: ', P.type, " Not recognized")
コード例 #7
0
def affine_map(T, P, t=None, get_inverse=True):
    """
    Returns the affine map of a polytope.
    """
    if type(t) == type(None):
        t = np.zeros((T.shape[0], 1))
    if P.type == 'AH_polytope':
        return pp.AH_polytope(t=t + np.dot(T, P.t), T=np.dot(T, P.T), P=P.P)
    elif P.type == 'zonotope':
        return pp.zonotope(x=t + np.dot(T, P.x), G=np.dot(T, P.G))
    elif P.type == "H_polytope":
        if T.shape[0] >= T.shape[1] and get_inverse:
            Tinv = np.linalg.pinv(T)
            H = np.dot(P.H, Tinv)
            #            print("inverse error=",np.linalg.norm(np.dot(Tinv,T)-np.eye(T.shape[1])))
            assert np.linalg.norm(np.dot(Tinv, T) -
                                  np.eye(T.shape[1])) <= 1e-2 * P.n
            return pp.H_polytope(H=H, h=P.h + np.dot(H, t))
        else:
            Q = pp.to_AH_polytope(P)
            return affine_map(T, Q, t)
    else:
        return ValueError('Polytope type: ', P.type, " Not recognized")
コード例 #8
0
import numpy as np
import pypolycontain as pp
import matplotlib.pyplot as plt

x = np.array([4, 0]).reshape(2, 1)  # offset
G = np.array([[1, 0, 0.5], [0, 0.5, -1]]).reshape(2, 3)
C = pp.zonotope(x=x, G=G)
pp.visualize([C], title=r'$C$')
plt.show()

x = np.array([-1, -2]).reshape(2, 1)  # offset
G = np.array([[0, 1, 0.707, 0.293, 0.293, 0.707],
              [-1, 0, -0.293, 0.707, -0.707, 0.293]]).reshape(2, 6)
C = pp.zonotope(x=x, G=G)
pp.visualize([C], title=r'$C$')
plt.show()

H = np.array([[1, 1], [-1, 1], [0, -1], [2, 3]])
h = np.array([1, 1, 0, 1])
A = pp.H_polytope(H, h)
# pp.visualize([A],title=r'$A$')

# D = pp.operations.intersection(A, A)
# pp.visualize([D])
# D=pp.operations.convex_hull(A,C)

# D = pp.operations.check_subset(C, C)
# D.color=(0.9, 0.9, 0.1)
# pp.visualize([D,A, C],title=r'$A$ (red),$C$ (blue), $D=A\oplus C$ (yellow)')
# t=np.array([5,0]).reshape(2,1) # offset
# theta=np.pi/6 # 30 degrees
コード例 #9
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Jun 23 23:35:22 2020

@author: sadra
"""

import numpy as np
from itertools import combinations
import pypolycontain as pp

G = np.random.random((2, 8)) - 0.5
G = np.array([[1, 0, 0], [0, 1, 0]])
Z = pp.zonotope(G, color='red')

S = combinations(range(G.shape[1]), G.shape[0])
V = 0
for s in S:
    #    print(s)
    Gs = np.hstack([G[:, i:i + 1] for i in s])
    print(Gs)
    V += abs(np.linalg.det(Gs))
V *= 2**G.shape[0]
print(V)

pp.visualize([Z, pp.zonotope(np.eye(2) * 0.5)], title=r'volume=%0.002f' % V)

S = combinations(range(G.shape[1]), G.shape[0])
V_dot = np.zeros(G.shape)
for s in S:
コード例 #10
0
def polytopic_trajectory(system,
                         start,
                         T,
                         list_of_goals,
                         q=None,
                         Q=None,
                         R=None):
    n, m = system.n, system.m
    if type(Q) == type(None):
        Q = np.eye(n)
    if type(R) == type(None):
        R = np.eye(m)
    if type(q) == type(None):
        q = n
    S = list(system.modes)
    S_all = S + ['all']
    prog = MP.MathematicalProgram()
    x={(i,t): prog.NewContinuousVariables(n,1,"x%s%d"%(i,t)) \
       for i in S_all for t in range(T+1)}
    u={(i,t): prog.NewContinuousVariables(m,1,"x%s%d"%(i,t)) \
       for i in S_all for t in range(T)}
    mu={(i,t): prog.NewBinaryVariables(1,1,"x%s%d"%(i,t)) \
       for i in S for t in range(T)}

    G={(i,t): prog.NewContinuousVariables(n,q,"x%s%d"%(i,t)) \
       for i in S_all for t in range(T+1)}
    theta={(i,t): prog.NewContinuousVariables(m,q,"x%s%d"%(i,t)) \
       for i in S_all for t in range(T)}

    # Containment
    for i in S:
        for t in range(T):
            XU = system.modes[i].XU
            xu = np.vstack((x[i, t], u[i, t]))
            Gtheta = np.vstack((G[i, t], theta[i, t]))
            inbody = pp.zonotope(x=xu, G=Gtheta)
            circumbody = pp.H_polytope(XU.H, XU.h * mu[i, t])
            pp.subset(prog, inbody, circumbody)

    # Dynamics of point
    for t in range(T):
        _M=np.hstack([np.hstack((-system.modes[i].A,-system.modes[i].B,\
                                 -system.modes[i].c)) for i in S]\
                     + [np.eye(n)])
        _v = np.vstack([np.vstack((x[i, t], u[i, t], mu[i, t]))
                        for i in S] + [x['all', t + 1]])
        prog.AddLinearEqualityConstraint(_M, np.zeros((n, 1)), _v)
        # Dynamics of polytopes
        _M=np.hstack([np.hstack((-system.modes[i].A,-system.modes[i].B)) for i in S]\
                     + [np.eye(n)])
        _v = np.vstack([np.vstack((G[i, t], theta[i, t]))
                        for i in S] + [G['all', t + 1]])
        for j in range(q):
            prog.AddLinearEqualityConstraint(_M, np.zeros((n, 1)), _v[:, j])

    # Summation Equation
    for t in range(T):
        _u = np.vstack([u[i, t] for i in S_all])
        _uI = np.hstack([np.eye(system.m)
                         for i in S] + [-np.eye(m)])  # Very non-efficient
        prog.AddLinearEqualityConstraint(_uI, np.zeros((m, 1)), _u)

        _theta = np.vstack([theta[i, t] for i in S_all])
        for j in range(q):
            prog.AddLinearEqualityConstraint(_uI, np.zeros((m, 1)), _theta[:,
                                                                           j])

        _mu = np.vstack([mu[i, t] for i in S])
        prog.AddLinearEqualityConstraint(np.ones((1, len(S))), np.ones((1, 1)),
                                         _mu)

    for t in range(T + 1):
        _x = np.vstack([x[i, t] for i in S_all])
        _xI = np.hstack([np.eye(n) for i in S] + [-np.eye(n)])
        prog.AddLinearEqualityConstraint(_xI, np.zeros((n, 1)), _x)

        _G = np.vstack([G[i, t] for i in S_all])
        for j in range(q):
            prog.AddLinearEqualityConstraint(_xI, np.zeros((n, 1)), _G[:, j])

    # start
    prog.AddLinearConstraint(
        np.equal(x['all', 0], start, dtype='object').flatten())
    # end
    mu_d, t_d, T_d = pp.add_disjunctive_subsets(
        prog, pp.zonotope(x=x['all', T], G=G['all', T]), list_of_goals)
    # pp.subset(prog, pp.zonotope(x=x['all',T],G=G['all',T]), goal)

    # Cost function
    for t in range(T + 1):
        prog.AddQuadraticCost(Q, np.zeros(n), x['all', t])
    for t in range(T):
        prog.AddQuadraticCost(R, np.zeros(n), u['all', t])

    # Volume Optimization
    prog.AddLinearCost(G['all', 0][0, 0] * 10 + G['all', 0][1, 1] * 1)
    print("*" * 10, " Set up a mixed-integer optimization problem", "*" * 10)
    # solve and result
    result = gurobi_solver.Solve(prog, None, None)
    if result.is_success():
        print('polytopic trajectory optimization succesfull')
        x_n = {t: result.GetSolution(x["all", t]) for t in range(T + 1)}
        u_n = {t: result.GetSolution(u["all", t]) for t in range(T)}
        mu_n = {(t, i): result.GetSolution(mu[i, t]).item()
                for i in S for t in range(T)}
        G_n = {t: result.GetSolution(G["all", t]) for t in range(T + 1)}
        theta_n = {t: result.GetSolution(theta["all", t]) for t in range(T)}
        # Disjunctive Sets
        # print(mu_d,type(mu_d))
        # print({result.GetSolution(i) for i in mu_d})
        # for i in t_d:
        #     print(result.GetSolution(t_d[i]))
        #     print(result.GetSolution(T_d[i]))
        return x_n, u_n, mu_n, G_n, theta_n
    else:
        print('polytopic trajectory optimization failed')
        return