stop_detector.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <string>
18 #include <vector>
19 #include <ros/ros.h>
20 #include <std_srvs/Trigger.h>
21 #include <geometry_msgs/Twist.h>
22 #include <controller_manager_msgs/SwitchController.h>
23 
30 double g_threshold;
33 std::vector<std::string> g_controller_spawn;
34 
35 
37  controller_manager_msgs::SwitchController switch_srv;
38  switch_srv.request.start_controllers = g_controller_spawn;
39  switch_srv.request.strictness = 1; // BEST_EFFORT
40  //switch_srv.request.strictness = 2; // STRICT
41 
42  if (g_switch_client.call(switch_srv))
43  {
44  if (switch_srv.response.ok)
45  {
46  ROS_INFO("Successfully switched controllers");
47  }
48  else
49  {
50  ROS_ERROR("Could not switch controllers");
51  }
52  }
53  else
54  {
55  ROS_ERROR("ServiceCall failed: switch_controller");
56  }
57 }
58 
59 void recover(){
60  g_recovering = true;
61  std_srvs::Trigger srv;
62  ROS_INFO("Recovering");
63  g_recover_client.call(srv);
65  g_recovered = srv.response.success;
66  g_recovering = false;
67 }
68 
77 void commandsCallback(const geometry_msgs::Twist::ConstPtr& msg){
78  if (fabs(msg->linear.x) >= g_threshold ||
79  fabs(msg->linear.y) >= g_threshold ||
80  fabs(msg->linear.z) >= g_threshold ||
81  fabs(msg->angular.x) >= g_threshold ||
82  fabs(msg->angular.y) >= g_threshold ||
83  fabs(msg->angular.z) >= g_threshold) {
84  g_halt_timer.stop();
85  if (!g_recovered && !g_recovering) {
86  recover();
87  }
88  ROS_DEBUG("Robot is moving, restarting halt timer");
89  g_halt_timer.start();
90  }
91 }
92 
94  g_recovered = false;
95  std_srvs::Trigger srv;
96  ROS_INFO_STREAM("Halt, no movement commands received for " << g_timeout << " seconds");
97  g_halt_client.call(srv);
98 }
99 
100 int main(int argc, char* argv[])
101 {
102  ros::init(argc, argv, "cob_stop_detector");
103 
104  ros::NodeHandle nh;
105  ros::NodeHandle nh_priv("~");
106 
107  double timeout;
108  if(!nh_priv.getParam("timeout", timeout) || timeout <= 0.0){
109  ROS_ERROR("Please provide valid timeout");
110  return 1;
111  }
112 
113  if(!nh_priv.getParam("threshold", g_threshold)){
114  ROS_ERROR("Please provide stop threshold");
115  return 1;
116  }
117 
118  g_recovered = true;
119  g_recovering = false;
120  g_timeout = ros::Duration(timeout);
121  g_controller_spawn = {"joint_state_controller", "twist_controller"};
122 
123  g_halt_client = nh.serviceClient<std_srvs::Trigger>("driver/halt");
124  g_recover_client = nh.serviceClient<std_srvs::Trigger>("driver/recover");
125  g_switch_client = nh.serviceClient<controller_manager_msgs::SwitchController>("controller_manager/switch_controller");
126  g_halt_client.waitForExistence();
127  g_recover_client.waitForExistence();
128  g_switch_client.waitForExistence();
129  g_halt_timer = nh.createTimer(g_timeout, haltCallback, true, false); //oneshot=true, auto_start=false
130  ros::Subscriber command_sub = nh.subscribe("twist_controller/command", 10, commandsCallback);
131 
132  ros::spin();
133  return 0;
134 }
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
int main(int argc, char *argv[])
void haltCallback(const ros::TimerEvent &)
ros::Timer g_silence_timer
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
void switch_controller()
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void commandsCallback(const geometry_msgs::Twist::ConstPtr &msg)
void stop()
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
bool call(MReq &req, MRes &res)
void start()
ros::ServiceClient g_switch_client
ros::Duration g_timeout
bool waitForExistence(ros::Duration timeout=ros::Duration(-1))
#define ROS_INFO(...)
bool getParam(const std::string &key, std::string &s) const
ROSCPP_DECL void spin()
std::vector< std::string > g_controller_spawn
#define ROS_INFO_STREAM(args)
ros::ServiceClient g_recover_client
bool g_recovered
#define ROS_ERROR(...)
double g_threshold
void recover()
ros::ServiceClient g_halt_client
ros::Timer g_halt_timer
#define ROS_DEBUG(...)
bool g_recovering


cob_base_controller_utils
Author(s): Felix Messmer , Mathias Lüdtke
autogenerated on Mon May 1 2023 02:50:06