00001 00026 #ifndef GRIZZLY_MOTION_ENCODERS_MONITOR_H 00027 #define GRIZZLY_MOTION_ENCODERS_MONITOR_H 00028 00029 #include <ros/ros.h> 00030 #include <grizzly_msgs/Drive.h> 00031 #include <grizzly_msgs/eigen.h> 00032 00033 namespace diagnostic_updater { 00034 class DiagnosticStatusWrapper; 00035 } 00036 00037 class EncodersMonitor { 00038 public: 00039 EncodersMonitor() {} 00040 EncodersMonitor(ros::NodeHandle* nh); 00041 00042 bool ok(); 00043 bool moving(); 00044 void diagnostic(diagnostic_updater::DiagnosticStatusWrapper&); 00045 00046 bool detectFailedEncoder(); 00047 bool detectFailedEncoderCandidate(VectorDrive::Index* candidate); 00048 00049 // Callbacks receive inbound data 00050 void encodersCallback(const grizzly_msgs::DriveConstPtr&); 00051 void driveCallback(const grizzly_msgs::DriveConstPtr&); 00052 00053 // Encoder data must be this fresh to not be considered out of date. 00054 ros::Duration encoders_timeout; 00055 00056 // Threshold of rad/s difference between mean error and a singular wheel's error necessary 00057 // to mark it as suspicious. 00058 double encoder_speed_error_diff_threshold; 00059 00060 // Time lag between suspecting a failure and taking action. 00061 ros::Duration encoder_fault_time_to_failure; 00062 00063 protected: 00064 ros::Subscriber sub_encoders_, sub_drive_; 00065 int failed_encoder_; 00066 00067 grizzly_msgs::DriveConstPtr last_received_encoders_; 00068 grizzly_msgs::DriveConstPtr last_received_drive_; 00069 ros::Time time_of_last_nonsuspect_encoders_; 00070 }; 00071 00072 #endif