Description
A common requirement is to request the transform between two arbitrary frames at a specific timestamp, but, when that timestamp cannot be resolved, fall back to the freshest available data rather than waiting for updates across the entire chain.
The desired behavior would be:
- Attempt the normal time-coherent lookup at the requested timestamp.
- If that timestamp cannot be resolved, determine the frame chain between source and target.
- Retrieve the exact or latest available transform for each edge independently.
- Compose those transforms.
- Return the timestamps of the individual transforms that were used.
This would have deliberately different temporal semantics from the existing:
lookupTransform(target_frame, source_frame, TimePointZero)
which resolves to the latest common timestamp at which the complete transform chain can be evaluated.
Motivation
There are applications where requiring a common timestamp is unnecessarily restrictive.
For example, several transform publishers may operate independently at different frequencies: a consumer may care primarily that every transform in the chain is sufficiently recent rather than that every edge can be evaluated at exactly the same timestamp.
Typical use cases include:
- low-latency control or state-estimation consumers;
- systems where transform publishers are not synchronized;
- diagnostics which need to know the freshness of every edge in a transform chain.
The caller would explicitly opt into the fact that the resulting transform is not always temporally coherent in the usual tf2 sense -> this would be a separate API and would not change the semantics of lookupTransform.
Design / Implementation Considerations
For example:
TransformWithChain lookupTransformBestEffort(
const std::string & target_frame,
const std::string & source_frame,
const TimePoint & requested_time);
with a result such as:
struct TransformChainEntry
{
std::string parent_frame;
std::string child_frame;
TimePoint stamp;
bool is_static;
};
struct TransformWithChain
{
TransformStamped transform;
std::vector<TransformChainEntry> chain;
bool time_coherent;
};
It may be preferable for the composed transform's timestamp to remain zero if no exact lookup at the proposed ts is possible, but I don't have a strong preference.
Additional Information
Would such an explicitly non-time-coherent lookup be considered useful functionality for tf2::BufferCore?
Implementing this kind of behavior out of it with the current API is quite tricky (trying a normal lookup, then as fallback figuring out the chain through other methods and repeadetly call lookupTransform with and without TimePointZero), and likely way less efficient than what could be done with a native implementation.
Description
A common requirement is to request the transform between two arbitrary frames at a specific timestamp, but, when that timestamp cannot be resolved, fall back to the freshest available data rather than waiting for updates across the entire chain.
The desired behavior would be:
This would have deliberately different temporal semantics from the existing:
lookupTransform(target_frame, source_frame, TimePointZero)which resolves to the latest common timestamp at which the complete transform chain can be evaluated.
Motivation
There are applications where requiring a common timestamp is unnecessarily restrictive.
For example, several transform publishers may operate independently at different frequencies: a consumer may care primarily that every transform in the chain is sufficiently recent rather than that every edge can be evaluated at exactly the same timestamp.
Typical use cases include:
The caller would explicitly opt into the fact that the resulting transform is not always temporally coherent in the usual tf2 sense -> this would be a separate API and would not change the semantics of lookupTransform.
Design / Implementation Considerations
For example:
with a result such as:
It may be preferable for the composed transform's timestamp to remain zero if no exact lookup at the proposed ts is possible, but I don't have a strong preference.
Additional Information
Would such an explicitly non-time-coherent lookup be considered useful functionality for tf2::BufferCore?
Implementing this kind of behavior out of it with the current API is quite tricky (trying a normal lookup, then as fallback figuring out the chain through other methods and repeadetly call lookupTransform with and without TimePointZero), and likely way less efficient than what could be done with a native implementation.