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

drop or reset upon large forward time jump #200

Open
wants to merge 5 commits into
base: noetic
Choose a base branch
from

Conversation

nachumlerner
Copy link

this PR is similar to #165

We discussed this a while ago (ref: #160).
The proposed solution adds the ability to drop/reset upon jump forward in time stamp

@@ -91,6 +91,8 @@ class ImuFilterRos
bool stateless_;
bool publish_tf_;
bool reverse_tf_;
bool refuse_large_time_update_;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This variable is never read and can be removed.

@@ -168,6 +182,10 @@ ImuFilterRos::~ImuFilterRos()
void ImuFilterRos::imuCallback(const ImuMsg::ConstPtr& imu_msg_raw)
{
checkTimeJump();
if (checkLargeTimeJumpForward(imu_msg_raw->header.stamp))
{
return; // large jump don't use reading
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't understand this comment. It should be something like "reject measurement if large time jump forward detected".

(repeated on line 253)

bool largeJump = false;
if (constant_dt_ > 0.0)
{
return largeJump; // use constant dt
Copy link
Collaborator

Choose a reason for hiding this comment

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

This can be simplified to return false;.

Also, the comment is not very helpful. It should be something like "don't reject measurement on large jump if using constant dt". But why does that make sense? Shouldn't we do the opposite (always reject if using constant_dt)?

Copy link
Author

Choose a reason for hiding this comment

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

We will change the comment and the return statement. If dt is constant, it doesn't matter what the jump in the timestamp is, so we should use the measurement.

(imu_stamp - last_time_).toSec());
largeJump = true;
last_time_ = imu_stamp; // save time for next move
if (reset_large_forward_time_jump_)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if we shouldn't always reset. This would simplify the code a lot:

  • we can remove the reset_large_forward_time_jump parameter
  • we can probably even remove the return value from this function, and the largeJump variable
  • we can make this function very similar to checkTimeJump(), and perhaps even merge this function into it.

Also, it sounds safer to always reset. The current implementation only rejects the first measurement after a large jump forward, but if the filter isn't reset, the next message will still have a large jump in values with a small dt, so rejecting the first measurement doesn't help at all.

Copy link
Author

Choose a reason for hiding this comment

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

I don't think we should always reset. In our application, we experience one large time jump when our robot establishes communication. It could be very dangerous to reset the IMU suddenly. Instead, I believe it is better to ignore one measurement. Why should the next message have a large jump in values?

Copy link
Collaborator

@mintar mintar May 31, 2024

Choose a reason for hiding this comment

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

Ah yes, after reading #160 again I remember the dilemma in your application. There can be two sources of large forward time jumps between two consecutive messages:

  1. Pause: If the connection to the IMU was lost somehow and messages were dropped for an extensive time, when the first message arrives again you get a large time jump and a large jump in values (because the IMU was moved in the meantime).
  2. Clock update: There is no connection error, and the IMU messages arrive continuously at the same rate, but the clock was moved forward between two messages. There's a large time jump but no large jump in values.

You're trying to deal with case 2 here, but I was thinking about case 1.

As I already wrote in #160 (comment), I think it's a bad idea to try to handle case 2 in the imu_filter_madgwick.

The source of the problem is the incorrect system clock. You are feeding bad data with incorrect time stamps (and a time jump) to all downstream software (such as imu_filter_madgwick). This will cause bad behavior in hundreds of different places, often with very subtle effects that will be a nightmare to track down.

Instead of trying to make the downstream software deal with incorrect inputs, you should fix the problem at the source and provide correct time stamps. Two wrongs don't make a right.

There are many ways you could fix the time jumps:

  1. Add a real time clock to the robot (they only cost a couple of bucks).
  2. Don't update the time after connecting to the internet.
  3. First connect to the internet, wait until the time is updated, then start the ROS software.
  4. Detect when time jumps happen and restart the ROS software then.
  5. ...

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.

2 participants