Initial commit
|
@ -0,0 +1,163 @@
|
|||
# MATLAB
|
||||
# Windows default autosave extension
|
||||
*.asv
|
||||
|
||||
# OSX / *nix default autosave extension
|
||||
*.m~
|
||||
|
||||
# Compiled MEX binaries (all platforms)
|
||||
*.mex*
|
||||
|
||||
# Packaged app and toolbox files
|
||||
*.mlappinstall
|
||||
*.mltbx
|
||||
|
||||
# Generated helpsearch folders
|
||||
helpsearch*/
|
||||
|
||||
# Simulink code generation folders
|
||||
slprj/
|
||||
sccprj/
|
||||
|
||||
# Matlab code generation folders
|
||||
codegen/
|
||||
|
||||
# Simulink autosave extension
|
||||
*.autosave
|
||||
|
||||
# Simulink cache files
|
||||
*.slxc
|
||||
|
||||
# Octave session info
|
||||
octave-workspace
|
||||
|
||||
# PYTHON
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 Jun Zeng
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,48 @@
|
|||
# MPC-CBF
|
||||
Model Predictive Control with Control Barrier Functions
|
||||
|
||||
![](car-racing/demo.gif)
|
||||
|
||||
# Prerequisites
|
||||
## Matlab
|
||||
The packages needed for running the code are [Yalmip](https://yalmip.github.io/) and [IPOPT](https://projects.coin-or.org/Ipopt/wiki/MatlabInterface).
|
||||
|
||||
We also provide the zipped version of precompiled .mex files for IPOPT in the folder `packages` in case you don't have it. Unzip that file and add those .mex files into your MATLAB path.
|
||||
|
||||
# Description
|
||||
## 2D double integrator
|
||||
The 2D double integrator is assigned to reach the target position at origin while avoiding obstacles. We have three classes for different controllers: `DCLF_DCBF.m` (DCLF-DCBF), `MPC_CBF.m` (MPC-CBF) and `MPC_DC` (MPC-DC), respectively.
|
||||
|
||||
Moreover, to illustrate the performance among them, we have:
|
||||
* `main.m`: Run DCLF-DCBF/MPC-CBF/MPC-DC respectively.
|
||||
* `analysis_gamma.m`: Run analysis for different hyperparameter $\gamma$.
|
||||
* `analysis_horizon.m`: Run analysis for different horizon.
|
||||
|
||||
We illustrate the performance between DCLF-DCBF/MPC-DC/MPC-CBF
|
||||
| DCLF-DCBF | MPC-DC (N=8) |
|
||||
| --- | --- |
|
||||
| <img src="double-integrator-2D/figures/dclf-dcbf-avoidance.png" width="200" height="200"> | <img src="double-integrator-2D/figures/mpc-dc-avoidance.png" width="200" height="200"> |
|
||||
|
||||
| MPC-CBF (N=1) | MPC-CBF (N=8) |
|
||||
| --- | --- |
|
||||
| <img src="double-integrator-2D/figures/mpc-cbf-avoidance-one-step.png" width="200" height="200"> | <img src="double-integrator-2D/figures/mpc-cbf-avoidance-several-steps.png" width="200" height="200"> |
|
||||
|
||||
and also the safety performance for different numbers of horizon and hyperparameters
|
||||
| Different hyperparameter | Different horizon |
|
||||
| --- | --- |
|
||||
| <img src="double-integrator-2D/figures/benchmark-gamma.png" width="200" height="200"> | <img src="double-integrator-2D/figures/benchmark-horizon.png" width="200" height="200"> |
|
||||
|
||||
## Car racing competition
|
||||
We have the speed profile and control input shown as follow,
|
||||
|
||||
<img src="car-racing/lmpc-speed-norm-profile.png" width="400">
|
||||
|
||||
<img src="car-racing/lmpc-deviation-profile.png" width="400">
|
||||
|
||||
<img src="car-racing/lmpc-input-profile.png" width="400">
|
||||
|
||||
The animation can be found on the top of this readme, we will release full code after the paper is accepted.
|
||||
|
||||
# References
|
||||
This repository is based on the following:
|
||||
* Jun Zeng, Bike Zhang and Koushil Sreenath. "Safety-Critical Model Predictive Control with Discrete-Time Control Barrier Function." [[PDF]](http://arxiv.org/abs/2007.11718)
|
After Width: | Height: | Size: 212 KiB |
After Width: | Height: | Size: 795 KiB |
After Width: | Height: | Size: 1.3 MiB |
After Width: | Height: | Size: 418 KiB |
After Width: | Height: | Size: 1.2 MiB |
|
@ -0,0 +1,105 @@
|
|||
classdef DCLF_DCBF < handle
|
||||
properties
|
||||
system
|
||||
params
|
||||
x0
|
||||
x_curr
|
||||
time_curr = 0.0
|
||||
xlog = []
|
||||
ulog = []
|
||||
u_cost = 0
|
||||
obs
|
||||
end
|
||||
|
||||
methods
|
||||
function self = DCLF_DCBF(x0, system, params)
|
||||
% Define DCLF-DCBF controller
|
||||
self.x0 = x0;
|
||||
self.x_curr = x0;
|
||||
self.system = system;
|
||||
self.params = params;
|
||||
end
|
||||
|
||||
function sim(self, time)
|
||||
% Simulate the system until a given time
|
||||
xk = self.x_curr;
|
||||
while self.time_curr <= time
|
||||
% Solve DCLF-DCBF
|
||||
uk = self.solve_dclf_dcbf();
|
||||
xk = self.system.A * xk + self.system.B * uk;
|
||||
% update system
|
||||
self.x_curr = xk;
|
||||
self.time_curr = self.time_curr + self.system.dt;
|
||||
self.xlog = [self.xlog, xk];
|
||||
self.ulog = [self.ulog, uk];
|
||||
self.u_cost = self.u_cost + uk'*uk*self.system.dt;
|
||||
end
|
||||
end
|
||||
|
||||
function uopt = solve_dclf_dcbf(self)
|
||||
% Solve DCLF-DCBF
|
||||
x = self.x_curr;
|
||||
u = sdpvar(2,1);
|
||||
delta = sdpvar(1,1);
|
||||
constraints = [];
|
||||
% add DCLF constraints
|
||||
x_next = self.system.A * x + self.system.B * u;
|
||||
v = x' * self.params.P * x;
|
||||
v_next = x_next' * self.params.P * x_next;
|
||||
constraints = [constraints; v_next - v + self.params.alpha * v <= delta];
|
||||
% add DCBF constraints
|
||||
pos = self.obs.pos;
|
||||
r = self.obs.r;
|
||||
b = (x(1:2)-pos)'*(x(1:2)-pos) - r^2;
|
||||
b_next = (x_next(1:2)-pos)'*(x_next(1:2)-pos) - r^2;
|
||||
constraints = [constraints; b_next - b + self.params.gamma*b >= 0];
|
||||
% input constraints
|
||||
constraints = [constraints; self.system.ul <= u <= self.system.uu];
|
||||
% cost
|
||||
cost = u'*self.params.H*u + delta'*self.params.p*delta;
|
||||
% solve optimization
|
||||
ops = sdpsettings('solver','ipopt','verbose',0);
|
||||
diagnostics = optimize(constraints, cost, ops);
|
||||
if diagnostics.problem == 0
|
||||
feas = true;
|
||||
uopt = value(u);
|
||||
else
|
||||
feas = false;
|
||||
uopt = [];
|
||||
end
|
||||
fprintf('solver time: %f\n', diagnostics.solvertime);
|
||||
end
|
||||
|
||||
function plot(self,figure_name)
|
||||
% Plot simulation
|
||||
figure('Renderer', 'painters', 'Position', [0 0 400 400]);
|
||||
set(gca,'LooseInset',get(gca,'TightInset'));
|
||||
hold on;
|
||||
% plot trajectory
|
||||
plot(self.xlog(1,:), self.xlog(2,:), 'ko-',...
|
||||
'LineWidth', 1.0,'MarkerSize',4);
|
||||
% plot obstacle
|
||||
pos = self.obs.pos;
|
||||
r = self.obs.r;
|
||||
th = linspace(0,2*pi*100);
|
||||
x = cos(th) ; y = sin(th) ;
|
||||
plot(pos(1) + r*x, pos(2) + r*y, 'Color', [0.8500, 0.3250, 0.0980], 'LineWidth', 2);
|
||||
plot(pos(1), pos(2), 'Color', [0.8500, 0.3250, 0.0980], 'MarkerSize', 5, 'LineWidth', 2);
|
||||
% plot target position
|
||||
plot(self.x0(1), self.x0(2), 'db', 'LineWidth', 1);
|
||||
plot(0.0, 0.0, 'dr', 'LineWidth', 1);
|
||||
h=get(gca,'Children');
|
||||
h_legend = legend(h([end]), {'DCLF-DCBF'}, 'Location', 'SouthEast');
|
||||
set(h_legend, 'Interpreter','latex');
|
||||
set(gca,'LineWidth', 0.2, 'FontSize', 15);
|
||||
grid on
|
||||
xlabel('$x (m)$','interpreter','latex','FontSize',20);
|
||||
ylabel('$y (m)$','interpreter','latex','FontSize',20);
|
||||
xticks(-5:0);
|
||||
yticks(-5:0);
|
||||
xlim([-5,0.2]);
|
||||
ylim([-5,0.2]);
|
||||
print(gcf,strcat('figures/',figure_name), '-depsc');
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,145 @@
|
|||
classdef MPC_CBF < handle
|
||||
% MPC with distance constraints
|
||||
properties
|
||||
system
|
||||
params
|
||||
x0
|
||||
x_curr
|
||||
time_curr = 0.0
|
||||
xlog = []
|
||||
ulog = []
|
||||
distlog = []
|
||||
solvertime = []
|
||||
xopenloop = {}
|
||||
uopenloop = {}
|
||||
u_cost = 0
|
||||
obs
|
||||
end
|
||||
methods
|
||||
function self = MPC_CBF(x0, system, params)
|
||||
% Define MPC_CBF controller
|
||||
self.x0 = x0;
|
||||
self.x_curr = x0;
|
||||
self.system = system;
|
||||
self.params = params;
|
||||
end
|
||||
|
||||
function sim(self, time)
|
||||
% Simulate the system until a given time
|
||||
xk = self.x_curr;
|
||||
while self.time_curr <= time
|
||||
% Solve CFTOC
|
||||
[~, uk] = self.solve_mpc_dc(self.x_curr);
|
||||
xk = self.system.A * xk + self.system.B * uk;
|
||||
% update system
|
||||
self.x_curr = xk;
|
||||
self.time_curr = self.time_curr + self.system.dt;
|
||||
self.xlog = [self.xlog, xk];
|
||||
self.ulog = [self.ulog, uk];
|
||||
self.u_cost = self.u_cost + uk'*uk*self.system.dt;
|
||||
end
|
||||
end
|
||||
|
||||
function [xopt, uopt] = solve_mpc_dc(self, xk)
|
||||
% Solve MPC-CBF
|
||||
[feas, x, u, J] = self.solve_cftoc(xk);
|
||||
if ~feas
|
||||
xopt = [];
|
||||
uopt = [];
|
||||
return
|
||||
else
|
||||
xopt = x(:,2);
|
||||
uopt = u(:,1);
|
||||
end
|
||||
end
|
||||
|
||||
function [feas, xopt, uopt, Jopt] = solve_cftoc(self, xk)
|
||||
% Solve CFTOC
|
||||
% extract variables
|
||||
N = self.params.N;
|
||||
% define variables and cost
|
||||
x = sdpvar(4, N+1);
|
||||
u = sdpvar(2, N);
|
||||
constraints = [];
|
||||
cost = 0;
|
||||
% initial constraint
|
||||
constraints = [constraints; x(:,1) == xk];
|
||||
% add constraints and costs
|
||||
for i = 1:N
|
||||
constraints = [constraints;
|
||||
self.system.xl <= x(:,i) <= self.system.xu;
|
||||
self.system.ul <= u(:,i) <= self.system.uu
|
||||
x(:,i+1) == self.system.A * x(:,i) + self.system.B * u(:,i)];
|
||||
cost = cost + x(:,i)'*self.params.Q*x(:,i) + u(:,i)'*self.params.R*u(:,i);
|
||||
end
|
||||
% add CBF constraints
|
||||
for i = 1:N
|
||||
pos = self.obs.pos;
|
||||
r = self.obs.r ;
|
||||
b = (x([1:2],i)-pos)'*((x([1:2],i)-pos)) - r^2;
|
||||
b_next = (x([1:2],i+1)-pos)'*((x([1:2],i+1)-pos)) - r^2;
|
||||
constraints = [constraints; b_next - b + self.params.gamma * b >= 0];
|
||||
end
|
||||
% add terminal cost
|
||||
cost = cost + x(:,N+1)'*self.params.P*x(:,N+1);
|
||||
ops = sdpsettings('solver','ipopt','verbose',0);
|
||||
% solve optimization
|
||||
diagnostics = optimize(constraints, cost, ops);
|
||||
if diagnostics.problem == 0
|
||||
feas = true;
|
||||
xopt = value(x);
|
||||
uopt = value(u);
|
||||
Jopt = value(cost);
|
||||
else
|
||||
feas = false;
|
||||
xopt = [];
|
||||
uopt = [];
|
||||
Jopt = [];
|
||||
end
|
||||
self.distlog = [self.distlog, sqrt((xk(1:2)-pos)'*(xk(1:2)-pos)-r^2)];
|
||||
self.xopenloop{size(self.xopenloop,2)+1} = xopt;
|
||||
self.uopenloop{size(self.uopenloop,2)+1} = uopt;
|
||||
self.solvertime = [self.solvertime, diagnostics.solvertime];
|
||||
fprintf('solver time: %f\n', diagnostics.solvertime);
|
||||
end
|
||||
|
||||
function plot(self, figure_name)
|
||||
% Plot simulation
|
||||
figure('Renderer', 'painters', 'Position', [0 0 400 400]);
|
||||
set(gca,'LooseInset',get(gca,'TightInset'));
|
||||
hold on;
|
||||
% plot closed-loop trajectory
|
||||
plot(self.xlog(1,:), self.xlog(2,:), 'ko-',...
|
||||
'LineWidth', 1.0, 'MarkerSize', 4);
|
||||
% plot open-loop trajectory
|
||||
for i = 1:size(self.xopenloop, 2)
|
||||
plot(self.xopenloop{i}(1,:), self.xopenloop{i}(2,:),...
|
||||
'k*-.', 'LineWidth', 0.5,'MarkerSize',0.5)
|
||||
end
|
||||
% plot obstacle
|
||||
pos = self.obs.pos;
|
||||
r = self.obs.r;
|
||||
th = linspace(0,2*pi*100);
|
||||
x = cos(th) ; y = sin(th) ;
|
||||
plot(pos(1) + r*x, pos(2) + r*y, 'Color', [0.8500, 0.3250, 0.0980],...
|
||||
'LineWidth', 2);
|
||||
plot(pos(1), pos(2), 'Color', [0.8500, 0.3250, 0.0980],...
|
||||
'MarkerSize', 5, 'LineWidth', 2);
|
||||
% plot target position
|
||||
plot(self.x0(1), self.x0(2), 'db', 'LineWidth', 1);
|
||||
plot(0.0, 0.0, 'dr', 'LineWidth', 1);
|
||||
h=get(gca,'Children');
|
||||
h_legend = legend(h([end]), {'MPC-CBF'}, 'Location', 'SouthEast');
|
||||
set(h_legend, 'Interpreter','latex');
|
||||
set(gca,'LineWidth', 0.2, 'FontSize', 15);
|
||||
grid on
|
||||
xlabel('$x (m)$','interpreter','latex','FontSize',20);
|
||||
ylabel('$y (m)$','interpreter','latex','FontSize',20);
|
||||
xticks(-5:0);
|
||||
yticks(-5:0);
|
||||
xlim([-5,0.2]);
|
||||
ylim([-5,0.2]);
|
||||
print(gcf,strcat('figures/',figure_name), '-depsc');
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,144 @@
|
|||
classdef MPC_DC < handle
|
||||
% MPC with distance constraints
|
||||
properties
|
||||
system
|
||||
params
|
||||
x0
|
||||
x_curr
|
||||
time_curr = 0.0
|
||||
xlog = []
|
||||
ulog = []
|
||||
distlog = []
|
||||
solvertime = []
|
||||
xopenloop = {}
|
||||
uopenloop = {}
|
||||
u_cost = 0
|
||||
obs
|
||||
end
|
||||
methods
|
||||
function self = MPC_DC(x0, system, params)
|
||||
% Define MPC_DC controller
|
||||
self.x0 = x0;
|
||||
self.x_curr = x0;
|
||||
self.system = system;
|
||||
self.params = params;
|
||||
end
|
||||
|
||||
function sim(self, time)
|
||||
% Simulate the system until a given time
|
||||
xk = self.x_curr;
|
||||
while self.time_curr <= time
|
||||
% Solve CFTOC
|
||||
[~, uk] = self.solve_mpc_dc(self.x_curr);
|
||||
xk = self.system.A * xk + self.system.B * uk;
|
||||
% update system
|
||||
self.x_curr = xk;
|
||||
self.time_curr = self.time_curr + self.system.dt;
|
||||
self.xlog = [self.xlog, xk];
|
||||
self.ulog = [self.ulog, uk];
|
||||
self.u_cost = self.u_cost + uk'*uk*self.system.dt;
|
||||
end
|
||||
end
|
||||
|
||||
function [xopt, uopt] = solve_mpc_dc(self, xk)
|
||||
% Solve MPC-DC
|
||||
[feas, x, u, J] = self.solve_cftoc(xk);
|
||||
if ~feas
|
||||
xopt = [];
|
||||
uopt = [];
|
||||
return
|
||||
else
|
||||
xopt = x(:,2);
|
||||
uopt = u(:,1);
|
||||
end
|
||||
end
|
||||
|
||||
function [feas, xopt, uopt, Jopt] = solve_cftoc(self, xk)
|
||||
% Solve CFTOC
|
||||
% extract variables
|
||||
N = self.params.N;
|
||||
% define variables and cost
|
||||
x = sdpvar(4, N+1);
|
||||
u = sdpvar(2, N);
|
||||
constraints = [];
|
||||
cost = 0;
|
||||
% initial constraint
|
||||
constraints = [constraints; x(:,1) == xk];
|
||||
% add constraints and costs
|
||||
for i = 1:N
|
||||
constraints = [constraints;
|
||||
self.system.xl <= x(:,i) <= self.system.xu;
|
||||
self.system.ul <= u(:,i) <= self.system.uu
|
||||
x(:,i+1) == self.system.A * x(:,i) + self.system.B * u(:,i)];
|
||||
cost = cost + x(:,i)'*self.params.Q*x(:,i) + u(:,i)'*self.params.R*u(:,i);
|
||||
end
|
||||
% add CBF constraints
|
||||
for i = 1:N
|
||||
pos = self.obs.pos;
|
||||
r = self.obs.r ;
|
||||
b = (x([1:2],i)-pos)'*((x([1:2],i)-pos)) - r^2;
|
||||
constraints = [constraints; b >= 0];
|
||||
end
|
||||
% add terminal cost
|
||||
cost = cost + x(:,N+1)'*self.params.P*x(:,N+1);
|
||||
ops = sdpsettings('solver','ipopt','verbose',0);
|
||||
% solve optimization
|
||||
diagnostics = optimize(constraints, cost, ops);
|
||||
if diagnostics.problem == 0
|
||||
feas = true;
|
||||
xopt = value(x);
|
||||
uopt = value(u);
|
||||
Jopt = value(cost);
|
||||
else
|
||||
feas = false;
|
||||
xopt = [];
|
||||
uopt = [];
|
||||
Jopt = [];
|
||||
end
|
||||
self.distlog = [self.distlog, sqrt((xk(1:2)-pos)'*(xk(1:2)-pos)-r^2)];
|
||||
self.xopenloop{size(self.xopenloop,2)+1} = xopt;
|
||||
self.uopenloop{size(self.uopenloop,2)+1} = uopt;
|
||||
self.solvertime = [self.solvertime, diagnostics.solvertime];
|
||||
fprintf('solver time: %f\n', diagnostics.solvertime);
|
||||
end
|
||||
|
||||
function plot(self, figure_name)
|
||||
% Plot simulation
|
||||
figure('Renderer', 'painters', 'Position', [0 0 400 400]);
|
||||
set(gca,'LooseInset',get(gca,'TightInset'));
|
||||
hold on;
|
||||
% plot closed-loop trajectory
|
||||
plot(self.xlog(1,:), self.xlog(2,:), 'ko-',...
|
||||
'LineWidth', 1.0, 'MarkerSize', 4);
|
||||
% plot open-loop trajectory
|
||||
for i = 1:size(self.xopenloop, 2)
|
||||
plot(self.xopenloop{i}(1,:), self.xopenloop{i}(2,:),...
|
||||
'k*-.', 'LineWidth', 0.5,'MarkerSize',0.5)
|
||||
end
|
||||
% plot obstacle
|
||||
pos = self.obs.pos;
|
||||
r = self.obs.r;
|
||||
th = linspace(0,2*pi*100);
|
||||
x = cos(th) ; y = sin(th) ;
|
||||
plot(pos(1) + r*x, pos(2) + r*y, 'Color', [0.8500, 0.3250, 0.0980],...
|
||||
'LineWidth', 2);
|
||||
plot(pos(1), pos(2), 'Color', [0.8500, 0.3250, 0.0980],...
|
||||
'MarkerSize', 5, 'LineWidth', 2);
|
||||
% plot target position
|
||||
plot(self.x0(1), self.x0(2), 'db', 'LineWidth', 1);
|
||||
plot(0.0, 0.0, 'dr', 'LineWidth', 1);
|
||||
h=get(gca,'Children');
|
||||
h_legend = legend(h([end]), {'MPC-DC'}, 'Location', 'SouthEast');
|
||||
set(h_legend, 'Interpreter','latex');
|
||||
set(gca,'LineWidth', 0.2, 'FontSize', 15);
|
||||
grid on
|
||||
xlabel('$x (m)$','interpreter','latex','FontSize',20);
|
||||
ylabel('$y (m)$','interpreter','latex','FontSize',20);
|
||||
xticks(-5:0);
|
||||
yticks(-5:0);
|
||||
xlim([-5,0.2]);
|
||||
ylim([-5,0.2]);
|
||||
print(gcf,strcat('figures/',figure_name), '-depsc');
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,66 @@
|
|||
close all
|
||||
clear
|
||||
|
||||
%% Setup and Parameters
|
||||
x0 = [-5; -5; 0; 0];
|
||||
time_total = 20.0;
|
||||
dt = 0.2;
|
||||
P = 100*eye(4);
|
||||
Q = 10*eye(4);
|
||||
R = eye(2);
|
||||
N = 8;
|
||||
umin = [-1; -1];
|
||||
umax = [1; 1];
|
||||
xmin = [-5; -5; -5; -5];
|
||||
xmax = [5; 5; 5; 5];
|
||||
|
||||
%% Discrete-time double integrator 2D
|
||||
system.dt = dt;
|
||||
system.A = [1 0 dt 0;
|
||||
0 1 0 dt;
|
||||
0 0 1 0;
|
||||
0 0 0 1];
|
||||
system.B = [0.5*dt^2 0;
|
||||
0 0.5*dt^2;
|
||||
dt 0;
|
||||
0 dt];
|
||||
system.xl = xmin;
|
||||
system.xu = xmax;
|
||||
system.ul = umin;
|
||||
system.uu = umax;
|
||||
|
||||
%% MPC-CBF parameters
|
||||
params.Q = Q;
|
||||
params.R = R;
|
||||
params.P = P;
|
||||
params.N = N;
|
||||
params.gamma = 0.5;
|
||||
|
||||
%% Obstacle
|
||||
obs.pos = [-2; -2.25];
|
||||
obs.r = 1.5;
|
||||
|
||||
%% Simulate MPC-CBF
|
||||
gamma_list = linspace(0.1, 0.5, 5);
|
||||
controller_mpc_cbf_list = {};
|
||||
for i = 1:size(gamma_list, 2)
|
||||
new_params = params;
|
||||
new_params.N = 5;
|
||||
new_params.gamma = gamma_list(i);
|
||||
controller_mpc_cbf = MPC_CBF(x0, system, new_params);
|
||||
controller_mpc_cbf.obs = obs;
|
||||
controller_mpc_cbf.sim(time_total);
|
||||
controller_mpc_cbf_list{i} = controller_mpc_cbf;
|
||||
end
|
||||
|
||||
%% Computational time benchmark
|
||||
for i = 1:size(gamma_list, 2)
|
||||
controller_mpc_cbf = controller_mpc_cbf_list{i};
|
||||
fprintf('Computational time for MPC-CBF3: mean %.3f, std %.3f, min %.3f, max %.3f, input cost %.3f, min dist %f\n',...
|
||||
[mean(controller_mpc_cbf.solvertime),...
|
||||
std(controller_mpc_cbf.solvertime),...
|
||||
min(controller_mpc_cbf.solvertime),...
|
||||
max(controller_mpc_cbf.solvertime),...
|
||||
controller_mpc_cbf.u_cost,...
|
||||
min(controller_mpc_cbf.distlog)]);
|
||||
end
|
|
@ -0,0 +1,95 @@
|
|||
close all
|
||||
clear
|
||||
|
||||
%% Setup and Parameters
|
||||
x0 = [-5; -5; 0; 0];
|
||||
time_total = 20.0;
|
||||
dt = 0.2;
|
||||
P = 100*eye(4);
|
||||
Q = 10*eye(4);
|
||||
R = eye(2);
|
||||
N = 8;
|
||||
umin = [-1; -1];
|
||||
umax = [1; 1];
|
||||
xmin = [-5; -5; -5; -5];
|
||||
xmax = [5; 5; 5; 5];
|
||||
|
||||
%% Discrete-time double integrator 2D
|
||||
system.dt = dt;
|
||||
system.A = [1 0 dt 0;
|
||||
0 1 0 dt;
|
||||
0 0 1 0;
|
||||
0 0 0 1];
|
||||
system.B = [0.5*dt^2 0;
|
||||
0 0.5*dt^2;
|
||||
dt 0;
|
||||
0 dt];
|
||||
system.xl = xmin;
|
||||
system.xu = xmax;
|
||||
system.ul = umin;
|
||||
system.uu = umax;
|
||||
|
||||
%% MPC-CBF parameters
|
||||
params_mpc_cbf.Q = Q;
|
||||
params_mpc_cbf.R = R;
|
||||
params_mpc_cbf.P = P;
|
||||
params_mpc_cbf.N = N;
|
||||
params_mpc_cbf.gamma = 0.5;
|
||||
|
||||
%% Obstacle
|
||||
obs.pos = [-2; -2.25];
|
||||
obs.r = 1.5;
|
||||
|
||||
%% Simulate MPC-CBF
|
||||
gamma_list = [0.1, 0.2, 0.3, 1.0];
|
||||
for ind = 1:size(gamma_list, 2)
|
||||
fprintf('Run MPC-CBF with gamma %f\n', gamma_list(ind));
|
||||
params_mpc_cbf.gamma = gamma_list(ind);
|
||||
controller_mpc_cbf_list{ind} = MPC_CBF(x0, system, params_mpc_cbf);
|
||||
controller_mpc_cbf_list{ind}.obs = obs;
|
||||
controller_mpc_cbf_list{ind}.sim(time_total);
|
||||
end
|
||||
|
||||
%% Simulate MPC-DC
|
||||
params_mpc_dc = params_mpc_cbf;
|
||||
controller_mpc_dc = MPC_DC(x0, system, params_mpc_cbf);
|
||||
controller_mpc_dc.obs = obs;
|
||||
controller_mpc_dc.sim(time_total);
|
||||
|
||||
%% Visualization benchmark
|
||||
figure('Renderer', 'painters', 'Position', [0 0 400 400]);
|
||||
set(gca,'LooseInset',get(gca,'TightInset'));
|
||||
hold on
|
||||
for ind = 1:size(gamma_list, 2)
|
||||
plot(controller_mpc_cbf_list{ind}.xlog(1,:), controller_mpc_cbf_list{ind}.xlog(2,:),...
|
||||
'-', 'LineWidth', 1.0, 'MarkerSize', 4);
|
||||
end
|
||||
plot(controller_mpc_dc.xlog(1,:), controller_mpc_dc.xlog(2,:),...
|
||||
'k--', 'LineWidth', 1.0, 'MarkerSize', 4);
|
||||
% plot obstacle
|
||||
pos = obs.pos;
|
||||
r = obs.r;
|
||||
th = linspace(0,2*pi*100);
|
||||
x = cos(th) ; y = sin(th) ;
|
||||
plot(pos(1) + r*x, pos(2) + r*y, 'Color', [0.8500, 0.3250, 0.0980],...
|
||||
'LineWidth', 2);
|
||||
plot(pos(1), pos(2), 'Color', [0.8500, 0.3250, 0.0980],...
|
||||
'MarkerSize', 5, 'LineWidth', 2);
|
||||
% plot target position
|
||||
plot(x0(1), x0(2), 'db', 'LineWidth', 1);
|
||||
plot(0.0, 0.0, 'dr', 'LineWidth', 1);
|
||||
h=get(gca,'Children');
|
||||
h_legend = legend(h([end, end-1, end-2, end-3, end-4]),...
|
||||
{'MPC-CBF ($\gamma=0.1$)', 'MPC-CBF ($\gamma=0.2$)',...
|
||||
'MPC-CBF ($\gamma=0.3$)', 'MPC-CBF ($\gamma=1.0$)', 'MPC-DC'}, 'Location', 'SouthEast');
|
||||
set(h_legend, 'Interpreter','latex');
|
||||
set(gca,'LineWidth', 0.2, 'FontSize', 15);
|
||||
grid on
|
||||
xlabel('$x (m)$','interpreter','latex','FontSize',20);
|
||||
ylabel('$y (m)$','interpreter','latex','FontSize',20);
|
||||
xticks(-5:1);
|
||||
yticks(-5:1);
|
||||
xlim([-5,0.2]);
|
||||
ylim([-5,0.2]);
|
||||
print(gcf,'figures/benchmark-gamma.eps', '-depsc');
|
||||
print(gcf,'figures/benchmark-gamma.png', '-dpng', '-r800');
|
|
@ -0,0 +1,198 @@
|
|||
close all
|
||||
clear
|
||||
|
||||
%% Setup and Parameters
|
||||
x0 = [-5; -5; 0; 0];
|
||||
time_total = 20.0;
|
||||
dt = 0.2;
|
||||
P = 100*eye(4);
|
||||
Q = 10*eye(4);
|
||||
R = eye(2);
|
||||
N = 8;
|
||||
umin = [-1; -1];
|
||||
umax = [1; 1];
|
||||
xmin = [-5; -5; -5; -5];
|
||||
xmax = [5; 5; 5; 5];
|
||||
|
||||
%% Discrete-time double integrator 2D
|
||||
system.dt = dt;
|
||||
system.A = [1 0 dt 0;
|
||||
0 1 0 dt;
|
||||
0 0 1 0;
|
||||
0 0 0 1];
|
||||
system.B = [0.5*dt^2 0;
|
||||
0 0.5*dt^2;
|
||||
dt 0;
|
||||
0 dt];
|
||||
system.xl = xmin;
|
||||
system.xu = xmax;
|
||||
system.ul = umin;
|
||||
system.uu = umax;
|
||||
|
||||
%% MPC-CBF parameters
|
||||
params.Q = Q;
|
||||
params.R = R;
|
||||
params.P = P;
|
||||
params.N = N;
|
||||
params.gamma = 0.5;
|
||||
|
||||
%% Obstacle
|
||||
obs.pos = [-2; -2.25];
|
||||
obs.r = 1.5;
|
||||
|
||||
%% Simulate MPC-CBF
|
||||
params.N = 5;
|
||||
params.gamma = 0.25;
|
||||
controller_mpc_cbf_1 = MPC_CBF(x0, system, params);
|
||||
controller_mpc_cbf_1.obs = obs;
|
||||
controller_mpc_cbf_1.sim(time_total);
|
||||
|
||||
%% Simulate MPC-CBF with lower gamma
|
||||
params.gamma = 0.20;
|
||||
controller_mpc_cbf_2 = MPC_CBF(x0, system, params);
|
||||
controller_mpc_cbf_2.obs = obs;
|
||||
controller_mpc_cbf_2.sim(time_total);
|
||||
|
||||
params.gamma = 0.15;
|
||||
controller_mpc_cbf_3 = MPC_CBF(x0, system, params);
|
||||
controller_mpc_cbf_3.obs = obs;
|
||||
controller_mpc_cbf_3.sim(time_total);
|
||||
|
||||
%% Simulate MPC-DC
|
||||
params.N = 7;
|
||||
controller_mpc_dc_1 = MPC_DC(x0, system, params);
|
||||
controller_mpc_dc_1.obs = obs;
|
||||
controller_mpc_dc_1.sim(time_total);
|
||||
|
||||
%% Simulate MPC-DC with larger horizon
|
||||
params.N = 15;
|
||||
controller_mpc_dc_2 = MPC_DC(x0, system, params);
|
||||
controller_mpc_dc_2.obs = obs;
|
||||
controller_mpc_dc_2.sim(time_total);
|
||||
|
||||
%%
|
||||
params.N = 30;
|
||||
controller_mpc_dc_3 = MPC_DC(x0, system, params);
|
||||
controller_mpc_dc_3.obs = obs;
|
||||
controller_mpc_dc_3.sim(time_total);
|
||||
|
||||
%% Visualization benchmark
|
||||
figure('Renderer', 'painters', 'Position', [0 0 400 400]);
|
||||
set(gca,'LooseInset',get(gca,'TightInset'));
|
||||
hold on
|
||||
plot(controller_mpc_cbf_3.xlog(1,:), controller_mpc_cbf_3.xlog(2,:),...
|
||||
'-', 'Color', [0, 0.4470, 0.7410], 'LineWidth', 1.0, 'MarkerSize', 4);
|
||||
plot(controller_mpc_cbf_2.xlog(1,:), controller_mpc_cbf_2.xlog(2,:),...
|
||||
'-', 'Color', [0.8500, 0.3250, 0.0980], 'LineWidth', 1.0, 'MarkerSize', 4);
|
||||
plot(controller_mpc_cbf_1.xlog(1,:), controller_mpc_cbf_1.xlog(2,:),...
|
||||
'-', 'Color', [0.9290, 0.6940, 0.1250], 'LineWidth', 1.0, 'MarkerSize', 4);
|
||||
plot(controller_mpc_dc_1.xlog(1,:), controller_mpc_dc_1.xlog(2,:),...
|
||||
'--', 'Color', [0.4940, 0.1840, 0.5560], 'LineWidth', 1.0, 'MarkerSize', 4);
|
||||
plot(controller_mpc_dc_2.xlog(1,:), controller_mpc_dc_2.xlog(2,:),...
|
||||
'--', 'Color', [0.4660, 0.6740, 0.1880], 'LineWidth', 1.0, 'MarkerSize', 4);
|
||||
plot(controller_mpc_dc_3.xlog(1,:), controller_mpc_dc_3.xlog(2,:),...
|
||||
'--', 'Color', [0.3010, 0.7450, 0.9330], 'LineWidth', 1.0, 'MarkerSize', 4);
|
||||
% plot obstacle
|
||||
pos = obs.pos;
|
||||
r = obs.r;
|
||||
th = linspace(0,2*pi*100);
|
||||
x = cos(th) ; y = sin(th) ;
|
||||
plot(pos(1) + r*x, pos(2) + r*y, 'Color', [0.8500, 0.3250, 0.0980],...
|
||||
'LineWidth', 2);
|
||||
plot(pos(1), pos(2), 'Color', [0.8500, 0.3250, 0.0980],...
|
||||
'MarkerSize', 5, 'LineWidth', 2);
|
||||
% plot target position
|
||||
plot(x0(1), x0(2), 'db', 'LineWidth', 1);
|
||||
plot(0.0, 0.0, 'dr', 'LineWidth', 1);
|
||||
h=get(gca,'Children');
|
||||
h_legend = legend(h([end, end-1, end-2, end-3, end-4, end-5]),...
|
||||
{'MPC-CBF ($N = 5, \gamma = 0.15$)', 'MPC-CBF ($N = 5, \gamma = 0.20$)',...
|
||||
'MPC-CBF ($N = 5, \gamma = 0.25$)', 'MPC-DC ($N = 7$)', 'MPC-DC ($N = 15$)',...
|
||||
'MPC-DC ($N = 30$)'}, 'Location', 'SouthEast');
|
||||
set(h_legend, 'Interpreter','latex', 'FontSize', 10);
|
||||
set(gca,'LineWidth', 0.2, 'FontSize', 15);
|
||||
grid on
|
||||
xlabel('$x (m)$','interpreter','latex','FontSize',20);
|
||||
ylabel('$y (m)$','interpreter','latex','FontSize',20);
|
||||
xticks(-5:0);
|
||||
yticks(-5:0);
|
||||
xlim([-5,0.2]);
|
||||
ylim([-5,0.2]);
|
||||
print(gcf,'figures/benchmark-horizon.eps', '-depsc');
|
||||
print(gcf,'figures/benchmark-horizon.png', '-dpng', '-r800');
|
||||
|
||||
%% Computational time benchmark
|
||||
figure('Renderer', 'painters', 'Position', [0 0 800 400]);
|
||||
xlabel('Computational time (s)', 'interpreter', 'latex', 'FontSize', 16);
|
||||
ylabel('Percentage', 'interpreter', 'latex', 'FontSize', 16);
|
||||
hold on
|
||||
% [N_mpc_3, edges_mpc_3] = histcounts(controller_mpc_cbf_3.solvertime, 10, 'Normalization', 'probability');
|
||||
% plot(edges_mpc_3(1:end-1), N_mpc_3, '-', 'Color', [0, 0.4470, 0.7410], 'LineWidth', 1);
|
||||
% [N_mpc_2, edges_mpc_2] = histcounts(controller_mpc_cbf_2.solvertime, 10, 'Normalization', 'probability');
|
||||
% plot(edges_mpc_2(1:end-1), N_mpc_2, '-', 'Color', [0.8500, 0.3250, 0.0980], 'LineWidth', 1);
|
||||
[N_mpc_1, edges_mpc_1] = histcounts(controller_mpc_cbf_1.solvertime, 10, 'Normalization', 'probability');
|
||||
plot(edges_mpc_1(1:end-1), N_mpc_1, '-', 'Color', [0.9290, 0.6940, 0.1250], 'LineWidth', 1);
|
||||
[N_dc_1, edges_dc_1] = histcounts(controller_mpc_dc_1.solvertime, 10, 'Normalization', 'probability');
|
||||
plot(edges_dc_1(1:end-1), N_dc_1, '--', 'Color', [0.4940, 0.1840, 0.5560], 'LineWidth', 1);
|
||||
[N_dc_2, edges_dc_2] = histcounts(controller_mpc_dc_2.solvertime, 10, 'Normalization', 'probability');
|
||||
plot(edges_dc_2(1:end-1), N_dc_2, '--', 'Color', [0.4660, 0.6740, 0.1880], 'LineWidth', 1);
|
||||
[N_dc_3, edges_dc_3] = histcounts(controller_mpc_dc_3.solvertime, 10, 'Normalization', 'probability');
|
||||
plot(edges_dc_3(1:end-1), N_dc_3, '--', 'Color', [0.3010, 0.7450, 0.9330], 'LineWidth', 1);
|
||||
h=get(gca,'Children');
|
||||
h_legend = legend(h([end, end-1, end-2, end-3]),...
|
||||
{'MPC-CBF ($N = 5, \gamma = 0.25$)',...
|
||||
'MPC-DC ($N = 7$)',...
|
||||
'MPC-DC ($N = 15$)',...
|
||||
'MPC-DC ($N = 30$)'}, 'Location', 'NorthEast');
|
||||
set(h_legend, 'Interpreter','latex');
|
||||
set(gca,'LineWidth', 0.2, 'FontSize', 15);
|
||||
print(gcf,'figures/benchmark-horizon-computational-time.eps', '-depsc');
|
||||
print(gcf,'figures/benchmark-horizon-computational-time.png', '-dpng', '-r800');
|
||||
%% Computational time table
|
||||
fprintf('Computational time for MPC-CBF3: mean %.3f, std %.3f, min %.3f, max %.3f, input cost %.3f, min dist %f\n',...
|
||||
[mean(controller_mpc_cbf_3.solvertime),...
|
||||
std(controller_mpc_cbf_3.solvertime),...
|
||||
min(controller_mpc_cbf_3.solvertime),...
|
||||
max(controller_mpc_cbf_3.solvertime),...
|
||||
controller_mpc_cbf_3.u_cost,...
|
||||
min(controller_mpc_cbf_3.distlog)]);
|
||||
|
||||
fprintf('Computational time for MPC-CBF2: mean %.3f, std %.3f, min %.3f, max %.3f, input cost %.3f, min dist %f\n',...
|
||||
[mean(controller_mpc_cbf_2.solvertime),...
|
||||
std(controller_mpc_cbf_2.solvertime),...
|
||||
min(controller_mpc_cbf_2.solvertime),...
|
||||
max(controller_mpc_cbf_2.solvertime),...
|
||||
controller_mpc_cbf_2.u_cost,...
|
||||
min(controller_mpc_cbf_2.distlog)]);
|
||||
|
||||
fprintf('Computational time for MPC-CBF1: mean %.3f, std %.3f, min %.3f, max %.3f, input cost %.3f, min dist %f\n',...
|
||||
[mean(controller_mpc_cbf_1.solvertime),...
|
||||
std(controller_mpc_cbf_1.solvertime),...
|
||||
min(controller_mpc_cbf_1.solvertime),...
|
||||
max(controller_mpc_cbf_1.solvertime),...
|
||||
controller_mpc_cbf_1.u_cost,...
|
||||
min(controller_mpc_cbf_1.distlog)]);
|
||||
|
||||
fprintf('Computational time for MPC-DC1: mean %.3f, std %.3f, min %.3f, max %.3f, input cost %.3f, min dist %f\n',...
|
||||
[mean(controller_mpc_dc_1.solvertime),...
|
||||
std(controller_mpc_dc_1.solvertime),...
|
||||
min(controller_mpc_dc_1.solvertime),...
|
||||
max(controller_mpc_dc_1.solvertime),...
|
||||
controller_mpc_dc_1.u_cost,...
|
||||
min(controller_mpc_dc_1.distlog)]);
|
||||
|
||||
fprintf('Computational time for MPC-DC2: mean %.3f, std %.3f, min %.3f, max %.3f, input cost %.3f, min dist %f\n',...
|
||||
[mean(controller_mpc_dc_2.solvertime),...
|
||||
std(controller_mpc_dc_2.solvertime),...
|
||||
min(controller_mpc_dc_2.solvertime),...
|
||||
max(controller_mpc_dc_2.solvertime),...
|
||||
controller_mpc_dc_2.u_cost,...
|
||||
min(controller_mpc_dc_2.distlog)]);
|
||||
|
||||
fprintf('Computational time for MPC-DC3: mean %.3f, std %.3f, min %.3f, max %.3f, input cost %.3f, min dist %f\n',...
|
||||
[mean(controller_mpc_dc_3.solvertime),...
|
||||
std(controller_mpc_dc_3.solvertime),...
|
||||
min(controller_mpc_dc_3.solvertime),...
|
||||
max(controller_mpc_dc_3.solvertime),...
|
||||
controller_mpc_dc_3.u_cost,...
|
||||
min(controller_mpc_dc_3.distlog)]);
|
After Width: | Height: | Size: 440 KiB |
After Width: | Height: | Size: 559 KiB |
After Width: | Height: | Size: 472 KiB |
After Width: | Height: | Size: 289 KiB |
After Width: | Height: | Size: 294 KiB |
After Width: | Height: | Size: 288 KiB |
After Width: | Height: | Size: 281 KiB |
|
@ -0,0 +1,235 @@
|
|||
close all
|
||||
clear
|
||||
|
||||
%% General Flags
|
||||
run_dclf_dcbf = true;
|
||||
display_dclf_dcbf = true;
|
||||
run_mpc_cbf_one = true;
|
||||
display_mpc_cbf_one = true;
|
||||
run_mpc_cbf_multiple = true;
|
||||
run_mpc_cbf_multiple = true;
|
||||
run_mpc_dc = true;
|
||||
display_mpc_dc = true;
|
||||
|
||||
%% Setup and Parameters
|
||||
x0 = [-5; -5; 0; 0];
|
||||
time_total = 30.0;
|
||||
dt = 0.2;
|
||||
P = 100*eye(4);
|
||||
Q = 10*eye(4);
|
||||
R = eye(2);
|
||||
N = 8;
|
||||
umin = [-1; -1];
|
||||
umax = [1; 1];
|
||||
xmin = [-5; -5; -5; -5];
|
||||
xmax = [5; 5; 5; 5];
|
||||
|
||||
%% Discrete-time double integrator 2D
|
||||
system.dt = dt;
|
||||
system.A = [1 0 dt 0;
|
||||
0 1 0 dt;
|
||||
0 0 1 0;
|
||||
0 0 0 1];
|
||||
system.B = [0.5*dt^2 0;
|
||||
0 0.5*dt^2;
|
||||
dt 0;
|
||||
0 dt];
|
||||
system.xl = xmin;
|
||||
system.xu = xmax;
|
||||
system.ul = umin;
|
||||
system.uu = umax;
|
||||
|
||||
%% DCLF-DCBF parameters
|
||||
p = 1e3;
|
||||
params_dclf_dcbf.P = P;
|
||||
params_dclf_dcbf.H = R;
|
||||
params_dclf_dcbf.p = p;
|
||||
params_dclf_dcbf.alpha = 1.0;
|
||||
params_dclf_dcbf.gamma = 0.4;
|
||||
|
||||
%% MPC-CBF parameters
|
||||
params_mpc_cbf.Q = Q;
|
||||
params_mpc_cbf.R = R;
|
||||
params_mpc_cbf.P = P;
|
||||
params_mpc_cbf.N = N;
|
||||
params_mpc_cbf.gamma = 0.4;
|
||||
|
||||
%% MPC-DC parameters
|
||||
params_mpc_dc.Q = Q;
|
||||
params_mpc_dc.R = R;
|
||||
params_mpc_dc.P = P;
|
||||
params_mpc_dc.N = N;
|
||||
|
||||
%% Obstacle
|
||||
obs.pos = [-2; -2.25];
|
||||
obs.r = 1.5;
|
||||
|
||||
%% Simulate DCLF-DCBF
|
||||
if run_dclf_dcbf
|
||||
fprintf('Run DCLF-DCBF\n');
|
||||
controller_dclf_dcbf = DCLF_DCBF(x0, system, params_dclf_dcbf);
|
||||
controller_dclf_dcbf.obs = obs;
|
||||
controller_dclf_dcbf.sim(time_total);
|
||||
end
|
||||
|
||||
%% Display DCLF-DCBF simulation
|
||||
if display_dclf_dcbf
|
||||
% Plot simulation
|
||||
figure('Renderer', 'painters', 'Position', [0 0 400 400]);
|
||||
set(gca,'LooseInset',get(gca,'TightInset'));
|
||||
hold on;
|
||||
% plot trajectory
|
||||
plot(controller_dclf_dcbf.xlog(1,:), controller_dclf_dcbf.xlog(2,:), 'ko-',...
|
||||
'LineWidth', 1.0,'MarkerSize',4);
|
||||
% plot obstacle
|
||||
pos = controller_dclf_dcbf.obs.pos;
|
||||
r = controller_dclf_dcbf.obs.r;
|
||||
th = linspace(0,2*pi*100);
|
||||
x = cos(th) ; y = sin(th) ;
|
||||
plot(pos(1) + r*x, pos(2) + r*y, 'Color', [0.8500, 0.3250, 0.0980], 'LineWidth', 2);
|
||||
plot(pos(1), pos(2), 'Color', [0.8500, 0.3250, 0.0980], 'MarkerSize', 5, 'LineWidth', 2);
|
||||
% plot target position
|
||||
plot(controller_dclf_dcbf.x0(1), controller_dclf_dcbf.x0(2), 'db', 'LineWidth', 1);
|
||||
plot(0.0, 0.0, 'dr', 'LineWidth', 1);
|
||||
h=get(gca,'Children');
|
||||
h_legend = legend(h([end]), {'DCLF-DCBF'}, 'Location', 'SouthEast');
|
||||
set(h_legend, 'Interpreter','latex');
|
||||
set(gca,'LineWidth', 0.2, 'FontSize', 15);
|
||||
grid on
|
||||
xlabel('$x (m)$','interpreter','latex','FontSize',20);
|
||||
ylabel('$y (m)$','interpreter','latex','FontSize',20);
|
||||
xticks(-5:0);
|
||||
yticks(-5:0);
|
||||
xlim([-5,0.2]);
|
||||
ylim([-5,0.2]);
|
||||
print(gcf,'figures/dclf-dcbf-avoidance.eps', '-depsc');
|
||||
print(gcf,'figures/dclf-dcbf-avoidance.png', '-dpng', '-r800');
|
||||
end
|
||||
|
||||
%% Simulate MPC-CBF with N=1;
|
||||
params_mpc_cbf.N = 1;
|
||||
if run_mpc_cbf_one
|
||||
fprintf('Run MPC-CBF\n');
|
||||
controller_mpc_cbf_one = MPC_CBF(x0, system, params_mpc_cbf);
|
||||
controller_mpc_cbf_one.obs = obs;
|
||||
controller_mpc_cbf_one.sim(time_total);
|
||||
end
|
||||
|
||||
%% Display MPC-CBF simulation with N=1
|
||||
if display_mpc_cbf_one
|
||||
% Plot simulation
|
||||
figure('Renderer', 'painters', 'Position', [0 0 400 400]);
|
||||
set(gca,'LooseInset',get(gca,'TightInset'));
|
||||
hold on;
|
||||
% plot trajectory
|
||||
plot(controller_mpc_cbf_one.xlog(1,:), controller_mpc_cbf_one.xlog(2,:), 'ko-',...
|
||||
'LineWidth', 1.0,'MarkerSize',4);
|
||||
% plot obstacle
|
||||
pos = controller_mpc_cbf_one.obs.pos;
|
||||
r = controller_mpc_cbf_one.obs.r;
|
||||
th = linspace(0,2*pi*100);
|
||||
x = cos(th) ; y = sin(th) ;
|
||||
plot(pos(1) + r*x, pos(2) + r*y, 'Color', [0.8500, 0.3250, 0.0980], 'LineWidth', 2);
|
||||
plot(pos(1), pos(2), 'Color', [0.8500, 0.3250, 0.0980], 'MarkerSize', 5, 'LineWidth', 2);
|
||||
% plot target position
|
||||
plot(controller_mpc_cbf_one.x0(1), controller_mpc_cbf_one.x0(2), 'db', 'LineWidth', 1);
|
||||
plot(0.0, 0.0, 'dr', 'LineWidth', 1);
|
||||
h=get(gca,'Children');
|
||||
h_legend = legend(h([end]), {'MPC-CBF ($N=1$)'}, 'Location', 'SouthEast');
|
||||
set(h_legend, 'Interpreter','latex');
|
||||
set(gca,'LineWidth', 0.2, 'FontSize', 15);
|
||||
grid on
|
||||
xlabel('$x (m)$','interpreter','latex','FontSize',20);
|
||||
ylabel('$y (m)$','interpreter','latex','FontSize',20);
|
||||
xticks(-5:0);
|
||||
yticks(-5:0);
|
||||
xlim([-5,0.2]);
|
||||
ylim([-5,0.2]);
|
||||
print(gcf, 'figures/mpc-cbf-avoidance-one-step.eps', '-depsc');
|
||||
print(gcf, 'figures/mpc-cbf-avoidance-one-step.png', '-dpng', '-r800');
|
||||
end
|
||||
|
||||
%% Simulate MPC-CBF with other N
|
||||
params_mpc_cbf.N = 8;
|
||||
if run_mpc_cbf_one
|
||||
fprintf('Run MPC-CBF\n');
|
||||
controller_mpc_cbf_multiple = MPC_CBF(x0, system, params_mpc_cbf);
|
||||
controller_mpc_cbf_multiple.obs = obs;
|
||||
controller_mpc_cbf_multiple.sim(time_total);
|
||||
end
|
||||
|
||||
%% Display MPC-CBF simulation with other N
|
||||
if display_mpc_cbf_one
|
||||
% Plot simulation
|
||||
figure('Renderer', 'painters', 'Position', [0 0 400 400]);
|
||||
set(gca,'LooseInset',get(gca,'TightInset'));
|
||||
hold on;
|
||||
% plot trajectory
|
||||
plot(controller_mpc_cbf_multiple.xlog(1,:), controller_mpc_cbf_multiple.xlog(2,:), 'ko-',...
|
||||
'LineWidth', 1.0,'MarkerSize',4);
|
||||
% plot obstacle
|
||||
pos = controller_mpc_cbf_multiple.obs.pos;
|
||||
r = controller_mpc_cbf_multiple.obs.r;
|
||||
th = linspace(0,2*pi*100);
|
||||
x = cos(th) ; y = sin(th) ;
|
||||
plot(pos(1) + r*x, pos(2) + r*y, 'Color', [0.8500, 0.3250, 0.0980], 'LineWidth', 2);
|
||||
plot(pos(1), pos(2), 'Color', [0.8500, 0.3250, 0.0980], 'MarkerSize', 5, 'LineWidth', 2);
|
||||
% plot target position
|
||||
plot(controller_mpc_cbf_multiple.x0(1), controller_mpc_cbf_multiple.x0(2), 'db', 'LineWidth', 1);
|
||||
plot(0.0, 0.0, 'dr', 'LineWidth', 1);
|
||||
h=get(gca,'Children');
|
||||
h_legend = legend(h([end]), {'MPC-CBF ($N=8$)'}, 'Location', 'SouthEast');
|
||||
set(h_legend, 'Interpreter','latex');
|
||||
set(gca,'LineWidth', 0.2, 'FontSize', 15);
|
||||
grid on
|
||||
xlabel('$x (m)$','interpreter','latex','FontSize',20);
|
||||
ylabel('$y (m)$','interpreter','latex','FontSize',20);
|
||||
xticks(-5:0);
|
||||
yticks(-5:0);
|
||||
xlim([-5,0.2]);
|
||||
ylim([-5,0.2]);
|
||||
print(gcf, 'figures/mpc-cbf-avoidance-several-steps.eps', '-depsc');
|
||||
print(gcf, 'figures/mpc-cbf-avoidance-several-steps.png', '-dpng', '-r800');
|
||||
end
|
||||
|
||||
%% Simulate MPC-DC
|
||||
if run_mpc_dc
|
||||
fprintf('Run MPC-DC\n');
|
||||
controller_mpc_dc = MPC_DC(x0, system, params_mpc_dc);
|
||||
controller_mpc_dc.obs = obs;
|
||||
controller_mpc_dc.sim(time_total);
|
||||
end
|
||||
|
||||
%% Display MPC-DC simulation
|
||||
if display_mpc_dc
|
||||
% Plot simulation
|
||||
figure('Renderer', 'painters', 'Position', [0 0 400 400]);
|
||||
set(gca,'LooseInset',get(gca,'TightInset'));
|
||||
hold on;
|
||||
% plot trajectory
|
||||
plot(controller_mpc_dc.xlog(1,:), controller_mpc_dc.xlog(2,:), 'ko-',...
|
||||
'LineWidth', 1.0,'MarkerSize',4);
|
||||
% plot obstacle
|
||||
pos = controller_mpc_dc.obs.pos;
|
||||
r = controller_mpc_dc.obs.r;
|
||||
th = linspace(0,2*pi*100);
|
||||
x = cos(th) ; y = sin(th) ;
|
||||
plot(pos(1) + r*x, pos(2) + r*y, 'Color', [0.8500, 0.3250, 0.0980], 'LineWidth', 2);
|
||||
plot(pos(1), pos(2), 'Color', [0.8500, 0.3250, 0.0980], 'MarkerSize', 5, 'LineWidth', 2);
|
||||
% plot target position
|
||||
plot(controller_mpc_dc.x0(1), controller_mpc_dc.x0(2), 'db', 'LineWidth', 1);
|
||||
plot(0.0, 0.0, 'dr', 'LineWidth', 1);
|
||||
h=get(gca,'Children');
|
||||
h_legend = legend(h([end]), {'MPC-DC ($N=8$)'}, 'Location', 'SouthEast');
|
||||
set(h_legend, 'Interpreter','latex');
|
||||
set(gca,'LineWidth', 0.2, 'FontSize', 15);
|
||||
grid on
|
||||
xlabel('$x (m)$','interpreter','latex','FontSize',20);
|
||||
ylabel('$y (m)$','interpreter','latex','FontSize',20);
|
||||
xticks(-5:0);
|
||||
yticks(-5:0);
|
||||
xlim([-5,0.2]);
|
||||
ylim([-5,0.2]);
|
||||
print(gcf, 'figures/mpc-dc-avoidance.eps', '-depsc');
|
||||
print(gcf, 'figures/mpc-dc-avoidance.png', '-dpng', '-r800');
|
||||
end
|