Boost OdeInt 在进入积分例程时无法设置类属性

问题描述 投票:0回答:1

我正在使用

boost::numeric::odeint
构建自定义集成器。 除了计算状态的离散导数之外,我还在输入
operator ()
的每个积分步骤中计算输出方程。我确实知道它效率不高,但到目前为止我需要它来了解图书馆是如何工作的。

在调试时,在

operator ()
方法中,
y
test
变量都计算得很好。但是,一旦程序返回主循环,
sys
对象就有
y
test
变量未初始化。

下面显示了代码以及重现所讨论内容的结果。

实时编译器资源管理器

#include <Eigen/Dense>
#include <iostream>

using Eigen::Matrix;
using Eigen::Vector;
using Eigen::VectorXd;

int constexpr n = 2; // State size
int constexpr q = 1; // Output size
int constexpr m = 1; // Input size

using state_type  = Vector<double, n>;
using input_type  = Vector<double, m>;
using output_type = Vector<double, q>;

using state_matrix_type       = Matrix<double, n, n>;
using input_matrix_type       = Matrix<double, n, m>;
using output_matrix_type      = Matrix<double, q, n>;
using feedthrough_matrix_type = Matrix<double, q, m>;

struct TestSystem {
    state_matrix_type       A{{-4.0, -3.0}, {1.0, 0.0}};
    input_matrix_type       B{1.0, 0.0};
    output_matrix_type      C{1.0, 1.0};
    feedthrough_matrix_type D{0.0};

    double test;

    input_type  u;
    output_type y;
    void        operator()(state_type const& x, state_type& x_dot, double t);
};

void TestSystem::operator()(state_type const& x, state_type& x_dot, double) {
    x_dot = A * x + B * u;

    this->y = C * x + D * u;

    this->test = (C * x + D * u)(0);
    std::cout << "Output computed within integration step: " << test << std::endl;
}

#include <boost/numeric/odeint/stepper/runge_kutta4.hpp>
#include <boost/numeric/odeint/integrate/integrate_n_steps.hpp>

namespace ode = boost::numeric::odeint;

int main() {
    int constexpr N = 5000;
    VectorXd t(N);

    t = VectorXd::LinSpaced(N, 0.0, 1.0);

    TestSystem sys;

    VectorXd u(N);
    u = (2 * M_PI * 200 * t).array().cos() + (2 * M_PI * 20 * t).array().sin();

    state_type x = state_type::Zero();
    
    // Just one step for example sake
    for (size_t i = 0; i < 1; i++) {
        input_type _u{ u(i) };
        // _u << u(i);

        sys.u = _u;

        ode::runge_kutta4<state_type> rk;

        rk.do_step(sys, x, t(i), t(1));

        std::cout << "System object output variable: " << sys.test << std::endl;
    }
}

结果

Output computed within integration step: 0
Output computed within integration step: 0.00010002
Output computed within integration step: 9.999e-05
Output computed within integration step: 0.00019998
System object output variable: 0
c++ boost odeint
1个回答
0
投票

系统是按值传递的。要强制引用语义,请使用引用包装器:

实时编译器资源管理器

#include <Eigen/Dense>
#include <iostream>

using Eigen::Matrix;
using Eigen::Vector;
using Eigen::VectorXd;

int constexpr n = 2; // State size
int constexpr q = 1; // Output size
int constexpr m = 1; // Input size

using state_type  = Vector<double, n>;
using input_type  = Vector<double, m>;
using output_type = Vector<double, q>;

using state_matrix_type       = Matrix<double, n, n>;
using input_matrix_type       = Matrix<double, n, m>;
using output_matrix_type      = Matrix<double, q, n>;
using feedthrough_matrix_type = Matrix<double, q, m>;

struct TestSystem {
    state_matrix_type       A{{-4.0, -3.0}, {1.0, 0.0}};
    input_matrix_type       B{1.0, 0.0};
    output_matrix_type      C{1.0, 1.0};
    feedthrough_matrix_type D{0.0};

    double test;

    input_type  u;
    output_type y;
    void        operator()(state_type const& x, state_type& x_dot, double t);
};

void TestSystem::operator()(state_type const& x, state_type& x_dot, double) {
    x_dot = A * x + B * u;

    this->y = C * x + D * u;

    this->test = (C * x + D * u)(0);
    std::cout << "Output computed within integration step: " << test << std::endl;
}

#include <boost/numeric/odeint/stepper/runge_kutta4.hpp>
#include <boost/numeric/odeint/integrate/integrate_n_steps.hpp>

namespace ode = boost::numeric::odeint;

int main() {
    int constexpr N = 5000;
    VectorXd t(N);

    t = VectorXd::LinSpaced(N, 0.0, 1.0);

    TestSystem sys;

    VectorXd u(N);
    u = (2 * M_PI * 200 * t).array().cos() + (2 * M_PI * 20 * t).array().sin();

    state_type x = state_type::Zero();
    
    // Just one step for example sake
    for (size_t i = 0; i < 1; i++) {
        input_type _u{ u(i) };
        // _u << u(i);

        sys.u = _u;

        ode::runge_kutta4<state_type> rk;

        rk.do_step(std::ref(sys), x, t(i), t(1));

        std::cout << "System object output variable: " << sys.test << std::endl;
    }
}

印刷

Output computed within integration step: 0
Output computed within integration step: 0.00010002
Output computed within integration step: 9.999e-05
Output computed within integration step: 0.00019998
System object output variable: 0.00019998
© www.soinside.com 2019 - 2024. All rights reserved.