CasADi库C++用法整理学习---以NMPC代码为例

参考几个使用方法博客
1
官方文档写的很清楚

对SM,DM,XM数据类型疑惑。什么时候使用什么样的类型,还是都可以?

x = MX.sym(“x”)
这将创建一个 1×1 矩阵,即一个包含名为 x 的符号基元的标量。这只是显示名称,而不是标识符。多个变量可以具有相同的名称,但仍然不同。identifier 是返回值。您还可以通过向 SX.sym 提供其他参数来创建向量值或矩阵值符号变量:

在这里插入图片描述
在这里插入图片描述

#include <casadi/casadi.hpp>
using namespace casadi;
int main() {SX x = SX::sym("x");SX y = SX::sym("y",5);SX Z = SX::sym("Z",4,2)SX f = pow(x,2) + 10;f = sqrt(f);std::cout << "f: " << f << std::endl;return 0;
}//sqrt((10+sq(x)))

DM 与 SX 非常相似,但不同之处在于非零元素是数值,而不是符号表达式。语法也是相同的,除了 SX.sym 等函数没有等效项。
DM 主要用于将矩阵存储在 CasADi 中,并用作函数的输入和输出。它不用于计算密集型计算。

MX 类型允许像 SX 一样构建由一系列基本操作组成的表达式。但与 SX 不同的是,这些初等运算并不局限于标量一元或二进制运算(R→R 或 R×R→R)。相反,用于形成 MX 表达式的基本运算可以是通用的多个稀疏矩阵值输入、多个稀疏矩阵值输出函数:Rn1×m1×…×RnN×mN→Rp1×q1×…×RpM×qM

  • SX和,MX两者对比
    在这里插入图片描述
    在这里插入图片描述

请注意,结果仅包含使用 MX 符号的两次运算(一次乘法和一次加法),而 SX 等效项则有八次运算(结果矩阵的每个元素两次)。因此,在处理具有许多元素的自然向量或矩阵值运算时,MX 可能更经济。
不能将 SX 对象与 MX 对象相乘,也不能执行任何其他操作来在同一表达式图中混合两者。但是,您可以在 MX 图中包含对 SX 表达式定义的 Function 的调用。

MPC 代码
注意:opti.subject_to,opti.minimize,MX::mtimes,opti.variable,opti.parameter都是怎么用的
总的来说:

