34 #include <boost/bind.hpp>
101 Eigen::Vector3d update_pose(
update.pose->pose.pose.position.x,
update.pose->pose.pose.position.y,
update.pose->pose.pose.position.z);
102 Eigen::Quaterniond update_orientation(
update.pose->pose.pose.orientation.w,
update.pose->pose.pose.orientation.x,
update.pose->pose.pose.orientation.y,
update.pose->pose.pose.orientation.z);
103 Eigen::Vector3d update_euler;
109 ROS_DEBUG_STREAM_NAMED(
"poseupdate",
"PoseUpdate: x = [ " <<
filter()->state().getVector().transpose() <<
" ], P = [ " <<
filter()->state().getCovariance() <<
" ]" << std::endl
110 <<
"update: pose = [ " << update_pose.transpose() <<
" ], rpy = [ " << update_euler.transpose() <<
" ], information = [ " << information <<
" ]");
114 if (!
update.pose->header.stamp.isZero()) {
117 ROS_DEBUG_STREAM_NAMED(
"poseupdate",
"Ignoring pose update as it has a negative time difference: dt = " << dt <<
"s");
121 ROS_DEBUG_STREAM_NAMED(
"poseupdate",
"Ignoring pose update as the time difference is too large: dt = " << dt <<
"s");
133 update_pose = update_pose + state_velocity * dt;
136 update_orientation = update_orientation * Eigen::Quaterniond().fromRotationVector(state_rate * dt);
142 const Eigen::Quaterniond &q = update_orientation;
143 update_euler(0) = atan2(2*(q.y()*q.z() + q.w()*q.x()), q.w()*q.w() - q.x()*q.x() - q.y()*q.y() + q.z()*q.z());
144 update_euler(1) = -asin(2*(q.x()*q.z() - q.w()*q.y()));
145 update_euler(2) = atan2(2*(q.x()*q.y() + q.w()*q.z()), q.w()*q.w() + q.x()*q.x() - q.y()*q.y() - q.z()*q.z());
149 if (information(0,0) > 0.0 || information(1,1) > 0.0) {
156 PositionXYModel::MeasurementVector y(update_pose.segment<2>(0));
157 PositionXYModel::NoiseVariance Iy(information.block<2,2>(0,0));
169 ROS_DEBUG_STREAM_NAMED(
"poseupdate",
" x = [" << x.transpose() <<
"], H = [ " << H <<
" ], Px = [" << (H *
filter()->state().P() * H.transpose()) <<
"], Ix = [ " << (H *
filter()->state().P() * H.transpose()).inverse() <<
"]");
173 ROS_DEBUG_STREAM_NAMED(
"poseupdate",
" ==> xy = [" << x <<
"], Pxy = [ " << (H *
filter()->state().P() * H.transpose()) <<
" ], innovation = " << innovation);
179 if (information(2,2) > 0.0) {
186 PositionZModel::MeasurementVector y(update_pose.segment<1>(2));
187 PositionZModel::NoiseVariance Iy(information.block<1,1>(2,2));
199 ROS_DEBUG_STREAM_NAMED(
"poseupdate",
" x = " << x(0) <<
", H = [ " << H <<
" ], Px = [" << (H *
filter()->state().P() * H.transpose()) <<
"], Ix = [ " << (H *
filter()->state().P() * H.transpose()).inverse() <<
"]");
203 ROS_DEBUG_STREAM_NAMED(
"poseupdate",
" ==> xy = " << x(0) <<
", Pxy = [ " << (H *
filter()->state().P() * H.transpose()) <<
" ], innovation = " << innovation);
209 if (information(5,5) > 0.0) {
215 YawModel::MeasurementVector y(update_euler.tail<1>());
216 YawModel::NoiseVariance Iy(information.block<1,1>(5,5));
228 ROS_DEBUG_STREAM_NAMED(
"poseupdate",
" x = " << x(0) * 180.0/M_PI <<
"°, H = [ " << H <<
" ], Px = [" << (H *
filter()->state().P() * H.transpose()) <<
"], Ix = [ " << (H *
filter()->state().P() * H.transpose()).inverse() <<
"]");
231 YawModel::MeasurementVector error(y - x);
232 error(0) = error(0) - 2.0*M_PI * round(error(0) / (2.0*M_PI));
236 ROS_DEBUG_STREAM_NAMED(
"poseupdate",
" ==> xy = " << x(0) * 180.0/M_PI <<
"°, Pxy = [ " << (H *
filter()->state().P() * H.transpose()) <<
" ], innovation = " << innovation);
246 Eigen::Vector3d update_linear(
update.twist->twist.twist.linear.x,
update.twist->twist.twist.linear.y,
update.twist->twist.twist.linear.z);
247 Eigen::Vector3d update_angular(
update.twist->twist.twist.angular.x,
update.twist->twist.twist.angular.y,
update.twist->twist.twist.angular.z);
253 ROS_DEBUG_STREAM_NAMED(
"poseupdate",
"TwistUpdate: state = [ " <<
filter()->state().getVector().transpose() <<
" ], P = [ " <<
filter()->state().getCovariance() <<
" ]" << std::endl
254 <<
" update: linear = [ " << update_linear.transpose() <<
" ], angular = [ " << update_angular.transpose() <<
" ], information = [ " << information <<
" ]");
258 if (!
update.twist->header.stamp.isZero()) {
261 ROS_DEBUG_STREAM_NAMED(
"poseupdate",
"Ignoring twist update as it has a negative time difference: dt = " << dt <<
"s");
265 ROS_DEBUG_STREAM_NAMED(
"poseupdate",
"Ignoring twist update as the time difference is too large: dt = " << dt <<
"s");
283 TwistModel::NoiseVariance Iy(information);
284 y.segment<3>(0) = update_linear;
285 y.segment<3>(3) = update_angular;
289 ROS_DEBUG_NAMED(
"poseupdate",
"Twist updates with covariance matrices are currently not supported");
294 if (information(0,0) > 0.0 || information(0,0) > 0.0) {
299 for(
int i = 0; i < 6; ++i) Iy(0,i) = Iy(1,i) = Iy(i,0) = Iy(i,1) = 0.0;
305 if (information(2,2) > 0.0) {
310 for(
int i = 0; i < 6; ++i) Iy(2,i) = Iy(i,2) = 0.0;
316 if (information(3,3) > 0.0 || information(4,4) > 0.0) {
321 for(
int i = 0; i < 6; ++i) Iy(3,i) = Iy(3,i) = Iy(i,4) = Iy(i,4) = 0.0;
327 if (information(5,5) > 0.0) {
332 for(
int i = 0; i < 6; ++i) Iy(5,i) = Iy(i,5) = 0.0;
338 ROS_DEBUG_STREAM_NAMED(
"poseupdate",
" x = [" << x.transpose() <<
"], H = [ " << H <<
" ], Px = [" << (H *
filter()->state().P() * H.transpose()) <<
"], Ix = [ " << (H *
filter()->state().P() * H.transpose()).inverse() <<
"]");
342 ROS_DEBUG_STREAM_NAMED(
"poseupdate",
" ==> xy = [" << x.transpose() <<
"], Pxy = [ " << (H *
filter()->state().P() * H.transpose()) <<
" ], innovation = " << innovation);
353 double tr_x = Ix.trace();
354 double tr_y = Iy.trace();
355 return tr_y / (tr_x + tr_y);
358 template <
typename MeasurementVector,
typename MeasurementMatrix,
typename NoiseVariance>
360 NoiseVariance H_Px_HT(H * state.
P() * H.transpose());
362 if (H_Px_HT.determinant() <= 0) {
363 ROS_DEBUG_STREAM(
"Ignoring poseupdate for " << text <<
" as the a-priori state covariance is zero!");
366 NoiseVariance Ix(H_Px_HT.inverse().eval());
372 if (alpha == 0.0 && beta == 0.0) {
384 if (max_error > 0.0) {
385 double error2 = (error.transpose() * Ix * (Ix + Iy).
inverse() * Iy * error)(0);
386 if (error2 > max_error * max_error) {
388 ROS_WARN_STREAM_NAMED(
"poseupdate",
"Ignoring poseupdate for " << text <<
" as the error [ " << error.transpose() <<
" ], |error| = " << sqrt(error2) <<
" sigma exceeds max_error!");
391 ROS_WARN_STREAM_NAMED(
"poseupdate",
"Update for " << text <<
" with error [ " << error.transpose() <<
" ], |error| = " << sqrt(error2) <<
" sigma exceeds max_error!");
392 jump_function(state, error);
403 NoiseVariance S_1(Ix - Ix * (Ix * alpha + Iy * beta).
inverse() * Ix);
407 double innovation = S_1.determinant();
408 state.
P() = state.
P() - P_HT * S_1 * P_HT.transpose();
409 state.
P().assertSymmetric();
410 state.
update(P_HT * Iy * beta * error);
434 state.
position()->vector().head<2>() += diff;
450 state.
position()->vector().segment<1>(
Z) += diff;
455 y_pred(0) = state.
getYaw();
475 S.block(state.
orientation()->getCovarianceIndex(), state.
orientation()->getCovarianceIndex(), 3, 3) = rotation.transpose();
480 S.block(state.
velocity()->getCovarianceIndex(), state.
velocity()->getCovarianceIndex(), 3, 3) = rotation.transpose();
481 state.
velocity()->vector() = rotation.transpose() * state.
velocity()->vector();
490 ROS_DEBUG_STREAM_NAMED(
"poseupdate",
"Jump yaw by " << (diff(0) * 180.0/M_PI) <<
" degrees. rotation = [" << rotation <<
"], S = [" << S <<
"].");
493 state.
P() = S * state.
P() * S.transpose();
498 y_pred.segment<3>(3) = state.
getRate();
509 state.
rate()->cols(C)(3,
X) = 1.0;
510 state.
rate()->cols(C)(4,
Y) = 1.0;
511 state.
rate()->cols(C)(5,
Z) = 1.0;