如何使用Odeint求解状态空间模型
How to solve a state space model with Odeint?
我正在尝试使用特征和Odeint实现状态空间模型的数值模拟。我的麻烦是我需要引用控制数据U(积分前预定义),以便正确求解状态空间模型的Ax + Bu部分。我试图通过使用计数器来跟踪当前时间步长来实现这一点,但无论出于何种原因,每次 Odeint 调用系统函数时,它都会重置为零。
我将如何解决这个问题?我对状态空间系统进行建模的方法是否存在缺陷?
我的系统
struct Eigen_SS_NLTIV_Model
{
Eigen_SS_NLTIV_Model(matrixXd &ssA, matrixXd &ssB, matrixXd &ssC,
matrixXd &ssD, matrixXd &ssU, matrixXd &ssY)
:A(ssA), B(ssB), C(ssC), D(ssD), U(ssU), Y(ssY)
{
Y.resizeLike(U);
Y.setZero();
observerStep = 0;
testPtr = &observerStep;
}
/* Observer Function:*/
void operator()(matrixXd &x, double t)
{
Y.col(observerStep) = C*x + D*U.col(observerStep);
observerStep += 1;
}
/* System Function:
* ONLY the mathematical description of the system dynamics may be placed
* here. Any data placed in here is destroyed after each iteration of the
* stepper.
*/
void operator()(matrixXd &x, matrixXd &dxdt, double t)
{
dxdt = A*x + B*U.col(*testPtr);
//Cannot reference the variable "observerStep" directly as it gets reset
//every time this is called. *testPtr doesn't work either.
}
int observerStep;
int *testPtr;
matrixXd &A, &B, &C, &D, &U, &Y; //Input Vectors
};
我的 ODE 求解器设置
const double t_end = 3.0;
const double dt = 0.5;
int steps = (int)std::ceil(t_end / dt) + 1;
matrixXd A(2, 2), B(2, 2), C(2, 2), D(2, 2), x(2, 1);
matrixXd U = matrixXd::Constant(2, steps, 1.0);
matrixXd Y;
A << -0.5572, -0.7814, 0.7814, 0.0000;
B << 1.0, -1.0, 0.0, 2.0;
C << 1.9691, 6.4493, 1.9691, 6.4493;
D << 0.0, 0.0, 0.0, 0.0;
x << 0, 0;
Eigen_SS_NLTIV_Model matrixTest(A, B, C, D, U, Y);
odeint::integrate_const(odeint::runge_kutta4<matrixXd, double, matrixXd, double,
odeint::vector_space_algebra>(),
matrixTest, x, 0.0, t_end, dt, matrixTest);
//Ignore these two functions. They are there mostly for debugging.
writeCSV<matrixXd>(Y, "Y_OUT.csv");
prettyPrint<matrixXd>(Y, "Out Full");
使用经典的 Runge-Kutta 您知道您的 ODE 模型函数每步调用 4 次,次数t, t+h/2, t+h/2, t+h
.对于实现自适应步长的其他求解器,您无法提前知道 ODE 模型函数的调用t
。
您应该通过某种插值函数实现U
,在最简单的情况下是 step 函数,它从t
计算某个索引并返回该索引的U
值。类似的东西
i = (int)(t/U_step)
dxdt = A*x + B*U.col(i);
相关文章:
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 命名空间中具有.h和.cpp文件的类
- 从父命名空间重载类型
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- 在命名空间中定义函数还是限定函数
- C++:对不存在的命名空间使用命名空间指令
- 通过继承类使用来自不同命名空间的运算符
- QTableView:endMoveRows在模型中重置水平页眉大小
- 使用命名空间时出现多个定义错误
- OpenGL相机和相机空间转型的困惑
- 将IBM Rhapsody模型集成到VS 2019中
- CUDA内核和数学函数的显式命名空间
- 我们可以将阈值应用于色彩空间模型的单个组件(如 RGB 和 LAB)吗?
- 将C++数据模型与Qt SCXML状态机一起使用
- 分层状态机涉及哪些原则,以及如何实现基本模型?
- OpenGL-绘制相机空间后,将模型放置在世界空间中
- 如何使用Odeint求解状态空间模型
- OpenCL:指令和地址之间的状态空间不匹配
- Qt5 C++如何访问模型中的项目以检查状态
- 为什么使用摄影机空间而不是模型空间作为法线