ACADO超详细教程!!包学会的!!

花了一整天的时间,终于把acado的例程给跑通了,我整合了一下目前我所能搜到的信息,写一篇博客来记录一下我的使用过程,并把这些和大家分享一下。

这篇博客主要分为4个部分

(1)什么是acado求解库,这个求解库和其他求解库的区别是什么?这部分内容可能只是简单介绍一下,如果有错误,各位大佬可以在评论区补充一下。
(2)第二部分主要是针对Linix系统的acado库的安装。这部分网上也有挺多教程的,不过最好还是跟着官方给的例子进行。
https://acado.github.io/install_linux.html(Linux系统的acado安装教程)
https://acado.sourceforge.net/doc/html/index.html(acado的简介)
https://acado.sourceforge.net/doc/pdf/acado_manual.pdf(acado使用手册)
这是官方提供的文档,还是很详细的。
https://blog.csdn.net/weixin_46479223/article/details/133743263
https://blog.csdn.net/tzr0725/article/details/120632370
https://zhuanlan.zhihu.com/p/635352092
这是在网上参考的相关教程,大家都可以去参考一下。
(3)第三部分主要是讲一下acado库的配置和使用了,这里主要是讲一下使用catkin_make去构建工作空间的情况。
(4)最后一部分是应用一下acado库的其他demo。系统大家看完之后如果觉得有用的话,可以点赞收藏一下,谢谢!!!

一.什么是ACADO工具包?

**
网上查找相关教程可以看到以下相关工具概念 ACADO Toolkit、ACADOS 、Matlab环境下的ACADO ,笔者理解他们是同一个工具的不同扩展,解释如下,以免在学习中不同资料i产生混淆:
ACADO Toolkit:ACADO (Automatic Control and Dynamic Optimization)是一个用于自动控制和动态优化的开源C++库。它提供了一组工具和功能,使用户能够轻松地建立、求解和部署动态优化问题,包括最优控制、模型预测控制(MPC)等。ACADO Toolkit的特点包括符号微分、生成C++代码、支持多种数值优化方法等。它是一个独立的C++库,用户可以直接使用它来建模和求解控制和优化问题。
ACADOS:ACADOS(Automatic Control and Dynamic Optimization Suite)是一个开源的自动控制和动态优化套件,它是建立在ACADO Toolkit的基础上的。ACADOS扩展了ACADO Toolkit的功能,提供了更多的工具和接口,支持多个编程语言,包括C、MATLAB、Python和Julia。ACADOS的目标是为不同领域的研究人员和工程师提供一个更广泛的工具集,以满足不同需求。
ACADO Matlab:ACADO Toolkit还提供了一个专门的MATLAB接口,称为ACADO Matlab。这个接口使MATLAB用户能够使用ACADO Toolkit的功能,尤其是在MATLAB环境中建立和求解动态优化问题。ACADO Matlab提供了与ACADO Toolkit相似的功能,但可以更容易地与MATLAB集成。

