Skip to content
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

RobotHWGroup with aliased interfaces #138

Closed
Closed
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
6ecdde0
Adding RobotHWGroup, which maintains a group of RobotHW as if it were…
kphawkins Jan 8, 2014
ecbc3d3
Updated tests, added changes to infrastructure.
kphawkins Jan 8, 2014
398e3a0
Updated documentation for RobotHWGroup.
kphawkins Jan 8, 2014
bc0d586
Added NULL-checking for the new method added.
kphawkins Jan 9, 2014
f5b54c0
Modified hardware_interface to allow multiple RobotHW registered in a
kphawkins Jan 13, 2014
d6b9daa
Removed getHandles/registerHandles and reimplemented in concatManagers:
kphawkins Jan 17, 2014
1d835cd
Moved concatManagers to base class ResourceManager, updated Interface…
kphawkins Jan 18, 2014
05bb7fb
Removed implementation of RobotHWGroup and moved its implementation t…
kphawkins Jan 18, 2014
c0f9e08
InterfaceManager keeps track of how many interfaces are combined in a…
kphawkins Jan 18, 2014
53b7a97
Added incremental InterfaceManager:get<T>() call test, as per Adolfo'…
kphawkins Jan 18, 2014
4ce12bd
Adding multi_controller.h, an extension of controller.h which allows …
kphawkins Jan 20, 2014
bcaad43
Adding new tests to test loading multiple different interfaces into a…
kphawkins Jan 20, 2014
613f30d
Added Controller2/3/4 for different numbers of interfaces.
kphawkins Jan 20, 2014
bdc2836
Merge branch 'hydro-devel' into hydro-devel-multi-iface
kphawkins Jul 20, 2014
b068bbb
Merge pull request #176 from bulwahn/hydro-devel
Jul 30, 2014
d3b838b
Adding PosVelAccJointInterface, a JointHandle which also allows for c…
kphawkins Aug 19, 2014
bdeaeb4
Merge branch 'hydro-add-pva-joint-iface' into hydro-devel-multi-iface
kphawkins Aug 19, 2014
841123a
Making ControllerInfo::hardware_interface a set
kphawkins Aug 19, 2014
079af40
Fixing hardware_interface reference in controller_manager_gui
kphawkins Aug 21, 2014
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
Prev Previous commit
Next Next commit
Making ControllerInfo::hardware_interface a set
This replaces all instances of ControllerInfo::hardware_interface
with std::set<std::string> hardware_interfaces instead.  This
allows one to properly represent multi-controllers which use
different types of interfaces.  getHardwareInterfaceType is
also converted to getHardwareInterfaceTypes.  A legacy version
of getHardwareInterfaceType is added which calls the other and
returns a random interface.  A warning is displayed if there is more
than one interface available. The ControllerState message is also
affected.
kphawkins committed Aug 19, 2014

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 841123a54f2250a752e7661f4552e1947b334507
Original file line number Diff line number Diff line change
@@ -111,7 +111,7 @@ class Controller: public ControllerBase
{
ROS_ERROR("This controller requires a hardware interface of type '%s'."
" Make sure this is registered in the hardware_interface::RobotHW class.",
getHardwareInterfaceType().c_str());
getHardwareInterfaceTypes().begin()->c_str());
return false;
}

@@ -130,9 +130,11 @@ class Controller: public ControllerBase
return true;
}

virtual std::string getHardwareInterfaceType() const
virtual std::set<std::string> getHardwareInterfaceTypes() const
{
return hardware_interface::internal::demangledTypeName<T>();
std::set<std::string> ret_types;
ret_types.insert(hardware_interface::internal::demangledTypeName<T>());
return ret_types;
}

private:
Original file line number Diff line number Diff line change
@@ -122,8 +122,24 @@ class ControllerBase
/** \name Non Real-Time Safe Functions
*\{*/

/// Get the name of this controller's hardware interface type
virtual std::string getHardwareInterfaceType() const = 0;
/// Get the names of the hardware interface types this controller uses
virtual std::set<std::string> getHardwareInterfaceTypes() const = 0;

