背景
我正在为涉及模拟大量State Space数学模型的项目编写一些C ++代码。因为有几种不同类型的模型存在不同程度的复杂性(即非线性/线性和时变/非变化)我创建了一个能够表示的多态类结构每种类型的各种功能,同时仍然很好地保持矩阵的共同属性捆绑在一起。通过这种方式,我可以轻松地将各种模型类型推广到OdeInt内部进行模拟。
简单基类的当前版本如下所示:
class SS_ModelBase
{
public:
virtual Eigen::MatrixXd getA() = 0;
virtual Eigen::MatrixXd getB() = 0;
virtual Eigen::MatrixXd getC() = 0;
virtual Eigen::MatrixXd getD() = 0;
virtual Eigen::MatrixXd getX0() = 0;
virtual int getNumInputs() = 0;
virtual int getNumOutputs() = 0;
virtual int getNumStates() = 0;
private:
};
typedef boost::shared_ptr<SS_ModelBase> SS_ModelBase_sPtr;
所提及类型的每个派生类然后具有它们自己的变量,用于实际存储矩阵A,B,C,D和&amp;的特定表示。 X0。输入,输出,状态用于某些尺寸信息,这些信息可能需要以后进行操作。在实践中,这对我来说非常好。
我将如何在模拟器中使用模型的示例如下所示:
Eigen::MatrixXd StateSpaceSimulator::stepResponse(const double start, const double stop, const double dt,
const SS_ModelBase_sPtr& model, const PID_Values pid)
{
/* Due to how Odeint works internally, it's not feasible to pass in a full state space model object
and run the algorithm directly on that. (Odeint REALLY dislikes pointers) Instead, a local copy of the
model will be made. For now, assume that only NLTIV models are handled. */
SS_NLTIVModel localModel(model);
/* Copy the relevant data from the model for cleaner code in main sim*/
Eigen::MatrixXd x = localModel.getX0();
Eigen::MatrixXd A = localModel.getA();
Eigen::MatrixXd B = localModel.getB();
Eigen::MatrixXd C = localModel.getC();
Eigen::MatrixXd D = localModel.getD();
//Other irrelevant code that actually performs numerical simulations
}
上面代码中的自定义复制构造函数如下所示:
/* Copy constructor */
SS_NLTIVModel(const SS_ModelBase_sPtr& base)
{
inputs = base->getNumInputs();
outputs = base->getNumOutputs();
states = base->getNumStates();
A.resize(states, states); A.setZero(states, states);
B.resize(states, inputs); B.setZero(states, inputs);
C.resize(outputs, states); C.setZero(outputs, states);
D.resize(outputs, inputs); D.setZero(outputs, inputs);
X0.resize(states, 1); X0.setZero(states, 1);
U.resize(inputs, 1); U.setZero(inputs, 1);
}
问题
我在一些模拟中注意到,在尝试调整各种矩阵的大小时,我会在复制构造函数中获得内存访问冲突错误。 std :: malloc()在Eigen框架中深入调用并抛出错误。经过几个小时撞击墙壁试图找出为什么Eigen软件突然无法正常工作,我偶然发现 解决方案,但我不知道它为什么会起作用或者是否有效更好的方式。
我旧的已损坏的功能签名如下所示:
Eigen::MatrixXd StateSpaceSimulator::stepResponse(const double start, const double stop, const double dt,
SS_ModelBase_sPtr model, PID_Values pid)
新的工作功能签名如下所示:
Eigen::MatrixXd StateSpaceSimulator::stepResponse(const double start, const double stop, const double dt,
const SS_ModelBase_sPtr& model, const PID_Values pid)
这两者之间的运行时差异可能导致我的错误?我知道第一个会增加shared_ptr的参考计数器而第二个不会增加,但除此之外,我不确定什么会改变行为足以引起我的问题...想法?