`waitForTransform()` throws an exception even though the future should be ready
@clalancette is already working on this.
Since Dec 3, 2020.
- Dominant language
- C++
- Stars
- 153
- Forks
- 256
- Avg merge
- 3d 23h
- Merged PRs (30d)
- 14
Description
Bug report
Required Info:
- Operating System: Ubuntu 20.04
- Installation type: Binaries
- Version or commit hash: Foxy
- DDS implementation: rmw_cyclonedds_cpp
- Client library (if applicable): rclcpp
Steps to reproduce issue
I made a simple test package with one node that sends two transforms and one node that requests a transform that can be interpolated from those two.
git clone git@github.com:nnmm/tf2_example.git
cd tf2_example
git checkout 5b837b82b15555f1cd5f35df3987b8e95c172e19 # for reproducibility in case the main branch changes
colcon build
source install/setup.bash
ros2 launch wait_for_transform wait_for_transform.launch.xml \
executor:=single \
method:=wft_wait_for \
request_time:=newest \
send_first_tf:=during \
send_second_tf:=after
It doesn't matter whether the second transform is sent during or after the waiting period.
The code that makes the request request looks essentially like this (wft_wait_for method in receiver.cpp):
auto future = tf_buffer_.waitForTransform("a", "b", tf2::TimePointZero, timeout_, callback_);
auto status = future.wait_for(timeout_);
if (status == std::future_status::deferred) {
RCLCPP_INFO(get_logger(), "Status is deferred");
} else if (status == std::future_status::timeout) {
RCLCPP_INFO(get_logger(), "Status is timeout");
} else {
RCLCPP_INFO(get_logger(), "Status is ready, calling future.get()");
const auto lu_time = tf2_ros::fromMsg(future.get().header.stamp);
}
Expected behavior
The most recent transform is requested, so as soon as the first transform arrives (which happens during the waiting period), I should be able to obtain the transform.
Actual behavior
The future has status ready as you'd hope, but an exception is thrown by get():
[receiver-2] [INFO] [1605268518.458370419] [receiver.callback]: Calling get() ...
[receiver-2] [INFO] [1605268518.458434859] [receiver]: Status is ready, calling future.get()
[receiver-2] terminate called after throwing an instance of 'tf2::LookupException'
Additional information
I haven't done much with futures before, but this seems like the way it could plausibly work, given https://github.com/ros2/geometry2/issues/347 and https://github.com/ros2/geometry2/issues/346 (only guessing since there is no documentation).
The timeout given to waitForTransform doesn't seem to matter anymore, only the timeout given to wait_for().
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.