From 0a72cd7fcb366d22214c25b929ce40b4cf676767 Mon Sep 17 00:00:00 2001 From: Jackie Kay Date: Wed, 26 Aug 2015 15:22:28 -0700 Subject: [PATCH 1/4] mark up all the functions to document --- rclcpp/include/rclcpp/executor.hpp | 37 +++++++++++++++++++ .../executors/single_threaded_executor.hpp | 1 + rclcpp/include/rclcpp/memory_strategy.hpp | 1 + .../rclcpp/message_memory_strategy.hpp | 1 + rclcpp/include/rclcpp/node.hpp | 2 + rclcpp/include/rclcpp/publisher.hpp | 2 + .../message_pool_memory_strategy.hpp | 1 + .../strategies/static_memory_strategy.hpp | 2 + rclcpp/include/rclcpp/subscription.hpp | 3 ++ rclcpp/include/rclcpp/timer.hpp | 1 + rclcpp/include/rclcpp/utilities.hpp | 4 ++ 11 files changed, 55 insertions(+) diff --git a/rclcpp/include/rclcpp/executor.hpp b/rclcpp/include/rclcpp/executor.hpp index 3911d59..2f4c671 100644 --- a/rclcpp/include/rclcpp/executor.hpp +++ b/rclcpp/include/rclcpp/executor.hpp @@ -36,6 +36,15 @@ namespace rclcpp namespace executor { +/// Coordinates the order and timing of available communication tasks. +/* Executor provides spin functions (including spin_node_once and spin_some). + * It coordinates the nodes and callback groups by looking for available work and completing it, + * based on the threading or concurrency scheme provided by the subclass implementation. + * An example of available work is executing a subscription callback, or a timer callback. + * The executor structure allows for a decoupling of the communication graph and the execution + * model. + * See SingleThreadedExecutor and MultiThreadedExecutor for examples of execution paradigms. + */ class Executor { friend class memory_strategy::MemoryStrategy; @@ -43,6 +52,8 @@ class Executor public: RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(Executor); + /// Default constructor. + // \param[in] ms The memory strategy to be used with this executor. explicit Executor(memory_strategy::MemoryStrategy::SharedPtr ms = memory_strategy::create_default_strategy()) : interrupt_guard_condition_(rmw_create_guard_condition()), @@ -50,8 +61,10 @@ public: { } + /// Default destructor. virtual ~Executor() { + // Try to deallocate the interrupt guard condition. if (interrupt_guard_condition_ != nullptr) { rmw_ret_t status = rmw_destroy_guard_condition(interrupt_guard_condition_); if (status != RMW_RET_OK) { @@ -61,8 +74,17 @@ public: } } + /// Do work periodically as it becomes available to us. Blocking call, may block indefinitely. + // It is up to the implementation of Executor to implement spin. virtual void spin() = 0; + /// Add a node to the executor. + /* An executor can have zero or more nodes which provide work during `spin` functions. + * \param[in] node_ptr Shared pointer to the node to be added. + * \param[in] notify True to trigger the interrupt guard condition during this function. If + * the executor is blocked at the rmw layer while waiting for work and it is notified that a new + * node was added, it will wake up. + */ virtual void add_node(rclcpp::node::Node::SharedPtr & node_ptr, bool notify = true) { @@ -84,6 +106,12 @@ public: } } + /// Remove a node from the executor. + /* \param[in] node_ptr Shared pointer to the node to remove. + * \param[in] notify True to trigger the interrupt guard condition and wake up the executor. + * This is useful if the last node was removed from the executor while the executor was blocked + * waiting for work in another thread, because otherwise the executor would never be notified. + */ virtual void remove_node(rclcpp::node::Node::SharedPtr & node_ptr, bool notify = true) { @@ -108,6 +136,11 @@ public: } } + /// Add a node to executor, complete the next available unit of work, and remove the node. + /* \param[in] node Shared pointer to the node to add. + * \param[in] timeout How long to wait for work to become available. Negative values cause + * spin_node_once to block indefinitely + */ template void spin_node_once(rclcpp::node::Node::SharedPtr & node, std::chrono::duration timeout = std::chrono::duration(-1)) @@ -121,6 +154,7 @@ public: this->remove_node(node, false); } +// TODO void spin_node_some(rclcpp::node::Node::SharedPtr & node) { this->add_node(node, false); @@ -128,6 +162,7 @@ public: this->remove_node(node, false); } +// TODO virtual void spin_some() { while (AnyExecutable::SharedPtr any_exec = @@ -137,6 +172,7 @@ public: } } +// TODO // Support dynamic switching of memory strategy void set_memory_strategy(memory_strategy::MemoryStrategy::SharedPtr memory_strategy) @@ -149,6 +185,7 @@ public: protected: void +// TODO execute_any_executable(AnyExecutable::SharedPtr & any_exec) { if (!any_exec) { diff --git a/rclcpp/include/rclcpp/executors/single_threaded_executor.hpp b/rclcpp/include/rclcpp/executors/single_threaded_executor.hpp index 96c9fa7..944f2c4 100644 --- a/rclcpp/include/rclcpp/executors/single_threaded_executor.hpp +++ b/rclcpp/include/rclcpp/executors/single_threaded_executor.hpp @@ -36,6 +36,7 @@ namespace executors namespace single_threaded_executor { +// TODO class SingleThreadedExecutor : public executor::Executor { public: diff --git a/rclcpp/include/rclcpp/memory_strategy.hpp b/rclcpp/include/rclcpp/memory_strategy.hpp index a417689..bcc039b 100644 --- a/rclcpp/include/rclcpp/memory_strategy.hpp +++ b/rclcpp/include/rclcpp/memory_strategy.hpp @@ -30,6 +30,7 @@ class Executor; namespace memory_strategy { +// TODO class MemoryStrategy { diff --git a/rclcpp/include/rclcpp/message_memory_strategy.hpp b/rclcpp/include/rclcpp/message_memory_strategy.hpp index bc9a2f9..e071705 100644 --- a/rclcpp/include/rclcpp/message_memory_strategy.hpp +++ b/rclcpp/include/rclcpp/message_memory_strategy.hpp @@ -24,6 +24,7 @@ namespace rclcpp namespace message_memory_strategy { +// TODO template class MessageMemoryStrategy { diff --git a/rclcpp/include/rclcpp/node.hpp b/rclcpp/include/rclcpp/node.hpp index 03ff9de..49edbd3 100644 --- a/rclcpp/include/rclcpp/node.hpp +++ b/rclcpp/include/rclcpp/node.hpp @@ -96,6 +96,7 @@ struct function_traits * * This is the single point of entry for creating publishers and subscribers. */ +// TODO class Node { friend class rclcpp::executor::Executor; @@ -103,6 +104,7 @@ class Node public: RCLCPP_SMART_PTR_DEFINITIONS(Node); +// TODO: ALL public functions /* Create a node based on the node name. */ Node(const std::string & node_name, bool use_intra_process_comms = false); /* Create a node based on the node name and a rclcpp::context::Context. */ diff --git a/rclcpp/include/rclcpp/publisher.hpp b/rclcpp/include/rclcpp/publisher.hpp index 21cf457..5a95876 100644 --- a/rclcpp/include/rclcpp/publisher.hpp +++ b/rclcpp/include/rclcpp/publisher.hpp @@ -39,10 +39,12 @@ class Node; namespace publisher { +// TODO class Publisher { friend rclcpp::node::Node; +// TODO public: RCLCPP_SMART_PTR_DEFINITIONS(Publisher); diff --git a/rclcpp/include/rclcpp/strategies/message_pool_memory_strategy.hpp b/rclcpp/include/rclcpp/strategies/message_pool_memory_strategy.hpp index 098078a..28f2efa 100644 --- a/rclcpp/include/rclcpp/strategies/message_pool_memory_strategy.hpp +++ b/rclcpp/include/rclcpp/strategies/message_pool_memory_strategy.hpp @@ -25,6 +25,7 @@ namespace strategies namespace message_pool_memory_strategy { +// TODO template::value>::type * = nullptr> diff --git a/rclcpp/include/rclcpp/strategies/static_memory_strategy.hpp b/rclcpp/include/rclcpp/strategies/static_memory_strategy.hpp index b92c72d..216f897 100644 --- a/rclcpp/include/rclcpp/strategies/static_memory_strategy.hpp +++ b/rclcpp/include/rclcpp/strategies/static_memory_strategy.hpp @@ -27,6 +27,7 @@ namespace memory_strategies namespace static_memory_strategy { +// TODO struct ObjectPoolBounds { public: @@ -80,6 +81,7 @@ public: }; +// TODO class StaticMemoryStrategy : public memory_strategy::MemoryStrategy { public: diff --git a/rclcpp/include/rclcpp/subscription.hpp b/rclcpp/include/rclcpp/subscription.hpp index 4952087..d74e6bb 100644 --- a/rclcpp/include/rclcpp/subscription.hpp +++ b/rclcpp/include/rclcpp/subscription.hpp @@ -49,6 +49,7 @@ class SubscriptionBase { friend class rclcpp::executor::Executor; +// TODO public: RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(SubscriptionBase); @@ -113,11 +114,13 @@ private: }; +// TODO template class Subscription : public SubscriptionBase { friend class rclcpp::node::Node; +// TODO public: using CallbackType = std::function &)>; RCLCPP_SMART_PTR_DEFINITIONS(Subscription); diff --git a/rclcpp/include/rclcpp/timer.hpp b/rclcpp/include/rclcpp/timer.hpp index 2f97740..7c5d2bd 100644 --- a/rclcpp/include/rclcpp/timer.hpp +++ b/rclcpp/include/rclcpp/timer.hpp @@ -82,6 +82,7 @@ protected: }; +// TODO template class GenericTimer : public TimerBase { diff --git a/rclcpp/include/rclcpp/utilities.hpp b/rclcpp/include/rclcpp/utilities.hpp index 9e77976..ab09b58 100644 --- a/rclcpp/include/rclcpp/utilities.hpp +++ b/rclcpp/include/rclcpp/utilities.hpp @@ -98,6 +98,7 @@ RMW_THREAD_LOCAL size_t thread_id = 0; namespace utilities { +// TODO void init(int argc, char * argv[]) { @@ -138,12 +139,14 @@ init(int argc, char * argv[]) } } +// TODO bool ok() { return ::g_signal_status == 0; } +// TODO void shutdown() { @@ -163,6 +166,7 @@ get_global_sigint_guard_condition() return ::g_sigint_guard_cond_handle; } +// TODO bool sleep_for(const std::chrono::nanoseconds & nanoseconds) { From b0a196ee9febbf40556690afbe2cc848ffeb0f47 Mon Sep 17 00:00:00 2001 From: Jackie Kay Date: Wed, 26 Aug 2015 17:26:25 -0700 Subject: [PATCH 2/4] Lots of comments --- rclcpp/include/rclcpp/executor.hpp | 29 ++++++--- .../executors/single_threaded_executor.hpp | 8 ++- rclcpp/include/rclcpp/memory_strategy.hpp | 27 +++++++- .../rclcpp/message_memory_strategy.hpp | 8 ++- rclcpp/include/rclcpp/node.hpp | 54 +++++++++++----- rclcpp/include/rclcpp/publisher.hpp | 34 +++++++++- rclcpp/include/rclcpp/rclcpp.hpp | 6 ++ .../message_pool_memory_strategy.hpp | 18 +++++- .../strategies/static_memory_strategy.hpp | 63 ++++++++++++++++++- rclcpp/include/rclcpp/subscription.hpp | 42 +++++++++++-- rclcpp/include/rclcpp/timer.hpp | 19 +++++- rclcpp/include/rclcpp/utilities.hpp | 23 +++++-- 12 files changed, 290 insertions(+), 41 deletions(-) diff --git a/rclcpp/include/rclcpp/executor.hpp b/rclcpp/include/rclcpp/executor.hpp index 2f4c671..0f6b1f3 100644 --- a/rclcpp/include/rclcpp/executor.hpp +++ b/rclcpp/include/rclcpp/executor.hpp @@ -136,10 +136,11 @@ public: } } - /// Add a node to executor, complete the next available unit of work, and remove the node. + /// Add a node to executor, execute the next available unit of work, and remove the node. /* \param[in] node Shared pointer to the node to add. * \param[in] timeout How long to wait for work to become available. Negative values cause - * spin_node_once to block indefinitely + * spin_node_once to block indefinitely (the default behavior). A timeout of 0 causes this + * function to be non-blocking. */ template void spin_node_once(rclcpp::node::Node::SharedPtr & node, @@ -154,7 +155,9 @@ public: this->remove_node(node, false); } -// TODO + /// Add a node, complete all immediately available work, and remove the node. + /* \param[in] node Shared pointer to the node to add. + */ void spin_node_some(rclcpp::node::Node::SharedPtr & node) { this->add_node(node, false); @@ -162,7 +165,12 @@ public: this->remove_node(node, false); } -// TODO + /// Complete all available queued work without blocking. + /* This function can be overridden. The default implementation is suitable for a + * single-threaded model of execution. + * Adding subscriptions, timers, services, etc. with blocking callbacks will cause this function + * to block (which may have unintended consequences). + */ virtual void spin_some() { while (AnyExecutable::SharedPtr any_exec = @@ -172,8 +180,11 @@ public: } } -// TODO - // Support dynamic switching of memory strategy + /// Support dynamic switching of the memory strategy. + /* Switching the memory strategy while the executor is spinning in another threading could have + * unintended consequences. + * \param[in] memory_strategy Shared pointer to the memory strategy to set. + */ void set_memory_strategy(memory_strategy::MemoryStrategy::SharedPtr memory_strategy) { @@ -184,8 +195,10 @@ public: } protected: + /// Find the next available executable and do the work associated with it. + // \param[in] any_exec Union structure that can hold any executable type (timer, subscription, + // service, client). void -// TODO execute_any_executable(AnyExecutable::SharedPtr & any_exec) { if (!any_exec) { @@ -938,8 +951,10 @@ protected: return any_exec; } + /// Guard condition for signaling the rmw layer to wake up for special events. rmw_guard_condition_t * interrupt_guard_condition_; + /// The memory strategy: an interface for handling user-defined memory allocation strategies. memory_strategy::MemoryStrategy::SharedPtr memory_strategy_; private: diff --git a/rclcpp/include/rclcpp/executors/single_threaded_executor.hpp b/rclcpp/include/rclcpp/executors/single_threaded_executor.hpp index 944f2c4..9155956 100644 --- a/rclcpp/include/rclcpp/executors/single_threaded_executor.hpp +++ b/rclcpp/include/rclcpp/executors/single_threaded_executor.hpp @@ -36,18 +36,24 @@ namespace executors namespace single_threaded_executor { -// TODO +/// Single-threaded executor implementation +// This is the default executor created by rclcpp::spin. class SingleThreadedExecutor : public executor::Executor { public: RCLCPP_SMART_PTR_DEFINITIONS(SingleThreadedExecutor); + /// Default constructor. See the default constructor for Executor. SingleThreadedExecutor(memory_strategy::MemoryStrategy::SharedPtr ms = memory_strategy::create_default_strategy()) : executor::Executor(ms) {} + /// Default destrcutor. virtual ~SingleThreadedExecutor() {} + /// Single-threaded implementation of spin. + // This function will block until work comes in, execute it, and keep blocking. + // It will only be interrupt by a CTRL-C (managed by the global signal handler). void spin() { while (rclcpp::utilities::ok()) { diff --git a/rclcpp/include/rclcpp/memory_strategy.hpp b/rclcpp/include/rclcpp/memory_strategy.hpp index bcc039b..c170b9a 100644 --- a/rclcpp/include/rclcpp/memory_strategy.hpp +++ b/rclcpp/include/rclcpp/memory_strategy.hpp @@ -30,7 +30,11 @@ class Executor; namespace memory_strategy { -// TODO +/// Delegate for handling memory allocations while the Executor is executing. +/* By default, the memory strategy dynamically allocates memory for structures that come in from + * the rmw implementation after the executor waits for work, based on the number of entities that + * come through. + */ class MemoryStrategy { @@ -38,23 +42,41 @@ class MemoryStrategy public: RCLCPP_SMART_PTR_DEFINITIONS(MemoryStrategy); + + /// Borrow memory for storing data for subscriptions, services, clients, or guard conditions. + /* The default implementation ignores the handle type and dynamically allocates the memory. + * \param[in] The type of entity that this function is requesting for. + * \param[in] The number of handles to borrow. + * \return Pointer to the allocated handles. + */ virtual void ** borrow_handles(HandleType type, size_t number_of_handles) { (void)type; return static_cast(alloc(sizeof(void *) * number_of_handles)); } + /// Return the memory borrowed in borrow_handles. + /* return_handles should always mirror the way memory was borrowed in borrow_handles. + * \param[in] The type of entity that this function is returning. + * \param[in] Pointer to the handles returned. + */ virtual void return_handles(HandleType type, void ** handles) { (void)type; this->free(handles); } + /// Provide a newly initialized AnyExecutable object. + // \return Shared pointer to the fresh executable. virtual executor::AnyExecutable::SharedPtr instantiate_next_executable() { return std::make_shared(); } + /// Implementation of a general-purpose allocation function. + /* \param[in] size Number of bytes to allocate. + * \return Pointer to the allocated chunk of memory. + */ virtual void * alloc(size_t size) { if (size == 0) { @@ -63,6 +85,9 @@ public: return std::malloc(size); } + /// Implementation of a general-purpose free. + /* \param[in] Pointer to deallocate. + */ virtual void free(void * ptr) { return std::free(ptr); diff --git a/rclcpp/include/rclcpp/message_memory_strategy.hpp b/rclcpp/include/rclcpp/message_memory_strategy.hpp index e071705..3ef46d8 100644 --- a/rclcpp/include/rclcpp/message_memory_strategy.hpp +++ b/rclcpp/include/rclcpp/message_memory_strategy.hpp @@ -24,7 +24,8 @@ namespace rclcpp namespace message_memory_strategy { -// TODO +/// Default allocation strategy for messages received by subscriptions. +// A message memory strategy must be templated on the type of the subscription it belongs to. template class MessageMemoryStrategy { @@ -32,16 +33,21 @@ class MessageMemoryStrategy public: RCLCPP_SMART_PTR_DEFINITIONS(MessageMemoryStrategy); + /// Default factory method static SharedPtr create_default() { return SharedPtr(new MessageMemoryStrategy); } + /// By default, dynamically allocate a new message. + // \return Shared pointer to the new message. virtual std::shared_ptr borrow_message() { return std::shared_ptr(new MessageT); } + /// Release ownership of the message, which will deallocate it if it has no more owners. + // \param[in] Shared pointer to the message we are returning. virtual void return_message(std::shared_ptr & msg) { msg.reset(); diff --git a/rclcpp/include/rclcpp/node.hpp b/rclcpp/include/rclcpp/node.hpp index 49edbd3..eceb816 100644 --- a/rclcpp/include/rclcpp/node.hpp +++ b/rclcpp/include/rclcpp/node.hpp @@ -92,11 +92,7 @@ struct function_traits : public function_traits {}; -/* ROS Node Interface. - * - * This is the single point of entry for creating publishers and subscribers. - */ -// TODO +/// Node is the single point of entry for creating publishers and subscribers. class Node { friend class rclcpp::executor::Executor; @@ -104,30 +100,51 @@ class Node public: RCLCPP_SMART_PTR_DEFINITIONS(Node); -// TODO: ALL public functions - /* Create a node based on the node name. */ + /// Create a new node with the specified name. + /* \param[in] node_name Name of the node. + * \param[in] use_intra_process_comms True to use the optimized intra-process communication + * pipeline to pass messages between nodes in the same process using shared memory. + */ Node(const std::string & node_name, bool use_intra_process_comms = false); - /* Create a node based on the node name and a rclcpp::context::Context. */ + + /// Create a node based on the node name and a rclcpp::context::Context. + /* \param[in] node_name Name of the node. + * \param[in] context The context for the node (usually represents the state of a process). + * \param[in] use_intra_process_comms True to use the optimized intra-process communication + * pipeline to pass messages between nodes in the same process using shared memory. + */ Node( const std::string & node_name, rclcpp::context::Context::SharedPtr context, bool use_intra_process_comms = false); - /* Get the name of the node. */ + /// Get the name of the node. + // \return The name of the node. const std::string & get_name() const {return name_; } - /* Create and return a callback group. */ + /// Create and return a callback group. rclcpp::callback_group::CallbackGroup::SharedPtr create_callback_group(rclcpp::callback_group::CallbackGroupType group_type); - /* Create and return a Publisher. */ + /// Create and return a Publisher. + /* \param[in] topic_name The topic for this publisher to publish on. + * \param[in] qos_profile The quality of service profile to pass on to the rmw implementation. + * \return Shared pointer to the created publisher. + */ template rclcpp::publisher::Publisher::SharedPtr create_publisher( const std::string & topic_name, const rmw_qos_profile_t & qos_profile); - /* Create and return a Subscription. */ - + /// Create and return a Subscription. + /* \param[in] topic_name The topic to subscribe on. + * \param[in] qos_profile The quality of service profile to pass on to the rmw implementation. + * \param[in] callback The user-defined callback function. + * \param[in] group The callback group for this subscription. NULL for no callback group. + * \param[in] ignore_local_publications True to ignore local publications. + * \param[in] msg_mem_strat The message memory strategy to use for allocating messages. + * \return Shared pointer to the created subscription. + */ /* TODO(jacquelinekay): Windows build breaks when static member function passed as default argument to msg_mem_strat, nullptr is a workaround. @@ -143,13 +160,22 @@ public: typename rclcpp::message_memory_strategy::MessageMemoryStrategy::SharedPtr msg_mem_strat = nullptr); - /* Create a timer. */ + /// Create a timer. + /* \param[in] period Time interval between triggers of the callback. + * \param[in] callback User-defined callback function. + * \param[in] group Callback group to execute this timer's callback in. + */ rclcpp::timer::WallTimer::SharedPtr create_wall_timer( std::chrono::nanoseconds period, rclcpp::timer::CallbackType callback, rclcpp::callback_group::CallbackGroup::SharedPtr group = nullptr); + /// Create a timer with a sub-nanosecond precision update period. + /* \param[in] period Time interval between triggers of the callback. + * \param[in] callback User-defined callback function. + * \param[in] group Callback group to execute this timer's callback in. + */ rclcpp::timer::WallTimer::SharedPtr create_wall_timer( std::chrono::duration period, diff --git a/rclcpp/include/rclcpp/publisher.hpp b/rclcpp/include/rclcpp/publisher.hpp index 5a95876..cd700e4 100644 --- a/rclcpp/include/rclcpp/publisher.hpp +++ b/rclcpp/include/rclcpp/publisher.hpp @@ -39,15 +39,22 @@ class Node; namespace publisher { -// TODO +/// A publisher publishes messages of any type to a topic. class Publisher { friend rclcpp::node::Node; -// TODO public: RCLCPP_SMART_PTR_DEFINITIONS(Publisher); + /// Default constructor. + /* Typically, a publisher is not created through this method, but instead is created through a + * call to `Node::create_publisher`. + * \param[in] node_handle The corresponding rmw representation of the owner node. + * \param[in] publisher_handle The rmw publisher handle corresponding to this publisher. + * \param[in] topic The topic that this publisher publishes on. + * \param[in] queue_size The maximum number of unpublished messages to queue. + */ Publisher( std::shared_ptr node_handle, rmw_publisher_t * publisher_handle, @@ -67,6 +74,7 @@ public: } } + /// Default destructor. virtual ~Publisher() { if (intra_process_publisher_handle_) { @@ -87,6 +95,10 @@ public: } } + /// Send a message to the topic for this publisher. + /* This function is templated on the input message type, MessageT. + * \param[in] msg A shared pointer to the message to send. + */ template void publish(std::shared_ptr & msg) @@ -114,36 +126,54 @@ public: } } + /// Get the topic that this publisher publishes on. + // \return The topic name. const std::string & get_topic_name() const { return topic_; } + /// Get the queue size for this publisher. + // \return The queue size. size_t get_queue_size() const { return queue_size_; } + /// Get the global identifier for this publisher (used in rmw and by DDS). + // \return The gid. const rmw_gid_t & get_gid() const { return rmw_gid_; } + /// Get the global identifier for this publisher used by intra-process communication. + // \return The intra-process gid. const rmw_gid_t & get_intra_process_gid() const { return intra_process_rmw_gid_; } + /// Compare this publisher to a gid. + /* Note that this function calls the next function. + * \param[in] gid Reference to a gid. + * \return True if the publisher's gid matches the input. + */ bool operator==(const rmw_gid_t & gid) const { return *this == &gid; } + /// Compare this publisher to a pointer gid. + /* A wrapper for comparing this publisher's gid to the input using rmw_compare_gids_equal. + * \param[in] gid A pointer to a gid. + * \return True if this publisher's gid matches the input. + */ bool operator==(const rmw_gid_t * gid) const { diff --git a/rclcpp/include/rclcpp/rclcpp.hpp b/rclcpp/include/rclcpp/rclcpp.hpp index 6d388d1..fb7b772 100644 --- a/rclcpp/include/rclcpp/rclcpp.hpp +++ b/rclcpp/include/rclcpp/rclcpp.hpp @@ -51,6 +51,8 @@ operator"" _ns(long double ns) std::chrono::duration(ns)); } +// Namespace escalations. +// For example, this next line escalates type "rclcpp:node::Node" to "rclcpp::Node" using rclcpp::node::Node; using rclcpp::publisher::Publisher; using rclcpp::subscription::SubscriptionBase; @@ -66,12 +68,16 @@ using rclcpp::utilities::shutdown; using rclcpp::utilities::init; using rclcpp::utilities::sleep_for; +/// Create a default single-threaded executor and execute any immediately available work. +// \param[in] node_ptr Shared pointer to the node to spin. void spin_some(Node::SharedPtr & node_ptr) { rclcpp::executors::SingleThreadedExecutor executor; executor.spin_node_some(node_ptr); } +/// Create a default single-threaded executor and spin the specified node. +// \param[in] node_ptr Shared pointer to the node to spin. void spin(Node::SharedPtr & node_ptr) { rclcpp::executors::SingleThreadedExecutor executor; diff --git a/rclcpp/include/rclcpp/strategies/message_pool_memory_strategy.hpp b/rclcpp/include/rclcpp/strategies/message_pool_memory_strategy.hpp index 28f2efa..983677a 100644 --- a/rclcpp/include/rclcpp/strategies/message_pool_memory_strategy.hpp +++ b/rclcpp/include/rclcpp/strategies/message_pool_memory_strategy.hpp @@ -25,7 +25,12 @@ namespace strategies namespace message_pool_memory_strategy { -// TODO +/// Completely static memory allocation strategy for messages. +/* Templated on the type of message pooled by this class and the size of the message pool. + * Templating allows the program to determine the memory required for this object at compile time. + * The size of the message pool should be at least the largest number of concurrent accesses to + * the subscription (usually the number of threads). + */ template::value>::type * = nullptr> @@ -34,6 +39,8 @@ class MessagePoolMemoryStrategy { public: RCLCPP_SMART_PTR_DEFINITIONS(MessagePoolMemoryStrategy); + + /// Default constructor MessagePoolMemoryStrategy() : next_array_index_(0) { @@ -43,6 +50,11 @@ public: } } + /// Borrow a message from the message pool. + /* Manage the message pool ring buffer. + * Throw an exception if the next message was not available. + * \return Shared pointer to the borrowed message. + */ std::shared_ptr borrow_message() { size_t current_index = next_array_index_; @@ -57,6 +69,10 @@ public: return pool_[current_index].msg_ptr_; } + /// Return a message to the message pool. + /* Manage metadata in the message pool ring buffer to release the message. + * \param[in] msg Shared pointer to the message to return. + */ void return_message(std::shared_ptr & msg) { for (size_t i = 0; i < Size; ++i) { diff --git a/rclcpp/include/rclcpp/strategies/static_memory_strategy.hpp b/rclcpp/include/rclcpp/strategies/static_memory_strategy.hpp index 216f897..fd5f856 100644 --- a/rclcpp/include/rclcpp/strategies/static_memory_strategy.hpp +++ b/rclcpp/include/rclcpp/strategies/static_memory_strategy.hpp @@ -27,7 +27,8 @@ namespace memory_strategies namespace static_memory_strategy { -// TODO + +/// Representation of the upper bounds on the memory pools managed by StaticMemoryStrategy. struct ObjectPoolBounds { public: @@ -38,41 +39,68 @@ public: size_t max_guard_conditions; size_t pool_size; + /// Default constructor attempts to set reasonable default limits on the fields. ObjectPoolBounds() : max_subscriptions(10), max_services(10), max_clients(10), max_executables(1), max_guard_conditions(2), pool_size(1024) {} + // Setters implement named parameter idiom/method chaining + + /// Set the maximum number of subscriptions. + /* \param[in] subscriptions Maximum number of subscriptions. + * \return Reference to this object, for method chaining. + */ ObjectPoolBounds & set_max_subscriptions(size_t subscriptions) { max_subscriptions = subscriptions; return *this; } + /// Set the maximum number of services. + /* \param[in] services Maximum number of services. + * \return Reference to this object, for method chaining. + */ ObjectPoolBounds & set_max_services(size_t services) { max_services = services; return *this; } + /// Set the maximum number of clients. + /* \param[in] clients Maximum number of clients. + * \return Reference to this object, for method chaining. + */ ObjectPoolBounds & set_max_clients(size_t clients) { max_clients = clients; return *this; } + /// Set the maximum number of guard conditions. + /* \param[in] guard conditions Maximum number of guard conditions. + * \return Reference to this object, for method chaining. + */ ObjectPoolBounds & set_max_guard_conditions(size_t guard_conditions) { max_guard_conditions = guard_conditions; return *this; } + /// Set the maximum number of executables. + /* \param[in] executables Maximum number of executables. + * \return Reference to this object, for method chaining. + */ ObjectPoolBounds & set_max_executables(size_t executables) { max_executables = executables; return *this; } + /// Set the maximum memory pool size. + /* \param[in] executables Maximum memory pool size. + * \return Reference to this object, for method chaining. + */ ObjectPoolBounds & set_memory_pool_size(size_t pool) { pool_size = pool; @@ -81,10 +109,19 @@ public: }; -// TODO +/// Static memory allocation alternative to the default memory strategy. +/* The name is a bit of a misnomer. The memory managed by this class is actually allocated + * dynamically in the constructor, but no subsequent accesses to the class (besides the destructor) + * allocate or free memory. + * StaticMemoryStrategy puts a hard limit on the number of subscriptions, etc. that can be executed + * in one iteration of `Executor::spin`. Thus it allows for memory allocation optimization for + * situations where a limit on the number of such entities is known. + */ class StaticMemoryStrategy : public memory_strategy::MemoryStrategy { public: + /// Default constructor. + // \param[in] bounds Representation of the limits on memory managed by this class. StaticMemoryStrategy(ObjectPoolBounds bounds = ObjectPoolBounds()) : bounds_(bounds), memory_pool_(nullptr), subscription_pool_(nullptr), service_pool_(nullptr), guard_condition_pool_(nullptr), executable_pool_(nullptr) @@ -132,6 +169,7 @@ public: } } + /// Default destructor. Free all allocated memory. ~StaticMemoryStrategy() { if (bounds_.pool_size) { @@ -151,6 +189,11 @@ public: } } + /// Borrow handles by returning a pointer to the preallocated object pool for the specified type. + /* \param[in] The type of entity that this function is requesting for. + * \param[in] The number of handles to borrow. + * \return Pointer to the allocated handles. + */ void ** borrow_handles(HandleType type, size_t number_of_handles) { switch (type) { @@ -184,6 +227,10 @@ public: throw std::runtime_error("Unrecognized enum, could not borrow handle memory."); } + /// Return the borrowed handles by clearing the object pool for the correspondign type. + /* \param[in] The type of entity that this function is returning. + * \param[in] Pointer to the handles returned. + */ void return_handles(HandleType type, void ** handles) { (void)handles; @@ -213,10 +260,12 @@ public: } } + /// Instantiate the next executable by borrowing space from the preallocated executables pool. + // \return Shared pointer to the executable. executor::AnyExecutable::SharedPtr instantiate_next_executable() { if (exec_seq_ >= bounds_.max_executables) { - // wrap around + // wrap around (ring buffer logic) exec_seq_ = 0; } size_t prev_exec_seq_ = exec_seq_; @@ -226,6 +275,7 @@ public: throw std::runtime_error("Executable pool member was NULL"); } + // Make sure to clear the executable fields. executable_pool_[prev_exec_seq_]->subscription.reset(); executable_pool_[prev_exec_seq_]->timer.reset(); executable_pool_[prev_exec_seq_]->service.reset(); @@ -236,6 +286,10 @@ public: return executable_pool_[prev_exec_seq_]; } + /// General allocate: reserve space in the memory pool reserved by this function. + /* \param[in] size Number of bytes to allocate. + * \return Pointer to the allocated chunk of memory. + */ void * alloc(size_t size) { // Extremely naive static allocation strategy @@ -255,6 +309,9 @@ public: return memory_pool_[prev_pool_seq]; } + /// Release the allocated memory in the memory pool. + /* \param[in] Pointer to deallocate. + */ void free(void * ptr) { if (memory_map_.count(ptr) == 0) { diff --git a/rclcpp/include/rclcpp/subscription.hpp b/rclcpp/include/rclcpp/subscription.hpp index d74e6bb..1739c8a 100644 --- a/rclcpp/include/rclcpp/subscription.hpp +++ b/rclcpp/include/rclcpp/subscription.hpp @@ -45,14 +45,20 @@ class Node; namespace subscription { +/// Virtual base class for subscriptions. This pattern allows us to iterate over different template +/// specializations of Subscription, among other things. class SubscriptionBase { friend class rclcpp::executor::Executor; -// TODO public: RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(SubscriptionBase); + /// Default constructor. + /* \param[in] node_handle The rmw representation of the node that owns this subscription. + * \param[in] topic_name Name of the topic to subscribe to. + * \param[in] ignore_local_publications True to ignore local publications (unused). + */ SubscriptionBase( std::shared_ptr node_handle, rmw_subscription_t * subscription_handle, @@ -68,6 +74,7 @@ public: (void)ignore_local_publications_; } + /// Default destructor. virtual ~SubscriptionBase() { if (subscription_handle_) { @@ -89,14 +96,26 @@ public: } } + /// Get the topic that this subscription is subscribed on. const std::string & get_topic_name() const { return this->topic_name_; } + /// Borrow a new message. + // \return Shared pointer to the fresh message. virtual std::shared_ptr create_message() = 0; + + /// Check if we need to handle the message, and execute the callback if we do. + /* \param[in] message Shared pointer to the message to handle. + * \param[in] sender_id Global identifier of the entity that sent this message. + */ virtual void handle_message(std::shared_ptr & message, const rmw_gid_t * sender_id) = 0; + + /// Return the message borrowed in create_message. + // \param[in] Shared pointer to the returned message. virtual void return_message(std::shared_ptr & message) = 0; + virtual void handle_intra_process_message(rcl_interfaces::msg::IntraProcessMessage & ipm) = 0; protected: @@ -114,17 +133,25 @@ private: }; -// TODO +/// Subscription implementation, templated on the type of message this subscription receives. template class Subscription : public SubscriptionBase { friend class rclcpp::node::Node; -// TODO public: using CallbackType = std::function &)>; RCLCPP_SMART_PTR_DEFINITIONS(Subscription); + /// Default constructor. + /* The constructor for a subscription is almost never called directly. Instead, subscriptions + * should be instantiated through Node::create_subscription. + * \param[in] node_handle rmw representation of the node that owns this subscription. + * \param[in] topic_name Name of the topic to subscribe to. + * \param[in] ignore_local_publications True to ignore local publications (unused). + * \param[in] callback User-defined callback to call when a message is received. + * \param[in] memory_strategy The memory strategy to be used for managing message memory. + */ Subscription( std::shared_ptr node_handle, rmw_subscription_t * subscription_handle, @@ -140,14 +167,21 @@ public: matches_any_intra_process_publishers_(nullptr) {} + /// Support dynamically setting the message memory strategy. + /* Behavior may be undefined if called while the subscription could be executing. + * \param[in] message_memory_strategy Shared pointer to the memory strategy to set. + */ void set_message_memory_strategy( typename message_memory_strategy::MessageMemoryStrategy::SharedPtr message_memory_strategy) { message_memory_strategy_ = message_memory_strategy; } - std::shared_ptr create_message() { + /* The default message memory strategy provides a dynamically allocated message on each call to + * create_message, though alternative memory strategies that re-use a preallocated message may be + * used (see rclcpp/strategies/message_pool_memory_strategy.hpp). + */ return message_memory_strategy_->borrow_message(); } diff --git a/rclcpp/include/rclcpp/timer.hpp b/rclcpp/include/rclcpp/timer.hpp index 7c5d2bd..d488f80 100644 --- a/rclcpp/include/rclcpp/timer.hpp +++ b/rclcpp/include/rclcpp/timer.hpp @@ -66,12 +66,20 @@ public: this->canceled_ = true; } + /// Check how long the timer has until its next scheduled callback. + // \return A std::chrono::duration representing the relative time until the next callback. virtual std::chrono::nanoseconds time_until_trigger() = 0; + /// Is the clock steady (i.e. is the time between ticks constant?) + // \return True if the clock used by this timer is steady. virtual bool is_steady() = 0; - // Interface for externally triggering the timer event + /// Check if the timer needs to trigger the callback. + /* This function expects its caller to immediately trigger the callback after this function, + * since it maintains the last time the callback was triggered. + * \return True if the timer needs to trigger. + */ virtual bool check_and_trigger() = 0; protected: @@ -82,7 +90,7 @@ protected: }; -// TODO +/// Generic timer templated on the clock type. Periodically executes a user-specified callback. template class GenericTimer : public TimerBase { @@ -91,6 +99,10 @@ class GenericTimer : public TimerBase public: RCLCPP_SMART_PTR_DEFINITIONS(GenericTimer); + /// Default constructor. + /* \param[in] period The interval at which the timer fires. + * \param[in] callback User-specified callback function. + */ GenericTimer(std::chrono::nanoseconds period, CallbackType callback) : TimerBase(period, callback), loop_rate_(period) { @@ -99,12 +111,13 @@ public: last_triggered_time_ = Clock::now() - period; } + /// Default destructor. virtual ~GenericTimer() { + // Stop the timer from running. cancel(); } - // return: true to trigger callback on the next "execute_timer" call in executor bool check_and_trigger() { diff --git a/rclcpp/include/rclcpp/utilities.hpp b/rclcpp/include/rclcpp/utilities.hpp index ab09b58..ec9c754 100644 --- a/rclcpp/include/rclcpp/utilities.hpp +++ b/rclcpp/include/rclcpp/utilities.hpp @@ -38,10 +38,14 @@ namespace { +/// Represent the status of the global interrupt signal. volatile sig_atomic_t g_signal_status = 0; +/// Guard condition for interrupting the rmw implementation when the global interrupt signal fired. rmw_guard_condition_t * g_sigint_guard_cond_handle = \ rmw_create_guard_condition(); +/// Condition variable for timed sleep (see sleep_for). std::condition_variable g_interrupt_condition_variable; +/// Mutex for protecting the global condition variable. std::mutex g_interrupt_mutex; #ifdef HAS_SIGACTION @@ -50,6 +54,9 @@ struct sigaction old_action; void (* old_signal_handler)(int) = 0; #endif +/// When the interrupt signal fires, the signal handler notifies the condition variable to wake up +/// and triggers the interrupt guard condition, so that all global threads managed by rclcpp +/// are interrupted. void #ifdef HAS_SIGACTION signal_handler(int signal_value, siginfo_t * siginfo, void * context) @@ -98,7 +105,10 @@ RMW_THREAD_LOCAL size_t thread_id = 0; namespace utilities { -// TODO +/// Initialize communications via the rmw implementation and set up a global signal handler. +/* \param[in] argc Number of arguments. + * \param[in] argv Argument vector. Will eventually be used for passing options to rclcpp. + */ void init(int argc, char * argv[]) { @@ -139,14 +149,15 @@ init(int argc, char * argv[]) } } -// TODO +/// Check rclcpp's status. +// \return True if SIGINT hasn't fired yet, false otherwise. bool ok() { return ::g_signal_status == 0; } -// TODO +/// Notify the signal handler and rmw that rclcpp is shutting down. void shutdown() { @@ -160,13 +171,17 @@ shutdown() } +/// Get a handle to the rmw guard condition that manages the signal handler. rmw_guard_condition_t * get_global_sigint_guard_condition() { return ::g_sigint_guard_cond_handle; } -// TODO +/// Use the global condition variable to block for the specified amount of time. +/* \param[in] nanoseconds A std::chrono::duration representing how long to sleep for. + * \return True if the condition variable did not timeout. + */ bool sleep_for(const std::chrono::nanoseconds & nanoseconds) { From 3ef83ec29282708a9f71d608da5a5cae55265b96 Mon Sep 17 00:00:00 2001 From: Jackie Kay Date: Wed, 26 Aug 2015 17:26:50 -0700 Subject: [PATCH 3/4] uncrustify --- rclcpp/include/rclcpp/executor.hpp | 2 +- rclcpp/include/rclcpp/timer.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rclcpp/include/rclcpp/executor.hpp b/rclcpp/include/rclcpp/executor.hpp index 0f6b1f3..3063120 100644 --- a/rclcpp/include/rclcpp/executor.hpp +++ b/rclcpp/include/rclcpp/executor.hpp @@ -37,7 +37,7 @@ namespace executor { /// Coordinates the order and timing of available communication tasks. -/* Executor provides spin functions (including spin_node_once and spin_some). +/* Executor provides spin functions (including spin_node_once and spin_some). * It coordinates the nodes and callback groups by looking for available work and completing it, * based on the threading or concurrency scheme provided by the subclass implementation. * An example of available work is executing a subscription callback, or a timer callback. diff --git a/rclcpp/include/rclcpp/timer.hpp b/rclcpp/include/rclcpp/timer.hpp index d488f80..c788fa6 100644 --- a/rclcpp/include/rclcpp/timer.hpp +++ b/rclcpp/include/rclcpp/timer.hpp @@ -101,7 +101,7 @@ public: /// Default constructor. /* \param[in] period The interval at which the timer fires. - * \param[in] callback User-specified callback function. + * \param[in] callback User-specified callback function. */ GenericTimer(std::chrono::nanoseconds period, CallbackType callback) : TimerBase(period, callback), loop_rate_(period) From 9f0cda20af5a5a8962cbb442f4cc1d1d085258d9 Mon Sep 17 00:00:00 2001 From: Jackie Kay Date: Thu, 27 Aug 2015 10:10:14 -0700 Subject: [PATCH 4/4] Correct doxygen blocks --- rclcpp/include/rclcpp/executor.hpp | 28 ++++++++++------ rclcpp/include/rclcpp/memory_strategy.hpp | 15 ++++++--- rclcpp/include/rclcpp/node.hpp | 18 ++++++---- rclcpp/include/rclcpp/publisher.hpp | 12 ++++--- .../message_pool_memory_strategy.hpp | 9 +++-- .../strategies/static_memory_strategy.hpp | 33 ++++++++++++------- rclcpp/include/rclcpp/subscription.hpp | 12 ++++--- rclcpp/include/rclcpp/timer.hpp | 6 ++-- rclcpp/include/rclcpp/utilities.hpp | 14 +++++--- 9 files changed, 97 insertions(+), 50 deletions(-) diff --git a/rclcpp/include/rclcpp/executor.hpp b/rclcpp/include/rclcpp/executor.hpp index 3063120..801259a 100644 --- a/rclcpp/include/rclcpp/executor.hpp +++ b/rclcpp/include/rclcpp/executor.hpp @@ -36,8 +36,9 @@ namespace rclcpp namespace executor { -/// Coordinates the order and timing of available communication tasks. -/* Executor provides spin functions (including spin_node_once and spin_some). +/// Coordinate the order and timing of available communication tasks. +/** + * Executor provides spin functions (including spin_node_once and spin_some). * It coordinates the nodes and callback groups by looking for available work and completing it, * based on the threading or concurrency scheme provided by the subclass implementation. * An example of available work is executing a subscription callback, or a timer callback. @@ -79,7 +80,8 @@ public: virtual void spin() = 0; /// Add a node to the executor. - /* An executor can have zero or more nodes which provide work during `spin` functions. + /** + * An executor can have zero or more nodes which provide work during `spin` functions. * \param[in] node_ptr Shared pointer to the node to be added. * \param[in] notify True to trigger the interrupt guard condition during this function. If * the executor is blocked at the rmw layer while waiting for work and it is notified that a new @@ -107,7 +109,8 @@ public: } /// Remove a node from the executor. - /* \param[in] node_ptr Shared pointer to the node to remove. + /** + * \param[in] node_ptr Shared pointer to the node to remove. * \param[in] notify True to trigger the interrupt guard condition and wake up the executor. * This is useful if the last node was removed from the executor while the executor was blocked * waiting for work in another thread, because otherwise the executor would never be notified. @@ -137,7 +140,8 @@ public: } /// Add a node to executor, execute the next available unit of work, and remove the node. - /* \param[in] node Shared pointer to the node to add. + /** + * \param[in] node Shared pointer to the node to add. * \param[in] timeout How long to wait for work to become available. Negative values cause * spin_node_once to block indefinitely (the default behavior). A timeout of 0 causes this * function to be non-blocking. @@ -156,7 +160,8 @@ public: } /// Add a node, complete all immediately available work, and remove the node. - /* \param[in] node Shared pointer to the node to add. + /** + * \param[in] node Shared pointer to the node to add. */ void spin_node_some(rclcpp::node::Node::SharedPtr & node) { @@ -166,7 +171,8 @@ public: } /// Complete all available queued work without blocking. - /* This function can be overridden. The default implementation is suitable for a + /** + * This function can be overridden. The default implementation is suitable for a * single-threaded model of execution. * Adding subscriptions, timers, services, etc. with blocking callbacks will cause this function * to block (which may have unintended consequences). @@ -181,7 +187,8 @@ public: } /// Support dynamic switching of the memory strategy. - /* Switching the memory strategy while the executor is spinning in another threading could have + /** + * Switching the memory strategy while the executor is spinning in another threading could have * unintended consequences. * \param[in] memory_strategy Shared pointer to the memory strategy to set. */ @@ -196,8 +203,9 @@ public: protected: /// Find the next available executable and do the work associated with it. - // \param[in] any_exec Union structure that can hold any executable type (timer, subscription, - // service, client). + /** \param[in] any_exec Union structure that can hold any executable type (timer, subscription, + * service, client). + */ void execute_any_executable(AnyExecutable::SharedPtr & any_exec) { diff --git a/rclcpp/include/rclcpp/memory_strategy.hpp b/rclcpp/include/rclcpp/memory_strategy.hpp index c170b9a..adb2bae 100644 --- a/rclcpp/include/rclcpp/memory_strategy.hpp +++ b/rclcpp/include/rclcpp/memory_strategy.hpp @@ -31,7 +31,8 @@ namespace memory_strategy { /// Delegate for handling memory allocations while the Executor is executing. -/* By default, the memory strategy dynamically allocates memory for structures that come in from +/** + * By default, the memory strategy dynamically allocates memory for structures that come in from * the rmw implementation after the executor waits for work, based on the number of entities that * come through. */ @@ -44,7 +45,8 @@ public: RCLCPP_SMART_PTR_DEFINITIONS(MemoryStrategy); /// Borrow memory for storing data for subscriptions, services, clients, or guard conditions. - /* The default implementation ignores the handle type and dynamically allocates the memory. + /** + * The default implementation ignores the handle type and dynamically allocates the memory. * \param[in] The type of entity that this function is requesting for. * \param[in] The number of handles to borrow. * \return Pointer to the allocated handles. @@ -56,7 +58,8 @@ public: } /// Return the memory borrowed in borrow_handles. - /* return_handles should always mirror the way memory was borrowed in borrow_handles. + /** + * return_handles should always mirror the way memory was borrowed in borrow_handles. * \param[in] The type of entity that this function is returning. * \param[in] Pointer to the handles returned. */ @@ -74,7 +77,8 @@ public: } /// Implementation of a general-purpose allocation function. - /* \param[in] size Number of bytes to allocate. + /** + * \param[in] size Number of bytes to allocate. * \return Pointer to the allocated chunk of memory. */ virtual void * alloc(size_t size) @@ -86,7 +90,8 @@ public: } /// Implementation of a general-purpose free. - /* \param[in] Pointer to deallocate. + /** + * \param[in] Pointer to deallocate. */ virtual void free(void * ptr) { diff --git a/rclcpp/include/rclcpp/node.hpp b/rclcpp/include/rclcpp/node.hpp index eceb816..31d58c8 100644 --- a/rclcpp/include/rclcpp/node.hpp +++ b/rclcpp/include/rclcpp/node.hpp @@ -101,14 +101,16 @@ public: RCLCPP_SMART_PTR_DEFINITIONS(Node); /// Create a new node with the specified name. - /* \param[in] node_name Name of the node. + /** + * \param[in] node_name Name of the node. * \param[in] use_intra_process_comms True to use the optimized intra-process communication * pipeline to pass messages between nodes in the same process using shared memory. */ Node(const std::string & node_name, bool use_intra_process_comms = false); /// Create a node based on the node name and a rclcpp::context::Context. - /* \param[in] node_name Name of the node. + /** + * \param[in] node_name Name of the node. * \param[in] context The context for the node (usually represents the state of a process). * \param[in] use_intra_process_comms True to use the optimized intra-process communication * pipeline to pass messages between nodes in the same process using shared memory. @@ -127,7 +129,8 @@ public: create_callback_group(rclcpp::callback_group::CallbackGroupType group_type); /// Create and return a Publisher. - /* \param[in] topic_name The topic for this publisher to publish on. + /** + * \param[in] topic_name The topic for this publisher to publish on. * \param[in] qos_profile The quality of service profile to pass on to the rmw implementation. * \return Shared pointer to the created publisher. */ @@ -137,7 +140,8 @@ public: const std::string & topic_name, const rmw_qos_profile_t & qos_profile); /// Create and return a Subscription. - /* \param[in] topic_name The topic to subscribe on. + /** + * \param[in] topic_name The topic to subscribe on. * \param[in] qos_profile The quality of service profile to pass on to the rmw implementation. * \param[in] callback The user-defined callback function. * \param[in] group The callback group for this subscription. NULL for no callback group. @@ -161,7 +165,8 @@ public: msg_mem_strat = nullptr); /// Create a timer. - /* \param[in] period Time interval between triggers of the callback. + /** + * \param[in] period Time interval between triggers of the callback. * \param[in] callback User-defined callback function. * \param[in] group Callback group to execute this timer's callback in. */ @@ -172,7 +177,8 @@ public: rclcpp::callback_group::CallbackGroup::SharedPtr group = nullptr); /// Create a timer with a sub-nanosecond precision update period. - /* \param[in] period Time interval between triggers of the callback. + /** + * \param[in] period Time interval between triggers of the callback. * \param[in] callback User-defined callback function. * \param[in] group Callback group to execute this timer's callback in. */ diff --git a/rclcpp/include/rclcpp/publisher.hpp b/rclcpp/include/rclcpp/publisher.hpp index cd700e4..014cf18 100644 --- a/rclcpp/include/rclcpp/publisher.hpp +++ b/rclcpp/include/rclcpp/publisher.hpp @@ -48,7 +48,8 @@ public: RCLCPP_SMART_PTR_DEFINITIONS(Publisher); /// Default constructor. - /* Typically, a publisher is not created through this method, but instead is created through a + /** + * Typically, a publisher is not created through this method, but instead is created through a * call to `Node::create_publisher`. * \param[in] node_handle The corresponding rmw representation of the owner node. * \param[in] publisher_handle The rmw publisher handle corresponding to this publisher. @@ -96,7 +97,8 @@ public: } /// Send a message to the topic for this publisher. - /* This function is templated on the input message type, MessageT. + /** + * This function is templated on the input message type, MessageT. * \param[in] msg A shared pointer to the message to send. */ template @@ -159,7 +161,8 @@ public: } /// Compare this publisher to a gid. - /* Note that this function calls the next function. + /** + * Note that this function calls the next function. * \param[in] gid Reference to a gid. * \return True if the publisher's gid matches the input. */ @@ -170,7 +173,8 @@ public: } /// Compare this publisher to a pointer gid. - /* A wrapper for comparing this publisher's gid to the input using rmw_compare_gids_equal. + /** + * A wrapper for comparing this publisher's gid to the input using rmw_compare_gids_equal. * \param[in] gid A pointer to a gid. * \return True if this publisher's gid matches the input. */ diff --git a/rclcpp/include/rclcpp/strategies/message_pool_memory_strategy.hpp b/rclcpp/include/rclcpp/strategies/message_pool_memory_strategy.hpp index 983677a..43e518c 100644 --- a/rclcpp/include/rclcpp/strategies/message_pool_memory_strategy.hpp +++ b/rclcpp/include/rclcpp/strategies/message_pool_memory_strategy.hpp @@ -26,7 +26,8 @@ namespace message_pool_memory_strategy { /// Completely static memory allocation strategy for messages. -/* Templated on the type of message pooled by this class and the size of the message pool. +/** + * Templated on the type of message pooled by this class and the size of the message pool. * Templating allows the program to determine the memory required for this object at compile time. * The size of the message pool should be at least the largest number of concurrent accesses to * the subscription (usually the number of threads). @@ -51,7 +52,8 @@ public: } /// Borrow a message from the message pool. - /* Manage the message pool ring buffer. + /** + * Manage the message pool ring buffer. * Throw an exception if the next message was not available. * \return Shared pointer to the borrowed message. */ @@ -70,7 +72,8 @@ public: } /// Return a message to the message pool. - /* Manage metadata in the message pool ring buffer to release the message. + /** + * Manage metadata in the message pool ring buffer to release the message. * \param[in] msg Shared pointer to the message to return. */ void return_message(std::shared_ptr & msg) diff --git a/rclcpp/include/rclcpp/strategies/static_memory_strategy.hpp b/rclcpp/include/rclcpp/strategies/static_memory_strategy.hpp index fd5f856..5cfdbe3 100644 --- a/rclcpp/include/rclcpp/strategies/static_memory_strategy.hpp +++ b/rclcpp/include/rclcpp/strategies/static_memory_strategy.hpp @@ -48,7 +48,8 @@ public: // Setters implement named parameter idiom/method chaining /// Set the maximum number of subscriptions. - /* \param[in] subscriptions Maximum number of subscriptions. + /** + * \param[in] subscriptions Maximum number of subscriptions. * \return Reference to this object, for method chaining. */ ObjectPoolBounds & set_max_subscriptions(size_t subscriptions) @@ -58,7 +59,8 @@ public: } /// Set the maximum number of services. - /* \param[in] services Maximum number of services. + /** + * \param[in] services Maximum number of services. * \return Reference to this object, for method chaining. */ ObjectPoolBounds & set_max_services(size_t services) @@ -68,7 +70,8 @@ public: } /// Set the maximum number of clients. - /* \param[in] clients Maximum number of clients. + /** + * \param[in] clients Maximum number of clients. * \return Reference to this object, for method chaining. */ ObjectPoolBounds & set_max_clients(size_t clients) @@ -78,7 +81,8 @@ public: } /// Set the maximum number of guard conditions. - /* \param[in] guard conditions Maximum number of guard conditions. + /** + * \param[in] guard conditions Maximum number of guard conditions. * \return Reference to this object, for method chaining. */ ObjectPoolBounds & set_max_guard_conditions(size_t guard_conditions) @@ -88,7 +92,8 @@ public: } /// Set the maximum number of executables. - /* \param[in] executables Maximum number of executables. + /** + * \param[in] executables Maximum number of executables. * \return Reference to this object, for method chaining. */ ObjectPoolBounds & set_max_executables(size_t executables) @@ -98,7 +103,8 @@ public: } /// Set the maximum memory pool size. - /* \param[in] executables Maximum memory pool size. + /** + * \param[in] executables Maximum memory pool size. * \return Reference to this object, for method chaining. */ ObjectPoolBounds & set_memory_pool_size(size_t pool) @@ -110,7 +116,8 @@ public: /// Static memory allocation alternative to the default memory strategy. -/* The name is a bit of a misnomer. The memory managed by this class is actually allocated +/** + * The name is a bit of a misnomer. The memory managed by this class is actually allocated * dynamically in the constructor, but no subsequent accesses to the class (besides the destructor) * allocate or free memory. * StaticMemoryStrategy puts a hard limit on the number of subscriptions, etc. that can be executed @@ -190,7 +197,8 @@ public: } /// Borrow handles by returning a pointer to the preallocated object pool for the specified type. - /* \param[in] The type of entity that this function is requesting for. + /** + * \param[in] The type of entity that this function is requesting for. * \param[in] The number of handles to borrow. * \return Pointer to the allocated handles. */ @@ -228,7 +236,8 @@ public: } /// Return the borrowed handles by clearing the object pool for the correspondign type. - /* \param[in] The type of entity that this function is returning. + /** + * \param[in] The type of entity that this function is returning. * \param[in] Pointer to the handles returned. */ void return_handles(HandleType type, void ** handles) @@ -287,7 +296,8 @@ public: } /// General allocate: reserve space in the memory pool reserved by this function. - /* \param[in] size Number of bytes to allocate. + /** + * \param[in] size Number of bytes to allocate. * \return Pointer to the allocated chunk of memory. */ void * alloc(size_t size) @@ -310,7 +320,8 @@ public: } /// Release the allocated memory in the memory pool. - /* \param[in] Pointer to deallocate. + /** + * \param[in] Pointer to deallocate. */ void free(void * ptr) { diff --git a/rclcpp/include/rclcpp/subscription.hpp b/rclcpp/include/rclcpp/subscription.hpp index 1739c8a..e73bf9d 100644 --- a/rclcpp/include/rclcpp/subscription.hpp +++ b/rclcpp/include/rclcpp/subscription.hpp @@ -55,7 +55,8 @@ public: RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(SubscriptionBase); /// Default constructor. - /* \param[in] node_handle The rmw representation of the node that owns this subscription. + /** + * \param[in] node_handle The rmw representation of the node that owns this subscription. * \param[in] topic_name Name of the topic to subscribe to. * \param[in] ignore_local_publications True to ignore local publications (unused). */ @@ -107,7 +108,8 @@ public: virtual std::shared_ptr create_message() = 0; /// Check if we need to handle the message, and execute the callback if we do. - /* \param[in] message Shared pointer to the message to handle. + /** + * \param[in] message Shared pointer to the message to handle. * \param[in] sender_id Global identifier of the entity that sent this message. */ virtual void handle_message(std::shared_ptr & message, const rmw_gid_t * sender_id) = 0; @@ -144,7 +146,8 @@ public: RCLCPP_SMART_PTR_DEFINITIONS(Subscription); /// Default constructor. - /* The constructor for a subscription is almost never called directly. Instead, subscriptions + /** + * The constructor for a subscription is almost never called directly. Instead, subscriptions * should be instantiated through Node::create_subscription. * \param[in] node_handle rmw representation of the node that owns this subscription. * \param[in] topic_name Name of the topic to subscribe to. @@ -168,7 +171,8 @@ public: {} /// Support dynamically setting the message memory strategy. - /* Behavior may be undefined if called while the subscription could be executing. + /** + * Behavior may be undefined if called while the subscription could be executing. * \param[in] message_memory_strategy Shared pointer to the memory strategy to set. */ void set_message_memory_strategy( diff --git a/rclcpp/include/rclcpp/timer.hpp b/rclcpp/include/rclcpp/timer.hpp index c788fa6..b68d954 100644 --- a/rclcpp/include/rclcpp/timer.hpp +++ b/rclcpp/include/rclcpp/timer.hpp @@ -76,7 +76,8 @@ public: virtual bool is_steady() = 0; /// Check if the timer needs to trigger the callback. - /* This function expects its caller to immediately trigger the callback after this function, + /** + * This function expects its caller to immediately trigger the callback after this function, * since it maintains the last time the callback was triggered. * \return True if the timer needs to trigger. */ @@ -100,7 +101,8 @@ public: RCLCPP_SMART_PTR_DEFINITIONS(GenericTimer); /// Default constructor. - /* \param[in] period The interval at which the timer fires. + /** + * \param[in] period The interval at which the timer fires. * \param[in] callback User-specified callback function. */ GenericTimer(std::chrono::nanoseconds period, CallbackType callback) diff --git a/rclcpp/include/rclcpp/utilities.hpp b/rclcpp/include/rclcpp/utilities.hpp index ec9c754..e0d2a11 100644 --- a/rclcpp/include/rclcpp/utilities.hpp +++ b/rclcpp/include/rclcpp/utilities.hpp @@ -54,9 +54,11 @@ struct sigaction old_action; void (* old_signal_handler)(int) = 0; #endif -/// When the interrupt signal fires, the signal handler notifies the condition variable to wake up -/// and triggers the interrupt guard condition, so that all global threads managed by rclcpp -/// are interrupted. +/// Handle the interrupt signal. +/** When the interrupt signal fires, the signal handler notifies the condition variable to wake up + * and triggers the interrupt guard condition, so that all global threads managed by rclcpp + * are interrupted. + */ void #ifdef HAS_SIGACTION signal_handler(int signal_value, siginfo_t * siginfo, void * context) @@ -106,7 +108,8 @@ namespace utilities { /// Initialize communications via the rmw implementation and set up a global signal handler. -/* \param[in] argc Number of arguments. +/** + * \param[in] argc Number of arguments. * \param[in] argv Argument vector. Will eventually be used for passing options to rclcpp. */ void @@ -179,7 +182,8 @@ get_global_sigint_guard_condition() } /// Use the global condition variable to block for the specified amount of time. -/* \param[in] nanoseconds A std::chrono::duration representing how long to sleep for. +/** + * \param[in] nanoseconds A std::chrono::duration representing how long to sleep for. * \return True if the condition variable did not timeout. */ bool