/// Get the single name of the hardware interface this controller uses
virtual std::string getHardwareInterfaceType()
{
std::set<std::string> types = getHardwareInterfaceTypes();

if(types.size() == 0) {
ROS_WARN("This controller has no interface type!");
return std::string("");
}

if(types.size() > 1)
ROS_WARN("This controller has more than one interface type!"
"Use 'getHardwareInterfaceTypes' instead.");
return *(types.begin());
}

/** \brief Request that the controller be initialized
*
Original file line number Diff line number Diff line change
@@ -116,9 +116,12 @@ class Controller2: public ControllerBase
T2* hw2 = robot_hw->get<T2>();
if (!hw1 || !hw2)
{
ROS_ERROR("This controller requires a hardware interface of type '%s'."
" Make sure this is registered in the hardware_interface::RobotHW class.",
getHardwareInterfaceType().c_str());
std::set<std::string>::iterator types_iter = getHardwareInterfaceTypes().begin();
std::string type1 = *types_iter; types_iter++;
std::string type2 = *types_iter;
ROS_ERROR("This controller requires hardware interfaces of types '%s' and '%s'."
" Make sure they are registered in the hardware_interface::RobotHW class.",
type1.c_str(), type2.c_str());
return false;
}

@@ -141,10 +144,12 @@ class Controller2: public ControllerBase
return true;
}

virtual std::string getHardwareInterfaceType() const
virtual std::set<std::string> getHardwareInterfaceTypes() const
{
return "<" + hardware_interface::internal::demangledTypeName<T1>() + "," +
hardware_interface::internal::demangledTypeName<T2>() + ">";
std::set<std::string> ret_types;
ret_types.insert(hardware_interface::internal::demangledTypeName<T1>());
ret_types.insert(hardware_interface::internal::demangledTypeName<T2>());
return ret_types;
}

private:
@@ -236,9 +241,13 @@ class Controller3: public ControllerBase
T3* hw3 = robot_hw->get<T3>();
if (!hw1 || !hw2 || !hw3)
{
ROS_ERROR("This controller requires a hardware interface of type '%s'."
" Make sure this is registered in the hardware_interface::RobotHW class.",
getHardwareInterfaceType().c_str());
std::set<std::string>::iterator types_iter = getHardwareInterfaceTypes().begin();
std::string type1 = *types_iter; types_iter++;
std::string type2 = *types_iter; types_iter++;
std::string type3 = *types_iter;
ROS_ERROR("This controller requires hardware interfaces of types '%s', '%s', and '%s'."
" Make sure they are registered in the hardware_interface::RobotHW class.",
type1.c_str(), type2.c_str(), type3.c_str());
return false;
}

@@ -265,11 +274,13 @@ class Controller3: public ControllerBase
return true;
}

virtual std::string getHardwareInterfaceType() const
virtual std::set<std::string> getHardwareInterfaceTypes() const
{
return "<" + hardware_interface::internal::demangledTypeName<T1>() + "," +
hardware_interface::internal::demangledTypeName<T2>() + "," +
hardware_interface::internal::demangledTypeName<T3>() + ">";
std::set<std::string> ret_types;
ret_types.insert(hardware_interface::internal::demangledTypeName<T1>());
ret_types.insert(hardware_interface::internal::demangledTypeName<T2>());
ret_types.insert(hardware_interface::internal::demangledTypeName<T3>());
return ret_types;
}

private:
@@ -369,9 +380,14 @@ class Controller4: public ControllerBase
T4* hw4 = robot_hw->get<T4>();
if (!hw1 || !hw2 || !hw3 || !hw4)
{
ROS_ERROR("This controller requires a hardware interface of type '%s'."
" Make sure this is registered in the hardware_interface::RobotHW class.",
getHardwareInterfaceType().c_str());
std::set<std::string>::iterator types_iter = getHardwareInterfaceTypes().begin();
std::string type1 = *types_iter; types_iter++;
std::string type2 = *types_iter; types_iter++;
std::string type3 = *types_iter; types_iter++;
std::string type4 = *types_iter;
ROS_ERROR("This controller requires hardware interfaces of types '%s', '%s', '%s', and '%s'."
" Make sure they are registered in the hardware_interface::RobotHW class.",
type1.c_str(), type2.c_str(), type3.c_str(), type4.c_str());
return false;
}

@@ -404,10 +420,12 @@ class Controller4: public ControllerBase

virtual std::string getHardwareInterfaceType() const
{
return "<" + hardware_interface::internal::demangledTypeName<T1>() + "," +
hardware_interface::internal::demangledTypeName<T2>() + "," +
hardware_interface::internal::demangledTypeName<T3>() + "," +
hardware_interface::internal::demangledTypeName<T4>() + ">";
std::set<std::string> ret_types;
ret_types.insert(hardware_interface::internal::demangledTypeName<T1>());
ret_types.insert(hardware_interface::internal::demangledTypeName<T2>());
ret_types.insert(hardware_interface::internal::demangledTypeName<T3>());
ret_types.insert(hardware_interface::internal::demangledTypeName<T4>());
return ret_types;
}

private:
7 changes: 5 additions & 2 deletions controller_manager/src/controller_manager.cpp
Original file line number Diff line number Diff line change
@@ -248,7 +248,7 @@ bool ControllerManager::loadController(const std::string& name)
// Adds the controller to the new list
to.resize(to.size() + 1);
to[to.size()-1].info.type = type;
to[to.size()-1].info.hardware_interface = c->getHardwareInterfaceType();
to[to.size()-1].info.hardware_interfaces = c->getHardwareInterfaceTypes();
to[to.size()-1].info.name = name;
to[to.size()-1].info.resources = claimed_resources;
to[to.size()-1].c = c;
@@ -564,7 +564,10 @@ bool ControllerManager::listControllersSrv(
controller_manager_msgs::ControllerState& cs = resp.controller[i];
cs.name = controllers[i].info.name;
cs.type = controllers[i].info.type;
cs.hardware_interface = controllers[i].info.hardware_interface;
cs.hardware_interfaces.clear();
cs.hardware_interfaces.reserve(controllers[i].info.hardware_interfaces.size());
for (std::set<std::string>::iterator it = controllers[i].info.hardware_interfaces.begin(); it != controllers[i].info.hardware_interfaces.end(); ++it)
cs.hardware_interfaces.push_back(*it);
cs.resources.clear();
cs.resources.reserve(controllers[i].info.resources.size());
for (std::set<std::string>::iterator it = controllers[i].info.resources.begin(); it != controllers[i].info.resources.end(); ++it)
Original file line number Diff line number Diff line change
@@ -57,7 +57,10 @@ def list_controllers():
print "No controllers are loaded in mechanism control"
else:
for c in resp.controller:
print '%s - %s ( %s )'%(c.name, c.hardware_interface, c.state)
if len(c.hardware_interfaces) == 1:
print '%s - %s ( %s )'%(c.name, c.hardware_interfaces[0], c.state)
else:
print '%s - [%s] ( %s )'%(c.name, ", ".join(c.hardware_interfaces), c.state)


def load_controller(name):
2 changes: 1 addition & 1 deletion controller_manager_msgs/msg/ControllerState.msg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
string name
string state
string type
string hardware_interface
string[] hardware_interfaces
string[] resources
Original file line number Diff line number Diff line change
@@ -42,7 +42,8 @@ namespace hardware_interface
*/
struct ControllerInfo
{
std::string name, type, hardware_interface;
std::string name, type;
std::set<std::string> hardware_interfaces;
std::set<std::string> resources;
};

6 changes: 3 additions & 3 deletions hardware_interface/test/robot_hw_test.cpp
Original file line number Diff line number Diff line change
@@ -117,19 +117,19 @@ TEST_F(RobotHWTest, ConflictChecking)
ControllerInfo info1;
info1.name = "controller_1";
info1.type = "type_1";
info1.hardware_interface = "interface_1";
info1.hardware_interfaces.insert("interface_1");
info1.resources.insert("resource_1");

ControllerInfo info2;
info2.name = "controller_2";
info2.type = "type_2";
info2.hardware_interface = "interface_2";
info2.hardware_interfaces.insert("interface_2");
info2.resources.insert("resource_2");

ControllerInfo info12;
info12.name = "controller_12";
info12.type = "type_12";
info12.hardware_interface = "interface_12";
info12.hardware_interfaces.insert("interface_12");
info12.resources.insert("resource_1");
info12.resources.insert("resource_2");