-
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
move creation of stateinterfaces to systeminterface #9
Changes from 2 commits
a8a3ab0
9931106
88f744f
8f73a83
c49735d
0782cdb
17f7a8f
7d4d939
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 |
---|---|---|
|
@@ -102,6 +102,28 @@ struct TransmissionInfo | |
std::unordered_map<std::string, std::string> parameters; | ||
}; | ||
|
||
/** | ||
* This structure stores information about an interface for a specific hardware which should be | ||
* instantiated internally. | ||
*/ | ||
struct InterfaceDescription | ||
{ | ||
InterfaceDescription(const std::string & prefix_name_in, const InterfaceInfo & interface_info_in) | ||
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. This is a good idea to add this class, but please add also then type and size and so on. Maybe we have already something suitable here. What about 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. Not sure what you mean, i already use InterfaceInfo but i created this since the unique name of the component is missing and ComponentInfo does store all command/state Interfaces which we don't want either. Or am i mistaken? |
||
: prefix_name(prefix_name_in), interface_info(interface_info_in) | ||
{ | ||
} | ||
|
||
/** | ||
* Name of the interface defined by the user. | ||
*/ | ||
std::string prefix_name; | ||
|
||
InterfaceInfo interface_info; | ||
|
||
std::string get_name() const { return prefix_name + interface_info.name; } | ||
mamueluth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
std::string get_type() const { return interface_info.name; } | ||
}; | ||
|
||
/// This structure stores information about hardware defined in a robot's URDF. | ||
struct HardwareInfo | ||
{ | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -15,13 +15,15 @@ | |||||
#ifndef HARDWARE_INTERFACE__SYSTEM_INTERFACE_HPP_ | ||||||
#define HARDWARE_INTERFACE__SYSTEM_INTERFACE_HPP_ | ||||||
|
||||||
#include <map> | ||||||
#include <memory> | ||||||
#include <string> | ||||||
#include <vector> | ||||||
|
||||||
#include "hardware_interface/handle.hpp" | ||||||
#include "hardware_interface/hardware_info.hpp" | ||||||
#include "hardware_interface/types/hardware_interface_return_values.hpp" | ||||||
#include "hardware_interface/types/hardware_interface_type_values.hpp" | ||||||
#include "hardware_interface/types/lifecycle_state_names.hpp" | ||||||
#include "lifecycle_msgs/msg/state.hpp" | ||||||
#include "rclcpp/duration.hpp" | ||||||
|
@@ -98,9 +100,56 @@ class SystemInterface : public rclcpp_lifecycle::node_interfaces::LifecycleNodeI | |||||
virtual CallbackReturn on_init(const HardwareInfo & hardware_info) | ||||||
{ | ||||||
info_ = hardware_info; | ||||||
add_state_interface_descriptions(); | ||||||
add_command_interface_descriptions(); | ||||||
return CallbackReturn::SUCCESS; | ||||||
}; | ||||||
|
||||||
virtual void add_state_interface_descriptions() | ||||||
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. Method name is not so good. Why don't you use the stateless method, this means doesn't access to the global variables? This parsing will repeat in all components, so maybe adding this into URDF parser or Hardware Info might be enough. Actually, we have this already in the 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. Cannot think of a better name. moved it to component parser 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. renamed it to |
||||||
{ | ||||||
for (const auto & joint : info_.joints) | ||||||
{ | ||||||
for (const auto & state_interface : joint.state_interfaces) | ||||||
{ | ||||||
joint_states_descr_.emplace_back(InterfaceDescription(joint.name, state_interface)); | ||||||
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. Just write the full name, it is clearer.
Suggested change
|
||||||
} | ||||||
} | ||||||
|
||||||
for (const auto & sensor : info_.sensors) | ||||||
{ | ||||||
for (const auto & state_interface : sensor.state_interfaces) | ||||||
{ | ||||||
sensor_states_descr_.emplace_back(InterfaceDescription(sensor.name, state_interface)); | ||||||
} | ||||||
} | ||||||
|
||||||
for (const auto & gpio : info_.gpios) | ||||||
{ | ||||||
for (const auto & state_interface : gpio.state_interfaces) | ||||||
{ | ||||||
gpio_states_descr_.emplace_back(InterfaceDescription(gpio.name, state_interface)); | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
virtual void add_command_interface_descriptions() | ||||||
{ | ||||||
for (const auto & joint : info_.joints) | ||||||
{ | ||||||
for (const auto & command_interface : joint.command_interfaces) | ||||||
{ | ||||||
joint_commands_descr_.emplace_back(InterfaceDescription(joint.name, command_interface)); | ||||||
} | ||||||
} | ||||||
for (const auto & gpio : info_.gpios) | ||||||
{ | ||||||
for (const auto & command_interface : gpio.command_interfaces) | ||||||
{ | ||||||
gpio_commands_descr_.emplace_back(InterfaceDescription(gpio.name, command_interface)); | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
/// Exports all state interfaces for this hardware interface. | ||||||
/** | ||||||
* The state interfaces have to be created and transferred according | ||||||
|
@@ -110,7 +159,19 @@ class SystemInterface : public rclcpp_lifecycle::node_interfaces::LifecycleNodeI | |||||
* | ||||||
* \return vector of state interfaces | ||||||
*/ | ||||||
virtual std::vector<StateInterface> export_state_interfaces() = 0; | ||||||
virtual std::vector<StateInterface> export_state_interfaces() | ||||||
{ | ||||||
std::vector<hardware_interface::StateInterface> state_interfaces; | ||||||
state_interfaces.reserve(joint_states_descr_.size()); | ||||||
|
||||||
for (const auto & descr : joint_states_descr_) | ||||||
{ | ||||||
joint_states_[descr.get_name()] = std::numeric_limits<double>::quiet_NaN(); | ||||||
state_interfaces.emplace_back(StateInterface(descr, &joint_states_[descr.get_name()])); | ||||||
} | ||||||
|
||||||
return state_interfaces; | ||||||
} | ||||||
|
||||||
/// Exports all command interfaces for this hardware interface. | ||||||
/** | ||||||
|
@@ -121,7 +182,19 @@ class SystemInterface : public rclcpp_lifecycle::node_interfaces::LifecycleNodeI | |||||
* | ||||||
* \return vector of command interfaces | ||||||
*/ | ||||||
virtual std::vector<CommandInterface> export_command_interfaces() = 0; | ||||||
virtual std::vector<CommandInterface> export_command_interfaces() | ||||||
{ | ||||||
std::vector<hardware_interface::CommandInterface> command_interfaces; | ||||||
command_interfaces.reserve(joint_commands_descr_.size()); | ||||||
|
||||||
for (const auto & descr : joint_commands_descr_) | ||||||
{ | ||||||
joint_commands_[descr.get_name()] = std::numeric_limits<double>::quiet_NaN(); | ||||||
command_interfaces.emplace_back(CommandInterface(descr, &joint_commands_[descr.get_name()])); | ||||||
} | ||||||
|
||||||
return command_interfaces; | ||||||
} | ||||||
|
||||||
/// Prepare for a new command interface switch. | ||||||
/** | ||||||
|
@@ -203,8 +276,75 @@ class SystemInterface : public rclcpp_lifecycle::node_interfaces::LifecycleNodeI | |||||
*/ | ||||||
void set_state(const rclcpp_lifecycle::State & new_state) { lifecycle_state_ = new_state; } | ||||||
|
||||||
double joint_state_get_value(const InterfaceDescription & interface_descr) const | ||||||
{ | ||||||
return joint_states_.at(interface_descr.get_name()); | ||||||
} | ||||||
|
||||||
void joint_state_set_value(const InterfaceDescription & interface_descr, const double & value) | ||||||
{ | ||||||
joint_states_[interface_descr.get_name()] = value; | ||||||
} | ||||||
|
||||||
double joint_command_get_value(const InterfaceDescription & interface_descr) const | ||||||
{ | ||||||
return joint_commands_.at(interface_descr.get_name()); | ||||||
} | ||||||
|
||||||
void joint_command_set_value(const InterfaceDescription & interface_descr, const double & value) | ||||||
{ | ||||||
joint_commands_[interface_descr.get_name()] = value; | ||||||
} | ||||||
|
||||||
double sensor_state_get_value(const InterfaceDescription & interface_descr) const | ||||||
{ | ||||||
return sensor_states_.at(interface_descr.get_name()); | ||||||
} | ||||||
|
||||||
void sensor_state_set_value(const InterfaceDescription & interface_descr, const double & value) | ||||||
{ | ||||||
sensor_states_[interface_descr.get_name()] = value; | ||||||
} | ||||||
|
||||||
double gpio_state_get_value(const InterfaceDescription & interface_descr) const | ||||||
{ | ||||||
return gpio_states_.at(interface_descr.get_name()); | ||||||
} | ||||||
|
||||||
void gpio_state_set_value(const InterfaceDescription & interface_descr, const double & value) | ||||||
{ | ||||||
gpio_states_[interface_descr.get_name()] = value; | ||||||
} | ||||||
|
||||||
double gpio_command_get_value(const InterfaceDescription & interface_descr) const | ||||||
{ | ||||||
return gpio_commands_.at(interface_descr.get_name()); | ||||||
} | ||||||
|
||||||
void gpio_commands_set_value(const InterfaceDescription & interface_descr, const double & value) | ||||||
{ | ||||||
gpio_commands_[interface_descr.get_name()] = value; | ||||||
} | ||||||
Comment on lines
+312
to
+360
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. This looks good! |
||||||
|
||||||
protected: | ||||||
HardwareInfo info_; | ||||||
std::vector<InterfaceDescription> joint_states_descr_; | ||||||
std::vector<InterfaceDescription> joint_commands_descr_; | ||||||
|
||||||
std::vector<InterfaceDescription> sensor_states_descr_; | ||||||
|
||||||
std::vector<InterfaceDescription> gpio_states_descr_; | ||||||
std::vector<InterfaceDescription> gpio_commands_descr_; | ||||||
|
||||||
private: | ||||||
std::map<std::string, double> joint_states_; | ||||||
std::map<std::string, double> joint_commands_; | ||||||
|
||||||
std::map<std::string, double> sensor_states_; | ||||||
|
||||||
std::map<std::string, double> gpio_states_; | ||||||
std::map<std::string, double> gpio_commands_; | ||||||
|
||||||
rclcpp_lifecycle::State lifecycle_state_; | ||||||
}; | ||||||
|
||||||
|
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.
I am not sure if we actually need to extend this here. We are not storing
InterfaceDescription
, but extending this might be useful in the future to support other types. What we also don't need here is the third argumentvalue_ptr
. Did you plan to remove it in the future? I mean we require this for backward compatibility, but for new approach onlyInterfaceDescription
should sufficient.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.
Looking into this, it might be useful to move the storage here, when using getter and setters, which means that we don't need this method, but more something like:
This should for now store the variable with value, and later we move it into handles, for example:
Later changes within this file / handles are OK. Therefore, it is not so relevant where you move storage, but of course nicer the code the better. Only the changes of external API are critical.
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.
working on this as a second step. Needs quite a lot of changes.