def __init__(self, mrobot):

  ## "Arbitrary" parameters
    self.N_s = 15 # nb of samples for discretization
    self.n_knot = 4 # nb of non zero lenght intervals of the knot series
    self.t_init = 0.0
    self.Tc = 0.5
    self.Tp = 1.1
    tstep = (self.Tp-self.t_init)/(self.N_s-1)
    Tc_idx = int(round(self.Tc/tstep))
    self.detection_radius = 2.0

  ## Mobile Robot object
    self.mrob = mrobot

  ## Other parameters
    self.d = self.mrob.l+2 # B-spline order (integer | d > l+1)
    self.n_ctrlpts = self.n_knot + self.d - 1 # nb of ctrl points

  ## Constaints values...
  ## ...for equations:
    # initial state
    self.q_init = np.matrix([[0.0], [0.0], [np.pi/2]])
    # final state
    self.q_fin = np.matrix([[2.0], [5.0], [np.pi/2]])
    # initial control input
    self.u_init = np.matrix([[0.0], [0.0]])
    # final control input
    self.u_fin = np.matrix([[0.0], [0.0]])
  ## ...for inequations:
    # Control boundary
    self.u_abs_max = self.mrob.u_abs_max
    # Obstacles (Q_occupied)
    # TODO: Obstacles random generation
    self.obst_map =                          np.matrix([0.25, 2.5, 0.2])
    self.obst_map = np.append(self.obst_map, np.matrix([2.3,  2.5, 0.5]),
        axis = 0)
    self.obst_map = np.append(self.obst_map, np.matrix([1.25, 3,   0.1]),
        axis = 0)
    self.obst_map = np.append(self.obst_map, np.matrix([0.3,  1.0,   0.1]),
        axis = 0)
    self.obst_map = np.append(self.obst_map, np.matrix([-0.5, 1.5, 0.3]),
        axis = 0)
#    self.obst_map = np.append(self.obst_map, np.matrix([1.6, 4.3, 0.2]),
#        axis = 0)
    
    # max distance within Tp
    self.D = self.Tp * self.u_abs_max[0,0]

    # Ctrl pts init
    C = np.array(np.zeros((self.n_ctrlpts,self.mrob.u_dim)))
    C_lower = np.array([-10, -1]*self.n_ctrlpts)
    C_upper = np.array([+10, +6]*self.n_ctrlpts)
    
    self.detected_obst_idxs = []

    # final trajectory
    self.C_ref = []

  ## Generate initial b-spline knots
    self.knots = self._gen_knots(self.t_init, self.Tp)
    self.mtime = np.linspace(self.t_init, self.Tp, self.N_s)

  ## Optimization results
    self.unsatisf_eq_values = []
    self.unsatisf_ieq_values = []

  ## Plot initialization
    plt.ion()
    self.fig = plt.figure()
    self.fig_speed = plt.subplots(2)
    ax = self.fig.gca()

    # creating obstacles' circles
    circ = []
    for r in range(self.obst_map.shape[0]):
      # external dashed circles
      circ = circ + \
          [plt.Circle((self.obst_map[r,0], self.obst_map[r,1]),
          self.obst_map[r,2]+self.mrob.rho,color='k',ls = 'dashed',fill=False)]
      # internal continous circles
      circ = circ + \
          [plt.Circle((self.obst_map[r,0], self.obst_map[r,1]),
          self.obst_map[r,2], color='k', fill=False)]

    # adding circles to axis
    [ax.add_artist(c) for c in circ]

    # plot curve and its control points
    self.rejected_path,self.plt_ctrl_pts,self.plt_curve,self.plt_dot_curve,self.seg_pts = ax.plot(
            0.0, 0.0, 'm:',
            0.0, 0.0, '*',
            0.0, 0.0, 'b-',
            0.0, 0.0, 'g.',
            0.0, 0.0, 'rd')
    
    # formating figure
    plt.xlabel('x(m)')
    plt.ylabel('y(m)')
    plt.title('Generated trajectory')
    ax.axis('equal')

    axarray = self.fig_speed[0].axes
    self.plt_linspeed, = axarray[0].plot(0.0, 0.0)
    self.plt_angspeed, = axarray[1].plot(0.0, 0.0)
    axarray[0].set_ylabel('v(m/s)')
    axarray[0].set_title('Linear speed')
    axarray[1].set_xlabel('time(s)')
    axarray[1].set_ylabel('w(rad/s)')
    axarray[1].set_title('Angular speed')
    axarray[0].grid()
    axarray[1].grid()

    final_z = self.mrob.phi0(self.q_fin)
    self.last_q = self.q_init
    self.last_u = self.u_init
    last_z = self.mrob.phi0(self.last_q)
    self.all_dz = []
    self.all_rejected_z = []
    self.itcount = 0

    usepyopt = False

    while LA.norm(last_z - final_z) > self.D: 
