基于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代码中进行代码修改,这也是后续的工作量。 

  • 15
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【资源说明】 1、该资源包括项目的全部源码下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 3、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 基于python的公交换乘系统源码+示例图片(求解最短路径,最少换乘问题).zip 基于python的公交换乘系统源码+示例图片(求解最短路径,最少换乘问题).zip 基于python的公交换乘系统源码+示例图片(求解最短路径,最少换乘问题).zip 基于python的公交换乘系统源码+示例图片(求解最短路径,最少换乘问题).zip 基于python的公交换乘系统源码+示例图片(求解最短路径,最少换乘问题).zip 基于python的公交换乘系统源码+示例图片(求解最短路径,最少换乘问题).zip 基于python的公交换乘系统源码+示例图片(求解最短路径,最少换乘问题).zip 基于python的公交换乘系统源码+示例图片(求解最短路径,最少换乘问题).zip 基于python的公交换乘系统源码+示例图片(求解最短路径,最少换乘问题).zip 基于python的公交换乘系统源码+示例图片(求解最短路径,最少换乘问题).zip 基于python的公交换乘系统源码+示例图片(求解最短路径,最少换乘问题).zip 基于python的公交换乘系统源码+示例图片(求解最短路径,最少换乘问题).zip
基于动态规划的鲁棒最优控制是一个比较复杂的算法,需要深厚的数学和控制理论基础。这里提供一个简单的案例,仅供参考: 假设有一个传送带系统,传送带上有不同种类的物品,需要通过控制传送带的速度来实现物品的分类和分拣。传送带的速度可以通过控制电机的转速来实现,但电机的转速受到外界环境的干扰,因此需要设计一个鲁棒最优控制器。 首先,将传送带的速度控制问题建立数学模型,可以得到控制系统的状态方程和性能指标。然后,使用动态规划算法进行求解,得到最优控制策略。最后,将最优控制策略转换为具体的控制算法,并在实际系统中进行实现和测试。 以下是一个简单的基于动态规划的鲁棒最优控制案例的源码(MATLAB实现): ```matlab % 传送带速度控制系统鲁棒最优控制 clc clear % 系统参数 Ts = 0.01; % 采样时间 m = 1; % 电机质量 b = 0.1; % 阻尼系数 g = 9.8; % 重力加速度 k1 = 1; % 电机增益 k2 = 1; % 电机增益 A = [0 1; 0 -b/m]; B = [0; k1/m]; C = [k2 0]; D = 0; % 性能指标 Q = [1 0; 0 0.1]; % 状态权重矩阵 R = 0.1; % 控制权重矩阵 % 鲁棒性能指标 delta = 0.1; % 不确定性幅值 rho = 0.2; % 稳定裕度 W = [1/delta^2 0; 0 rho^2]; % 不确定性权重矩阵 % 状态空间模型 sys = ss(A,B,C,D); % 离散化 sysd = c2d(sys,Ts); % 动态规划求解最优控制策略 [K,P,~] = dlqr(sysd.A,sysd.B,Q,R); % 鲁棒最优控制器参数计算 P1 = [Q zeros(2,1); zeros(1,2) 0]; P2 = [zeros(2,1); 1]'*P*W*[zeros(2,1); 1]; P3 = [zeros(2,1); 1]'*P*W*[zeros(2,1); 1]; P4 = [zeros(2,1); 1]'*(P+W)^(-1)*[zeros(2,1); 1]; alpha = P2/P4; beta = P3/P4; Krobust = K + (alpha/beta)*W*[zeros(2,1); 1]'*K; % 仿真测试 t = 0:Ts:10; x0 = [0.1; 0]; u0 = 0; x = zeros(2,length(t)); u = zeros(1,length(t)); x(:,1) = x0; u(1) = u0; for i = 2:length(t) x(:,i) = sysd.A*x(:,i-1) + sysd.B*Krobust*(x(:,i-1)-[1;0]) + delta*randn(2,1); u(i) = Krobust*(x(:,i)-[1;0]); end % 结果可视化 figure subplot(2,1,1) plot(t,x(1,:),'b',t,x(2,:),'r') legend('位置','速度') xlabel('时间') ylabel('状态') subplot(2,1,2) plot(t,u,'b') xlabel('时间') ylabel('控制输入') ``` 需要注意的是,该代码仅为基于动态规划的鲁棒最优控制的简单实现,不能直接用于实际工程中。如果您需要更具体的帮助或指导,可以提供更详细的问题描述,我会尽力为您解答。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值