Arthur Spooner
Arthur Spooner

Reputation: 159

finding the right design approach

i am having some design problem in c++. My basic idea:

i have a state class and two kalman-filter classes. The Kalman-Filter classes have the same base class with the same interface correction(state, measurement). but each implementation works in a different way.

my state class, handles basically a vector.

class StateBase{
protected:
  Eigen::VectorXd state_;
};

class StateCV : public StateBase {}
class StateCA : public StateBase {}

Kalman-Filter Base class:

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

Derived KalmanA Class

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_ ;
};

Derived KalmanB Class

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) {}
};

And I also have subclasses of KalmanA and KalmanB for each type of state.

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 { ... }

Depending on my measurement i have to change my C_ Matrix in KalmanA or my CFunc in KalmanB, to map the dimension of the state vector to the dimension of the measurement vector.

so from outside i would simply like to define a measurement type and state type and do something like:

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

and depending on the type of measurement i would like that kalmanA or KalmanB use the corrosponding C_ Matrix or C_Function.

I would be grateful for some design advice.

Upvotes: 1

Views: 93

Answers (2)

MSalters
MSalters

Reputation: 179779

For starters, it appears that StateBase::state_ is unused. Makes sense: it's neither the state of KalmanA nor that of KalmanB.

Secondly, KalmanA is just a specialized version of KalmanB. In particular, StateFunc is [](Eigen::VectorXd& state) { state *= A_; }.

Hence, I'd advice you to just drop the whole inheritance model, and just create a class Kalman with std::function<void(Eigen::VectorXd& state)> StateFunc.

On a final note, you're using new quite a bit. That can probably be avoided, just use variables directly: Kalman kal { A_matrix, C_matrix }; // Selects the right ctor overload

Upvotes: 0

Roberto
Roberto

Reputation: 713

I don't know exactly how you imagine this to work, but essentially this would be a good one for the visitor pattern I guess. For a rough overview take a look at the wikipedia page.

Upvotes: 1

Related Questions