Skip to content

Commit

Permalink
Add a struct for Interface information, update the test URDF (ros-con…
Browse files Browse the repository at this point in the history
…trols#167)

* Add a struct for Interface information, update the test URDF

* Add a name retrieval function. Minor renaming.

* Use vector<string> args for API simplicity.

* Fix several build errors. Parsing tests pass!

* Fix member variable naming in test_component_interfaces

* Update test_component_interfaces. All pass!

* Parse command interface min/max attributes

* Format and lint

* Minor renaming and whitespace cleanup
  • Loading branch information
AndyZe authored Oct 20, 2020
1 parent f9d4e61 commit 891f524
Show file tree
Hide file tree
Showing 11 changed files with 347 additions and 218 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,27 @@ namespace hardware_interface
namespace components
{

/**
* \brief This structure stores information about components defined for a specific hardware
* in robot's URDF.
*/
struct InterfaceInfo
{
/**
* \brief name of the command interfaces that can be set, e.g. "position", "velocity", etc.
* Used by joints.
*/
std::string name;
/**
* \brief (optional) minimal allowed values of the interface.
*/
std::string min;
/**
* \brief (optional) maximal allowed values of the interface.
*/
std::string max;
};

/**
* \brief This structure stores information about components defined for a specific hardware
* in robot's URDF.
Expand All @@ -46,14 +67,14 @@ struct ComponentInfo
* \brief name of the command interfaces that can be set, e.g. "position", "velocity", etc.
* Used by joints.
*/
std::vector<std::string> command_interfaces;
std::vector<InterfaceInfo> command_interfaces;
/**
* \brief name of the state interfaces that can be read, e.g. "position", "velocity", etc.
* Used by Joints and Sensors.
*/
std::vector<std::string> state_interfaces;
std::vector<InterfaceInfo> state_interfaces;
/**
* \brief (optional) key-value pairs of components parameters.
* \brief (optional) key-value pairs of component parameters, e.g. min/max values or serial number.
*/
std::unordered_map<std::string, std::string> parameters;
};
Expand Down
49 changes: 27 additions & 22 deletions hardware_interface/include/hardware_interface/components/joint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,26 +50,36 @@ class Joint
* return_type::ERROR otherwise.
*/
HARDWARE_INTERFACE_PUBLIC
virtual
return_type configure(const ComponentInfo & joint_info);

/**
* \brief Provide the list of command interfaces configured for the joint.
*
* \return string list with command interfaces.
* \return vector of command interface names.
*/
HARDWARE_INTERFACE_PUBLIC
virtual
std::vector<std::string> get_command_interfaces() const;
std::vector<std::string> get_command_interface_names() const;

/**
* \brief Provide the list of command interfaces configured for the joint.
* \return vector of command interfaces.
*/
HARDWARE_INTERFACE_PUBLIC
std::vector<InterfaceInfo> get_command_interfaces() const;

/**
* \brief Provide the list of state interfaces configured for the joint.
* \return vector of state interface names.
*/
HARDWARE_INTERFACE_PUBLIC
std::vector<std::string> get_state_interface_names() const;

/**
* \brief Provide the list of state interfaces configured for the joint.
*
* \return string list with state interfaces.
*/
HARDWARE_INTERFACE_PUBLIC
virtual
std::vector<std::string> get_state_interfaces() const;
std::vector<InterfaceInfo> get_state_interfaces() const;

/**
* \brief Get command list from the joint. This function is used in the write function of the
Expand All @@ -78,16 +88,16 @@ class Joint
* provide.
*
* \param command list of doubles with commands for the hardware.
* \param interfaces list of interfaces on which commands have to set.
* \param interfaces list of interface names to retrieve from.
* \return return_type::INTERFACE_VALUE_SIZE_NOT_EQUAL if command and interfaces arguments do not
* have the same length; return_type::INTERFACE_NOT_FOUND if one of provided interfaces is not
* defined for the joint; return return_type::INTERFACE_NOT_PROVIDED if the list of interfaces
* is empty; return_type::OK otherwise.
*/
HARDWARE_INTERFACE_EXPORT
virtual
return_type get_command(
std::vector<double> & command, const std::vector<std::string> & interfaces) const;
std::vector<double> & command,
const std::vector<std::string> & interfaces) const;

/**
* \brief Get complete command list for the joint. This function is used by the hardware to get
Expand All @@ -98,7 +108,6 @@ class Joint
* \return return_type::OK always.
*/
HARDWARE_INTERFACE_EXPORT
virtual
return_type get_command(std::vector<double> & command) const;

