joystick_manual_control.h
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2015, University of Colorado, Boulder
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the Univ of CO, Boulder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 /* Author: Dave Coleman <dave@dav.ee>
36  Desc: Inherit from this file to enable joystick mode switching of your robot
37 */
38 
39 #ifndef ROS_CONTROL_BOILERPLATE__JOYSTICK_MANUAL_CONTROL
40 #define ROS_CONTROL_BOILERPLATE__JOYSTICK_MANUAL_CONTROL
41 
42 // ROS
43 #include <ros/ros.h>
44 #include <sensor_msgs/Joy.h>
45 
46 // ros_control
47 #include <controller_manager_msgs/SwitchController.h>
48 #include <controller_manager_msgs/LoadController.h>
49 
51 {
52 class JoystickManualControl
53 {
54 public:
61  JoystickManualControl(const std::string& parent_name, const std::string& service_namespace)
62  : parent_name_(parent_name), using_trajectory_controller_(true)
63  {
64  switch_service_ = service_namespace + "/controller_manager/switch_controller";
65  load_service_ = service_namespace + "/controller_manager/load_controller";
66 
67  // Switch modes of controllers
68  switch_controlers_client_ = nh_.serviceClient<controller_manager_msgs::SwitchController>(switch_service_);
69  load_controlers_client_ = nh_.serviceClient<controller_manager_msgs::LoadController>(load_service_);
70 
71  // Subscribe to joystick control
72  std::size_t queue_size = 1;
73  remote_joy_ = nh_.subscribe("/joy", queue_size, &JoystickManualControl::joyCallback, this);
74 
75  ROS_INFO_STREAM_NAMED(parent_name_, "JoystickManualControl Ready.");
76  }
77 
82  virtual void joyCallback(const sensor_msgs::Joy::ConstPtr& msg) = 0;
83 
88  {
89  // Ensure services are up
90  ROS_INFO_STREAM_NAMED(parent_name_, "Waiting for serivces...");
92  ROS_ERROR_STREAM_NAMED(parent_name_, "Unable to find service " << switch_service_);
94  ROS_ERROR_STREAM_NAMED(parent_name_, "Unable to find service " << load_service_);
95 
96  for (std::size_t i = 0; i < manual_controllers_.size(); ++i)
97  {
98  ROS_INFO_STREAM_NAMED(parent_name_, "Loading controller " << manual_controllers_[i]);
99  controller_manager_msgs::LoadController service;
100  service.request.name = manual_controllers_[i];
101  std::size_t counter = 0;
102  while (!load_controlers_client_.call(service) && ros::ok())
103  {
104  if (counter > 100)
106  "Failed to load controller '" << manual_controllers_[i] << "', trying again");
107  ros::spinOnce();
108  ros::Duration(0.1).sleep();
109  counter++;
110  }
111  }
112 
113  return true;
114  }
115 
116  void switchToManual()
117  {
118  // Stop all controllers, soft E-Stop
119  controller_manager_msgs::SwitchController service;
120  service.request.strictness = service.request.STRICT;
121 
122  ROS_WARN_STREAM_NAMED(parent_name_, "Switching to MANUAL control");
123  for (std::size_t i = 0; i < manual_controllers_.size(); ++i)
124  {
125  service.request.start_controllers.push_back(manual_controllers_[i]);
126  }
127  for (std::size_t i = 0; i < trajectory_controllers_.size(); ++i)
128  {
129  service.request.stop_controllers.push_back(trajectory_controllers_[i]);
130  }
131 
132  // Attempt stop
133  if (!switch_controlers_client_.call(service))
134  {
135  ROS_ERROR_STREAM_NAMED(parent_name_, "Failed to switch controllers");
136  return;
137  }
138  }
139 
140  void switchToTrajectory()
141  {
142  // Stop all controllers, soft E-Stop
143  controller_manager_msgs::SwitchController service;
144  service.request.strictness = service.request.STRICT;
145 
146  ROS_INFO_STREAM_NAMED(parent_name_, "Switching to TRAJECTORY control");
147  for (std::size_t i = 0; i < manual_controllers_.size(); ++i)
148  {
149  service.request.stop_controllers.push_back(manual_controllers_[i]);
150  }
151  for (std::size_t i = 0; i < trajectory_controllers_.size(); ++i)
152  {
153  service.request.start_controllers.push_back(trajectory_controllers_[i]);
154  }
155 
156  // Attempt stop
157  if (!switch_controlers_client_.call(service))
158  {
159  ROS_ERROR_STREAM_NAMED(parent_name_, "Failed to switch controllers");
160  return;
161  }
162  }
163 
164 protected:
165  // A shared node handle
167 
168  // Name of parent class, used for logging messages
169  const std::string parent_name_;
170  std::string switch_service_;
171  std::string load_service_;
172 
173  // Subscribe to joystick commands
175 
176  // Ability to switch controllers
179 
180  // Switching controller mode
182 
183  // Controller lists
184  std::vector<std::string> manual_controllers_;
185  std::vector<std::string> trajectory_controllers_;
186 
187 }; // end class
188 
189 } // namespace ros_control_boilerplate
190 
191 #endif
ROS_WARN_STREAM_THROTTLE_NAMED
#define ROS_WARN_STREAM_THROTTLE_NAMED(period, name, args)
ros_control_boilerplate::JoystickManualControl::switchToManual
void switchToManual()
Definition: joystick_manual_control.h:180
ros_control_boilerplate::JoystickManualControl::joyCallback
virtual void joyCallback(const sensor_msgs::Joy::ConstPtr &msg)=0
Response to joystick control Button mapping is customized by each class that inherits from this.
ros_control_boilerplate::JoystickManualControl::switch_controlers_client_
ros::ServiceClient switch_controlers_client_
Definition: joystick_manual_control.h:241
ros_control_boilerplate
Definition: generic_hw_control_loop.h:44
ros.h
ros::NodeHandle::serviceClient
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
ros::spinOnce
ROSCPP_DECL void spinOnce()
ros_control_boilerplate::JoystickManualControl::remote_joy_
ros::Subscriber remote_joy_
Definition: joystick_manual_control.h:238
ros::ok
ROSCPP_DECL bool ok()
ros_control_boilerplate::JoystickManualControl::switchToTrajectory
void switchToTrajectory()
Definition: joystick_manual_control.h:204
ros_control_boilerplate::JoystickManualControl::nh_
ros::NodeHandle nh_
Definition: joystick_manual_control.h:230
ros_control_boilerplate::JoystickManualControl::load_controlers_client_
ros::ServiceClient load_controlers_client_
Definition: joystick_manual_control.h:242
ros_control_boilerplate::JoystickManualControl::load_service_
std::string load_service_
Definition: joystick_manual_control.h:235
ros_control_boilerplate::JoystickManualControl::JoystickManualControl
JoystickManualControl(const std::string &parent_name, const std::string &service_namespace)
Constructor.
Definition: joystick_manual_control.h:125
ROS_ERROR_STREAM_NAMED
#define ROS_ERROR_STREAM_NAMED(name, args)
ros::ServiceClient
ros::NodeHandle::subscribe
Subscriber subscribe(const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints())
ros_control_boilerplate::JoystickManualControl::manual_controllers_
std::vector< std::string > manual_controllers_
Definition: joystick_manual_control.h:248
ROS_WARN_STREAM_NAMED
#define ROS_WARN_STREAM_NAMED(name, args)
ros_control_boilerplate::JoystickManualControl::trajectory_controllers_
std::vector< std::string > trajectory_controllers_
Definition: joystick_manual_control.h:249
ros_control_boilerplate::JoystickManualControl::parent_name_
const std::string parent_name_
Definition: joystick_manual_control.h:233
ros::ServiceClient::call
bool call(const MReq &req, MRes &resp, const std::string &service_md5sum)
ros::service::waitForService
ROSCPP_DECL bool waitForService(const std::string &service_name, int32_t timeout)
ROS_INFO_STREAM_NAMED
#define ROS_INFO_STREAM_NAMED(name, args)
ros::Duration::sleep
bool sleep() const
ros_control_boilerplate::JoystickManualControl::using_trajectory_controller_
bool using_trajectory_controller_
Definition: joystick_manual_control.h:245
ros::Duration
ros_control_boilerplate::JoystickManualControl::loadManualControllers
bool loadManualControllers()
Load a secondary manual controller.
Definition: joystick_manual_control.h:151
ros_control_boilerplate::JoystickManualControl::switch_service_
std::string switch_service_
Definition: joystick_manual_control.h:234
ros::NodeHandle
ros::Subscriber


ros_control_boilerplate
Author(s): Dave Coleman
autogenerated on Wed Mar 2 2022 00:52:14