类似求解器的优劣:

  1. ACADO
    优点:
    (1)功能强大且灵活:支持多种优化问题,包括最优控制问题(OCP)、非线性模型预测控制(NMPC)、线性模型预测控制(LMPC)等。
    (2)用户友好:提供了高层次的C++接口,便于定义优化问题。
    (3)自动代码生成:可以生成高效的C代码,用于嵌入式系统。
    (4)广泛的文档和示例:提供了详细的文档和丰富的示例代码,有助于快速上手。
    缺点:
    (1)性能有限:在处理大规模或高频率的优化问题时,性能可能不如一些更现代的工具。
    (2)社区支持有限:相比于一些新兴工具,社区活跃度和支持可能较低。

  2. ACADOS
    优点:
    (1)高性能:专为实时优化设计,具有高性能和高效率,适合嵌入式系统。
    (2)现代化:基于现代算法和数据结构,支持多种求解器(如HPIPM、QP_OASES、OSQP等)。
    (3)灵活性:支持多种优化问题,包括OCP、NMPC等,且可以与MATLAB、Python等接口集成。
    (4)活跃的社区和开发:有一个活跃的开发社区,频繁更新和改进。
    缺点
    (1)学习曲线较陡峭:尽管功能强大,但初学者可能需要一些时间来熟悉其API和工作流程。
    (2)文档相对复杂:虽然有详细的文档,但由于功能多样,可能需要更多时间来理解。

  3. qpOASES
    优点:
    (1)专注于QP问题:特别优化用于求解二次规划(QP)问题,性能优异。
    (2)易于集成:轻量级,易于集成到各种应用中,包括嵌入式系统。
    (3)实时性能:设计初衷是为实时应用提供高效的QP求解器。
    缺点
    (1)仅限于QP问题:只能求解QP问题,不支持其他类型的优化问题(如非线性规划)。
    (2)功能相对单一:不如其他工具那么多功能和灵活。

  4. OSQP
    优点:
    (1)开源和高效:开源项目,专注于快速求解二次锥规划(QCP)问题,性能优异。
    (2)鲁棒性:采用ADMM算法,具有良好的鲁棒性和稳定性。
    (3)易于使用:提供了简单易用的API,支持多种编程语言(如C、Python等)。
    (4)活跃的社区:有一个活跃的开发和用户社区,持续更新和改进。
    缺点:
    (1)仅限于QP和QCP问题:虽然性能强大,但功能范围有限,只能求解QP和QCP问题。
    (2)文档相对简单:虽然文档齐全,但对于复杂应用场景可能需要更多的用户探索。

  5. Control Toolbox (CT)
    优点:
    (1)全面的控制工具集:提供了广泛的控制算法和工具,包括线性和非线性控制、优化、仿真等。
    (2)模块化设计:设计灵活,模块化强,易于扩展和集成。
    (3)实时性:优化了实时控制性能,适合嵌入式和实时应用。
    (4)丰富的文档:提供详细的文档和示例代码,支持快速上手。
    缺点
    (1)复杂性:功能全面,但对于初学者来说,可能会显得过于复杂。
    (2)性能依赖于具体实现:实际性能可能依赖于具体的实现和配置,可能需要一定的调优。

  6. CasADi
    优点
    (1)符号计算和自动微分:CasADi 擅长符号计算和自动微分,能够自动生成高效的导数计算代码,这对于优化问题尤其重要。
    (2)灵活性:支持多种优化问题,包括非线性规划(NLP)、二次规划(QP)、微分代数方程(DAE)等。
    (3)接口丰富:提供了Python和C++接口,方便不同用户的需求。
    (4)集成求解器:可以与多种求解器(如 IPOPT、SNOPT、qpOASES)集成使用,用户可以根据需求选择最合适的求解器。
    (5)良好支持:有一个活跃的开发社区和详细的文档,便于用户学习和使用。
    缺点
    (1)性能依赖于外部求解器:CasADi 本身并不是一个求解器,而是一个工具包,求解性能主要依赖于所选的外部求解器。
    (2)学习曲线:对于初学者来说,可能需要一些时间来熟悉其符号计算和自动微分的机制。

  7. IPOPT (Interior Point OPTimizer)
    优点
    (1)强大的非线性优化:IPOPT 是一个高效的非线性规划(NLP)求解器,适用于大规模优化问题。
    (2)稳健性:对于多种复杂的非线性问题具有良好的稳健性和收敛性。
    (3)广泛应用:在控制、经济学、工程等领域有广泛应用。
    缺点
    (1)依赖线性求解器:IPOPT 的性能依赖于所使用的线性求解器(如MA27、MA57等),这些线性求解器可能需要单独安装和配置。
    (2)不支持混合整数规划:IPOPT 仅支持连续优化问题,不支持混合整数规划(MIP)。

这部分只是一些简单的介绍了,然后在网上收索资料的过程中,有看到知乎评论里聊到Acado停止了维护,CasADi很多人在用,但是Acado的求解速度比CasADi快,这里还没有一一对比求证以上消息,仅供参考也欢迎大家留言交流,未来研究一下其他求解器。

二.Acado的安装

这里有官网的详细的安装过程,我这里也是直接按照官网的步骤来进行,使用的是ubuntu20.04的版本。
https://acado.github.io/install_linux.html

2.1首先,需要通过 apt-get 包管理器下载一些包(您需要 root 权限):

sudo apt-get install gcc g++ cmake git gnuplot doxygen graphviz