# while the remaining dist (straight line) is greater than the max dist during Tp

        self.detected_obst_idxs = self._detected_obst_idx(last_z)
#        print('No of detected obst: {}'.format(len(self.detected_obst_idxs)))
#        print('Detected obst: {}'.format(self.obst_map[self.detected_obst_idxs,:]))

        # initiate ctrl points (straight line towards final z)
        direc = final_z - last_z
        direc = direc/LA.norm(direc)
        C[:,0] =np.array(np.linspace(last_z[0,0],\
                last_z[0,0]+self.D*direc[0,0], self.n_ctrlpts)).T
        C[:,1] =np.array(np.linspace(last_z[1,0],\
                last_z[1,0]+self.D*direc[1,0], self.n_ctrlpts)).T

        tic = time.time()
        if usepyopt:
            # Define the optimization problem
            self.opt_prob = pyOpt.Optimization(
                    'Faster path with obstacles', # name of the problem
                    self._obj_func) # object function (criterium, eq. and ineq.)
    
            self.opt_prob.addObj('J')
    
            self.opt_prob.addVarGroup( # minimization arguments
                    'C',
                    self.mrob.u_dim*self.n_ctrlpts, # dimension
                    'c', # continous
                    lower=list(C_lower),
                    value=list(np.squeeze(C.reshape(1,self.n_ctrlpts*self.mrob.u_dim))),
                    upper=list(C_upper))
    
            self.opt_prob.addConGroup( # equations constraints
                    'ec',
                    self.mrob.q_dim + self.mrob.u_dim, # dimension
                    'e') # equations
    
            self.opt_prob.addConGroup( # inequations constraints
                    'ic',
                    self.N_s*self.mrob.u_dim +
                            self.N_s*len(self.detected_obst_idxs), # dimenstion
                    'i') # inequations
    
            # solve constrained optmization
#            solver = pyOpt.SLSQP(pll_type='POA')
#            solver.setOption('ACC', 1e-6)
#            solver.setOption('MAXIT', 30)
            solver = pyOpt.ALGENCAN(pll_type='POA')
            solver.setOption('epsfeas', 1e-1)
            solver.setOption('epsopt', 9e-1)
    
            [J, C_aux, information] = solver(self.opt_prob) 
            C_aux = np.array(C_aux)
