   * can only be resolved after the creation of the client, and it
   * depends on the underlying rmw implementation.
   * If the underlying setting in use can't be represented in ROS terms,
   * it will be set to RMW_QOS_POLICY_*_UNKNOWN.
   * May throw runtime_error when an unexpected error occurs.
   *
   * \return The actual request publsher qos settings.
   * \throws std::runtime_error if failed to get qos settings
   */
  RCLCPP_PUBLIC
  rclcpp::QoS
  get_request_publisher_actual_qos() const;
  /// Get the actual response subscription QoS settings, after the defaults have been determined.
  /**
   * The actual configuration applied when using RMW_QOS_POLICY_*_SYSTEM_DEFAULT
   * can only be resolved after the creation of the client, and it
   * depends on the underlying rmw implementation.
   * If the underlying setting in use can't be represented in ROS terms,
   * it will be set to RMW_QOS_POLICY_*_UNKNOWN.
   * May throw runtime_error when an unexpected error occurs.
   *
   * \return The actual response subscription qos settings.
   * \throws std::runtime_error if failed to get qos settings
   */
  RCLCPP_PUBLIC
  rclcpp::QoS
  get_response_subscription_actual_qos() const;
  /// Set a callback to be called when each new response is received.
  /**
   * The callback receives a size_t which is the number of responses received
   * since the last time this callback was called.
   * Normally this is 1, but can be > 1 if responses were received before any
   * callback was set.
   *
   * Since this callback is called from the middleware, you should aim to make
   * it fast and not blocking.
   * If you need to do a lot of work or wait for some other event, you should
   * spin it off to another thread, otherwise you risk blocking the middleware.
   *
   * Calling it again will clear any previously set callback.


[ std::vector ](http://en.cppreference.com/w/cpp/container/vector.html)
<rcl_interfaces::msg::ParameterDescriptor> rclcpp::Node::describe_parameters
|  (  |  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.


|  [ RCLCPP_ACTION_PUBLIC
](visibility__control_8hpp.html#a736fe60d4de4417a213ed34ba1926048) bool
rclcpp_action::ServerBase::is_ready  |  (  |  [ rcl_wait_set_t
](http://docs.ros2.org/foxy/api/rcl/structrcl__wait__set__t.html) *  |  |  )
|
---|---|---|---|---|---
override  virtual

Return true if any entity belonging to the action server is ready to be
executed.


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

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

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


August 4, 2022  ·  2 min  read


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


This method will result in any callback registered with
add_on_set_parameters_callback to be called, just one time. If the callback
prevents the parameters from being set, then it will be reflected in the
SetParametersResult which is returned, but no exception will be thrown.


Collaboration diagram for rclcpp::Node:


sub_node1->get_effective_namespace();  // -> "/my_ns/a"


     [ std::runtime_error ](http://en.cppreference.com/w/cpp/error/runtime_error.html) |  anything that rcl_error can throw
---|---

##  ◆  get_service_names_and_types_by_node()


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

##  ◆  ServerBase()


[ rclcpp::QoS ](classrclcpp_1_1QoS.html)


Hello,
this is an old topic, but i am currently still looking for a solution for a
generic service client (i don’t need a generic server, only client).
Apparently [ @rokel_race ](/u/rokel_race) created a solution for this, but i
am not sure that it is released somewhere. Maybe someone else has solved this
in the meantime and published a working implementation of a generic service
client for rclcpp?


#  1 Create a package  ï

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

Navigate into the ` ros2_ws  ` directory created in a [ previous tutorial
](Creating-A-Workspace/Creating-A-Workspace.html#new-directory) .

Recall that packages should be created in the ` src  ` directory, not the root
of the workspace. Navigate into ` ros2_ws/src  ` and create a new package:

    ros2 pkg create --build-type ament_cmake --license Apache-2.0 cpp_srvcli --dependencies rclcpp example_interfaces

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

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

    int64 a
    int64 b
    ---
    int64 sum

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


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


Internally, this class is responsible for interfacing with the ` rcl_action `
API.


pub = node->create_publisher<MsgT>(  "chatter"  , QoS(KeepAll()));


true if the parameter was set, false otherwise.


See also


If the parameter has not been declared, it will not attempt to coerce the
value into the requested type, as it is known that the type is not set.


        };

        send_goal_options.result_callback = [this](const GoalHandleFibonacci::WrappedResult & result)
        {
          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);
      }

This function does the following:

  1. Cancels the timer (so it is only called once).

  2. Waits for the action server to come up.

  3. Instantiates a new ` Fibonacci::Goal  ` .

  4. Sets the response, feedback, and result callbacks.

  5. Sends the goal to the server.


Tasks  ï


  2.2 Add executable  ï

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

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

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

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

You could build your package now, source the local setup files, and run it,
but letâs create the client node first so you can see the full system at
work.


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


const char* rclcpp::Node::get_name  |  (  |  |  )  |  const
---|---|---|---|---

Get the name of the node.


Parameters


Catch our latest news and features, sent directly to your inbox.


        [goal_handle, this](std::shared_ptr<void> response) mutable
        {
          // Wrap the response in a struct with the fields a user cares about
          WrappedResult wrapped_result;
          using GoalResultResponse = typename ActionT::Impl::GetResultService::Response;
          auto result_response = std::static_pointer_cast<GoalResultResponse>(response);
          wrapped_result.result = std::make_shared<typename ActionT::Result>();
          *wrapped_result.result = result_response->result;
          wrapped_result.goal_id = goal_handle->get_goal_id();
          wrapped_result.code = static_cast<ResultCode>(result_response->status);
          goal_handle->set_result(wrapped_result);
          std::lock_guard<std::mutex> lock(goal_handles_mutex_);
          goal_handles_.erase(goal_handle->get_goal_id());
        });
    } catch (rclcpp::exceptions::RCLError & ex) {
      // This will cause an exception when the user tries to access the result
      goal_handle->invalidate(exceptions::UnawareGoalHandleError(ex.message));
    }
  }
  /// \internal
  std::shared_future<typename CancelResponse::SharedPtr>
  async_cancel(
    typename CancelRequest::SharedPtr cancel_request,
    CancelCallback cancel_callback = nullptr)
  {
    // Put promise in the heap to move it around.
    auto promise = std::make_shared<std::promise<typename CancelResponse::SharedPtr>>();
    std::shared_future<typename CancelResponse::SharedPtr> future(promise->get_future());
    this->send_cancel_request(
      std::static_pointer_cast<void>(cancel_request),
      [cancel_callback, promise](std::shared_ptr<void> response) mutable
      {
        auto cancel_response = std::static_pointer_cast<CancelResponse>(response);
        promise->set_value(cancel_response);
        if (cancel_callback) {
          cancel_callback(cancel_response);
        }
      });
    return future;
  }


Shared pointer to the created publisher.


[ Creating ROS 2 Actions  ](/blog/creating-ros2-actions)


When ` motor_node ` executes and the server activates, it performs its checks.
In this case, a warning shows because we don't have any motors – there is no
possible way for the checks to succeed!


Public Member Functions  |  Protected Member Functions  | [ List of all
members ](classrclcpp__action_1_1ServerBase-members.html)


##  Ready to try Foxglove?


The name and type in the given rcl_interfaces::msg::ParameterDescriptor are
ignored, and should be specified using the name argument to this function and
the default value's type instead.


auto rclcpp::Node::declare_parameter  |  (  |  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.


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


        // Check if goal is done
        if (rclcpp::ok()) {
          result->sequence = sequence;
          goal_handle->succeed(result);
          RCLCPP_INFO(this->get_logger(), "Goal succeeded");
        }
      };

This work thread processes one sequence number of the Fibonacci sequence every
second, publishing a feedback update for each step. When it has finished
processing, it marks the ` goal_handle  ` as succeeded, and quits.

We now have a fully functioning action server. Letâs get it built and
running.


For example, consider:


template<typename ParameterT >


  {
    return this->future.wait_for(timeout_duration);
  }
  /// See std::future::wait_until().
  template<class Clock, class Duration>
  std::future_status wait_until(
    const std::chrono::time_point<Clock, Duration> & timeout_time) const
  {
    return this->future.wait_until(timeout_time);
  }
  // Rule of five, we could use the rule of zero here, but better be explicit as some of the
  // methods are deleted.
  /// Move constructor.
  FutureAndRequestId(FutureAndRequestId && other) noexcept = default;
  /// Deleted copy constructor, each instance is a unique owner of the future.
  FutureAndRequestId(const FutureAndRequestId & other) = delete;
  /// Move assignment.
  FutureAndRequestId & operator=(FutureAndRequestId && other) noexcept = default;
  /// Deleted copy assignment, each instance is a unique owner of the future.
  FutureAndRequestId & operator=(const FutureAndRequestId & other) = delete;
  /// Destructor.
  ~FutureAndRequestId() = default;
};
}  // namespace detail
namespace node_interfaces
{
class NodeBaseInterface;
}  // namespace node_interfaces
class ClientBase
{
public:
  RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(ClientBase)
  RCLCPP_PUBLIC
  ClientBase(
    rclcpp::node_interfaces::NodeBaseInterface * node_base,
    rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph);
  RCLCPP_PUBLIC
  virtual ~ClientBase() = default;
  /// Take the next response for this client as a type erased pointer.
  /**


rcl_interfaces::msg::SetParametersResult


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


#  [ ROS2 C++ Generic Action / Service Client ](/t/ros2-c-generic-action-
service-client/14671)


a map of existing service names to list of service types.


Parameters are set in the order they are given within the input vector.


The requested parameter inside of a rclcpp parameter object.


The principles are the same, just using the service type support instead of
the message type support. One oddity I did find is that I had to use an rmw-
specific typesupport library ( ` rosidl_typesupport_fastrtps_cpp ` ) to get
the service typesupport for a given type, which wasn’t necessary for messages.


###  Subscribe to our newsletter


**Definition:** qos.hpp:59


[ std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) < [
rclcpp::Parameter ](classrclcpp_1_1Parameter.html) >
rclcpp::Node::get_parameters  |  (  |  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.


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


      // Client sends its asynchronous request
      auto result = client->async_send_request(request);
      // Wait for the result
      if (rclcpp::spin_until_future_complete(node, result) == rclcpp::FutureReturnCode::SUCCESS) {
        // Get the response's success field to see if all checks passed
        if (result.get()->success) {
          RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "The checks were successful!");
        } else {
          RCLCPP_WARN(rclcpp::get_logger("rclcpp"), "The checks were not successful: %s", result.get()->message.c_str());
        }
      } else {
        RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Failed to call service 'checks'");
      }

      // Shut down rclcpp and client node
      rclcpp::shutdown();
      return 0;
    }


An empty string for the prefix will match all parameters.


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

Returns


     [in]  |  sub_namespace  |  sub-namespace of the sub-node.
---|---|---

Returns


Identical to the non-templated version of this method, except that when
assigning the output argument called "parameter", this method will attempt to
coerce the parameter value into the type requested by the given template
argument, which may fail and throw an exception.


      #define CUSTOM_ACTION_CPP_EXPORT __attribute__ ((visibility("default")))
      #define CUSTOM_ACTION_CPP_IMPORT
      #if __GNUC__ >= 4
        #define CUSTOM_ACTION_CPP_PUBLIC __attribute__ ((visibility("default")))
        #define CUSTOM_ACTION_CPP_LOCAL  __attribute__ ((visibility("hidden")))
      #else
        #define CUSTOM_ACTION_CPP_PUBLIC
        #define CUSTOM_ACTION_CPP_LOCAL
      #endif
      #define CUSTOM_ACTION_CPP_PUBLIC_TYPE
    #endif

    #ifdef __cplusplus
    }
    #endif

    #endif  // CUSTOM_ACTION_CPP__VISIBILITY_CONTROL_H_


If the parameter was not declared, then the output argument for this method
which is called "parameter" will not be assigned a value. If the parameter was
declared, and therefore has a value, then it is assigned into the "parameter"
argument of this method.


#  3 Write the client node  ï

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

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

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

    using namespace std::chrono_literals;

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

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

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

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

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


[ rclcpp::Logger ](classrclcpp_1_1Logger.html) rclcpp::Node::get_logger  |  (
|  |  )  |  const
---|---|---|---|---

Get the logger of the node.


#  1 Creating the custom_action_cpp package  ï

As we saw in the [ Creating a package  ](../../Beginner-Client-
Libraries/Creating-Your-First-ROS2-Package.html) tutorial, we need to create a
new package to hold our C++ and supporting code.


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

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


The returned reference will remain valid until the parameter is undeclared.


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

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


Parameters


##  ◆  is_ready()


true if the parameter was previously declared, otherwise false.


      // Wait for the service to be activated
      while (!client->wait_for_service(1s)) {
        // If ROS is shutdown before the service is activated, show this error
        if (!rclcpp::ok()) {
          RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");
          return 0;
        }
        // Print in the screen some information so the user knows what is happening
        RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "service not available, waiting again...");
      }


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

Return the number of timers used to implement an action server


rclcpp::Event::SharedPtr  |  [ get_graph_event
](classrclcpp_1_1Node.html#a9e5851844ecb1794503b8fc0f9f5c898) ()
|  Return a graph event, which will be set anytime a graph change occurs. [
More... ](classrclcpp_1_1Node.html#a9e5851844ecb1794503b8fc0f9f5c898)

void  |  [ wait_for_graph_change
](classrclcpp_1_1Node.html#ab72e2c59951c08c515fd597bfc9e8cfd)
(rclcpp::Event::SharedPtr event, [ std::chrono::nanoseconds
](http://en.cppreference.com/w/cpp/chrono/duration.html) timeout)
|  Wait for a graph event to occur by waiting on an [ Event
](classrclcpp_1_1Event.html) to become set. [ More...
](classrclcpp_1_1Node.html#ab72e2c59951c08c515fd597bfc9e8cfd)

rclcpp::Clock::SharedPtr  |  [ get_clock
](classrclcpp_1_1Node.html#aec0332887ae90caed727e5025cb62195) ()
|  Get a clock as a non-const shared pointer which is managed by the node. [
More... ](classrclcpp_1_1Node.html#aec0332887ae90caed727e5025cb62195)

rclcpp::Clock::ConstSharedPtr  |  [ get_clock
](classrclcpp_1_1Node.html#a2c725f0bb2e36943ca5c0255ad0bc0cf) () const
|  Get a clock as a const shared pointer which is managed by the node. [
More... ](classrclcpp_1_1Node.html#a2c725f0bb2e36943ca5c0255ad0bc0cf)

[ Time ](classrclcpp_1_1Time.html) |  [ now
](classrclcpp_1_1Node.html#a1db9cec1af19a994b3f1dad2059d2707) () const
|  Returns current time from the time source specified by clock_type. [
More... ](classrclcpp_1_1Node.html#a1db9cec1af19a994b3f1dad2059d2707)

rclcpp::node_interfaces::NodeBaseInterface::SharedPtr  |  [
get_node_base_interface
](classrclcpp_1_1Node.html#a37e5b136ef0a29853e01d5cecb8e4690) ()
|  Return the [ Node ](classrclcpp_1_1Node.html "Node is the single point of
entry for creating publishers and subscribers.") 's internal NodeBaseInterface
implementation. [ More...
](classrclcpp_1_1Node.html#a37e5b136ef0a29853e01d5cecb8e4690)

rclcpp::node_interfaces::NodeClockInterface::SharedPtr  |  [
get_node_clock_interface
](classrclcpp_1_1Node.html#a5495b9faae261feed33d8d8828840709) ()
|  Return the [ Node ](classrclcpp_1_1Node.html "Node is the single point of


##  ◆  get_node_names()


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


Made with  by [ Foxglove ](/about)


Email address


Continue playing around with running your nodes to see how they behave. For
example, what would you expect to happen if you run the server node before the
client?


[ rclcpp ](https://discourse.ros.org/tag/rclcpp) , [ ros2
](https://discourse.ros.org/tag/ros2)


sub_node2->get_effective_namespace();  // -> "/my_ns/a/b"


You can see that the SetParametersResult is a boolean flag for success and an
optional reason that can be used in error reporting when it fails.


##  Member Typedef Documentation


You will need two terminal windows – remember to source ` install/setup.bash `
in each one before running any ROS 2 command:


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_result_request  |  (  |  |  )  |
---|---|---|---|---
protected  pure virtual

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


     [ get_namespace() ](classrclcpp_1_1Node.html#a7be04e55e2934e05df992b188d9dce6d "Get the namespace of the node.")
     [ get_effective_namespace() ](classrclcpp_1_1Node.html#afe4790bba38942b795d24b6ccb3e9c5a "Return the effective namespace that is used when creating entities.")


##  ◆  get_node_parameters_interface()


Now that we’ve discussed how when you might use ROS services, let’s dive into
some actual code.


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

##  ◆  get_publishers_info_by_topic()


Set the given parameter and then return result of the set action.


  handle_feedback_message(std::shared_ptr<void> message) = 0;
  /// \internal
  virtual
  std::shared_ptr<void>
  create_status_message() const = 0;
  /// \internal
  virtual
  void
  handle_status_message(std::shared_ptr<void> message) = 0;
  // End API for communication between ClientBase and Client<>
  // ---------------------------------------------------------
  /// \internal
  /// Set a callback to be called when the specified entity is ready
  RCLCPP_ACTION_PUBLIC
  void
  set_on_ready_callback(
    EntityType entity_type,
    rcl_event_callback_t callback,
    const void * user_data);
  // Mutex to protect the callbacks storage.
  std::recursive_mutex listener_mutex_;
  // Storage for std::function callbacks to keep them in scope
  std::unordered_map<EntityType, std::function<void(size_t)>> entity_type_to_on_ready_callback_;
private:
  std::unique_ptr<ClientBaseImpl> pimpl_;
  /// Set a std::function callback to be called when the specified entity is ready
  RCLCPP_ACTION_PUBLIC
  void
  set_callback_to_entity(
    EntityType entity_type,
    std::function<void(size_t, int)> callback);
  bool on_ready_callback_set_{false};
};
/// Action Client
/**
 * This class creates an action client.
 *
 * To create an instance of an action client use `rclcpp_action::create_client()`.
 *
 * Internally, this class is responsible for:


Parameters


See also


Topic  |  |  Replies  |  Views  |  Activity
---|---|---|---|---
[ Rust support for embedded devices ](https://discourse.ros.org/t/rust-
support-for-embedded-devices/22263)


[ OnParametersSetCallbackType
](classrclcpp_1_1Node.html#ab403fecdb5ec2eb9f88e3eb7ae6f6d0c)
rclcpp::Node::set_on_parameters_set_callback  |  (  |  [
rclcpp::Node::OnParametersSetCallbackType
](classrclcpp_1_1Node.html#ab403fecdb5ec2eb9f88e3eb7ae6f6d0c) |  _callback_ |
)  |
---|---|---|---|---|---

Register a callback to be called anytime a parameter is about to be changed.


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

Return the number of guard conditions used to implement an action server


###  Writing a server node


If undeclared parameters are allowed, then a default initialized descriptor
will be returned for the undeclared parameter's descriptor.


Exceptions


A const reference to the value of the parameter.


If no parameters with the prefix are found, then the output parameter "values"
will be unchanged and false will be returned. Otherwise, the parameter names
and values will be stored in the map and true will be returned to indicate
"values" was mutated.


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

##  ◆  set_parameters()


rclcpp::node_interfaces::NodeGraphInterface::SharedPtr
rclcpp::Node::get_node_graph_interface  |  (  |  |  )  |
---|---|---|---|---

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


##  ◆  create_goal_request()


  void
  execute(std::shared_ptr<void> & data) override;
  /// \internal
  /// Set a callback to be called when action client entities have an event
  /**
   * The callback receives a size_t which is the number of messages received
   * since the last time this callback was called.
   * Normally this is 1, but can be > 1 if messages were received before any
   * callback was set.
   *
   * The callback also receives an int identifier argument, which identifies
   * the action client entity which is ready.
   * This implies that the provided callback can use the identifier to behave
   * differently depending on which entity triggered the waitable to become ready.
   *
   * Calling it again will clear any previously set callback.
   *
   * An exception will be thrown if the callback is not callable.
   *
   * This function is thread-safe.
   *
   * If you want more information available in the callback, like the subscription
   * or other information, you may use a lambda with captures or std::bind.
   *
   * \param[in] callback functor to be called when a new message is received.
   */
  RCLCPP_ACTION_PUBLIC
  void
  set_on_ready_callback(std::function<void(size_t, int)> callback) override;
  /// Unset the callback registered for new events, if any.
  RCLCPP_ACTION_PUBLIC
  void
  clear_on_ready_callback() override;
  // End Waitables API
  // -----------------
