Использование boost::numeric::odeint внутри класса

Для моделирования я использую boost::numeric::odeint, но у меня возникла проблема. Я использую функцию интеграции внутри метода одного из моих классов, и у меня возникает ошибка «нет соответствующей функции для вызова интеграции». Чтобы было понятнее, вот сжатая версия моего кода:

#include "MotionGeneration.h"
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>

typedef boost::array< double , 10 > state_type;

MotionGeneration::MotionGeneration(some_data) {
     //My constructor.
     //some_data assignment.
}

MotionGeneration::~MotionGeneration() {

}

double MotionGeneration::getError(double time) {
   //error calculation.
}

void MotionGeneration::execute(){
    state_type init_conf = { 0, -1.5708, 0, 0, 0, -1.5708, 0, -1.5708, 0, 0.5};
    boost::numeric::odeint::integrate(motionScheme, init_conf, 0.0, 1.0, 0.05, plot);
}

void MotionGeneration::motionScheme(const state_type &q, state_type &q_dot, double t){
     //Some long code goes here. Also I have some calls to some methods of this class. for example:
     double err = getError(t);          
}

void MotionGeneration::plot(const state_type &q , const double t){
    //some data pfintf here.
}

Обратите внимание, что ни один из моих методов не является статическим, и на самом деле я не могу использовать статический метод. Когда я создаю проект, у меня есть следующая ошибка:

error: no matching function for call to `integrate(<unknown type>, state_type&, double, double, double, <unknown type>)'

Я думаю, что проблема заключается в том, что системная функция работает как метод класса, но я не знаю, как справиться с этой ситуацией.


person Pouya    schedule 11.06.2012    source источник
comment
Ну, одним из решений были бы функции друзей вместо функций-членов. Не могу сказать, что в конце концов это действительно сработает, если есть лучший вариант.   -  person chris    schedule 11.06.2012
comment
@chris, интересная идея, но есть некоторые трудности. Например, мне нужно отправить экземпляр класса MotionGeneration функции друга, и это может быть несовместимо с функцией интеграции.   -  person Pouya    schedule 11.06.2012
comment
@Крис, я сделал это. Очень болезненно :/ Превращаю методы интегратора в статические методы. А потом переписал почти весь класс с начала.   -  person Pouya    schedule 11.06.2012
comment
Это действительно позор. Я ожидаю, что там будет лучший выход, чем этот.   -  person chris    schedule 11.06.2012
comment
Также очень вероятно, что это как-то моя вина :D После того, как я решил проблему и начал ее тестировать, я нашел ее очень мощной.   -  person Pouya    schedule 11.06.2012


Ответы (1)


одеинту нужен operator()( const state_type &x , state_type &dxdt , double dt )

В вашем случае у MotionGenerator нет этого оператора, но вы можете привязать метод motionScheme

#include <functional>
namespace pl = std::placeholders;

// ...

// not tested
void MotionGeneration::execute()
{
    state_type init_conf = { 0, -1.5708, 0, 0, 0, -1.5708, 0, -1.5708, 0, 0.5};
    boost::numeric::odeint::integrate(
        std::bind(&MotionGenerator::motionScheme, *this , pl::_1 , pl::_2 , pl::_3 ) , init_conf, 0.0, 1.0, 0.05, plot);
}

```

Но было бы легко переименовать ваш метод motionScheme в operator() и просто передать *this для интеграции.

Изменить: вы также можете использовать std::ref, чтобы избежать копирования вашего экземпляра MotionGenerator:

void MotionGeneration::execute()
{
    state_type init_conf = { 0, -1.5708, 0, 0, 0, -1.5708, 0, -1.5708, 0, 0.5};
    boost::numeric::odeint::integrate(
        std::bind(&MotionGenerator::motionScheme, std::ref(*this) , pl::_1 , pl::_2 , pl::_3 ) , init_conf, 0.0, 1.0, 0.05, plot);
}
person headmyshoulder    schedule 13.06.2012
comment
Я получил эту работу, используя integrate_const( stepper , *this , a_state, a_time , end_time , time_step );, он выполняет интеграцию, но кажется, что на самом деле он не меняет свойства состояния или скорости класса. Почему это? Работает ли это на какой-то копии класса? - person Simon Woodward; 13.09.2018
comment
К сожалению, я забыл использовать std::ref(*this) - person Simon Woodward; 29.10.2018