Deps  |  |  Name  |  [ ](/p/lifecycle_msgs#bouncy-deps) |  [ 1
](/packages/lifecycle_msgs) |  [ lifecycle_msgs ](/p/lifecycle_msgs#bouncy)
---|---|---
[ ](/p/rclcpp_lifecycle#bouncy-deps) |  [ 1 ](/packages/rclcpp_lifecycle) |  [
rclcpp_lifecycle ](/p/rclcpp_lifecycle#bouncy)
[ ](/p/std_msgs#bouncy-deps) |  [ 2 ](/packages/std_msgs) |  [ std_msgs
](/p/std_msgs#bouncy)
[ ](/p/ament_cmake#bouncy-deps) |  [ 1 ](/packages/ament_cmake) |  [
ament_cmake ](/p/ament_cmake#bouncy)
[ ](/p/ros2run#bouncy-deps) |  [ 1 ](/packages/ros2run) |  [ ros2run
](/p/ros2run#bouncy)
[ ](/p/ament_lint_auto#bouncy-deps) |  [ 1 ](/packages/ament_lint_auto) |  [
ament_lint_auto ](/p/ament_lint_auto#bouncy)
[ ](/p/ament_lint_common#bouncy-deps) |  [ 1 ](/packages/ament_lint_common) |
[ ament_lint_common ](/p/ament_lint_common#bouncy)

###  System Dependencies


The ` lifecycle_service_client ` is a script calling different transitions on
the ` lifecycle_talker ` . This is meant as the external user controlling the
lifecycle of nodes.


_No additional links._


class LifecycleTalker : public rclcpp_lifecycle::LifecycleNode


The demo is split into 3 separate applications:


* Service ` <node_name>__get_available_transitions ` : Same as above, meant to an introspection tool. It returns a list of all possible transitions this node can execute.


For a more verbose explanation on the applied state machine, we refer to the
design page which provides an in-detail explanation about each state and
transition.


##  0.9.2 (2020-05-26)


**Checkout URI** |  [ https://github.com/ros2/demos.git
](https://github.com/ros2/demos.git)
---|---
**VCS Type** |  git
**VCS Version** |  humble
**Last Updated**

2023-01-10  |  **Dev Status** |  DEVELOPED
**CI status** |  No Continuous Integration
**Released** |  RELEASED
**Tags** |  _No category tags._
**Contributing** |  [ Help Wanted (  0  ) ](/r/demos/#humble-contribute-lists-
help-wanted)
[ Good First Issues (  0  ) ](/r/demos/#humble-contribute-lists-good-first-
issue)
[ Pull Requests to Review (  0  ) ](/r/demos/#humble-contribute-lists-pull-
requests)

###  Package Description


It is slightly less convenient, because you have to know the IDs which
correspond to each transition. You can find them though in the lifecycle_msgs
package.


      10: [ RUN      ] TestControllerManagerHWManagementSrvs.list_hardware_components
       ...
      10: [WARN] [1703729657.862577856] [resource_manager]: (hardware 'TestSystemHardware'): 'joint2/velocity' command interface not in available list. This should not happen (hint: multiple cleanup calls).
      10: [WARN] [1703729657.862596992] [resource_manager]: (hardware 'TestSystemHardware'): 'joint3/velocity' command interface not in available list. This should not happen (hint: multiple cleanup calls).
      10: [WARN] [1703729657.862601260] [resource_manager]: (hardware 'TestSystemHardware'): 'joint2/max_acceleration' command interface not in available list. This should not happen (hint: multiple cleanup calls).
      10: [WARN] [1703729657.862605888] [resource_manager]: (hardware 'TestSystemHardware'): 'configuration/max_tcp_jerk' command interface not in available list. This should not happen (hint: multiple cleanup calls).

---

All reactions
Sorry, something went wrong.
[
![@saikishor](https://avatars.githubusercontent.com/u/10082428?s=80&u=a8449baf27fec21608c3919a53021b418098ddfe&v=4)
](/saikishor)
Copy link
Member
###
**[ saikishor ](/saikishor) ** commented  Dec 29, 2023
[ @christophfroehlich ](https://github.com/christophfroehlich) Thank you for
the logs. Ok this seems to be getting important now. I'll see if I can find
some time to fix it when I'm back from holidays

---

All reactions
Sorry, something went wrong.
[
![@saikishor](https://avatars.githubusercontent.com/u/10082428?s=80&u=a8449baf27fec21608c3919a53021b418098ddfe&v=4)
](/saikishor)
Copy link
Member
###
**[ saikishor ](/saikishor) ** commented  Jan 6, 2024
[ @christophfroehlich ](https://github.com/christophfroehlich) after checking,
these PRs should fix the issue : [ #1175 ](https://github.com/ros-
controls/ros2_control/pull/1175) and [ #1271 ](https://github.com/ros-
controls/ros2_control/pull/1271)


##  0.9.1 (2020-05-12)


![](/assets/package.png) |


    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
    on_configure(const rclcpp_lifecycle::State & previous_state)

    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
    on_activate(const rclcpp_lifecycle::State & previous_state)

    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
    on_deactivate(const rclcpp_lifecycle::State & previous_state)

    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
    on_cleanup(const rclcpp_lifecycle::State & previous_state)

    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
    on_shutdown(const rclcpp_lifecycle::State & previous_state)


* Service ` <node_name>__get_state ` : query about the current state of the node.


Primary States (steady states):


##  0.20.3 (2023-01-10)


Transition States (intermediate states):


The demo is split into 3 different separate applications.


    [lc_talker] on_configure() is called.
    Lifecycle publisher is currently inactive. Messages are not published.
    ...


This gives room for executing a custom error handling. Only (!) in the case
that this function returns ` CallbackReturn::SUCCESS ` , the state machine
transitions to the state ` unconfigured ` . By default, the ` on_error `
returns ` CallbackReturn::FAILURE ` and the state machine transitions into `
finalized ` .


The difference to the transition event before is that our listener now also
receives the actual published data.


$ ros2 interface show lifecycle_msgs/msg/Transition


_No direct system dependencies._


The next step would be to execute a state change:


##  0.7.3 (2019-05-10)


_No message files found._


  * change ParameterEventHandler to take events as const ref instead of shared pointer ( [ #494 ](https://github.com/ros2/demos/issues/494) )
  * Contributors: William Woodall


  * Switch to using RCLCPP logging macros in the lifecycle package. ( [ #644 ](https://github.com/ros2/demos/issues/644) )
  * Contributors: Chris Lalancette


6. Change last return of ` on_init  ` to ` return  CallbackReturn::SUCCESS;  `


##  0.12.0 (2021-01-25)


##  0.7.2 (2019-05-08)


##  0.8.1 (2019-10-23)


**Tags** |  _No category tags._
---|---
**Version** |  0.8.4
**License** |  Apache License 2.0
**Build type** |  AMENT_CMAKE
**Use** |  RECOMMENDED

###  Repository Summary


###  Messages


##  0.6.0 (2018-12-07)


ros2 launch lifecycle lifecycle_demo.launch.py


](https://policy.medium.com/medium-terms-of-
service-9db0094a1e0f?source=post_page-----
5fafa2738700--------------------------------)


##  0.10.1 (2020-09-21)


##  ros2 lifecycle command line interface


#  Changelog for package lifecycle


© Copyright 2024, ros2_control Development Team.


##  0.8.0 (2019-09-26)


##  lifecycle_talker, lifecycle_listener and lifecycle_service_client


In order to trigger a transition, we call the ` change_state ` service


##  0.8.4 (2019-11-19)


##  0.20.0 (2022-03-01)


The possible transitions to invoke are:


    [lc_listener] data_callback: Lifecycle HelloWorld #11
    [lc_listener] data_callback: Lifecycle HelloWorld #12
    ...


Return either a primary or transition state.


All of the above commands are nothing else than calling the lifecycle node\'s
services. With that being said, we can also call these services directly with
the ros2 command line interface:


#  The demo


* Service ` <node_name>__get_available_transitions ` : Same as above, meant to an introspection tool.


    [lc_client] Transition 1 successfully triggered.
    [lc_client] Node lc_talker has current state inactive.


  * unconfigured
  * inactive
  * active
  * shutdown


####  Additional Links


The lifecycle listener on the same time receives a notification as it listens
to every state change notification of the lifecycle talker. In fact, the
listener receives two consecutive notifications. One for changing from the
primary state \"unconfigured\" to \"configuring\". Because the configuring
step was successful within the lifecycle talker, a second notification from
\"configuring\" to \"inactive\".


##  0.9.0 (2020-04-30)


This demo shows a typical talker/listener pair of nodes. However, imagine a
real scenario with attached hardware which may have a rather long booting
phase, i.e. a laser or camera. One could imagine bringing up the device driver
in the configuring state, start and stop only the publishing of the device\'s
data in active/deactive state, and only in the cleanup/shutdown state actually
shutdown the device.


The ` lifecycle_service_client ` is a script calling different transitions on
the ` lifecycle_talker ` . This is meant as the external user controlling the
lifecycle of nodes.


` $ ros2 run lifecycle lifecycle_talker ` ` $ ros2 run lifecycle
lifecycle_listener ` ` $ ros2 run lifecycle lifecycle_service_client ` [
![asciicast](https://asciinema.org/a/249049.png)
](https://asciinema.org/a/249049) [
![asciicast](https://asciinema.org/a/249050.png)
](https://asciinema.org/a/249050) [
![asciicast](https://asciinema.org/a/249051.png)
](https://asciinema.org/a/249051)


    $ ros2 lifecycle get /lc_talker
    unconfigured [1]


####  Package Summary


#  Changelog for package lifecycle


####  Authors


makes the lifecycle talker change its state to active. That means all
publishers and timers are now activated and herefore the messages are now
getting published.


##  0.16.0 (2021-08-11)


####  Maintainers


  * update launch file name format to match documentation ( [ #588 ](https://github.com/ros2/demos/issues/588) )
  * Contributors: Patrick Wspanialy


##  What\'s happening


  * Karsten Knese
  * Mabel Zhang


[ lifecycle/README.rst
](https://github.com/ros2/demos/tree/rolling/lifecycle/README.rst "Open in git
repository")


Please note that the index of the published message is already at 11. The
purpose of this demo is to show that even though we call ` publish ` at every
state of the lifecycle talker, the messages are only actually published when
the state in active.


##  0.25.0 (2023-03-01)


**Tags** |  _No category tags._
---|---
**Version** |  0.27.1
**License** |  Apache License 2.0
**Build type** |  AMENT_CMAKE
**Use** |  RECOMMENDED

###  Repository Summary


##  0.8.2 (2019-11-08)


Status


What is the current state of the camera_node and how can the node state be
modified?


  * Cleaned up lifecycle demo ( [ #283 ](https://github.com/ros2/demos/issues/283) )
  * Updated for refactoring in rclcpp ( [ #276 ](https://github.com/ros2/demos/issues/276) )
  * Added semicolons to all RCLCPP and RCUTILS macros. ( [ #278 ](https://github.com/ros2/demos/issues/278) )
  * Fixed typo in comment ( [ #270 ](https://github.com/ros2/demos/issues/270) )
  * Contributors: Chris Lalancette, Karsten Knese, Yutaka Kondo


  * Cleanup the README.rst for the lifecycle demo. ( [ #508 ](https://github.com/ros2/demos/issues/508) )
  * Contributors: Chris Lalancette


**Checkout URI** |  [ https://github.com/ros2/demos.git
](https://github.com/ros2/demos.git)
---|---
**VCS Type** |  git
**VCS Version** |  eloquent
**Last Updated**

2020-11-04  |  **Dev Status** |  DEVELOPED
**CI status** |  No Continuous Integration
**Released** |  RELEASED
**Tags** |  _No category tags._
**Contributing** |  [ Help Wanted (  0  ) ](/r/demos/#eloquent-contribute-
lists-help-wanted)
[ Good First Issues (  0  ) ](/r/demos/#eloquent-contribute-lists-good-first-
issue)
[ Pull Requests to Review (  0  ) ](/r/demos/#eloquent-contribute-lists-pull-
requests)

###  Package Description


  * Converted launch files to the new launch style. ( [ #262 ](https://github.com/ros2/demos/issues/262) )
  * Updated to support remapping arguments to python nodes by passing unused arguments to rclpy from argparse. ( [ #252 ](https://github.com/ros2/demos/issues/252) )
  * Updated to handle change in signature to ` get_service_name ` . ( [ #245 ](https://github.com/ros2/demos/issues/245) )
  * Updated launch files to account for the \"old launch\" getting renamespaced as ` launch ` -> ` launch.legacy ` . ( [ #239 ](https://github.com/ros2/demos/issues/239) )
  * Updated service client demos to handle multiple requests. ( [ #228 ](https://github.com/ros2/demos/issues/228) )
  * Contributors: Geoffrey Biggs, Kevin Allen, Shane Loretz, William Woodall, dhood


Update the CMakeLists.txt,


Package containing demos for lifecycle implementation


In order to trigger a transition, we call the ` change_state ` service


###  Recent questions tagged ` lifecycle ` at **[ Robotics Stack Exchange
](https://robotics.stackexchange.com/) **


#  Changelog for package lifecycle


##  0.6.0 (2018-12-07)


Makes the lifecycle talker change its state to inactive. Inactive means that
all publishers and timers are created and configured. However, the node is
still not active. Therefore no messages are getting published.


In order to run this demo, we open three terminals and source our ROS 2
environment variables either from the binary distributions or the workspace we
compiled from source.


In the following we assume that we are inside the namespace `
rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface ` to shorten the
name of the return type. All these callbacks have a positive default return
value ( ` return CallbackReturn::SUCCESS ` ). This allows a lifecycle node to
change its state even though no explicit callback function was overwritten.
There is one other callback function for error handling. Whenever a state
transition throws an uncaught exception, we call ` on_error ` .


##  0.7.6 (2019-05-30)


    [lc_listener]: notify callback: Transition from state inactive to activating
    [lc_listener]: notify callback: Transition from state activating to active


If we look at the output of the ` lifecycle_talker ` , we notice that nothing
seems to happen. This makes sense, since every node starts as ` unconfigured `
. The lifecycle_talker is not configured yet and in our example, no publishers
and timers are created yet. The same behavior can be seen for the `
lifecycle_listener ` , which is less surprising given that no publishers are
available at this moment. The interesting part starts with the third terminal.
In there we launch our ` lifecycle_service_client ` which is responsible for
changing the states of the ` lifecycle_talker ` .


  * Fix lifecycle_service_client namespace ( [ #369 ](https://github.com/ros2/demos/issues/369) )
  * Contributors: Cameron Evans


##  0.5.0 (2018-06-27)


ros2 launch lifecycle lifecycle_demo.launch.py


    $ ros2 service call /lc_talker/get_state lifecycle_msgs/GetState
    requester: making request: lifecycle_msgs.srv.GetState_Request()

    response:
    lifecycle_msgs.srv.GetState_Response(current_state=lifecycle_msgs.msg.State(id=1, label='unconfigured'))


###  Source Tutorials


If we look at the output of the ` lifecycle_talker ` , we notice that nothing
seems to happen. And this does make sense, since every node starts as `
unconfigured ` . The lifecycle_talker is not configured yet and in our
example, no publishers and timers are created yet. The same behavior can be
seen for the ` lifecycle_listener ` , which is less surprising given that no
publishers are available at this moment. The interesting part starts with the
third terminal. In there we launch our ` lifecycle_service_client ` which is
responsible for changing the states of the ` lifecycle_talker ` .


If we have a look at the code, there is one significant change for the
lifecycle talker compared to a regular talker. Our node does not inherit from
the regular ` rclcpp::node::Node ` but from ` rclcpp_lifecycle::LifecycleNode
` .


* ` CallbackReturn on_error(const rclcpp_lifecycle::State & previous_state) `


##  0.12.0 (2021-01-25)


_No direct system dependencies._


##  0.33.2 (2024-03-28)


##  0.20.1 (2022-04-08)


_No service files found_


##  0.6.0 (2018-12-07)


    [lc_client] Transition 1 successfully triggered.
    [lc_client] Node lc_talker has current state inactive.


4. Add include of header ` rclcpp_lifecycle/state.hpp  ` although this may not be strictly necessary


  * changes to avoid deprecated API\'s ( [ #332 ](https://github.com/ros2/demos/issues/332) )
  * Corrected publish calls with shared_ptr signature ( [ #327 ](https://github.com/ros2/demos/issues/327) )
  * Contributors: William Woodall, ivanpauno


##  0.6.2 (2019-01-15)


##  0.6.1 (2018-12-13)


##  0.8.1 (2019-10-23)


For instance, consider a robot that relies on a camera for object detection
and obstacle avoidance. The camera configuration is crucial to ensure that the
system receives reliable data. To manage the lifecycle of the camera Node, we
can use a _Lifecycle Node instead of the standard Node_ . This specialized
node would be responsible for configuring the _camera parameters_ , such as
_resolution_ , _frame rate_ , and _exposure_ , as well as publishing the
camera data to the detection and obstacle avoidance components. By doing so,
we can ensure that the camera Node is set up correctly and that its data is
reliable, allowing us to manage its lifecycle more effectively.


###  Source Tutorials


###  Plugins


Careers


    [lc_listener] notify callback: Transition from state unconfigured to configuring
    [lc_listener] notify callback: Transition from state configuring to inactive


12. If you get link errors with undefined refernences to symbols in ` rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface  ` , then add ` rclcpp_lifecyle  ` package dependency to ` CMakeLists.txt  ` and ` package.xml  `


    [lc_listener] data_callback: Lifecycle HelloWorld #11
    [lc_listener] data_callback: Lifecycle HelloWorld #12
    ...


**Tags** |  _No category tags._
---|---
**Version** |  0.33.2
**License** |  Apache License 2.0
**Build type** |  AMENT_CMAKE
**Use** |  RECOMMENDED

###  Repository Summary


[ ![Jegathesan
Shanmugam](https://miro.medium.com/v2/resize:fill:144:144/2*h3PRzfT7jps1zKlfhvGp6Q.jpeg)
](/@nullbyte.in?source=post_page-----
5fafa2738700--------------------------------)


  * configure
  * activate
  * deactivate
  * cleanup
  * shutdown


_No service files found_


##  Triggering transition 1 (configure)


    $ ros2 service call /lc_talker/change_state lifecycle_msgs/ChangeState "{transition: {id: 2}}"
    requester: making request: lifecycle_msgs.srv.ChangeState_Request(transition=lifecycle_msgs.msg.Transition(id=2, label=''))

    response:
    lifecycle_msgs.srv.ChangeState_Response(success=True)


  * Update the package.xml files with the latest Open Robotics maintainers ( [ #466 ](https://github.com/ros2/demos/issues/466) )
  * Contributors: Michael Jeronimo


[ action_tutorials_cpp ](/p/action_tutorials_cpp/github-ros2-demos) [
action_tutorials_interfaces ](/p/action_tutorials_interfaces/github-
ros2-demos) [ action_tutorials_py ](/p/action_tutorials_py/github-ros2-demos)
[ composition ](/p/composition/github-ros2-demos) [ demo_nodes_cpp
](/p/demo_nodes_cpp/github-ros2-demos) [ demo_nodes_cpp_native
](/p/demo_nodes_cpp_native/github-ros2-demos) [ demo_nodes_py
](/p/demo_nodes_py/github-ros2-demos) [ dummy_map_server
](/p/dummy_map_server/github-ros2-demos) [ dummy_robot_bringup
](/p/dummy_robot_bringup/github-ros2-demos) [ dummy_sensors
](/p/dummy_sensors/github-ros2-demos) [ image_tools ](/p/image_tools/github-
ros2-demos) [ intra_process_demo ](/p/intra_process_demo/github-ros2-demos)
lifecycle  [ logging_demo ](/p/logging_demo/github-ros2-demos) [
pendulum_control ](/p/pendulum_control/github-ros2-demos) [ pendulum_msgs
](/p/pendulum_msgs/github-ros2-demos) [ quality_of_service_demo_cpp
](/p/quality_of_service_demo_cpp/github-ros2-demos) [
quality_of_service_demo_py ](/p/quality_of_service_demo_py/github-ros2-demos)
[ topic_monitor ](/p/topic_monitor/github-ros2-demos)
---|---

github-ros2-demos


###  Dependant Packages


In this case we see that currently, the available transitions are ` configure
` and ` shutdown ` . The complete state machine can be viewed with the
following command, which can be helpful for debugging or visualization
purposes:


[ lifecycle/README.rst
](https://github.com/ros2/demos/tree/eloquent/lifecycle/README.rst "Open in
git repository")


  * Remove unnecessary dependency on ros2run ( [ #413 ](https://github.com/ros2/demos/issues/413) )
  * Contributors: Michel Hidalgo


It is slightly less convenient, because you have to know the IDs which
correspond to each transition. You can find them though in the lifecycle_msgs
package.


    [lc_client] Transition 1 successfully triggered.
    [lc_client] Node lc_talker has current state inactive.


###  Wiki Tutorials


_See[ ROS Wiki Tutorials ](http://wiki.ros.org/lifecycle/Tutorials) for more
details. _


The ` lifecycle_service_client ` application is a fixed order script for this
demo purpose only. It explains the use and the API calls made for this
lifecycle implementation, but may be inconvenient to use otherwise. For this
reason, we implemented a separate python script, which lets you dynamically
change states or various nodes.


_No direct system dependencies._


The lifecycle listener receives the same set of notifications as before.
Lifecycle talker changed its state from inactive to active.


  * Add lifecycle rostest ( [ #336 ](https://github.com/ros2/demos/issues/336) )
  * Contributors: Michel Hidalgo


##  0.8.1 (2019-10-23)


class LifecycleTalker : public rclcpp_lifecycle::LifecycleNode


  * changes to avoid deprecated API\'s ( [ #332 ](https://github.com/ros2/demos/issues/332) )
  * Corrected publish calls with shared_ptr signature ( [ #327 ](https://github.com/ros2/demos/issues/327) )
  * Contributors: William Woodall, ivanpauno


  * Add missing required parameter in LifecycleNode launch action ( [ #456 ](https://github.com/ros2/demos/issues/456) )
  * Contributors: Ivan Santiago Paunovic


    $ ros2 lifecycle set /lc_talker configure
    Transitioning successful


[ Sign in
](/m/signin?operation=login&redirect=https%3A%2F%2Fmedium.com%2F%40nullbyte.in%2Fros2-from-
the-ground-up-part-8-simplify-robotic-software-components-management-with-
ros2-5fafa2738700&source=post_page---two_column_layout_nav
-----------------------global_nav-----------)


At the same time, every lifecycle node has by default 5 different
communication interfaces.


In the case you want to get the current state of the ` lc_talker ` node, you
would call:


Failed to get question list, you can ticket an issue [ here
](https://github.com/ros-infrastructure/rosindex/issues/new)


    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
    on_configure(const rclcpp_lifecycle::State & previous_state)

    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
    on_activate(const rclcpp_lifecycle::State & previous_state)

    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
    on_deactivate(const rclcpp_lifecycle::State & previous_state)

    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
    on_cleanup(const rclcpp_lifecycle::State & previous_state)

    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
    on_shutdown(const rclcpp_lifecycle::State & previous_state)


#  Outlook


    [lc_talker] on_configure() is called.
    Lifecycle publisher is currently inactive. Messages are not published.
    ...


##  0.20.2 (2022-05-10)


  * [ Actions  ](/ros-controls/ros2_control/actions)
  * [ Projects  0  ](/ros-controls/ros2_control/projects)
  * [ Security  ](/ros-controls/ros2_control/security)
  * [ Insights  ](/ros-controls/ros2_control/pulse)
Additional navigation options
  * [ Code  ](/ros-controls/ros2_control)
  * [ Issues  ](/ros-controls/ros2_control/issues)
  * [ Pull requests  ](/ros-controls/ros2_control/pulls)
  * [ Actions  ](/ros-controls/ros2_control/actions)
  * [ Projects  ](/ros-controls/ros2_control/projects)
  * [ Security  ](/ros-controls/ros2_control/security)
  * [ Insights  ](/ros-controls/ros2_control/pulse)
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.
Pick a username

Email Address

Password

Sign up for GitHub
By clicking “Sign up for GitHub”, you agree to our [ terms of service
](https://docs.github.com/terms) and [ privacy statement
](https://docs.github.com/privacy) . We’ll occasionally send you account
related emails.
Already on GitHub? [ Sign in ](/login?return_to=%2Fros-
controls%2Fros2_control%2Fissues%2Fnew%2Fchoose) to your account
Jump to bottom
#  Ressource manager hangs up on lifecycle changes  #1103
Closed
[ christophfroehlich ](/christophfroehlich) opened this issue  Aug 22, 2023  ·
6 comments  · Fixed by [ #1279 ](https://github.com/ros-
controls/ros2_control/pull/1279)
Closed
#  Ressource manager hangs up on lifecycle changes  #1103
[ christophfroehlich ](/christophfroehlich) opened this issue  Aug 22, 2023  ·
6 comments  · Fixed by [ #1279 ](https://github.com/ros-
controls/ros2_control/pull/1279)
Labels


Package containing demos for lifecycle implementation


    [lc_client] Transition 1 successfully triggered.
    [lc_client] Node lc_talker has current state inactive.


When designing a robotic system, certain components are critical to the proper
functioning of the system, and may require special attention to manage their
lifecycle. In ROS2, **two types of nodes are available at a high level:**


The difference to the transition event before is that our listener now also
receives the actual published data.


#  The demo


  * [ Getting Started ](../../../getting_started/getting_started.html)
  * [ ros2_control ](../../doc/index.html)
    * [ API Documentation ](../../doc/index.html#api-documentation)
    * [ Features ](../../doc/index.html#features)
    * [ Concepts ](../../doc/index.html#concepts)
      * [ Controller Manager ](../../controller_manager/doc/userdoc.html)
      * [ Controller Chaining / Cascade Control ](../../controller_manager/doc/controller_chaining.html)
      * Hardware Components
        * Guidelines and Best Practices
          * [ Hardware Interface Types ](hardware_interface_types_userdoc.html)
          * [ Writing a Hardware Component ](writing_new_hardware_component.html)
          * [ Different Update Rates ](different_update_rates_userdoc.html)
          * Handling of errors that happen during read() and write() calls
          * Migration from Foxy to newer versions
      * [ Mock Components ](mock_components_userdoc.html)
  * [ ros2_controllers ](../../../ros2_controllers/doc/controllers_index.html)
  * [ Demos ](../../../ros2_control_demos/doc/index.html)
  * [ Command Line Interface ](../../ros2controlcli/doc/userdoc.html)
  * [ Simulator Integrations ](../../../simulators/simulators.html)
  * [ Differences to ros_control (ROS1) ](../../../differences_to_ros1/differences_to_ros1.html)
  * [ Migration Guide to ros2_control ](../../../differences_to_ros1/differences_to_ros1.html#migration-guide-to-ros2-control)
  * [ API Documentation ](../../../api/api.html)
  * [ Supported Robots ](../../../supported_robots/supported_robots.html)
  * [ Resources ](../../../resources/resources.html)
  * [ Contributing ](../../../contributing/contributing.html)
  * [ Project Ideas for GSoC 2024 ](../../../project_ideas.html)
  * [ Acknowledgements ](../../../acknowledgements/acknowledgements.html)


##  0.7.1 (2019-04-26)


      return status;
    }

    class LifecycleServiceClient : public rclcpp::Node
    {
    public:
      explicit LifecycleServiceClient(const std::string & node_name)
      : Node(node_name)
      {}

      void
      init()
      {
        client_get_state_ = this->create_client<lifecycle_msgs::srv::GetState>(
          node_get_state_topic);
        client_change_state_ = this->create_client<lifecycle_msgs::srv::ChangeState>(
          node_change_state_topic);
      }

      unsigned int
      get_state(std::chrono::seconds time_out = 3s)
      {
        auto request = std::make_shared<lifecycle_msgs::srv::GetState::Request>();

        if (!client_get_state_->wait_for_service(time_out)) {
          RCLCPP_ERROR(
            get_logger(),
            "Service %s is not available.",
            client_get_state_->get_service_name());
          return lifecycle_msgs::msg::State::PRIMARY_STATE_UNKNOWN;
        }

        auto future_result = client_get_state_->async_send_request(request);

        auto future_status = wait_for_result(future_result, time_out);

        if (future_status != std::future_status::ready) {
          RCLCPP_ERROR(
            get_logger(), "Server time out while getting current state for node %s", lifecycle_node);
          return lifecycle_msgs::msg::State::PRIMARY_STATE_UNKNOWN;


  * configure
  * activate
  * deactivate
  * cleanup
  * shutdown


##  0.8.2 (2019-11-08)


Please note that the index of the published message is already at 11. The
purpose of this demo is to show that even though we call ` publish ` at every
state of the lifecycle talker, only when the state in active, the messages are
actually published. As for the beta1, all other messages are getting ignored.
This behavior may change in future versions in order to provide better error
handling.


The ` lifecycle_listener ` is a simple listener which shows the
characteristics of the lifecycle talker. The talker enables the message
publishing only in the active state and thus making the listener receiving
only messages when the talker is in an active state.


  * Python lifecycle nodes
  * Lifecycle manager: A global node, handling and dispatching trigger requests for multiple nodes.
  * LifeyclceSubscriber/LifecycleWalltimer/... add more lifecycle controlled entities.


#  Run the demo


Share


In order to run this demo, we open three terminals and source our ROS2
environment variables either from the binary distributions or the workspace we
compiled from source.


##  ◆  rcl_disable_ros_time_override()


Parameters


###  4 Build and run  ï


Built with [ Sphinx ](https://www.sphinx-doc.org/) using a [ theme
](https://github.com/readthedocs/sphinx_rtd_theme) provided by [ Read the Docs
](https://readthedocs.org) .


* 2 Write the service node


##  ◆  rcl_ros_clock_fini()


Itâs good practice to run ` rosdep  ` in the root of your workspace ( `
ros2_ws  ` ) to check for missing dependencies before building:


[ pabled91  ](https://get-help.theconstruct.ai/u/pabled91) June 30, 2023,
7:47am  6


rosdep only runs on Linux, so you can skip ahead to next step.


##  Prerequisites  ï


Open a new terminal and [ source your ROS 2 installation  ](../Beginner-CLI-
Tools/Configuring-ROS2-Environment.html) so that ` ros2  ` commands will work.


1 Like


#include <std_srvs/srv/set_bool.hpp>


This function takes two time points and computes the duration between them.
The two time points must be using the same time abstraction, and the resultant
duration will also be of the same abstraction.


###  1 Create a package  ï


[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796)
rcl_set_ros_time_override  |  (  |  [ rcl_clock_t ](structrcl__clock__t.html)
*  |  _clock_ ,
---|---|---|---
|  |  [ rcl_time_point_value_t
](time_8h.html#a504861cd584105c7ddfea1dd6539f8e8) |  _time_value_
|  )  |  |

Set the current time for this ` RCL_ROS_TIME ` time source.


Hello,


[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796) |  [
rcl_clock_get_now ](time_8h.html#ac411ad081f7acea558554a810461d36d) ( [
rcl_clock_t ](structrcl__clock__t.html) *clock, [ rcl_time_point_t
](structrcl__time__point__t.html) *time_point)
|  Fill the time point with the current value of the associated clock.
More...

[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796) |  [
rcl_enable_ros_time_override ](time_8h.html#ae19a2d0487f2a01849394f10a03da737)
( [ rcl_clock_t ](structrcl__clock__t.html) *clock)
|  Enable the ROS time abstraction override.  More...

[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796) |  [
rcl_disable_ros_time_override
](time_8h.html#a0608b7f86a89d146c86b88892bbf4ed3) ( [ rcl_clock_t
](structrcl__clock__t.html) *clock)
|  Disable the ROS time abstraction override.  More...

[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796) |  [
rcl_is_enabled_ros_time_override
](time_8h.html#aebac6161fdb021143c95111bef6358e3) ( [ rcl_clock_t
](structrcl__clock__t.html) *clock, bool *is_enabled)
|  Check if the ` RCL_ROS_TIME ` time source has the override enabled.
More...

[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796) |  [
rcl_set_ros_time_override ](time_8h.html#a1fee15ebac42449043dfabef4922d618) (
[ rcl_clock_t ](structrcl__clock__t.html) *clock, [ rcl_time_point_value_t
](time_8h.html#a504861cd584105c7ddfea1dd6539f8e8) time_value)
|  Set the current time for this ` RCL_ROS_TIME ` time source.  More...

##  Macro Definition Documentation


  * Spins the node, making the service available.

        rclcpp::spin(node);


The first two lines are the parameters of the request, and below the dashes is
the response.


rclcpp::Client<std_srvs::srv::SetBool>::SharedPtr service_client_;


This will deallocate all necessary internal structures, and clean up any
variables. It is specifically setting up a system time source. It is expected
to be paired with the init fuction.


  * [ ](../../index.html)
  * [ Tutorials ](../../Tutorials.html)
  * [ Beginner: Client libraries ](../Beginner-Client-Libraries.html)
  * Writing a simple service and client (C++)
  * [ Edit on GitHub ](https://github.com/ros2/ros2_documentation/blob/foxy/source/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Service-And-Client.rst)


    // There are two ways you can check the result of the service call:
    // 1. using std::future<Result>
    // 2. using a callback
    // Examples for each case follow.


  Custom Time Source

It is possible that the user may have access to an out of band time source
which can provide better performance than the default source the ` /clock `
topic. It might be possible that for their use case a more advanced algorithm
would be needed to propagate the simulated time with adequate precision or
latency with restricted bandwidth or connectivity. The user will be able to
switch out the time source for the instance of their Time object as well as
have the ability to override the default for the process.

It is possible to use an external time source such as GPS as a ROSTime source,
but it is recommended to integrate a time source like that using standard NTP
integrations with the system clock since that is already an established
mechanism and will not need to deal with more complicated changes such as time
jumps.

For the current implementation a ` TimeSource ` API will be defined such that
it can be overridden in code. If in the future a common implementation is
found that would be generally useful it could be extended to optionally
dynamically select the alternative TimeSource via a parameter similar to
enabling the simulated time.


        case 3:
          RCLCPP_INFO(this->get_logger(), "wall behind");
          twist_msg.angular.z = 0.2;
          break;
        }

        // start_scan_sub();

        while (laser_forward > laser_backward || laser_forward > laser_left ||
               laser_forward > laser_right) {
          publisher_->publish(twist_msg);
          /*RCLCPP_INFO(this->get_logger(), "[FORWARD] = '%f'",
          this->laser_forward); RCLCPP_INFO(this->get_logger(), "[LEFT] = '%f'",
          this->laser_left); RCLCPP_INFO(this->get_logger(), "[RIGHT] = '%f'",
          this->laser_right); RCLCPP_INFO(this->get_logger(), "[FORWARD] = '%f'",
          this->laser_forward); RCLCPP_INFO(this->get_logger(), "[BACKWARD] = '%f'",
                      this->laser_backward);
          */
          // rclcpp::sleep_for(1s);
        }
        this->twist_msg.linear.x = 0;
        this->twist_msg.angular.z = 0;
        publisher_->publish(twist_msg);
        RCLCPP_INFO(this->get_logger(), "facing the wall, going to approach");
        this->twist_msg.linear.x = 0.05;
        this->twist_msg.angular.z = 0;
        while (laser_forward > 0.3) {
          publisher_->publish(twist_msg);
        }
        this->twist_msg.linear.x = 0;
        this->twist_msg.angular.z = 0;
        publisher_->publish(twist_msg);
        RCLCPP_INFO(this->get_logger(),
                    "close to the wall, rotating to start position");
        this->twist_msg.linear.x = 0;
        this->twist_msg.angular.z = 0.2;
        while (laser_right > laser_backward || laser_right > laser_left ||
               laser_forward < laser_right) {
          publisher_->publish(twist_msg);
          /*RCLCPP_INFO(this->get_logger(), "[FORWARD] = '%f'",


##  ◆  RCL_NS_TO_US


        start_scan_sub();

        while (laser_forward > laser_backward || laser_forward > laser_left ||
               laser_forward > laser_right) {
          publisher_->publish(twist_msg);
          /*RCLCPP_INFO(this->get_logger(), "[FORWARD] = '%f'",
          this->laser_forward); RCLCPP_INFO(this->get_logger(), "[LEFT] = '%f'",
          this->laser_left); RCLCPP_INFO(this->get_logger(), "[RIGHT] = '%f'",
          this->laser_right); RCLCPP_INFO(this->get_logger(), "[FORWARD] = '%f'",
          this->laser_forward); RCLCPP_INFO(this->get_logger(), "[BACKWARD] = '%f'",
                      this->laser_backward);
          */
          // rclcpp::sleep_for(1s);
        }
        this->twist_msg.linear.x = 0;
        this->twist_msg.angular.z = 0;
        publisher_->publish(twist_msg);
        RCLCPP_INFO(this->get_logger(), "facing the wall, going to approach");
        this->twist_msg.linear.x = 0.05;
        this->twist_msg.angular.z = 0;
        while (laser_forward > 0.3) {
          publisher_->publish(twist_msg);
        }
        this->twist_msg.linear.x = 0;
        this->twist_msg.angular.z = 0;
        publisher_->publish(twist_msg);
        RCLCPP_INFO(this->get_logger(),
                    "close to the wall, rotating to start position");
        this->twist_msg.linear.x = 0;
        this->twist_msg.angular.z = 0.2;
        while (laser_right > laser_backward || laser_right > laser_left ||
               laser_forward < laser_right) {
          publisher_->publish(twist_msg);
          /*RCLCPP_INFO(this->get_logger(), "[FORWARD] = '%f'",
          this->laser_forward); RCLCPP_INFO(this->get_logger(), "[LEFT] = '%f'",
          this->laser_left); RCLCPP_INFO(this->get_logger(), "[RIGHT] = '%f'",
          this->laser_right); RCLCPP_INFO(this->get_logger(), "[FORWARD] = '%f'",
          this->laser_forward); RCLCPP_INFO(this->get_logger(), "[BACKWARD] = '%f'",
                      this->laser_backward);
          */


##  ◆  rcl_clock_get_now()


Parameters


This will allocate all necessary internal structures, and initialize
variables.


[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796)
rcl_system_clock_fini  |  (  |  [ rcl_clock_t ](structrcl__clock__t.html) *  |
_clock_ |  )  |
---|---|---|---|---|---

Finalize a clock as a ` RCL_SYSTEM_TIME ` time source.


Linux  macOS  Windows


##  ◆  rcl_ros_clock_init()


  * [ Installation ](../../Installation.html)
    * [ Ubuntu (Debian) ](../../Installation/Ubuntu-Install-Debians.html)
    * [ Windows (binary) ](../../Installation/Windows-Install-Binary.html)
    * [ Alternatives ](../../Installation/Alternatives.html)
      * [ Ubuntu (source) ](../../Installation/Alternatives/Ubuntu-Development-Setup.html)
      * [ Ubuntu (binary) ](../../Installation/Alternatives/Ubuntu-Install-Binary.html)
      * [ Windows (source) ](../../Installation/Alternatives/Windows-Development-Setup.html)
      * [ macOS (source) ](../../Installation/Alternatives/macOS-Development-Setup.html)
      * [ macOS (binary) ](../../Installation/Alternatives/macOS-Install-Binary.html)
      * [ Fedora (source) ](../../Installation/Alternatives/Fedora-Development-Setup.html)
      * [ Latest development (source) ](../../Installation/Alternatives/Latest-Development-Setup.html)
    * [ Maintain source checkout ](../../Installation/Maintaining-a-Source-Checkout.html)
    * [ Testing with pre-release binaries ](../../Installation/Testing.html)
    * [ DDS implementations ](../../Installation/DDS-Implementations.html)
      * [ Connext security plugins ](../../Installation/DDS-Implementations/Install-Connext-Security-Plugins.html)
      * [ RTI Connext DDS ](../../Installation/DDS-Implementations/Install-Connext-University-Eval.html)
      * [ Eclipse Cyclone DDS ](../../Installation/DDS-Implementations/Working-with-Eclipse-CycloneDDS.html)
      * [ GurumNetworks GurumDDS ](../../Installation/DDS-Implementations/Working-with-GurumNetworks-GurumDDS.html)
      * [ eProsima Fast DDS ](../../Installation/DDS-Implementations/Working-with-eProsima-Fast-DDS.html)
  * [ Distributions ](../../Releases.html)
    * [ Iron Irwini ( ` iron  ` ) ](../../Releases/Release-Iron-Irwini.html)
      * [ Iron Irwini Changelog ](../../Releases/Iron-Irwini-Complete-Changelog.html)
    * [ Humble Hawksbill ( ` humble  ` ) ](../../Releases/Release-Humble-Hawksbill.html)
      * [ Humble Hawksbill changelog ](../../Releases/Humble-Hawksbill-Complete-Changelog.html)
    * [ Rolling Ridley ( ` rolling  ` ) ](../../Releases/Release-Rolling-Ridley.html)
    * [ Development Distribution ](../../Releases/Development.html)
      * [ Jazzy Jalisco (codename âjazzyâ; May, 2024) ](../../Releases/Release-Jazzy-Jalisco.html)
    * [ End-of-Life Distributions ](../../Releases/End-of-Life.html)
      * [ Galactic Geochelone ( ` galactic  ` ) ](../../Releases/Release-Galactic-Geochelone.html)
        * [ Galactic Geochelone changelog ](../../Releases/Galactic-Geochelone-Complete-Changelog.html)
      * [ Foxy Fitzroy ( ` foxy  ` ) ](../../Releases/Release-Foxy-Fitzroy.html)
      * [ Eloquent Elusor ( ` eloquent  ` ) ](../../Releases/Release-Eloquent-Elusor.html)
      * [ Dashing Diademata ( ` dashing  ` ) ](../../Releases/Release-Dashing-Diademata.html)
      * [ Crystal Clemmys ( ` crystal  ` ) ](../../Releases/Release-Crystal-Clemmys.html)
      * [ Bouncy Bolson ( ` bouncy  ` ) ](../../Releases/Release-Bouncy-Bolson.html)
      * [ Ardent Apalone ( ` ardent  ` ) ](../../Releases/Release-Ardent-Apalone.html)
      * [ Beta 3 ( ` r2b3  ` ) ](../../Releases/Beta3-Overview.html)
      * [ Beta 2 ( ` r2b2  ` ) ](../../Releases/Beta2-Overview.html)
      * [ Beta 1 ( ` Asphalt  ` ) ](../../Releases/Beta1-Overview.html)
      * [ Alphas ](../../Releases/Alpha-Overview.html)


If the client is canceled (e.g. by you entering ` Ctrl+C  ` into the
terminal), it will return an error log message stating it was interrupted.


bool rcl_clock_valid  |  (  |  [ rcl_clock_t ](structrcl__clock__t.html) *  |
_clock_ |  )  |
---|---|---|---|---|---

Check if the clock has valid values.


#include <rclcpp_components/register_node_macro.hpp>
RCLCPP_COMPONENTS_REGISTER_NODE(ros2_examples::ServiceClientExample)


##  ◆  RCL_NS_TO_MS


  Public API

The implementation from client library will provide ` Time ` , ` Duration ` ,
and ` Rate ` datatypes, for all three time source abstractions.

The ` Clock ` will support a ` sleep_for ` function as well as a ` sleep_until
` method using a ` Duration ` or ` Time ` argument respectively. The
implementation will also provide a ` Timer ` object which will provide
periodic callback functionality for all the abstractions.

It will also support registering callbacks for before and after a time jump.
The first callback will be to allow proper preparations for a time jump. The
latter will allow code to respond to the change in time and include the new
time specifically as well as a quantification of the jump.

Any API which is blocking will allow a set of flags to indicate the
appropriate behavior in case of time jump. This will allow the user to choose
to error immediately on a time jump or choose to ignore. When registering a
callback for jumps a filter for the minimum backwards or forwards distance
will be possible and well as whether a clock change is to be included.


[ pabled91  ](https://get-help.theconstruct.ai/u/pabled91) June 23, 2023,
4:14pm  1


#define RCL_US_TO_NS [ RCUTILS_US_TO_NS
](http://docs.ros2.org/ardent/api/rcutils/time_8h.html#abfe5ac86d1a02406a218b145ab79c498)
---

Convenience macro to convert microseconds to nanoseconds.


* Related content


typedef [ rcutils_time_point_value_t
](http://docs.ros2.org/ardent/api/rcutils/time_8h.html#a14de75ad74511cd94d4964c6422564e6)
[ rcl_time_point_value_t ](time_8h.html#a504861cd584105c7ddfea1dd6539f8e8)
---

A single point in time, measured in nanoseconds since the Unix epoch.


#define RCL_MS_TO_NS [ RCUTILS_MS_TO_NS
](http://docs.ros2.org/ardent/api/rcutils/time_8h.html#a428e1debfc4394e50ba59f1aaa2a5a03)
---

Convenience macro to convert milliseconds to nanoseconds.


[ Course Support  ](/c/course-support/ros2-in-5-days-c/62) [ ROS2 in 5 Days
C++  ](/c/course-support/ros2-in-5-days-c/62)


  Background

Many robotics algorithms inherently rely on timing as well as synchronization.
To this end we require that nodes running in the ROS network have a
synchronized system clock such that they can accurately report timestamps for
events.

There are however several use cases where being able to control the progress
of the system is important.


This method will enable the ROS time abstraction override values, such that
the time source will report the set value instead of falling back to system
time.


In any case, maybe you need to solve your problem using another approach,
because it seems that there is [ an issue with the wait-for-message
implementation ](https://github.com/ros2/rclcpp/issues/1953) .


  * Prints a log message when itâs ready:

        RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Ready to add two ints.");


     ` RCL_RET_OK ` if the time source was successfully finalized, or
     ` RCL_RET_INVALID_ARGUMENT ` if any arguments are invalid, or
     ` RCL_RET_ERROR ` an unspecified error occur.


                              const std::shared_ptr<FindWall::Response> response) {
        typeid(request).name(); // non intrusive function to avoid unused value warning

        auto message = sensor_msgs::msg::LaserScan();

        RCLCPP_INFO(this->get_logger(), "starting to wait for message");
        bool scan_found = false;
        while (!scan_found) {
          scan_found = rclcpp::wait_for_message(message, this->shared_from_this(),"/scan",std::chrono::seconds(1));
          RCLCPP_INFO(this->get_logger(), "scan_found = %d", scan_found);
          RCLCPP_INFO(this->get_logger(), "still waiting for message");
        }

          this->laser_left = message.ranges[90];
          this->laser_right = message.ranges[270];
          this->laser_forward = message.ranges[0];
          this->laser_backward = message.ranges[180];
          RCLCPP_INFO(this->get_logger(), "[LEFT] = '%f'", this->laser_left);
          RCLCPP_INFO(this->get_logger(), "[RIGHT] = '%f'", this->laser_right);
          RCLCPP_INFO(this->get_logger(), "[FORWARD] = '%f'", this->laser_forward);
          RCLCPP_INFO(this->get_logger(), "[BACKWARD] = '%f'", this->laser_backward);

        response->wallfound = true;
      }
    };

    int main(int argc, char *argv[]) {
      rclcpp::init(argc, argv);
      rclcpp::spin(std::make_shared<ServerNode>());
      rclcpp::shutdown();
      return 0;
    }


     ` RCL_RET_OK ` if the difference was computed successfully, or
     ` RCL_RET_INVALID_ARGUMENT ` if any arguments are invalid, or
     ` RCL_RET_ERROR ` an unspecified error occur.


##  ◆  rcl_is_enabled_ros_time_override()


  * [ Home ](/)
  * [ Categories ](/categories)
  * [ FAQ/Guidelines ](/guidelines)
  * [ Terms of Service ](http://www.theconstructsim.com/terms_and_conditions/)
  * [ Privacy Policy ](http://www.theconstructsim.com/privacy_policy/)


}  // namespace ros2_examples


typedef enum [ rcl_clock_type_t
](time_8h.html#a5c734f508ce06aec7974af10ad09d071) [ rcl_clock_type_t
](time_8h.html#a5c734f508ce06aec7974af10ad09d071)
---

Time source type, used to indicate the source of a time measurement.


     [in]  |  clock  |  The clock to enable.
---|---|---

Returns


          this->laser_forward); RCLCPP_INFO(this->get_logger(), "[LEFT] = '%f'",
          this->laser_left); RCLCPP_INFO(this->get_logger(), "[RIGHT] = '%f'",
          this->laser_right); RCLCPP_INFO(this->get_logger(), "[FORWARD] = '%f'",
          this->laser_forward); RCLCPP_INFO(this->get_logger(), "[BACKWARD] = '%f'",
                      this->laser_backward);
          */
          rclcpp::sleep_for(1s);
        }
        this->twist_msg.linear.x = 0;
        this->twist_msg.angular.z = 0;
        publisher_->publish(twist_msg);
        subscription_.reset();
        RCLCPP_INFO(this->get_logger(), "in position, end of service");
        response->wallfound = true;
      }

      int find_min_index(std::vector<float> laser_values) {
        int length = laser_values.size();
        // RCLCPP_INFO(this->get_logger(), "length= %d", length);
        float min = laser_values[0];
        int index = 0;
        for (int i = 0; i < length; i++) {
          // RCLCPP_INFO(this->get_logger(), " %f\n", laser_values[i]);
          if (laser_values[i] < min) {
            min = laser_values[i];
            index = i;
          }
        }
        return index;
      }

      void start_scan_sub() {
        rclcpp::SubscriptionOptions sub_options;
        sub_options.callback_group = callback_group_2_;
        subscription_ = this->create_subscription<sensor_msgs::msg::LaserScan>(
            "/scan", rclcpp::SensorDataQoS(),
            std::bind(&ServerNode::scan_callback, this, _1), sub_options);
      }

      void scan_callback(const sensor_msgs::msg::LaserScan::SharedPtr msg) {


Linux  macOS  Windows


can somebody explain me how to use rclcpp::wait_for_message(), and more
specifically inside of a node class please?


     [in]  |  clock  |  The clock to update.
---|---|---
[in]  |  time_value  |  The new current time.

Returns


[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796)
rcl_enable_ros_time_override  |  (  |  [ rcl_clock_t
](structrcl__clock__t.html) *  |  _clock_ |  )  |
---|---|---|---|---|---

Enable the ROS time abstraction override.


The ` --dependencies  ` argument will automatically add the necessary
dependency lines to ` package.xml  ` and ` CMakeLists.txt  ` . `
example_interfaces  ` is the package that includes [ the .srv file
](https://github.com/ros2/example_interfaces/blob/foxy/srv/AddTwoInts.srv) you
will need to structure your requests and responses:


[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796)
rcl_system_clock_init  |  (  |  [ rcl_clock_t ](structrcl__clock__t.html) *  |
_clock_ ,
---|---|---|---
|  |  [ rcl_allocator_t ](allocator_8h.html#ac7146d98a03ca836efa0d0d77c78984c)
*  |  _allocator_
|  )  |  |

Initialize a clock as a ` RCL_SYSTEM_TIME ` time source.


[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796)
rcl_ros_clock_fini  |  (  |  [ rcl_clock_t ](structrcl__clock__t.html) *  |
_clock_ |  )  |
---|---|---|---|---|---

Finalize a clock as a ` RCL_ROS_TIME ` time source.


The terminal should return the following message, and then wait:


That works in simulation without using wait_for_message


> I don’t want to use directly a subscriber because I want to make sur to get
> a real message before starting to move.


##  ◆  rcl_clock_type_t


####  2.2 Add executable  ï


RCUTILS_NS_TO_MS
](http://docs.ros2.org/ardent/api/rcutils/time_8h.html#a32b8b03e8399363992e8b7b2275072d2)
|  Convenience macro to convert nanoseconds to milliseconds.  More...

#define  |  [ RCL_NS_TO_US ](time_8h.html#a3d9a69217c72e18a5b94ac714681ae1c) [
RCUTILS_NS_TO_US
](http://docs.ros2.org/ardent/api/rcutils/time_8h.html#a2f4bb125791d58045e4b6d57c83b6209)
|  Convenience macro to convert nanoseconds to microseconds.  More...

##  Typedefs

---
typedef [ rcutils_time_point_value_t
](http://docs.ros2.org/ardent/api/rcutils/time_8h.html#a14de75ad74511cd94d4964c6422564e6)
|  [ rcl_time_point_value_t ](time_8h.html#a504861cd584105c7ddfea1dd6539f8e8)
|  A single point in time, measured in nanoseconds since the Unix epoch.
More...

typedef [ rcutils_duration_value_t
](http://docs.ros2.org/ardent/api/rcutils/time_8h.html#a7fd03e84bd0de8c6e189bf2a21cf3946)
|  [ rcl_duration_value_t ](time_8h.html#acf6c7e80500a4ed249168d1d5866f09a)
|  A duration of time, measured in nanoseconds.  More...

typedef enum [ rcl_clock_type_t
](time_8h.html#a5c734f508ce06aec7974af10ad09d071) |  [ rcl_clock_type_t
](time_8h.html#a4bd4c56c46a056fb155e225ca3726885)
|  Time source type, used to indicate the source of a time measurement.
More...

typedef struct [ rcl_clock_t ](structrcl__clock__t.html) |  [ rcl_clock_t
](time_8h.html#a5cf0b96b0d4e809381b8b24e1d47e890)
|  Encapsulation of a time source.  More...

typedef struct [ rcl_time_point_t ](structrcl__time__point__t.html) |  [
rcl_time_point_t ](time_8h.html#aa21896a85e4005fd9ef40f67625c7e4e)
|  A single point in time, measured in nanoseconds, the reference point is
based on the source.  More...

typedef struct [ rcl_duration_t ](structrcl__duration__t.html) |  [


This function will populate the data of the time_point object with the current
value from it's associated time abstraction.


  Clock and Time

This article describes the ROS primitives to support programming which can run
both in real time as well as simulated time which may be faster or slower.

Authors: [ Tully Foote ](https://github.com/tfoote)

Date Written: 2018-07

Last Modified: 2015-12


Enumerator
---
RCL_CLOCK_UNINITIALIZED  |
RCL_ROS_TIME  |
RCL_SYSTEM_TIME  |
RCL_STEADY_TIME  |

##  Function Documentation


    cmake_minimum_required(VERSION 3.5)
    project(cpp_srvcli)

    find_package(ament_cmake REQUIRED)
    find_package(rclcpp REQUIRED)
    find_package(example_interfaces REQUIRED)

    add_executable(server src/add_two_ints_server.cpp)
    ament_target_dependencies(server rclcpp example_interfaces)

    add_executable(client src/add_two_ints_client.cpp)
    ament_target_dependencies(client rclcpp example_interfaces)

    install(TARGETS
      server
      client
      DESTINATION lib/${PROJECT_NAME})

    ament_package()


     ` RCL_RET_OK ` if the time source was successfully initialized, or
     ` RCL_RET_INVALID_ARGUMENT ` if any arguments are invalid, or
     ` RCL_RET_ERROR ` an unspecified error occur.


* Tasks


[INFO] [rclcpp]: Sum: 5


Parameters


     [in]  |  clock  |  the handle to the clock which is being initialized
---|---|---

Returns


Your terminal will return a message verifying the creation of your package `
cpp_srvcli  ` and all its necessary files and folders.


**Time:** 20 minutes


##  ◆  rcl_difference_times()


So ` ros2  run  ` can find the executable, add the following lines to the end
of the file, right before ` ament_package()  ` :


#define RCL_NS_TO_S [ RCUTILS_NS_TO_S
](http://docs.ros2.org/ardent/api/rcutils/time_8h.html#aa67004f0b6b3206da7b72b7ed8dd7914)
---

Convenience macro to convert nanoseconds to seconds.


####  2.1 Examine the code  ï


##  ◆  rcl_clock_type_t


    install(TARGETS
        server
      DESTINATION lib/${PROJECT_NAME})


    rclcpp::Client<std_srvs::srv::SetBool>::SharedFuture setbool_future_;
    void timer_future();


What setup do you have (for the service and the laser scan callback)?


  ServiceClientExample::ServiceClientExample(rclcpp::NodeOptions options) : Node("service_client_example", options)
  {
    RCLCPP_INFO(get_logger(), "[ServiceClientExample]: initializing");


Open another terminal, source the setup files from inside ` ros2_ws  ` again.
Start the client node, followed by any two integers separated by a space:


     [in]  |  clock  |  the handle to the clock which is being queried
---|---|---

Returns


This will allocate all necessary internal structures, and initialize
variables. It is specifically setting up a ` RCL_STEADY_TIME ` time source.


##  Related content  ï


####  3.2 Add executable  ï


* Next steps


1 Like


* 3 Write the client node


/* timer_callback() //{ */


Initialize the clock as a ` RCL_SYSTEM_TIME ` time source.


In Development


  * Creates a node named ` add_two_ints_server  ` :

        std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("add_two_ints_server");


     ` RCL_RET_OK ` if the last call time was retrieved successfully, or
     ` RCL_RET_INVALID_ARGUMENT ` if any arguments are invalid, or
     ` RCL_RET_ERROR ` an unspecified error occur.


Parameters


     [in]  |  clock  |  the handle to the clock which is being initialized
---|---|---
[in]  |  allocator  |  The allocator to use for allocations

Returns


##  ◆  RCL_S_TO_NS


            rmw_qos_profile_services_default, callback_group_1_);

        publisher_ =
            this->create_publisher<geometry_msgs::msg::Twist>("cmd_vel", 1);

        this->laser_left = 0.0;
        this->laser_right = 0.0;
        this->laser_forward = 0.0;
        this->laser_backward = 0.0;
      }

    private:
      rclcpp::Service<FindWall>::SharedPtr srv_;
      rclcpp::TimerBase::SharedPtr timer_;
      rclcpp::CallbackGroup::SharedPtr callback_group_1_;
      rclcpp::CallbackGroup::SharedPtr callback_group_2_;
      rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr publisher_;
      rclcpp::Subscription<sensor_msgs::msg::LaserScan>::SharedPtr subscription_;
      geometry_msgs::msg::Twist twist_msg;
      float laser_left;
      float laser_right;
      float laser_forward;
      float laser_backward;
      bool scan_found;

      void find_wall_callback(const std::shared_ptr<FindWall::Request> request,
                              const std::shared_ptr<FindWall::Response> response) {
        // non intrusive function to avoid unused value warning
        typeid(request).name();

        auto scan_message = sensor_msgs::msg::LaserScan();
        twist_msg.linear.x = 0.0;
        twist_msg.angular.z = 0.0;

        scan_found = false;
        RCLCPP_INFO(this->get_logger(), "starting to wait for message");
        start_scan_sub();
        while (!scan_found) {
          RCLCPP_INFO(this->get_logger(), "still waiting for message");
          rclcpp::sleep_for(1s);


  * Creates a service named ` add_two_ints  ` for that node and automatically advertises it over the networks with the ` &add  ` method:

        rclcpp::Service<example_interfaces::srv::AddTwoInts>::SharedPtr service =
    node->create_service<example_interfaces::srv::AddTwoInts>("add_two_ints", &add);


     [in]  |  clock  |  the handle to the clock which is being initialized.
---|---|---

Returns


      * [ Contributing to ROS 2 Documentation ](../../The-ROS2-Project/Contributing/Contributing-To-ROS-2-Documentation.html)
    * [ Features Status ](../../The-ROS2-Project/Features.html)
    * [ Feature Ideas ](../../The-ROS2-Project/Feature-Ideas.html)
    * [ Roadmap ](../../The-ROS2-Project/Roadmap.html)
    * [ ROSCon Talks ](../../The-ROS2-Project/ROSCon-Content.html)
    * [ Project Governance ](../../The-ROS2-Project/Governance.html)
      * [ ROS 2 Technical Steering Committee Charter ](../../The-ROS2-Project/Governance/ROS2-TSC-Charter.html)
      * [ ROS 2 TSC applicant intake process ](../../The-ROS2-Project/Governance/ROS2-TSC-Intake-process.html)
      * [ How to Start a Community Working Group ](../../The-ROS2-Project/Governance/How-To-Start-A-Community-Working-Group.html)
    * [ Marketing ](../../The-ROS2-Project/Marketing.html)
  * [ Related Projects ](../../Related-Projects.html)
    * [ Intel ROS 2 Projects ](../../Related-Projects/Intel-ROS2-Projects.html)
    * [ NVIDIA ROS 2 Projects ](../../Related-Projects/Nvidia-ROS2-Projects.html)
  * [ Glossary ](../../Glossary.html)
  * [ Citations ](../../Citations.html)


This function will update the internal storage for the ` RCL_ROS_TIME ` time
source. If queried and override enabled the time source will return this
value, otherwise it will return the system time.


####  1.1 Update ` package.xml  ` ï


#include <rclcpp/rclcpp.hpp>


  // a timer callback should never block for too long, so all checks should return after a while
  void ServiceClientExample::timer_future()
  {
    // if the future is already waiting for a result, check if we got one
    if (setbool_future_.valid())
    {
        const std::future_status status = setbool_future_.wait_for(std::chrono::seconds(1));;
        if (status == std::future_status::ready)
        {
          // future already got a result, check it and report to user
          const auto result = setbool_future_.get();
          // reset the future
          setbool_future_ = {};
          if (result->success)
            RCLCPP_INFO_STREAM(get_logger(), "[ServiceClientExample]: future finished, service call successful with message: " << result->message);
          else
            RCLCPP_INFO_STREAM(get_logger(), "[ServiceClientExample]: future finished, service call reports failure: " << result->message);
        }
        else
          // future isn't ready yet
          RCLCPP_INFO(get_logger(), "[ServiceClientExample]: service future not ready yet, waiting again...");
    }
    // if the future is not waiting for a result, make a new service call
    else
    {
      // you should not send a service request unless the service is ready, otherwise the future will never be ready
      if (service_client_->service_is_ready())
      {
        auto request = std::make_shared<std_srvs::srv::SetBool::Request>();
        request->data = true;
        setbool_future_ = service_client_->async_send_request(request);
        RCLCPP_INFO(get_logger(), "[ServiceClientExample]: called service using future");
      }
      else
        RCLCPP_WARN(get_logger(), "[ServiceClientExample]: not calling service using future, service not ready!");
    }
  }


[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796)
rcl_disable_ros_time_override  |  (  |  [ rcl_clock_t
](structrcl__clock__t.html) *  |  _clock_ |  )  |
---|---|---|---|---|---

Disable the ROS time abstraction override.


     [in]  |  clock  |  The clock to query.
---|---|---
[out]  |  is_enabled  |  Whether the override is enabled..

Returns


    while (!rclcpp::wait_for_message(message, node_, "scan",1)) {
          RCLCPP_INFO(this->get_logger(), "still waiting for message");
    }


    [INFO] [rclcpp]: Incoming request
    a: 2 b: 3
    [INFO] [rclcpp]: sending back response: [5]


This method will disable the ` RCL_ROS_TIME ` time abstraction override
values, such that the time source will report the system time even if a custom
value has been set.


     [in]  |  clock  |  The clock to disable.
---|---|---

Returns


__ [ ROS 2 Documentation: Foxy ](../../index.html)


You could provide more context here. Which exercise are you trying to solve
exactly?


What is strange is that rqt_graph shows that I subscribed to the topic but it
doesn’t get any value:


    int64 a
    int64 b
    ---
    int64 sum


© Copyright 2024, Open Robotics.


The example used here is a simple integer addition system; one node requests
the sum of two integers, and the other responds with the result.


  RCL implementation

In ` rcl ` there will be datatypes and methods to implement each of the three
time abstractions for each of the core datatypes. However at the ` rcl ` level
the implementation will be incomplete as it will not have a threading model
and will rely on the higher level implementation to provide any threading
functionality which is required by sleep methods. It also will require
appropriate threading to support the reception of ` TimeSource ` data.

It will provide implementations parallel to the public datastructures and
storage which the client library can depend upon and to which it can delegate.
The underlying datatypes will also provide ways to register notifications,
however it is the responsibility of the client library implementation to
collect and dispatch user callbacks.

**TODO:** Enumerate the ` rcl ` datastructures and methods here.


The ` while  ` loop gives the client 1 second to search for service nodes in
the network. If it canât find any, it will continue waiting.


Linux  macOS  Windows


Parameters


##  ◆  rcl_duration_value_t


  // The callback function for service call response.
  // This function will be executed once the other side decides to respond to the service call.
  void ServiceClientExample::setbool_callback(rclcpp::Client<std_srvs::srv::SetBool>::SharedFuture future)
  {
    // the future must be ready now that the callback was called
    const auto result = setbool_future_.get();
    if (result->success)
      RCLCPP_INFO_STREAM(get_logger(), "[ServiceClientExample]: callback called, service call successful with message: " << result->message);
    else
      RCLCPP_INFO_STREAM(get_logger(), "[ServiceClientExample]: callback called, service call reports failure: " << result->message);
  }


using namespace std::chrono_literals;


Powered by [ Discourse ](https://www.discourse.org) , best viewed with
JavaScript enabled


##  ◆  RCL_MS_TO_NS


Then the client sends its request, and the node spins until it receives its
response, or fails.


#define RCL_S_TO_NS [ RCUTILS_S_TO_NS
](http://docs.ros2.org/ardent/api/rcutils/time_8h.html#a09bb0400aa6b85f877d616e7475aa173)
---

Convenience macro to convert seconds to nanoseconds.


// | --------------------- service client --------------------- |


[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796)
rcl_difference_times  |  (  |  [ rcl_time_point_t
](structrcl__time__point__t.html) *  |  _start_ ,
---|---|---|---
|  |  [ rcl_time_point_t ](structrcl__time__point__t.html) *  |  _finish_ ,
|  |  [ rcl_duration_t ](structrcl__duration__t.html) *  |  _delta_
|  )  |  |

Compute the difference between two time points.


This will deallocate all necessary internal structures, and clean up any
variables. It is specifically setting up a ` RCL_ROS_TIME ` time source. It is
expected to be paired with the init fuction.


      {
        RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Sum: %ld", result.get()->sum);
      } else {
        RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Failed to call service add_two_ints");
      }

      rclcpp::shutdown();
      return 0;
    }


This will deallocate all necessary internal structures, and clean up any
variables. It is specifically setting up a steady time source. It is expected
to be paired with the init fuction.


  Time Abstractions

There will be at least three versions of these abstractions with the following
types, ` SystemTime ` , ` SteadyTime ` and ` ROSTime ` . These choices are
designed to parallel the [ ` std::chrono `
](http://en.cppreference.com/w/cpp/chrono) [ ` system_clock `
](http://en.cppreference.com/w/cpp/chrono/system_clock) and [ ` steady_clock `
](http://en.cppreference.com/w/cpp/chrono/steady_clock) . It is expected that
the default choice of time will be to use the ` ROSTime ` source, however the
parallel implementations supporting ` steady_clock ` and ` system_clock ` will
be maintained for use cases where the alternate time source is required.


service_client_ = create_client<std_srvs::srv::SetBool>("~/set_bool_out");


[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796) |  [
rcl_ros_clock_init ](time_8h.html#abb633aa71d9479bbf66c3fbc55d28f4a) ( [
rcl_clock_t ](structrcl__clock__t.html) *clock, [ rcl_allocator_t
](allocator_8h.html#ac7146d98a03ca836efa0d0d77c78984c) *allocator)
|  Initialize a clock as a RCL_ROS_TIME time source.  More...

[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796) |  [
rcl_ros_clock_fini ](time_8h.html#a3ef06ff7e2502f0d8ea35471e294a15b) ( [
rcl_clock_t ](structrcl__clock__t.html) *clock)
|  Finalize a clock as a ` RCL_ROS_TIME ` time source.  More...

[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796) |  [
rcl_steady_clock_init ](time_8h.html#a21f3f7dc409aca89bf47e9dbd20b9131) ( [
rcl_clock_t ](structrcl__clock__t.html) *clock, [ rcl_allocator_t
](allocator_8h.html#ac7146d98a03ca836efa0d0d77c78984c) *allocator)
|  Initialize a clock as a ` RCL_STEADY_TIME ` time source.  More...

[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796) |  [
rcl_steady_clock_fini ](time_8h.html#a138ee1f2510700becae5772a9da4de02) ( [
rcl_clock_t ](structrcl__clock__t.html) *clock)
|  Finalize a clock as a ` RCL_STEADY_TIME ` time source.  More...

[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796) |  [
rcl_system_clock_init ](time_8h.html#ad994c08334a592682c66b4214c6b12f0) ( [
rcl_clock_t ](structrcl__clock__t.html) *clock, [ rcl_allocator_t
](allocator_8h.html#ac7146d98a03ca836efa0d0d77c78984c) *allocator)
|  Initialize a clock as a ` RCL_SYSTEM_TIME ` time source.  More...

[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796) |  [
rcl_system_clock_fini ](time_8h.html#afe67d05b2d2c4e5bfcec40fcee1ec84a) ( [
rcl_clock_t ](structrcl__clock__t.html) *clock)
|  Finalize a clock as a ` RCL_SYSTEM_TIME ` time source.  More...

[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796) |  [
rcl_difference_times ](time_8h.html#a39207579484ea036093170e8d0c2955c) ( [
rcl_time_point_t ](structrcl__time__point__t.html) *start, [ rcl_time_point_t
](structrcl__time__point__t.html) *finish, [ rcl_duration_t
](structrcl__duration__t.html) *delta)
|  Compute the difference between two time points.  More...


// | -------------------------- timer ------------------------- |


\-----EDIT------
It appears that my last problem was due to the fact that for some reason the
turtle bot didn’t publish values on the topic.
This code worked for me.


####  3.1 Examine the code  ï


Thank you in advance
Pablo


// | --------------------- finish the init -------------------- |


##  Tasks  ï


  ROS Time

The ` ROSTime ` will report the same as ` SystemTime ` when a ROS Time Source
is not active. When the ROS time source is active ` ROSTime ` will return the
latest value reported by the Time Source. ` ROSTime ` is considered active
when the parameter ` use_sim_time ` is set on the node.


    timer_future_ = create_wall_timer(std::chrono::duration<double>(1.0 / 2.0), std::bind(&ServiceClientExample::timer_future, this));
    timer_callback_ = create_wall_timer(std::chrono::duration<double>(1.0 / 2.0), std::bind(&ServiceClientExample::timer_callback, this));


// | ------------------------ routines ------------------------ |


#define RCL_NS_TO_US [ RCUTILS_NS_TO_US
](http://docs.ros2.org/ardent/api/rcutils/time_8h.html#a2f4bb125791d58045e4b6d57c83b6209)
---

Convenience macro to convert nanoseconds to microseconds.


![](https://get-help.robotigniteacademy.com/user_avatar/get-
help.robotigniteacademy.com/pabled91/48/6967_2.png) pabled91:


In the last few tutorials youâve been utilizing interfaces to pass data
across topics and services. Next, youâll learn how to [ create custom
interfaces  ](Custom-ROS2-Interfaces.html) .


Generated by [ ![doxygen](doxygen.png) ](http://www.doxygen.org/index.html)
1.8.14


##  ◆  rcl_clock_fini()


     ` RCL_RET_OK ` if the time source was successfully initialized, or
     ` RCL_RET_INVALID_ARGUMENT ` if any arguments are invalid, or
     ` RCL_RET_ERROR ` an unspecified error occur.


     [in]  |  clock  |  the handle to the clock which is being initialized
---|---|---
[in]  |  allocator  |  The allocator to use for allocations

Returns


Parameters


As always, though, make sure to add the description, maintainer email and
name, and license information to ` package.xml  ` .


##  ◆  rcl_system_clock_init()


[ ![image](https://get-
help.robotigniteacademy.com/uploads/default/optimized/2X/8/856d13549367a8426ea64c5f756a83da41e3c1d2_2_690x328.jpeg)
image  1327×632 69.8 KB  ](https://get-
help.robotigniteacademy.com/uploads/default/original/2X/8/856d13549367a8426ea64c5f756a83da41e3c1d2.jpeg
"image")


  Use cases requiring time abstraction

When playing back logged data it is often very valuable to support
accelerated, slowed, or stepped control over the progress of time. This
control can allow you to get to a specific time and pause the system so that
you can debug it in depth. It is possible to do this with a log of the sensor
data, however if the sensor data is out of synchronization with the rest of
the system it will break many algorithms.

Another important use case for using an abstracted time source is when you are
running logged data against a simulated robot instead of a real robot.
Depending on the simulation characteristics, the simulator may be able to run
much faster than real time or it may need to run much slower. Running faster
than real time can be valuable for high level testing as well allowing for
repeated system tests. Slower than real time simulation is necessary for
complicated systems where accuracy is more important than speed. Often the
simulation is the limiting factor for the system and as such the simulator can
be a time source for faster or slower playback. Additionally if the simulation
is paused the system can also pause using the same mechanism.


  class ServiceClientExample : public rclcpp::Node
  {
  public:
    ServiceClientExample(rclcpp::NodeOptions options);


##  ◆  rcl_clock_t


It’s a little bit strange it works very well when it wait for message gets the
message but sometimes even if i see the scan topic being published with ` ros2
topic echo /scan ` my function seems to not get the message…
That’s a little bit problematic because I’m blocked waiting to get a message
sometimes so it’s a little bit complicated to debbug sometimes. I dont want to
use directly a subscriber because I want to make sur to get a real message
before starting to move.


rcl_duration_t ](time_8h.html#ae40b4a93b882580708a9d2cad3dab077)
|  A duration of time, measured in nanoseconds and its source.  More...

##  Enumerations

---
enum  |  [ rcl_clock_type_t ](time_8h.html#a5c734f508ce06aec7974af10ad09d071)
{ [ RCL_CLOCK_UNINITIALIZED
](time_8h.html#a5c734f508ce06aec7974af10ad09d071a529af8240ca9a5ca9ad5246f245e4f78)
= 0, [ RCL_ROS_TIME
](time_8h.html#a5c734f508ce06aec7974af10ad09d071a3ad5b0e7c618d4b050a88e1c6a721888)
, [ RCL_SYSTEM_TIME
](time_8h.html#a5c734f508ce06aec7974af10ad09d071a423b9ea49c5f5119c3b9b812c01e6bc9)
, [ RCL_STEADY_TIME
](time_8h.html#a5c734f508ce06aec7974af10ad09d071a57ed8e9becda146fecef1e0e894eb828)
}
|  Time source type, used to indicate the source of a time measurement. [
More... ](time_8h.html#a5c734f508ce06aec7974af10ad09d071)

##  Functions

---
bool  |  [ rcl_clock_valid ](time_8h.html#af31a56ad09ba849983b8969794e09e93) (
[ rcl_clock_t ](structrcl__clock__t.html) *clock)
|  Check if the clock has valid values.  More...

[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796) |  [
rcl_clock_init ](time_8h.html#a532ecf48864c752c8aafd0103a1ac5e7) (enum [
rcl_clock_type_t ](time_8h.html#a5c734f508ce06aec7974af10ad09d071) clock_type,
[ rcl_clock_t ](structrcl__clock__t.html) *clock, [ rcl_allocator_t
](allocator_8h.html#ac7146d98a03ca836efa0d0d77c78984c) *allocator)
|  Initialize a clock based on the passed type.  More...

[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796) |  [
rcl_clock_fini ](time_8h.html#adcbaa99199e30d33dcf103aa510f65ff) ( [
rcl_clock_t ](structrcl__clock__t.html) *clock)
|  Finalize a clock.  More...


#  [ How to use rclcpp::wait_for_message() in a node class ](/t/how-to-use-
rclcpp-wait-for-message-in-a-node-class/25045)


* There are several ways you could write a service and client in C++; check out the ` minimal_service  ` and ` minimal_client  ` packages in the [ ros2/examples ](https://github.com/ros2/examples/tree/foxy/rclcpp/services) repo.


     ` RCL_RET_OK ` if the time source was disabled successfully, or
     ` RCL_RET_INVALID_ARGUMENT ` if any arguments are invalid, or
     ` RCL_RET_ERROR ` an unspecified error occur.


[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796)
rcl_ros_clock_init  |  (  |  [ rcl_clock_t ](structrcl__clock__t.html) *  |
_clock_ ,
---|---|---|---
|  |  [ rcl_allocator_t ](allocator_8h.html#ac7146d98a03ca836efa0d0d77c78984c)
*  |  _allocator_
|  )  |  |

Initialize a clock as a RCL_ROS_TIME time source.


                                       "/scan", std::chrono::seconds(1));
          //RCLCPP_INFO(this->get_logger(), "still waiting for message");
        }
        RCLCPP_INFO(this->get_logger(), "scan_found = %d", scan_found);
        this->laser_left = scan_message.ranges[90];
        this->laser_right = scan_message.ranges[270];
        this->laser_forward = scan_message.ranges[0];
        this->laser_backward = scan_message.ranges[180];

        std::vector<float> laser_values = {this->laser_left, this->laser_right,
                                           this->laser_forward,
                                           this->laser_backward};

        int min_index = find_min_index(laser_values);
        RCLCPP_INFO(this->get_logger(), "min value is at index %d", min_index);
        switch (min_index) {
        case 0:
          RCLCPP_INFO(this->get_logger(), "wall on the left");
          twist_msg.angular.z = 0.2;
          break;
        case 1:
          RCLCPP_INFO(this->get_logger(), "wall on the right");
          if (laser_right < 0.3) {
            RCLCPP_INFO(this->get_logger(), "already in position, end of service");
            response->wallfound = true;
            return;
          }
          twist_msg.angular.z = -0.2;
          break;
        case 2:
          RCLCPP_INFO(this->get_logger(), "wall in front");
          twist_msg.linear.x = 0.2;
          break;
        case 3:
          RCLCPP_INFO(this->get_logger(), "wall behind");
          twist_msg.linear.x = 0.2;
          break;
        }


[ Go to the source code of this file. ](time_8h_source.html)


The ` add  ` function adds two integers from the request and gives the sum to
the response, while notifying the console of its status using logs.


Open a new terminal, navigate to ` ros2_ws  ` , and source the setup files:


##  Summary  ï


    #include "rclcpp/rclcpp.hpp"
    #include "example_interfaces/srv/add_two_ints.hpp"

    #include <chrono>
    #include <cstdlib>
    #include <memory>

    using namespace std::chrono_literals;

    int main(int argc, char **argv)
    {
      rclcpp::init(argc, argv);

      if (argc != 3) {
          RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "usage: add_two_ints_client X Y");
          return 1;
      }

      std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("add_two_ints_client");
      rclcpp::Client<example_interfaces::srv::AddTwoInts>::SharedPtr client =
        node->create_client<example_interfaces::srv::AddTwoInts>("add_two_ints");

      auto request = std::make_shared<example_interfaces::srv::AddTwoInts::Request>();
      request->a = atoll(argv[1]);
      request->b = atoll(argv[2]);

      while (!client->wait_for_service(1s)) {
        if (!rclcpp::ok()) {
          RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");
          return 0;
        }
        RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "service not available, waiting again...");
      }

      auto result = client->async_send_request(request);
      // Wait for the result.
      if (rclcpp::spin_until_future_complete(node, result) ==
        rclcpp::FutureReturnCode::SUCCESS)


articles/130_ros_time.md

Toggle navigation  [ ROS 2 Design ](/)

  * [ Contribute ](/contribute.html)

[ Login disabled for now ]()

  * Clock and Time
    * Background
      * Real Time vs real-time computing
    * Use cases requiring time abstraction
    * Approach
    * Clock
      * Challenges in using abstracted time
      * Time Abstractions
        * System Time
        * ROS Time
        * Steady Time
      * ROS Time Source
        * Default Time Source
          * No Advanced Estimating Clock By Default
        * Custom Time Source
    * Implementation
      * Public API
      * RCL implementation
    * References


[INFO] [rclcpp]: Ready to add two ints.


* 4 Build and run


Return to the terminal where your service node is running. You will see that
it published log messages when it received the request and the data it
received, and the response it sent back:


Next, the request is created. Its structure is defined by the ` .srv  ` file
mentioned earlier.


Parameters


##  ◆  rcl_set_ros_time_override()


// | ------------------------- timers ------------------------- |


    #include "rclcpp/rclcpp.hpp"
    #include "example_interfaces/srv/add_two_ints.hpp"

    #include <memory>

    void add(const std::shared_ptr<example_interfaces::srv::AddTwoInts::Request> request,
              std::shared_ptr<example_interfaces::srv::AddTwoInts::Response>      response)
    {
      response->sum = request->a + request->b;
      RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Incoming request\na: %ld" " b: %ld",
                    request->a, request->b);
      RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "sending back response: [%ld]", (long int)response->sum);
    }

    int main(int argc, char **argv)
    {
      rclcpp::init(argc, argv);

      std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("add_two_ints_server");

      rclcpp::Service<example_interfaces::srv::AddTwoInts>::SharedPtr service =
        node->create_service<example_interfaces::srv::AddTwoInts>("add_two_ints", &add);

      RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Ready to add two ints.");

      rclcpp::spin(node);
      rclcpp::shutdown();
    }


          this->laser_right = msg->ranges[270];
          this->laser_forward = msg->ranges[0];
          this->laser_backward = msg->ranges[180];
        } else {
          //---------------real turtle bot values 720 values angle_min:
          //-3.1241390705108643 angle_max: 3.1415927410125732
          this->laser_left = msg->ranges[540];
          this->laser_right = msg->ranges[180];
          this->laser_forward = msg->ranges[360];
          this->laser_backward = msg->ranges[0];
        }
        /*
        RCLCPP_INFO(this->get_logger(), "[LEFT] = '%f'", this->laser_left);
        RCLCPP_INFO(this->get_logger(), "[RIGHT] = '%f'", this->laser_right);
        RCLCPP_INFO(this->get_logger(), "[FORWARD] = '%f'", this->laser_forward);
        RCLCPP_INFO(this->get_logger(), "[BACKWARD] = '%f'", this->laser_backward);
        */
      }
    };

    int main(int argc, char *argv[]) {
      rclcpp::init(argc, argv);

      std::shared_ptr<ServerNode> find_wall_server = std::make_shared<ServerNode>();

      rclcpp::executors::MultiThreadedExecutor executor;

      executor.add_node(find_wall_server);
      executor.spin();

      rclcpp::shutdown();
      return 0;
    }


    <description>C++ client server tutorial</description>
    <maintainer email="you@email.com">Your Name</maintainer>
    <license>Apache License 2.0</license>


[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796)
rcl_clock_get_now  |  (  |  [ rcl_clock_t ](structrcl__clock__t.html) *  |
_clock_ ,
---|---|---|---
|  |  [ rcl_time_point_t ](structrcl__time__point__t.html) *  |  _time_point_
|  )  |  |

Fill the time point with the current value of the associated clock.


The ` add_executable  ` macro generates an executable you can run using ` ros2
run  ` . Add the following code block to ` CMakeLists.txt  ` to create an
executable named ` server  ` :


[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796)
rcl_steady_clock_init  |  (  |  [ rcl_clock_t ](structrcl__clock__t.html) *  |
_clock_ ,
---|---|---|---
|  |  [ rcl_allocator_t ](allocator_8h.html#ac7146d98a03ca836efa0d0d77c78984c)
*  |  _allocator_
|  )  |  |

Initialize a clock as a ` RCL_STEADY_TIME ` time source.


[ bayodesegun  ](https://get-help.theconstruct.ai/u/bayodesegun) Closed  July
3, 2023, 7:47am  7


        * [ Introducing ` tf2  ` ](../Intermediate/Tf2/Introduction-To-Tf2.html)
        * [ Writing a static broadcaster (Python) ](../Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Py.html)
        * [ Writing a static broadcaster (C++) ](../Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Cpp.html)
        * [ Writing a broadcaster (Python) ](../Intermediate/Tf2/Writing-A-Tf2-Broadcaster-Py.html)
        * [ Writing a broadcaster (C++) ](../Intermediate/Tf2/Writing-A-Tf2-Broadcaster-Cpp.html)
        * [ Writing a listener (Python) ](../Intermediate/Tf2/Writing-A-Tf2-Listener-Py.html)
        * [ Writing a listener (C++) ](../Intermediate/Tf2/Writing-A-Tf2-Listener-Cpp.html)
        * [ Adding a frame (Python) ](../Intermediate/Tf2/Adding-A-Frame-Py.html)
        * [ Adding a frame (C++) ](../Intermediate/Tf2/Adding-A-Frame-Cpp.html)
        * [ Using time (Python) ](../Intermediate/Tf2/Learning-About-Tf2-And-Time-Py.html)
        * [ Using time (C++) ](../Intermediate/Tf2/Learning-About-Tf2-And-Time-Cpp.html)
        * [ Traveling in time (Python) ](../Intermediate/Tf2/Time-Travel-With-Tf2-Py.html)
        * [ Traveling in time (C++) ](../Intermediate/Tf2/Time-Travel-With-Tf2-Cpp.html)
        * [ Debugging ](../Intermediate/Tf2/Debugging-Tf2-Problems.html)
        * [ Quaternion fundamentals ](../Intermediate/Tf2/Quaternion-Fundamentals.html)
        * [ Using stamped datatypes with ` tf2_ros::MessageFilter  ` ](../Intermediate/Tf2/Using-Stamped-Datatypes-With-Tf2-Ros-MessageFilter.html)
      * [ Testing ](../Intermediate/Testing/Testing-Main.html)
        * [ Running Tests in ROS 2 from the Command Line ](../Intermediate/Testing/CLI.html)
        * [ Writing Basic Tests with C++ with GTest ](../Intermediate/Testing/Cpp.html)
        * [ Writing Basic Tests with Python ](../Intermediate/Testing/Python.html)
      * [ URDF ](../Intermediate/URDF/URDF-Main.html)
        * [ Building a visual robot model from scratch ](../Intermediate/URDF/Building-a-Visual-Robot-Model-with-URDF-from-Scratch.html)
        * [ Building a movable robot model ](../Intermediate/URDF/Building-a-Movable-Robot-Model-with-URDF.html)
        * [ Adding physical and collision properties ](../Intermediate/URDF/Adding-Physical-and-Collision-Properties-to-a-URDF-Model.html)
        * [ Using Xacro to clean up your code ](../Intermediate/URDF/Using-Xacro-to-Clean-Up-a-URDF-File.html)
        * [ Using URDF with ` robot_state_publisher  ` ](../Intermediate/URDF/Using-URDF-with-Robot-State-Publisher.html)
    * [ Advanced ](../Advanced.html)
      * [ Enabling topic statistics (C++) ](../Advanced/Topic-Statistics-Tutorial/Topic-Statistics-Tutorial.html)
      * [ Using Fast DDS Discovery Server as discovery protocol [community-contributed] ](../Advanced/Discovery-Server/Discovery-Server.html)
      * [ Implementing a custom memory allocator ](../Advanced/Allocator-Template-Tutorial.html)
      * [ Recording a bag from a node (C++) ](../Advanced/Recording-A-Bag-From-Your-Own-Node-CPP.html)
      * [ Simulators ](../Advanced/Simulators/Simulation-Main.html)
        * [ Webots ](../Advanced/Simulators/Webots/Simulation-Webots.html)
          * [ Installation (Ubuntu) ](../Advanced/Simulators/Webots/Installation-Ubuntu.html)
          * [ Installation (Windows) ](../Advanced/Simulators/Webots/Installation-Windows.html)
          * [ Installation (macOS) ](../Advanced/Simulators/Webots/Installation-MacOS.html)
          * [ Setting up a robot simulation (Basic) ](../Advanced/Simulators/Webots/Setting-Up-Simulation-Webots-Basic.html)
          * [ Setting up a robot simulation (Advanced) ](../Advanced/Simulators/Webots/Setting-Up-Simulation-Webots-Advanced.html)
        * [ Ignition ](../Advanced/Simulators/Ignition/Simulation-Ignition.html)
          * [ Setting up a robot simulation (Ignition Gazebo) ](../Advanced/Simulators/Ignition/Ignition.html)


Enter ` Ctrl+C  ` in the server terminal to stop the node from spinning.


     [in]  |  clock_type  |  the type identifying the time source to provide
---|---|---
[in]  |  clock  |  the handle to the clock which is being initialized
[in]  |  allocator  |  The allocator to use for allocations

Returns


My advice is to use a subscriber because, as I mentioned earlier, there are
some quirks with the wait-for-message implementation in ROS2.


The first two ` #include  ` statements are your package dependencies.


If you chose ` 2  ` and ` 3  ` , for example, the client would receive a
response like this:


    source install/setup.bash

    . install/setup.bash

    call install/setup.bat


Similar to the service node, the following lines of code create the node and
then create the client for that node:


[ rcl_ret_t ](types_8h.html#af66ec2e20118b821dbf3f9b0067e8796)
rcl_steady_clock_fini  |  (  |  [ rcl_clock_t ](structrcl__clock__t.html) *  |
_clock_ |  )  |
---|---|---|---|---|---

Finalize a clock as a ` RCL_STEADY_TIME ` time source.


/* ServiceClientExample() //{ */


* Summary


` #include " [ rcl/allocator.h ](allocator_8h_source.html) " `
` #include " [ rcl/macros.h ](macros_8h_source.html) " `
` #include " [ rcl/types.h ](types_8h_source.html) " `
` #include " [ rcl/visibility_control.h ](visibility__control_8h_source.html)
" `
` #include " [ rcutils/time.h
](http://docs.ros2.org/ardent/api/rcutils/time_8h.html) " `


Inside the ` ros2_ws/src/cpp_srvcli/src  ` directory, create a new file called
` add_two_ints_client.cpp  ` and paste the following code within:


#  Writing a simple service and client (C++)  ï


[ bayodesegun  ](https://get-help.theconstruct.ai/u/bayodesegun) June 29,
2023, 8:21am  5


    void setbool_callback(rclcpp::Client<std_srvs::srv::SetBool>::SharedFuture future);
    void timer_callback();
  };


**You're reading the documentation for a version of ROS 2 that has reached its
EOL (end-of-life), and is no longer officially supported. If you want up-to-
date information, please have a look at[ Iron
](../../../iron/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-
Service-And-Client.html) . **


* Background


This will allocate all necessary internal structures, and initialize
variables. It is specifically setting up a system time source.


        }
        RCLCPP_INFO(this->get_logger(), "message found");
        /*RCLCPP_INFO(this->get_logger(), "starting to wait for message");
        while (!scan_found) {
          scan_found =
              rclcpp::wait_for_message(scan_message, this->shared_from_this(),
                                       "/scan", std::chrono::seconds(1));
          //RCLCPP_INFO(this->get_logger(), "still waiting for message");
        }
        RCLCPP_INFO(this->get_logger(), "scan_found = %d", scan_found);
        this->laser_left = scan_message.ranges[90];
        this->laser_right = scan_message.ranges[270];
        this->laser_forward = scan_message.ranges[0];
        this->laser_backward = scan_message.ranges[180];
        */

        std::vector<float> laser_values = {this->laser_left, this->laser_right,
                                           this->laser_forward,
                                           this->laser_backward};

        int min_index = find_min_index(laser_values);
        RCLCPP_INFO(this->get_logger(), "min value is at index %d", min_index);
        switch (min_index) {
        case 0:
          RCLCPP_INFO(this->get_logger(), "wall on the left");
          twist_msg.angular.z = 0.2;
          break;
        case 1:
          RCLCPP_INFO(this->get_logger(), "wall on the right");
          if (laser_right < 0.3) {
            RCLCPP_INFO(this->get_logger(), "already in position, end of service");
            response->wallfound = true;
            return;
          }
          twist_msg.angular.z = -0.2;
          break;
        case 2:
          RCLCPP_INFO(this->get_logger(), "wall in front");
          twist_msg.linear.x = 0.05;
          break;


     [in]  |  clock  |  the handle to the clock which is being initialized
---|---|---

Returns


     ` RCL_RET_OK ` if the time source was successfully finalized, or
     ` RCL_RET_INVALID_ARGUMENT ` if any arguments are invalid, or
     ` RCL_RET_ERROR ` an unspecified error occur.


I want to make a service node that, when called, reads one time a scan topic
and does something depending on what was read. I tries to read the scan during
1sec and restarts trying.


This will populate the is_enabled object to indicate if the time overide is
enabled. If it is enabled, the set value will be returned. Otherwise this time
source will return the equivalent to system time abstraction.


  Implementation

The ` SystemTime ` , ` SteadyTime ` , and ` ROSTime ` API’s will be provided
by each client library in an idiomatic way, but they may share a common
implementation, e.g. provided by ` rcl ` . However, if a client library
chooses to not use the shared implementation then it must implement the
functionality itself.

` SteadyTime ` will be typed differently than the interchangable ` SystemTime
` and ` ROSTime ` . This is because SystemTime and ROSTime have a common base
class with runtime checks that they are valid to compare against each other.
However SteadyTime is never comparable to SystemTime or ROSTime so it would
actually have a separate implementation of the same API. Thus you could get
protection from misusing them at compile time (in compiled languages) instead
of only catching it at runtime.


##  ◆  RCL_US_TO_NS


##  Next steps  ï


##  ◆  rcl_time_point_value_t


true if the source is believed to be valid, otherwise return false.


This will deallocate all necessary internal structures, and clean up any
variables. It can be combined with any of the init functions.


[ howto ](https://get-help.theconstruct.ai/tag/howto) , [ ros2 ](https://get-
help.theconstruct.ai/tag/ros2)


  Default Time Source

To implement the time abstraction the following approach will be used.

The time abstraction can be published by one source on the ` /clock ` topic.
The topic will contain the most up to date time for the ROS system. If a
publisher exists for the topic, it will override the system time when using
the ROS time abstraction. If ` /clock ` is being published, calls to the ROS
time abstraction will return the latest time received from the ` /clock `
topic. If time has not been set it will return zero if nothing has been
received. A time value of zero should be considered an error meaning that time
is uninitialized.

If the time on the clock jumps backwards, a callback handler will be invoked
and be required to complete before any calls to the ROS time abstraction
report the new time. Calls that come in before that must block. The developer
has the opportunity to register callbacks with the handler to clear any state
from their system if necessary before time will be in the past.

The frequency of publishing the ` /clock ` as well as the granularity are not
specified as they are application specific.


##  ◆  rcl_system_clock_fini()


[ bayodesegun  ](https://get-help.theconstruct.ai/u/bayodesegun) June 26,
2023, 8:55am  2


##  ◆  rcl_clock_init()


##  ◆  RCL_NS_TO_S


Parameters


rosdep only runs on Linux, so you can skip ahead to next step.


    RCLCPP_INFO(get_logger(), "[ServiceClientExample]: initialized");
  }


ros2 run cpp_srvcli client 2 3


  Real Time vs real-time computing

In this article the term ‘real time’ is used to express the true rate of
progression of time. This is not connected to ‘real-time’ computing with
deterministic deadlines.


* Prerequisites


typedef [ rcutils_duration_value_t
](http://docs.ros2.org/ardent/api/rcutils/time_8h.html#a7fd03e84bd0de8c6e189bf2a21cf3946)
[ rcl_duration_value_t ](time_8h.html#acf6c7e80500a4ed249168d1d5866f09a)
---

A duration of time, measured in nanoseconds.


[ ROS 2 Documentation: Foxy ![Logo](../../_static/foxy-small.png)
](../../index.html)


rcl  master


[ Previous ](Writing-A-Simple-Py-Publisher-And-Subscriber.html "Writing a
simple publisher and subscriber \(Python\)") [ Next  ](Writing-A-Simple-Py-
Service-And-Client.html "Writing a simple service and client \(Python\)")


In previous tutorials, you learned how to [ create a workspace  ](Creating-A-
Workspace/Creating-A-Workspace.html) and [ create a package  ](Creating-Your-
First-ROS2-Package.html) .


     [in]  |  start  |  The time point for the start of the duration.
---|---|---
[in]  |  finish  |  The time point for the end of the duration.
[out]  |  delta  |  The duration between the start and finish.

Returns


    // Improvement axis:
    // start scan subscriber after wait for msg
    // and at the end of service callback sub.shutdown();

    #include "geometry_msgs/msg/twist.hpp"
    #include "rcl/event.h"
    #include "rclcpp/rclcpp.hpp"
    #include "rclcpp/subscription_base.hpp"
    #include "rclcpp/subscription_options.hpp"
    #include "rclcpp/utilities.hpp"
    #include "rclcpp/wait_for_message.hpp"
    #include "sensor_msgs/msg/detail/laser_scan__struct.hpp"
    #include "sensor_msgs/msg/laser_scan.hpp"
    #include "wall_following_pkg/srv/find_wall.hpp"

    #include <chrono>
    #include <functional>
    #include <memory>

    using FindWall = wall_following_pkg::srv::FindWall;
    using std::placeholders::_1;
    using std::placeholders::_2;
    using namespace std::chrono_literals;

    const bool SIMULATION = true;

    class ServerNode : public rclcpp::Node {
    public:
      ServerNode() : Node("find_wall_server") {
        RCLCPP_INFO(this->get_logger(), "Robot simulated = %d", SIMULATION);

        callback_group_1_ = this->create_callback_group(
            rclcpp::CallbackGroupType::MutuallyExclusive);
        callback_group_2_ = this->create_callback_group(
            rclcpp::CallbackGroupType::MutuallyExclusive);

        srv_ = create_service<FindWall>(
            "find_wall", std::bind(&ServerNode::find_wall_callback, this, _1, _2),


     [ Iron (latest) ](../../../iron/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Service-And-Client.html)
     [ Humble ](../../../humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Service-And-Client.html)
     [ Galactic (EOL) ](../../../galactic/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Service-And-Client.html)
     [ Foxy (EOL) ](Writing-A-Simple-Cpp-Service-And-Client.html)
     [ Eloquent (EOL) ](../../../eloquent/index.html)
     [ Dashing (EOL) ](../../../dashing/index.html)
     [ Crystal (EOL) ](../../../crystal/index.html)


Hello there,


##  ◆  rcl_enable_ros_time_override()


rosdep install -i --from-path src --rosdistro foxy -y


Messages you get from a subscriber are as real as what you get from wait-for-
message, even better (because it’s real-time). You can revise your logic such
that the robot does not move until you get the first message from the
subscriber. Indeed, for real-time applications, the logic for moving the robot
should be based on the subscriber callback.


Finalize the clock as a ` RCL_SYSTEM_TIME ` time source.


typedef struct [ rcl_duration_t ](structrcl__duration__t.html) [
rcl_duration_t ](structrcl__duration__t.html)
---

A duration of time, measured in nanoseconds and its source.


##  ◆  rcl_time_point_t


Contents


    void add(const std::shared_ptr<example_interfaces::srv::AddTwoInts::Request> request,
             std::shared_ptr<example_interfaces::srv::AddTwoInts::Response>      response)
    {
        response->sum = request->a + request->b;
        RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Incoming request\na: %ld" " b: %ld",
            request->a, request->b);
        RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "sending back response: [%ld]", (long int)response->sum);
    }


##  ◆  rcl_duration_t