#            if information.value != 0 and iformation.value != 9:
            usepyopt = False 

        else:
            # solve constrained optmization
            outp = fmin_slsqp(self._criteria,
                                np.squeeze(C.reshape(1,self.n_ctrlpts*self.mrob.u_dim)),
                                eqcons=(),
                                f_eqcons=self._feqcons,
                                ieqcons=(),
                                f_ieqcons=self._fieqcons,
                                iprint=1,
                                iter=50,
                                acc=1e-6,
                                full_output=True,
                                callback=self._plot_update)
            C_aux = outp[0]
            imode = outp[3]
            print('\n'.format(imode))
            if imode != 0 and imode != 9:
                usepyopt = True
                continue
        

        print('Elapsed time for {} iteraction: {}'.format(self.itcount, time.time()-tic))

        print('No of equations unsatisfied: {}'.format(len(self.unsatisf_eq_values)))
        print('Mean and variance of equations unsatisfied: ({},{})'.format(np.mean(self.unsatisf_eq_values), np.std(self.unsatisf_eq_values)))
        print('No of inequations unsatisfied: {}'.format(len(self.unsatisf_ieq_values)))
        print('Mean and variance of inequations unsatisfied: ({},{})'.format(np.mean(self.unsatisf_ieq_values), np.std(self.unsatisf_ieq_values)))

        # test if opt went well
        # if yes
        C = C_aux
        # if no
        # continue

        C = C.reshape(self.n_ctrlpts, self.mrob.u_dim)
        # store ctrl points and [z dz ddz](t)
        self.C_ref += [C]
        dz = self._comb_bsp(self.mtime[0:Tc_idx], C, 0).T
        for dev in range(1,self.mrob.l+1):
            dz = np.append(dz,self._comb_bsp(
                    self.mtime[0:Tc_idx], C, dev).T,axis=0)
        self.all_dz += [dz]

        rejected_z = self._comb_bsp(self.mtime[Tc_idx:], C, 0).T
        self.all_rejected_z += [np.append(np.append(dz[0:2,:], rejected_z, axis=1), np.fliplr(rejected_z), axis=1)]
        
        # update needed values
        self.knots = self.knots + self.Tc
        self.mtime = [tk+self.Tc for tk in self.mtime]
        last_z = self.all_dz[-1][0:self.mrob.u_dim,-1]
#        print('Last z: {}', last_z)
#        print(self.all_dz[-1][:,-1].reshape(
#                self.mrob.l+1, self.mrob.u_dim).T)
        self.last_q = self.mrob.phi1(self.all_dz[-1][:,-1].reshape(
                self.mrob.l+1, self.mrob.u_dim).T)
        self.last_u = self.mrob.phi2(self.all_dz[-1][:,-1].reshape(
                self.mrob.l+1, self.mrob.u_dim).T)

        #raw_input('paradinha')
        self.itcount += 1
    #endwhile
    
    self.detected_obst_idxs = self._detected_obst_idx(last_z)
    print(self.detected_obst_idxs)

    # initiate ctrl points (straight line towards final z)
    C[:,0] =np.array(np.linspace(last_z[0,0],\
            final_z[0,0], self.n_ctrlpts)).T
    C[:,1] =np.array(np.linspace(last_z[1,0],\
            final_z[1,0], self.n_ctrlpts)).T
    x_aux = np.append(np.asarray([self.Tp]), np.squeeze(C.reshape(1,self.n_ctrlpts*self.mrob.u_dim)), axis=1)

    print(x_aux)
    self._lstep_plot_update(x_aux)

    tic = time.time()

    while True:
        if False:
            # Define the optimization problem
            self.opt_prob = pyOpt.Optimization(
                    'Faster path with obstacles', # name of the problem
                    self._lstep_obj_func) # object function (criterium, eq. and ineq.)
        
            self.opt_prob.addObj('J')
        
            self.opt_prob.addVarGroup( # minimization arguments
                    'x',
                    self.mrob.u_dim*self.n_ctrlpts+1, # dimension
                    'c', # continous
                    lower=[0.0]+list(C_lower),
                    value=[self.Tp]+list(np.squeeze(C.reshape(1,self.n_ctrlpts*self.mrob.u_dim))),
                    upper=[1e10]+list(C_upper))
        
            self.opt_prob.addConGroup( # equations constraints
                    'ec',
                    2*self.mrob.q_dim + 2*self.mrob.u_dim, # dimension
                    'e') # equations
        
            self.opt_prob.addConGroup( # inequations constraints
                    'ic',
                    self.N_s*self.mrob.u_dim +
                            self.N_s*len(self.detected_obst_idxs), # dimenstion
                    'i') # inequations
        
            # solve constrained optmization