opti.variable: 定义变量。
opti.parameter: 定义参考值,已知的常量。
opti.set_value: 设置参数的具体值。
opti.minimize: 定义目标函数。
opti.subject_to: 添加约束条件。
MX::mtimes: 执行矩阵乘法。
#include "mpc_tracking/mpc.h"Mpc::Mpc() {N_ = 10;dt_ = 0.1;u_max_ = 1;w_max_ = 0.5;vector<double> weights = {1,1,1,2,2}; //Q,Ru_min_ = - u_max_;w_min_ = - w_max_;Q_ = DM::zeros(3,3); //索引之前初始化sizeR_ = DM::zeros(2,2);setWeights(weights);kinematic_equation_ = setKinematicEquation();
}
Mpc::~Mpc() {}void Mpc::setWeights(vector<double> weights) {//cout << "setweights" << endl;Q_(0, 0) = weights[0];Q_(1, 1) = weights[1];Q_(2, 2) = weights[2];R_(0, 0) = weights[3];R_(1, 1) = weights[4];//R_(2, 2) = weights[5];//cout << "set weight finish" << endl;}Function Mpc::setKinematicEquation() {//cout << "set kinematic" << endl;MX x = MX::sym("x");MX y = MX::sym("y");MX theta = MX::sym("theta");MX state_vars = MX::vertcat({x, y, theta});  //将状态变量组合成一个垂直向量(列向量)。MX v = MX::sym("v");MX w = MX::sym("w");MX control_vars = MX::vertcat({v, w});  //控制变量control_vars是一个包含两个元素的垂直向量,分别是v(线速度)和w(角速度)//rhs means right hand sideMX rhs = MX::vertcat({v * MX::cos(theta), v * MX::sin(theta), w}); // 动力学方程return Function("kinematic_equation", {state_vars, control_vars}, {rhs});// MX x = MX::sym("x");// MX y = MX::sym("y");// MX theta = MX::sym("theta");// MX state_vars = MX::vertcat({x, y, theta});// MX u = MX::sym("u");// MX v = MX::sym("v");// MX w = MX::sym("w");// MX control_vars = MX::vertcat({u, v, w});// MX rhs = u * MX::cos(theta) - v * MX::sin(theta); //这个方程描述了一个更复杂的非线性系统,例如四轮独立驱动的车辆或具有横向控制输入的系统// rhs = MX::vertcat({rhs, u * MX::sin(theta) + v * MX::cos(theta), w});// return Function("kinematic_equation", {state_vars, control_vars}, {rhs});
}bool Mpc::solve(Eigen::Vector3d current_states, Eigen::MatrixXd desired_states) {//cout << "jinqiujiele" << endl;Opti opti = Opti();Slice all;MX cost = 0;X = opti.variable(3, N_ + 1);// 定义一个3行N_+1列的矩阵变量X 注意:是变量。//第一个时间步(索引为0)表示当前时刻的状态 后面N_个时间步表示未来N_个时刻的状态和U对应U = opti.variable(2, N_);MX x = X(0, all);MX y = X(1, all);MX theta = X(2, all);MX v = U(0, all);MX w = U(1, all);//MX w = U(2, all);MX X_ref = opti.parameter(3, N_ + 1);   // 定义一个3行N_+1列的参数矩阵X_ref 注意:是已知的常量MX X_cur = opti.parameter(3);DM x_tmp1 = {current_states[0], current_states[1], current_states[2]};opti.set_value(X_cur, x_tmp1);  //set current state opti.set_value 用于设置参数的具体值cout << "set current state success" << endl;//按列索引vector<double> X_ref_v(desired_states.data(), desired_states.data() + desired_states.size());//auto tp1 = std::chrono::steady_clock::now();DM X_ref_d(X_ref_v);//X_ref_d.resize(3, N_ + 1);//cout << "desired_states:" << desired_states << endl;//cout << "X_ref_v:" << X_ref_v << endl;//cout << "X_ref_d:" << X_ref_d << endl;// DM x_tmp2(3, N_ + 1);// for (int i = 0; i < 3; ++i) {//     for (int j = 0; j <= N_; ++j) {//         x_tmp2(i, j) = desired_states(i, j);//     }// }X_ref = MX::reshape(X_ref_d, 3, N_ + 1);//opti.set_value(X_ref, X_ref_d);  //set reference traj// auto tp2 = std::chrono::steady_clock::now();// cout <<"set trajectory time:" // << chrono::duration_cast<chrono::microseconds>(tp2 - tp1).count() // << "microseconds" << endl;//cout << "set reference traj success" << endl;//cout << "x_ref:" << X_ref.size() << endl;//set costfunctionfor (int i = 0; i < N_; ++i) {MX X_err = X(all, i) - X_ref(all, i); MX U_0 = U(all, i);//cout << "U_0 size:" << U_0.size() << endl;//cout << "cost size:" << cost_.size() << endl;cost += MX::mtimes({X_err.T(), Q_, X_err}); //目标函数是状态误差和控制输入的成本之和//cout << "cost size:" << cost_.size() << endl; cost += MX::mtimes({U_0.T(), R_, U_0});//cout << "cost size:" << cost_.size() << endl;}//cout << "cost size:" << cost_.size() << endl;//MX::mtimes 用于执行矩阵乘法,用于计算两个矩阵的乘积cost += MX::mtimes({(X(all, N_) - X_ref(all, N_)).T(), Q_,X(all, N_) - X_ref(all, N_)});  //终端项//cout << "cost:" << cost << endl;opti.minimize(cost); //opti.minimize 用于定义优化问题的目标函数//cout << "set cost success" << endl;//kinematic constrains opti.subject_to 用于添加约束条件到优化问题中for (int i = 0; i < N_; ++i) {vector<MX> input(2);input[0] = X(all, i);input[1] = U(all, i);MX X_next = kinematic_equation_(input)[0] * dt_ + X(all, i); //这里体现了模型预测控制,模型。  下一步的状态=通过模型计算的速度* dt_ +当前状态opti.subject_to(X_next == X(all, i + 1));  // 动力学约束}//init value 初始化,初始状态赋值第一列所有行opti.subject_to(X(all, 0) == X_cur);//第一个时间步(索引为0)表示当前时刻的状态//speed angle_speed limit 控制输入的约束opti.subject_to(0 <= v <= u_max_);opti.subject_to(w_min_ <= w <= w_max_);//set solvercasadi::Dict solver_opts; // 设置求解器选项solver_opts["expand"] = true; //MX change to SX for speed upsolver_opts["ipopt.max_iter"] = 100;solver_opts["ipopt.print_level"] = 0;solver_opts["print_time"] = 0;solver_opts["ipopt.acceptable_tol"] = 1e-6;solver_opts["ipopt.acceptable_obj_change_tol"] = 1e-6;opti.solver("ipopt", solver_opts);//auto sol = opti.solve();solution_ = std::make_unique<casadi::OptiSol>(opti.solve());return true;
}
vector<double> Mpc::getFirstU() {vector<double> res;auto first_v =  solution_->value(U)(0, 0);auto first_w = solution_->value(U)(1, 0);//cout << "first_u" << first_u << " " << "first_v" << first_v << endl;res.push_back(static_cast<double>(first_v));res.push_back(static_cast<double>(first_w));return res;
}vector<double> Mpc::getPredictX() {vector<double> res;auto predict_x = solution_->value(X);cout << "nomal" << endl;//cout << "predict_x size :" << predict_x.size() << endl;for (int i = 0; i <= N_; ++i) {res.push_back(static_cast<double>(predict_x(0, i)));res.push_back(static_cast<double>(predict_x(1, i)));}return res;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/449994.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Java的免税商品优选购物商城设计与实现代码(论文+源码)_kaic

目 录 摘 要 Abstract 第一章 绪论 1.1 课题开发的背景 1.2 课题研究的意义 1.3 研究内容 第二章 系统开发关键技术 2.1 JAVA技术 2.2 MyEclipse开发环境 2.3 Tomcat服务器 2.4 Spring Boot框架 2.5 MySQL数据库 第三章 系统分析 3.1 系统可行性研究…

ClickHouse的原理及使用,

1、前言 一款MPP查询分析型数据库——ClickHouse。它是一个开源的&#xff0c;面向列的分析数据库&#xff0c;由Yandex为OLAP和大数据用例创建。ClickHouse对实时查询处理的支持使其适用于需要亚秒级分析结果的应用程序。ClickHouse的查询语言是SQL的一种方言&#xff0c;它支…

01数组算法/代码随想录

一、数组 好久没写算法题&#xff0c;之前喜欢按着习惯选择刷题&#xff0c;很早以前就听说代码随想录&#xff0c;今天跟着代码随想录再过一遍算法 1.1二分查找 常见疑问 middle一定是在[left, right]这个范围内标准代码不会越界&#xff0c;因为在else if中出现越界后&…

【windows个性化】在 Windows 10/11 上使 Windows 任务栏半透明/透明

实现目的&#xff1a;在 Windows 10/11 上使 Windows 任务栏半透明/透明. TranslucentTB plugin 描述 只需几 MB 内存&#xff0c;几乎不占用 CPU&#xff0c;便可以在 Windows 10/11 上使 Windows 任务栏半透明/透明的轻量小工具 功能 高级颜色选择器(color picker)&…

X(twitter)推特广告类型有哪些?如何选择?

X&#xff08;twitter&#xff09;推特是全球最热门的几大社交媒体平台之一&#xff0c;也是很多电商卖家进行宣传推广工作的阵地之一。在营销过程中不可避免地需要借助平台广告&#xff0c;因此了解其广告类型和适配场景也十分重要。 一、广告类型及选择 1.轮播广告 可滑动的…

JavaScript的100个概念

JavaScript对初学者来说既是福音&#xff0c;也是挑战。一方面&#xff0c;掌握它后可以构建各种项目&#xff0c;比如网站、应用程序和服务器&#xff0c;还能在很多行业找到工作。但另一方面&#xff0c;它又充满怪异之处&#xff0c;并被各种复杂的库和框架包围。在这段课程…

FLUX LoRA模型揭秘:COMFYUI中的AI绘画新动力!

嗨&#xff0c;艺术爱好者们&#xff01;今天我们要揭开一个神秘的面纱——FLUX LoRA模型&#xff0c;这个模型就像是一个神奇的魔法师&#xff0c;将COMFYUI中的AI绘画提升到了一个新的高度&#xff01; 想象一下&#xff0c;你有一个AI助手&#xff0c;它能够理解你的绘画梦…

【Redis】Zset类型常用命令

文章目录 一. Zset有序集合简介.二. 添加元素相关命令.2.1 向有序集合中添加元素(zadd) 三. 查询元素相关操作.3.1 查询有序集合中的元素个数( zcard zcount)3.2 查询指定区间内的元素(zrange zrevrange zrangebyscore)3.3 查询有序集合中指定成员的排名(zrank zrevrank )3.4 查…

钴粉Co纳米微球100nm|CoNP/CoN2-C催化剂

钴粉Co纳米微球100nm|CoNP/CoN2-C催化剂 钴粉Co纳米微球100nm是一种具有独特物理和化学性质的纳米材料&#xff0c;因其高比表面积、优良的磁性和化学稳定性&#xff0c;在多个领域展现出广阔的应用前景。以下是关于钴粉Co纳米微球100nm的相关信息&#xff1a; 性质 高比表面…

ubuntu20.04安装gerrit

1、update 2、updategrale 一&#xff1a;安装前准备 配置管理gerrit的专属账号&#xff1a;(本次测试安装我用的ROOT) sudo adduser gerrit sudo usermod -a -G sudo gerrit //分配sudo 权限 sudo su gerrit java、git环境&#xff1a; sudo apt-get update sudo apt-g…

群晖前面加了雷池WAF,安装失败,然后无法识别出用户真实访问IP

有nas的相信对公网都不模式&#xff0c;在现在基础上传带宽能有100兆的时代&#xff0c;有公网代表着家里有一个小服务器&#xff0c;像百度网盘&#xff0c;优酷这种在线服务都能部署为私有化服务。但现在运营商几乎不可能提供公网ip&#xff0c;要么自己买个云服务器做内网穿…

多jdk版本环境下,jenkins系统设置需指定JAVA_HOME环境变量

一、背景 由于不同项目对jdk版本的要求不同&#xff0c;有些是要求jdk11&#xff0c;有些只需要jdk8即可。 而linux机器上安装jdk的方式又多种多样&#xff0c;最后导致jenkins打包到底使用的是哪个jdk&#xff0c;比较混乱。 1、java在哪 > whereis java java: /usr/bin/…

测试人生 | 双非院校,2年工作经验年薪近20万

本人本科毕业于双非院校&#xff0c;大学毕业之后就开始从事软件测试工作&#xff0c;有两年多的工作经验&#xff0c;工作当中学习的测试技能较少&#xff0c;比较多重复的工作内容&#xff0c;主要对软件进行功能测试、简单的接口测试及专项测试&#xff0c;自学的测试知识零…

【STL】模拟实现list

目录 list需要实现的接口 结点类的创建 迭代器类的实现 构造函数 运算符的重载 --运算符的重载 !运算符重载和运算符重载 operator* operator-> list的模拟实现 构造函数 拷贝构造函数 赋值运算符重载函数 析构函数 迭代器相关函数 begin和end front和back …

【超详细】TCP协议

TCP(Transmission Control Protocol 传输控制协议) 传输层协议有连接可靠传输面向字节流 为什么TCP是传输控制协议呢&#xff1f; 我们以前所看到的write接口&#xff0c;都是把用户级缓冲区的数据拷贝到发送缓冲区中&#xff0c;然后数据就由TCP自主决定了&#xff0c;所以…

crashrpt3 开源项目的Vs 2022 C++20及其以上的编译

1. 首先从github 下载源代码 crashrpt3 2. 用CMake Gui 编译成vs studio 工程文件 2.1 点击 config 按钮 2.2 依次点击 Generate 按钮、Open Project 按钮.之后vs 2022 会打开编译好的sln工程文件 3.全选解决方案里面的所有项目,设置C语言标准,我这里设置是最新C,即启用的是…

【文档智能】文本文字识别、公式识别、表格文字识别核心算法及思路及实践-DBNet、CRNN、TrOCR

前言 OCR技术作为文档智能解析链路中的核心组件之一&#xff0c;贯穿整个技术链路&#xff0c;包括&#xff1a;文字识别、表格文字识别、公式识别&#xff0c;参看下面这张架构图&#xff1a; 前期介绍了很多关于文档智能解析相关核心技术及思路&#xff0c;本着连载的目的&a…

IT监控平台可视化:多维度展示助力运维效率提升

在信息化时代&#xff0c;IT设备的稳定性与业务的连续性紧密相连&#xff0c;任何细微的故障都可能给企业带来巨大的损失。因此&#xff0c;IT运维团队面临着前所未有的挑战&#xff0c;他们需要迅速、准确地识别和解决问题&#xff0c;以确保业务的平稳运行。而IT监控平台的可…

应届生毕业找不到工作转行IT需要做好哪些准备呢?

前言 相信这是很多即将毕业的应届生们都非常关心的问题。在这里&#xff0c;我们将站在一个应届生毕业且对IT行业感兴趣的角度&#xff0c;来探讨一下这个问题。 首先&#xff0c;我们先来了解一下什么是应届生。应届生是指在学校毕业之后&#xff0c;能够在当年或者下一年度…

AIGC验证码如何对抗,AIGC VS AIGC

AI类型的验证码&#xff0c;当然使用AI对对抗&#xff0c;使用大量的样本叠加训练&#xff0c;我的生成如下: 如果可以生词大量词汇&#xff0c;那么准确率必然上升&#xff0c;有办法的可以讨论