8 #include <controller_manager_msgs/SwitchController.h> 19 controller_manager_msgs::SwitchController srv;
20 srv.request.stop_controllers = controllers;
21 srv.request.strictness = srv.request.BEST_EFFORT;
22 boost::thread
call(boost::bind(ros::service::call<controller_manager_msgs::SwitchController>,
"controller_manager/switch_controller", srv));
28 handles_.insert(std::make_pair(name, handle));
47 urdf::JointConstSharedPtr joint =
getJoint(it->first);
50 status.
error(
"joint " + it->first +
" not found");
60 if(!has_joint_limits){
68 it->second->registerHandle(
pos_interface_, limits, has_soft_limits ? &soft_limits : 0);
69 it->second->registerHandle(
vel_interface_, limits, has_soft_limits ? &soft_limits : 0);
70 it->second->registerHandle(
eff_interface_, limits, has_soft_limits ? &soft_limits : 0);
79 it->second->enforceLimits(period, reset);
89 has_default_mode_ = nh_c.
getParam(
"required_drive_mode", default_mode_);
90 has_lookup_ = nh_c.
getParam(
"required_drive_modes", lookup_);
92 bool hasModes() {
return has_default_mode_ || has_lookup_; }
95 std::map<std::string, int>::iterator
f = lookup_.find(key);
96 if(f != lookup_.end()){
99 }
else if (has_default_mode_) {
106 bool RobotLayer::prepareSwitch(
const std::list<hardware_interface::ControllerInfo> &start_list,
const std::list<hardware_interface::ControllerInfo> &stop_list) {
111 for (std::list<hardware_interface::ControllerInfo>::const_iterator controller_it = stop_list.begin(); controller_it != stop_list.end(); ++controller_it){
120 for (std::list<hardware_interface::ControllerInfo>::const_iterator controller_it = start_list.begin(); controller_it != start_list.end(); ++controller_it){
125 std::set<std::string> claimed_interfaces;
127 if(controller_it->claimed_resources.size() > 0){
128 for (std::vector<hardware_interface::InterfaceResources>::const_iterator cres_it = controller_it->claimed_resources.begin(); cres_it != controller_it->claimed_resources.end(); ++cres_it){
129 for (std::set<std::string>::const_iterator res_it = cres_it->resources.begin(); res_it != cres_it->resources.end(); ++res_it){
130 claimed_interfaces.insert(cres_it->hardware_interface);
132 ROS_ERROR_STREAM(
"Please set required_drive_mode(s) for controller " << controller_it->name);
136 ROS_ERROR_STREAM(
"controller "<< controller_it->name <<
" has mixed interfaces, please set required_drive_modes.");
140 boost::unordered_map< std::string, HandleLayerBaseSharedPtr >::const_iterator h_it =
handles_.find(*res_it);
142 const std::string & joint = *res_it;
156 if(g_interface_mapping.
hasConflict(cres_it->hardware_interface, sd.
mode)){
173 to_switch.push_back(sd);
178 switch_map_.insert(std::make_pair(controller_it->name, to_switch));
182 boost::unordered_set<HandleLayerBaseSharedPtr > to_stop;
183 std::vector<std::string> failed_controllers;
184 for (std::list<hardware_interface::ControllerInfo>::const_iterator controller_it = stop_list.begin(); controller_it != stop_list.end(); ++controller_it){
186 for(RobotLayer::SwitchContainer::iterator it = to_switch.begin(); it != to_switch.end(); ++it){
187 to_stop.insert(it->handle);
190 for (std::list<hardware_interface::ControllerInfo>::const_iterator controller_it = start_list.begin(); controller_it != start_list.end(); ++controller_it){
193 for(RobotLayer::SwitchContainer::iterator it = to_switch.begin(); it != to_switch.end(); ++it){
196 for(RobotLayer::SwitchContainer::iterator it = to_switch.begin(); it != to_switch.end(); ++it){
197 if(!it->handle->switchMode(it->mode)){
198 failed_controllers.push_back(controller_it->name);
199 ROS_ERROR_STREAM(
"Could not switch one joint for " << controller_it->name <<
", will stop all related joints and the controller.");
200 for(RobotLayer::SwitchContainer::iterator stop_it = to_switch.begin(); stop_it != to_switch.end(); ++stop_it){
201 to_stop.insert(stop_it->handle);
206 it->handle->enableLimits(it->enforce_limits);
208 to_stop.erase(it->handle);
211 for(boost::unordered_set<HandleLayerBaseSharedPtr >::iterator it = to_stop.begin(); it != to_stop.end(); ++it){
214 if(!failed_controllers.empty()){
222 void RobotLayer::doSwitch(
const std::list<hardware_interface::ControllerInfo> &start_list,
const std::list<hardware_interface::ControllerInfo> &stop_list) {
223 std::vector<std::string> failed_controllers;
224 for (std::list<hardware_interface::ControllerInfo>::const_iterator controller_it = start_list.begin(); controller_it != start_list.end(); ++controller_it){
227 for(RobotLayer::SwitchContainer::iterator it = to_switch.begin(); it != to_switch.end(); ++it){
228 if(!it->handle->forwardForMode(it->mode)){
229 failed_controllers.push_back(controller_it->name);
230 ROS_ERROR_STREAM(
"Could not switch one joint for " << controller_it->name <<
", will stop all related joints and the controller.");
231 for(RobotLayer::SwitchContainer::iterator stop_it = to_switch.begin(); stop_it != to_switch.end(); ++stop_it){
238 }
catch(
const std::out_of_range&){
239 ROS_ERROR_STREAM(
"Conttroller " << controller_it->name <<
"not found, will stop it");
240 failed_controllers.push_back(controller_it->name);
243 if(!failed_controllers.empty()){
void registerInterface(T *iface)
virtual void add(const VectorMemberSharedPtr &l)
hardware_interface::PositionJointInterface pos_interface_
urdf::JointConstSharedPtr getJoint(const std::string &n) const
std::map< std::string, int > lookup_
void add(const std::string &name, HandleLayerBaseSharedPtr handle)
HandleLayerBaseSharedPtr handle
void enforce(const ros::Duration &period, bool reset)
ModeLookup(ros::NodeHandle &nh_c)
virtual void handleInit(LayerStatus &status)
virtual bool prepareSwitch(const std::list< ControllerInfo > &start_list, const std::list< ControllerInfo > &stop_list)
bool hasConflict(const std::string &interface, canopen::MotorBase::OperationMode mode)
virtual void handleInit(canopen::LayerStatus &status)
bool getSoftJointLimits(urdf::JointConstSharedPtr urdf_joint, SoftJointLimits &soft_limits)
hardware_interface::JointStateInterface state_interface_
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
canopen::MotorBase::OperationMode mode
URDF_EXPORT bool initParam(const std::string ¶m)
#define ROS_WARN_STREAM(args)
bool getMode(MotorBase::OperationMode &om, const std::string &key)
boost::atomic< bool > first_init_
vector_type::iterator call(FuncType func, Data &status)
InterfaceMapping g_interface_mapping
hardware_interface::VelocityJointInterface vel_interface_
bool getParam(const std::string &key, std::string &s) const
hardware_interface::EffortJointInterface eff_interface_
bool getJointLimits(urdf::JointConstSharedPtr urdf_joint, JointLimits &limits)
virtual void doSwitch(const std::list< hardware_interface::ControllerInfo > &start_list, const std::list< hardware_interface::ControllerInfo > &stop_list)
const void error(const std::string &r)
std::vector< SwitchData > SwitchContainer
#define ROS_ERROR_STREAM(args)
virtual bool prepareSwitch(const std::list< hardware_interface::ControllerInfo > &start_list, const std::list< hardware_interface::ControllerInfo > &stop_list)
RobotLayer(ros::NodeHandle nh)
void stopControllers(const std::vector< std::string > controllers)