#            solver = pyOpt.SLSQP(pll_type='POA')
#            solver.setOption('ACC', 1e-6)
#            solver.setOption('MAXIT', 30)
            solver = pyOpt.ALGENCAN(pll_type='POA')
            solver.setOption('epsfeas', 5e-1)
            solver.setOption('epsopt', 9e-1)
        
            [J, x_aux, information] = solver(self.opt_prob) 
            x_aux = np.array(x_aux)
            break

        else:
            # solve constrained optmization
            outp = fmin_slsqp(self._lstep_criteria,
                                x_aux,
                                eqcons=(),
                                f_eqcons=self._lstep_feqcons,
                                ieqcons=(),
                                f_ieqcons=self._lstep_fieqcons,
                                iprint=1,
                                iter=30,
                                acc=1e-6,
                                full_output=True,
                                callback=self._lstep_plot_update)

            x_aux = outp[0]
            imode = outp[3]
            print('\n'.format(imode))
            if imode != 0 and imode != 9:
                usepyopt = True
                continue
            break

    print('Elapsed time for {} (last) iteraction: {}'.format(self.itcount, time.time()-tic))
    print('No of equations unsatisfied: {}'.format(len(self.unsatisf_eq_values)))
    print('Mean and variance of equations unsatisfied: ({},{})'.format(np.mean(self.unsatisf_eq_values), np.std(self.unsatisf_eq_values)))
    print('No of inequations unsatisfied: {}'.format(len(self.unsatisf_ieq_values)))
    print('Mean and variance of inequations unsatisfied: ({},{})'.format(np.mean(self.unsatisf_ieq_values), np.std(self.unsatisf_ieq_values)))

    # test if opt went well
    # if yes
    dt_final = x_aux[0]
    print(x_aux)
    self.t_final = self.mtime[0] + dt_final
    C = x_aux[1:].reshape(self.n_ctrlpts, self.mrob.u_dim)
    # if no
    # continue

    print('Final time: {}'.format(self.t_final))

    # store ctrl points and [z dz ddz](t)
    self.C_ref += [C]

    self.mtime = np.linspace(self.mtime[0], self.t_final, self.N_s)

    dz = self._comb_bsp(self.mtime, C, 0).T
    for dev in range(1,self.mrob.l+1):
        dz = np.append(dz,self._comb_bsp(
                self.mtime, C, dev).T,axis=0)
    self.all_dz += [dz]
