42 Aggregator::Aggregator() :
44 analyzer_group_(NULL),
45 other_analyzer_(NULL),
55 bool other_as_errors =
false;
56 nh.
param(
"other_as_errors", other_as_errors,
false);
62 ROS_ERROR(
"Analyzer group for diagnostic aggregator failed to initialize!");
76 if (diag_msg->header.stamp.toSec() != 0)
79 string stamp_warn =
"No timestamp set for diagnostic message. Message names: ";
80 vector<diagnostic_msgs::DiagnosticStatus>::const_iterator it;
81 for (it = diag_msg->status.begin(); it != diag_msg->status.end(); ++it)
83 if (it != diag_msg->status.begin())
85 stamp_warn += it->name;
99 bool analyzed =
false;
102 boost::mutex::scoped_lock lock(
mutex_);
103 for (
unsigned int j = 0; j < diag_msg->status.size(); ++j)
127 boost::mutex::scoped_lock lock(
mutex_);
128 ROS_WARN(
"Bond for namespace %s was broken", bond_id.c_str());
129 std::vector<boost::shared_ptr<bond::Bond> >::iterator elem;
131 if (elem ==
bonds_.end()){
132 ROS_WARN(
"Broken bond tried to erase a bond which didn't exist.");
138 ROS_WARN(
"Broken bond tried to remove an analyzer which didn't exist.");
146 boost::mutex::scoped_lock lock(
mutex_);
152 diagnostic_msgs::AddDiagnostics::Response &res)
154 ROS_DEBUG(
"Got load request for namespace %s", req.load_namespace.c_str());
156 if (req.load_namespace[0] !=
'/')
158 res.message =
"Requested load from non-global namespace. Private and relative namespaces are not supported.";
166 boost::mutex::scoped_lock lock(
mutex_);
170 res.message =
"Requested load from namespace " + req.load_namespace +
" which is already in use";
179 "/diagnostics_agg/bond" + req.load_namespace, req.load_namespace,
185 bonds_.push_back(req_bond);
190 res.message =
"Successfully initialised AnalyzerGroup. Waiting for bond to form.";
196 res.message =
"Failed to initialise AnalyzerGroup.";
204 diagnostic_msgs::DiagnosticArray diag_array;
206 diagnostic_msgs::DiagnosticStatus diag_toplevel_state;
207 diag_toplevel_state.name =
"toplevel_state";
208 diag_toplevel_state.level = -1;
211 vector<boost::shared_ptr<diagnostic_msgs::DiagnosticStatus> > processed;
213 boost::mutex::scoped_lock lock(
mutex_);
216 for (
unsigned int i = 0; i < processed.size(); ++i)
218 diag_array.status.push_back(*processed[i]);
220 if (processed[i]->level > diag_toplevel_state.level)
221 diag_toplevel_state.level = processed[i]->level;
222 if (processed[i]->level < min_level)
223 min_level = processed[i]->level;
226 vector<boost::shared_ptr<diagnostic_msgs::DiagnosticStatus> > processed_other =
other_analyzer_->
report();
227 for (
unsigned int i = 0; i < processed_other.size(); ++i)
229 diag_array.status.push_back(*processed_other[i]);
231 if (processed_other[i]->level > diag_toplevel_state.level)
232 diag_toplevel_state.level = processed_other[i]->level;
233 if (processed_other[i]->level < min_level)
234 min_level = processed_other[i]->level;
242 if (diag_toplevel_state.level > 2 && min_level <= 2)
243 diag_toplevel_state.level = 2;
virtual std::vector< boost::shared_ptr< diagnostic_msgs::DiagnosticStatus > > report()
The processed output is the combined output of the sub-analyzers, and the top level status...
AnalyzerGroup * analyzer_group_
void diagCallback(const diagnostic_msgs::DiagnosticArray::ConstPtr &diag_msg)
Callback for incoming "/diagnostics".
virtual bool addAnalyzer(boost::shared_ptr< Analyzer > &analyzer)
Add an analyzer to this analyzerGroup.
void publish(const boost::shared_ptr< M > &message) const
virtual bool analyze(const boost::shared_ptr< StatusItem > item)
Update state with new StatusItem.
ros::ServiceServer add_srv_
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
std::string base_path_
Prepended to all status names of aggregator.
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
bool init(std::string path)
void bondFormed(boost::shared_ptr< Analyzer > group)
std::vector< boost::shared_ptr< diagnostic_msgs::DiagnosticStatus > > report()
Reports current state, returns vector of formatted status messages.
void checkTimestamp(const diagnostic_msgs::DiagnosticArray::ConstPtr &diag_msg)
void bondBroken(std::string bond_id, boost::shared_ptr< Analyzer > analyzer)
std::set< std::string > ros_warnings_
Records all ROS warnings. No warnings are repeated.
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
ros::Subscriber diag_sub_
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool addDiagnostics(diagnostic_msgs::AddDiagnostics::Request &req, diagnostic_msgs::AddDiagnostics::Response &res)
Service request callback for addition of diagnostics. Creates a bond between the calling node and the...
virtual bool analyze(const boost::shared_ptr< StatusItem > item)
Analyze returns true if any sub-analyzers will analyze an item.
std::vector< boost::shared_ptr< bond::Bond > > bonds_
Contains all bonds for additional diagnostics.
Allows analyzers to be grouped together, or used as sub-analyzers.
OtherAnalyzer * other_analyzer_
virtual bool init(const std::string base_path, const ros::NodeHandle &n)
Initialized with base path and namespace.
void resetMatches()
Clear match arrays. Used when analyzers are added or removed.
void publishData()
Processes, publishes data. Should be called at pub_rate.
virtual bool removeAnalyzer(boost::shared_ptr< Analyzer > &analyzer)
Remove an analyzer from this analyzerGroup.
virtual bool match(const std::string name)
Match returns true if any sub-analyzers match an item.
ros::Publisher toplevel_state_pub_
Helper class to hold, store DiagnosticStatus messages.