Gnuplot, Doxygen and Graphviz 不是必须的,但是为了可视化和生成API,故推荐安装

2.2 下载源码

git clone https://github.com/acado/acado.git -b stable ACADOtoolkit

这里官网有两个版本,一般推荐的是使用stable的版本。 如果这个代码安装不了的话,就去上面的官网链接下载。
在这里插入图片描述
2.3编译
和安装其他求解库一样,在ACADOtoolkit功能包目录下建一个build文件夹,在其中进行操作编译。

cd ACADOtoolkit
mkdir build
cd build
cmake ..
make
sudo make install  

这里补充一下最后一步sudo make install的作用,虽然官网没有用上,但是安装其他求解库一般是会用上的,使用 sudo 提升权限,运行 make install 命令,可以将编译好的文件复制到系统的标准目录中。

sudo make install 是一个常见的步骤。它的主要目的是将编译好的程序、库文件和相关资源安装到系统的标准位置。
sudo make install 的目的
(1)安装编译好的文件:
将编译好的二进制文件(如可执行文件、库文件)复制到系统的标准目录(如 /usr/local/bin, /usr/local/lib)。
安装过程中会将库文件放置在 /usr/local/lib,头文件放置在 /usr/local/include,可执行文件放置在 /usr/local/bin,以及其他资源文件放置在相应的目录中。
(2)设置权限:
使用 sudo 命令以超级用户(root)权限运行 make install,确保有权限将文件复制到系统的受保护目录中。
一般用户对这些系统目录没有写权限,所以需要使用 sudo 来提升权限。
(3)配置环境:
安装过程中可能会执行一些脚本来配置系统环境,如更新共享库缓存(ldconfig),添加环境变量等。
完成编译之后,ACADOtoolkit包的内容大概如下:

在这里插入图片描述2.4 检查测试
可以使用自带的范例测试,范例文件夹下有很多参考供研究,我这里还是按照官网的给的案例来运行。

cd ..
cd examples/getting_started
./simple_ocp

具体的运行效果如下,如果能够成功运行,那就说明你已经安装成功了。
在这里插入图片描述在这里插入图片描述在这里插入图片描述

如果你还想测试一下其他的例程可以允许一下其他的示例源文件:
在这里插入图片描述

三.Acado的使用

3.1 刷新环境变量
首先我们需要将Acado的库加入系统变量里面,方便以后使用,操作和所有加path一样,将:

source <YourAcadoPath>/build/acado_env.sh

YourAcadoPath,这个得子行去查看该文件的路径。然后加入到根目录.bashrc下,最后使用下面的指令刷新一下:

. ~/.bashrc

3.2 功能包的创建
(1)创建工作空间并初始化

mkdir -p Acado_ws/src
cd Acado_ws
catkin_make

上述命令,首先会创建一个工作空间以及一个 src 子目录,然后再进入工作空间调用 catkin_make命令编译。
(2)进入 src 创建 ros 包并添加依赖

cd src
catkin_create_pkg acado_test roscpp rospy std_msgs geometry_msgs

上述命令,会在工作空间下生成一个功能包,该功能包依赖于 roscpp、rospy 与 std_msgs,其中roscpp是使用C++实现的库,而rospy则是使用python实现的库,std_msgs是标准消息库,创建ROS功能包时,一般都会依赖这三个库实现。

然后就可以正常建立工程文件目录,结构如图,其中红框中的文件必须要放置,否则编译如下的cmakelsit时候会报找不到一些文件,它在/cmake/FindACADO.cmake中
在这里插入图片描述
在ACODO/camke里找到FindACADO.cmake,放进你的工程包Acado_ws里面,然后新建一个cmake用于存放FindACADO.cmake。
在这里插入图片描述

3.3 CMakeLists的配置

然后是配置cmakelist,大家关注acado相关的内容即可,尤其是这一行增加了检索路径,去找到我们拷贝的cmake文件

set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR} ) 

最后我的CMakeLists.txt文件的配置如下:

cmake_minimum_required(VERSION 3.0.2)	// cmake_minimum_required(VERSION 3.0.2):指定所需的CMake最低版本为3.0.2。
project(acado_test)					// project(acado_test):定义项目名称为 acado_test。


