Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevention of (0,0,0) Gps Odometry Due To Failed Transform #40

Conversation

1hada
Copy link

@1hada 1hada commented Sep 21, 2023

Overview

Impact

  • There is a bug in which the navsat transform can send an invalid (0,0,0) gps odometry message. this results in downstream users receiving invalid data and not realizing this. This can cause safety concerns in which a vehicle will react very differently than expected.
  • This PR mitigates this safety issue by preventing the navsat transform from sending invalid gps odometry when the transform is unavailable.

Description

  • Logged data shows that a valid GPS update can result in an invalid (0,0,0) GPS odometry message sent from the navsat transform.
  • This issue was tracked to the navsat transform not finding the last transform when needed.
  • The navsat transform code only logs a throttled message, but does not prevent the invalid data from being sent.
  • This PR prevents the invalid data from being sent to avoid downstream users from receiving invalid data.
  • Since the output data is typically used as measurements into a filter (e.g. the Kalman Filters in this package), the filter should not be harmed by the lack of update and will instead grow the covariance. We suggest monitoring to prevent acting on high covariances from the filter.

Changes

  • Added check for whether the Transform between the GPS module and the Base Link was successful.
  • Not publishing GPS odometry if the Transform between GPS and baselink is not successful. OR if the transform between baselink and world frame is not available.

Testing:

  • Tests were conducted using NEWTIME=$(date -d "$(date '+%F %T.%N Z') - 0.5 second" '+%F %T.%N') ; timedatectl set-time "$NEWTIME" after making sure set-ntp was set to false.
  • Tests were also conducted using NEWTIME=$(date -d "$(date '+%F %T.%N Z') - 30.5 second" '+%F %T.%N') ; timedatectl set-time "$NEWTIME" after making sure set-ntp was set to false.
  • In all tests, no (0,0,0) was observed as a result of the time shift. This shows the fix passes.

Checklist:

  • PR Title updated to include [Platforms]
  • Write entry on CHANGELOG.rst
  • Tested on vehicle

@shortcut-integration
Copy link

Comment on lines +874 to +908
// Rotate the covariance as well
tf2::Matrix3x3 rot(cartesian_world_transform_.getRotation());
Eigen::MatrixXd rot_6d(POSE_SIZE, POSE_SIZE);
rot_6d.setIdentity();

// Rotate the covariance
latest_cartesian_covariance_ = rot_6d * latest_cartesian_covariance_.eval() * rot_6d.transpose();
for (size_t rInd = 0; rInd < POSITION_SIZE; ++rInd)
{
rot_6d(rInd, 0) = rot.getRow(rInd).getX();
rot_6d(rInd, 1) = rot.getRow(rInd).getY();
rot_6d(rInd, 2) = rot.getRow(rInd).getZ();
rot_6d(rInd+POSITION_SIZE, 3) = rot.getRow(rInd).getX();
rot_6d(rInd+POSITION_SIZE, 4) = rot.getRow(rInd).getY();
rot_6d(rInd+POSITION_SIZE, 5) = rot.getRow(rInd).getZ();
}

// Now fill out the message. Set the orientation to the identity.
tf2::toMsg(transformed_cartesian_robot, gps_odom.pose.pose);
gps_odom.pose.pose.position.z = (zero_altitude_ ? 0.0 : gps_odom.pose.pose.position.z);
// Rotate the covariance
latest_cartesian_covariance_ = rot_6d * latest_cartesian_covariance_.eval() * rot_6d.transpose();

// Copy the measurement's covariance matrix so that we can rotate it later
for (size_t i = 0; i < POSE_SIZE; i++)
{
for (size_t j = 0; j < POSE_SIZE; j++)
// Now fill out the message. Set the orientation to the identity.
tf2::toMsg(transformed_cartesian_robot, gps_odom.pose.pose);
gps_odom.pose.pose.position.z = (zero_altitude_ ? 0.0 : gps_odom.pose.pose.position.z);

// Copy the measurement's covariance matrix so that we can rotate it later
for (size_t i = 0; i < POSE_SIZE; i++)
{
gps_odom.pose.covariance[POSE_SIZE * i + j] = latest_cartesian_covariance_(i, j);
for (size_t j = 0; j < POSE_SIZE; j++)
{
gps_odom.pose.covariance[POSE_SIZE * i + j] = latest_cartesian_covariance_(i, j);
}
}
}

// Mark this GPS as used
gps_updated_ = false;
new_data = true;
// Mark this GPS as used
gps_updated_ = false;
new_data = true;
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That code was only indented. not changed.

gps_updated_ = false;
new_data = true;
// Mark this GPS as used
gps_updated_ = false;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to do something with this class-member variable in an else condition? If gps_updated_ remains true, what consequence does that have?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If gps_updated_ remains true, what consequence does that have?

The only consequence is that next time the prepareGpsOdometry(..) is called , then it would use the latest latest_cartesian_pose_ ( made from the latest time a gps fix message was received.) . We'd also be using that latest gps fix header time as well.

@1hada 1hada changed the title [Intrepid] Prevention of (0,0,0) Gps Odometry Due To Failed Transform Prevention of (0,0,0) Gps Odometry Due To Failed Transform Sep 22, 2023
@1hada 1hada merged commit ee5cfe1 into noetic-devel Sep 22, 2023
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants