Skip to content

Commit 7709cba

Browse files
committed
feat: adds enable_overrun parameter to CM
Introduces a new parameter `enable_overrun` to the controller manager, allowing users to disable the overrun detection and warning mechanism. This parameter defaults to true, maintaining the existing behavior.
1 parent 9c368f1 commit 7709cba

File tree

3 files changed

+33
-17
lines changed

3 files changed

+33
-17
lines changed

controller_manager/src/controller_manager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3179,7 +3179,7 @@ void ControllerManager::write(const rclcpp::Time & time, const rclcpp::Duration
31793179
execution_time_.total_time =
31803180
execution_time_.write_time + execution_time_.update_time + execution_time_.read_time;
31813181
const double expected_cycle_time = 1.e6 / static_cast<double>(get_update_rate());
3182-
if (execution_time_.total_time > expected_cycle_time)
3182+
if (execution_time_.total_time > expected_cycle_time && params_->enable_overrun)
31833183
{
31843184
RCLCPP_WARN_THROTTLE(
31853185
get_logger(), *get_clock(), 1000,

controller_manager/src/controller_manager_parameters.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ controller_manager:
66
description: "The frequency of controller manager's real-time update loop. This loop reads states from hardware, updates controllers and writes commands to hardware."
77
}
88

9+
enable_overrun: {
10+
type: bool,
11+
default_value: true,
12+
description: "If true, the controller manager will detect timing overruns, log warnings, and adjust the next iteration time to compensate for missed cycles."
13+
}
14+
915
enforce_command_limits: {
1016
type: bool,
1117
default_value: false,

controller_manager/src/ros2_control_node.cpp

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ int main(int argc, char ** argv)
5858
executor, manager_node_name, "", cm_node_options);
5959

6060
const bool use_sim_time = cm->get_parameter_or("use_sim_time", false);
61+
const bool enable_overrun = cm->get_parameter_or("enable_overrun", true);
6162

6263
const bool has_realtime = realtime_tools::has_realtime_kernel();
6364
const bool lock_memory = cm->get_parameter_or<bool>("lock_memory", has_realtime);
@@ -75,13 +76,14 @@ int main(int argc, char ** argv)
7576
cm->get_clock()->sleep_for(rclcpp::Duration::from_seconds(1.0 / cm->get_update_rate()));
7677

7778
RCLCPP_INFO(cm->get_logger(), "update rate is %d Hz", cm->get_update_rate());
79+
RCLCPP_INFO(cm->get_logger(), "Overrun logic: %s", enable_overrun ? "enabled " : "disabled");
7880
const int thread_priority = cm->get_parameter_or<int>("thread_priority", kSchedPriority);
7981
RCLCPP_INFO(
8082
cm->get_logger(), "Spawning %s RT thread with scheduler priority: %d", cm->get_name(),
8183
thread_priority);
8284

8385
std::thread cm_thread(
84-
[cm, thread_priority, use_sim_time]()
86+
[cm, thread_priority, use_sim_time, enable_overrun]()
8587
{
8688
rclcpp::Parameter cpu_affinity_param;
8789
if (cm->get_parameter("cpu_affinity", cpu_affinity_param))
@@ -152,23 +154,31 @@ int main(int argc, char ** argv)
152154
else
153155
{
154156
next_iteration_time += period;
155-
const auto time_now = std::chrono::steady_clock::now();
156-
if (next_iteration_time < time_now)
157+
158+
if (enable_overrun)
157159
{
158-
const double time_diff =
159-
static_cast<double>(
160-
std::chrono::duration_cast<std::chrono::nanoseconds>(time_now - next_iteration_time)
161-
.count()) /
162-
1.e6;
163-
const double cm_period = 1.e3 / static_cast<double>(cm->get_update_rate());
164-
const int overrun_count = static_cast<int>(std::ceil(time_diff / cm_period));
165-
RCLCPP_WARN_THROTTLE(
166-
cm->get_logger(), *cm->get_clock(), 1000,
167-
"Overrun detected! The controller manager missed its desired rate of %d Hz. The loop "
168-
"took %f ms (missed cycles : %d).",
169-
cm->get_update_rate(), time_diff + cm_period, overrun_count + 1);
170-
next_iteration_time += (overrun_count * period);
160+
const auto time_now = std::chrono::steady_clock::now();
161+
if (next_iteration_time < time_now)
162+
{
163+
const double time_diff =
164+
static_cast<double>(std::chrono::duration_cast<std::chrono::nanoseconds>(
165+
time_now - next_iteration_time)
166+
.count()) /
167+
1.e6;
168+
const double cm_period = 1.e3 / static_cast<double>(cm->get_update_rate());
169+
const int overrun_count = static_cast<int>(std::ceil(time_diff / cm_period));
170+
171+
RCLCPP_WARN_THROTTLE(
172+
cm->get_logger(), *cm->get_clock(), 1000,
173+
"Overrun detected! The controller manager missed its desired rate of %d Hz. The "
174+
"loop "
175+
"took %f ms (missed cycles : %d).",
176+
cm->get_update_rate(), time_diff + cm_period, overrun_count + 1);
177+
178+
next_iteration_time += (overrun_count * period);
179+
}
171180
}
181+
172182
std::this_thread::sleep_until(next_iteration_time);
173183
}
174184
}

0 commit comments

Comments
 (0)