-
Notifications
You must be signed in to change notification settings - Fork 225
Description
Bug report / Missing functionality
Required Info:
- Operating System:
- OpenSUSE 15.5
- Installation type:
- binaries
- Version or commit hash:
- Humble
- DDS implementation:
- N/A
- Client library (if applicable):
- rclpy
Explanation
In tf2 for ros1 there existed a function to retrieve the chain of two frames as a list of strings. Now migrating to ros2, we need the functionality of this function. The corresponding function of tf2 for ros2 is here:
geometry2/tf2/src/buffer_core.cpp
Lines 1549 to 1631 in c3cafef
| void BufferCore::_chainAsVector( | |
| const std::string & target_frame, TimePoint target_time, | |
| const std::string & source_frame, TimePoint source_time, | |
| const std::string & fixed_frame, | |
| std::vector<std::string> & output) const | |
| { | |
| std::string error_string; | |
| output.clear(); // empty vector | |
| std::unique_lock<std::mutex> lock(frame_mutex_); | |
| TransformAccum accum; | |
| // Get source frame/time using getFrame | |
| CompactFrameID source_id = lookupFrameNumber(source_frame); | |
| CompactFrameID fixed_id = lookupFrameNumber(fixed_frame); | |
| CompactFrameID target_id = lookupFrameNumber(target_frame); | |
| std::vector<CompactFrameID> source_frame_chain; | |
| tf2::TF2Error retval = walkToTopParent( | |
| accum, source_time, fixed_id, source_id, &error_string, | |
| &source_frame_chain); | |
| if (retval != tf2::TF2Error::TF2_NO_ERROR) { | |
| switch (retval) { | |
| case tf2::TF2Error::TF2_CONNECTIVITY_ERROR: | |
| throw ConnectivityException(error_string); | |
| case tf2::TF2Error::TF2_EXTRAPOLATION_ERROR: | |
| throw ExtrapolationException(error_string); | |
| case tf2::TF2Error::TF2_LOOKUP_ERROR: | |
| throw LookupException(error_string); | |
| default: | |
| CONSOLE_BRIDGE_logError("Unknown error code: %d", retval); | |
| assert(0); | |
| } | |
| } | |
| if (source_time != target_time) { | |
| std::vector<CompactFrameID> target_frame_chain; | |
| retval = walkToTopParent( | |
| accum, target_time, target_id, fixed_id, &error_string, | |
| &target_frame_chain); | |
| if (retval != tf2::TF2Error::TF2_NO_ERROR) { | |
| switch (retval) { | |
| case tf2::TF2Error::TF2_CONNECTIVITY_ERROR: | |
| throw ConnectivityException(error_string); | |
| case tf2::TF2Error::TF2_EXTRAPOLATION_ERROR: | |
| throw ExtrapolationException(error_string); | |
| case tf2::TF2Error::TF2_LOOKUP_ERROR: | |
| throw LookupException(error_string); | |
| default: | |
| CONSOLE_BRIDGE_logError("Unknown error code: %d", retval); | |
| assert(0); | |
| } | |
| } | |
| size_t m = target_frame_chain.size(); | |
| size_t n = source_frame_chain.size(); | |
| while (m > 0u && n > 0u) { | |
| --m; | |
| --n; | |
| if (source_frame_chain[n] != target_frame_chain[m]) { | |
| break; | |
| } | |
| } | |
| // Erase all duplicate items from frame_chain | |
| if (n > 0u) { | |
| source_frame_chain.erase(source_frame_chain.begin() + (n - 1u), source_frame_chain.end()); | |
| } | |
| if (m < target_frame_chain.size()) { | |
| for (size_t i = 0u; i <= m; ++i) { | |
| source_frame_chain.push_back(target_frame_chain[i]); | |
| } | |
| } | |
| } | |
| // Write each element of source_frame_chain as string | |
| for (size_t i = 0u; i < source_frame_chain.size(); ++i) { | |
| output.push_back(lookupFrameString(source_frame_chain[i])); | |
| } | |
| } | |
| } // namespace tf2 |
However, it is now not wrapped as a listener function but can only be accessed via the private member function buffer._chain(). The bigger problem is that the implementation seems erroneous. Consider this simple tf tree:
A
/ \
B D
|
C
Querying _chainAsVector(target_frame=D, source_frame=C, fixed_frame=A) (regardless of the time), yields the chain ['C', 'B'] and not as expected ['C', 'B', 'A', 'D'].
Does anyone have an idea why it is like this?
And also why the implementation changed from ros1 tf2 to ros2 tf2 (compare upper links) while the previous implementation worked just fine?
Is there a similar function that I don't know of that can achieve the same thing (python)?