/**
Expand All @@ -107,7 +116,7 @@ class Joint
* of elements. Using the interfaces list, the controller can choose which values to set.
*
* \param command list of doubles with commands for the hardware.
* \param interfaces list of interfaces on which commands have to be provided.
* \param interfaces list of interface names on which commands have to be provided.
* \return return_type::INTERFACE_VALUE_SIZE_NOT_EQUAL if command and interfaces arguments do not
* have the same length; return_type::COMMAND_OUT_OF_LIMITS if one of the command values is out
* of limits; return_type::INTERFACE_NOT_FOUND if one of provided interfaces is not
Expand All @@ -118,9 +127,9 @@ class Joint
* (see: https://github.com/ros-controls/ros2_control/issues/129)
*/
HARDWARE_INTERFACE_EXPORT
virtual
return_type set_command(
const std::vector<double> & command, const std::vector<std::string> & interfaces);
const std::vector<double> & command,
const std::vector<std::string> & interfaces);

/**
* \brief Get complete state list from the joint. This function is used by the hardware to get
Expand All @@ -133,7 +142,6 @@ class Joint
* of limits; return_type::OK otherwise.
*/
HARDWARE_INTERFACE_EXPORT
virtual
return_type set_command(const std::vector<double> & command);

/**
Expand All @@ -142,14 +150,13 @@ class Joint
* number of elements. Using the interfaces list, the controller can choose which values to get.
*
* \param state list of doubles with states of the hardware.
* \param interfaces list of interfaces on which states have to be provided.
* \param interfaces list of interface names to provide for.
* \return return_type::INTERFACE_VALUE_SIZE_NOT_EQUAL if state and interfaces arguments do not
* have the same length; return_type::INTERFACE_NOT_FOUND if one of provided interfaces is not
* defined for the joint; return return_type::INTERFACE_NOT_PROVIDED if the list of interfaces
* is empty; return_type::OK otherwise.
*/
HARDWARE_INTERFACE_EXPORT
virtual
return_type get_state(
std::vector<double> & state,
const std::vector<std::string> & interfaces) const;
Expand All @@ -163,7 +170,6 @@ class Joint
* \return return_type::OK always.
*/
HARDWARE_INTERFACE_EXPORT
virtual
return_type get_state(std::vector<double> & state) const;

/**
Expand All @@ -172,15 +178,15 @@ class Joint
* the interfaces list, the hardware can choose which values to set.
*
* \param state list of doubles with states of the hardware.
* \param interfaces list of interfaces on which states have to be provided.
* \param interfaces list of interface names to provide for.
* \return return_type::INTERFACE_VALUE_SIZE_NOT_EQUAL if state and interfaces arguments do not
* have the same length; return_type::INTERFACE_NOT_FOUND if one of provided interfaces is not
* defined for the joint; return_type::OK otherwise.
*/
HARDWARE_INTERFACE_EXPORT
virtual
return_type set_state(
const std::vector<double> & state, const std::vector<std::string> & interfaces);
const std::vector<double> & state,
const std::vector<std::string> & interfaces);

/**
* \brief Set complete state list from the joint.This function is used by the hardware to set its
Expand All @@ -192,7 +198,6 @@ class Joint
* joint's state interfaces, return_type::OK otherwise.
*/
HARDWARE_INTERFACE_EXPORT
virtual
return_type set_state(const std::vector<double> & state);

protected:
Expand Down
28 changes: 16 additions & 12 deletions hardware_interface/include/hardware_interface/components/sensor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,34 +50,40 @@ class Sensor
* return_type::ERROR otherwise.
*/
HARDWARE_INTERFACE_PUBLIC
virtual
return_type configure(const ComponentInfo & joint_info);

// TODO(andyz): implement this
/**
* \brief Provide the list of state interfaces configured for the joint.
* \return vector of state interface names.
*/
HARDWARE_INTERFACE_PUBLIC
std::vector<std::string> get_state_interface_names() const;

/**
* \brief Provide the list of state interfaces configured for the sensor.
*
* \return string list with state interfaces.
* \return list of state interfaces.
*/
HARDWARE_INTERFACE_PUBLIC
virtual
std::vector<std::string> get_state_interfaces() const;
std::vector<components::InterfaceInfo> get_state_interfaces() const;

/**
* \brief Get state list from the sensor. This function is used by the controller to get the
* actual state of the hardware. The parameters state, and interfaces have the same order and
* number of elements. Using the interfaces list, the controller can choose which values to get.
*
* \param state list of doubles with states of the hardware.
* \param interfaces list of interfaces on which states have to be provided.
* \param interfaces list of interface names to provide for.
* \return return_type::INTERFACE_VALUE_SIZE_NOT_EQUAL if state and interfaces arguments do not
* have the same length; return_type::INTERFACE_NOT_FOUND if one of provided interfaces is not
* defined for the sensor; return return_type::INTERFACE_NOT_PROVIDED if the list of interfaces
* is empty; return_type::OK otherwise.
*/
HARDWARE_INTERFACE_EXPORT
virtual
return_type get_state(
std::vector<double> & state, const std::vector<std::string> & interfaces) const;
std::vector<double> & state,
const std::vector<std::string> & interfaces) const;

