Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

How to define the expression for the terminal and running costs P and L for nonlinear MPC controller in the form of the quadratic one

How to define the expression for the terminal and running costs P and L for nonlinear MPC controller in the form of the quadratic one and based on x_model = ca.MX.sym('xm', (Dim_state, 1))
and u_model = ca.MX.sym('um', (Dim_ctrl, 1)), and based on the following requirements:

image.png
Image transcription text

Car Overtaking In this task. you will design a nonlinear MP0 on a
kinematic bicycle carmodel to overtake the leading vehicle. You
will need to complete the nmpc_controllen function to ...
Show more
image.png
Image transcription text

X Controller design: You ara supposed to design an MPC
controller of the following form to takeover the leading vehicle
with desired velocity and go back to the same lane as t...
Show more
image.png
Image transcription text

Constraints: 1 Cons1: Collision avoidance: We consider a
elliposoidal safety set for the vehicle when overtaking the car
(#)2+ (2)2 -120, We assign rx = 2 m, ry = 30 m. Cons1: ...
Show more
image.png
Image transcription text

Cons4: Input bounds The input is within the bounds: —1[)ml'52 =
"min 3 a g a".ax = 4 math:2 —fl.6rad : 5min g 6 3 5mm : 0.6rad
Submission detail Controller input The autograder will...
Show more
And the relvant codes are:

import casadi as ca
import numpy as np
import numpy.matlib
import matplotlib.pyplot as plt
import time

def nmpc_controller():
    # Declare simulation constants
    T = 4 # TODO: You are supposed to design the planning horizon
    N = 40 # TODO  You are supposed to design the planning horizon
    h = 0.1 # TODO: What is the time interval for simulation?

    # system dimensions
    Dim_state = 4 # TODO
    Dim_ctrl  = 2 # TODO

    # additional parameters
    x_init = ca.MX.sym('x_init', (Dim_state, 1)) # initial condition, # the state should be position to the leader car
    v_leader = ca.MX.sym('v_leader',(2, 1))      # leader car's velocity w.r.t ego car
    v_des = ca.MX.sym('v_des')
    delta_last = ca.MX.sym('delta_last')
    par = ca.vertcat(x_init, v_leader, v_des, delta_last)
   
    # Continuous dynamics model
    x_model = ca.MX.sym('xm', (Dim_state, 1))
    u_model = ca.MX.sym('um', (Dim_ctrl, 1))

    L_f = 1.0 # Car parameters, do not change
    L_r = 1.0 # Car parameters, do not change

    beta = ca.atan(L_r / (L_r + L_f) * ca.atan(u_model[1])) # TODO

    xdot = ca.vertcat(x_model[3] * ca.cos(x_model[2] + beta) - v_leader[0],
                      x_model[3] * ca.sin(x_model[2] + beta) - v_leader[1],
                      x_model[3] / L_r * ca.sin(beta),
                      u_model[0]) # TODO
 
    # Discrete time dynmamics model
    Fun_dynmaics_dt = ca.Function('f_dt', [x_model, u_model, par], [xdot * h + x_model]) # TODO
   
    # Declare model variables, note the dimension
    x = ca.MX.sym('x', (Dim_state, N+1)) # TODO
    u = ca.MX.sym('u', (Dim_ctrl, N)) # TODO

    # Keep in the same lane and take over it while maintaing a high speed, cost function
    P = x[2,N]**2 + x[3,N]**2 + x[4,N]**2 + x[0,N]**2 # TODO
    L = sum([x[2,i]**2 + x[3,i]**2 + x[4,i]**2 + x[0,i]**2 + u[:,i]**2  for i in range(N)]) # TODO

    Fun_cost_terminal = ca.Function('P', [x_model, par], [P])
    Fun_cost_running = ca.Function('Q', [x_model, u_model, par], [L])

    # state and control constraints
    state_ub = ca.DM([2, 3, np.inf, 4]) # TODO
    state_lb = ca.DM([-2, -1, -np.inf, 0]) # TODO
    ctrl_ub  = np.array([4, 0.6]) # TODO
    ctrl_lb  = np.array([-10, -0.6]) # TODO
   
    # upper bound and lower bound
    ub_x = np.matlib.repmat(state_ub, N + 1, 1)
    lb_x = np.matlib.repmat(state_lb, N + 1, 1)

    ub_u = np.matlib.repmat(ctrl_ub, N, 1)
    lb_u = np.matlib.repmat(ctrl_lb, N, 1)

    ub_var = np.concatenate((ub_u.reshape((Dim_ctrl * N, 1)), ub_x.reshape((Dim_state * (N+1), 1))))
    lb_var = np.concatenate((lb_u.reshape((Dim_ctrl * N, 1)), lb_x.reshape((Dim_state * (N+1), 1))))

    # dynamics constraints: x[k+1] = x[k] + f(x[k], u[k]) * dt
    cons_dynamics = []
    ub_dynamics = np.zeros((Dim_state * N, 1))
    lb_dynamics = np.zeros((Dim_state * N, 1))
    for k in range(N):
        Fx = Fun_dynmaics_dt(x[:, k], u[:, k], par)
        cons_dynamics.append(x[:, k+1] - Fx)
        ub_dynamics = np.concatenate((ub_dynamics, np.zeros((Dim_state,1))))
        lb_dynamics = np.concatenate((lb_dynamics, np.zeros((Dim_state,1)))) # TODO


    # state constraints: G(x) <= 0
    cons_state = []
    for k in range(N):
        #### collision avoidance:
        # TODO
        r_x = 30
        r_y = 2
        cons_state.append((x[0, k] / r_x)**2 + (x[1, k] / r_y)**2 - 1)

        #### Maximum lateral acceleration ####
        dx = (x[:, k+1] - x[:, k]) / h
        ay = x[3, k] * (x[2, k+1]-x[2, k]) / h # TODO: Compute the lateral acc using the hints
       
        gmu = (0.5 * 0.6 * 9.81) # TODO
        cons_state.append(ay - gmu) # TODO
        cons_state.append(-ay - gmu) # TODO


        #### lane keeping ####
        cons_state.append(x[1, k] - 3)
        cons_state.append(-x[1, k] + 1)

        #### steering rate ####
        if k >= 1:
            d_delta = (u[1, k] - u[1, k-1]) / h
            cons_state.append(d_delta - 0.6) # TODO
            cons_state.append(-d_delta - 0.6) # TODO
        else:
            d_delta = (u[1, k] - delta_last) / h # TODO, for the first input, given d_last from param
            cons_state.append(d_delta - 0.6) # TODO
            cons_state.append(-d_delta - 0.6) # TODO
 
    ub_state_cons = np.zeros((len(cons_state), 1))
    lb_state_cons = np.zeros((len(cons_state), 1)) - 1e5

    # cost function: # NOTE: You can also hard code everything here
    J = Fun_cost_terminal(x[:, -1], par)
    for k in range(N):
        J = J + Fun_cost_running(x[:, k], u[:, k], par)

    # initial condition as parameters
    cons_init = [x[:, 0] - x_init]
    ub_init_cons = np.zeros((Dim_state, 1))
    lb_init_cons = np.zeros((Dim_state, 1))
   
    # Define variables for NLP solver
    vars_NLP   = ca.vertcat(u.reshape((Dim_ctrl * N, 1)), x.reshape((Dim_state * (N+1), 1)))
    cons_NLP = cons_dynamics + cons_state + cons_init
    cons_NLP = ca.vertcat(*cons_NLP)
    lb_cons = np.concatenate((lb_dynamics, lb_state_cons, lb_init_cons))
    ub_cons = np.concatenate((ub_dynamics, ub_state_cons, ub_init_cons))
   
    # Define an NLP solver
    prob = {"x": vars_NLP, "p":par, "f": J, "g":cons_NLP}
    return prob, N, vars_NLP.shape[0], cons_NLP.shape[0], par.shape[0], lb_var, ub_var, lb_cons, ub_cons
Reference codes are:

import casadi as ca
import numpy as np
import numpy.matlib
import matplotlib.pyplot as plt
import time
#from nmpc_takeover_gsi import *
from nmpc_takeover_student import

def eval_controller(par_init: np.ndarray):
    '''
    par_init: [x, y, yaw, v, v_x_leader, v_y_leader, v_x_desired]
        x: x distance between our car and leader car
        y: y distance between our car and leader car
        yaw: yaw angle of our car
        v: velocity of our car
        v_x_leader: x velocity of leader car
        v_y_leader: y velocity of leader car
        v_x_desired: desired takeover x velocity of our car
    '''
   
    # We define the default evaluation rate and other constants here
    h = 0.1
    N_sim = int(np.ceil(17/ h))
    Dim_state = 4
    Dim_ctrl  = 2
   
    # define some parameters
    x_init = ca.MX.sym('x_init', (Dim_state, 1)) # initial condition, the state should be position to the leader car
    v_leader = ca.MX.sym('v_leader',(2, 1))      # leader car's velocity
    v_des = ca.MX.sym('v_des')                   # desired speed of ego car
    delta_last = ca.MX.sym('delta_last')         # steering angle at last step
    par = ca.vertcat(x_init, v_leader, v_des, delta_last) # concatenate them
   
    # Continuous dynamics model
    x_model = ca.MX.sym('xm', (Dim_state, 1))
    u_model = ca.MX.sym('um', (Dim_ctrl, 1))
   
    L_f = 1.0
    L_r = 1.0

    beta = ca.atan(L_r / (L_r + L_f) * ca.atan(u_model[1]))

    xdot = ca.vertcat(x_model[3] * ca.cos(x_model[2] + beta) - v_leader[0],
                      x_model[3] * ca.sin(x_model[2] + beta) - v_leader[1],
                      x_model[3] / L_r * ca.sin(beta),
                      u_model[0])

    # Discretized dynamics model
    Fun_dynmaics_dt = ca.Function('f_dt', [x_model, u_model, par], [xdot * h + x_model])
   
    # student controller are constructed here:
    prob, N_mpc, n_x, n_g, n_p, lb_var, ub_var, lb_cons, ub_cons = nmpc_controller()
    # students are expected to provide
    # NLP problem, the problem size (n_x, n_g, n_p), horizon and bounds
   
    opts = {'ipopt.print_level': 3, 'print_time': 0} # , 'ipopt.sb': 'yes'}
    solver = ca.nlpsol('solver', 'ipopt', prob , opts)
   
    # our initial conditions, see if we want to change it ...
    state_0 = par_init[:4] #np.array([-80, 0.0, 0.15, 30.])
    d_last = 0
    # our initial conditions, see if we want to change it ...
   
    # logger of states
    xt = np.zeros((N_sim+1, Dim_state))
    ut = np.zeros((N_sim, Dim_ctrl))
   
    # place holder for warm start
    x0_nlp    = np.random.randn(n_x, 1) * 0.01 # np.zeros((n_x, 1))
    lamx0_nlp = np.random.randn(n_x, 1) * 0.01 # np.zeros((n_x, 1))
    lamg0_nlp = np.random.randn(n_g, 1) * 0.01 # np.zeros((n_g, 1))

    xt[0, :] = state_0
   
    # main loop of simulation
    for k in range(N_sim):
        state_0 = xt[k, :]
       
        # the leader car's velocity and desired velocity will not change in the planning horizon
        par_nlp = np.concatenate((state_0, par_init[4:], np.array([d_last]))) # state_0 + [v_x_leader, v_y_leader, v_x_desired, d_last]

        sol = solver(x0=x0_nlp, lam_x0=lamx0_nlp, lam_g0=lamg0_nlp,
                     lbx=lb_var, ubx=ub_var, lbg=lb_cons, ubg=ub_cons, p = par_nlp)
       
        x0_nlp = sol["x"].full()
        lamx0_nlp = sol["lam_x"].full()
        lamg0_nlp = sol["lam_g"].full()
               
        ut[k, :] = np.squeeze(sol['x'].full()[0:Dim_ctrl])
        d_last = ut[k, 1]
       
        ut[k, 0] = np.clip(ut[k, 0], -10, 4)
        ut[k, 1] = np.clip(ut[k, 1], -0.6, 0.6)
       
        xkp1 = Fun_dynmaics_dt(xt[k, :], ut[k, :], par_nlp)

        xt[k+1, :] = np.squeeze(xkp1.full())

   
    return xt, ut
   
     # Initial test case
x_init = np.array([-49., # x: x distance between our car and leader car
                0.0, # y: y distance between our car and leader car
                0.0, # yaw: yaw angle of our car
                50., # v: velocity of our car
                20., # v_x_leader: x velocity of leader car
                0.0, # v_y_leader: y velocity of leader car, fixed as 0.
                50.0 # v_x_desired: desired takeover x velocity of our car
                ])      
xt, ut = eval_controller(x_init)
Which the expression may similar as something like: J = 100 * ((x[0, -1] - 10)**2 + (x[1, -1] - 10)**2)  + 100 * x[2, -1]**2 + 100 * x[3, -1]**2 as an example

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Income Tax Fundamentals 2013

Authors: Gerald E. Whittenburg, Martha Altus Buller, Steven L Gill

31st Edition

1111972516, 978-1285586618, 1285586611, 978-1285613109, 978-1111972516

More Books

Students also viewed these Programming questions