Hello,
I have also been trying out MPC for an obstacle avoidance maneuver using a Two track Vehicle Dynamics model. The problem is that I am used to forming the characteristic equations as an ODE and I tried out the same using Euler discrete method. Unfortunately I cannot get any optimised control sequence, which in this case is steering input. Have a look at my code though....% Obstacle Avoidance - Optimized Steering Sequence Using MPC
clear all; close all;
global Fy1_curr Fy2_curr Fy3_curr Fy4_curr
%% Parameters definition
% model parameters
params.l_f = 1; % distance between center of gravity and front axle
params.l_b = 1; % distance between center of gravity and rear axle
params.mass = 1435; % Vehicle Mass
params.Cf = 100000; % Front Cornering Stiffness
params.Cr = 100000; % Rear Cornering Stiffness
params.Jz = 2380; % Vehicle Moment of Inertia
params.vehicle_width = 2; % vehicle width
params.Ts = 0.1; % sampling time (both of MPC and simulated vehicle)
params.nstates = 10; % number of states
params.ninputs = 1; % number of inputs
% environment parameters
params.track_end = 20; % end of the track
params.activate_obstacles = 1; % 0 if there are no obstacle, 1 otherwise
params.obstacle_centers = [11 0]; % x and y coordinate of the 4 obstacles
params.obstacle_size = [2 1]; % size of the obstacles
params.lane_semiwidth = 4; % semi-width of the lane
% control parameters
params.controller = 'MPC'; % 'SF' for state-feedback controller, 'MPC' for MPC controller
objective = 0;
% simulation parameters
params.x0 = 0; % initial x coordinate
params.y0 = 1; % initial y coordinate
params.vx = 14; % initial longitudinal speed
params.vy0 = 0; % initial lateral speed
params.psi0 = 0; % initial heading angle
params.psidot0 = 0; % initial heading angle rate
params.N_max = 1000; % maximum number of simulation steps
% plotting parameters
params.window_size = 10; % plot window size for the during simulation, centered at the current position (x,y) of the vehicle
params.plot_full = 0; % 0 for plotting only the window size, 1 for plotting from 0 to track_end
%% Simulation environment
% initialization
z = zeros(params.N_max,params.nstates); % z(k,j) denotes state j at step k-1
u = zeros(params.N_max,params.ninputs); % u(k,j) denotes input j at step k-1
z(1,:) = [params.x0,params.vx,params.y0,0.1,0,0,params.x0,0,params.y0,0]; % definition of the intial state
% u(1,:) = [0.01];
comp_times = zeros(params.N_max); % total computation time each sample
solve_times = zeros(params.N_max); % optimization solver time each sample
N = 3;
i = 0;
objective = 0;
u_predicted = [];
z_predicted = [];
% ref = [50 0 10 0];
Q = eye(10);
R = eye(2);
while (z(i+1,1)<params.track_end) && (i<params.N_max)
i = i+1;
switch params.controller
case 'SF' % state-feedbaack controller definition
K = [0 0 0 0 ];
u(i,:) = K * z(i,:)';
pause(0.1);
case 'MPC' % MPC controller definition
yalmip('clear')
constraints = [];
u_var = sdpvar(N,1);
% u_var(1,:) = u(i,:)
z_var = sdpvar(N,10);
z_var(1,:) = z(i,:);
for k = 1:N-1
Fy1 = -params.Cf * (atan( (z_var(k,4) + params.l_f * z_var(k,5))/(params.vx -
params.tw * z_var(k,5)) ) - u_var(k,1)); %Fy1
Fy2 = -params.Cf * (atan( (z_var(k,4) + params.l_f * z_var(k,5))/(params.vx +
params.tw * z_var(k,5)) ) - u_var(k,1)); %Fy2
Fy3 = -params.Cr * atan( (z_var(k,4) - params.l_b * z_var(k,5))/(params.vx -
params.tw * z_var(k,5)) ); %Fy3
Fy4 = -params.Cr * atan( (z_var(k,4) - params.l_b * z_var(k,5))/(params.vx +
params.tw * z_var(k,5))); %Fy4
if isnan(value(Fy1)) == 1
Fy1 = 0;
end
if isnan(value(Fy2)) == 1
Fy2 = 0;
end
if isnan(value(Fy2)) == 1
Fy3 = 0;
end
if isnan(value(Fy2)) == 1
Fy4 = 0;
end
z_var(k+1,1) = z_var(k,1) + params.Ts * z_var(k,2); %x
z_var(k+1,2) = z_var(k,2) + params.Ts * (1/params.mass * ( -( value(Fy1) + value(Fy2) )*sin(u_var(k,1)) ) + z_var(k,5)*z_var(k,4)); %Vx
z_var(k+1,3) = z_var(k,3) + params.Ts * z_var(k,4); %y
z_var(k+1,4) = z_var(k,4) + params.Ts * (1/params.mass * ( ( value(Fy1) + value(Fy2) )* cos(u_var(k,1)) + value(Fy3) + value(Fy4) ) - z_var(k,5)*z_var(k,2)); %V_y
z_var(k+1,5) = z_var(k,5) + params.Ts * z_var(k,6); %psi_dot
z_var(k+1,6) = z_var(k,6) + params.Ts * (1/params.Jz * ( ( value(Fy1) - value(Fy2) )* sin(u_var(k,1))*
params.tw + ( value(Fy1) + value(Fy2) )* cos(u_var(k,1))*params.l_f - ( value(Fy3) + value(Fy4) )*params.l_b ) ); %psi_double_dot
z_var(k+1,7) = z_var(k,7) + params.Ts * z_var(k,8); %Global_X
z_var(k+1,8) = z_var(k,8) + params.Ts *( z_var(2) - z_var(k,5)*z_var(k,9)); %Global_Vx
z_var(k+1,9) = z_var(k,9) + params.Ts * z_var(k,10); %Global_Y
z_var(k+1,10) = z_var(k,10) + params.Ts *( z_var(4) + z_var(k,5)*z_var(k,7)); %Global_Vy
objective = objective + (z_var(k,3)) * 10 *(z_var(k,3))' ;
constraints = [constraints, -10 <= u_var(k,1) <= 10]
constraints = [constraints, -params.lane_semiwidth <= z_var(k,2) <= params.lane_semiwidth]
% constraints = [constraints, (z_var(k,1) - 11)^2/2 + (z_var(k,2))^2/0.5 >= 1]
end
tic()
options = sdpsettings('solver', 'fmincon', 'usex0', 1);
diagnostic = optimize(constraints, objective, options);
comp_times(i) = toc();
solve_times(i) = diagnostic.solvertime;
u(i,:) = u_var(1,1);
for j = 1:N
z_predicted(j,:) = z_var(j,:);
end
for h = 1:N-1
u_predicted(h,:) = u_var(h,:);
end
end
% simulate the vehicle
z(i+1,:) = car_sim_test(z(i,:), u(i,:), params);