rclcpp icon indicating copy to clipboard operation
rclcpp copied to clipboard

Time: Differentiating Between Uninitialized and Zero-Initialized

Open methylDragon opened this issue 3 years ago • 1 comments

Feature request

Context

Currently in the design docs it's stated that A time value of zero should be considered an error meaning that time is uninitialized (though it's ambiguous whether this applies to time abstractions using all clock types or using just the ROS clock type.)

Feature description

Currently there is no way to create an rclcpp::Time object pointing to 0 without it also meaning that it is uninitialized.

I'm thinking of adding a flag that represents time "validity" that is set if a time object is set to a non-zero time, or if a parameter passed in explicitly forces it to be valid.

That is:

rclcpp::Time(0, 0, <some rcl_clock_type_t>).initialized();  // INVALID, uninitialized time
rclcpp::Time(1, 0, <some rcl_clock_type_t>).initialized(); // Valid
rclcpp::Time(0, 0, <some rcl_clock_type_t>, true).initialized(); // Valid too

This would allow for creating a notion of zero-time/earliest possible time for use with comparisons. Would this be a good idea to implement?

Implementation considerations

One possible reason for not wanting to implement this is that one could use rclcpp::Time(0, 1) (representing a time point 1 nanosecond from the clock epoch) instead as the 'zero-time', but it seems a little unintuitive that 0 would be necessarily invalid.

I guess another reason for not wanting this is that the Time message doesn't provide a way to differentiate between an uninitialized time message (0, 0) and a message that's been explicitly set to (0, 0).

Some downstream users of rclcpp::Time who are relying on rclcpp::Time(0, 0) continuing to be invalid will not be broken, up until they decide to pass the initialize flag, in which case they should migrate to using the initialized() getter.

methylDragon avatar Oct 14 '22 21:10 methylDragon

Hi! I would also like to have a more explicit way to see whether time is initialized.

Did you consider tf2's semantics of zero stamps (see e.g. this tutorial)? They also have the tf2::TimePointZero construct. Apparently, this corresponds to rclcpp::Time(0,0). However, in the tf2 context, it does not mean "invalid", but "latest available". I think this difference in meaning is confusing and could be made cleaner with what you suggest to implement.

Another case I just struggled with had to do with sim time. When using sim time, depending on your clock source, it is likely that you end up using stamps at zero or very close to zero after application startup. Being able to explicitly differentiate between uninitialized / invalid time and a correct time at zero would be nice.

Cakem1x avatar Nov 20 '24 14:11 Cakem1x