Exemple #1
0
def ray_shooting_hyperplanes_older(Q,N=0,H_rays=None):
    """
    Ray Shooting to find an outer-approximation of the AH-polytope
    """
    prog=MP.MathematicalProgram()
    Q=pp.to_AH_polytope(Q)

    if type(H_rays)==type(None):
        if N==0:
            N=2**(Q.n-1) # This many hyperplanes I want :) 
        H_rays=np.random.normal(size=(N,Q.n))
    else:
        N=H_rays.shape[0]
        assert H_rays.shape[1]==Q.n
    h_y=prog.NewContinuousVariables(2*N,1,"hy")
    H_y=np.vstack(( H_rays , -H_rays ))
    Y=pp.H_polytope(H_y,h_y)
    pp.subset(prog,Q,Y)
    prog.AddLinearCost(np.ones(2*N),np.array([0]),h_y)
    result=gurobi_solver.Solve(prog,None,None)
    if result.is_success():
        h_y_n=result.GetSolution(h_y).reshape(2*N,1)
        return pp.H_polytope(H_y,h_y_n)
    else:
        print("The polytope you gave me seems unbounded or \
              there is another error")
Exemple #2
0
def inner_optimization_new(Q,X=None,N=100,k=-1):
    """
    Q= AH_polytope
    X= H_polytope Candidate
    """
    # Sanity Checks
    assert Q.type=='AH_polytope' or Q.type=='V_polytope'
    Q=pp.to_AH_polytope(Q)
    if type(X)==type(None):
        X=ray_shooting_hyperplanes(Q,N=N)
    else:
        assert X.type=='H_polytope'
    # Program
    n=Q.n
    prog=MP.MathematicalProgram()
    # T=prog.NewSymmetricContinuousVariables(Q.n,'T')
    T=prog.NewContinuousVariables(n,n,"T")
    t=prog.NewContinuousVariables(n,1,"t")
#    prog.AddPositiveSemidefiniteConstraint(T)
    Y=pp.AH_polytope(T=T,t=t,P=X) 
    pp.subset(prog,Y,Q,k=k,verbose=True)
    result=volume_maximization(prog, T,0.1*np.eye(n)+0.1 )
    if result.is_success():
        print("success")
        T_n= result.GetSolution(T)
        t_n= result.GetSolution(t).reshape(n,1)
        print("determinent=",np.linalg.det(T_n))
        return pp.affine_map( T=T_n, P=X, t=t_n),np.linalg.det(T_n)
    else:
        print("not succesfull")         
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
def add_disjunctive_subsets(program, inbody, list_of_circumbodies):
    """
    Parameters
    ----------
    program : add constraints to the program
        DESCRIPTION.
    inbody : polytopic object
        the inbody.
    list_of_circumbodies : list
        the list of circumbodies.

    Returns
    -------
    mu : dict 
        dict of binary auxilary variables
        dict[hash(polytope)]=BINARYVARIABLE (drake mathematical program)

    """
    mu, T, t = {}, {}, {}
    print("disjunctive subset with %d circumbodies" %
          len(list_of_circumbodies))
    assert type(list_of_circumbodies) == list
    my_inbody = pp.to_AH_polytope(inbody)
    sigma_T = my_inbody.T
    sigma_t = my_inbody.t
    for circumbody in list_of_circumbodies:
        i = hash(circumbody)
        T[i] = program.NewContinuousVariables(my_inbody.T.shape[0],
                                              my_inbody.T.shape[1])
        t[i] = program.NewContinuousVariables(my_inbody.t.shape[0], 1)
        mu[i] = program.NewBinaryVariables(1, 1, 'dmu')
        _inbody = pp.AH_polytope(t=t[i], T=T[i], P=my_inbody.P)
        _circumbody = pp.to_AH_polytope(circumbody)
        _circumbody.P.h = _circumbody.P.h * mu[i]
        _circumbody.t = _circumbody.t * mu[i]
        pp.subset(program, _inbody, _circumbody)
        sigma_T = sigma_T - T[i]
        sigma_t = sigma_t - t[i]

    # print(sigma_T.shape,sigma_t.shape)
    _mu = np.vstack(
        [mu[hash(circumbody)] for circumbody in list_of_circumbodies])
    program.AddLinearEqualityConstraint(\
        np.ones((1,len(list_of_circumbodies))),np.ones((1,1)),_mu)

    program.AddLinearConstraint(
        np.equal(sigma_T, np.zeros(sigma_T.shape), dtype='object').flatten())
    program.AddLinearConstraint(
        np.equal(sigma_t, np.zeros(sigma_t.shape), dtype='object').flatten())
    return mu, t, T
def Hausdorff_distance(Q1,
                       Q2,
                       directed=False,
                       ball="infinty_norm",
                       solver="gurobi",
                       k=-1):
    X, Y = pp.to_AH_polytope(Q1), pp.to_AH_polytope(Q2)
    prog = MP.MathematicalProgram()
    # Variables
    n = Q1.n
    D1 = prog.NewContinuousVariables(1, "D1")
    D2 = prog.NewContinuousVariables(1, "D2")
    if ball == "infinty_norm":
        P_ball = pp.unitbox(n).H_polytope
    elif ball in ["L1", 1, "1", "l1"]:
        P_ball = pp.unitball(n, 1)
    else:
        print("I don't recognize the ball norm")
        raise NotImplementedError

    if P_ball.type == 'H_polytope':
        Dball1 = pp.H_polytope(P_ball.H, P_ball.h * D1)
        if not directed:
            Dball2 = pp.H_polytope(P_ball.H, P_ball.h * D2)

    if P_ball.type == 'AH_polytope':
        Dball1=pp.AH_polytope(t=P_ball.t*D1,T=P_ball.T,\
                             P=pp.H_polytope(P_ball.P.H,P_ball.P.h*D1))
        if not directed:
            Dball2=pp.AH_polytope(t=P_ball.t*D2,T=P_ball.T,\
                     P=pp.H_polytope(P_ball.P.H,P_ball.P.h*D2))

    X_plus = pp.minkowski_sum(X, Dball1)
    pp.subset(prog, Y, X_plus, k=k)
    prog.AddLinearCost(np.array([1]), np.array([0]), D1)
    if not directed:
        Y_plus = pp.minkowski_sum(Y, Dball2)
        pp.subset(prog, X, Y_plus, k=k)
        prog.AddLinearCost(np.array([1]), np.array([0]), D2)
    if solver == "gurobi":
        result = gurobi_solver.Solve(prog, None, None)
    if result.is_success():
        dXY = np.asscalar(result.GetSolution(D1))
        if not directed:
            dYX = np.asscalar(result.GetSolution(D2))
            return max(dXY, dYX), dXY, dYX
        else:
            return dXY
Exemple #6
0
def outer_optimization(Q,X=None,N=100,k=-1):
    """
    Q= AH_polytope
    X= H_polytope Candidate
    """
    # Sanity Checks
    assert Q.type=='AH_polytope' or Q.type=='V_polytope'
    Q=pp.to_AH_polytope(Q)
    if type(X)==type(None):
        X=ray_shooting_hyperplanes(Q,N=N)
    else:
        assert X.type=='H_polytope'
    # Program
    n=Q.n
    prog=MP.MathematicalProgram()
#    T=prog.NewSymmetricContinuousVariables(Q.n,'T')
    T=prog.NewContinuousVariables(n,n,"T")
    t=prog.NewContinuousVariables(n,1,"t")
#    prog.AddPositiveSemidefiniteConstraint(T)
    prog.AddMaximizeLogDeterminantSymmetricMatrixCost(T)
    Q_new=pp.AH_polytope(T=np.dot(T,Q.T),t=np.dot(T,Q.t)+t,P=Q.P) 
    pp.subset(prog,Q_new,X,k=k,verbose=True)
    result=scs_solver.Solve(prog,None,None)
    if result.is_success():
        print("success")
        T_n= result.GetSolution(T)
        t_n= result.GetSolution(t).reshape(n,1)
        Tinv=np.linalg.inv(T_n)
        t_new=np.dot(-Tinv,t_n)
        print("determinent=",np.linalg.det(T_n))
#        Q_new_n=pp.AH_polytope(T=np.dot(T_n,Q.T),t=np.dot(T_n,Q.t)+t_n,P=Q.P) 
#        return Q_new_n
        return pp.affine_map( T=Tinv, P=X, t=t_new),np.linalg.det(Tinv)
#        return pp.AH_polytope(T=Tinv,t=t_new,P=X) 
    else:
        print("not succesfull") 
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")
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