19 #include <cob_base_controller_utils/WheelCommands.h> 20 #include <controller_manager_msgs/SwitchController.h> 21 #include <diagnostic_msgs/DiagnosticArray.h> 22 #include <geometry_msgs/Twist.h> 23 #include <std_srvs/Trigger.h> 50 controller_manager_msgs::SwitchController switch_srv;
52 switch_srv.request.strictness = 1;
54 if (g_switch_controller_client.
call(switch_srv)) {
55 if (switch_srv.response.ok) {
56 ROS_INFO(
"Successfully switched controllers");
58 ROS_ERROR(
"Could not switch controllers");
61 ROS_ERROR(
"ServiceCall failed: switch_controller");
72 std_srvs::Trigger srv;
73 g_recover_client.
call(srv);
86 std_srvs::Trigger srv;
87 g_halt_client.
call(srv);
96 ROS_INFO_STREAM(
"Halt, no movement commands received for " << g_stop_timeout <<
" seconds");
107 g_stop_timer.
start();
110 g_stuck_timeout.
sleep();
122 if (std::strstr(
string.c_str(), substring.c_str())) {
137 for (
size_t i = 0; i < msg->status.size(); i++) {
140 if (msg->status[i].level > diagnostic_msgs::DiagnosticStatus::WARN &&
145 for (
size_t j = 0; j < msg->status[i].values.size(); j++) {
148 if (msg->status[i].values[j].key ==
"errors") {
156 ROS_INFO(
"Recovering from diagnostic error");
160 g_stop_timer.
start();
184 for (
size_t i = 0; i < msg->steer_target_error.size(); ++i) {
194 bool exceeded =
false;
206 g_recover_after_stuck_timer.
stop();
209 g_recover_after_stuck_timer.
start();
233 ROS_INFO(
"Recovering after stopped");
236 ROS_DEBUG(
"Robot is moving, restarting halt timer");
237 g_stop_timer.
start();
243 int main(
int argc,
char* argv[])
245 ros::init(argc, argv,
"cob_halt_detector");
252 ROS_ERROR(
"Please provide a stop threshold");
257 ROS_ERROR(
"Please provide a stuck threshold");
262 if (!nh_priv.
getParam(
"stop_timeout", timeout) || timeout <= 0.0) {
263 ROS_ERROR(
"Please provide valid stop timeout");
268 if (!nh_priv.
getParam(
"stuck_timeout", timeout) || timeout <= 0.0) {
269 ROS_ERROR(
"Please provide valid stuck timeout");
274 if (!nh_priv.
getParam(
"recover_after_stuck_timeout", timeout) || timeout <= 0.0) {
275 ROS_ERROR(
"Please provide valid timeout for recovering after stuck");
281 if (nh_priv.
hasParam(
"diagnostic_recovery_trigger")) {
287 g_last_diagnostic_recover_timestamp =
ros::Time(0);
297 g_halt_client = nh.
serviceClient<std_srvs::Trigger>(
"driver/halt");
298 g_recover_client = nh.
serviceClient<std_srvs::Trigger>(
"driver/recover");
299 g_switch_controller_client = nh.
serviceClient<controller_manager_msgs::SwitchController>(
"controller_manager/switch_controller");
301 g_recover_client.waitForExistence();
302 g_switch_controller_client.waitForExistence();
ros::Duration g_stuck_timeout
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
void haltAfterStopTimeoutCallback(const ros::TimerEvent &)
ros::Time g_last_diagnostic_recover_timestamp
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
ros::ServiceClient g_halt_client
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
std::vector< std::string > g_controller_spawn
bool containsSubstring(std::string string, std::string substring)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
ros::ServiceClient g_recover_client
bool call(MReq &req, MRes &res)
void baseCommandsCallback(const geometry_msgs::Twist::ConstPtr &msg)
void switch_controllers()
bool waitForExistence(ros::Duration timeout=ros::Duration(-1))
bool getParam(const std::string &key, std::string &s) const
std::vector< std::string > g_diagnostic_recovery_trigger
#define ROS_DEBUG_STREAM(args)
int main(int argc, char *argv[])
void recoverAfterStuckCallback(const ros::TimerEvent &)
bool hasParam(const std::string &key) const
ros::ServiceClient g_switch_controller_client
#define ROS_INFO_STREAM(args)
ros::Timer g_recover_after_stuck_timer
ros::Duration g_recover_after_stuck_timeout
ros::Duration g_stop_timeout
std::vector< ros::Time > g_last_wheel_commands_ok
void diagnosticsAggCallback(const diagnostic_msgs::DiagnosticArray::ConstPtr &msg)
#define ROS_ERROR_STREAM(args)
void wheelCommandsCallback(const cob_base_controller_utils::WheelCommands::ConstPtr &msg)