Question

I want to know how I can log the values other than states during integration by odeint. I have a simulation of the satellite dynamics, which is described as differential equations of total angular momentum, L, and momentum of an internal wheel, h. My simulation is running correctly. But I need to log not only the state variables but also some other values such as external torque, N, and angular velocity, omega, that is Jinv*L, where Jinv is a 3x3 constant, satellite-inertia matrix. In a sense, the purpose of my simulator is not to calculate L and h, but to generate time-histories of "other" varialbes.

To show what I'm doing, below is a slightly simplified version of my current code.

class satellite
{
public:
Eigen::Matrix3d Jinv;

void operator()( state_type &x , state_type &dxdt , double t )
{
    L << x[0], x[1], x[2];
    h << x[3], x[4], x[5], x[6];

    N = external_torque(t);

    omega = Jinv * (L-h);
    dLdt = N - omega.cross(L);

    OMEGA = func1(omega(0), omega(1), omega(2));

    dqdt = OMEGA * q * 0.5;

    dxdt[0] = dLdt(0);    dxdt[1] = dLdt(1);    dxdt[2] = dLdt(2);
    dxdt[3] = dqdt(0);    dxdt[4] = dqdt(1);    dxdt[5] = dqdt(2);    dxdt[6] = dqdt(3);
}
};

class streaming_observer
{
public:
std::ostream& os;
satellite& sat;

streaming_observer( std::ostream& _os, satellite& _sat ) : os(_os), sat(_sat) { }

template<class State>
void operator() (const State& x, double t) const
{
     L << x[0], x[1], x[2];

    os << t << ' ' << (sat.Jinv*(L)).transpose() << std::endl;
}
};
Was it helpful?

Solution

You must do the calculation of your intermediate and the logging in the observer. To avoid redundancy it might be favourable to out the calculations in a separate function of class method and call this method from the system function (hence the operator() in your example) and from the observer. You can also record values in there and do some later analysis with these values.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top