Exemple #2
0
def Opt():
    problem = {}
    # Problem Solution Info #
    order = 5 # Order should be kept relatively low <=6, if more accuracy is required, increase the number of partitions
    N = order-1
    problem['N'] = N
    problem['nConstraint'] = 10
    problem['nDivisions'] = 1 # number of segments, each fitted with its own polynomial of the specified order 
    # Problem Info #
    isp = 290
    
    problem['x0'] = -3200
    problem['xf'] = 0
    
    problem['y0'] = 2000
    problem['yf'] = 0
    
    problem['u0'] = 625
    problem['uf'] = 0
    
    problem['v0'] = -270
    problem['vf'] = 0
    
    problem['udotf'] = 0
    
    problem['m0'] =  8500
    problem['ve'] = isp*9.81
    thrust = 600000
    problem['Tmax'] = thrust
    problem['Tmin'] = thrust*0.1 # 10% throttle
    
    V0 = (problem['u0']**2 + problem['v0']**2)**0.5
    fpa0 = np.arcsin(problem['v0']/V0)
    problem['mu0'] = np.pi+fpa0
    problem['mudotmax'] = 40*np.pi/180 # 40 deg/s
    problem['mudotmin'] = -problem['mudotmax']
    
    # Initial Guess
    tf = 12
    x = np.linspace(problem['x0'],problem['xf'],order+1)
    y = np.linspace(problem['y0'],problem['yf'],order+1)
    # tau = -cos(pi*np.arange(0,N+2)/(N+1))
    # t = (tau+1)*0.5*tf
    # x = interp1d(np.linspace(0,tf,order+1),x)(t)
    # y = interp1d(np.linspace(0,tf,order+1),y)(t)
    c0 = np.hstack((x[1:-1],y[1:-1],tf))
    
    # Form D
    problem['D'] = ChebyshevDiff(order)

    opt = pyOpt.Optimization('Flat Pseudospectral PDG',lambda c: Cost(c,problem))
    
    
    # Add the design variables
    for i,xi in enumerate(x[1:-1]):
        opt.addVar('x{}'.format(i+1), 'c', lower = problem['x0'], upper = problem['xf'], value = xi)
    
    for i,xi in enumerate(y[1:-1]):
        opt.addVar('y{}'.format(i+1), 'c', lower = problem['yf'], upper = problem['y0'], value = xi)
    
    opt.addVar('tf','c', lower = 5, upper = 50, value=tf)
    
    # Add the objective and constraints
    opt.addObj('J')
    
    for i in range(1,7):
        opt.addCon('g{}'.format(i),'e')
          
          
    for i in range(1,4*problem['nConstraint'] + 0*order):
        opt.addCon('h{}'.format(i),'i')
        
    # optimizer = pyOpt.COBYLA()
    # optimizer = pyOpt.ALPSO()
    optimizer = pyOpt.ALGENCAN()
    # optimizer = pyOpt.SLSQP()
    # optimizer = pyOpt.SDPEN()
    # optimizer = pyOpt.PSQP()
    # optimizer = pyOpt.SOLVOPT()
    
    
    sens_type = 'CS' # Differencing Type, options ['FD', CS']
    # optimizer.setOption('MAXIT',100) #SLSQP option
    # optimizer.setOption('MIT',200) # PSQP
    # fopt,copt,info = optimizer(opt,sens_type=sens_type)
    fopt,copt,info = optimizer(opt)

    print info
    print opt.solution(0)

    t,x,y,u,v,udot,vdot,m,T,mu,mudot = Parse(copt,problem)


    plt.figure()
    plt.plot(x,y)
    plt.title('Positions')
    
    plt.figure()
    plt.plot(u,v)
    plt.title('Velocities')
    
    plt.figure()
    plt.plot(udot,vdot)
    plt.title('Accelerations')
    
    plt.figure()
    plt.plot(t,m)
    plt.title('Mass')
    
    plt.figure()
    plt.plot(t,mu*180/np.pi)
    plt.title('Thrust Angle')
    
    plt.figure()
    plt.plot(t,T)
    plt.title('Thrust')
    
    plt.figure()
    plt.plot(t,x)
    
    plt.figure()
    plt.plot(t,y)
    
    plt.show()    
Exemple #3
0
    def optimizePyopt(self, solver, sens, options):

        # pyOpt requires empty options to be specified as {}, not None
        if options is None: options = {}

        eqConstr = ('SLSQP' not in solver and 'CONMIN' not in solver
                    and 'COBYLA' not in solver and 'FILTERSD' not in solver
                    and 'SDPEN' not in solver)

        # Organize constraints
        indLinEq = []
        indLinIneq = []
        indNonlinEq = []
        indNonlinIneq = []
        for k, bnd in enumerate(self.linBounds):
            if bnd[0] == bnd[1] and eqConstr: indLinEq.append(k)
            else: indLinIneq.append(k)
        indLinEq = np.array(indLinEq)
        indLinIneq = np.array(indLinIneq)
        for k, bnd in enumerate(self.nonlinBounds):
            if bnd[0] == bnd[1] and eqConstr: indNonlinEq.append(k)
            else: indNonlinIneq.append(k)
        indNonlinEq = np.array(indNonlinEq)
        indNonlinIneq = np.array(indNonlinIneq)

        # pyOpt objective
        def objectivePyopt(xIn, *args, **kwargs):

            x = xIn[:self.nvar]

            f = self.objective(x)
            g = np.zeros(0, dtype=float)
            if len(indLinEq) > 0:
                g = np.r_[g, np.dot(self.linMat[indLinEq, :], x)]
            if len(indNonlinEq) > 0:
                g = np.r_[g,
                          self.evalNonlinConstraints(x, 'constr', indNonlinEq)]
            if len(indLinIneq) > 0:
                g = np.r_[g, np.dot(self.linMat[indLinIneq, :], x)]
            if len(indNonlinIneq) > 0:
                g = np.r_[
                    g,
                    self.evalNonlinConstraints(x, 'constr', indNonlinIneq)]

            fail = 0
            if f >= self.inf or np.any(g >= self.inf): fail = 1

            return f, g, fail

        # pyOpt gradient
        def gradientPyopt(xIn, f, g, *args, **kwargs):

            x = xIn[:self.nvar]

            df = self.gradient(x)
            dg = np.zeros((0, self.nvar), dtype=float)
            if len(indLinEq) > 0:
                dg = np.r_[dg, self.linMat[indLinEq, :]]
            if len(indNonlinEq) > 0:
                dg = np.r_[dg,
                           self.evalNonlinConstraints(x, 'jac', indNonlinEq)]
            if len(indLinIneq) > 0:
                dg = np.r_[dg, self.linMat[indLinIneq, :]]
            if len(indNonlinIneq) > 0:
                dg = np.r_[dg,
                           self.evalNonlinConstraints(x, 'jac', indNonlinIneq)]

            fail = 0
            if f >= self.inf or np.any(g >= self.inf): fail = 1

            return df.reshape((1, -1)), dg, fail

        # Instantiate optimization problem
        optProb = pyOpt.Optimization('pyopt', objectivePyopt)

        # Add objective
        optProb.addObj('objective')

        # Add variables
        optProb.addVarGroup('var',
                            self.nvar,
                            type='c',
                            value=self.varInit,
                            lower=self.varBounds[:, 0],
                            upper=self.varBounds[:, 1])
        # Add constraints
        if len(indLinEq) > 0:
            optProb.addConGroup('lin-equality',
                                len(indLinEq),
                                type='e',
                                equal=self.linBounds[indLinEq, 0])
        if len(indNonlinEq) > 0:
            optProb.addConGroup('nonlin-equality',
                                len(indNonlinEq),
                                type='e',
                                equal=self.nonlinBounds[indNonlinEq, 0])
        if len(indLinIneq) > 0:
            optProb.addConGroup('lin-inequality',
                                len(indLinIneq),
                                type='i',
                                lower=self.linBounds[indLinIneq, 0],
                                upper=self.linBounds[indLinIneq, 1])
        if len(indNonlinIneq) > 0:
            optProb.addConGroup('nonlin-inequality',
                                len(indNonlinIneq),
                                type='i',
                                lower=self.nonlinBounds[indNonlinIneq, 0],
                                upper=self.nonlinBounds[indNonlinIneq, 1])

        # Setup solver
        if 'SNOPT' in solver:
            optimizer = pyOpt.SNOPT(options=options)
        if 'SLSQP' in solver:
            optimizer = pyOpt.SLSQP(options=options)
        if 'CONMIN' in solver:
            optimizer = pyOpt.CONMIN(options=options)
        if 'ALGENCAN' in solver:
            optimizer = pyOpt.ALGENCAN(options=options)
        if 'ALPSO' in solver:
            optimizer = pyOpt.ALPSO(options=options)
        if 'ALHSO' in solver:
            optimizer = pyOpt.ALHSO(options=options)
        if 'COBYLA' in solver:
            optimizer = pyOpt.COBYLA(options=options)
        if 'FILTERSD' in solver:
            optimizer = pyOpt.FILTERSD(options=options)
        if 'KOPT' in solver:
            optimizer = pyOpt.KOPT(options=options)
        if 'MIDACO' in solver:
            optimizer = pyOpt.MIDACO(options=options)
        if 'KSQP' in solver:
            optimizer = pyOpt.KSQP(options=options)
        if 'SDPEN' in solver:
            optimizer = pyOpt.SDPEN(options=options)
        if 'SOLVOPT' in solver:
            optimizer = pyOpt.SOLVOPT(options=options)

        # Run optimization
        if sens == 'finite-difference':
            optimizer(optProb, sens_type='FD')
        else:
            optimizer(optProb, sens_type=gradientPyopt)

        # Extract solution
        j = len(optProb._solutions) - 1
        xStar = np.zeros(self.nvar)
        for k in range(self.nvar):
            xStar[k] = optProb._solutions[j].getVar(k).value

        return xStar, objectivePyopt(xStar)[0]