1#include "modulo_controllers/ControllerInterface.hpp"
4using namespace state_representation;
5using namespace std::chrono_literals;
7namespace modulo_controllers {
14 if (
status != CallbackReturn::SUCCESS) {
17 on_init_called_ =
true;
23 "The string formatted content of the controller's URDF description");
25 std::make_shared<
Parameter<std::vector<std::string>>>(
"joints"),
26 "A vector of joint names that the controller will claim");
28 "activation_timeout", 1.0,
"The seconds to wait for valid data on the state interfaces before activating");
30 "input_validity_period", 1.0,
"The maximum age of an input state before discarding it as expired");
33 }
catch (
const std::exception&
e) {
36 return CallbackReturn::ERROR;
40 return CallbackReturn::SUCCESS;
43rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
46 if (
status != CallbackReturn::SUCCESS) {
50 if (!on_init_called_) {
53 "The controller has not been properly initialized! Derived controller classes must call "
54 "'ControllerInterface::on_init()' during their own initialization before being configured.");
55 return CallbackReturn::ERROR;
61 return CallbackReturn::ERROR;
70 }
catch (
const std::exception&
ex) {
73 return CallbackReturn::ERROR;
77 return CallbackReturn::SUCCESS;
81 add_interface(
name,
interface, state_interface_names_,
"state");
85 add_interface(
name,
interface, command_interface_names_,
"command");
88void ControllerInterface::add_interface(
89 const std::string& name,
const std::string& interface, std::vector<std::string>& list,
const std::string& type) {
91 throw std::runtime_error(
"Interfaces can only be added when the controller is in state 'configuring'");
108 if (command_interface_names_.empty()) {
115 for (
const auto&
interface : command_interface_names_) {
125 if (claim_all_state_interfaces_) {
132 for (
const auto&
interface : state_interface_names_) {
140rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
146 if (command_interface_indices_.find(
command_interface.get_prefix_name()) == command_interface_indices_.cend()) {
147 command_interface_indices_.insert_or_assign(
148 command_interface.get_prefix_name(), std::unordered_map<std::string, unsigned int>());
157 if (state_interface_data_.find(
state_interface.get_prefix_name()) == state_interface_data_.cend()) {
158 state_interface_data_.insert_or_assign(
159 state_interface.get_prefix_name(), std::unordered_map<std::string, double>());
165 auto status = CallbackReturn::ERROR;
168 }
catch (
const std::exception&
ex) {
171 if (
status != CallbackReturn::SUCCESS) {
180 "Activation is not possible yet; the controller did not receive valid states from hardware");
185 "Activation was not successful; the controller did not receive valid states from hardware");
186 return CallbackReturn::FAILURE;
191 return CallbackReturn::SUCCESS;
195 return CallbackReturn::SUCCESS;
198rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
202 }
catch (
const std::exception&
ex) {
205 return CallbackReturn::ERROR;
209 return CallbackReturn::SUCCESS;
212controller_interface::return_type
215 if (
status != controller_interface::return_type::OK) {
221 }
catch (
const std::exception&
e) {
224 return controller_interface::return_type::ERROR;
226 if (
status != controller_interface::return_type::OK) {
230 if (command_interface_data_.empty()) {
231 return controller_interface::return_type::OK;
234 controller_interface::return_type
ret;
240 if (missed_locks_ > 2) {
243 "Controller is unable to acquire lock for command interfaces, returning an error now");
244 ret = controller_interface::return_type::ERROR;
259 return controller_interface::return_type::OK;
267 return controller_interface::return_type::OK;
271 return state_interface_data_.at(
name);
284 command_interface_data_.at(command_interface_indices_.at(
name).at(
interface)) =
value;
285 }
catch (
const std::out_of_range&) {
288 "set_command_interface called with an unknown name/interface: %s/%s",
name.c_str(),
interface.c_str());
Base controller class to combine ros2_control, control libraries and modulo.
std::shared_ptr< state_representation::ParameterInterface > get_parameter(const std::string &name) const
Get a parameter by name.
CallbackReturn on_configure(const rclcpp_lifecycle::State &previous_state) override
Add signals.
T get_parameter_value(const std::string &name) const
Get a parameter value by name.
void set_input_validity_period(double input_validity_period)
Set the input validity period of input signals.
CallbackReturn on_init() override
Declare parameters and register the on_set_parameters callback.
void add_parameter(const std::shared_ptr< state_representation::ParameterInterface > ¶meter, const std::string &description, bool read_only=false)
Add a parameter.
std::timed_mutex & get_command_mutex()
Get the reference to the command mutex.
virtual CallbackReturn add_interfaces()
Add interfaces like parameters, signals, services, and predicates to the controller.
controller_interface::InterfaceConfiguration command_interface_configuration() const final
Configure the command interfaces.
virtual controller_interface::return_type write_command_interfaces(const rclcpp::Duration &period)
Write the command interfaces.
virtual CallbackReturn on_configure()
Configure the controller.
virtual controller_interface::return_type evaluate(const rclcpp::Time &time, const std::chrono::nanoseconds &period)=0
The control logic callback.
virtual controller_interface::return_type read_state_interfaces()
Read the state interfaces.
std::unordered_map< std::string, double > get_state_interfaces(const std::string &name) const
Get a map containing the state interfaces by name of the parent tag.
CallbackReturn on_init() override
Declare parameters.
ControllerInterface(bool claim_all_state_interfaces=false)
Default constructor.
void add_state_interface(const std::string &name, const std::string &interface)
Add a state interface to the controller by name.
double get_command_interface(const std::string &name, const std::string &interface) const
Get the value of a command interface by name.
virtual CallbackReturn on_activate()
Activate the controller.
double get_state_interface(const std::string &name, const std::string &interface) const
Get the value of a state interface by name.
controller_interface::return_type update(const rclcpp::Time &time, const rclcpp::Duration &period) final
Read the state interfaces, perform control evaluation and write the command interfaces.
void set_command_interface(const std::string &name, const std::string &interface, double value)
Set the value of a command interface by name.
std::string hardware_name_
The hardware name provided by a parameter.
virtual CallbackReturn on_deactivate()
Deactivate the controller.
void add_command_interface(const std::string &name, const std::string &interface)
Add a command interface to the controller by name.
controller_interface::InterfaceConfiguration state_interface_configuration() const final
Configure the state interfaces.