Skip to content

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
@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?

@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. 

const rclcpp::node_interfaces::NodeTimeSourceInterface::SharedPtr
time_source() const;

/// Set the time source to be used.
Copy link
Contributor Author

@roncapat roncapat Jun 30, 2025

Choose a reason for hiding this comment

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

@fujitatomoya something like this in code?

Suggested change
/// Set the time source to be used.
/// Set the time source to be used.
/**
* This will cause the node to use the provided TimeSource,
* usually obtained by another node. User must understand that
* either the node that owns the TimeSource has to be spinned,
* or `use_clock_thread_` must be configured as `true` on that node.
*/

@roncapat
Copy link
Contributor Author

@fujitatomoya I'm back on this, sorry for the long wait.
I pushed a few fixes and updated the branch.

The remaining tasks are:

  • documentation
  • tests

I need some guidance, and I would start from the documentation.

  • 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.

See my comment in the code.

  • The subordinate Nodes will not have /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.

Where to put in code? And suggested place/section in ros2_documentation?

@roncapat roncapat marked this pull request as ready for review July 26, 2025 13:15
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