I have recently been implementing one of the vehicle control algorithms that solves the "steering to the point" problem. The algorithm itself involves multiple matrix ODE solving and I wanted to implement my main algorithm class in such a way that it was independent on system (ODE) we wish to control.
The most intuitive approach seems to be:
class EquationBase
{
public:
virtual ~EquationBase();
/* Due to supposed bug in odeint this class is not abstract and operator() is not pure virtual */
virtual void operator() (const state_type &x, state_type &dxdt, const time_type t);
/* method specific for the considered algorithm, this should be part of the interface */
virtual void setLambdas(std::vector<double> lambdas);
};
class VehicleEquation: public EquationBase
{
public:
VehicleEquation();
~VehicleEquation();
void operator() (const state_type &x, state_type &dxdt, const time_type t) override;
void setLambdas(std::vector<double> lambdas) override;
private:
/* here some fields/methods specific for the system */
};
class MyAlgorithm
{
public:
MyAlgorithm();
MyAlgorithm(EquationBase *eq);
void start();
private:
EquationBase *eqPtr_;
};
Now each system that is a child of EquationBase may be used via eqPtr. Unfortunately, a second argument (ODE System) to the odeint::integrate_adaptive must be an object, not a pointer. To bypass this limitation I introduced a wrapper that contains the actual pointer to the ODE system, but does not need to use virtual functions itself:
class EquationWrapper
{
public:
void operator() (const state_type &x, state_type &dxdt, const time_type t)
{
(*eqPtr_)(x,dxdt,t);
}
void setEquation(EquationBase *eqPtr)
{
eqPtr_ = eqPtr;
}
private:
EquationBase *eqPtr_;
};
class MyAlgorithm
{
public:
MyAlgorithm();
/* somewhere here: eqWrapper_.setEquation(eq); */
MyAlgorithm(EquationBase *eq);
/* somewhere in the algorithm: odeint::integrate_adaptive( .... , eqWrapper_, ... ) */
void start();
private:
EquationWrapper eqWrapper_;
};
Of course this solution works, but I wish to know whether this is safe, clean (obviously odeint will copy my equation pointer multiple times, but will not delete it unless I declare it explicitly in the wrapper destructor), and is there a better way to achieve the desired behaviour (I thought of templates, but found this even worse)?
Since I did not find a similar problem being considered elsewhere, please refer to my solution, should you need to use odeint in such a way.