-
Notifications
You must be signed in to change notification settings - Fork 526
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create a transform subscribers to enable virtual joints #310
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.
|
@@ -200,7 +200,6 @@ int main(int argc, char** argv) | |||
|
|||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do always call startStateMonitor when constructing move_group & moveit_cpp
@@ -61,7 +60,6 @@ MoveItCpp::MoveItCpp(const rclcpp::Node::SharedPtr& node, const Options& options | |||
{ | |||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here the same, we should run a TransformListener independent of the CSM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same with this comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
@@ -200,7 +200,6 @@ int main(int argc, char** argv) | |||
|
|||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this comment is obsolete now, since parallel functionality was implemented through subscribers on the /tf
topic.
@@ -61,7 +60,6 @@ MoveItCpp::MoveItCpp(const rclcpp::Node::SharedPtr& node, const Options& options | |||
{ | |||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same with this comment.
@JafarAbdi Any thoughts on addressing @schornakj 's comments? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't this redundant in case of a transform exception?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
@@ -200,7 +200,6 @@ int main(int argc, char** argv) | |||
|
|||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
@@ -401,8 +408,11 @@ void CurrentStateMonitor::tfCallback() | |||
continue; | |||
} | |||
|
|||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// 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>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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