Skip to content

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

Conversation

guihomework
Copy link
Contributor

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

@guihomework
Copy link
Contributor Author

I think the build fail due to a change in the controller_interface (ros-controls/ros2_control@fea2d8a) not yet accessible by the CI ?

@destogl destogl force-pushed the add-filtering-capability-to-fts-broadcaster-rolling branch from ebaa3d6 to 8163413 Compare April 13, 2023 12:32
Copy link
Contributor

mergify bot commented Feb 5, 2024

This pull request is in conflict. Could you fix it @guihomework?

Copy link
Contributor

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.

@github-actions github-actions bot added the stale label Apr 11, 2025
Copy link

codecov bot commented Apr 11, 2025

Codecov Report

❌ Patch coverage is 83.87097% with 30 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.37%. Comparing base (9e89020) to head (63dcce2).
⚠️ Report is 16 commits behind head on master.

Files with missing lines Patch % Lines
...roadcaster/src/force_torque_sensor_broadcaster.cpp 68.83% 21 Missing and 3 partials ⚠️
...ster/test/test_force_torque_sensor_broadcaster.cpp 85.71% 1 Missing and 2 partials ⚠️
...t_force_torque_sensor_broadcaster_with_filters.cpp 96.59% 0 Missing and 3 partials ⚠️
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     
Flag Coverage Δ
unittests 86.37% <83.87%> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...ster/test/test_force_torque_sensor_broadcaster.cpp 96.73% <85.71%> (-1.43%) ⬇️
...t_force_torque_sensor_broadcaster_with_filters.cpp 96.59% <96.59%> (ø)
...roadcaster/src/force_torque_sensor_broadcaster.cpp 81.76% <68.83%> (-10.74%) ⬇️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

mergify bot commented Apr 11, 2025

This pull request is in conflict. Could you fix it @guihomework?

@OscarMrZ
Copy link

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:

  1. Should I open a new PR with a fork with the needed changes?
  2. I see a lot of CI checks are failing, any input for that?

Thanks a lot!

P.D. @guihomework are you interested in finishing this?

@christophfroehlich
Copy link
Contributor

I can fix the latest conflicts in the next days. This PR was ready to merge, only reviews were missing.

Copy link

@Raivias Raivias left a 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.

Comment on lines 154 to 170
// 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");
Copy link

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.

Copy link
Contributor

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.

Copy link
Contributor

mergify bot commented Jul 1, 2025

This pull request is in conflict. Could you fix it @guihomework?

@christophfroehlich
Copy link
Contributor

christophfroehlich commented Jul 1, 2025

@OscarMrZ could you leave your review here please? I fixed the merge conflicts, and failing binary tests are due to upstream changes.

Comment on lines +76 to +77
std::string sensor_name_;
std::array<std::string, 6> interface_names_;
Copy link
Member

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(),
Copy link
Member

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?

Copy link
Member

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

Comment on lines +149 to +165
// 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();
}
Copy link
Member

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.

Comment on lines +228 to +238
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())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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?

Comment on lines +265 to +271
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();
Copy link
Member

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

Comment on lines +251 to +258
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");
}
Copy link
Member

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

@destogl
Copy link
Member

destogl commented Jul 30, 2025

We can close this in favor of creating a new node that transforms the input Wrench topic to output Wrench topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants