-
Notifications
You must be signed in to change notification settings - Fork 392
Add filtering capability and publishers for additional frames to fts broadcaster #559
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
Add filtering capability and publishers for additional frames to fts broadcaster #559
Conversation
I think the build fail due to a change in the controller_interface (ros-controls/ros2_control@fea2d8a) not yet accessible by the CI ? |
ebaa3d6
to
8163413
Compare
This pull request is in conflict. Could you fix it @guihomework? |
This PR is stale because it has been open for 45 days with no activity. Please tag a maintainer for help on completing this PR, or close it if you think it has become obsolete. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #559 +/- ##
==========================================
- Coverage 86.42% 86.37% -0.05%
==========================================
Files 123 124 +1
Lines 12231 12400 +169
Branches 1021 1031 +10
==========================================
+ Hits 10571 10711 +140
- Misses 1344 1366 +22
- Partials 316 323 +7
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
This pull request is in conflict. Could you fix it @guihomework? |
…ility-to-fts-broadcaster-rolling
.github/workflows/rolling-compatibility-humble-binary-build.yml
Outdated
Show resolved
Hide resolved
…ility-to-fts-broadcaster-rolling
Hello @christophfroehlich, I'm interested in finishing this PR. I did some preliminary testing (in Humble) and it seems to be working fine. Some Could you provide me with some suggestions on how to do this? Namely:
Thanks a lot! P.D. @guihomework are you interested in finishing this? |
I can fix the latest conflicts in the next days. This PR was ready to merge, only reviews were missing. |
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.
Functionally looks good to me. Just some readability/maintainability comments.
force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp
Outdated
Show resolved
Hide resolved
// TODO(juliaj): remove the logging after resolving | ||
// https://github.com/ros-controls/ros2_controllers/issues/1574 | ||
RCLCPP_INFO(get_node()->get_logger(), "Locking realtime publisher"); | ||
realtime_publisher_->lock(); | ||
RCLCPP_INFO(get_node()->get_logger(), "Locked realtime publisher"); | ||
|
||
realtime_publisher_->msg_.header.frame_id = params_.frame_id; | ||
|
||
RCLCPP_INFO(get_node()->get_logger(), "Unlocking realtime publisher"); | ||
realtime_publisher_->unlock(); | ||
RCLCPP_INFO(get_node()->get_logger(), "Unlocked realtime publisher"); | ||
RCLCPP_INFO(get_node()->get_logger(), "Locking realtime_raw_publisher"); | ||
realtime_raw_publisher_->lock(); | ||
RCLCPP_INFO(get_node()->get_logger(), "Locked realtime_raw_publisher"); | ||
realtime_raw_publisher_->msg_.header.frame_id = params_.frame_id; | ||
RCLCPP_INFO(get_node()->get_logger(), "Unlocking realtime_raw_publisher"); | ||
realtime_raw_publisher_->unlock(); | ||
RCLCPP_INFO(get_node()->get_logger(), "Unlocked realtime_raw_publisher"); | ||
|
||
RCLCPP_INFO(get_node()->get_logger(), "Locking realtime_filtered_publisher"); | ||
realtime_filtered_publisher_->lock(); | ||
RCLCPP_INFO(get_node()->get_logger(), "Locked realtime_filtered_publisher"); | ||
realtime_filtered_publisher_->msg_.header.frame_id = params_.frame_id; | ||
RCLCPP_INFO(get_node()->get_logger(), "Unlocking realtime_filtered_publisher"); | ||
realtime_filtered_publisher_->unlock(); | ||
RCLCPP_INFO(get_node()->get_logger(), "Unlocked realtime_filtered_publisher"); |
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.
Seems like the logging can be pulled out. The linked issue is closed, and it doesn't seem to add much valuable information. If we do want to keep it, maybe set it to debug rather than info.
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 cleaned it up: the respective logging was reverted on the master branch.
force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster_parameters.yaml
Outdated
Show resolved
Hide resolved
This pull request is in conflict. Could you fix it @guihomework? |
Co-authored-by: Xavier Guay <[email protected]>
Co-authored-by: Xavier Guay <[email protected]>
@OscarMrZ could you leave your review here please? I fixed the merge conflicts, and failing binary tests are due to upstream changes. |
std::string sensor_name_; | ||
std::array<std::string, 6> interface_names_; |
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.
Do we need these?, don't we have the same information in the GPL params?
return CallbackReturn::ERROR; | ||
} | ||
if (!filter_chain_->configure( | ||
"sensor_filter_chain", get_node()->get_node_logging_interface(), |
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.
Can you add some documentation of the sensor_filter_chain
namespace and how it can be used to configure filters?
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 happens currently if there is no filter configuration present in the params? THis would fail and the broadcaster won't activate right?. I believe this shouldn't be the case
// Add additional frames to publish if any exits | ||
if (!params_.additional_frames_to_publish.empty()) | ||
{ | ||
auto nr_frames = params_.additional_frames_to_publish.size(); | ||
wrench_additional_frames_pubs_.reserve(nr_frames); | ||
wrench_additional_frames_publishers_.reserve(nr_frames); | ||
for (const auto & frame : params_.additional_frames_to_publish) | ||
{ | ||
StatePublisher pub = get_node()->create_publisher<WrenchMsgType>( | ||
"~/wrench_filtered_" + frame, rclcpp::SystemDefaultsQoS()); | ||
wrench_additional_frames_pubs_.emplace_back(pub); | ||
wrench_additional_frames_publishers_.emplace_back(std::make_unique<StateRTPublisher>(pub)); | ||
|
||
wrench_additional_frames_publishers_.back()->lock(); | ||
wrench_additional_frames_publishers_.back()->msg_.header.frame_id = frame; | ||
wrench_additional_frames_publishers_.back()->unlock(); | ||
} |
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 don't know if we should do this here. I think every individual should be responsible for transforming to their desired one. I don't think it make sense to transform and do it and have publisher for each of those.
if (!filtered) | ||
{ | ||
wrench_filtered_.wrench.force.x = std::numeric_limits<double>::quiet_NaN(); | ||
wrench_filtered_.wrench.force.y = std::numeric_limits<double>::quiet_NaN(); | ||
wrench_filtered_.wrench.force.z = std::numeric_limits<double>::quiet_NaN(); | ||
wrench_filtered_.wrench.torque.x = std::numeric_limits<double>::quiet_NaN(); | ||
wrench_filtered_.wrench.torque.y = std::numeric_limits<double>::quiet_NaN(); | ||
wrench_filtered_.wrench.torque.z = std::numeric_limits<double>::quiet_NaN(); | ||
} | ||
|
||
if (realtime_filtered_publisher_ && realtime_filtered_publisher_->trylock()) |
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.
if (!filtered) | |
{ | |
wrench_filtered_.wrench.force.x = std::numeric_limits<double>::quiet_NaN(); | |
wrench_filtered_.wrench.force.y = std::numeric_limits<double>::quiet_NaN(); | |
wrench_filtered_.wrench.force.z = std::numeric_limits<double>::quiet_NaN(); | |
wrench_filtered_.wrench.torque.x = std::numeric_limits<double>::quiet_NaN(); | |
wrench_filtered_.wrench.torque.y = std::numeric_limits<double>::quiet_NaN(); | |
wrench_filtered_.wrench.torque.z = std::numeric_limits<double>::quiet_NaN(); | |
} | |
if (realtime_filtered_publisher_ && realtime_filtered_publisher_->trylock()) | |
if (filtered && realtime_filtered_publisher_ && realtime_filtered_publisher_->trylock()) |
If the filtering is failing, just don't publish it. Publishing NaNs might mess up other's code right?
publisher->msg_.header.frame_id.c_str(), e.what()); | ||
publisher->msg_.wrench.force.x = std::numeric_limits<double>::quiet_NaN(); | ||
publisher->msg_.wrench.force.y = std::numeric_limits<double>::quiet_NaN(); | ||
publisher->msg_.wrench.force.z = std::numeric_limits<double>::quiet_NaN(); | ||
publisher->msg_.wrench.torque.x = std::numeric_limits<double>::quiet_NaN(); | ||
publisher->msg_.wrench.torque.y = std::numeric_limits<double>::quiet_NaN(); | ||
publisher->msg_.wrench.torque.z = std::numeric_limits<double>::quiet_NaN(); |
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.
If it fails, just don't publish it. Better skip that iteration
auto transform = tf_buffer_->lookupTransform( | ||
publisher->msg_.header.frame_id, params_.frame_id, tf2::TimePointZero); | ||
tf2::doTransform(wrench_filtered_, publisher->msg_, transform); | ||
} | ||
else | ||
{ | ||
throw tf2::TransformException("cannot transform, filtered message is invalid"); | ||
} |
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'm not a big fan of having tf inside the RT loops. If this is the case, I would ask you to time it and share the results on how much time it consumes 1. static transforms 2. dynamic transforms
We can close this in favor of creating a new node that transforms the input Wrench topic to output Wrench topic. |
Is a rebase of #269, using ParameterListener, with additional tests and some fixes.
Also already includes revised #268
depends on ros-controls/control_toolbox#152 and ros-controls/control_toolbox#153