/**
* \brief Get complete state list from the sensor. This function is used by the controller to get
Expand All @@ -88,7 +94,6 @@ class Sensor
* \return return_type::OK always.
*/
HARDWARE_INTERFACE_EXPORT
virtual
return_type get_state(std::vector<double> & state) const;

/**
Expand All @@ -97,15 +102,15 @@ class Sensor
* the interfaces list, the hardware can choose which values to set.
*
* \param state list of doubles with states of the hardware.
* \param interfaces list of interfaces on which states have to be provided.
* \param interfaces list of interface names to provide for.
* \return return_type::INTERFACE_VALUE_SIZE_NOT_EQUAL if state and interfaces arguments do not
* have the same length; return_type::INTERFACE_NOT_FOUND if one of provided interfaces is not
* defined for the sensor; return_type::OK otherwise.
*/
HARDWARE_INTERFACE_EXPORT
virtual
return_type set_state(
const std::vector<double> & state, const std::vector<std::string> & interfaces);
const std::vector<double> & state,
const std::vector<std::string> & interfaces);

/**
* \brief Set complete state list from the sensor.This function is used by the hardware to set its
Expand All @@ -117,7 +122,6 @@ class Sensor
* sensor's state interfaces, return_type::OK otherwise.
*/
HARDWARE_INTERFACE_EXPORT
virtual
return_type set_state(const std::vector<double> & state);

protected:
Expand Down
47 changes: 39 additions & 8 deletions hardware_interface/src/component_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ constexpr const auto kSensorTag = "sensor";
constexpr const auto kTransmissionTag = "transmission";
constexpr const auto kCommandInterfaceTypeTag = "commandInterfaceType";
constexpr const auto kStateInterfaceTypeTag = "stateInterfaceType";
constexpr const auto kMinTag = "min";
constexpr const auto kMaxTag = "max";
} // namespace

namespace hardware_interface
Expand Down Expand Up @@ -64,7 +66,7 @@ std::string get_text_for_element(
* If attribute is not found throws an error.
*
* \param element_it XMLElement iterator to search for the attribute
* \param attribute_name atribute name to serach for and return value
* \param attribute_name attribute name to search for and return value
* \param tag_name parent tag name where attribute is searched for (used for error output)
* \return attribute value
* \throws std::runtime_error if attribute is not found
Expand All @@ -88,7 +90,7 @@ std::string get_attribute_value(
* If attribute is not found throws an error.
*
* \param element_it XMLElement iterator to search for the attribute
* \param attribute_name atribute name to serach for and return value
* \param attribute_name atribute name to search for and return value
* \param tag_name parent tag name where attribute is searched for (used for error output)
* \return attribute value
* \throws std::runtime_error if attribute is not found
Expand Down Expand Up @@ -132,22 +134,51 @@ std::unordered_map<std::string, std::string> parse_parameters_from_xml(
/**
* \brief Search XML snippet for definition of interfaceTypes.
*
* \param interfaces_it pointer to the interator over interfaces
* \param interfaces_it pointer to the iterator over interfaces
* \param interfaceTag interface type tag (command or state)
* \return std::vector< std::__cxx11::string > list of interface types
* \throws std::runtime_error if the interfaceType text not set in a tag
*/
std::vector<std::string> parse_interfaces_from_xml(
std::vector<components::InterfaceInfo> parse_interfaces_from_xml(
const tinyxml2::XMLElement * interfaces_it, const char * interfaceTag)
{
std::vector<std::string> interfaces;
std::vector<components::InterfaceInfo> interfaces;

while (interfaces_it) {
const std::string interface_type = get_text_for_element(
interfaces_it, std::string(interfaceTag) + " type ");
interfaces.push_back(interface_type);
hardware_interface::components::InterfaceInfo interface;

// Joint interfaces have a name attribute
if (std::string(interfaceTag) == "commandInterfaceType") {
const std::string interface_name = get_attribute_value(
interfaces_it, "name",
std::string(interfaceTag));
interface.name = interface_name;

// Optional min/max attributes
std::unordered_map<std::string, std::string> interface_params =
parse_parameters_from_xml(interfaces_it->FirstChildElement(kParamTag));
std::unordered_map<std::string, std::string>::const_iterator interface_param =
interface_params.find(kMinTag);
if (interface_param != interface_params.end()) {
interface.min = interface_param->second;
}
interface_param = interface_params.find(kMaxTag);
if (interface_param != interface_params.end()) {
interface.max = interface_param->second;
}
}
// State interfaces have an element to define the type, not a name attribute
if (std::string(interfaceTag) == "stateInterfaceType") {
const std::string interface_type = get_text_for_element(
interfaces_it,
std::string(interfaceTag) + " type ");
interface.name = interface_type;
}

interfaces.push_back(interface);
interfaces_it = interfaces_it->NextSiblingElement(interfaceTag);
}

return interfaces;
}

Expand Down
Loading

0 comments on commit 891f524

Please sign in to comment.