find_package(Eigen3 REQUIRED)		// 查找并加载 Eigen3 库,这是一个用于线性代数计算的C++库。
find_package(ACADO REQUIRED) 		// 查找并加载 ACADO 工具包,这是一个用于优化控制的工具库。

// 将项目根目录添加到 CMake 模块路径中。这可以使得 CMake 在该目录中查找自定义的模块文件。
SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR} ) 	

//查找并加载 Catkin 工具包以及所需的 ROS 组件
//包括 roscpp(C++接口)、rospy(Python接口)、std_msgs(标准消息类型)和 geometry_msgs(几何消息类型)。
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  geometry_msgs
)

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES acado_test
#  CATKIN_DEPENDS roscpp rospy std_msgs
#  DEPENDS system_lib
)

include_directories(
  include
  ${catkin_INCLUDE_DIRS}
  ${EIGEN3_INCLUDE_DIRS}
  ${ACADO_INCLUDE_DIRS}		// ACADO 工具包的头文件目录。
)

// 可执行文件,每个文件对应一个源文件。
add_executable(test_acado src/test_acado.cpp)
add_executable(main src/main.cpp)
add_executable(MPC src/MPC.cpp)

// 为每个可执行文件指定需要链接的库文件。
target_link_libraries(test_acado
  ${catkin_LIBRARIES}				// Catkin 包的库文件
  ${ACADO_SHARED_LIBRARIES}			// ACADO 工具包的共享库文件。
)
target_link_libraries(main
  ${catkin_LIBRARIES}
  ${ACADO_SHARED_LIBRARIES}
)
target_link_libraries(MPC
  ${catkin_LIBRARIES}
  ${ACADO_SHARED_LIBRARIES}
)

3.4 简单实例

例子1:以最优控制问题官方示例src举例:火箭以最小时间走完。(我存放在了main.cpp)

#include <acado_toolkit.hpp>
#include <acado_gnuplot.hpp>

int main()
{
    USING_NAMESPACE_ACADO

    DifferentialState s, v, m; // 微分状态量
    Control u;
    Parameter T;
    DifferentialEquation f(0.0, T);

    // ----------------------------
    OCP ocp(0.0, T);
    ocp.minimizeMayerTerm(T);

    f << dot(s) == v;
    f << dot(v) == (u - 0.2 * v * v) / m;
    f << dot(m) == -0.01 * u * u;

    ocp.subjectTo(f);
    // 状态初始化
    ocp.subjectTo(AT_START, s == 0.0);
    ocp.subjectTo(AT_START, v == 0.0);
    ocp.subjectTo(AT_START, m == 1.0);
    // 终止条件约束
    ocp.subjectTo(AT_END, s == 10.0);
    ocp.subjectTo(AT_END, v == 0.0);
    // 其他条件约束
    ocp.subjectTo(-0.1 <= v <= 1.7);
    ocp.subjectTo(-1.1 <= u <= 1.1);
    ocp.subjectTo(5.0 <= T <= 15.0);

    //------------------------------
    GnuplotWindow window; // 在窗口中结果可视化
    window.addSubplot(s, "DISTANCE s");
    window.addSubplot(v, "VELOCITY v");
    window.addSubplot(m, "MASS m");
    window.addSubplot(u, "CONTROL u");

    OptimizationAlgorithm algorithm(ocp); // 构建优化算法
    algorithm << window;
    algorithm.solve();

    return 0;
}

写完main函数之后就保存,然后通过catkin_make去编译,然后通过rosrun去运行,具体代码如下:

cd Acado_ws/
catkin_make
source ./devel/setup.bash	// 刷新环境变量
rosrun acado_test main

运行后出现下面的窗口就说明成功了!!这和我们一开始的测试代码是一致的。
在这里插入图片描述
在这里插入图片描述

例子2:MPC控制器
令 x 表示状态,u 表示控制输入,pa 表示时间常数参数,T 表示 MPC 优化问题的时间范围。我们感兴趣的是跟踪 MPC 问题,其一般形式为:
在这里插入图片描述
这里,函数 f 表示模型方程,s 表示路径约束,r 表示终端约束。请注意,在线情况下,必须迭代解决上述问题以改变 x0 和 t0 。此外,我们在此假设目标以最小二乘形式给出。实践中出现的大多数跟踪问题都可以用这种形式来表示,其中 η 和 μ 表示跟踪和终端参考。

具体代码如下,存放在(MPC.cpp):

#include <acado_toolkit.hpp>
#include <acado_gnuplot.hpp>

using namespace std;

USING_NAMESPACE_ACADO

int main( )
{
    // INTRODUCE THE VARIABLES:
    // -------------------------
	DifferentialState xB;
	DifferentialState xW;
	DifferentialState vB;
	DifferentialState vW;

	Control R;
	Control F;

	double mB = 350.0;
	double mW = 50.0;
	double kS = 20000.0;
	double kT = 200000.0;


    // DEFINE A DIFFERENTIAL EQUATION:
    // -------------------------------
    DifferentialEquation f;// 创建微分方程

	f << dot(xB) == vB;
	f << dot(xW) == vW;
	f << dot(vB) == ( -kS*xB + kS*xW + F ) / mB;
	f << dot(vW) == (  kS*xB - (kT+kS)*xW + kT*R - F ) / mW;


    // DEFINE LEAST SQUARE FUNCTION:
    // -----------------------------
    Function h;
//函数 h 用于定义最小二乘(Least Squares)问题中的cost函数
//平方和并没有在 h 中直接计算,而是在优化问题的目标函数中由 ocp.minimizeLSQ(Q, h, r) 执行。这个函数会将这些项加权并计算它们的平方和,其中权重由矩阵 Q 控制。也就是典型的最小二乘带权重,ps 推荐下bilibili老王和DR. Can 视频,最优估计,最优控制,机器学习感觉很多理论共用。
    h << xB;
    h << xW;
	h << vB;
    h << vW;

    DMatrix Q(4,4);
    Q.setIdentity();
	Q(0,0) = 10.0;
	Q(1,1) = 10.0;
//参考值 ,量测值或者 可观测值转为对应状态量测值
    DVector r(4);
    r.setAll( 0.0 );


    // DEFINE AN OPTIMAL CONTROL PROBLEM:
    // ----------------------------------
    const double t_start = 0.0;
    const double t_end   = 1.0;

    OCP ocp( t_start, t_end, 20 );
    // 这里设置了步长20,则实际求解间隔为1/20 =0.05,可以从我截图的红框内看出
    //换一句话说0.05 即为mpc根据状态空间方程外推下一步状态的时长
    ocp.minimizeLSQ( Q, h, r );
// 这里不再使用mayer,使用了最小二乘作为cost函数

//   Q:权重矩阵,用于调整每个目标项的相对重要性。
//   h:目标函数的描述。
//   r:期望的目标值。
	ocp.subjectTo( f );

	ocp.subjectTo( -500.0 <= F <= 500.0 );
	ocp.subjectTo( R == 0.0 );
//笔者认为这里mpc设置已经ok,后续在设置仿真环境


    // SETTING UP THE (SIMULATED) PROCESS:
    // -----------------------------------
	OutputFcn identity;
	//创建了一个名为 identity 的输出函数对象。输出函数通常用于记录系统状态和控制输入的信息
	DynamicSystem dynamicSystem( f,identity );
	//创建了一个名为 dynamicSystem 的动态系统对象,它用于描述系统的动态行为。
	//它需要两个参数:    f:前面定义的微分方程对象,用于描述系统的状态变化。    identity:前面创建的输出函数对象,用于记录系统状态和控制输入。
	Process process( dynamicSystem,INT_RK45 );
	//创建了一个名为 process 的进程对象,用于模拟系统的行为。它需要两个参数:
//  dynamicSystem:前面创建的动态系统对象,用于描述系统的动态行为. INT_RK45:表示使用4/5阶Runge-Kutta积分器进行系统模拟

    // SETTING UP THE MPC CONTROLLER:
    // ------------------------------
	RealTimeAlgorithm alg( ocp,0.05 );
	//建立算法对象
	// 这里有一个值得注意的点
	//RealTimeAlgorithm alg(ocp, 0.05); 也就是这里的0.05是执行一次ocp对象,也就是我们mpc算法的时间间隔
	//而之前的OCP ocp(0,1, 20) 恰好也是0.05的时间长度,但他是一次mpc过程中,滚动迭代的小周期,也是利用状态方程外推下一步状态的时间步长。
	//0到1的1秒时间长度为我的mpc的预测优化时域

	DVector x0(4);
	x0(0) = 0.01;
	x0(1) = 0.0;
	x0(2) = 0.0;
	x0(3) = 0.0;
	//初始化输出向量
	alg.set( MAX_NUM_ITERATIONS, 2 );
	

//以下应该是是demo用来仿真的代码,建立controller和一些设置作图给用户展示,不再研究
	StaticReferenceTrajectory zeroReference;

	Controller controller( alg,zeroReference );


    // SETTING UP THE SIMULATION ENVIRONMENT,  RUN THE EXAMPLE...
    // ----------------------------------------------------------
	SimulationEnvironment sim( 0.0,3.0,process,controller );


	if (sim.init( x0 ) != SUCCESSFUL_RETURN)
		exit( EXIT_FAILURE );
	if (sim.run( ) != SUCCESSFUL_RETURN)
		exit( EXIT_FAILURE );

    // ...AND PLOT THE RESULTS
    // ----------------------------------------------------------
	VariablesGrid sampledProcessOutput;
	sim.getSampledProcessOutput( sampledProcessOutput );

	VariablesGrid feedbackControl;
	sim.getFeedbackControl( feedbackControl );

	GnuplotWindow window;
	window.addSubplot( sampledProcessOutput(0), "Body Position [m]" );
	window.addSubplot( sampledProcessOutput(1), "Wheel Position [m]" );
	window.addSubplot( sampledProcessOutput(2), "Body Velocity [m/s]" );
	window.addSubplot( sampledProcessOutput(3), "Wheel Velocity [m/s]" );
	window.addSubplot( feedbackControl(1),      "Damping Force [N]" );
	window.addSubplot( feedbackControl(0),      "Road Excitation [m]" );
	window.plot( );

    return EXIT_SUCCESS;
}

