基于Bocop核心源码+CppAD+ipopt 求解最优控制问题

这里的最优控制问题参考的是伪谱法处理优化问题,参考下面这个链接:

数值法求解最优控制问题(四)——伪谱法-CSDN博客

在matlab中有NLP问题的求解器fmincon,可以用来求解伪谱法离散之后的非线性规划问题,但是伪谱法离散的程序需要自己编写。另外有求解器GPOPS2也能利用伪谱法处理最优控制问题,但是速度比较慢,而且gpops的求解器核心也是ipopt,为了加快求解速度,抛弃matlab来使用求解器。我选择基于bocop的核心源码来完成自定义求解器。

GPOPS2使用参考:
用GPOPS2解最优控制问题-CSDN博客

c++求解器Bocop链接:
control-toolbox/bocop: Bocop 3 (github.com)

求解器Bocop的学习笔记如下:
最优控制工具箱Bocop学习笔记(一)——下载与安装 - 知乎 (zhihu.com)

求解器依赖的两个库,一个自动微分工具CppAD,一个是内点法求解器ipopt,这两个库的链接和安装参考如下:
CppAD/cppad_ipopt at master · coin-or/CppAD (github.com)
coin-or/Ipopt: COIN-OR Interior Point Optimizer IPOPT (github.com)
Linux | Ubuntu 20.04安装ipopt和cppAD | 安装全流程+报错解决_csdn ipopt anzhaung-CSDN博客

注:cppad库的安装比较简单,而ipopt安装相对复杂,需要安装其他的依赖,例如线性求解器MUMPS,要多尝试几种方法,但是我推荐安装方法使用coinbrew安装。下列指令仅供参考:
安装依赖:

sudo apt-get install gcc g++ gfortran cmake git patch wget pkg-config liblapack-dev libblas-dev

下载coinbrew脚本和修改权限:

wget https://raw.githubusercontent.com/coin-or/coinbrew/master/coinbrew
chmod u+x coinbrew

克隆ipopt库:

./coinbrew fetch Ipopt

配置ipopt,我这里选择的线性求解器是mumps,也可以选择HSL,将Ipopt安装到/usr/local目录,安装目录很重要,一般都是这个:

./coinbrew build Ipopt --prefix=/usr/local --test --enable-linear-solver=mumps

接下来新建项目bocopcore,拖入bocop的核心源码src,添加一个例子goddard,抛弃了bocop的gui界面。

重写main.cpp:


/** ********************************************************************
* \mainpage Bocop3 main workflow
*
* create OCP and initialize from .def file
*
* create dOCP from OCP
*
* create NLPSolver (Ipopt)
*
* call solve() from NLPSolver
*
* **********************************************************************/

#include <iostream>
#include "OCP.h"
#include "dOCPCppAD.h"
#include "NLPSolverIpopt.h"

int main(int argc, char **argv) {
    OCP *myocp = new OCP();
    myocp->initialize();

    // Assume the problem definition file is named 'problem.def'
    std::string definition_file = (argc > 1) ? argv[1] : "problem.def";
    myocp->load(definition_file);

    // Initialize the derived OCP class which is designed to handle the specific Goddard problem
    dOCPCppAD *mydocp = new dOCPCppAD();
    mydocp->setOCP(myocp);
    mydocp->initialize();

    // Initialize the solver
    NLPSolver *mysolver = new NLPSolverIpopt();
    mysolver->setNLP(mydocp);
    mysolver->setOptions(myocp->getDefinitionMap());

    // Solve the problem
    mysolver->solve();

    // Cleanup
    delete myocp;
    delete mydocp;
    delete mysolver;

    return 0;
}

重写cmake文件:

cmake_minimum_required(VERSION 3.16)
project(bocopcorelib)

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 包含目录
include_directories(${CMAKE_SOURCE_DIR})
include_directories(AD DOCP NLP OCP tools goddard)

# 手动包含 CppAD 和 IPOPT 目录
include_directories(/usr/local/include/cppad)  # CppAD 的头文件路径
include_directories(/usr/local/include/coin-or)  # IPOPT 的头文件路径

# 寻找 CppAD 库
find_library(CPPAD_LIBRARY NAMES cppad_lib HINTS /usr/local/lib)

# 寻找 IPOPT 库
find_library(IPOPT_LIBRARY NAMES ipopt HINTS /usr/local/lib)

# 检查库是否找到
if(NOT CPPAD_LIBRARY)
    message(FATAL_ERROR "Cannot find cppad library")
endif()

if(NOT IPOPT_LIBRARY)
    message(FATAL_ERROR "Cannot find ipopt library")
endif()

# 源文件列表
set(SOURCES
    AD/dOCPCppAD.cpp
    DOCP/dOCP.cpp
    DOCP/dODE.cpp
    DOCP/dControl.cpp
    DOCP/dState.cpp
    DOCP/solution.cpp
    NLP/NLPSolverIpopt.cpp
    OCP/OCP.cpp
    tools/tools.cpp
    tools/tools_interpolation.cpp
    goddard/problem.cpp
)

# 添加动态库目标
add_library(bocopcore SHARED ${SOURCES})
target_link_libraries(bocopcore ${IPOPT_LIBRARY} ${CPPAD_LIBRARY})

# 添加主程序可执行文件
add_executable(bocop_solver main.cpp)
target_link_libraries(bocop_solver bocopcore ${IPOPT_LIBRARY} ${CPPAD_LIBRARY})

在文件目录下新建build,编译链接项目,即可得到可执行程序:bocop_solver

求解结果: 

本文最重要的是在c++下求解复杂的最优控制问题。后续可以修改代码中的problem文件和代码,更改为自己的最优控制或者轨迹优化问题,进行求解。但是bocop采用的配点方法是梯形法、龙格库达、三阶高斯方法;如果想要更改为LGL、CGL等配点方法,需要在dOCP代码中进行代码修改,这也是后续的工作量。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值