@@ -57,6 +57,8 @@ class SimpleActionServer
5757 * @param server_timeout Timeout to to react to stop or preemption requests
5858 * @param spin_thread Whether to spin with a dedicated thread internally
5959 * @param options Options to pass to the underlying rcl_action_server_t
60+ * @param realtime Whether the action server's worker thread should have elevated
61+ * prioritization (soft realtime)
6062 */
6163 template <typename NodeT>
6264 explicit SimpleActionServer (
@@ -66,13 +68,15 @@ class SimpleActionServer
6668 CompletionCallback completion_callback = nullptr ,
6769 std::chrono::milliseconds server_timeout = std::chrono::milliseconds(500 ),
6870 bool spin_thread = false,
69- const rcl_action_server_options_t & options = rcl_action_server_get_default_options())
71+ const rcl_action_server_options_t & options = rcl_action_server_get_default_options(),
72+ const bool realtime = false)
7073 : SimpleActionServer(
7174 node->get_node_base_interface (),
7275 node->get_node_clock_interface(),
7376 node->get_node_logging_interface(),
7477 node->get_node_waitables_interface(),
75- action_name, execute_callback, completion_callback, server_timeout, spin_thread, options)
78+ action_name, execute_callback, completion_callback,
79+ server_timeout, spin_thread, options, realtime)
7680 {}
7781
7882 /* *
@@ -83,6 +87,8 @@ class SimpleActionServer
8387 * @param server_timeout Timeout to to react to stop or preemption requests
8488 * @param spin_thread Whether to spin with a dedicated thread internally
8589 * @param options Options to pass to the underlying rcl_action_server_t
90+ * @param realtime Whether the action server's worker thread should have elevated
91+ * prioritization (soft realtime)
8692 */
8793 explicit SimpleActionServer (
8894 rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base_interface,
@@ -94,7 +100,8 @@ class SimpleActionServer
94100 CompletionCallback completion_callback = nullptr ,
95101 std::chrono::milliseconds server_timeout = std::chrono::milliseconds(500 ),
96102 bool spin_thread = false,
97- const rcl_action_server_options_t & options = rcl_action_server_get_default_options())
103+ const rcl_action_server_options_t & options = rcl_action_server_get_default_options(),
104+ const bool realtime = false)
98105 : node_base_interface_(node_base_interface),
99106 node_clock_interface_(node_clock_interface),
100107 node_logging_interface_(node_logging_interface),
@@ -106,6 +113,7 @@ class SimpleActionServer
106113 spin_thread_(spin_thread)
107114 {
108115 using namespace std ::placeholders; // NOLINT
116+ use_realtime_prioritization_ = realtime;
109117 if (spin_thread_) {
110118 callback_group_ = node_base_interface->create_callback_group (
111119 rclcpp::CallbackGroupType::MutuallyExclusive, false );
@@ -170,6 +178,26 @@ class SimpleActionServer
170178 return rclcpp_action::CancelResponse::ACCEPT;
171179 }
172180
181+ /* *
182+ * @brief Sets thread priority level
183+ */
184+ void setSoftRealTimePriority ()
185+ {
186+ if (use_realtime_prioritization_) {
187+ sched_param sch;
188+ sch.sched_priority = 49 ;
189+ if (sched_setscheduler (0 , SCHED_FIFO, &sch) == -1 ) {
190+ std::string errmsg (
191+ " Cannot set as real-time thread. Users must set: <username> hard rtprio 99 and "
192+ " <username> soft rtprio 99 in /etc/security/limits.conf to enable "
193+ " realtime prioritization! Error: " );
194+ throw std::runtime_error (errmsg + std::strerror (errno));
195+ } else {
196+ debug_msg (" Soft realtime prioritization successfully set!" );
197+ }
198+ }
199+ }
200+
173201 /* *
174202 * @brief Handles accepted goals and adds to preempted queue to switch to
175203 * @param Goal A server goal handle to cancel
@@ -202,7 +230,11 @@ class SimpleActionServer
202230
203231 // Return quickly to avoid blocking the executor, so spin up a new thread
204232 debug_msg (" Executing goal asynchronously." );
205- execution_future_ = std::async (std::launch::async, [this ]() {work ();});
233+ execution_future_ = std::async (
234+ std::launch::async, [this ]() {
235+ setSoftRealTimePriority ();
236+ work ();
237+ });
206238 }
207239 }
208240
@@ -509,6 +541,7 @@ class SimpleActionServer
509541 CompletionCallback completion_callback_;
510542 std::future<void > execution_future_;
511543 bool stop_execution_{false };
544+ bool use_realtime_prioritization_{false };
512545
513546 mutable std::recursive_mutex update_mutex_;
514547 bool server_active_{false };
0 commit comments