-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AMRNAV-6169 Extend use of composition: ros2 control #1
Changes from 4 commits
a795f63
30ed1d4
8d42dd4
5f55b87
f57eff0
25b7cb4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ | |
#include "rclcpp/rclcpp.hpp" | ||
#include "rclcpp_lifecycle/state.hpp" | ||
|
||
using namespace std::chrono_literals; | ||
namespace // utility | ||
{ | ||
static constexpr const char * kControllerInterfaceNamespace = "controller_interface"; | ||
|
@@ -248,6 +249,55 @@ rclcpp::NodeOptions get_cm_node_options() | |
return node_options; | ||
} | ||
|
||
ControllerManager::ControllerManager(rclcpp::NodeOptions options) | ||
: rclcpp::Node("controller_manager", options.allow_undeclared_parameters(true).automatically_declare_parameters_from_overrides(true)), | ||
diagnostics_updater_(this), | ||
loader_(std::make_shared<pluginlib::ClassLoader<controller_interface::ControllerInterface>>( | ||
kControllerInterfaceNamespace, kControllerInterfaceClassName)), | ||
chainable_loader_( | ||
std::make_shared<pluginlib::ClassLoader<controller_interface::ChainableControllerInterface>>( | ||
kControllerInterfaceNamespace, kChainableControllerInterfaceClassName)), | ||
resource_manager_(std::make_unique<hardware_interface::ResourceManager>( | ||
update_rate_, this->get_node_clock_interface())) | ||
{ | ||
if (!get_parameter("update_rate", update_rate_)) | ||
{ | ||
RCLCPP_WARN(get_logger(), "'update_rate' parameter not set, using default value."); | ||
} | ||
auto update_period = std::chrono::duration<double>(1.0 / update_rate_); | ||
|
||
std::string robot_description = ""; | ||
// TODO(destogl): remove support at the end of 2023 | ||
get_parameter("robot_description", robot_description); | ||
if (robot_description.empty()) | ||
{ | ||
subscribe_to_robot_description_topic(); | ||
} | ||
else | ||
{ | ||
RCLCPP_WARN( | ||
get_logger(), | ||
"[Deprecated] Passing the robot description parameter directly to the control_manager node " | ||
"is deprecated. Use '~/robot_description' topic from 'robot_state_publisher' instead."); | ||
init_resource_manager(robot_description); | ||
} | ||
|
||
diagnostics_updater_.setHardwareID("ros2_control"); | ||
diagnostics_updater_.add( | ||
"Controllers Activity", this, &ControllerManager::controller_activity_diagnostic_callback); | ||
executor_ = std::make_shared<rclcpp::executors::MultiThreadedExecutor>(); | ||
spin_executor_thread_ = std::thread([this]() { | ||
executor_->spin(); | ||
}); | ||
init_services(); | ||
init_timer_ = this->create_wall_timer( | ||
1s, | ||
[this]() -> void { | ||
init_timer_->cancel(); | ||
update_loop(); | ||
}); | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Workaround to execute the update_loop thread from outside the constructor |
||
|
||
ControllerManager::ControllerManager( | ||
std::shared_ptr<rclcpp::Executor> executor, const std::string & manager_node_name, | ||
const std::string & namespace_, const rclcpp::NodeOptions & options) | ||
|
@@ -281,12 +331,12 @@ ControllerManager::ControllerManager( | |
"[Deprecated] Passing the robot description parameter directly to the control_manager node " | ||
"is deprecated. Use '~/robot_description' topic from 'robot_state_publisher' instead."); | ||
init_resource_manager(robot_description); | ||
init_services(); | ||
} | ||
|
||
diagnostics_updater_.setHardwareID("ros2_control"); | ||
diagnostics_updater_.add( | ||
"Controllers Activity", this, &ControllerManager::controller_activity_diagnostic_callback); | ||
init_services(); | ||
} | ||
|
||
ControllerManager::ControllerManager( | ||
|
@@ -308,15 +358,12 @@ ControllerManager::ControllerManager( | |
RCLCPP_WARN(get_logger(), "'update_rate' parameter not set, using default value."); | ||
} | ||
|
||
if (resource_manager_->is_urdf_already_loaded()) | ||
{ | ||
init_services(); | ||
} | ||
subscribe_to_robot_description_topic(); | ||
|
||
diagnostics_updater_.setHardwareID("ros2_control"); | ||
diagnostics_updater_.add( | ||
"Controllers Activity", this, &ControllerManager::controller_activity_diagnostic_callback); | ||
init_services(); | ||
} | ||
|
||
void ControllerManager::subscribe_to_robot_description_topic() | ||
|
@@ -349,7 +396,6 @@ void ControllerManager::robot_description_callback(const std_msgs::msg::String & | |
return; | ||
} | ||
init_resource_manager(robot_description.data.c_str()); | ||
init_services(); | ||
} | ||
catch (std::runtime_error & e) | ||
{ | ||
|
@@ -465,6 +511,52 @@ void ControllerManager::init_resource_manager(const std::string & robot_descript | |
} | ||
} | ||
|
||
|
||
void ControllerManager::update_loop(){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For normal launch this same code is ran from |
||
|
||
cm_thread_ = std::thread( | ||
[this]() | ||
{ | ||
if (realtime_tools::has_realtime_kernel()) | ||
{ | ||
if (!realtime_tools::configure_sched_fifo(50)) | ||
{ | ||
RCLCPP_WARN(this->get_logger(), "Could not enable FIFO RT scheduling policy"); | ||
} | ||
} | ||
else | ||
{ | ||
RCLCPP_INFO(this->get_logger(), "RT kernel is recommended for better performance"); | ||
} | ||
|
||
// for calculating sleep time | ||
auto const period = std::chrono::nanoseconds(1'000'000'000 / this->get_update_rate()); | ||
auto const cm_now = std::chrono::nanoseconds(this->now().nanoseconds()); | ||
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> | ||
next_iteration_time{cm_now}; | ||
|
||
// for calculating the measured period of the loop | ||
rclcpp::Time previous_time = this->now(); | ||
|
||
while (rclcpp::ok()) | ||
{ | ||
// calculate measured period | ||
auto const current_time = this->now(); | ||
auto const measured_period = current_time - previous_time; | ||
previous_time = current_time; | ||
|
||
// execute update loop | ||
this->read(this->now(), measured_period); | ||
this->update(this->now(), measured_period); | ||
this->write(this->now(), measured_period); | ||
|
||
// wait until we hit the end of the period | ||
next_iteration_time += period; | ||
std::this_thread::sleep_until(next_iteration_time); | ||
} | ||
}); | ||
} | ||
|
||
void ControllerManager::init_services() | ||
{ | ||
// TODO(anyone): Due to issues with the MutliThreadedExecutor, this control loop does not rely on | ||
|
@@ -1332,6 +1424,10 @@ controller_interface::ControllerInterfaceBaseSharedPtr ControllerManager::add_co | |
|
||
return to.back().c; | ||
} | ||
ControllerManager::~ControllerManager() | ||
{ | ||
cm_thread_.join(); | ||
} | ||
|
||
void ControllerManager::manage_switch() | ||
{ | ||
|
@@ -2581,3 +2677,6 @@ void ControllerManager::controller_activity_diagnostic_callback( | |
} | ||
|
||
} // namespace controller_manager | ||
|
||
#include "rclcpp_components/register_node_macro.hpp" | ||
RCLCPP_COMPONENTS_REGISTER_NODE(controller_manager::ControllerManager) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,6 +41,7 @@ target_compile_definitions(hardware_interface PRIVATE "HARDWARE_INTERFACE_BUILDI | |
|
||
add_library(mock_components SHARED | ||
src/mock_components/generic_system.cpp | ||
src/lexical_casts.cpp | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤷♂️ |
||
) | ||
target_compile_features(mock_components PUBLIC cxx_std_17) | ||
target_include_directories(mock_components PUBLIC | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remapping with the same name, otherwise the name is overriden from the composable node container (amr_container)