编译后运行也是一样的步骤

cd Acado_ws/
catkin_make
source ./devel/setup.bash	// 刷新环境变量
rosrun acado_test MPC

效果如下:

4.生成代码

具体步骤也是参考官方提供的例程:

这里将详细描述如何设置一个简单的示例,并使用 ACADO 代码生成工具 (CGT) 为 NMPC 应用程序生成优化代码。我们还概述了如何运行生成的代码。
4.1问题描述

我们考虑以下教程示例:一台起重机,其质量为 m m m ,线长为 L L L,激励角度为 ϕ \phi ϕ,水平小车位置为 p p p。我们的控制输入是小车的加速度 a a a v v v为小车速度, ω \omega ω为质点的角速度,该系统可以用一个简单但非线性的微分方程系统来描述:
在这里插入图片描述
其中 b b b= 0.2J , s s s是正阻尼常数,我们使用参数 m m m= 1 千克、 L L L= 1m,和 g g g= 9.81 * m / s^2。
我们的目标是反复解决以下最优控制问题(OCP):
在这里插入图片描述
其中 F ( ⋅ ) F(\cdot) F,描述前面描述的离散系统动力学。为简单起见,我们将定义参考函数如下:
在这里插入图片描述

以及加权矩阵 W = I 5 W = I_5 W=I5, W N = 5 ⋅ I 4 W_N = 5 \cdot I_4 WN=5I4。对于此示例,我们选择使用$N = 10 控制(预测)间隔和采样时间 控制(预测)间隔和采样时间 控制(预测)间隔和采样时间T_s = 0.3s。

生成代码
大纲
为了使用 CGT 为本教程示例生成优化代码,需要执行以下步骤:
(1)设置一个源文件,使用 ACADO 语法描述您的非线性 MPC 问题,定义所需选项并为导出的代码指定目标目录。编译此源文件。
(2)运行编译的源文件,将代码(即完整的非线性 MPC 算法)导出到目标目录中。
(3)如果您使用qpOASES QP 求解器,则需要将求解器源代码文件复制到导出文件夹中,更准确地说,复制到子文件夹 qpoases 中。
我们现在将详细描述这些步骤。

