Create a transform subscribers to enable virtual joints#310
Create a transform subscribers to enable virtual joints#310JafarAbdi merged 17 commits intomoveit:mainfrom
Conversation
Codecov Report
@@ Coverage Diff @@
## main #310 +/- ##
==========================================
+ Coverage 53.98% 54.12% +0.14%
==========================================
Files 190 190
Lines 20002 20034 +32
==========================================
+ Hits 10796 10841 +45
+ Misses 9206 9193 -13
Continue to review full report at Codecov.
|
|
|
||
| std::shared_ptr<tf2_ros::Buffer> tf_buffer = | ||
| std::make_shared<tf2_ros::Buffer>(nh->get_clock(), tf2::durationFromSec(10.0)); | ||
| std::shared_ptr<tf2_ros::TransformListener> tfl = std::make_shared<tf2_ros::TransformListener>(*tf_buffer); |
There was a problem hiding this comment.
We shouldn't rely on the CurrentStateMonitor to fill the tf_buffer. The TransformListener is required for the PlanningSceneMonitor to work without it.
There was a problem hiding this comment.
I think this comment is obsolete now, since parallel functionality was implemented through subscribers on the /tf topic.
There was a problem hiding this comment.
How is this comment obsolete? The subscribers are initialized inside the CSM so unless we call PSM::startStateMonitor() there won't be any listeners updating the buffer. A reasonable workaround would be to move the transform subscribers into the PSM and to call CSM::updateMultiDofJoints from there. What do you think?
There was a problem hiding this comment.
We do always call startStateMonitor when constructing move_group & moveit_cpp
| { | ||
| if (!tf_buffer_) | ||
| tf_buffer_ = std::make_shared<tf2_ros::Buffer>(node_->get_clock()); | ||
| tf_listener_ = std::make_shared<tf2_ros::TransformListener>(*tf_buffer_); |
There was a problem hiding this comment.
Here the same, we should run a TransformListener independent of the CSM.
There was a problem hiding this comment.
See my previous comment
|
I thought about this and I don't think we should merge this solution. We should have an independent TransformListener running at all times. If that's not possible, we might implement our own listener that supports callbacks. |
7afc314 to
d0cd946
Compare
d0cd946 to
534cc10
Compare
moveit_ros/planning/planning_scene_monitor/src/current_state_monitor.cpp
Outdated
Show resolved
Hide resolved
|
|
||
| std::shared_ptr<tf2_ros::Buffer> tf_buffer = | ||
| std::make_shared<tf2_ros::Buffer>(nh->get_clock(), tf2::durationFromSec(10.0)); | ||
| std::shared_ptr<tf2_ros::TransformListener> tfl = std::make_shared<tf2_ros::TransformListener>(*tf_buffer); |
There was a problem hiding this comment.
I think this comment is obsolete now, since parallel functionality was implemented through subscribers on the /tf topic.
| { | ||
| if (!tf_buffer_) | ||
| tf_buffer_ = std::make_shared<tf2_ros::Buffer>(node_->get_clock()); | ||
| tf_listener_ = std::make_shared<tf2_ros::TransformListener>(*tf_buffer_); |
|
@JafarAbdi Any thoughts on addressing @schornakj 's comments? |
There was a problem hiding this comment.
Sorry for letting the reviews pend for so long. I think this PR is really getting there but the original complaint doesn't seem to be fixed, which is that the PSM doesn't update TF if the CSM is not initialized (please correct me if I'm wrong). This could for instance break the planning scene display as that one doesn't listen for joint states explicitly. The callback implementation looks good to me on its own (argree, no class required) but please consider moving them into the PSM and updating the transforms from there (see comment).
moveit_ros/planning/planning_scene_monitor/src/current_state_monitor.cpp
Outdated
Show resolved
Hide resolved
moveit_ros/planning/planning_scene_monitor/src/current_state_monitor.cpp
Outdated
Show resolved
Hide resolved
| transform.child_frame_id.c_str(), transform.header.frame_id.c_str(), temp.c_str()); | ||
| } | ||
| } | ||
| updateMultiDofJoints(); |
There was a problem hiding this comment.
isn't this redundant in case of a transform exception?
There was a problem hiding this comment.
What if the exception happened after adding few transforms to the buffer .?
...lanning/planning_scene_monitor/include/moveit/planning_scene_monitor/current_state_monitor.h
Outdated
Show resolved
Hide resolved
|
|
||
| std::shared_ptr<tf2_ros::Buffer> tf_buffer = | ||
| std::make_shared<tf2_ros::Buffer>(nh->get_clock(), tf2::durationFromSec(10.0)); | ||
| std::shared_ptr<tf2_ros::TransformListener> tfl = std::make_shared<tf2_ros::TransformListener>(*tf_buffer); |
There was a problem hiding this comment.
How is this comment obsolete? The subscribers are initialized inside the CSM so unless we call PSM::startStateMonitor() there won't be any listeners updating the buffer. A reasonable workaround would be to move the transform subscribers into the PSM and to call CSM::updateMultiDofJoints from there. What do you think?
0eb4492 to
16814bb
Compare
a0b6b0c to
9f3be3e
Compare
|
I think this PR is ready to be merged, regarding having an independent transform listener for PSM I didn't change the behavior from ROS1, the user have to provide it themselves unless a current state monitor is also enabled in that case a warning message will be print telling that the transforms will be added by both transform listener & current state monitor's callbacks |
moveit_ros/planning/planning_scene_monitor/src/current_state_monitor.cpp
Outdated
Show resolved
Hide resolved
moveit_ros/planning/planning_scene_monitor/src/current_state_monitor.cpp
Outdated
Show resolved
Hide resolved
moveit_ros/planning/planning_scene_monitor/src/current_state_monitor.cpp
Show resolved
Hide resolved
moveit_ros/planning/planning_scene_monitor/src/current_state_monitor.cpp
Show resolved
Hide resolved
moveit_ros/planning/planning_scene_monitor/src/current_state_monitor.cpp
Show resolved
Hide resolved
| if (auto joint_time_it = joint_time_.find(joint); joint_time_it == joint_time_.end()) | ||
| joint_time_.emplace(joint, rclcpp::Time(0, 0, RCL_ROS_TIME)); | ||
|
|
||
| // allow update if time is more recent or if it is a static transform (time = 0) |
There was a problem hiding this comment.
| // allow update if time is more recent or if it is a static transform (time = 0) | |
| // skip if time is not more recent and is not a static transform (time = 0) |
Comments should use the same logic as the conditionals, don't make the person parsing it invert conditions.
9f3be3e to
56f718c
Compare
…onitor.cpp Co-authored-by: Nathan Brooks <nbbrooks@gmail.com>
…onitor.cpp Co-authored-by: Nathan Brooks <nbbrooks@gmail.com>
henningkayser
left a comment
There was a problem hiding this comment.
LGTM! Also, thanks for the tests @JafarAbdi. This fix is good for now, but I think this PR exposes serious flaws in the PSM API that should be addressed.
Using an external TF listener is discouraged now in case CSM is used since transforms callbacks would be duplicate. This should be documented and ideally checked for inside the PSM constructor. If the CSM is not used, an external listener is strictly required to keep transforms updated. For the PSM it means that it's highly questionable if tf_buffer receives updated transforms or not. Obviously, some of this confusion was already present in ROS 1, but this PR makes it just a little bit more confusing.
One way to guarantee that PSM has a valid listener would be to:
- Remove/Deprecate tf_buffer from PSM constructors
- Initialize a private tf_listener inside PSM, possibly using startTFListener() to make this optional
- Stop tf_listener with
startStateMonitor(), restart it withstopStateMonitor()
(this is definitely out of scope of this PR)
tylerjw
left a comment
There was a problem hiding this comment.
Thank you for adding this. I generally agree with Henning that this part of the code needs a closer look to make the correct use of the API more obvious.
Description
Fix: #261
Fix: #251
Checklist