      void send_goal()
      {
        using namespace std::placeholders;

        this->timer_->cancel();

        if (!this->client_ptr_->wait_for_action_server()) {
          RCLCPP_ERROR(this->get_logger(), "Action server not available after waiting");
          rclcpp::shutdown();
        }

        auto goal_msg = Fibonacci::Goal();
        goal_msg.order = 10;

        RCLCPP_INFO(this->get_logger(), "Sending goal");

        auto send_goal_options = rclcpp_action::Client<Fibonacci>::SendGoalOptions();
        send_goal_options.goal_response_callback = [this](const GoalHandleFibonacci::SharedPtr & goal_handle)
        {
          if (!goal_handle) {
            RCLCPP_ERROR(this->get_logger(), "Goal was rejected by server");
          } else {
            RCLCPP_INFO(this->get_logger(), "Goal accepted by server, waiting for result");
          }
        };

        send_goal_options.feedback_callback = [this](
          GoalHandleFibonacci::SharedPtr,
          const std::shared_ptr<const Fibonacci::Feedback> feedback)
        {
          std::stringstream ss;
          ss << "Next number in sequence received: ";
          for (auto number : feedback->partial_sequence) {
            ss << number << " ";
          }
          RCLCPP_INFO(this->get_logger(), ss.str().c_str());
        };

        send_goal_options.result_callback = [this](const GoalHandleFibonacci::WrappedResult & result)
        {


the sub-namespace string, not including the node's original namespace


In our [ previous ROS 2 basics tutorial ](/blog/the-building-blocks-of-ros2) ,
we covered how ROS nodes communicate with each other by publishing and
subscribing to message streams on topics.


The "prefix" argument is used to list the parameters which are prefixed with
that prefix, see also [ list_parameters()
](classrclcpp_1_1Node.html#a37aa95886a706c174db77c2b160f6d7d "Return a list of
parameters with any of the given prefixes, up to the given depth.") .


|  virtual [ RCLCPP_ACTION_PUBLIC
](visibility__control_8hpp.html#a736fe60d4de4417a213ed34ba1926048) [ GoalUUID
](namespacerclcpp__action.html#a67daf44a45003173e42ccc612fcb052b)
rclcpp_action::ServerBase::get_goal_id_from_goal_request  |  (  |  void *  |
_message_ |  )  |
---|---|---|---|---|---
protected  pure virtual

Given a goal request message, return the UUID contained within.


[ Client ](classrclcpp_1_1Client.html) <ServiceT>::SharedPtr
rclcpp::Node::create_client  |  (  |  const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) & |
_service_name_ ,
---|---|---|---
|  |  const [ rmw_qos_profile_t
](http://docs.ros2.org/foxy/api/rmw/structrmw__qos__profile__t.html) & |
_qos_profile_ ,
|  |  rclcpp::CallbackGroup::SharedPtr  |  _group_
|  )  |  |

* * *


**[ Todo: ](todo.html#_todo000001) **


pub = node->create_publisher<MsgT>(  "chatter"  , 10);  // implicitly KeepLast


node->get_sub_namespace();  // -> ""


|  rclcpp::Node::Node  |  (  |  const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) & |  _node_name_
,
---|---|---|---
|  |  const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) & |  _namespace__
,
|  |  const [ NodeOptions ](classrclcpp_1_1NodeOptions.html) & |  _options_ =
` [ NodeOptions ](classrclcpp_1_1NodeOptions.html) () `
|  )  |  |
explicit

Create a new node with the specified name.


##  ◆  call_handle_cancel_callback()


     [ rclcpp::exceptions::ParameterNotDeclaredException ](classrclcpp_1_1exceptions_1_1ParameterNotDeclaredException.html "Thrown if parameter is not declared, e.g. either set or get was called without first declaring.") |  if any of the parameters have not been declared and undeclared parameters are not allowed.
---|---
[ std::runtime_error
](http://en.cppreference.com/w/cpp/error/runtime_error.html) |  if the number
of described parameters is more than one

##  ◆  get_parameter_types()


See also


Next, let’s create a request that the client can send to the server using the
` Trigger.srv ` service:


  2.1 Examine the code  ï

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

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.

    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);
    }

The ` main  ` function accomplishes the following, line by line:

  * Initializes ROS 2 C++ client library:

        rclcpp::init(argc, argv);

  * Creates a node named ` add_two_ints_server  ` :

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

  * 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);

  * Prints a log message when itâs ready:

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


[ Get started for free ](https://app.foxglove.dev/signup)


Parameters


template<typename DurationRepT , typename DurationT , typename CallbackT >


##  ◆  now()


     [ rclcpp::exceptions::ParameterAlreadyDeclaredException ](classrclcpp_1_1exceptions_1_1ParameterAlreadyDeclaredException.html "Thrown if parameter is already declared.") |  if parameter has already been declared.
---|---
[ rclcpp::exceptions::InvalidParametersException
](classrclcpp_1_1exceptions_1_1InvalidParametersException.html "Thrown if
passed parameters are inconsistent or invalid.") |  if a parameter name is
invalid.
[ rclcpp::exceptions::InvalidParameterValueException
](classrclcpp_1_1exceptions_1_1InvalidParameterValueException.html "Thrown if
passed parameter value is invalid.") |  if initial value fails to be set.

##  ◆  declare_parameters()  [2/2]


rclcpp::Node::SharedPtr rclcpp::Node::create_sub_node  |  (  |  const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html) & |
_sub_namespace_ |  )  |
---|---|---|---|---|---

Create a sub-node, which will extend the namespace of all entities created
with it.


[ [ legend ](graph_legend.html) ]


[ rust ](https://discourse.ros.org/tag/rust)


template<typename MessageT , typename AllocatorT , typename PublisherT >


##  ◆  Node()  [1/3]


##  ◆  get_node_time_source_interface()


For example, all of these cases will work:


If you pass multiple [ rclcpp::Parameter ](classrclcpp_1_1Parameter.html
"Structure to store an arbitrary parameter with templated get/set methods.")
instances with the same name, then only the last one in the vector (forward
iteration) will be set.


template<typename MessageT , typename CallbackT , typename AllocatorT ,
typename CallbackMessageT , typename SubscriptionT , typename
MessageMemoryStrategyT >


If a parameter fails to be set due to any other reason, like being rejected by
the user's callback (basically any reason other than not having been declared
beforehand), then that is reflected in the corresponding SetParametersResult
in the vector returned by this function.


The documentation for this class was generated from the following file:


const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) &
rclcpp::Node::get_sub_namespace  |  (  |  |  )  |  const
---|---|---|---|---

Return the sub-namespace, if this is a sub-node, otherwise an empty string.


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


|  [ RCLCPP_ACTION_PUBLIC
](visibility__control_8hpp.html#a736fe60d4de4417a213ed34ba1926048)
rclcpp_action::ServerBase::ServerBase  |  (  |
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr  |  _node_base_ ,
---|---|---|---
|  |  rclcpp::node_interfaces::NodeClockInterface::SharedPtr  |  _node_clock_
,
|  |  rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr  |
_node_logging_ ,
|  |  const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) & |  _name_ ,
|  |  const rosidl_action_type_support_t *  |  _type_support_ ,
|  |  const [ rcl_action_server_options_t
](http://docs.ros2.org/foxy/api/rcl_action/structrcl__action__server__options__t.html)
& |  _options_
|  )  |  |
protected

##  Member Function Documentation


Parameters


     InvalidTopicNameError  |  if the given topic_name is invalid.
---|---
[ std::runtime_error
](http://en.cppreference.com/w/cpp/error/runtime_error.html) |  if internal
error happens.

##  ◆  get_subscriptions_info_by_topic()


template<typename ParameterT >


Like [ set_parameter()
](classrclcpp_1_1Node.html#a8c753036cd5cbdf0168ca3b39a193223 "Set a single
parameter.") this method will implicitly undeclare parameters with the type [
rclcpp::PARAMETER_NOT_SET
](namespacerclcpp.html#a1b307a4b7368b68f325812cd2aeb8784adefddb470d1054265245a0c5dbeccf4e)
.


[ std::map ](http://en.cppreference.com/w/cpp/container/map.html) < [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html) , [
std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) < [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html) > >
rclcpp::Node::get_service_names_and_types_by_node  |  (  |  const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html) & |
_node_name_ ,
---|---|---|---
|  |  const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) & |  _namespace__
|  )  |  |  const

Return the number of publishers that are advertised on a given topic.


auto  node = std::make_shared<rclcpp::Node>(  "my_node"  ,  "my_ns"  );


     handler  |  The callback handler to remove.
---|---

Exceptions


If no parameter_descriptor is given, then the default values from the message
definition will be used, e.g. read_only will be false.


Now that we have a server node, let's move on to the client node that will
request a response from it.


|  virtual [ RCLCPP_ACTION_PUBLIC
](visibility__control_8hpp.html#a736fe60d4de4417a213ed34ba1926048) [ GoalUUID
](namespacerclcpp__action.html#a67daf44a45003173e42ccc612fcb052b)
rclcpp_action::ServerBase::get_goal_id_from_result_request  |  (  |  void *  |
_message_ |  )  |
---|---|---|---|---|---
protected  pure virtual

Given a result request message, return the UUID contained within.


  Summary  ï

You created two nodes to request and respond to data over a service. You added
their dependencies and executables to the package configuration files so that
you could build and run them, and see a service/client system at work.


#  4 Build and run  ï

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

Linux  macOS  Windows

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

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

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

Navigate back to the root of your workspace, ` ros2_ws  ` , and build your new
package:

Linux  macOS  Windows

    colcon build --packages-select cpp_srvcli

    colcon build --packages-select cpp_srvcli

    colcon build --merge-install --packages-select cpp_srvcli

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

Linux  macOS  Windows


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


     [in]  |  names  |  The list of parameter names to describe.
---|---|---

Returns


But if you were to create a service instead, your server node wouldn't
broadcast any data before it is explicitly requested by a client node. Using a
service ensures that you do not miss crucial information due to inopportune
timing.


Furthermore, a sub-node may be used to create additional sub-node's, in which
case the sub-namespace passed to this function will further extend the sub-
namespace of the existing sub-node. See [ get_sub_namespace()
](classrclcpp_1_1Node.html#aa9ac5055f3f7a3537642482bd505d4bd "Return the sub-
namespace, if this is a sub-node, otherwise an empty string.") and [
get_effective_namespace()
](classrclcpp_1_1Node.html#afe4790bba38942b795d24b6ccb3e9c5a "Return the
effective namespace that is used when creating entities.") for examples.


##  ◆  get_topic_names_and_types()


Let's start with our ` main ` function:


The resulting list of parameter names are used to get the values of the
parameters.


Parameters


##  ◆  get_parameter()  [3/3]


This namespace is the "node's" namespace, and therefore is not affected by any
sub-namespace's that may affect entities created with this instance. Use [
get_effective_namespace()
](classrclcpp_1_1Node.html#afe4790bba38942b795d24b6ccb3e9c5a "Return the
effective namespace that is used when creating entities.") to get the full
namespace used by entities.


bool rclcpp::Node::has_parameter  |  (  |  const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) & |  _name_ |  )
|  const
---|---|---|---|---|---

Return true if a given parameter is declared.


  * [ API ](/docs/data-platform/api/introduction)
  * [ Status ](https://foxglovestatus.com/)
  * [ GitHub ](https://github.com/foxglove)


auto  sub_node3 = node->create_sub_node(  "foo"  );


auto  sub_node2 = sub_node1->create_sub_node(  "b"  );


fully-qualified name of the node.


  Summary  ï

In this tutorial, you put together a C++ action server and action client line
by line, and configured them to exchange goals, feedback, and results.


##  Protected Member Functions

---
|  [ Node ](classrclcpp_1_1Node.html#a52e594aa6a2790c0190739d862f68270) (const
[ Node ](classrclcpp_1_1Node.html) &other, const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) &sub_namespace)
|  Construct a sub-node, which will extend the namespace of all entities
created with it. [ More...
](classrclcpp_1_1Node.html#a52e594aa6a2790c0190739d862f68270)

##  Detailed Description


This method will result in any callback registered with
add_on_set_parameters_callback to be called, once for each parameter. If the
callback prevents the parameter from being set, then, as mentioned before, it
will be reflected in the corresponding SetParametersResult that is returned,
but no exception will be thrown.


  Prerequisites  ï

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


##  ◆  get_number_of_ready_services()


const [ rclcpp::ParameterValue ](classrclcpp_1_1ParameterValue.html) &
rclcpp::Node::declare_parameter  |  (  |  const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) & |  _name_ ,
---|---|---|---
|  |  const [ rclcpp::ParameterValue ](classrclcpp_1_1ParameterValue.html) & |
_default_value_ = ` [ rclcpp::ParameterValue
](classrclcpp_1_1ParameterValue.html) () ` ,
|  |  const rcl_interfaces::msg::ParameterDescriptor & |
_parameter_descriptor_ = ` rcl_interfaces::msg::ParameterDescriptor() ` ,
|  |  bool  |  _ignore_override_ = ` false `
|  )  |  |

Declare and initialize a parameter, return the effective value.


  {
    using FeedbackMessage = typename ActionT::Impl::FeedbackMessage;
    return std::shared_ptr<void>(new FeedbackMessage());
  }
  /// \internal
  void
  handle_feedback_message(std::shared_ptr<void> message) override
  {
    std::lock_guard<std::mutex> guard(goal_handles_mutex_);
    using FeedbackMessage = typename ActionT::Impl::FeedbackMessage;
    typename FeedbackMessage::SharedPtr feedback_message =
      std::static_pointer_cast<FeedbackMessage>(message);
    const GoalUUID & goal_id = feedback_message->goal_id.uuid;
    if (goal_handles_.count(goal_id) == 0) {
      RCLCPP_DEBUG(
        this->get_logger(),
        "Received feedback for unknown goal. Ignoring...");
      return;
    }
    typename GoalHandle::SharedPtr goal_handle = goal_handles_[goal_id].lock();
    // Forget about the goal if there are no more user references
    if (!goal_handle) {
      RCLCPP_DEBUG(
        this->get_logger(),
        "Dropping weak reference to goal handle during feedback callback");
      goal_handles_.erase(goal_id);
      return;
    }
    auto feedback = std::make_shared<Feedback>();
    *feedback = feedback_message->feedback;
    goal_handle->call_feedback_callback(goal_handle, feedback);
  }
  /// \internal
  std::shared_ptr<void>
  create_status_message() const override
  {
    using GoalStatusMessage = typename ActionT::Impl::GoalStatusMessage;
    return std::shared_ptr<void>(new GoalStatusMessage());
  }
  /// \internal


Exceptions


sub_node3->get_sub_namespace();  // -> "foo"


     [in]  |  name  |  The name of the parameter to get.
---|---|---
[out]  |  parameter  |  The output where the value of the parameter should be
assigned.
[in]  |  alternative_value  |  Value to be stored in output if the parameter
was not set.

Returns


for  (  const  auto  & parameter : parameters) {


    $ cd ros2_ws/
    $ colcon build


if (goal_handle->is_invalidated()) {
      // This case can happen if there was a failure to send the result request
      // during the goal response callback
      throw goal_handle->invalidate_exception_;
    }
    if (result_callback) {
      // This will override any previously registered callback
      goal_handle->set_result_callback(result_callback);
    }
    this->make_result_aware(goal_handle);
    return goal_handle->async_get_result();
  }
  /// Asynchronously request a goal be canceled.
  /**
   * \throws exceptions::UnknownGoalHandleError If the goal is unknown or already reached a
   *   terminal state.
   * \param[in] goal_handle The goal handle requesting to be canceled.
   * \param[in] cancel_callback Optional callback that is called when the response is received.
   *   The callback takes one parameter: a shared pointer to the CancelResponse message.
   * \return A future to a CancelResponse message that is set when the request has been
   * acknowledged by an action server.
   * See
   *
   * action_msgs/CancelGoal.srv.
   */
  std::shared_future<typename CancelResponse::SharedPtr>
  async_cancel_goal(
    typename GoalHandle::SharedPtr goal_handle,
    CancelCallback cancel_callback = nullptr)
  {
    std::lock_guard<std::mutex> lock(goal_handles_mutex_);
    if (goal_handles_.count(goal_handle->get_goal_id()) == 0) {
      throw exceptions::UnknownGoalHandleError();
    }
    auto cancel_request = std::make_shared<CancelRequest>();
    // cancel_request->goal_info.goal_id = goal_handle->get_goal_id();
    cancel_request->goal_info.goal_id.uuid = goal_handle->get_goal_id();
    return async_cancel(cancel_request, cancel_callback);
  }
  /// Asynchronously request for all goals to be canceled.


return  result;


$ ros2 run srv_client_checks diagnostics_node


Hello, I’m trying to make a generic C++ application for controlling ROS
robots. The idea is to allow design of GUIs in a higher-level language (QML)
without requiring modifying the C++ when integrating new ROS systems.


This method, if successful, will result in any callback registered with
add_on_set_parameters_callback to be called, once for each parameter. If that
callback prevents the initial value for any parameter from being set then [
rclcpp::exceptions::InvalidParameterValueException
](classrclcpp_1_1exceptions_1_1InvalidParameterValueException.html "Thrown if
passed parameter value is invalid.") is thrown.


      * [ Quality guide: ensuring code quality ](../../The-ROS2-Project/Contributing/Quality-Guide.html)
      * [ ROS Build Farms ](../../The-ROS2-Project/Contributing/Build-Farms.html)
      * [ Windows Tips and Tricks ](../../The-ROS2-Project/Contributing/Windows-Tips-and-Tricks.html)
      * [ 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)
      * [ About Working Groups ](../../The-ROS2-Project/Governance/Working-Groups.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)
    * [ Metrics ](../../The-ROS2-Project/Metrics.html)
  * [ API Documentation ](../../API-Docs.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)

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

  * [ ](../../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/rolling/source/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Service-And-Client.rst)

* * *

**You're reading the documentation for a development version. For the latest
released version, please have a look at[ Iron
](../../../iron/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-
Service-And-Client.html) . **

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

**Goal:** Create and run service and client nodes using C++.


[ rclcpp::Parameter ](classrclcpp_1_1Parameter.html)
rclcpp::Node::get_parameter  |  (  |  const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) & |  _name_ |  )
|  const
---|---|---|---|---|---

Return the parameter by the given name.


This version will take a map where the value is a pair, with the default
parameter value as the first item and a parameter descriptor as the second.


  std::map<GoalUUID, typename GoalHandle::WeakPtr> goal_handles_;
  std::mutex goal_handles_mutex_;
};
}  // namespace rclcpp_action
#endif  // RCLCPP_ACTION__CLIENT_HPP_


Shared pointer to the created service.


rcl_interfaces::msg::SetParametersResult
rclcpp::Node::set_parameters_atomically  |  (  |  const [ std::vector
](http://en.cppreference.com/w/cpp/container/vector.html) < [
rclcpp::Parameter ](classrclcpp_1_1Parameter.html) > & |  _parameters_ |  )  |
---|---|---|---|---|---

Set one or more parameters, all at once.


We hope you enjoyed this tutorial and now have a better understand of how you
can use ROS 2 services in your own robotics project. Continue learning with
our ROS [ tutorials ](/tutorials) and other articles on our [ blog ](/blog) .


        auto handle_cancel = [this](
          const std::shared_ptr<GoalHandleFibonacci> goal_handle)
        {
          RCLCPP_INFO(this->get_logger(), "Received request to cancel goal");
          (void)goal_handle;
          return rclcpp_action::CancelResponse::ACCEPT;
        };

        auto handle_accepted = [this](
          const std::shared_ptr<GoalHandleFibonacci> goal_handle)
        {
          // this needs to return quickly to avoid blocking the executor,
          // so we declare a lambda function to be called inside a new thread
          auto execute_in_thread = [this, goal_handle](){return this->execute(goal_handle);};
          std::thread{execute_in_thread}.detach();
        };

        this->action_server_ = rclcpp_action::create_server<Fibonacci>(
          this,
          "fibonacci",
          handle_goal,
          handle_cancel,
          handle_accepted);
      }

    private:
      rclcpp_action::Server<Fibonacci>::SharedPtr action_server_;

      void execute(const std::shared_ptr<GoalHandleFibonacci> goal_handle) {
        RCLCPP_INFO(this->get_logger(), "Executing goal");
        rclcpp::Rate loop_rate(1);
        const auto goal = goal_handle->get_goal();
        auto feedback = std::make_shared<Fibonacci::Feedback>();
        auto & sequence = feedback->partial_sequence;
        sequence.push_back(0);
        sequence.push_back(1);
        auto result = std::make_shared<Fibonacci::Result>();

        for (int i = 1; (i < goal->order) && rclcpp::ok(); ++i) {


Parameters


fibonacci_action_client  ` in the ` custom_action_cpp  ` package.


ROS


  * [ Foxglove ](/product)
  * [ MCAP ](/mcap)


This method, if successful, will result in any callback registered with
add_on_set_parameters_callback to be called. If that callback prevents the
initial value for the parameter from being set then [
rclcpp::exceptions::InvalidParameterValueException
](classrclcpp_1_1exceptions_1_1InvalidParameterValueException.html "Thrown if
passed parameter value is invalid.") is thrown.


##  ◆  wait_for_graph_change()


auto  sub_node1 = node->create_sub_node(  "a"  );


     [in]  |  topic_name  |  the topic_name on which to find the publishers.
---|---|---
[in]  |  no_mangle  |  if ` true ` , ` topic_name ` needs to be a valid
middleware topic name, otherwise it should be a valid ROS topic name. Defaults
to ` false ` .

Returns


rclcpp::CallbackGroup::SharedPtr rclcpp::Node::create_callback_group  |  (  |
[ rclcpp::CallbackGroupType
](namespacerclcpp.html#a0027d5804ef28f0b6fea8eea4195c44a) |  _group_type_ |  )
|
---|---|---|---|---|---

Create and return a callback group.


![Esther Weon](/images/blog/authors/estherweon.webp) Esther Weon  Esther Weon


Go to the ` src ` folder of your new package and create a file named `
motor_node.cpp ` :


my_callback(  const  [ std::vector<rclcpp::Parameter>
](http://en.cppreference.com/w/cpp/container/vector.html) & parameters)


The returned sub-namespace is either the accumulated sub-namespaces which were
given to one-to-many [ create_sub_node()
](classrclcpp_1_1Node.html#a1df8e4507d17a503630317432449d69d "Create a sub-
node, which will extend the namespace of all entities created with it.")
calls, or an empty string if this is an original node instance, i.e. not a
sub-node.


##  When should I use services?


fibonacci_action_server  ` in the ` custom_action_cpp  ` package.


![José L. Millán](/images/blog/authors/joselmillan.webp) José L. Millán  ·


rcl_interfaces::msg::SetParametersResult rclcpp::Node::set_parameter  |  (  |
const [ rclcpp::Parameter ](classrclcpp_1_1Parameter.html) & |  _parameter_ |
)  |
---|---|---|---|---|---

Set a single parameter.


bool rclcpp::Node::get_parameter  |  (  |  const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) & |  _name_ ,
---|---|---|---
|  |  [ rclcpp::Parameter ](classrclcpp_1_1Parameter.html) & |  _parameter_
|  )  |  |  const

Get the value of a parameter by the given name, and return true if it was set.


Some constraints like read_only are enforced before the callback is called.


**Tutorial level:** Beginner

**Time:** 20 minutes

Contents

  * Background

  * Prerequisites

  * Tasks

    * 1 Create a package

    * 2 Write the service node

    * 3 Write the client node

    * 4 Build and run

  * Summary

  * Next steps

  * Related content


|  virtual rclcpp::Node::~Node  |  (  |  |  )  |
---|---|---|---|---
virtual

##  ◆  Node()  [3/3]


See also


    $ cd ros2_ws/
    $ source install/setup.bash


          switch (result.code) {
            case rclcpp_action::ResultCode::SUCCEEDED:
              break;
            case rclcpp_action::ResultCode::ABORTED:
              RCLCPP_ERROR(this->get_logger(), "Goal was aborted");
              return;
            case rclcpp_action::ResultCode::CANCELED:
              RCLCPP_ERROR(this->get_logger(), "Goal was canceled");
              return;
            default:
              RCLCPP_ERROR(this->get_logger(), "Unknown result code");
              return;
          }
          std::stringstream ss;
          ss << "Result received: ";
          for (auto number : result.result->sequence) {
            ss << number << " ";
          }
          RCLCPP_INFO(this->get_logger(), ss.str().c_str());
          rclcpp::shutdown();
        };
        this->client_ptr_->async_send_goal(goal_msg, send_goal_options);
      }

    private:
      rclcpp_action::Client<Fibonacci>::SharedPtr client_ptr_;
      rclcpp::TimerBase::SharedPtr timer_;
    };  // class FibonacciActionClient

    }  // namespace custom_action_cpp

    RCLCPP_COMPONENTS_REGISTER_NODE(custom_action_cpp::FibonacciActionClient)

The first few lines include all of the headers we need to compile.

Next we create a class that is a derived class of ` rclcpp::Node  ` :


pub = node->create_publisher<MsgT>(  "chatter"  , QoS(10));  // implicitly
KeepLast


C++ ROS Action Client Library

---

  * [ rclcpp_action ](namespacerclcpp__action.html)
  * [ ServerBase ](classrclcpp__action_1_1ServerBase.html)


[ rclcpp::Client ](classrclcpp_1_1Client.html) <ServiceT>::SharedPtr
rclcpp::Node::create_client  |  (  |  const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) & |
_service_name_ ,
---|---|---|---
|  |  const [ rmw_qos_profile_t
](http://docs.ros2.org/foxy/api/rmw/structrmw__qos__profile__t.html) & |
_qos_profile_ = ` rmw_qos_profile_services_default ` ,
|  |  rclcpp::CallbackGroup::SharedPtr  |  _group_ = ` nullptr `
|  )  |  |

Create and return a [ Client ](classrclcpp_1_1Client.html) .


 *  - coverting between the C++ action type and generic types for `rclcpp_action::ClientBase`, and
 *  - calling user callbacks.
 */
template<typename ActionT>
class Client : public ClientBase
{
public:
  RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(Client<ActionT>)
  using Goal = typename ActionT::Goal;
  using Feedback = typename ActionT::Feedback;
  using GoalHandle = ClientGoalHandle<ActionT>;
  using WrappedResult = typename GoalHandle::WrappedResult;
  using GoalResponseCallback = std::function<void (typename GoalHandle::SharedPtr)>;
  using FeedbackCallback = typename GoalHandle::FeedbackCallback;
  using ResultCallback = typename GoalHandle::ResultCallback;
  using CancelRequest = typename ActionT::Impl::CancelGoalService::Request;
  using CancelResponse = typename ActionT::Impl::CancelGoalService::Response;
  using CancelCallback = std::function<void (typename CancelResponse::SharedPtr)>;
  /// Options for sending a goal.
  /**
   * This struct is used to pass parameters to the function `async_send_goal`.
   */
  struct SendGoalOptions
  {
    SendGoalOptions()
    : goal_response_callback(nullptr),
      feedback_callback(nullptr),
      result_callback(nullptr)
    {
    }
    /// Function called when the goal is accepted or rejected.
    /**
     * Takes a single argument that is a goal handle shared pointer.
     * If the goal is accepted, then the pointer points to a valid goal handle.
     * If the goal is rejected, then pointer has the value `nullptr`.
     */
    GoalResponseCallback goal_response_callback;
    /// Function called whenever feedback is received for the goal.
    FeedbackCallback feedback_callback;
    /// Function called when the result for the goal is received.


Parameters


[ std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) < [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html) >
rclcpp::Node::get_node_names  |  (  |  |  )  |  const
---|---|---|---|---

Get the fully-qualified names of all available nodes.


template<typename ServiceT >


rclcpp::node_interfaces::NodeBaseInterface::SharedPtr
rclcpp::Node::get_node_base_interface  |  (  |  |  )  |
---|---|---|---|---

Return the [ Node ](classrclcpp_1_1Node.html "Node is the single point of
entry for creating publishers and subscribers.") 's internal NodeBaseInterface
implementation.


     [in]  |  topic_name  |  The topic to subscribe on.
---|---|---
[in]  |  qos  |  [ QoS ](classrclcpp_1_1QoS.html "Encapsulation of Quality of
Service settings.") profile for Subcription.
[in]  |  callback  |  The user-defined callback function to receive a message
[in]  |  options  |  Additional options for the creation of the [ Subscription
](classrclcpp_1_1Subscription.html "Subscription implementation, templated on
the type of message this subscription receives.") .
[in]  |  msg_mem_strat  |  The message memory strategy to use for allocating
messages.

Returns


Next, run the server ` motor_node ` to execute the checks:


[ [ legend ](graph_legend.html) ]


##  ◆  get_goal_id_from_result_request()


     [in]  |  names  |  The names of the parameters to be retrieved.
---|---|---

Returns


|  virtual [ RCLCPP_ACTION_PUBLIC
](visibility__control_8hpp.html#a736fe60d4de4417a213ed34ba1926048) [ std::pair
](http://en.cppreference.com/w/cpp/utility/pair.html) < [ GoalResponse
](namespacerclcpp__action.html#ababbbebf29fec7c541687c724fc82ba7) , [
std::shared_ptr ](http://en.cppreference.com/w/cpp/memory/shared_ptr.html)
<void> > rclcpp_action::ServerBase::call_handle_goal_callback  |  (  |  [
GoalUUID ](namespacerclcpp__action.html#a67daf44a45003173e42ccc612fcb052b) & |
,
---|---|---|---
|  |  [ std::shared_ptr
](http://en.cppreference.com/w/cpp/memory/shared_ptr.html) < void > |
_request_
|  )  |  |
protected  pure virtual

Implemented in [ rclcpp_action::Server< ActionT >
](classrclcpp__action_1_1Server.html#aa8375168f664cf423ad8a23a233a1825) .


Like [ get_parameters()
](classrclcpp_1_1Node.html#a25890d01a2cd47ce99af887f556c529b "Return the
parameters by the given parameter names.") , this method may throw the [
rclcpp::exceptions::ParameterNotDeclaredException
](classrclcpp_1_1exceptions_1_1ParameterNotDeclaredException.html "Thrown if
parameter is not declared, e.g. either set or get was called without first
declaring.") exception if the requested parameter has not been declared and
undeclared parameters are not allowed.


If ` ignore_override ` is ` true ` , the parameter override will be ignored.


* include/rclcpp_action/ [ server.hpp ](server_8hpp_source.html)


Unlike topics, which follow a publish-subscribe model to send each other
information, services follow a request-response model.


   * \param[in] introspection_state the state to set introspection to
   */
  void
  configure_introspection(
    Clock::SharedPtr clock, const QoS & qos_service_event_pub,
    rcl_service_introspection_state_t introspection_state)
  {
    rcl_publisher_options_t pub_opts = rcl_publisher_get_default_options();
    pub_opts.qos = qos_service_event_pub.get_rmw_qos_profile();
    rcl_ret_t ret = rcl_client_configure_service_introspection(
      client_handle_.get(),
      node_handle_.get(),
      clock->get_clock_handle(),
      srv_type_support_handle_,
      pub_opts,
      introspection_state);
    if (RCL_RET_OK != ret) {
      rclcpp::exceptions::throw_from_rcl_error(ret, "failed to configure client introspection");
    }
  }
protected:
  using CallbackTypeValueVariant = std::tuple<CallbackType, SharedFuture, Promise>;
  using CallbackWithRequestTypeValueVariant = std::tuple<
    CallbackWithRequestType, SharedRequest, SharedFutureWithRequest, PromiseWithRequest>;
  using CallbackInfoVariant = std::variant<
    std::promise<SharedResponse>,
    CallbackTypeValueVariant,
    CallbackWithRequestTypeValueVariant>;
  int64_t
  async_send_request_impl(const Request & request, CallbackInfoVariant value)
  {
    int64_t sequence_number;
    std::lock_guard<std::mutex> lock(pending_requests_mutex_);
    rcl_ret_t ret = rcl_send_request(get_client_handle().get(), &request, &sequence_number);
    if (RCL_RET_OK != ret) {
      rclcpp::exceptions::throw_from_rcl_error(ret, "failed to send request");
    }
    pending_requests_.try_emplace(
      sequence_number,
      std::make_pair(std::chrono::system_clock::now(), std::move(value)));


Implemented in [ rclcpp_action::Server< ActionT >
](classrclcpp__action_1_1Server.html#aea1d871fd85088d4574f8b1416eb695d) .


     [in]  |  service_name  |  The topic to service on.
---|---|---
[in]  |  qos_profile  |  [ rmw_qos_profile_t
](http://docs.ros2.org/foxy/api/rmw/structrmw__qos__profile__t.html) Quality
of service profile for client.
[in]  |  group  |  Callback group to call the service.

Returns


A list of parameter types, one for each parameter given.


[ Client Libraries  ](/c/client-libraries/22)


Published  August 12, 2022


     [in]  |  parameters  |  The vector of parameters to be set.
---|---|---

Returns


Returns


##  ◆  create_wall_timer()


    // Include the rclcpp library and trigger service type
    #include "rclcpp/rclcpp.hpp"
    #include "std_srvs/srv/trigger.hpp"


bool rclcpp::Node::get_parameter_or  |  (  |  const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) & |  _name_ ,
---|---|---|---
|  |  ParameterT & |  _parameter_ ,
|  |  const ParameterT & |  _alternative_value_
|  )  |  |  const

Get the parameter value, or the "alternative_value" if not set, and assign it
to "parameter".


template<typename MessageT , typename CallbackT , typename AllocatorT =
std::allocator<void>, typename CallbackMessageT = typename
rclcpp::subscription_traits::has_message_type<CallbackT>::type, typename
SubscriptionT = rclcpp::Subscription<CallbackMessageT, AllocatorT>, typename
MessageMemoryStrategyT =
rclcpp::message_memory_strategy::MessageMemoryStrategy< CallbackMessageT,
AllocatorT >>
[ std::shared_ptr ](http://en.cppreference.com/w/cpp/memory/shared_ptr.html) <
SubscriptionT > |  [ create_subscription
](classrclcpp_1_1Node.html#a82f97ad29e3d54c91f6ef3265a8636d1) (const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&topic_name, const [ rclcpp::QoS ](classrclcpp_1_1QoS.html) &qos, CallbackT
&&callback, const [ SubscriptionOptionsWithAllocator
](structrclcpp_1_1SubscriptionOptionsWithAllocator.html) < AllocatorT >
&options= [ SubscriptionOptionsWithAllocator
](structrclcpp_1_1SubscriptionOptionsWithAllocator.html) < AllocatorT >(),
typename MessageMemoryStrategyT::SharedPtr
msg_mem_strat=(MessageMemoryStrategyT::create_default()))
|  Create and return a [ Subscription ](classrclcpp_1_1Subscription.html
"Subscription implementation, templated on the type of message this
subscription receives.") . [ More...
](classrclcpp_1_1Node.html#a82f97ad29e3d54c91f6ef3265a8636d1)

template<typename DurationRepT = int64_t, typename DurationT = std::milli,
typename CallbackT >
[ rclcpp::WallTimer ](classrclcpp_1_1WallTimer.html) < CallbackT >::SharedPtr
|  [ create_wall_timer
](classrclcpp_1_1Node.html#ad27d1f6d1c5ff633b1b42ab6f77479c5) ( [
std::chrono::duration ](http://en.cppreference.com/w/cpp/chrono/duration.html)
< DurationRepT, DurationT > period, CallbackT callback,
rclcpp::CallbackGroup::SharedPtr group=nullptr)
|  Create a timer. [ More...
](classrclcpp_1_1Node.html#ad27d1f6d1c5ff633b1b42ab6f77479c5)

template<typename ServiceT >
[ rclcpp::Client ](classrclcpp_1_1Client.html) < ServiceT >::SharedPtr  |  [
create_client ](classrclcpp_1_1Node.html#aed42f345ae1de3a1979d5a8076127199)
(const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) &service_name,


When the ` no_mangle ` parameter is ` true ` , the provided ` topic_name `
should be a valid topic name for the middleware (useful when combining ROS
with native middleware (e.g. DDS) apps). When the ` no_mangle ` parameter is `
false ` , the provided ` topic_name ` should follow ROS topic name
conventions.


###  Related Topics


The returned namespace is a concatenation of the node namespace and the
accumulated sub-namespaces, which is used as the namespace when creating
entities which have relative names.


See also


![](https://sea2.discourse-
cdn.com/business7/user_avatar/discourse.ros.org/wjwwood/48/13715_2.png)
wjwwood:


     InvalidNamespaceError  |  if the namespace is invalid
---|---

##  ◆  Node()  [2/3]


sub_node3->get_effective_namespace();  // -> "/my_ns/foo"


data management


[ std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) <
rcl_interfaces::msg::ParameterDescriptor > |  [ describe_parameters
](classrclcpp_1_1Node.html#adbfb47c0983e14482c39159b274f6308) (const [
std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) < [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html) >
&names) const
|  Return a vector of parameter descriptors, one for each of the given names.
[ More... ](classrclcpp_1_1Node.html#adbfb47c0983e14482c39159b274f6308)

[ std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) <
uint8_t > |  [ get_parameter_types
](classrclcpp_1_1Node.html#af9855812e7873bd35b28afa420d4242b) (const [
std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) < [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html) >
&names) const
|  Return a vector of parameter types, one for each of the given names. [
More... ](classrclcpp_1_1Node.html#af9855812e7873bd35b28afa420d4242b)

rcl_interfaces::msg::ListParametersResult  |  [ list_parameters
](classrclcpp_1_1Node.html#a37aa95886a706c174db77c2b160f6d7d) (const [
std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) < [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html) >
&prefixes, uint64_t depth) const
|  Return a list of parameters with any of the given prefixes, up to the given
depth. [ More... ](classrclcpp_1_1Node.html#a37aa95886a706c174db77c2b160f6d7d)

[ RCUTILS_WARN_UNUSED
](http://docs.ros2.org/foxy/api/rcutils/macros_8h.html#a6be4031432c70fddf878bd574c8bccc4)
OnSetParametersCallbackHandle::SharedPtr  |  [ add_on_set_parameters_callback
](classrclcpp_1_1Node.html#a12d535bced9f26b65c0a450e6f40aff8) ( [
OnParametersSetCallbackType
](classrclcpp_1_1Node.html#ab403fecdb5ec2eb9f88e3eb7ae6f6d0c) callback)
|  Add a callback for when parameters are being set. [ More...
](classrclcpp_1_1Node.html#a12d535bced9f26b65c0a450e6f40aff8)

void  |  [ remove_on_set_parameters_callback
](classrclcpp_1_1Node.html#a15d4f7fa0ef760941b6a78f42cccb7e0) (const [
OnSetParametersCallbackHandle
](classrclcpp_1_1Node.html#aac7e1fe50bc2683380cd9a635ac51edb) *const handler)
|  Remove a callback registered with ` add_on_set_parameters_callback ` . [


|  6  |  1931  |  February 23, 2021
[ Plain C API ](https://discourse.ros.org/t/plain-c-api/11911)


template<typename ServiceT , typename CallbackT >


##  ◆  call_handle_goal_callback()


10 min  read


template<typename ServiceT >


Base Action [ Server ](classrclcpp__action_1_1Server.html "Action Server.")
implementation This class should not be used directly by users writing an
action server. Instead users should use ` [ rclcpp_action::Server
](classrclcpp__action_1_1Server.html "Action Server.") ` .


     [ std::runtime_error ](http://en.cppreference.com/w/cpp/error/runtime_error.html) |  if publishers could not be counted
---|---

##  ◆  count_publishers()


##  ◆  get_node_logging_interface()


  Background  ï

Actions are a form of asynchronous communication in ROS. _Action clients_ send
goal requests to _action servers_ . _Action servers_ send goal feedback and
results to _action clients_ .


     [in]  |  node_name  |  Name of the node.
---|---|---
[in]  |  options  |  Additional options to control creation of the node.

Exceptions


node->get_effective_namespace();  // -> "/my_ns"


##  ◆  get_node_topics_interface()


    ResultCallback result_callback;
  };
  /// Construct an action client.
  /**
   * This constructs an action client, but it will not work until it has been added to a node.
   * Use `rclcpp_action::create_client()` to both construct and add to a node.
   *
   * \param[in] node_base A pointer to the base interface of a node.
   * \param[in] node_graph A pointer to an interface that allows getting graph information about
   *   a node.
   * \param[in] node_logging A pointer to an interface that allows getting a node's logger.
   * \param[in] action_name The action name.
   * \param[in] client_options Options to pass to the underlying `rcl_action::rcl_action_client_t`.
   */
  Client(
    rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base,
    rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph,
    rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging,
    const std::string & action_name,
    const rcl_action_client_options_t & client_options = rcl_action_client_get_default_options()
  )
  : ClientBase(
      node_base, node_graph, node_logging, action_name,
      rosidl_typesupport_cpp::get_action_type_support_handle<ActionT>(),
      client_options)
  {
  }
  /// Send an action goal and asynchronously get the result.
  /**
   * If the goal is accepted by an action server, the returned future is set to a `ClientGoalHandle`.
   * If the goal is rejected by an action server, then the future is set to a `nullptr`.
   *
   * The returned goal handle is used to monitor the status of the goal and get the final result.
   * It is valid as long as you hold a reference to the shared pointer or until the
   * rclcpp_action::Client is destroyed at which point the goal status will become UNKNOWN.
   *
   * \param[in] goal The goal request.
   * \param[in] options Options for sending the goal request. Contains references to callbacks for
   *   the goal response (accepted/rejected), feedback, and the final result.
   * \return A future that completes when the goal has been accepted or rejected.


The aggregate result of setting all the parameters atomically.


true if the parameter name has been declared, otherwise false.


` topic_name ` may be a relative, private, or fully qualified topic name. A
relative or private topic will be expanded using this node's namespace and
name. The queried ` topic_name ` is not remapped.


Reimplemented from [ rclcpp::Waitable
](http://docs.ros2.org/foxy/api/rclcpp/classrclcpp_1_1Waitable.html#aeb7d6a8213736f5a60d9c8f9290866a9)
.


using [ rclcpp::Node::OnParametersSetCallbackType
](classrclcpp_1_1Node.html#ab403fecdb5ec2eb9f88e3eb7ae6f6d0c) = [
rclcpp::node_interfaces::NodeParametersInterface::OnParametersSetCallbackType
](classrclcpp_1_1node__interfaces_1_1NodeParametersInterface.html#a7143766bc4249673edb6244820fc5a94)
---

##  Constructor & Destructor Documentation


     [ rclcpp::exceptions::ParameterNotDeclaredException ](classrclcpp_1_1exceptions_1_1ParameterNotDeclaredException.html "Thrown if parameter is not declared, e.g. either set or get was called without first declaring.") |  if any parameter has not been declared and undeclared parameters are not allowed.
---|---

##  ◆  get_parameter()  [1/3]


void rclcpp::Node::undeclare_parameter  |  (  |  const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) & |  _name_ |  )
|
---|---|---|---|---|---

Undeclare a previously declared parameter.


e.g.:


[ rclcpp::node_interfaces::NodeClock::get_clock ](classrclcpp_1_1node__interfaces_1_1NodeClock.html#a0998d27ad1fceaa0af4f101f54177f1a "Get a clock which will be kept up to date by the node.")


Returns


std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&name, ParameterT &parameter) const
|  Get the value of a parameter by the given name, and return true if it was
set. [ More... ](classrclcpp_1_1Node.html#a3158e5520c58531ae4d85a2e98cdf210)

template<typename ParameterT >
bool  |  [ get_parameter_or
](classrclcpp_1_1Node.html#a4bba086f9d74de0f1f10ffb8deb4c11a) (const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&name, ParameterT &parameter, const ParameterT &alternative_value) const
|  Get the parameter value, or the "alternative_value" if not set, and assign
it to "parameter". [ More...
](classrclcpp_1_1Node.html#a4bba086f9d74de0f1f10ffb8deb4c11a)

[ std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) < [
rclcpp::Parameter ](classrclcpp_1_1Parameter.html) > |  [ get_parameters
](classrclcpp_1_1Node.html#a25890d01a2cd47ce99af887f556c529b) (const [
std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) < [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html) >
&names) const
|  Return the parameters by the given parameter names. [ More...
](classrclcpp_1_1Node.html#a25890d01a2cd47ce99af887f556c529b)

template<typename ParameterT >
bool  |  [ get_parameters
](classrclcpp_1_1Node.html#ae5ab12777100f65bd09163814dbbf486) (const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&prefix, [ std::map ](http://en.cppreference.com/w/cpp/container/map.html) < [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html) ,
ParameterT > &values) const
|  Get the parameter values for all parameters that have a given prefix. [
More... ](classrclcpp_1_1Node.html#ae5ab12777100f65bd09163814dbbf486)

rcl_interfaces::msg::ParameterDescriptor  |  [ describe_parameter
](classrclcpp_1_1Node.html#a39de814a51b5792e86cd9b315e631fe0) (const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&name) const
|  Return the parameter descriptor for the given parameter name. [ More...
](classrclcpp_1_1Node.html#a39de814a51b5792e86cd9b315e631fe0)


    class FibonacciActionClient : public rclcpp::Node

The constructor for the ` FibonacciActionClient  ` class initializes the node
name as ` fibonacci_action_client  ` :

      explicit FibonacciActionClient(const rclcpp::NodeOptions & options)
      : Node("fibonacci_action_client", options)

The constructor also instantiates a new action client:

        this->client_ptr_ = rclcpp_action::create_client<Fibonacci>(
          this,
          "fibonacci");

An action client requires 3 things:

  1. The templated action type name: ` Fibonacci  ` .

  2. A ROS 2 node to add the action client to: ` this  ` .

  3. The action name: ` 'fibonacci'  ` .

We also instantiate a ROS timer that will kick off the one and only call to `
send_goal  ` :

        auto timer_callback_lambda = [this](){ return this->send_goal(); };
        this->timer_ = this->create_wall_timer(
          std::chrono::milliseconds(500),
          timer_callback_lambda);


Parameters


See also


[ rclcpp::QoS ](classrclcpp_1_1QoS.html) custom_qos(KeepLast(10),
rmw_qos_profile_sensor_data);


##  ◆  get_sub_namespace()


The previous callback that was registered, if there was one, otherwise nullptr.


Shared pointer to the created client.


[ ![Foxglove](/images/logo-white.svg) ](/)


     callback  |  The callback to register.
---|---

Returns


> Is developing this functionality on any current roadmap, or has anybody
> attempted this before?


     [in]  |  name  |  The name of the parameter to get.
---|---|---
[out]  |  parameter  |  The output storage for the parameter being retrieved.

Returns


    // DDS helps pass the request and response between client and server
    void doChecks(const std::shared_ptr<std_srvs::srv::Trigger::Request> request, std::shared_ptr<std_srvs::srv::Trigger::Response> response){

      // Prepare response
      response->success = true;
      response->message = "";
      RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Received request to check motors...");

      // Iterate over all motors (e.g. 5) to perform the check
      for (int i = 0; i < 5; i++) {
        RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Checking motor %i",i);
        auto res = moveMotorToMinAndMax(i);
        // If something fails, change response `success` to false and add info to the `message`
        if (!res) {
          response->success = false;
          response->message += "Motor"+std::to_string(i)+" Failed";
        }
      }

      RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Sending back response...");
    }


#  Creating ROS 2 Services


     [in]  |  names  |  The list of parameter names to get the types.
---|---|---

Returns


     InvalidNamespaceError  |  if the namespace is invalid
---|---

##  ◆  ~Node()


newly created sub-node


     [in]  |  parameter  |  The parameter to be set.
---|---|---

Returns


|  7  |  5014  |  May 29, 2022
[ ROS2 C based dynamic typesupport example?
](https://discourse.ros.org/t/ros2-c-based-dynamic-typesupport-example/19079)


     [in]  |  prefix  |  The prefix of the parameters to get.
---|---|---
[out]  |  values  |  The map used to store the parameter names and values,
respectively, with one entry per parameter matching prefix.

Returns


Exceptions


[ phuicy  ](https://discourse.ros.org/u/phuicy) June 19, 2020, 12:10pm  3


If you were to create a publisher for this task, your node could publish its
check results before a corresponding subscriber becomes available. As a
result, you'd miss the check results and be left in the dark about the status
of your motors.


Services consist of two parts - a **request** and a **response** . Each part
can be empty or contain as many data **fields** that you want to share between
nodes.


##  Public Types

---
using  |  [ OnSetParametersCallbackHandle
](classrclcpp_1_1Node.html#aac7e1fe50bc2683380cd9a635ac51edb) = [
rclcpp::node_interfaces::OnSetParametersCallbackHandle
](structrclcpp_1_1node__interfaces_1_1OnSetParametersCallbackHandle.html)
using  |  [ OnParametersSetCallbackType
](classrclcpp_1_1Node.html#ab403fecdb5ec2eb9f88e3eb7ae6f6d0c) = [
rclcpp::node_interfaces::NodeParametersInterface::OnParametersSetCallbackType
](classrclcpp_1_1node__interfaces_1_1NodeParametersInterface.html#a7143766bc4249673edb6244820fc5a94)

##  Public Member Functions

---
|  [ Node ](classrclcpp_1_1Node.html#abaa409bd2dc2cc2437fd9e47378cc5af) (const
[ std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&node_name, const [ NodeOptions ](classrclcpp_1_1NodeOptions.html) &options= [
NodeOptions ](classrclcpp_1_1NodeOptions.html) ())
|  Create a new node with the specified name. [ More...
](classrclcpp_1_1Node.html#abaa409bd2dc2cc2437fd9e47378cc5af)

|  [ Node ](classrclcpp_1_1Node.html#a83f5f45604217b3dc583dac7ab3b66a8) (const
[ std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&node_name, const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) &namespace_,
const [ NodeOptions ](classrclcpp_1_1NodeOptions.html) &options= [ NodeOptions
](classrclcpp_1_1NodeOptions.html) ())
|  Create a new node with the specified name. [ More...
](classrclcpp_1_1Node.html#a83f5f45604217b3dc583dac7ab3b66a8)

virtual  |  [ ~Node
](classrclcpp_1_1Node.html#a63584993927b11869d15a34af7e64937) ()
const char *  |  [ get_name
](classrclcpp_1_1Node.html#a1e162104495b21f50c1e9aa11460fb93) () const
|  Get the name of the node. [ More...
](classrclcpp_1_1Node.html#a1e162104495b21f50c1e9aa11460fb93)

const char *  |  [ get_namespace
](classrclcpp_1_1Node.html#a7be04e55e2934e05df992b188d9dce6d) () const


Calling ` remove_on_set_parameters_callback ` more than once with the same
handler, or calling it after the shared pointer has been reset is an error.
Resetting or letting the smart pointer go out of scope after calling `
remove_on_set_parameters_callback ` is not a problem.


This node will wait for ` motor_node ` to appear before requesting the checks.


  3.2 Compiling the action client  ï

In the previous section we put the action client code into place. To get it to
compile and run, we need to do a couple of additional things.

First we need to setup the CMakeLists.txt so that the action client is
compiled. Open up ` custom_action_cpp/CMakeLists.txt  ` , and add the
following right after the ` find_package  ` calls:

    add_library(action_client SHARED
      src/fibonacci_action_client.cpp)
    target_include_directories(action_client PRIVATE
      $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
      $<INSTALL_INTERFACE:include>)
    target_compile_definitions(action_client
      PRIVATE "CUSTOM_ACTION_CPP_BUILDING_DLL")
    ament_target_dependencies(action_client
      "custom_action_interfaces"
      "rclcpp"
      "rclcpp_action"
      "rclcpp_components")
    rclcpp_components_register_node(action_client PLUGIN "custom_action_cpp::FibonacciActionClient" EXECUTABLE fibonacci_action_client)
    install(TARGETS
      action_client
      ARCHIVE DESTINATION lib
      LIBRARY DESTINATION lib
      RUNTIME DESTINATION bin)

And now we can compile the package. Go to the top-level of the ` ros2_ws  ` ,
and run:

    colcon build

This should compile the entire workspace, including the `


![Inheritance graph](classrclcpp__action_1_1ServerBase__inherit__graph.png)


Reimplemented from [ rclcpp::Waitable
](http://docs.ros2.org/foxy/api/rclcpp/classrclcpp_1_1Waitable.html#a4f428f90de03558d8e5090b45fa96ac8)
.


auto  sub_node2 = sub_node1->create_sub_node(  "b"  );


Once the server is on, the program will exit the ` while ` loop, send the
request, and spin the node until the future is complete (i.e. the client
receives a response from the server).


     [ get_namespace() ](classrclcpp_1_1Node.html#a7be04e55e2934e05df992b188d9dce6d "Get the namespace of the node.")
     [ get_sub_namespace() ](classrclcpp_1_1Node.html#aa9ac5055f3f7a3537642482bd505d4bd "Return the sub-namespace, if this is a sub-node, otherwise an empty string.")


// Copyright 2014 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef RCLCPP__CLIENT_HPP_
#define RCLCPP__CLIENT_HPP_
#include <atomic>
#include <functional>
#include <future>
#include <memory>
#include <mutex>
#include <optional>
#include <sstream>
#include <string>
#include <tuple>
#include <unordered_map>
#include <utility>
#include <variant>
#include <vector>
#include "rcl/client.h"
#include "rcl/error_handling.h"
#include "rcl/event_callback.h"
#include "rcl/service_introspection.h"
#include "rcl/wait.h"
#include "rclcpp/clock.hpp"
#include "rclcpp/detail/cpp_callback_trampoline.hpp"
#include "rclcpp/exceptions.hpp"
#include "rclcpp/expand_topic_or_service_name.hpp"
#include "rclcpp/function_traits.hpp"
#include "rclcpp/logging.hpp"
#include "rclcpp/macros.hpp"


If ` spin_until_future_complete ` returns a ` SUCCESS ` , we know that the
server has responded correctly, and we can process that response. If the
return value is not ` SUCCESS ` , we can assume there was a problem with
reaching the server:


With services, a client node must first **call** the server in order to send a
**request** . This means that in the server-client mode, nodes do not use a
communication stream until it’s absolutely needed, preventing unnecessary
bandwidth usage. Then, the client node must wait for a **response** from the
server (or until a timeout is reached). For this reason, services can confirm
communication between nodes.


rclcpp::Clock::ConstSharedPtr rclcpp::Node::get_clock  |  (  |  |  )  |  const
---|---|---|---|---

Get a clock as a const shared pointer which is managed by the node.


Another common way nodes can share information with each other is via
services. With ROS 2 services, one or many "client" nodes can make requests to
a "server" node and wait for its response. These make services great for
performing on-demand tasks – like performing on-the-fly computations or simple
one-time tasks.


if  (!some_condition) {


Agreed - being a bit of a ROS2 novice I was disappointed to find that I needed
to duplicate the(de)serialization method used in the specific rmw
implementation I was using in order to get usable data out of a
SerializedMessage. It feels like something that should be possible without
coupling my application to a specific rmw implementation.


The result of the set action.


##  ◆  ~ServerBase()


The name expansion is naive, so if you set the namespace to be "foo.", then
the resulting parameter names will be like "foo..key". However, if the
namespace is an empty string, then no leading '.' will be placed before each
key, which would have been the case when naively expanding "namespace.key".
This allows you to declare several parameters at once without a namespace.


     [in]  |  callback  |  The callback to be called when the value for a parameter is about to be set.
---|---|---

Returns


|  [ RCLCPP_ACTION_PUBLIC
](visibility__control_8hpp.html#a736fe60d4de4417a213ed34ba1926048) size_t
rclcpp_action::ServerBase::get_number_of_ready_subscriptions  |  (  |  |  )  |
---|---|---|---|---
override  virtual

Return the number of subscriptions used to implement an action server


Like the version of [ get_parameter()
](classrclcpp_1_1Node.html#a0bf1077fba623d72fe1b49805f6c0a5a "Return the
parameter by the given name.") which returns a bool, this method will not
throw the [ rclcpp::exceptions::ParameterNotDeclaredException
](classrclcpp_1_1exceptions_1_1ParameterNotDeclaredException.html "Thrown if
parameter is not declared, e.g. either set or get was called without first
declaring.") exception.


the sub-namespace string, not including the node's original namespace


![Running both nodes](/images/blog/creating-ros2-services/terminal.webp)
_**Left** : Client ` diagnostics_node ` . **Right** : Server ` motor_node ` _
.


Return to the root folder of your workspace to compile with your new nodes:


|  8  |  1648  |  September 14, 2022

  * [ Home ](/)
  * [ Categories ](/categories)
  * [ FAQ/Guidelines ](/guidelines)
  * [ Terms of Service ](/tos)
  * [ Privacy Policy ](/privacy)


     [ rclcpp::exceptions::ParameterNotDeclaredException ](classrclcpp_1_1exceptions_1_1ParameterNotDeclaredException.html "Thrown if parameter is not declared, e.g. either set or get was called without first declaring.") |  if any parameter has not been declared and undeclared parameters are not allowed.
---|---

##  ◆  set_parameters_atomically()


![Creating ROS 2 Services](/images/blog/creating-ros2-services/hero.webp)


|  21  |  6946  |  May 1, 2019
[ ROS2 client library for Julialang ](https://discourse.ros.org/t/ros2-client-
library-for-julialang/11858)


Returns


However, now I’d like to do the same for calling services and actions. From
looking at the code, it looks like a writing a “GenericClient” for services
would mean creating a new subclass of [ ` rclcpp::ClientBase `
](http://docs.ros2.org/foxy/api/rclcpp/classrclcpp_1_1ClientBase.html) and
instantiating it with the relevant typesupport handle. Similarly for actions
with [ ` rclcpp_action::ClientBase `
](http://docs.ros2.org/foxy/api/rclcpp_action/classrclcpp__action_1_1ClientBase.html)
. Or perhaps I am misreading it, and using the ` ClientBase ` classes directly
would suffice.


     [in]  |  name  |  The name of the parameter to describe.
---|---|---

Returns


Parameters


[ std::shared_ptr ](http://en.cppreference.com/w/cpp/memory/shared_ptr.html) <
SubscriptionT > rclcpp::Node::create_subscription  |  (  |  const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html) & |
_topic_name_ ,
---|---|---|---
|  |  const [ rclcpp::QoS ](classrclcpp_1_1QoS.html) & |  _qos_ ,
|  |  CallbackT && |  _callback_ ,
|  |  const [ SubscriptionOptionsWithAllocator
](structrclcpp_1_1SubscriptionOptionsWithAllocator.html) < AllocatorT > & |
_options_ = ` [ SubscriptionOptionsWithAllocator
](structrclcpp_1_1SubscriptionOptionsWithAllocator.html) <AllocatorT>() ` ,
|  |  typename MessageMemoryStrategyT::SharedPtr  |  _msg_mem_strat_ = ` (
MessageMemoryStrategyT::create_default() ) `
|  )  |  |

Create and return a [ Subscription ](classrclcpp_1_1Subscription.html
"Subscription implementation, templated on the type of message this
subscription receives.") .


     [in]  |  period  |  [ Time ](classrclcpp_1_1Time.html) interval between triggers of the callback.
---|---|---
[in]  |  callback  |  User-defined callback function.
[in]  |  group  |  Callback group to execute this timer's callback in.

##  ◆  create_client()  [1/2]


![Esther Weon](/images/blog/authors/estherweon.webp) Esther Weon  Esther Weon


Set the given parameters, one at a time, and then return result of each set
action.


          this->make_result_aware(goal_handle);
        }
      });
    // TODO(jacobperron): Encapsulate into it's own function and
    //                    consider exposing an option to disable this cleanup
    // To prevent the list from growing out of control, forget about any goals
    // with no more user references
    {
      std::lock_guard<std::mutex> guard(goal_handles_mutex_);
      auto goal_handle_it = goal_handles_.begin();
      while (goal_handle_it != goal_handles_.end()) {
        if (!goal_handle_it->second.lock()) {
          RCLCPP_DEBUG(
            this->get_logger(),
            "Dropping weak reference to goal handle during send_goal()");
          goal_handle_it = goal_handles_.erase(goal_handle_it);
        } else {
          ++goal_handle_it;
        }
      }
    }
    return future;
  }
  /// Asynchronously get the result for an active goal.
  /**
   * \throws exceptions::UnknownGoalHandleError If the goal unknown or already reached a terminal
   *   state, or if there was an error requesting the result.
   * \param[in] goal_handle The goal handle for which to get the result.
   * \param[in] result_callback Optional callback that is called when the result is received.
   * \return A future that is set to the goal result when the goal is finished.
   */
  std::shared_future<WrappedResult>
  async_get_result(
    typename GoalHandle::SharedPtr goal_handle,
    ResultCallback result_callback = nullptr)
  {
    std::lock_guard<std::mutex> lock(goal_handles_mutex_);
    if (goal_handles_.count(goal_handle->get_goal_id()) == 0) {
      throw exceptions::UnknownGoalHandleError();
    }


std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html) > > |
[ get_service_names_and_types_by_node
](classrclcpp_1_1Node.html#aa3df8a7d8b174f8049dfd2766f4b2eb9) (const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&node_name, const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) &namespace_)
const
|  Return the number of publishers that are advertised on a given topic. [
More... ](classrclcpp_1_1Node.html#aa3df8a7d8b174f8049dfd2766f4b2eb9)

size_t  |  [ count_publishers
](classrclcpp_1_1Node.html#a8792429fa0ee5c5d7f9eca537cf4cff0) (const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&topic_name) const
size_t  |  [ count_subscribers
](classrclcpp_1_1Node.html#a7aa2ed22450d2f3300ea5b879acd73b8) (const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&topic_name) const
|  Return the number of subscribers who have created a subscription for a
given topic. [ More...
](classrclcpp_1_1Node.html#a7aa2ed22450d2f3300ea5b879acd73b8)

[ std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) < [
rclcpp::TopicEndpointInfo ](classrclcpp_1_1TopicEndpointInfo.html) > |  [
get_publishers_info_by_topic
](classrclcpp_1_1Node.html#a08220daf1d66596012e858d19efd1212) (const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&topic_name, bool no_mangle=false) const
|  Return the topic endpoint information about publishers on a given topic. [
More... ](classrclcpp_1_1Node.html#a08220daf1d66596012e858d19efd1212)

[ std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) < [
rclcpp::TopicEndpointInfo ](classrclcpp_1_1TopicEndpointInfo.html) > |  [
get_subscriptions_info_by_topic
](classrclcpp_1_1Node.html#afba993c401901433b3c8647ef716c7e4) (const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&topic_name, bool no_mangle=false) const
|  Return the topic endpoint information about subscriptions on a given topic.
[ More... ](classrclcpp_1_1Node.html#afba993c401901433b3c8647ef716c7e4)


Like [ get_parameters()
](classrclcpp_1_1Node.html#a25890d01a2cd47ce99af887f556c529b "Return the
parameters by the given parameter names.") , this method may throw the [
rclcpp::exceptions::ParameterNotDeclaredException
](classrclcpp_1_1exceptions_1_1ParameterNotDeclaredException.html "Thrown if
parameter is not declared, e.g. either set or get was called without first
declaring.") exception if the requested parameter has not been declared and
undeclared parameters are not allowed.


  2.3 Running the action server  ï

Now that we have the action server built, we can run it. Source the workspace
we just built ( ` ros2_ws  ` ), and try to run the action server:

    ros2 run custom_action_cpp fibonacci_action_server


     [ rclcpp::exceptions::ParameterNotDeclaredException ](classrclcpp_1_1exceptions_1_1ParameterNotDeclaredException.html "Thrown if parameter is not declared, e.g. either set or get was called without first declaring.") |  if the parameter has not been declared and undeclared parameters are not allowed.
---|---
[ std::runtime_error
](http://en.cppreference.com/w/cpp/error/runtime_error.html) |  if the number
of described parameters is more than one

##  ◆  describe_parameters()


The callback signature is designed to allow handling of any of the above `
set_parameter* ` or ` declare_parameter* ` methods, and so it takes a const
reference to a vector of parameters to be set, and returns an instance of
rcl_interfaces::msg::SetParametersResult to indicate whether or not the
parameter should be set or not, and if not why.


The descriptor for the given parameter name.


: properly document and test this method.


     [in]  |  name  |  The name of the parameter to get.
---|---|---

Returns


|  virtual [ RCLCPP_ACTION_PUBLIC
](visibility__control_8hpp.html#a736fe60d4de4417a213ed34ba1926048) [
std::shared_ptr ](http://en.cppreference.com/w/cpp/memory/shared_ptr.html)
<void> rclcpp_action::ServerBase::create_goal_request  |  (  |  |  )  |
---|---|---|---|---
protected  pure virtual

Create an empty goal request message so it can be taken from a lower layer.


[ iaamp  ](https://discourse.ros.org/u/iaamp) April 27, 2023, 11:17am  6


     [ rclcpp::exceptions::ParameterNotDeclaredException ](classrclcpp_1_1exceptions_1_1ParameterNotDeclaredException.html "Thrown if parameter is not declared, e.g. either set or get was called without first declaring.") |  if the parameter has not been declared and undeclared parameters are not allowed.
---|---

##  ◆  get_parameter()  [2/3]


The callbacks added with ` add_on_set_parameters_callback ` are stored in a
different place. ` remove_on_set_parameters_callback ` can't be used with the
callbacks registered with this method. For removing it, use `
set_on_parameters_set_callback(nullptr) ` .


Returns


  * [ https://en.cppreference.com/w/cpp/language/lifetime ](https://en.cppreference.com/w/cpp/language/lifetime)
  * [ https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/ ](https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/)
  * [ https://www.youtube.com/watch?v=uQyT-5iWUow ](https://www.youtube.com/watch?v=uQyT-5iWUow) (cppnow 2018 presentation)


rclcpp::Clock::SharedPtr rclcpp::Node::get_clock  |  (  |  |  )  |
---|---|---|---|---

Get a clock as a non-const shared pointer which is managed by the node.


The callback may introspect other already set parameters (by calling any of
the {get,list,describe}_parameter() methods), but may _not_ modify other
parameters (by calling any of the {set,declare}_parameter() methods) or modify
the registered callback itself (by calling the [
add_on_set_parameters_callback()
](classrclcpp_1_1Node.html#a12d535bced9f26b65c0a450e6f40aff8 "Add a callback
for when parameters are being set.") method). If a callback tries to do any of
the latter things, [ rclcpp::exceptions::ParameterModifiedInCallbackException
](classrclcpp_1_1exceptions_1_1ParameterModifiedInCallbackException.html
"Thrown if parameter is modified while in a set callback.") will be thrown.


##  ◆  create_result_request()


visualization


As an alternative, the smart pointer can be reset:


Inheritance diagram for rclcpp_action::ServerBase:


The map contains default values for parameters. There is another overload
which takes the [ std::pair
](http://en.cppreference.com/w/cpp/utility/pair.html) with the default value
and descriptor.


Exceptions


    rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging,
    const std::string & action_name,
    const rosidl_action_type_support_t * type_support,
    const rcl_action_client_options_t & options);
  /// Wait for action_server_is_ready() to become true, or until the given timeout is reached.
  RCLCPP_ACTION_PUBLIC
  bool
  wait_for_action_server_nanoseconds(std::chrono::nanoseconds timeout);
  // -----------------------------------------------------
  // API for communication between ClientBase and Client<>
  using ResponseCallback = std::function<void (std::shared_ptr<void> response)>;
  /// \internal
  RCLCPP_ACTION_PUBLIC
  rclcpp::Logger get_logger();
  /// \internal
  RCLCPP_ACTION_PUBLIC
  virtual
  GoalUUID
  generate_goal_id();
  /// \internal
  RCLCPP_ACTION_PUBLIC
  virtual
  void
  send_goal_request(
    std::shared_ptr<void> request,
    ResponseCallback callback);
  /// \internal
  RCLCPP_ACTION_PUBLIC
  virtual
  void
  send_result_request(
    std::shared_ptr<void> request,
    ResponseCallback callback);
  /// \internal
  RCLCPP_ACTION_PUBLIC
  virtual
  void
  send_cancel_request(
    std::shared_ptr<void> request,
    ResponseCallback callback);


    source install/setup.bash

    . install/setup.bash

    call install/setup.bat

Now run the service node:

    ros2 run cpp_srvcli server

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

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

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:

    ros2 run cpp_srvcli client 2 3

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

    [INFO] [rclcpp]: Sum: 5


A vector of fully-qualified names of nodes.


In the ` CMakeList.txt ` file, make sure that you've the following:


Implements [ rclcpp::Waitable
](http://docs.ros2.org/foxy/api/rclcpp/classrclcpp_1_1Waitable.html#a7a71a73b57677c3097012a0bb23b83d4)
.


  * [ How-to Guides ](../../../How-To-Guides.html)
    * [ Installation troubleshooting ](../../../How-To-Guides/Installation-Troubleshooting.html)
    * [ Developing a ROS 2 package ](../../../How-To-Guides/Developing-a-ROS-2-Package.html)
    * [ Documenting a ROS 2 package ](../../../How-To-Guides/Documenting-a-ROS-2-Package.html)
    * [ ament_cmake user documentation ](../../../How-To-Guides/Ament-CMake-Documentation.html)
    * [ ament_cmake_python user documentation ](../../../How-To-Guides/Ament-CMake-Python-Documentation.html)
    * [ Migrating from ROS 1 to ROS 2 ](../../../How-To-Guides/Migrating-from-ROS1.html)
      * [ Migrating Packages ](../../../How-To-Guides/Migrating-from-ROS1/Migrating-Packages.html)
      * [ Migrating Interfaces ](../../../How-To-Guides/Migrating-from-ROS1/Migrating-Interfaces.html)
      * [ Migrating C++ Packages ](../../../How-To-Guides/Migrating-from-ROS1/Migrating-CPP-Packages.html)
      * [ Migrating Python Packages ](../../../How-To-Guides/Migrating-from-ROS1/Migrating-Python-Packages.html)
      * [ Migrating Launch Files ](../../../How-To-Guides/Migrating-from-ROS1/Migrating-Launch-Files.html)
      * [ Migrating Parameters ](../../../How-To-Guides/Migrating-from-ROS1/Migrating-Parameters.html)
      * [ Migrating Scripts ](../../../How-To-Guides/Migrating-from-ROS1/Migrating-Scripts.html)
    * [ Using Python, XML, and YAML for ROS 2 Launch Files ](../../../How-To-Guides/Launch-file-different-formats.html)
    * [ Using ROS 2 launch to launch composable nodes ](../../../How-To-Guides/Launching-composable-nodes.html)
    * [ Passing ROS arguments to nodes via the command-line ](../../../How-To-Guides/Node-arguments.html)
    * [ Synchronous vs. asynchronous service clients ](../../../How-To-Guides/Sync-Vs-Async.html)
    * [ DDS tuning information ](../../../How-To-Guides/DDS-tuning.html)
    * [ rosbag2: Overriding QoS Policies ](../../../How-To-Guides/Overriding-QoS-Policies-For-Recording-And-Playback.html)
    * [ Working with multiple ROS 2 middleware implementations ](../../../How-To-Guides/Working-with-multiple-RMW-implementations.html)
    * [ Cross-compilation ](../../../How-To-Guides/Cross-compilation.html)
    * [ Releasing a Package ](../../../How-To-Guides/Releasing/Releasing-a-Package.html)
      * [ First Time Release ](../../../How-To-Guides/Releasing/First-Time-Release.html)
      * [ Subsequent Releases ](../../../How-To-Guides/Releasing/Subsequent-Releases.html)
      * [ Release Team / Repository ](../../../How-To-Guides/Releasing/Release-Team-Repository.html)
      * [ Release Track ](../../../How-To-Guides/Releasing/Release-Track.html)
    * [ Using Python Packages with ROS 2 ](../../../How-To-Guides/Using-Python-Packages.html)
    * [ Porting RQt plugins to Windows ](../../../How-To-Guides/RQt-Port-Plugin-Windows.html)
    * [ Running ROS 2 nodes in Docker [community-contributed] ](../../../How-To-Guides/Run-2-nodes-in-single-or-separate-docker-containers.html)
    * [ Visualizing ROS 2 data with Foxglove Studio ](../../../How-To-Guides/Visualizing-ROS-2-Data-With-Foxglove-Studio.html)
    * [ ROS 2 Package Maintainer Guide ](../../../How-To-Guides/Package-maintainer-guide.html)
    * [ Building a custom Debian package ](../../../How-To-Guides/Building-a-Custom-Debian-Package.html)
    * [ Building ROS 2 with tracing ](../../../How-To-Guides/Building-ROS-2-with-Tracing.html)
    * [ Topics vs Services vs Actions ](../../../How-To-Guides/Topics-Services-Actions.html)
    * [ Using variants ](../../../How-To-Guides/Using-Variants.html)
    * [ Using the ` ros2  param  ` command-line tool ](../../../How-To-Guides/Using-ros2-param.html)
    * [ Using ` ros1_bridge  ` with upstream ROS on Ubuntu 22.04 ](../../../How-To-Guides/Using-ros1_bridge-Jammy-upstream.html)
    * [ Configure Zero Copy Loaned Messages ](../../../How-To-Guides/Configure-ZeroCopy-loaned-messages.html)
    * [ ROS 2 on Raspberry Pi ](../../../How-To-Guides/Installing-on-Raspberry-Pi.html)


auto  sub_node1 = node->create_sub_node(  "a"  );


See also


    std::lock_guard<std::recursive_mutex> lock(callback_mutex_);
    // Set it temporarily to the new callback, while we replace the old one.
    // This two-step setting, prevents a gap where the old std::function has
    // been replaced but the middleware hasn't been told about the new one yet.
    set_on_new_response_callback(
      rclcpp::detail::cpp_callback_trampoline<decltype(new_callback), const void *, size_t>,
      static_cast<const void *>(&new_callback));
    // Store the std::function to keep it in scope, also overwrites the existing one.
    on_new_response_callback_ = new_callback;
    // Set it again, now using the permanent storage.
    set_on_new_response_callback(
      rclcpp::detail::cpp_callback_trampoline<
        decltype(on_new_response_callback_), const void *, size_t>,
      static_cast<const void *>(&on_new_response_callback_));
  }
  /// Unset the callback registered for new responses, if any.
  void
  clear_on_new_response_callback()
  {
    std::lock_guard<std::recursive_mutex> lock(callback_mutex_);
    if (on_new_response_callback_) {
      set_on_new_response_callback(nullptr, nullptr);
      on_new_response_callback_ = nullptr;
    }
  }
protected:
  RCLCPP_DISABLE_COPY(ClientBase)
  RCLCPP_PUBLIC
  bool
  wait_for_service_nanoseconds(std::chrono::nanoseconds timeout);
  RCLCPP_PUBLIC
  rcl_node_t *
  get_rcl_node_handle();
  RCLCPP_PUBLIC
  const rcl_node_t *
  get_rcl_node_handle() const;
  RCLCPP_PUBLIC
  void
  set_on_new_response_callback(rcl_event_callback_t callback, const void * user_data);
  rclcpp::node_interfaces::NodeGraphInterface::WeakPtr node_graph_;


In all cases, the parameter is never set or declared within the node.


##  ◆  get_number_of_ready_subscriptions()


rclcpp::node_interfaces::NodeWaitablesInterface::SharedPtr
rclcpp::Node::get_node_waitables_interface  |  (  |  |  )  |
---|---|---|---|---

Return the [ Node ](classrclcpp_1_1Node.html "Node is the single point of
entry for creating publishers and subscribers.") 's internal
NodeWaitablesInterface implementation.


August 15, 2022  ·  11 min  read


##  ◆  declare_parameter()  [1/2]


|  [ RCLCPP_ACTION_PUBLIC
](visibility__control_8hpp.html#a736fe60d4de4417a213ed34ba1926048) void
rclcpp_action::ServerBase::publish_feedback  |  (  |  [ std::shared_ptr
](http://en.cppreference.com/w/cpp/memory/shared_ptr.html) < void > |
_feedback_msg_ |  )  |
---|---|---|---|---|---
protected

* * *


      // Create the request, which is empty
      auto request = std::make_shared<std_srvs::srv::Trigger::Request>();


rclcpp::node_interfaces::NodeClockInterface::SharedPtr
rclcpp::Node::get_node_clock_interface  |  (  |  |  )  |
---|---|---|---|---

Return the [ Node ](classrclcpp_1_1Node.html "Node is the single point of
entry for creating publishers and subscribers.") 's internal
NodeClockInterface implementation.


const [ rmw_qos_profile_t
](http://docs.ros2.org/foxy/api/rmw/structrmw__qos__profile__t.html)
&qos_profile=rmw_qos_profile_services_default,
rclcpp::CallbackGroup::SharedPtr group=nullptr)
|  Create and return a [ Client ](classrclcpp_1_1Client.html) . [ More...
](classrclcpp_1_1Node.html#aed42f345ae1de3a1979d5a8076127199)

template<typename ServiceT , typename CallbackT >
[ rclcpp::Service ](classrclcpp_1_1Service.html) < ServiceT >::SharedPtr  |  [
create_service ](classrclcpp_1_1Node.html#a20d1f389ba5e4a57559203d5d9e77ec9)
(const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) &service_name,
CallbackT &&callback, const [ rmw_qos_profile_t
](http://docs.ros2.org/foxy/api/rmw/structrmw__qos__profile__t.html)
&qos_profile=rmw_qos_profile_services_default,
rclcpp::CallbackGroup::SharedPtr group=nullptr)
|  Create and return a [ Service ](classrclcpp_1_1Service.html) . [ More...
](classrclcpp_1_1Node.html#a20d1f389ba5e4a57559203d5d9e77ec9)

const [ rclcpp::ParameterValue ](classrclcpp_1_1ParameterValue.html) & |  [
declare_parameter
](classrclcpp_1_1Node.html#a095ea977b26e7464d9371efea5f36c42) (const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&name, const [ rclcpp::ParameterValue ](classrclcpp_1_1ParameterValue.html)
&default_value= [ rclcpp::ParameterValue ](classrclcpp_1_1ParameterValue.html)
(), const rcl_interfaces::msg::ParameterDescriptor
&parameter_descriptor=rcl_interfaces::msg::ParameterDescriptor(), bool
ignore_override=false)
|  Declare and initialize a parameter, return the effective value. [ More...
](classrclcpp_1_1Node.html#a095ea977b26e7464d9371efea5f36c42)

template<typename ParameterT >
auto  |  [ declare_parameter
](classrclcpp_1_1Node.html#a5b1ca8c48e28bd1f3e5fda2ab3116efd) (const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&name, const ParameterT &default_value, const
rcl_interfaces::msg::ParameterDescriptor
&parameter_descriptor=rcl_interfaces::msg::ParameterDescriptor(), bool
ignore_override=false)
|  Declare and initialize a parameter with a type. [ More...


When the timer expires, it will call ` send_goal  ` :

      void send_goal()
      {
        using namespace std::placeholders;

        this->timer_->cancel();

        if (!this->client_ptr_->wait_for_action_server()) {
          RCLCPP_ERROR(this->get_logger(), "Action server not available after waiting");
          rclcpp::shutdown();
        }

        auto goal_msg = Fibonacci::Goal();
        goal_msg.order = 10;

        RCLCPP_INFO(this->get_logger(), "Sending goal");

        auto send_goal_options = rclcpp_action::Client<Fibonacci>::SendGoalOptions();
        send_goal_options.goal_response_callback = [this](const GoalHandleFibonacci::SharedPtr & goal_handle)
        {
          if (!goal_handle) {
            RCLCPP_ERROR(this->get_logger(), "Goal was rejected by server");
          } else {
            RCLCPP_INFO(this->get_logger(), "Goal accepted by server, waiting for result");
          }
        };

        send_goal_options.feedback_callback = [this](
          GoalHandleFibonacci::SharedPtr,
          const std::shared_ptr<const Fibonacci::Feedback> feedback)
        {
          std::stringstream ss;
          ss << "Next number in sequence received: ";
          for (auto number : feedback->partial_sequence) {
            ss << number << " ";
          }
          RCLCPP_INFO(this->get_logger(), ss.str().c_str());


Exceptions


rclcpp_action  master


$ ros2 run srv_client_checks motor_node


##  ◆  publish_status()


     [ rclcpp::exceptions::ParameterNotDeclaredException ](classrclcpp_1_1exceptions_1_1ParameterNotDeclaredException.html "Thrown if parameter is not declared, e.g. either set or get was called without first declaring.") |  if any of the parameters have not been declared and undeclared parameters are not allowed.
---|---

##  ◆  list_parameters()


##  ◆  undeclare_parameter()


Let’s suppose you want to create a routine check for your robot – for example,
you may want to verify at start-up that your robot's servo motors are all
working properly.


size_t rclcpp::Node::count_subscribers  |  (  |  const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) & |  _topic_name_
|  )  |  const
---|---|---|---|---|---

Return the number of subscribers who have created a subscription for a given
topic.


The ` doChecks ` **server callback** receives two inputs (a ` request ` and `
response ` ) and will run when the server is activated by a client. It
iterates over all available motors to perform the ` moveMotorToMinAndMax `
check on each one, then sends back a response:


  {
    std::lock_guard guard(pending_requests_mutex_);
    return pending_requests_.erase(request_id) != 0u;
  }
  /// Cleanup a pending request.
  /**
   * Convenient overload, same as:
   *
   * `Client::remove_pending_request(this, future.request_id)`.
   */
  bool
  remove_pending_request(const FutureAndRequestId & future)
  {
    return this->remove_pending_request(future.request_id);
  }
  /// Cleanup a pending request.
  /**
   * Convenient overload, same as:
   *
   * `Client::remove_pending_request(this, future.request_id)`.
   */
  bool
  remove_pending_request(const SharedFutureAndRequestId & future)
  {
    return this->remove_pending_request(future.request_id);
  }
  /// Cleanup a pending request.
  /**
   * Convenient overload, same as:
   *
   * `Client::remove_pending_request(this, future.request_id)`.
   */
  bool
  remove_pending_request(const SharedFutureWithRequestAndRequestId & future)
  {
    return this->remove_pending_request(future.request_id);
  }
  /// Clean all pending requests.
  /**
   * \return number of pending requests that were removed.


[ std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) <
ParameterT > rclcpp::Node::declare_parameters  |  (  |  const [ std::string
](http://en.cppreference.com/w/cpp/string/basic_string.html) & |  _namespace__
,
---|---|---|---
|  |  const [ std::map ](http://en.cppreference.com/w/cpp/container/map.html)
< [ std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html) ,
[ std::pair ](http://en.cppreference.com/w/cpp/utility/pair.html) <
ParameterT, rcl_interfaces::msg::ParameterDescriptor > > & |  _parameters_ ,
|  |  bool  |  _ignore_overrides_ = ` false `
|  )  |  |

Declare and initialize several parameters with the same namespace and type.


Parameters


    # Request
    ---
    # Response


##  ◆  create_callback_group()


[ Share on Twitter
](https://twitter.com/intent/tweet?text=Creating%20ROS%202%20Services%3A%20https%3A%2F%2Ffoxglove.dev%2Fblog%2Fcreating-
ros2-services%20%40foxglove) [ Share on LinkedIn
](http://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Ffoxglove.dev%2Fblog%2Fcreating-
ros2-services)


We start with the callback for handling new goals:

        auto handle_goal = [this](
          const rclcpp_action::GoalUUID & uuid,
          std::shared_ptr<const Fibonacci::Goal> goal)
        {
          RCLCPP_INFO(this->get_logger(), "Received goal request with order %d", goal->order);
          (void)uuid;
          return rclcpp_action::GoalResponse::ACCEPT_AND_EXECUTE;
        };

This implementation just accepts all goals.

Next up is the callback for dealing with cancellation:

        auto handle_cancel = [this](
          const std::shared_ptr<GoalHandleFibonacci> goal_handle)
        {
          RCLCPP_INFO(this->get_logger(), "Received request to cancel goal");
          (void)goal_handle;
          return rclcpp_action::CancelResponse::ACCEPT;
        };

This implementation just tells the client that it accepted the cancellation.

The last of the callbacks accepts a new goal and starts processing it:

        auto handle_accepted = [this](
          const std::shared_ptr<GoalHandleFibonacci> goal_handle)
        {
          // this needs to return quickly to avoid blocking the executor,
          // so we declare a lambda function to be called inside a new thread


     [ std::bad_alloc ](http://en.cppreference.com/w/cpp/memory/new/bad_alloc.html) |  if the allocation of the OnSetParametersCallbackHandle fails.
---|---

##  ◆  remove_on_set_parameters_callback()


##  ◆  create_sub_node()


      * [ Implementing a custom memory allocator ](../Advanced/Allocator-Template-Tutorial.html)
      * [ Unlocking the potential of Fast DDS middleware [community-contributed] ](../Advanced/FastDDS-Configuration.html)
      * [ Improved Dynamic Discovery ](../Advanced/Improved-Dynamic-Discovery.html)
      * [ Recording a bag from a node (C++) ](../Advanced/Recording-A-Bag-From-Your-Own-Node-CPP.html)
      * [ Recording a bag from a node (Python) ](../Advanced/Recording-A-Bag-From-Your-Own-Node-Py.html)
      * [ Reading from a bag file (C++) ](../Advanced/Reading-From-A-Bag-File-CPP.html)
      * [ How to use ros2_tracing to trace and analyze an application ](../Advanced/ROS2-Tracing-Trace-and-Analyze.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)
          * [ Setting up a Reset Handler ](../Advanced/Simulators/Webots/Simulation-Reset-Handler.html)
          * [ The Ros2Supervisor Node ](../Advanced/Simulators/Webots/Simulation-Supervisor.html)
        * [ Gazebo ](../Advanced/Simulators/Gazebo/Simulation-Gazebo.html)
          * [ Setting up a robot simulation (Gazebo) ](../Advanced/Simulators/Gazebo/Gazebo.html)
      * [ Security ](../Advanced/Security/Security-Main.html)
        * [ Setting up security ](../Advanced/Security/Introducing-ros2-security.html)
        * [ Understanding the security keystore ](../Advanced/Security/The-Keystore.html)
        * [ Ensuring security across machines ](../Advanced/Security/Security-on-Two.html)
        * [ Examining network traffic ](../Advanced/Security/Examine-Traffic.html)
        * [ Setting access controls ](../Advanced/Security/Access-Controls.html)
        * [ Deployment Guidelines ](../Advanced/Security/Deployment-Guidelines.html)
    * [ Demos ](../Demos.html)
      * [ Using quality-of-service settings for lossy networks ](../Demos/Quality-of-Service.html)
      * [ Managing nodes with managed lifecycles ](../Demos/Managed-Nodes.html)
      * [ Setting up efficient intra-process communication ](../Demos/Intra-Process-Communication.html)
      * [ Recording and playing back data with ` rosbag  ` using the ROS 1 bridge ](../Demos/Rosbag-with-ROS1-Bridge.html)
      * [ Understanding real-time programming ](../Demos/Real-Time-Programming.html)
      * [ Experimenting with a dummy robot ](../Demos/dummy-robot-demo.html)
      * [ Logging ](../Demos/Logging-and-logger-configuration.html)
      * [ Creating a content filtering subscription ](../Demos/Content-Filtering-Subscription.html)
      * [ Configure service introspection ](../Demos/Service-Introspection.html)
    * [ Miscellaneous ](../Miscellaneous.html)
      * [ Deploying on IBM Cloud Kubernetes [community-contributed] ](../Miscellaneous/Deploying-ROS-2-on-IBM-Cloud.html)
      * [ Using Eclipse Oxygen with ` rviz2  ` [community-contributed] ](../Miscellaneous/Eclipse-Oxygen-with-ROS-2-and-rviz2.html)
      * [ Building a real-time Linux kernel [community-contributed] ](../Miscellaneous/Building-Realtime-rt_preempt-kernel-for-ROS-2.html)
      * [ Building a package with Eclipse 2021-06 ](../Miscellaneous/Building-ROS2-Package-with-eclipse-2021-06.html)


Use add_on_set_parameters_callback instead. With this method, only one callback can be set at a time. The callback that was previously set by this method is returned or ` nullptr ` if no callback was previously set.


If setting a parameter fails due to not being declared, then the parameters
which have already been set will stay set, and no attempt will be made to set
the parameters which come after.


The name of the node.


     [in]  |  topic_name  |  the topic_name on which to count the subscribers.
---|---|---

Returns


Like [ get_parameters()
](classrclcpp_1_1Node.html#a25890d01a2cd47ce99af887f556c529b "Return the
parameters by the given parameter names.") , this method may throw the [
rclcpp::exceptions::ParameterNotDeclaredException
](classrclcpp_1_1exceptions_1_1ParameterNotDeclaredException.html "Thrown if
parameter is not declared, e.g. either set or get was called without first
declaring.") exception if any of the requested parameters have not been
declared and undeclared parameters are not allowed.


##  How do services work?


##  ◆  add_on_set_parameters_callback()


For example, consider:


|  [ RCLCPP_ACTION_PUBLIC
](visibility__control_8hpp.html#a736fe60d4de4417a213ed34ba1926048) size_t
rclcpp_action::ServerBase::get_number_of_ready_clients  |  (  |  |  )  |
---|---|---|---|---
override  virtual

Return the number of service clients used to implement an action server


Note that the callback is called when [ declare_parameter()
](classrclcpp_1_1Node.html#a095ea977b26e7464d9371efea5f36c42 "Declare and
initialize a parameter, return the effective value.") and its variants are
called, and so you cannot assume the parameter has been set before this
callback, so when checking a new value against the existing one, you must
account for the case where the parameter is not yet set.


    # Tell compiler that we require the rclcpp and std_srvs packages
    find_package(rclcpp REQUIRED)
    find_package(std_srvs REQUIRED)

    # Add the nodes as executables with their dependencies
    add_executable(motor_node src/motor_node.cpp)
    ament_target_dependencies(motor_node
        rclcpp std_srvs)
    add_executable(diagnostics_node src/diagnostics_node.cpp)
    ament_target_dependencies(diagnostics_node
        rclcpp std_srvs)

    # Install the executables so 'ros2 run' can find them
    install(TARGETS
        motor_node
        diagnostics_node
        DESTINATION lib/${PROJECT_NAME})


##  ◆  get_node_waitables_interface()


  /// \internal
  virtual
  std::shared_ptr<void>
  create_goal_response() const = 0;
  /// \internal
  RCLCPP_ACTION_PUBLIC
  virtual
  void
  handle_goal_response(
    const rmw_request_id_t & response_header,
    std::shared_ptr<void> goal_response);
  /// \internal
  virtual
  std::shared_ptr<void>
  create_result_response() const = 0;
  /// \internal
  RCLCPP_ACTION_PUBLIC
  virtual
  void
  handle_result_response(
    const rmw_request_id_t & response_header,
    std::shared_ptr<void> result_response);
  /// \internal
  virtual
  std::shared_ptr<void>
  create_cancel_response() const = 0;
  /// \internal
  RCLCPP_ACTION_PUBLIC
  virtual
  void
  handle_cancel_response(
    const rmw_request_id_t & response_header,
    std::shared_ptr<void> cancel_response);
  /// \internal
  virtual
  std::shared_ptr<void>
  create_feedback_message() const = 0;
  /// \internal
  virtual
  void


|  virtual [ RCLCPP_ACTION_PUBLIC
](visibility__control_8hpp.html#a736fe60d4de4417a213ed34ba1926048) void
rclcpp_action::ServerBase::call_goal_accepted_callback  |  (  |  [
std::shared_ptr ](http://en.cppreference.com/w/cpp/memory/shared_ptr.html) < [
rcl_action_goal_handle_t
](http://docs.ros2.org/foxy/api/rcl_action/structrcl__action__goal__handle__t.html)
> |  _rcl_goal_handle_ ,
---|---|---|---
|  |  [ GoalUUID
](namespacerclcpp__action.html#a67daf44a45003173e42ccc612fcb052b) |  _uuid_ ,
|  |  [ std::shared_ptr
](http://en.cppreference.com/w/cpp/memory/shared_ptr.html) < void > |
_goal_request_message_
|  )  |  |
protected  pure virtual

Call user callback to inform them a goal has been accepted.


##  ◆  execute()


Exceptions