From 54e2477dd6a64f5f595b9e8db2a2143f2051127f Mon Sep 17 00:00:00 2001 From: bav6096 <benedikt.deike@informatik.uni-hamburg.de> Date: Mon, 1 Nov 2021 00:33:09 +0100 Subject: [PATCH] added topic for visualisation --- CMakeLists.txt | 4 +++ msg/Metric.msg | 9 +++--- msg/Monitoring.msg | 1 - msg/State.msg | 3 ++ msg/States.msg | 1 + nodes/monitor_test | 4 +-- nodes/monitor_test2 | 25 ++++++++++++++++ nodes/watchdog | 3 +- src/monitoring/monitor.py | 6 ++-- src/monitoring/watchdog.py | 60 ++++++++++++++++++++++++-------------- 10 files changed, 82 insertions(+), 34 deletions(-) create mode 100644 msg/State.msg create mode 100644 msg/States.msg create mode 100755 nodes/monitor_test2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bd6a6a..8ec28b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,8 @@ add_message_files( FILES Monitoring.msg Metric.msg + States.msg + State.msg ) ## Generate services in the 'srv' folder @@ -161,6 +163,8 @@ include_directories( ## Mark executable scripts (Python etc.) for installation ## in contrast to setup.py, you can choose the destination catkin_install_python(PROGRAMS + nodes/watchdog + nodes/monitor_test2 nodes/monitor_test DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) diff --git a/msg/Metric.msg b/msg/Metric.msg index 26728b1..08f3888 100644 --- a/msg/Metric.msg +++ b/msg/Metric.msg @@ -1,4 +1,5 @@ -string label # Label of the metric. -string value # Value of the metric. -string unit # Unit of the metric. -float32 critical # Critical level of the metric. \ No newline at end of file +string component # A metric is affiliated with a roboter component. +string label # Label of the metric. +string value # Value of the metric. +string unit # Unit of the metric. +float32 critical # Critical level of the metric. \ No newline at end of file diff --git a/msg/Monitoring.msg b/msg/Monitoring.msg index 4274d62..dd121ac 100644 --- a/msg/Monitoring.msg +++ b/msg/Monitoring.msg @@ -1,3 +1,2 @@ -string family # Affiliation of the monitored metric. string origin # Origin of the monitored metric. Metric metric # Monitored metric. \ No newline at end of file diff --git a/msg/State.msg b/msg/State.msg new file mode 100644 index 0000000..0d2c235 --- /dev/null +++ b/msg/State.msg @@ -0,0 +1,3 @@ +string component # Name of the component, whose + # critical level is monitored. +float32 critical # Critical level of the family. \ No newline at end of file diff --git a/msg/States.msg b/msg/States.msg new file mode 100644 index 0000000..d670583 --- /dev/null +++ b/msg/States.msg @@ -0,0 +1 @@ +State[] states # Array of states. diff --git a/nodes/monitor_test b/nodes/monitor_test index 01d669c..50119dd 100755 --- a/nodes/monitor_test +++ b/nodes/monitor_test @@ -6,11 +6,11 @@ from monitoring.monitor import Monitor def monitor_test(): rospy.init_node("monitor_test") - monitor = Monitor(1, 1, "test") + monitor = Monitor(1, 1) rate = rospy.Rate(10) while not rospy.is_shutdown(): - monitor.update_metric("test", 10, "test", 0.5) + monitor.update_metric("family", "label1", 10, "unit", 0.5) rate.sleep() diff --git a/nodes/monitor_test2 b/nodes/monitor_test2 new file mode 100755 index 0000000..663b197 --- /dev/null +++ b/nodes/monitor_test2 @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import rospy +from monitoring.monitor import Monitor + + +def monitor_test(): + rospy.init_node("monitor_test2") + monitor = Monitor(1, 1) + + rate = rospy.Rate(10) + value = 0 + while not rospy.is_shutdown(): + monitor.update_metric("family", "label2", 10, "unit", value) + value = value + 0.1 + if value > 1.0: + value = 0 + rate.sleep() + + +if __name__ == '__main__': + try: + monitor_test() + except rospy.ROSInterruptException: + pass diff --git a/nodes/watchdog b/nodes/watchdog index 24ef85b..dc20214 100755 --- a/nodes/watchdog +++ b/nodes/watchdog @@ -6,11 +6,10 @@ from monitoring.watchdog import Watchdog def watchdog(): rospy.init_node("watchdog") - watching = Watchdog(1.0) + watching = Watchdog(1, 1.0) rate = rospy.Rate(10) while not rospy.is_shutdown(): - print(watching.states) rate.sleep() diff --git a/src/monitoring/monitor.py b/src/monitoring/monitor.py index 54c986a..307b26a 100755 --- a/src/monitoring/monitor.py +++ b/src/monitoring/monitor.py @@ -7,7 +7,7 @@ from monitoring.msg import Metric class Monitor: - def __init__(self, mode=1, freq=1.0, family="generic"): + def __init__(self, mode=1, freq=1.0): self.log = {} # Logging dictionary. Is used to accomplish different publishing modes. self.pub = rospy.Publisher('monitoring', Monitoring, queue_size=1) self.mode = mode @@ -19,16 +19,16 @@ class Monitor: self.timer = rospy.Timer(rospy.Duration(1.0 / freq), self.publish_monitoring) self.monitoring = Monitoring() - self.monitoring.family = family self.monitoring.origin = socket.gethostname() + rospy.get_name() # At the moment the last metric update ist published over and over. def publish_monitoring(self, event): self.pub.publish(self.monitoring) - def update_metric(self, label, value, unit, critical): + def update_metric(self, component, label, value, unit, critical): def set_metric(): metric = Metric() + metric.component = str(component) metric.label = str(label) metric.value = str(value) metric.unit = str(unit) diff --git a/src/monitoring/watchdog.py b/src/monitoring/watchdog.py index 829d084..3529bfd 100755 --- a/src/monitoring/watchdog.py +++ b/src/monitoring/watchdog.py @@ -2,54 +2,70 @@ import rospy from monitoring.msg import Monitoring +from monitoring.msg import State +from monitoring.msg import States class Watchdog: - def __init__(self, freq): - self.states = {} + def __init__(self, mode=1, freq=1.0): + self.mode = mode + self.pub = rospy.Publisher('states', States, queue_size=1) + self.component_states = {} self.observing = {} if not freq > 0.0: rospy.logwarn("Frequency must be greater then 0! Using 1 as frequency!") freq = 1.0 - self.timer = rospy.Timer(rospy.Duration(1.0 / freq), self.update_state) + self.timer = rospy.Timer(rospy.Duration(1.0 / freq), self.update_states) rospy.Subscriber("monitoring", Monitoring, self.logging) def logging(self, monitoring): - family = monitoring.family origin = monitoring.origin metric = monitoring.metric + component = metric.component label = metric.label value = metric.value unit = metric.unit critical = metric.critical - if family in self.observing: - if origin in self.observing[family]: - self.observing[family][origin].update({label: {"value": value, "unit": unit, "critical": critical}}) + if component in self.observing: + if origin in self.observing[component]: + self.observing[component][origin].update({label: {"value": value, "unit": unit, "critical": critical}}) else: - self.observing[family][origin] = {} - self.observing[family][origin][label] = {"value": value, "unit": unit, "critical": critical} + self.observing[component][origin] = {} + self.observing[component][origin][label] = {"value": value, "unit": unit, "critical": critical} else: - self.observing[family] = {} - self.observing[family][origin] = {} - self.observing[family][origin][label] = {"value": value, "unit": unit, "critical": critical} + self.observing[component] = {} + self.observing[component][origin] = {} + self.observing[component][origin][label] = {"value": value, "unit": unit, "critical": critical} - def update_state(self, event): - for family in self.observing: - aggregation = 0 - number = 0 + def update_states(self, event): + for component in self.observing: + # Mode 1: Take the average critical level for a component + if self.mode == 1: + aggregation = 0 + number = 0 - for origin in self.observing[family]: - for label in self.observing[family][origin]: - number = number + 1 - aggregation = aggregation + self.observing[family][origin][label]["critical"] + for origin in self.observing[component]: + for label in self.observing[component][origin]: + number = number + 1 + aggregation = aggregation + self.observing[component][origin][label]["critical"] - quotient = aggregation / number - self.states.update({family: quotient}) + quotient = aggregation / number + self.component_states.update({component: quotient}) + self.publish_states() + def publish_states(self): + topic = States() + for component in self.component_states: + state = State() + state.component = component + state.critical = self.component_states[component] + topic.states.append(state) + + self.pub.publish(topic) -- GitLab