odqp作为二次规划库具有非常重要的作用,可以运用于模型预测控制算法(MPC)
目前在网站上面已经有很多相关的源码,也有结合Eigen的osqp-eigen代码包,但是很多小伙伴们拿到这个代码包后不知道具体该怎么调用库。
我一开始拿到这个代码包的时候也很懵逼,网站上有很多代码包,都大同小异,我也不知道选择哪个,最后在我师父的帮助下,成功的调用了osqp-eigrn的第三方库。
所以结合自己的经验,将这个过程具体梳理一下,同时也是做一个笔记。
温馨提示:代码包大家可以按照我所提供的下载,按照文章的步骤来操作,绝对没有问题,试过两遍。
ROS python调用osqp库的过程可以见另一篇:ROS python调用osqp库的具体操作步骤
STEP1:拿到osqp和osqp-eigen的功能包
链接:https://pan.baidu.com/s/1Y2p1WwKStDL9j3CbGS0mDQ 提取码:osqp
STEP2:将这两个包复制到Linux的桌面上
STEP3:开始进行库的调用设置
一:首先需要进行基础的二次规划库osqp的安装
1.进入osqp-master代码包进行编译
~$ cd osqp-master
~$ mkdir build
~$ cd build
~$ cmake ..
~$ cmake .. -DCMAKE_INSTALL_PREFIT=usr/local/osqp
~$ sudo make install
~$ source ~/.bashrc ##设置环境变量,这一步不能忘记
2.在我们自己的功能包的CmakeLists.txt中进行编辑,搜索头文件和库
###########
## Build ##
###########
## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
/usr/local/osqp/include #######添加这一行,对代码编译后会在该路径下生成所需的头文件
${catkin_INCLUDE_DIRS}
...
)
link_directories(
${catkin_LIB_DIRS}
/usr/local/osqp/lib #######添加这一行,对代码编译后会在该路径下生成所需的库
...
)
二:添加ROS自带的Eigen模块
在我们自己的功能包的CmakeLists.txt中进行编辑,包含Eigen库,并给出头文件和库路径
cmake_minimum_required(VERSION 3.0.2)
project(PROJECT_NAME)
find_package(catkin REQUIRED COMPONENTS
...
cmake_modules ######添加这一行
)
find_package(Eigen REQUIRED) ######添加这一行,添加Eigen库
###########
## Build ##
###########
## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
/usr/local/osqp/include
${catkin_INCLUDE_DIRS}
${Eigen_INCLUDE_DIRS} #####添加这一行,头文件路径
...
)
link_directories(
${catkin_LIB_DIRS}
${Eigen_LIB_DIRS} #####添加这一行,库路径
/usr/local/osqp/lib
...
)
三:osqp-eigen第三方库调用
现在我们已经做好osqp库和Eigen库的调用,那么我们就可以开始进行第三方库osqp-eigen的调用了。osqp-eigen是使用Eigen库封装osqp库的得到的代码库,相比于osqp有着更方便的接口。
1.进入osqp-eigen-master代码包进行编译
~$ cd osqp-eigen-master
~$ mkdir build
~$ cd build
~$ cmake ..
~$ cmake .. -DCMAKE_INSTALL_PREFIT=usr/local/osqp-eigen
~$ sudo make install
~$ source ~/.bashrc ##设置环境变量,这一步不能忘记
2.在我们自己的功能包的CmakeLists.txt中进行编辑,搜索头文件和库
###########
## Build ##
###########
## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
/usr/local/osqp/include
/usr/local/osqp-eigen/include #######添加这一行,对代码编译后会在该路径下生成所需的头文件
${catkin_INCLUDE_DIRS}
...
)
link_directories(
${catkin_LIB_DIRS}
/usr/local/osqp/lib
/usr/local/osqp-eigen/lib #######添加这一行,对代码编译后会在该路径下生成所需的库
...
)
这一步和调用基础osqp库是差不多的步骤
四:终于全部调用完了,然后就是我们的目标文件去链接这些库
在CmakeLists.txt中进行目标文件的生成和库的链接,在这个例子中我所使用的是mpc_test,大家可以在桌面的osqp-eigen-master/example/src中找到,文件的原名称是MPCExample.cpp,我改成了mpc_test.cpp放到了我自己的功能包src下,并进行库的链接:
add_executable(mpc_test src/mpc_test.cpp) ######目标文件生成的常规步骤
target_link_libraries(mpc_test
${catkin_LIBRARIES}
osqp #####链接osqp库,因为OsqpEigen需要osqp库
OsqpEigen #####链接OsqpEigen库
)
五:catkin_make
终于都做完了,接下来就是进行编译了
~$ cd catkin_ws
~/catkin_ws$ catkin_make
编译出错第一种
编译中...出错了!!!!这是正常现象,但是不用慌,我们先来看一看错误是什么:
错误提示没有<osqp.h>这个文件或目录,是因为在 include_directories( /usr/local/osqp/include)中,include里面有osqp文件夹和dqlql文件夹,而osqp.h是在osqp文件夹下:
Constants.hpp位置如下图:
所以我们在这个Constants.hpp中要对这个语句进行更改。
更改文件夹权限,进入/usr/local:
~$ sduo nautilus
[sudo] xxxx 的密码:
根据报错的路径找到这个文件,编辑Constants.hpp,进行更改:
#include <osqp/osqp.h>
编译出错第二种
再次进行编译,又出错了!!!!!错误内容如下:
老样子,编辑Solver.tpp文件,但是要找到auxil.h这个头文件在那个文件夹下面,通过之前一个错误,推测这个头文件也在/include/osqp文件夹下面:
果然,所以对 Solver.tpp进行更改,指明头文件搜索路径:
#include <iostream>
#include <osqp/auxil.h>
#include <osqp/scaling.h> //对这个头文件一并更改
#include "Debug.hpp"
然后继续编译,出现上述的报错内容一般都是include语句有问题,头文件路径不对,改过来就好了。
所有类似的错误都改完了之后,就可以进行正常的编译了,程序也可以跑了。
六:程序效果
输入指令:
~$ roscore
~$ rosrun path_track mpc_test
我修改了优化次数,优化5次,跑出来的效果如下:
zhz@zhzrobot:~/gzrobot_ws$ rosrun path_track mpc_test
-----------------------------------------------------------------
OSQP v0.6.0 - Operator Splitting QP Solver
(c) Bartolomeo Stellato, Goran Banjac
University of Oxford - Stanford University 2019
-----------------------------------------------------------------
problem: variables n = 332, constraints m = 584
nnz(P) + nnz(A) = 1971
settings: linear system solver = qdldl,
eps_abs = 1.0e-03, eps_rel = 1.0e-03,
eps_prim_inf = 1.0e-04, eps_dual_inf = 1.0e-04,
rho = 1.00e-01 (adaptive),
sigma = 1.00e-06, alpha = 1.60, max_iter = 4000
check_termination: on (interval 25),
scaling: on, scaled_termination: off
warm start: on, polish: off, time_limit: off
iter objective pri res dua res rho time
1 -6.5518e+01 8.34e-01 6.00e+00 1.00e-01 6.22e-04s
25 -9.0968e+01 5.79e-05 2.18e-04 1.00e-01 9.84e-04s
status: solved
number of iterations: 25
optimal objective: -90.9683
run time: 1.03e-03s
optimal rho estimate: 8.80e-02
iter objective pri res dua res rho time
1 -9.0968e+01 1.66e+00 9.34e+02 1.00e-01 4.71e-05s
25 -9.6366e+01 4.42e-04 4.43e-03 1.00e-01 4.17e-04s
status: solved
number of iterations: 25
optimal objective: -96.3664
run time: 4.66e-04s
optimal rho estimate: 4.48e-02
iter objective pri res dua res rho time
1 -9.6366e+01 9.60e-01 5.40e+02 1.00e-01 4.55e-05s
25 -1.0095e+02 2.40e-04 2.56e-03 1.00e-01 3.99e-04s
status: solved
number of iterations: 25
optimal objective: -100.9496
run time: 4.37e-04s
optimal rho estimate: 4.34e-02
iter objective pri res dua res rho time
1 -1.0095e+02 2.77e-01 4.91e+02 1.00e-01 8.44e-05s
25 -1.0349e+02 6.00e-05 2.33e-03 1.00e-01 4.41e-04s
status: solved
number of iterations: 25
optimal objective: -103.4940
run time: 4.80e-04s
optimal rho estimate: 3.73e-02
iter objective pri res dua res rho time
1 -1.0349e+02 9.28e-01 5.22e+02 1.00e-01 4.50e-05s
25 -1.0454e+02 2.50e-04 2.47e-03 1.00e-01 3.98e-04s
status: solved
number of iterations: 25
optimal objective: -104.5361
run time: 4.79e-04s
optimal rho estimate: 5.47e-02
zhz@zhzrobot:~/gzrobot_ws$
总结
大功告成了,最后总结一下:
1.osqp库调用
2.Eigen库调用
3.第三方库osqp-eigen库调用
第三方库需要前面两个库作为基础。
我也在网站上面搜索了很多osqp的代码包,但是都不知道该怎么去调用这个库,最后在我师父的帮助下顺利调用,这篇博客也是用来做一个小笔记,同时也是帮助大家了解如何调用第三方库。
如果有什么不对的地方,欢迎指正,有问题也可以给我留言。