4.2 用代码描述你的求解问题
首先制定非线性 MPC 问题
现在我们将逐步讨论上面问题描述的可能的非线性 MPC 公式。完整源代码也可在找到examples/code_generation/getting_started.cpp。有关 ACADO 语法的更多详细信息,请参阅 ACADO 用户手册。
全部代码如下,存放在test_acado.cpp :

//---------------------code generator---------------------
#include <acado_toolkit.hpp>

int main()
{

 USING_NAMESPACE_ACADO

    // Variables:
 DifferentialState p;     // the trolley position
 DifferentialState v;     // the trolley velocity
 DifferentialState phi;   // the excitation angle
 DifferentialState omega; // the angular velocity
 Control a;               // the acc. of the trolley

 const double g = 9.81; // the gravitational constant
 const double b = 0.20; // the friction coefficient

    // Model equations:
 DifferentialEquation f;

 f << dot(p) == v;
 f << dot(v) == a;
 f << dot(phi) == omega;
 f << dot(omega) == -g * sin(phi) - a * cos(phi) - b * omega;

    // Reference functions and weighting matrices:
 Function h, hN;
 h << p << v << phi << omega << a;
 hN << p << v << phi << omega;

 DMatrix W = DMatrix::Identity(h.getDim(), h.getDim());
 DMatrix WN = DMatrix::Identity(hN.getDim(), hN.getDim());
 WN *= 5;

 std::cout << "W" << std::endl;
 std::cout << W << std::endl;

 std::cout << "h.getDim()" << std::endl;
 std::cout << h.getDim() << std::endl;

 std::cout << "WN" << std::endl;
 std::cout << WN << std::endl;

    //
    // Optimal Control Problem
    //
 OCP ocp(0.0, 3.0, 10);

 ocp.subjectTo(f);

 ocp.minimizeLSQ(W, h);
 ocp.minimizeLSQEndTerm(WN, hN);

 ocp.subjectTo(-1.0 <= a <= 1.0);
 ocp.subjectTo(-0.5 <= v <= 1.5);

    // Export the code:
 OCPexport mpc(ocp);

 mpc.set(HESSIAN_APPROXIMATION, GAUSS_NEWTON);
 mpc.set(DISCRETIZATION_TYPE, SINGLE_SHOOTING);
 mpc.set(INTEGRATOR_TYPE, INT_RK4);
 mpc.set(NUM_INTEGRATOR_STEPS, 30);

 mpc.set(QP_SOLVER, QP_QPOASES);
 mpc.set(GENERATE_TEST_FILE, YES);
 mpc.set(GENERATE_MAKE_FILE, YES);
 mpc.set(GENERATE_MATLAB_INTERFACE, YES);
 mpc.set(GENERATE_SIMULINK_INTERFACE, YES);

 if (mpc.exportCode("getting_started_export") != SUCCESSFUL_RETURN)
 exit(EXIT_FAILURE);

 mpc.printDimensionsQP();

 return EXIT_SUCCESS;
}

4.3 编译生成代码
还是相同的步骤,写好代码后通过下面步骤编译生成代码

cd Acado_ws/
catkin_make
source ./devel/setup.bash	// 刷新环境变量
rosrun acado_test test_acado

运行后会出现下面的情况:

在这里插入图片描述
然后就会新增加了一个功能包getting_started_export
在这里插入图片描述
然后我们设定使用qpoases求解,所以需要在在安装ACADOtoolkit的地方找到external_packages/qpoases,然后将他放进我们新增加的getting_started_export功能包里
在这里插入图片描述
在这里插入图片描述
然后进入到getting_started_export里面,因为里面有个Makefile,我们可以直接make 来编译这个makefile,完成输出。

cd Acado_ws/getting_started_export/
make

在这里插入图片描述
然后他就会生成对应的test可执行文件,我们运行一下,以下即为刚才print的结果们:

./test

下面就是打印的结果了。
在这里插入图片描述

到此已经完成所有案例的实现了,写到这里也接近16000多字了,因为也是刚刚复现了一下acado的使用,只是为了记录一下,还存在很多不动的地方,后续还会继续在实际使用中发现更多的问题,如果你看到了这里,也麻烦能给个点赞或者收藏一下吧,有其他问题也可以在评论区讨论一下。

  • 11
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值