Skip to content
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 subscriber on constructor #4859

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

Tacha-S
Copy link

@Tacha-S Tacha-S commented Jan 16, 2025


Basic Info

Info Please fill out this column
Ticket(s) this addresses #4802
Primary OS tested on Ubuntu
Robotic platform tested on gazebo simulation of Tally
Does this PR contain AI generated software? No

Description of contribution in a few bullet points

  • I modified it to create a subscriber during initialization while maintaining the functionality to switch topics based on the input port status.

Description of documentation updates required from your changes

  • There are no changes to the inputs, outputs, parameters, or overall behavior, so there is no need to update the documentation.

Description of how this change was tested

  • Create a tree with IsBatteryLow as the top-level condition and invoke the tree when the battery level is low.

Future work that may be required in bullet points

For Maintainers:

  • Check that any new parameters added are updated in docs.nav2.org
  • Check that any significant change is added to the migration guide
  • Check that any new features OR changes to existing behaviors are reflected in the tuning guide
  • Check that any new functions have Doxygen added
  • Check that any new features have test coverage
  • Check that any new plugins is added to the plugins page
  • If BT Node, Additionally: add to BT's XML index of nodes for groot, BT package's readme table, and BT library lists

@Tacha-S Tacha-S force-pushed the feature/create-subscriber-on-init branch from 229c5a1 to a7475eb Compare January 16, 2025 01:54
Signed-off-by: Tatsuro Sakaguchi <tatsuro.sakaguchi@g.softbank.co.jp>
@Tacha-S Tacha-S force-pushed the feature/create-subscriber-on-init branch from a7475eb to 7eb4915 Compare January 17, 2025 01:15
Copy link
Contributor

mergify bot commented Jan 17, 2025

@Tacha-S, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

Signed-off-by: Tatsuro Sakaguchi <tatsuro.sakaguchi@g.softbank.co.jp>
@Tacha-S Tacha-S force-pushed the feature/create-subscriber-on-init branch from 7eb4915 to c65bdfe Compare January 17, 2025 01:20
Copy link
Member

@SteveMacenski SteveMacenski left a comment

Choose a reason for hiding this comment

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

I approve of these changes, but I think this should be made for all BT nodes so that this behavior is consistent across the board. Plus, I'm sure you'll use other BT nodes and want this done for them anyway, so may as well save yourself the headache and batch it out now :-)

@Tacha-S
Copy link
Author

Tacha-S commented Jan 21, 2025

Understood. I will check and fix the other BT nodes as well.

@Tacha-S Tacha-S marked this pull request as draft January 21, 2025 23:46
Copy link
Contributor

mergify bot commented Jan 31, 2025

@Tacha-S, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

Signed-off-by: Tatsuro Sakaguchi <tatsuro.sakaguchi@g.softbank.co.jp>
@Tacha-S Tacha-S force-pushed the feature/create-subscriber-on-init branch from f9ed2dc to 99c1359 Compare February 2, 2025 02:07
Copy link
Member

@SteveMacenski SteveMacenski left a comment

Choose a reason for hiding this comment

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

I'm not entirely sure if this PR is done / needing review, can you let me know?

I'm not seeing that all the nodes updated have the initialize implementation so we create on construction to resolve your issue and set properly if the port is updated like in IsBatteryLow.

@Tacha-S
Copy link
Author

Tacha-S commented Feb 4, 2025

In the node with Initialize(), there were no other nodes updating topics, actions, or services except for IsBatteryLow, so it was unclear what was expected.
As a result, I ended up adding them to all the components that create topics, actions, and services in the constructor, but I don’t think this is what was intended.

@SteveMacenski
Copy link
Member

SteveMacenski commented Feb 4, 2025

Got it, I'm sorry that I was not clear.

The pattern that is battery low established was good; checking for changes and creating the updated subscription if/when the topic changed. For BT nodes that derive from the BTServiceNode and BTActionNode, we can leave these alone because they don't have their topics as a port, so they don't change at runtime ever. But, we need to have them dynamic for ones were the topic itself is a port, like the isBatteryLow since it has:

getInput("battery_topic", battery_topic_new);

The other updates you made to things like SmootherSelector, ProgressCheckerSelector, etc all also have their own input port topics that need to be checked not just on construction, but when running an initialization when ticking from IDLE. This is because these ports may be blackboard variables that are not known at construction time, not hard-coded values in the XML which is known at construction time.

So, what I was asking was to create that same pattern you made for isBatteryLow for all BT nodes with subscriptions/publishers with topic input ports:

MyNode::MyNode(...)
{
  createROSInterfaces()
}

MyNode::tick()
{
  if (!BT::isStatusActive(status())) {
    initialize();
  }
 
  // ... continues
}

Whereas initialize calls createROSInterfaces and createROSInterfaces checks if the topic has changed or if the subscriber isn't yet initialized for creating the new subscription.

Does that make sense?

@Tacha-S
Copy link
Author

Tacha-S commented Feb 4, 2025

Thank you for the explanation, I understand.
The current scope of applying initialize is still insufficient,
so for cases where the topic or service name is specified through an input port, I should introduce initialize and createROSInterfaces to enable dynamic updates.

Once the changes are complete, I’ll reopen and reply again.

@SteveMacenski
Copy link
Member

SteveMacenski commented Feb 4, 2025

Correct! I went through the files and you did identify all of the files that would need to be updated, so you don't need to go through every file again. The ones that you touched in this PR are all of them :-)

Thanks for the help!

Signed-off-by: Tatsuro Sakaguchi <tatsuro.sakaguchi@g.softbank.co.jp>
@Tacha-S Tacha-S force-pushed the feature/create-subscriber-on-init branch from d460fc7 to 12249d0 Compare February 5, 2025 03:06
Copy link
Contributor

mergify bot commented Feb 5, 2025

@Tacha-S, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

@Tacha-S Tacha-S marked this pull request as ready for review February 5, 2025 03:10
@Tacha-S
Copy link
Author

Tacha-S commented Feb 5, 2025

I have made the corrections as you pointed out.

Signed-off-by: Tatsuro Sakaguchi <tatsuro.sakaguchi@g.softbank.co.jp>
Copy link
Member

@SteveMacenski SteveMacenski left a comment

Choose a reason for hiding this comment

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

Small changes and LGTM!

service_name_,
rclcpp::SystemDefaultsQoS(),
callback_group_);
createROSInterfaces();
Copy link
Member

Choose a reason for hiding this comment

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

Should be initialize() instead? This wouldn't setup the loop rate and timeouts

@@ -29,19 +29,25 @@ IsBatteryLowCondition::IsBatteryLowCondition(
is_voltage_(false),
is_battery_low_(false)
{
createROSInterfaces();
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't we do initialize() here because initialize gets the input ports

Copy link
Member

Choose a reason for hiding this comment

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

In general, should we change them all from createROSInterfaces() in the constructor to initalize() so that if there are other non-ros-interface making initialization steps that might be important for the interface definitions, we perform them here too?

Copy link
Author

Choose a reason for hiding this comment

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

I think consistently calling initialize() in the constructor is a good idea, and I agree with that approach.
However, limiting createROSInterfaces() to only within initialize() and not calling either createROSInterfaces() or initialize() from the constructor would not resolve the issue mentioned in the issue, where the behavior during the first execution becomes undefined. Therefore, I would like to avoid this.

@SteveMacenski SteveMacenski linked an issue Feb 5, 2025 that may be closed by this pull request
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.

The first-time failure in the IsBatteryLow condition check
3 participants