Skip to content

Instantly share code, notes, and snippets.

@mikepurvis
Created November 24, 2017 19:58
Show Gist options
  • Save mikepurvis/070a4f163986da4513e7907576aa25b9 to your computer and use it in GitHub Desktop.
Save mikepurvis/070a4f163986da4513e7907576aa25b9 to your computer and use it in GitHub Desktop.
Example of extending a controller and changing the interface _without_ needing multiple inheritance.
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017, Clearpath Robotics Inc.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of hiDOF, Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//////////////////////////////////////////////////////////////////////////////
#include <controller_manager_tests/extensible_controllers.h>
using namespace controller_manager_tests;
bool ExtensibleController::init(hardware_interface::RobotHW* robot_hw,
ros::NodeHandle& root_nh, ros::NodeHandle& controller_nh)
{
std::string vel_joint_name;
controller_nh.getParam("velocity_joint", vel_joint_name);
hardware_interface::VelocityJointInterface* joint_iface = robot_hw->get<hardware_interface::VelocityJointInterface>();
joint_iface->getHandle(vel_joint_name);
return true;
}
int ExtensibleController::helper()
{
return 1;
}
void ExtensibleController::update(const ros::Time&, const ros::Duration&)
{
// TODO: Publish this return value so that the test can validate it?
int foo = helper();
}
bool DerivedController::init(hardware_interface::RobotHW* robot_hw,
ros::NodeHandle& root_nh, ros::NodeHandle& controller_nh)
{
// First initialize the base controller.
base_controller.reset(new ExtendingController());
if (!base_controller->init(robot_hw, root_nh, controller_nh))
{
return false;
}
std::string eff_joint_name;
controller_nh.getParam("effort_joint", eff_joint_name);
hardware_interface::EffortJointInterface* joint_iface = robot_hw->get<hardware_interface::EffortJointInterface>();
joint_iface->getHandle(eff_joint_name);
return true;
}
void DerivedController::update(const ros::Time& t, const ros::Duration& d)
{
base_controller->update(t, d);
}
int ExtendingController::helper()
{
return 2;
}
PLUGINLIB_EXPORT_CLASS(controller_manager_tests::ExtensibleController, controller_interface::ControllerBase)
PLUGINLIB_EXPORT_CLASS(controller_manager_tests::DerivedController, controller_interface::ControllerBase)
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017, Clearpath Robotics Inc.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of hiDOF, Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//////////////////////////////////////////////////////////////////////////////
#ifndef CONTROLLER_MANAGER_TESTS_EXTENSIBLE_CONTROLLERS_H
#define CONTROLLER_MANAGER_TESTS_EXTENSIBLE_CONTROLLERS_H
#include <boost/scoped_ptr.hpp>
#include <controller_interface/multi_interface_controller.h>
#include <hardware_interface/joint_command_interface.h>
#include <pluginlib/class_list_macros.h>
namespace controller_manager_tests
{
/**
* This controller supplies an intentional extension point in the form of the virtual
* "helper" function that the update method calls.
*/
class ExtensibleController : public controller_interface::MultiInterfaceController<hardware_interface::VelocityJointInterface>
{
public:
bool init(hardware_interface::RobotHW* robot_hw, ros::NodeHandle& root_nh, ros::NodeHandle& controller_nh);
virtual int helper();
void update(const ros::Time&, const ros::Duration&);
};
/**
* The derived controller not only overrides the virtual helper method, it also adds an additional
* hardware interface, in order to demonstrate the flexbility of this mechanism.
*/
class ExtendingController : public ExtensibleController
{
friend class DerivedController;
virtual int helper();
};
class DerivedController : public controller_interface::MultiInterfaceController<
hardware_interface::VelocityJointInterface, hardware_interface::EffortJointInterface>
{
public:
bool init(hardware_interface::RobotHW* robot_hw, ros::NodeHandle& root_nh, ros::NodeHandle& controller_nh);
void update(const ros::Time&, const ros::Duration&);
boost::scoped_ptr<ExtendingController> base_controller;
};
} // namespace controller_manager_tests
#endif // CONTROLLER_MANAGER_TESTS_EXTENSIBLE_CONTROLLERS_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment