Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions mavros/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ Main node. Allow disable GCS proxy by setting empty URL.

ros2 run mavros mavros_node --ros-args --params-file params.yaml

For ROS 2 deployments where the UAS plugin executor consumes too much CPU,
set `MAVROS_UAS_EXECUTOR_THREADS` to limit its worker count. Values are clamped
to 2-16 threads; for example:

MAVROS_UAS_EXECUTOR_THREADS=2 ros2 run mavros mavros_node --ros-args --params-file params.yaml


Launch Files
------------
Expand Down
33 changes: 33 additions & 0 deletions mavros/src/lib/uas_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,41 @@
*/

#include <algorithm>
#include <charconv>
#include <cstdlib>
#include <string_view>
#include <system_error>

#include "mavros/uas_executor.hpp"

using namespace mavros; // NOLINT
using namespace mavros::uas; // NOLINT
using namespace std::chrono_literals; // NOLINT

namespace
{
constexpr size_t kMinExecutorThreads = 2;
constexpr size_t kMaxExecutorThreads = 16;
constexpr std::string_view kExecutorThreadsEnv = "MAVROS_UAS_EXECUTOR_THREADS";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer old C-convention for the constants.
Also i don't think it really needs string view.


size_t configured_number_of_threads()
{
auto value = std::getenv(kExecutorThreadsEnv.data());
if (value == nullptr || value[0] == '\0') {
return 0;
}

size_t threads = 0;
const auto input = std::string_view(value);
const auto result = std::from_chars(input.data(), input.data() + input.size(), threads);
if (result.ec != std::errc{} || result.ptr != input.data() + input.size() || threads == 0) {
return 0;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::stoi() seems much more compact...


return std::clamp(threads, kMinExecutorThreads, kMaxExecutorThreads);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If user sets amount of threads we should only limit minimum to be 2+.

}
} // namespace

UASExecutor::UASExecutor(const rclcpp::ExecutorOptions & options)
: MultiThreadedExecutor(options, select_number_of_threads(), true, 1000ms),
source_system(0),
Expand All @@ -28,6 +56,11 @@ UASExecutor::UASExecutor(const rclcpp::ExecutorOptions & options)

size_t UASExecutor::select_number_of_threads()
{
auto configured_threads = configured_number_of_threads();
if (configured_threads > 0) {
return configured_threads;
}

// return std::max<size_t>(16, std::min<size_t>(std::thread::hardware_concurrency(), 4));
return std::clamp<size_t>(std::thread::hardware_concurrency(), 4, 16);
}
Expand Down
Loading