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

WIP: Allow to pass existing TimeSource via NodeOptions #2673

Draft
wants to merge 2 commits into
base: rolling
Choose a base branch
from

Conversation

roncapat
Copy link
Contributor

@roncapat roncapat commented Nov 13, 2024

Addresses #2659 (task 1).

This allows to put an existing TimeSource in NodeOptions so that a Node in the same process space can avoid re-creating a TimeSource.

For example, the TimeSource may be extracted via rclcpp::Node::get_node_time_source_interface() from an existing node, and passed via NodeOptions to all the others that share the process space.

This is, for example, how I tested it locally in an application of mine.

Main benefit: a single subscriber can be shared when using use_sim_time: better scaling for large rclcpp-composed simulations.

@roncapat roncapat force-pushed the feat/shared_time_source_1 branch 3 times, most recently from e88dff2 to a7d891f Compare November 13, 2024 15:08
@roncapat roncapat marked this pull request as ready for review November 13, 2024 15:36
Signed-off-by: Patrick Roncagliolo <ronca.pat@gmail.com>
Signed-off-by: Patrick Roncagliolo <ronca.pat@gmail.com>
@roncapat roncapat force-pushed the feat/shared_time_source_1 branch from edd5b50 to 31f87f6 Compare November 14, 2024 08:28
@MichaelOrlov MichaelOrlov marked this pull request as draft November 21, 2024 18:29
@fujitatomoya
Copy link
Collaborator

@roncapat is this still in draft / WIP status?

@roncapat
Copy link
Contributor Author

roncapat commented Nov 22, 2024

@fujitatomoya works nicely for me locally, but I'd like at least a review to understand what are your opinion on this / if I need to change something.

Copy link
Collaborator

@fujitatomoya fujitatomoya left a comment

Choose a reason for hiding this comment

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

@roncapat thanks for the PR and feedback.

a several comments for now, i think we need to add more unit tests to verify this feature.

  • if the TimeSource is shared with use_clock_thread_ disabled, this main Node must be spinning to update the clock for everybody else, otherwise other nodes sharing TimeSource cannot get the update for the simulation clock information. user application must understand this condition.
  • i think if the TimeSource is shared, we cannot reset this in the subordinate Nodes during destruction. only main Node can do the reset once the TimeSource is no longer required to keep?
  • The subordinate Nodes will not have <nodename>/use_sim_time parameter neither clock subscription QoS parameters, but only main Node. i think this is also important for user to know, i would suggest doc section in the code and ros2_documentation.
  • unit test required to make sure TimeSource is shared within multiple Nodes instances w/ and w/o simulation time. (currently only copy assignment test is added.)
  • LifecycleNode support is missing? or is this on purpose for any constraints?

@@ -235,6 +237,7 @@ Node::Node(
sub_namespace_(""),
effective_namespace_(create_effective_namespace(this->get_namespace(), sub_namespace_))
{
node_time_source_->attachClock(node_clock_);
Copy link
Collaborator

Choose a reason for hiding this comment

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

this actually tries to insert the same element node_cloeck_ if TimeSource is not specified in NodeOption, but that is just fine since std::unordered_set checks the hash to avoid duplication.

Copy link
Contributor Author

@roncapat roncapat Dec 3, 2024

Choose a reason for hiding this comment

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

Would you prefer to leave it as it is, maybe with a comment, or make some kind of check to avoid this tentative re-insertion instead?

@roncapat
Copy link
Contributor Author

roncapat commented Dec 3, 2024

Thank you for the useful comments. I will surely try to satisfy every request, starting with LifecycleNode support for this option.

Two quick replies:

  • if the TimeSource is shared with use_clock_thread_ disabled, this main Node must be spinning to update the clock for everybody else, otherwise other nodes sharing TimeSource cannot get the update for the simulation clock information. user application must understand this condition.

Do you mean by documentation or via a console warning?

I think if the TimeSource is shared, we cannot reset this in the subordinate Nodes during destruction. only main Node can do the reset once the TimeSource is no longer required to keep?

I think not, the shared_ptr of each node gets just "unlinked" from the TimeSource object, i.e. reference counting descreases, but the object itself gets destroyed at the last reset() only.
std::shared_ptr::reset() on cppreference.com:

Releases the ownership of the managed object, if any. After the call, *this manages no object. 
Equivalent to shared_ptr().swap(*this);

If *this already owns an object and it is the last shared_ptr owning it,
the object is destroyed through the owned deleter. 

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.

2 participants