protected:
  RCLCPP_ACTION_PUBLIC
  ClientBase(
    rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base,
    rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph,


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


The first terminal will contain the client ` diagnostics_node ` :


###  Compiling the package


    int main(int argc, char **argv) {
      // Initiate the rclcpp library
      rclcpp::init(argc, argv);

      // Create a shared pointer to a Node type and name it "motor_node"
      std::shared_ptr<rclcpp::Node> node=rclcpp::Node::make_shared("motor_node");

      // Create the "checks" service with a doChecks callback
      rclcpp::Service<std_srvs::srv::Trigger>::SharedPtr service =
        node->create_service<std_srvs::srv::Trigger>("checks", &doChecks);

      RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Ready to check motors");

      // Spin the node until it's terminated
      rclcpp::spin(node);
      rclcpp::shutdown();
    }


|  [ RCLCPP_ACTION_PUBLIC
](visibility__control_8hpp.html#a736fe60d4de4417a213ed34ba1926048) void
rclcpp_action::ServerBase::publish_status  |  (  |  |  )  |
---|---|---|---|---
protected

##  ◆  notify_goal_terminal_state()


      * [ 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)
  * [ Intermediate ](../../Intermediate.html)
  * Writing an action server and client (C++)
  * [ Edit on GitHub ](https://github.com/ros2/ros2_documentation/blob/rolling/source/Tutorials/Intermediate/Writing-an-Action-Server-Client/Cpp.rst)

* * *

**You're reading the documentation for a development version. For the latest
released version, please have a look at[ Iron
](../../../../iron/Tutorials/Intermediate/Writing-an-Action-Server-
Client/Cpp.html) . **

#  Writing an action server and client (C++)  ï

**Goal:** Implement an action server and client in C++.


  std::shared_ptr<rcl_node_t> node_handle_;
  std::shared_ptr<rclcpp::Context> context_;
  rclcpp::Logger node_logger_;
  std::recursive_mutex callback_mutex_;
  // It is important to declare on_new_response_callback_ before
  // client_handle_, so on destruction the client is
  // destroyed first. Otherwise, the rmw client callback
  // would point briefly to a destroyed function.
  std::function<void(size_t)> on_new_response_callback_{nullptr};
  // Declare client_handle_ after callback
  std::shared_ptr<rcl_client_t> client_handle_;
  std::atomic<bool> in_use_by_wait_set_{false};
};
template<typename ServiceT>
class Client : public ClientBase
{
public:
  using Request = typename ServiceT::Request;
  using Response = typename ServiceT::Response;
  using SharedRequest = typename ServiceT::Request::SharedPtr;
  using SharedResponse = typename ServiceT::Response::SharedPtr;
  using Promise = std::promise<SharedResponse>;
  using PromiseWithRequest = std::promise<std::pair<SharedRequest, SharedResponse>>;
  using SharedPromise = std::shared_ptr<Promise>;
  using SharedPromiseWithRequest = std::shared_ptr<PromiseWithRequest>;
  using Future = std::future<SharedResponse>;
  using SharedFuture = std::shared_future<SharedResponse>;
  using SharedFutureWithRequest = std::shared_future<std::pair<SharedRequest, SharedResponse>>;
  using CallbackType = std::function<void (SharedFuture)>;
  using CallbackWithRequestType = std::function<void (SharedFutureWithRequest)>;
  RCLCPP_SMART_PTR_DEFINITIONS(Client)
  /// A convenient Client::Future and request id pair.
  /**
   * Public members:
   * - future: a std::future<SharedResponse>.
   * - request_id: the request id associated with the future.
   *
   * All the other methods are equivalent to the ones std::future provides.
   */
  struct FutureAndRequestId


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

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


[ Next Generation ROS  ](/c/ng-ros/25)


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


` #include < [ server.hpp ](server_8hpp_source.html) > `


   *
   * An exception will be thrown if the callback is not callable.
   *
   * This function is thread-safe.
   *
   * If you want more information available in the callback, like the client
   * or other information, you may use a lambda with captures or std::bind.
   *
   * \sa rmw_client_set_on_new_response_callback
   * \sa rcl_client_set_on_new_response_callback
   *
   * \param[in] callback functor to be called when a new response is received
   */
  void
  set_on_new_response_callback(std::function<void(size_t)> callback)
  {
    if (!callback) {
      throw std::invalid_argument(
              "The callback passed to set_on_new_response_callback "
              "is not callable.");
    }
    auto new_callback =
      [callback, this](size_t number_of_responses) {
        try {
          callback(number_of_responses);
        } catch (const std::exception & exception) {
          RCLCPP_ERROR_STREAM(
            node_logger_,
            "rclcpp::ClientBase@" << this <<
              " caught " << rmw::impl::cpp::demangle(exception) <<
              " exception in user-provided callback for the 'on new response' callback: " <<
              exception.what());
        } catch (...) {
          RCLCPP_ERROR_STREAM(
            node_logger_,
            "rclcpp::ClientBase@" << this <<
              " caught unhandled exception in user-provided callback " <<
              "for the 'on new response' callback");
        }
      };


  * Spins the node, making the service available.

        rclcpp::spin(node);


Supposing that ` scoped_callback ` was the only owner.


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

Set one or more parameters, one at a time.


[ Announcing Private Foxglove Studio Extensions for Your Organization
](/blog/announcing-private-foxglove-studio-extensions-for-your-organization)


  Related content  ï

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

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

* * *

© Copyright 2024, Open Robotics.

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

Other Versions  v: rolling

Releases

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

In Development

     [ Rolling ](Writing-A-Simple-Cpp-Service-And-Client.html)


Resetting or letting the smart pointer go out of scope unregisters the
callback. ` remove_on_set_parameters_callback ` can also be used.


See the non-templated [ declare_parameter()
](classrclcpp_1_1Node.html#a095ea977b26e7464d9371efea5f36c42 "Declare and
initialize a parameter, return the effective value.") on this class for
details.


ROS Resources: [ ROS Homepage ](http://ros.org/) | [ Media and Trademarks
](https://www.ros.org/blog/media/) | [ Documentation ](http://docs.ros.org/) |
[ ROS Index ](https://index.ros.org/) | [ How to Get Help
](http://wiki.ros.org/Support) | [ Q&A Help Site
](https://robotics.stackexchange.com/) | [ Discussion Forum
](http://discourse.ros.org/) | [ Service Status ](http://status.ros.org/)
---

[ ROS Discourse ](/)


##  ◆  get_number_of_ready_timers()


#  2 Write the service node  ï

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

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

    #include <memory>

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

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

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

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

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

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


Let's use the [ ` Trigger.srv `
](http://docs.ros.org/en/api/std_srvs/html/srv/Trigger.html) we saw before.
Remember that this service definition contains no field in the request. The
client is not sending any data to the server when it makes this request - it
is just a trigger. The server, however, will respond with ` success ` and `
message ` fields.


result.successful =  true  ;


The constructor for the ` FibonacciActionServer  ` class initializes the node
name as ` fibonacci_action_server  ` :

      explicit FibonacciActionServer(const rclcpp::NodeOptions & options = rclcpp::NodeOptions())
      : Node("fibonacci_action_server", options)

The constructor also instantiates a new action server:

          loop_rate.sleep();
        }

        // Check if goal is done
        if (rclcpp::ok()) {

An action server requires 6 things:

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

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

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

  4. A callback function for handling goals: ` handle_goal  `

  5. A callback function for handling cancellation: ` handle_cancel  ` .

  6. A callback function for handling goal accept: ` handle_accept  ` .

The implementation of the various callbacks is done with [lambda expressions](
[ https://en.cppreference.com/w/cpp/language/lambda
](https://en.cppreference.com/w/cpp/language/lambda) ) within the constructor.
Note that all of the callbacks need to return quickly, otherwise we risk
starving the executor.


` #include < [ node.hpp ](node_8hpp_source.html) > `


entry for creating publishers and subscribers.") 's internal
NodeClockInterface implementation. [ More...
](classrclcpp_1_1Node.html#a5495b9faae261feed33d8d8828840709)

rclcpp::node_interfaces::NodeGraphInterface::SharedPtr  |  [
get_node_graph_interface
](classrclcpp_1_1Node.html#a2378e5b1486e58afdead52fa14928c2b) ()
|  Return the [ Node ](classrclcpp_1_1Node.html "Node is the single point of
entry for creating publishers and subscribers.") 's internal
NodeGraphInterface implementation. [ More...
](classrclcpp_1_1Node.html#a2378e5b1486e58afdead52fa14928c2b)

rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr  |  [
get_node_logging_interface
](classrclcpp_1_1Node.html#af05394f5147dd263af2df15a99f5a4bb) ()
|  Return the [ Node ](classrclcpp_1_1Node.html "Node is the single point of
entry for creating publishers and subscribers.") 's internal
NodeLoggingInterface implementation. [ More...
](classrclcpp_1_1Node.html#af05394f5147dd263af2df15a99f5a4bb)

rclcpp::node_interfaces::NodeTimersInterface::SharedPtr  |  [
get_node_timers_interface
](classrclcpp_1_1Node.html#aa28869f473b562a08aa581fc7deae867) ()
|  Return the [ Node ](classrclcpp_1_1Node.html "Node is the single point of
entry for creating publishers and subscribers.") 's internal
NodeTimersInterface implementation. [ More...
](classrclcpp_1_1Node.html#aa28869f473b562a08aa581fc7deae867)

rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr  |  [
get_node_topics_interface
](classrclcpp_1_1Node.html#a5ae76be5bac60aea82486a9b4c6b2ff5) ()
|  Return the [ Node ](classrclcpp_1_1Node.html "Node is the single point of
entry for creating publishers and subscribers.") 's internal
NodeTopicsInterface implementation. [ More...
](classrclcpp_1_1Node.html#a5ae76be5bac60aea82486a9b4c6b2ff5)

rclcpp::node_interfaces::NodeServicesInterface::SharedPtr  |  [
get_node_services_interface
](classrclcpp_1_1Node.html#a588cb7990fd658e58c532d65e4872df3) ()
|  Return the [ Node ](classrclcpp_1_1Node.html "Node is the single point of


  /**
   * \return `true` if the service is ready, `false` otherwise
   */
  RCLCPP_PUBLIC
  bool
  service_is_ready() const;
  /// Wait for a service to be ready.
  /**
   * \param timeout maximum time to wait
   * \return `true` if the service is ready and the timeout is not over, `false` otherwise
   */
  template<typename RepT = int64_t, typename RatioT = std::milli>
  bool
  wait_for_service(
    std::chrono::duration<RepT, RatioT> timeout = std::chrono::duration<RepT, RatioT>(-1))
  {
    return wait_for_service_nanoseconds(
      std::chrono::duration_cast<std::chrono::nanoseconds>(timeout)
    );
  }
  virtual std::shared_ptr<void> create_response() = 0;
  virtual std::shared_ptr<rmw_request_id_t> create_request_header() = 0;
  virtual void handle_response(
    std::shared_ptr<rmw_request_id_t> request_header, std::shared_ptr<void> response) = 0;
  /// Exchange the "in use by wait set" state for this client.
  /**
   * This is used to ensure this client is not used by multiple
   * wait sets at the same time.
   *
   * \param[in] in_use_state the new state to exchange into the state, true
   *   indicates it is now in use by a wait set, and false is that it is no
   *   longer in use by a wait set.
   * \returns the previous state.
   */
  RCLCPP_PUBLIC
  bool
  exchange_in_use_by_wait_set_state(bool in_use_state);
  /// Get the actual request publsher QoS settings, after the defaults have been determined.
  /**
   * The actual configuration applied when using RMW_QOS_POLICY_*_SYSTEM_DEFAULT


     [ 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_parameter()  [2/2]


  1.1 Update ` package.xml  ` ï

Because you used the ` --dependencies  ` option during package creation, you
donât have to manually add dependencies to ` package.xml  ` or `
CMakeLists.txt  ` .

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

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


[ std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) < [
rclcpp::TopicEndpointInfo ](classrclcpp_1_1TopicEndpointInfo.html) >
rclcpp::Node::get_subscriptions_info_by_topic  |  (  |  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.


|  rclcpp::Node::Node  |  (  |  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) () `
|  )  |  |
explicit

Create a new node with the specified name.


###  Writing a client node


If undeclared parameters are allowed, see the node option [
rclcpp::NodeOptions::allow_undeclared_parameters
](classrclcpp_1_1NodeOptions.html#a5b9580203b3cb88c75b5b858e26b3b7d "Return
the allow_undeclared_parameters flag.") , then this method will not throw an
exception, and instead return a default initialized [ rclcpp::Parameter
](classrclcpp_1_1Parameter.html "Structure to store an arbitrary parameter
with templated get/set methods.") , which has a type of
rclcpp::ParameterType::PARAMETER_NOT_SET.


pub = node->create_publisher<MsgT>(  "chatter"  ,
QoS(1).best_effort().volatile());


###  Run your nodes


  void
  handle_status_message(std::shared_ptr<void> message) override
  {
    std::lock_guard<std::mutex> guard(goal_handles_mutex_);
    using GoalStatusMessage = typename ActionT::Impl::GoalStatusMessage;
    auto status_message = std::static_pointer_cast<GoalStatusMessage>(message);
    for (const GoalStatus & status : status_message->status_list) {
      const GoalUUID & goal_id = status.goal_info.goal_id.uuid;
      if (goal_handles_.count(goal_id) == 0) {
        RCLCPP_DEBUG(
          this->get_logger(),
          "Received status for unknown goal. Ignoring...");
        continue;
      }
      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 status callback");
        goal_handles_.erase(goal_id);
        continue;
      }
      goal_handle->set_status(status.status);
    }
  }
  /// \internal
  void
  make_result_aware(typename GoalHandle::SharedPtr goal_handle)
  {
    // Avoid making more than one request
    if (goal_handle->set_result_awareness(true)) {
      return;
    }
    using GoalResultRequest = typename ActionT::Impl::GetResultService::Request;
    auto goal_result_request = std::make_shared<GoalResultRequest>();
    goal_result_request->goal_id.uuid = goal_handle->get_goal_id();
    try {
      this->send_result_request(
        std::static_pointer_cast<void>(goal_result_request),


  3.1 Examine the code  ï

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

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

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

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

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

    RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "service not available, waiting again...");

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

    RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");

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


###  Get in touch


     NameValidationError  |  if the sub-namespace is absolute, i.e. starts with a leading '/'.
---|---

##  ◆  get_node_options()


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


rclcpp::node_interfaces::NodeParametersInterface::SharedPtr
rclcpp::Node::get_node_parameters_interface  |  (  |  |  )  |
---|---|---|---|---

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


##  ◆  create_client()  [2/2]


##  A ROS 2 service in action


Exceptions


[ rokel_race  ](https://discourse.ros.org/u/rokel_race) July 10, 2020, 10:53am
5


|  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_result_response  |  (  |
decltype(action_msgs::msg::GoalStatus::status)  |  _status_ |  )  |
---|---|---|---|---|---
protected  pure virtual

Create an empty goal result message so it can be sent as a reply in a lower
layer


If the parameter has not been declared, then 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.


   * \param[in] request request to be send.
   * \param[in] cb callback that will be called when we get a response for this request.
   * \return the request id representing the request just sent.
   */
  template<
    typename CallbackT,
    typename std::enable_if<
      rclcpp::function_traits::same_arguments<
        CallbackT,
        CallbackWithRequestType
      >::value
    >::type * = nullptr
  >
  SharedFutureWithRequestAndRequestId
  async_send_request(SharedRequest request, CallbackT && cb)
  {
    PromiseWithRequest promise;
    auto shared_future = promise.get_future().share();
    auto req_id = async_send_request_impl(
      *request,
      std::make_tuple(
        CallbackWithRequestType{std::forward<CallbackT>(cb)},
        request,
        shared_future,
        std::move(promise)));
    return SharedFutureWithRequestAndRequestId{std::move(shared_future), req_id};
  }
  /// Cleanup a pending request.
  /**
   * This notifies the client that we have waited long enough for a response from the server
   * to come, we have given up and we are not waiting for a response anymore.
   *
   * Not calling this will make the client start using more memory for each request
   * that never got a reply from the server.
   *
   * \param[in] request_id request id returned by async_send_request().
   * \return true when a pending request was removed, false if not (e.g. a response was received).
   */
  bool
  remove_pending_request(int64_t request_id)


The registered callbacks are called when a parameter is set. When a callback
returns a not successful result, the remaining callbacks aren't called. The
order of the callback is the reverse from the registration order.


      * [ Launch ](../Launch/Launch-Main.html)
        * [ Creating a launch file ](../Launch/Creating-Launch-Files.html)
        * [ Integrating launch files into ROS 2 packages ](../Launch/Launch-system.html)
        * [ Using substitutions ](../Launch/Using-Substitutions.html)
        * [ Using event handlers ](../Launch/Using-Event-Handlers.html)
        * [ Managing large projects ](../Launch/Using-ROS2-Launch-For-Large-Projects.html)
      * [ ` tf2  ` ](../Tf2/Tf2-Main.html)
        * [ Introducing ` tf2  ` ](../Tf2/Introduction-To-Tf2.html)
        * [ Writing a static broadcaster (Python) ](../Tf2/Writing-A-Tf2-Static-Broadcaster-Py.html)
        * [ Writing a static broadcaster (C++) ](../Tf2/Writing-A-Tf2-Static-Broadcaster-Cpp.html)
        * [ Writing a broadcaster (Python) ](../Tf2/Writing-A-Tf2-Broadcaster-Py.html)
        * [ Writing a broadcaster (C++) ](../Tf2/Writing-A-Tf2-Broadcaster-Cpp.html)
        * [ Writing a listener (Python) ](../Tf2/Writing-A-Tf2-Listener-Py.html)
        * [ Writing a listener (C++) ](../Tf2/Writing-A-Tf2-Listener-Cpp.html)
        * [ Adding a frame (Python) ](../Tf2/Adding-A-Frame-Py.html)
        * [ Adding a frame (C++) ](../Tf2/Adding-A-Frame-Cpp.html)
        * [ Using time (Python) ](../Tf2/Learning-About-Tf2-And-Time-Py.html)
        * [ Using time (C++) ](../Tf2/Learning-About-Tf2-And-Time-Cpp.html)
        * [ Traveling in time (Python) ](../Tf2/Time-Travel-With-Tf2-Py.html)
        * [ Traveling in time (C++) ](../Tf2/Time-Travel-With-Tf2-Cpp.html)
        * [ Debugging ](../Tf2/Debugging-Tf2-Problems.html)
        * [ Quaternion fundamentals ](../Tf2/Quaternion-Fundamentals.html)
        * [ Using stamped datatypes with ` tf2_ros::MessageFilter  ` ](../Tf2/Using-Stamped-Datatypes-With-Tf2-Ros-MessageFilter.html)
      * [ Testing ](../Testing/Testing-Main.html)
        * [ Running Tests in ROS 2 from the Command Line ](../Testing/CLI.html)
        * [ Writing Basic Tests with C++ with GTest ](../Testing/Cpp.html)
        * [ Writing Basic Tests with Python ](../Testing/Python.html)
      * [ URDF ](../URDF/URDF-Main.html)
        * [ Building a visual robot model from scratch ](../URDF/Building-a-Visual-Robot-Model-with-URDF-from-Scratch.html)
        * [ Building a movable robot model ](../URDF/Building-a-Movable-Robot-Model-with-URDF.html)
        * [ Adding physical and collision properties ](../URDF/Adding-Physical-and-Collision-Properties-to-a-URDF-Model.html)
        * [ Using Xacro to clean up your code ](../URDF/Using-Xacro-to-Clean-Up-a-URDF-File.html)
        * [ Using URDF with ` robot_state_publisher  ` ](../URDF/Using-URDF-with-Robot-State-Publisher.html)
        * [ Generating an URDF File ](../URDF/Exporting-an-URDF-File.html)
      * [ RViz ](../RViz/RViz-Main.html)
        * [ RViz User Guide ](../RViz/RViz-User-Guide/RViz-User-Guide.html)
        * [ Building a Custom RViz Display ](../RViz/RViz-Custom-Display/RViz-Custom-Display.html)
    * [ Advanced ](../../Advanced.html)
      * [ Enabling topic statistics (C++) ](../../Advanced/Topic-Statistics-Tutorial/Topic-Statistics-Tutorial.html)
      * [ Using Fast DDS Discovery Server as discovery protocol [community-contributed] ](../../Advanced/Discovery-Server/Discovery-Server.html)


[ Time ](classrclcpp_1_1Time.html) rclcpp::Node::now  |  (  |  |  )  |  const
---|---|---|---|---

Returns current time from the time source specified by clock_type.


     [ 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.
---|---
[ rclcpp::exceptions::ParameterImmutableException
](classrclcpp_1_1exceptions_1_1ParameterImmutableException.html "Thrown if
parameter is immutable and therefore cannot be undeclared.") |  if the
parameter was create as read_only (immutable).

##  ◆  has_parameter()


     [ rclcpp::ParameterTypeException ](classrclcpp_1_1ParameterTypeException.html "Indicate the parameter type does not match the expected type.") |  if the requested type does not match the value of the parameter which is stored.
---|---

##  ◆  get_parameter_or()


    }
  }
  virtual ~Client()
  {
  }
  /// Take the next response for this client.
  /**
   * \sa ClientBase::take_type_erased_response().
   *
   * \param[out] response_out The reference to a Service Response into
   *   which the middleware will copy the response being taken.
   * \param[out] request_header_out The request header to be filled by the
   *   middleware when taking, and which can be used to associte the response
   *   to a specific request.
   * \returns true if the response was taken, otherwise false.
   * \throws rclcpp::exceptions::RCLError based exceptions if the underlying
   *   rcl function fail.
   */
  bool
  take_response(typename ServiceT::Response & response_out, rmw_request_id_t & request_header_out)
  {
    return this->take_type_erased_response(&response_out, request_header_out);
  }
  /// Create a shared pointer with the response type
  /**
   * \return shared pointer with the response type
   */
  std::shared_ptr<void>
  create_response() override
  {
    return std::shared_ptr<void>(new typename ServiceT::Response());
  }
  /// Create a shared pointer with a rmw_request_id_t
  /**
   * \return shared pointer with a rmw_request_id_t
   */
  std::shared_ptr<rmw_request_id_t>
  create_request_header() override
  {
    // TODO(wjwwood): This should probably use rmw_request_id's allocator.


Tasks  ï


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

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


// Copyright 2018 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_ACTION__CLIENT_HPP_
#define RCLCPP_ACTION__CLIENT_HPP_
#include <algorithm>
#include <chrono>
#include <functional>
#include <future>
#include <map>
#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>
#include <utility>
#include "rcl/event_callback.h"
#include "rclcpp/exceptions.hpp"
#include "rclcpp/macros.hpp"
#include "rclcpp/node_interfaces/node_base_interface.hpp"
#include "rclcpp/node_interfaces/node_logging_interface.hpp"
#include "rclcpp/node_interfaces/node_graph_interface.hpp"
#include "rclcpp/logger.hpp"
#include "rclcpp/time.hpp"
#include "rclcpp/waitable.hpp"
#include "rosidl_runtime_c/action_type_support_struct.h"
#include "rosidl_typesupport_cpp/action_type_support.hpp"
#include "rclcpp_action/client_goal_handle.hpp"
#include "rclcpp_action/exceptions.hpp"
#include "rclcpp_action/types.hpp"
#include "rclcpp_action/visibility_control.hpp"


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


The [ rclcpp::QoS ](classrclcpp_1_1QoS.html "Encapsulation of Quality of
Service settings.") has several convenient constructors, including a
conversion constructor for size_t, which mimics older API's that allows just a
string and size_t to create a publisher.


For an example callback:


|  [ RCLCPP_ACTION_PUBLIC
](visibility__control_8hpp.html#a736fe60d4de4417a213ed34ba1926048) void
rclcpp_action::ServerBase::publish_result  |  (  |  const [ GoalUUID
](namespacerclcpp__action.html#a67daf44a45003173e42ccc612fcb052b) & |  _uuid_
,
---|---|---|---
|  |  [ std::shared_ptr
](http://en.cppreference.com/w/cpp/memory/shared_ptr.html) < void > |
_result_msg_
|  )  |  |
protected

##  ◆  publish_feedback()


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.


Define two functions: ` moveMotorToMinAndMax ` and ` doChecks ` .


##  ◆  set_parameter()


Public Types  |  Public Member Functions  |  Protected Member Functions  | [
List of all members ](classrclcpp_1_1Node-members.html)


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


##  ◆  get_callback_groups()


If the names vector is empty, then an empty vector will be returned.


Delete a handler returned by ` add_on_set_parameters_callback ` .


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


     [ std::runtime_error ](http://en.cppreference.com/w/cpp/error/runtime_error.html) |  anything that rcl_error can throw
---|---

##  ◆  get_service_names_and_types()


This method is used to declare that a parameter exists on this node. If, at
run-time, the user has provided an initial value then it will be set in this
method, otherwise the given default_value will be set. In either case, the
resulting value is returned, whether or not it is based on the default value
or the user provided initial value.


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

We now have a fully functioning action client. Letâs get it built and
running.


rclcpp  master


const char* rclcpp::Node::get_fully_qualified_name  |  (  |  |  )  |  const
---|---|---|---|---

Get the fully-qualified name of the node.


  Related content  ï

  * There are several ways you could write an action server and client in C++; check out the ` minimal_action_server  ` and ` minimal_action_client  ` packages in the [ ros2/examples ](https://github.com/ros2/examples/tree/rolling/rclcpp) repo.

  * For more detailed information about ROS actions, please refer to the [ design article ](http://design.ros2.org/articles/actions.html) .

[ Previous ](../Creating-an-Action.html "Creating an action") [ Next
](Py.html "Writing an action server and client \(Python\)")

* * *

© Copyright 2024, Open Robotics.

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

Other Versions  v: rolling

Releases

     [ Iron (latest) ](../../../../iron/Tutorials/Intermediate/Writing-an-Action-Server-Client/Cpp.html)
     [ Humble ](../../../../humble/Tutorials/Intermediate/Writing-an-Action-Server-Client/Cpp.html)
     [ Galactic (EOL) ](../../../../galactic/Tutorials/Intermediate/Writing-an-Action-Server-Client/Cpp.html)
     [ Foxy (EOL) ](../../../../foxy/Tutorials/Intermediate/Writing-an-Action-Server-Client/Cpp.html)
     [ Eloquent (EOL) ](../../../../eloquent/index.html)
     [ Dashing (EOL) ](../../../../dashing/index.html)
     [ Crystal (EOL) ](../../../../crystal/index.html)

In Development

     [ Rolling ](Cpp.html)


   *   If the goal is rejected, then the result will be a `nullptr`.
   */
  std::shared_future<typename GoalHandle::SharedPtr>
  async_send_goal(const Goal & goal, const SendGoalOptions & options = SendGoalOptions())
  {
    // Put promise in the heap to move it around.
    auto promise = std::make_shared<std::promise<typename GoalHandle::SharedPtr>>();
    std::shared_future<typename GoalHandle::SharedPtr> future(promise->get_future());
    using GoalRequest = typename ActionT::Impl::SendGoalService::Request;
    auto goal_request = std::make_shared<GoalRequest>();
    goal_request->goal_id.uuid = this->generate_goal_id();
    goal_request->goal = goal;
    this->send_goal_request(
      std::static_pointer_cast<void>(goal_request),
      [this, goal_request, options, promise](std::shared_ptr<void> response) mutable
      {
        using GoalResponse = typename ActionT::Impl::SendGoalService::Response;
        auto goal_response = std::static_pointer_cast<GoalResponse>(response);
        if (!goal_response->accepted) {
          promise->set_value(nullptr);
          if (options.goal_response_callback) {
            options.goal_response_callback(nullptr);
          }
          return;
        }
        GoalInfo goal_info;
        goal_info.goal_id.uuid = goal_request->goal_id.uuid;
        goal_info.stamp = goal_response->stamp;
        // Do not use std::make_shared as friendship cannot be forwarded.
        std::shared_ptr<GoalHandle> goal_handle(
          new GoalHandle(goal_info, options.feedback_callback, options.result_callback));
        {
          std::lock_guard<std::mutex> guard(goal_handles_mutex_);
          goal_handles_[goal_handle->get_goal_id()] = goal_handle;
        }
        promise->set_value(goal_handle);
        if (options.goal_response_callback) {
          options.goal_response_callback(goal_handle);
        }
        if (options.result_callback) {


namespace rclcpp_action
{
// Forward declaration
class ClientBaseImpl;
/// Base Action Client implementation
/// \internal
/**
 * This class should not be used directly by users wanting to create an aciton client.
 * Instead users should use `rclcpp_action::Client<>`.
 *
 * Internally, this class is responsible for interfacing with the `rcl_action` API.
 */
class ClientBase : public rclcpp::Waitable
{
public:
  RCLCPP_ACTION_PUBLIC
  virtual ~ClientBase();
  /// Enum to identify entities belonging to the action client
  enum class EntityType : std::size_t
  {
    GoalClient,
    ResultClient,
    CancelClient,
    FeedbackSubscription,
    StatusSubscription,
  };


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


If the parameter was not set, then the "parameter" argument is assigned the
"alternative_value".


The logger of the node.


pub = node->create_publisher<MsgT>(  "chatter"  , custom_qos);


[ Product ](/product) [ Blog ](/blog) [ Customers ](/customers) [ Pricing
](/pricing) [ Docs ](https://docs.foxglove.dev) [ Download
](https://foxglove.dev/download) [ Sign in ](https://app.foxglove.dev/signin)
[ Get started ](https://app.foxglove.dev/signup)


Parameters


##  Keep learning!


    /// Return true if there is an action server that is ready to take goal requests.
  RCLCPP_ACTION_PUBLIC
  bool
  action_server_is_ready() const;
  /// Wait for action_server_is_ready() to become true, or until the given timeout is reached.
  template<typename RepT = int64_t, typename RatioT = std::milli>
  bool
  wait_for_action_server(
    std::chrono::duration<RepT, RatioT> timeout = std::chrono::duration<RepT, RatioT>(-1))
  {
    return wait_for_action_server_nanoseconds(
      std::chrono::duration_cast<std::chrono::nanoseconds>(timeout)
    );
  }
  // -------------
  // Waitables API
  /// \internal
  RCLCPP_ACTION_PUBLIC
  size_t
  get_number_of_ready_subscriptions() override;
  /// \internal
  RCLCPP_ACTION_PUBLIC
  size_t
  get_number_of_ready_timers() override;
  /// \internal
  RCLCPP_ACTION_PUBLIC
  size_t
  get_number_of_ready_clients() override;
  /// \internal
  RCLCPP_ACTION_PUBLIC
  size_t
  get_number_of_ready_services() override;
  /// \internal
  RCLCPP_ACTION_PUBLIC
  size_t
  get_number_of_ready_guard_conditions() override;
  /// \internal
  RCLCPP_ACTION_PUBLIC
  void
  add_to_wait_set(rcl_wait_set_t * wait_set) override;
  /// \internal
  RCLCPP_ACTION_PUBLIC
  bool
  is_ready(rcl_wait_set_t * wait_set) override;
  /// \internal
  RCLCPP_ACTION_PUBLIC
  std::shared_ptr<void>
  take_data() override;
  /// \internal
  RCLCPP_ACTION_PUBLIC
  std::shared_ptr<void>
  take_data_by_entity_id(size_t id) override;
  /// \internal
  RCLCPP_ACTION_PUBLIC


[ get_namespace() ](classrclcpp_1_1Node.html#a7be04e55e2934e05df992b188d9dce6d
"Get the namespace of the node.") will return the original node namespace, and
will not include the sub-namespace if one exists. To get that you need to call
the [ get_effective_namespace()
](classrclcpp_1_1Node.html#afe4790bba38942b795d24b6ccb3e9c5a "Return the
effective namespace that is used when creating entities.") method.


[ All blog posts ](/blog)


Inheritance diagram for rclcpp::Node:


      std::shared_future<std::pair<SharedRequest, SharedResponse>>
    >::FutureAndRequestId;
  };
  /// Default constructor.
  /**
   * The constructor for a Client is almost never called directly.
   * Instead, clients should be instantiated through the function
   * rclcpp::create_client().
   *
   * \param[in] node_base NodeBaseInterface pointer that is used in part of the setup.
   * \param[in] node_graph The node graph interface of the corresponding node.
   * \param[in] service_name Name of the topic to publish to.
   * \param[in] client_options options for the subscription.
   */
  Client(
    rclcpp::node_interfaces::NodeBaseInterface * node_base,
    rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph,
    const std::string & service_name,
    rcl_client_options_t & client_options)
  : ClientBase(node_base, node_graph),
    srv_type_support_handle_(rosidl_typesupport_cpp::get_service_type_support_handle<ServiceT>())
  {
    rcl_ret_t ret = rcl_client_init(
      this->get_client_handle().get(),
      this->get_rcl_node_handle(),
      srv_type_support_handle_,
      service_name.c_str(),
      &client_options);
    if (ret != RCL_RET_OK) {
      if (ret == RCL_RET_SERVICE_NAME_INVALID) {
        auto rcl_node_handle = this->get_rcl_node_handle();
        // this will throw on any validation problem
        rcl_reset_error();
        expand_topic_or_service_name(
          service_name,
          rcl_node_get_name(rcl_node_handle),
          rcl_node_get_namespace(rcl_node_handle),
          true);
      }
      rclcpp::exceptions::throw_from_rcl_error(ret, "could not create client");


    * [ Using Callback Groups ](../../How-To-Guides/Using-callback-groups.html)
    * [ IDEs and Debugging [community-contributed] ](../../How-To-Guides/ROS-2-IDEs.html)
    * [ Setup ROS 2 with VSCode and Docker [community-contributed] ](../../How-To-Guides/Setup-ROS-2-with-VSCode-and-Docker-Container.html)
    * [ Using Custom Rosdistro Version ](../../How-To-Guides/Using-Custom-Rosdistro.html)
    * [ Building RQt from source ](../../How-To-Guides/RQt-Source-Install.html)
      * [ Building RQt from source on macOS ](../../How-To-Guides/RQt-Source-Install-MacOS.html)
      * [ Building RQt from source on Windows 10 ](../../How-To-Guides/RQt-Source-Install-Windows10.html)
  * [ Concepts ](../../Concepts.html)
    * [ Basic Concepts ](../../Concepts/Basic.html)
      * [ Nodes ](../../Concepts/Basic/About-Nodes.html)
      * [ Discovery ](../../Concepts/Basic/About-Discovery.html)
      * [ Interfaces ](../../Concepts/Basic/About-Interfaces.html)
      * [ Topics ](../../Concepts/Basic/About-Topics.html)
      * [ Services ](../../Concepts/Basic/About-Services.html)
      * [ Actions ](../../Concepts/Basic/About-Actions.html)
      * [ Parameters ](../../Concepts/Basic/About-Parameters.html)
      * [ Introspection with command line tools ](../../Concepts/Basic/About-Command-Line-Tools.html)
      * [ Launch ](../../Concepts/Basic/About-Launch.html)
      * [ Client libraries ](../../Concepts/Basic/About-Client-Libraries.html)
    * [ Intermediate Concepts ](../../Concepts/Intermediate.html)
      * [ The ROS_DOMAIN_ID ](../../Concepts/Intermediate/About-Domain-ID.html)
      * [ Different ROS 2 middleware vendors ](../../Concepts/Intermediate/About-Different-Middleware-Vendors.html)
      * [ Logging and logger configuration ](../../Concepts/Intermediate/About-Logging.html)
      * [ Quality of Service settings ](../../Concepts/Intermediate/About-Quality-of-Service-Settings.html)
      * [ Executors ](../../Concepts/Intermediate/About-Executors.html)
      * [ Topic statistics ](../../Concepts/Intermediate/About-Topic-Statistics.html)
      * [ Overview and usage of RQt ](../../Concepts/Intermediate/About-RQt.html)
      * [ Composition ](../../Concepts/Intermediate/About-Composition.html)
      * [ Cross-compilation ](../../Concepts/Intermediate/About-Cross-Compilation.html)
      * [ ROS 2 Security ](../../Concepts/Intermediate/About-Security.html)
      * [ Tf2 ](../../Concepts/Intermediate/About-Tf2.html)
    * [ Advanced Concepts ](../../Concepts/Advanced.html)
      * [ The build system ](../../Concepts/Advanced/About-Build-System.html)
      * [ Internal ROS 2 interfaces ](../../Concepts/Advanced/About-Internal-Interfaces.html)
      * [ ROS 2 middleware implementations ](../../Concepts/Advanced/About-Middleware-Implementations.html)
  * [ Contact ](../../Contact.html)
  * [ The ROS 2 Project ](../../The-ROS2-Project.html)
    * [ Contributing ](../../The-ROS2-Project/Contributing.html)
      * [ ROS 2 developer guide ](../../The-ROS2-Project/Contributing/Developer-Guide.html)
      * [ Code style and language versions ](../../The-ROS2-Project/Contributing/Code-Style-Language-Versions.html)


     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_graph_event()


##  ◆  get_effective_namespace()


[ rclcpp::WallTimer ](classrclcpp_1_1WallTimer.html) < CallbackT >::SharedPtr
rclcpp::Node::create_wall_timer  |  (  |  [ 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.


Like set_parameter and set_parameters, this method may throw an [
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 parameters to be set have not first been
declared. If the exception is thrown then none of the parameters will have
been set.


Subscribe


Also like [ get_parameters()
](classrclcpp_1_1Node.html#a25890d01a2cd47ce99af887f556c529b "Return the
parameters by the given parameter names.") , if undeclared parameters are
allowed and the parameter has not been declared, then the corresponding [
rclcpp::Parameter ](classrclcpp_1_1Parameter.html "Structure to store an
arbitrary parameter with templated get/set methods.") will be default
initialized and therefore have the type
rclcpp::ParameterType::PARAMETER_NOT_SET.


The parameters that were retrieved.


Open menu


Behaves like set_parameter, except that it sets multiple parameters, failing
all if just one of the parameters are unsuccessfully set. Either all of the
parameters are set or none of them are set.


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

##  ◆  get_parameters()  [2/2]


The publisher options may optionally be passed as the third argument for any
of the above cases.


A shared pointer. The callback is valid as long as the smart pointer is alive.


    $ cd ros2_ws/src/
    $ ros2 pkg create srv_client_checks --dependencies rclcpp std_srvs


     [in]  |  namespace_  |  The namespace in which to declare the parameters.
---|---|---
[in]  |  parameters  |  The parameters to set in the given namespace.
[in]  |  ignore_overrides  |  When ` true ` , the parameters overrides are
ignored. Default to ` false ` .

Exceptions


##  ◆  call_goal_accepted_callback()


](classrclcpp_1_1Node.html#a5b1ca8c48e28bd1f3e5fda2ab3116efd)

template<typename ParameterT >
[ std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) <
ParameterT > |  [ declare_parameters
](classrclcpp_1_1Node.html#a5ebda51ed6fa4ce8f2cddc9f77e9674e) (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) , ParameterT >
&parameters, bool ignore_overrides=false)
|  Declare and initialize several parameters with the same namespace and type.
[ More... ](classrclcpp_1_1Node.html#a5ebda51ed6fa4ce8f2cddc9f77e9674e)

template<typename ParameterT >
[ std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) <
ParameterT > |  [ declare_parameters
](classrclcpp_1_1Node.html#a9b3300ad15cdf9e22ee7bfc844b9a30c) (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.
[ More... ](classrclcpp_1_1Node.html#a9b3300ad15cdf9e22ee7bfc844b9a30c)

void  |  [ undeclare_parameter
](classrclcpp_1_1Node.html#a2c525bd10070bd025bd570e98afd0d7d) (const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&name)
|  Undeclare a previously declared parameter. [ More...
](classrclcpp_1_1Node.html#a2c525bd10070bd025bd570e98afd0d7d)

bool  |  [ has_parameter
](classrclcpp_1_1Node.html#aabb818bb5c848c5a980ddbe745517b7c) (const [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html)
&name) const
|  Return true if a given parameter is declared. [ More...


Share custom visualization tools with your teammates


1 Like


The fully-qualified name includes the local namespace and name of the node.


Add the executables to your compilation file, and install them in your path,
so that the ` ros2 run ` command can find them.


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


|  virtual [ RCLCPP_ACTION_PUBLIC
](visibility__control_8hpp.html#a736fe60d4de4417a213ed34ba1926048) [
CancelResponse
](namespacerclcpp__action.html#a27ea2386548de7ad3bef27bb3c0eed05)
rclcpp_action::ServerBase::call_handle_cancel_callback  |  (  |  const [
GoalUUID ](namespacerclcpp__action.html#a67daf44a45003173e42ccc612fcb052b) & |
_uuid_ |  )  |
---|---|---|---|---|---
protected  pure virtual

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


[ [ legend ](graph_legend.html) ]


const [ std::vector ](http://en.cppreference.com/w/cpp/container/vector.html)
<rclcpp::CallbackGroup::WeakPtr>& rclcpp::Node::get_callback_groups  |  (  |
|  )  |  const
---|---|---|---|---

Return the list of callback groups in the node.


Parameters


a list of [ TopicEndpointInfo ](classrclcpp_1_1TopicEndpointInfo.html) representing all the subscriptions on this topic.


Let's start out with our server **motor_node** , which will run the necessary
check on the servo motors.


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


More... ](classrclcpp_1_1Node.html#a15d4f7fa0ef760941b6a78f42cccb7e0)

[ OnParametersSetCallbackType
](classrclcpp_1_1Node.html#ab403fecdb5ec2eb9f88e3eb7ae6f6d0c) |  [
set_on_parameters_set_callback
](classrclcpp_1_1Node.html#a9f742edc00998b24d0a52f537bc95ad8) ( [
rclcpp::Node::OnParametersSetCallbackType
](classrclcpp_1_1Node.html#ab403fecdb5ec2eb9f88e3eb7ae6f6d0c) callback)
|  Register a callback to be called anytime a parameter is about to be
changed. [ More...
](classrclcpp_1_1Node.html#a9f742edc00998b24d0a52f537bc95ad8)

[ std::vector ](http://en.cppreference.com/w/cpp/container/vector.html) < [
std::string ](http://en.cppreference.com/w/cpp/string/basic_string.html) > |
[ get_node_names ](classrclcpp_1_1Node.html#a9e4302d8e28f17078cbc3b6db93c97ba)
() const
|  Get the fully-qualified names of all available nodes. [ More...
](classrclcpp_1_1Node.html#a9e4302d8e28f17078cbc3b6db93c97ba)

[ 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) > > |
[ get_topic_names_and_types
](classrclcpp_1_1Node.html#ab64ee81d61071100f222b819eab3e311) () const
|  Return a map of existing topic names to list of topic types. [ More...
](classrclcpp_1_1Node.html#ab64ee81d61071100f222b819eab3e311)

[ 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) > > |
[ get_service_names_and_types
](classrclcpp_1_1Node.html#a0d400bbd606a936a556b747f519eab38) () const
|  Return a map of existing service names to list of service types. [ More...
](classrclcpp_1_1Node.html#a0d400bbd606a936a556b747f519eab38)

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


rclcpp::node_interfaces::NodeTimeSourceInterface::SharedPtr
rclcpp::Node::get_node_time_source_interface  |  (  |  |  )  |
---|---|---|---|---

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


Note, this method cannot return a const reference, because extending the
lifetime of a temporary only works recursively with member initializers, and
cannot be extended to members of a class returned. The return value of this
class is a copy of the member of a [ ParameterValue
](classrclcpp_1_1ParameterValue.html "Store the type and value of a
parameter.") which is returned by the other version of [ declare_parameter()
](classrclcpp_1_1Node.html#a095ea977b26e7464d9371efea5f36c42 "Declare and
initialize a parameter, return the effective value.") . See also:


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


> This (interacting with unknown types at runtime) is an area that we need to
> improve on still in the core API, in my opinion.