找到正确的设计方法

finding the right design approach

本文关键字:方法      更新时间:2023-10-16

我在 C++ 中遇到了一些设计问题。我的基本想法:

我有一个状态类和两个卡尔曼滤波类。卡尔曼滤波器类具有相同的基类,具有相同的接口校正(状态、测量)。但是每个实现都以不同的方式工作。

我的状态类基本上处理一个向量。

class StateBase{
protected:
  Eigen::VectorXd state_;
};
class StateCV : public StateBase {}
class StateCA : public StateBase {}

卡尔曼滤波基类:

class KalmanBase {
public:
  virtual void prediction(Eigen::VectorXd& state)
  virtual void Correction(Eigen::VectorXd& state, Eigen::VectorXd& measurement) = 0;
 ...
};
  virtual StateBase* CreateState() = 0;

派生卡尔曼A级

class KalmanA : public KalmanBase {
public:
  void Prediction(Eigen::VectorXd& state) {
      state = A_ * state;
  void Correction(Eigen::VectorXd& state, Eigen::VectorXd& measurement) {
      ... 
      Eigen::VectorXd x = C_*state - measurement;
      ...
  }
protected:
  Eigen::MatrixXd A_, C_ ;
};

派生卡尔曼B类

class KalmanB : public KalmanBase {
public:
  void Prediction(Eigen::VectorXd& state) {
    StateFunc(state);
  }
  void Correction(Eigen::VectorXd& state, Eigen::VectorXd& measurement) {
      ... 
      Eigen::VectorXd x = measurement - CFunc(state);
      ...
  }
private:
    void StateFunc(Eigen::VectorXd& state) {}
    CFunc(const Eigen::VectorXd& measurement) {}
};

对于每种类型的状态,我也有卡尔曼A和卡尔曼B的子类。

class KalmanA_CV : public KalmanA {
  StateBase* CreateState() { return new StateCV(); }  
}
class KalmanA_CA : public KalmanA {
  StateBase* CreateState() { return new StateCA(); } 
}
class KalmanB_CV : public KalmanB { ...}
class KalmanB_CA : public KalmanB { ... }

根据我的测量结果,我必须更改卡尔曼A中的C_矩阵或卡尔曼B中的CFunc,以将状态向量的维度映射到测量向量的维度。

因此,从外部,我只想定义测量类型和状态类型,并执行以下操作:

KalmanBase* Kalman
Kalman = new KalmanA_CV
state = Kalman.CreateState()
// Measurement1 m;
// m.initMeasurement(...)
Kalman.correction(*state, m)

根据测量类型,我希望卡尔曼A或卡尔曼B使用腐蚀C_矩阵或C_Function。

我将不胜感激一些设计建议。

我不知道你想象它是如何工作的,但本质上这对我猜的访问者模式来说是一个很好的选择。有关粗略的概述,请查看维基百科页面。

对于初学者来说,似乎StateBase::state_未使用。这是有道理的:它既不是卡尔曼A的状态,也不是卡尔曼B的状态。

其次,KalmanA只是KalmanB的专门版本。特别 StateFunc [](Eigen::VectorXd& state) { state *= A_; }.

因此,我建议您放弃整个继承模型,而只是创建一个带有std::function<void(Eigen::VectorXd& state)> StateFunc class Kalman

最后一点,你用了new很多。这可能是可以避免的,只需直接使用变量:Kalman kal { A_matrix, C_matrix }; // Selects the right ctor overload