考虑下面的类,我想从两个传递给构造函数的Eigen::Ref初始化两个成员变量(普通的const ref)。
在构造函数内部,打印
std::cout << "Matrix Param: " << current_predicted_sigma_points << std::endl;
std::cout << "Matrix Member: " << current_predicted_sigma_points_ << std::endl;
按预期工作,它们打印相同的矩阵,这意味着current_predicted_sigma_points_
已正确初始化。
然而,当我调用Update函数时,变量current_predicted_sigma_points_
包含垃圾,但weights_
仍然正确。
template <typename ProcessModel, typename MeasurementModel>
class UnscentedUpdateStrategy
{
public:
UnscentedUpdateStrategy(
const Eigen::Ref<const ukf_utils::PredictedSigmaMatrix<ProcessModel, ProcessModel::n_sigma_points>>
current_predicted_sigma_points,
const Eigen::Ref<const Eigen::Vector<double, ProcessModel::n_sigma_points>> weights)
: current_predicted_sigma_points_{current_predicted_sigma_points}, weights_{weights}
{
std::cout << "Matrix Param: " << current_predicted_sigma_points << std::endl;
std::cout << "Matrix Member: " << current_predicted_sigma_points_ << std::endl;
}
void Update(const Eigen::Ref<const typename MeasurementModel::PredictedVector>& measure,
const simpleukf::ukf_utils::MeanAndCovariance<ProcessModel>& current_hypotesis,
simpleukf::ukf_utils::MeanAndCovariance<ProcessModel>& mean_and_cov_out) const
{
simpleukf::ukf_utils::PredictedSigmaMatrix<MeasurementModel, ProcessModel::n_sigma_points>
measurement_predicted_sigma_matrix_out;
std::cout << "Matrix Member Update: " << current_predicted_sigma_points_ << std::endl;
std::cout << "Weights Update: " << weights_ << std::endl;
auto measurement_prediction = ukf_utils::PredictMeanAndCovarianceFromSigmaPoints<MeasurementModel>(
measurement_predicted_sigma_matrix_out, current_predicted_sigma_points_, weights_);
// std::forward<const MeasurementPredictionArgs>(args)...);
// add measurement noise covariance matrix
measurement_prediction.covariance += MeasurementModel::noise_matrix_squared;
// create matrix for cross correlation: predicted measurement `measurement_prediction.mean` and pred covariance
// `measurement_prediction.covariance`
const auto cross_correlation_matrix =
ukf_utils::ComputeCrossCorrelation<ProcessModel, MeasurementModel, ProcessModel::n_sigma_points>(
current_predicted_sigma_points_,
current_hypotesis.mean,
measurement_predicted_sigma_matrix_out,
measurement_prediction.mean,
weights_);
// Kalman gain K;
Eigen::Matrix<double, ProcessModel::n, MeasurementModel::n> K =
cross_correlation_matrix * measurement_prediction.covariance.inverse();
// residual
typename MeasurementModel::PredictedVector measure_diff = measure - measurement_prediction.mean;
// angle normalization
models_utils::AdjustIfNeeded<MeasurementModel>(measure_diff);
// update state mean and covariance matrix
mean_and_cov_out.mean = current_hypotesis.mean + K * measure_diff;
mean_and_cov_out.covariance =
current_hypotesis.covariance - K * measurement_prediction.covariance * K.transpose();
}
private:
// TODO: should we keep a copy or not?
const ukf_utils::PredictedSigmaMatrix<ProcessModel, ProcessModel::n_sigma_points>& current_predicted_sigma_points_;
const Eigen::Vector<double, ProcessModel::n_sigma_points>& weights_;
};
当将成员切换到Eigen::Ref类型时,问题消失了,但我想了解在原始情况下发生了什么,因为我可能在嵌套函数接受普通引用时遇到同样的问题。
1条答案
按热度按时间fxnxkyjh1#
您的参数传递存在多个问题:
1.您试图从
const Eigen::Ref<const Eigen::Vector<...>>
类型的对象初始化const Eigen::Vector<...>&
类型的成员。它们显然不是同一类型。其他参数也是如此1.您传递了一个
Eigen::Ref
,但希望将其保留在函数(本例中为构造函数)的作用域之外,这是不安全的,原因有二。Ref
通常只Map您传递的向量或矩阵,但在某些情况下,Ref
将获取临时副本(特别是如果内部跨距大于1,例如,当将矩阵中的一行作为向量传递时;或者当你传递一个需要求值的表达式时)。当ref超出作用域时,通常是当函数返回时,这个副本将被销毁。此外,当传递其他参数作为函数参数时,通常只通过转换操作符构造Ref。由于当函数(这里是构造函数)返回时,Ref被销毁,因此保留对该对象的引用或指针会创建一个悬空指针。
第二个问题可以通过复制一个引用对象来解决。第一个问题不能这样解决。所以永远不要这样做。
1.一个小问题是你传递引用的方式。规范的方式是
const Eigen::Ref<const ...>&
作为输入参数,Eigen::Ref<...>
作为输入-输出参数。注意你错过了&
作为常量引用。如何解决这一切?两个选项:
1.通过复制Refs将属性类型更改为普通
Vector<double, ...>
和PredictedSigmaMatrix
,construct1.将构造函数的参数改为普通的对象引用、指针、
shared_ptr
或其他类型,并保留这些指针/引用。不要使用Eigen::Ref
。这只适用于临时引用