def get_short_data(self): """ Returns a shortend version of the item data. :returns: data of the item :rtype: str """ data_dict = self.get_latest_data() if data_dict["window_stop"] == Time(0): return "No data yet" elif (Time.now() - data_dict["window_stop"]) > Duration(MAXIMUM_OFFLINE_TIME): # last entry was more than MAXIMUM_OFFLINE_TIME ago, it could be offline! return "No data since " + str(round((Time.now() - data_dict["window_stop"]).to_sec(), ROUND_DIGITS)) \ + " seconds" content = "" if data_dict["state"] is "error": content += self.get_erroneous_entries_for_log() else: content += self.tr("node_cpu_usage_mean") + ": " + prepare_number_for_representation( data_dict["node_cpu_usage_mean"]) + " " + self.tr("node_cpu_usage_mean_unit") + " - " content += self.tr("node_ramusage_mean") + ": " + prepare_number_for_representation( data_dict["node_ramusage_mean"]) \ + " " + self.tr("node_ramusage_mean_unit") + " - " content += self.tr("node_message_frequency_mean") + ": " + prepare_number_for_representation( data_dict["node_message_frequency_mean"]) \ + " " + self.tr("node_message_frequency_mean_unit") + " - " content += self.tr("node_bandwidth_mean") + ": " + prepare_number_for_representation( data_dict["node_bandwidth_mean"]) \ + " " + self.tr("node_bandwidth_mean_unit") return content
def get_short_data(self): """ Returns a shortend version of the item data. :returns: data of the item :rtype: str """ data_dict = self.get_latest_data() if data_dict["window_stop"] == Time(0): return "No data yet" elif (Time.now() - data_dict["window_stop"]) > Duration(MAXIMUM_OFFLINE_TIME): # last entry was more than MAXIMUM_OFFLINE_TIME ago, it could be offline! return "No data since " + prepare_number_for_representation(Time.now() - data_dict["window_stop"]) \ + " seconds" content = "" if data_dict["state"] is "error": content += self.get_erroneous_entries_for_log() else: content += self.tr("frequency") + ": " + prepare_number_for_representation(data_dict["frequency"]) \ + " " + self.tr("frequency_unit") + " - " content += self.tr("bandwidth") + ": " + prepare_number_for_representation( data_dict["bandwidth"]) + " " \ + self.tr("bandwidth_unit") + " - " content += self.tr("dropped_msgs") + ": " + prepare_number_for_representation(data_dict["dropped_msgs"]) \ + " " + self.tr("dropped_msgs_unit") return content
def _get_start_end_time(self, limit): """ Returns the start and end time to use (rospy.Time). also sets self.start_stamp, self.end_stamp """ from rospy.rostime import Time # @UnresolvedImport self.info('limit: %r' % limit) warnings.warn('Make better code for dealing with unindexed') if limit is not None and limit != 0: # try: chunks = self.bag.__dict__['_chunks'] self.start_stamp = chunks[0].start_time.to_sec() self.end_stamp = chunks[-1].end_time.to_sec() start_time = Time.from_sec(self.start_stamp) end_time = Time.from_sec(self.start_stamp + limit) return start_time, end_time # except Exception as e: # self.error('Perhaps unindexed bag?') # self.error(traceback.format_exc(e)) # raise # start_time = None # end_time = None # # self.info('start_stamp: %s' % self.start_stamp) # self.info('end_stamp: %s' % self.end_stamp) else: self.start_stamp = None self.end_stamp = None return None, None
def __transform_rated_statistics_item(self, item): """ Integrates RatedStatistics in the model by moding its item/s by adding a new dict to the corresponding item. :param item: the RatedStatisics item :type item: RatedStatistics """ # get identifier seuid = item.seuid if item.seuid == "t!/image_raw": tmp = self.__identifier_dict[seuid] for i in range(0, len(item.rated_statistics_entity)): if item.rated_statistics_entity[i].statistic_type == "frequency": print(item.rated_statistics_entity[i].actual_value) print(tmp.get_latest_data()["frequency"]) # check if avaiable if seuid not in self.__identifier_dict: # having a problem, item doesn't exist but should not be created here self.__logger.log("Warning", Time.now(), "RosModel", "A rating was received for an item the gui does not " "know about. This typically means a dead node/ host but" " could also indicate an error. If this happens at " "startup you can typically ignore it. ") else: # update it current_item = self.__identifier_dict[seuid] current_item.update_rated_data(item)
def update_rated_data(self, data): """ Appends data to the rated_data of the AbstractItem. :param data: the data to append in key value form :type data: RatedStatistics :raises KeyError: if an entry is in the rated dictionary but not found in the message """ self._rated_data_lock.acquire() self._rated_data["window_start"].append(data.window_start) self._rated_data["window_stop"].append(data.window_stop) last_state = self.get_state() new_state = "unknown" for element in data.rated_statistics_entity: self._rated_data[element.statistic_type + ".actual_value"].append(element.actual_value) self._rated_data[element.statistic_type + ".expected_value"].append(element.expected_value) for i in range(0, len(element.state)): state = topic_statistics_state_to_string(element, element.state[i]) self._rated_data[element.statistic_type + ".state"].append(state) if (state is "low" or state is "high") and state is not "ok" and state is not "unkown": new_state = "error" elif state is "ok" and new_state is not "error": new_state = "ok" self.add_state(new_state) self._update_current_state() if new_state is "error" and last_state is not "error": self._logger.log("error", Time.now(), self.seuid, self.get_erroneous_entries_for_log()) self._rated_data_lock.release()
def append_data_dict(self, data): """ Appends data to the data of the AbstractItem. :param data: the data to append in key value form :type data: dict :raises KeyError: if an entry is in the global data dictionary but not found in the given dictionary """ self._data_lock.acquire() self.alive = True if "window_stop" not in data: data["window_stop"] = Time.now() for attribute in self._data: if attribute in data: self._data[attribute].append(data[attribute]) else: self._data[attribute].append(None) if "state" in data: self.add_state((data["state"])) else: self.add_state("unknown") self._length_of_data += 1 self._update_current_state() self._data_lock.release()
def create_graphs(self): """ Creates the graphs for the plot. """ self.__update_graphs_lock.acquire() if self.__selected_item is not None: first_iteration = True first_view = None i = 0 self.__expected_items_per_group = 0 self.__graph_layout.clear() if len(self.__plotable_items) is 0: raise UserWarning() for key in self.__plotable_items[min( self.__current_selected_combo_box_index * self.__items_per_group, len(self.__plotable_items)):min( (self.__current_selected_combo_box_index + 1) * self.__items_per_group, len(self.__plotable_items))]: plot_widget = None if first_iteration: first_iteration = False date_axis = DateAxis(orientation="bottom") first_view = pg.ViewBox() plot_widget = self.__graph_layout.addPlot( title=self.tr(key), axisItems={'bottom': date_axis}, viewBox=first_view) else: date_axis = DateAxis(orientation="bottom") view_box = pg.ViewBox() plot_widget = self.__graph_layout.addPlot( title=self.tr(key), viewBox=view_box, axisItems={'bottom': date_axis}) view_box.setXLink(first_view) #performance enhancements when only a short range of the plot is shown #plot_widget.setClipToView(clip=True) plot_widget.setYRange(-1, 1) self.__graph_dict[key] = plot_widget self.__graph_layout.nextRow() plot_widget = self.__graph_dict[key] plot_widget.showGrid(x=True, y=True) plot_widget.setMenuEnabled(enableMenu=True) plot_widget.enableAutoRange('xy', True) x = np.array([1]) y = np.array([int(str(Time.now())) / 1000000000]) self.__plotted_curves[key] = plot_widget.plot(x=x, y=y, fillLevel=0, brush=(50, 50, 200, 100), pen=(255, 0, 0)) self.__expected_items_per_group += 1 self.__first_update_pending = True self.__update_graphs_lock.release()
def update_graphs(self, event): """ Updates and redraws the graphs. """ self.__update_graphs_lock.acquire() if self.__draw_graphs or self.__first_update_pending: plotable_items = self.__plotable_items[min( self.__current_selected_combo_box_index * self.__items_per_group, len(self.__plotable_items)):min( (self.__current_selected_combo_box_index + 1) * self.__items_per_group, len(self.__plotable_items))] plotable_data = self.__model.get_root_item( ).get_items_younger_than( Time.now() - (Duration(secs=self.__combo_box_index_to_seconds( self.__current_range_combo_box_index)) if int( Duration(secs=self.__combo_box_index_to_seconds( self.__current_range_combo_box_index)).to_sec()) <= int(Time.now().to_sec()) else Time(0)), "window_stop", *plotable_items) temp_time = [] temp_content = [] if plotable_data["window_stop"]: modulo = (len(plotable_data["window_stop"]) / 200) + 1 length = len(plotable_data["window_stop"]) else: length = 0 modulo = 1 for i in range(0, length, modulo): # now having maximally 100 items to plot :) temp_time.append( int(str(plotable_data["window_stop"][i])) / 1000000000) x = np.array(temp_time) for key in plotable_items: for i in range(0, length, modulo): temp_content.append(plotable_data[key][i]) y = np.array(temp_content) del temp_content[:] self.__plotted_curves[key].setData(x=x, y=y) self.__first_update_pending = False self.__update_graphs_lock.release()
def get_short_data(self): """ Returns a shortend version of the item data. :returns: data of the item :rtype: str """ data_dict = self.get_latest_data() if data_dict["window_stop"] == Time(0): return "No data yet" elif (Time.now() - data_dict["window_stop"]) > Duration(MAXIMUM_OFFLINE_TIME): # last entry was more than MAXIMUM_OFFLINE_TIME ago, it could be offline! return ( "No data since " + prepare_number_for_representation(Time.now() - data_dict["window_stop"]) + " seconds" ) content = "" if data_dict["state"] is "error": content += self.get_erroneous_entries_for_log() else: content += ( self.tr("cpu_usage_mean") + ": " + prepare_number_for_representation(data_dict["cpu_usage_mean"]) + " " + self.tr("cpu_usage_mean_unit") + " - " ) content += ( self.tr("ram_usage_mean") + ": " + prepare_number_for_representation(data_dict["ram_usage_mean"]) + " " + self.tr("ram_usage_mean_unit") + " - " ) content += ( self.tr("cpu_temp_mean") + ": " + prepare_number_for_representation(data_dict["cpu_temp_mean"]) + " " + self.tr("cpu_temp_mean_unit") ) return content
def _rosout(level, msg, fname, line, func): global _in_rosout try: if _rosout_pub is not None: # protect against infinite recursion if not _in_rosout: try: _in_rosout = True msg = str(msg) # check parameter server/cache for omit_topics flag # the same parameter is checked in rosout_appender.cpp for the same purpose disable_topics_ = rospy.get_param_cached( "/rosout_disable_topics_generation", False) # if not disable_topics_: # topics = get_topic_manager().get_topics() # else: # topics = "" ros_master_uri = "" ros_ip = "" ros_hostname = "" if "ROS_MASTER_URI" in os.environ: ros_master_uri = os.environ["ROS_MASTER_URI"] if "ROS_IP" in os.environ: ros_ip = os.environ["ROS_IP"] if "ROS_HOSTNAME" in os.environ: ros_hostname = os.environ["ROS_HOSTNAME"] l = Log( level=level, name=str(rospy.names.get_caller_id()), msg=str(msg), # topics=topics, file=fname, line=line, function=func, username=getpass.getuser(), ros_master_uri=ros_master_uri, ros_ip=ros_ip, ros_hostname=ros_hostname, ) l.header.stamp = Time.now() _rosout_pub.publish(l) finally: _in_rosout = False except Exception as e: # traceback.print_exc() # don't use logerr in this case as that is recursive here logger = logging.getLogger("rospy.rosout") logger.error("Unable to report rosout: %s\n%s", e, traceback.format_exc()) return False
def __aggregate_topic_data(self, event): """ Aggregates the topic every TOPIC_AGGREGATION_FREQUENCY nsecs and pushes the updated data to self.__calculated_data. :param event: containing information when this method was called - not used but needed for the interface """ aggregated_data = {} for key in self._attributes: aggregated_data[key] = 0 for key in self.__calculated_data.keys(): self.__calculated_data[key].append(0) child_count = 0 for connection in self.get_childs(): # !assuming all childs are connection items! values = connection.aggregate_data(self.__aggregation_window) # average over N seconds if values: for key in self.add_keys: aggregated_data[key] += values[key] for key in self.max_keys: if values[key] > aggregated_data[key]: aggregated_data[key] = values[key] for key in self.avg_keys: aggregated_data[key] += values[key] child_count += 1 for key in self.avg_keys: if child_count == 0: aggregated_data[key] = 0 else: aggregated_data[key] /= child_count self._data_lock.acquire() for key in self._attributes: self.__calculated_data[key][-1] = aggregated_data[key] self.__calculated_data["window_start"][-1] = Time.now() self.__calculated_data["window_stop"][-1] = Time.now() - (Duration(secs=1) if int(Duration(secs=1).to_sec()) <= int(Time.now().to_sec()) else Time(0)) self._data_lock.release()
def __init__(self, parent=None): """ Defines the class attributes especially the root_item which later contains the list of headers e.g. for a TreeView representation. :param parent: the parent of the model :type parent: QObject """ super(ROSModel, self).__init__(parent) self.__logger = ModelLogger() self._translator = QTranslator() # internationalize everything including the 2 plugins self.rp = rospkg.RosPack() directory = os.path.join(self.rp.get_path('arni_gui'), 'translations') files = find_qm_files(directory) translator = self.get_translator() # todo: make this more intelligent (should be done as soon as new languages are needed / implemented) print("chose translation " + files[0]) translator.load(files[0]) qApp.installTranslator(translator) self.__root_item = RootItem(self.__logger, "abstract", self) self.__parent = parent self.__model_lock = Lock() self.update_signal.connect(self.update_model) """ IMPORTANT: Does not contain the models nodes but the logical nodes. E.g. a ConnectionItem splits up to two TreeConnectionItems where the identifier_dict only contains the connectionitem. This allows to push data into one item but to show it at two places in the Qt GUI. """ self.__identifier_dict = {"root": self.__root_item} self.__item_delegate = SizeDelegate() # CAUTION: Do not change this mapping if not absolutely necessary. If you change it remember to change # item_filter_proxy (and maybe other classes) as well - sadly not all functions use the access function. self.__mapping = { 0: 'type', 1: 'name', 2: 'state', 3: 'data' } self.__last_time_error_occured = 0 self.__logger.log("info", Time.now(), "ROSModel", "ROSModel initialization finished") self.__seuid_helper = SEUID() self.__find_host = HostLookup() self.__buffer_thread = BufferThread(self) self.__buffer_thread.start()
def get_short_data(self): """ Returns a shortend version of the item data. :returns: data of the item :rtype: str """ data_dict = {} for key in self.__calculated_data: if self.__calculated_data[key]: data_dict[key] = self.__calculated_data[key][-1] else: data_dict[key] = self.tr("Currently no value available") data_dict["window_stop"] = Time(0) data_dict["window_start"] = Time(0) data_dict["state"] = self.get_state() try: if data_dict["window_stop"] == Time(0): return "No data yet" elif (Time.now() - data_dict["window_stop"]) > Duration(MAXIMUM_OFFLINE_TIME): # last entry was more than MAXIMUM_OFFLINE_TIME ago, it could be offline! return "No data since " + prepare_number_for_representation(Time.now() - data_dict["window_stop"]) \ + " seconds" except: print(data_dict["window_stop"]) raise UserWarning content = "" if data_dict["state"] is "error": content += self.get_erroneous_entries_for_log() else: content += self.tr("frequency") + ": " + prepare_number_for_representation( data_dict["frequency"]) + " " \ + self.tr("frequency_unit") + " - " content += self.tr("bandwidth") + ": " + prepare_number_for_representation(data_dict["bandwidth"]) \ + " " + self.tr("bandwidth_unit") + " - " content += self.tr("dropped_msgs") + ": " + prepare_number_for_representation(data_dict["dropped_msgs"]) \ + " " + self.tr("dropped_msgs_unit") return content
def __init__(self, logger, seuid, parent=None): """ Initializes the AbstractItem. :param seuid: the seuid of the AbstractItem :type seuid: str :param logger: a logger where to log when special events occur :type logger: ModelLogger :param parent: the parent-item :type parent: AbstractItem """ super(AbstractItem, self).__init__(parent) self._logger = logger self._data = {} self.counter = 0 """ _rated_data is dict containing the rated data. state, window_start and window_end are simply lists with the corresponding entries. Any other values typically is a list containing lists which however contain the values. This is equivalent to the representation in the RatedStatistics/Entity. """ self._rated_data = {} self._child_items = [] self.__parent = parent self.seuid = seuid self._type = "type" self.__data_attribute = "data" self.__state = [] # self.__last_update = Time.now() self.__creation_time = Time.now() self.marked = False # self.markation_date = Time.now() self._add_data_list("window_start") self._add_data_list("window_stop") self._add_rated_data_list("window_start") self._add_rated_data_list("window_stop") self._length_of_data = 0 self._length_of_rated_data = 0 self._data_lock = Lock() self._rated_data_lock = Lock() self._rated_attributes = [] self._rated_attributes.append("alive.actual_value") self._rated_attributes.append("alive.expected_value") self._rated_attributes.append("alive.state") #self._alive_timer = rospy.Time.now() #self.alive = True #rospy.Timer(rospy.Duration(ALIVE_TIMER_CALLBACK), self._updateTimer) #self._offline_time = rospy.Duration(MAXIMUM_OFFLINE_TIME) self.is_subscriber = False
def update_graphs(self, event): """ Updates and redraws the graphs. """ self.__update_graphs_lock.acquire() if self.__selected_item is not None: if self.__draw_graphs or self.__first_update_pending: #print("items per group: " + str(self.__items_per_group)) #print("combo index: " + str(self.__current_selected_combo_box_index)) #print("len plot " + str(len(self.__plotable_items))) plotable_items = self.__plotable_items[min(self.__current_selected_combo_box_index * self.__items_per_group, len(self.__plotable_items)):min((self.__current_selected_combo_box_index + 1) * self.__items_per_group, len(self.__plotable_items))] plotable_data = self.__selected_item.get_items_younger_than( #Time.now() - Duration(secs=self.__combo_box_index_to_seconds(self.__current_range_combo_box_index)), Time.now() - (Duration(secs=(self.__combo_box_index_to_seconds(self.__current_range_combo_box_index) + 10 )) if int(Duration(secs=self.__combo_box_index_to_seconds(self.__current_range_combo_box_index)).to_sec()) <= int(Time.now().to_sec()) else Time(0) ), "window_stop", *plotable_items) if "window_stop" in plotable_data: if plotable_data["window_stop"]: temp_time = [] temp_content = [] length = len(plotable_data["window_stop"]) modulo = (length / 200) + 1 for i in range(0, length, modulo): # now having maximally 100 items to plot :) temp_time.append(plotable_data["window_stop"][i].to_sec()) x = np.array(temp_time) list_entries = self.__selected_item.get_list_items() time_entries = self.__selected_item.get_time_items() for key in plotable_items: if key in list_entries: pass else: if key in time_entries: for i in range(0, length, modulo): temp_content.append(float(str(plotable_data[key][i]))/1000000000) else: for i in range(0, length, modulo): temp_content.append(plotable_data[key][i]) y = np.array(temp_content) del temp_content[:] self.__plotted_curves[key].setData(x=x, y=y) else: pass self.__first_update_pending = False self.__update_graphs_lock.release()
def create_graphs(self): """ Creates the graphs for the plot. """ self.__update_graphs_lock.acquire() if self.__selected_item is not None: first_iteration = True first_view = None i = 0 self.__expected_items_per_group = 0 self.__graph_layout.clear() if len(self.__plotable_items) is 0: raise UserWarning() for key in self.__plotable_items[min(self.__current_selected_combo_box_index * self.__items_per_group, len(self.__plotable_items)): min((self.__current_selected_combo_box_index + 1) * self.__items_per_group, len(self.__plotable_items))]: plot_widget = None if first_iteration: first_iteration = False date_axis = DateAxis(orientation="bottom") first_view = pg.ViewBox() plot_widget = self.__graph_layout.addPlot(title=self.tr(key), axisItems={'bottom': date_axis}, viewBox=first_view) else: date_axis = DateAxis(orientation="bottom") view_box = pg.ViewBox() plot_widget = self.__graph_layout.addPlot(title=self.tr(key), viewBox=view_box, axisItems={'bottom': date_axis}) view_box.setXLink(first_view) #performance enhancements when only a short range of the plot is shown #plot_widget.setClipToView(clip=True) plot_widget.setYRange(-1, 1) self.__graph_dict[key] = plot_widget self.__graph_layout.nextRow() plot_widget = self.__graph_dict[key] plot_widget.showGrid(x=True, y=True) plot_widget.setMenuEnabled(enableMenu=True) plot_widget.enableAutoRange('xy', True) x = np.array([1]) y = np.array([int(str(Time.now()))/1000000000]) self.__plotted_curves[key] = plot_widget.plot(x=x, y=y, fillLevel=0, brush=(50, 50, 200, 100), pen=(255, 0, 0)) self.__expected_items_per_group += 1 self.__first_update_pending = True self.__update_graphs_lock.release()
def execute_action(self, action): """ Sends a signal to top or restart the node. :param action: action to be executed :type action: RemoteAction """ host_formatted = helper.underscore_ip(self.__parent.get_seuid()[2:]) service_name = "/execute_node_reaction/%s" % host_formatted try: execute = rospy.ServiceProxy( service_name, NodeReaction) resp = execute(self.seuid[2:], action, '') except ServiceException: self._logger.log("error", Time.now(), self.seuid, "could not stop node %s, service %s not found" % (self.seuid, service_name))
def decode(self, _, data): """ Generate a rospy.rostime.Time instance based on the given data of the form 'YYYY-MM-DDTHH:MM:SS.mmmmmm' (ISO 8601). """ if '+' in data: data = data[:data.index('+')] try: dt = datetime(year=int(data[0:4]), month=int(data[5:7]), day=int(data[8:10]), hour=int(data[11:13]), minute=int(data[14:16]), second=int(data[17:19]), microsecond=int(data[20:])) except ValueError: return Time() return Time.from_sec(time.mktime(dt.timetuple()))
def on_enter(self, userdata): self._error = False # activate controller actiavtion_request = SetOperationalGoal() actiavtion_request.operational = True actiavtion_request.resources = self._target_joint_state.name try: self._action_client.send_goal(self._controller, actiavtion_request) except Exception as e: Logger.logwarn( 'SetJointStateBase: Failed to send the SetOperational command:\n%s' % str(e)) self._error = True return # set start timestamp self._timestamp = Time.now()
def __init__(self, logger, seuid, first_message, parent=None): """Initializes the TopicItem. :param seuid: the seuid of the item :type seuid: str :param logger: a logger where to log when special events occur :type logger: ModelLogger :param parent: the parent-item :type parent: AbstractItem """ AbstractItem.__init__(self, logger, seuid, parent) self.__parent = parent self._type = "topic" self.add_keys=["dropped_msgs", "traffic", "bandwidth", "frequency"] self.avg_keys=["period_mean", "period_stddev", "stamp_age_mean", "stamp_age_stddev"] self.max_keys=["period_max", "stamp_age_max"] self._attributes = [] self._attributes.extend(["dropped_msgs", "traffic", "period_mean", "period_stddev", "period_max", "stamp_age_mean", "stamp_age_stddev", "stamp_age_max", "bandwidth", "frequency"]) for item in self._attributes: self._add_data_list(item) self.__calculated_data = {} for key in self._attributes: self.__calculated_data[key] = [] self.__calculated_data["window_stop"] = [] self.__calculated_data["window_start"] = [] for item in self._attributes: self._rated_attributes.append(item + ".actual_value") self._rated_attributes.append(item + ".expected_value") self._rated_attributes.append(item + ".state") for item in self._rated_attributes: self._add_rated_data_list(item) self._logger.log("info", Time.now(), seuid, "Created a new TopicItem") self.__timer = Timer(Duration(nsecs=TOPIC_AGGREGATION_FREQUENCY), self.__aggregate_topic_data) self.tree_items = [] self.__aggregation_window = rospy.get_param("~aggregation_window", 5)
def __get_history(self): """ For fetching the history from the monitoring_node. """ try: get_statistic_history = rospy.ServiceProxy('monitoring_node/get_statistic_history', StatisticHistory) response = get_statistic_history(rospy.Time(0)) rated_statistics_history = response.rated_topic_statistics + response.rated_node_statistics + \ response.rated_host_statistics + response.rated_node_statistics self.__rated_statistics_buffer = rated_statistics_history self.__topic_statistics_buffer = response.topic_statistics self.__host_statistics_buffer = response.host_statistics self.__node_statistics_buffer = response.node_statistics self.__update_model(None) except ServiceException as msg: self.__model.get_logger().log("info", Time.now(), "BufferThread", "get_statistic_history is not available, probably monitoring_node is not " "running. Will continue without the information about the past")
def publish_stop_message(self): header = Header( stamp=Time.now(), frame_id="base_link", ) drive = AckermannDrive( steering_angle=self.last_steering_angle, steering_angle_velocity=0, speed=0, # STOP! acceleration=0, jerk=0, ) msg = AckermannDriveStamped( header=header, drive=drive, ) rospy.logwarn("STOP: safety controller ordered a stop!") self.safety_pub.publish(msg)
def _update_current_state(self): """ This method updates the current state of the AbstractItem. :raises TypeError: at the initialization, it's possible that last_states["state"] has no entries and a TypeError occures """ if self.get_state(): if self.get_state() is not "error": last_states = self.get_rated_items_younger_than(Time.now() - ( Duration(secs=WARNING_TIMEOUT) if int(Duration(secs=5).to_sec()) <= int(Time.now().to_sec()) else Time(0)), "state") try: for i in range(0, len(last_states["state"])): if last_states["state"][i] is "error": self.set_state("warning") break except TypeError: return
def __init__(self, logger, seuid, first_message, parent=None): """ Initializes the ConnectionItem. :param seuid: the seuid of the item :type seuid: str :param logger: a logger where to log when special events occur :type logger: ModelLogger :param type: the type of the item :type type: str :param parent: the parent-item :type parent: AbstractItem """ AbstractItem.__init__(self, logger, seuid, parent) self.__parent = parent self._type = "connection" self.add_keys=["dropped_msgs", "traffic"] self.avg_keys=["period_mean", "period_stddev", "stamp_age_mean", "stamp_age_stddev", "bandwidth", "frequency"] self.max_keys=["period_max", "stamp_age_max"] self._attributes = [] self._attributes.extend(["dropped_msgs", "traffic", "period_mean", "period_stddev", "period_max", "stamp_age_mean", "stamp_age_stddev", "stamp_age_max", "bandwidth", "frequency"]) for item in self._attributes: self._add_data_list(item) for item in self._attributes: self._rated_attributes.append(item + ".actual_value") self._rated_attributes.append(item + ".expected_value") self._rated_attributes.append(item + ".state") for item in self._rated_attributes: self._add_rated_data_list(item) self._logger.log("info", Time.now(), seuid, "Created a new ConnectionItem") self.show_as_subscriber = False self.tree_item1 = None self.tree_item2 = None
def __init__(self, logger, seuid, parent=None): """ Initializes the NodeItem. :param seuid: the seuid of the item :type seuid: str :param logger: a logger where to log when special events occur :type logger: ModelLogger :param parent: the parent-item :type parent: AbstractItem """ AbstractItem.__init__(self, logger, seuid, parent) self._type = "node" self.__parent = parent self._type = "node" self._attributes = [] self._attributes.extend(["node_cpu_usage_mean", "node_cpu_usage_stddev", "node_cpu_usage_max", "node_cpu_usage_core_mean", "node_cpu_usage_core_stddev", "node_cpu_usage_core_max", "node_gpu_usage_mean", "node_gpu_usage_stddev", "node_gpu_usage_max", "node_ramusage_mean", "node_ramusage_stddev", "node_ramusage_max", "node_message_frequency_mean", "node_message_frequency_stddev", "node_message_frequency_max", "node_bandwidth_mean", "node_bandwidth_stddev", "node_bandwidth_max", "node_write_mean", "node_write_stddev", "node_write_max", "node_read_mean", "node_read_stddev", "node_read_max"]) for item in self._attributes: self._add_data_list(item) for item in self._attributes: self._rated_attributes.append(item + ".actual_value") self._rated_attributes.append(item + ".expected_value") self._rated_attributes.append(item + ".state") for item in self._rated_attributes: self._add_rated_data_list(item) self._logger.log("info", Time.now(), seuid, "Created a new NodeItem")
def __init__(self, logger, seuid, parent=None): """ Initializes the ConnectionItem. :param seuid: the seuid of the HostItem :type list: list :param logger: a logger where to log when special events occur :type logger: ModelLogger :param parent: the parent-item :type parent: AbstractItem """ AbstractItem.__init__(self, logger, seuid, parent) self.__parent = parent self._type = "host" self._attributes = [] self._attributes.extend([ "cpu_temp_mean", "cpu_temp_stddev", "cpu_temp_max", "cpu_usage_mean", "cpu_usage_stddev", "cpu_usage_max", "cpu_usage_core_mean", "cpu_usage_core_stddev", "cpu_usage_core_max", "cpu_temp_core_mean", "cpu_temp_core_stddev", "cpu_temp_core_max", "gpu_temp_mean", "gpu_temp_stddev", "gpu_temp_max", "gpu_usage_mean", "gpu_usage_stddev", "gpu_usage_max", "ram_usage_mean", "ram_usage_stddev", "ram_usage_max", "interface_name", "message_frequency_mean", "message_frequency_stddev", "message_frequency_max", "bandwidth_mean", "bandwidth_stddev", "bandwidth_max", "drive_name", "drive_free_space", "drive_read", "drive_write" ]) for item in self._attributes: self._add_data_list(item) for item in self._attributes: self._rated_attributes.append(item + ".actual_value") self._rated_attributes.append(item + ".expected_value") self._rated_attributes.append(item + ".state") for item in self._rated_attributes: self._add_rated_data_list(item) self._logger.log("info", Time.now(), seuid, "Created a new HostItem")
def _rosout(level, msg): global _in_rosout try: if _rosout_pub is not None: # protect against infinite recursion if not _in_rosout: try: _in_rosout = True msg = str(msg) topics = get_topic_manager().get_topics() l = Log(level=level, name=str(rospy.names.get_caller_id()), msg=str(msg), topics=topics) l.header.stamp = Time.now() _rosout_pub.publish(l) finally: _in_rosout = False except Exception as e: #traceback.print_exc() # don't use logerr in this case as that is recursive here logger = logging.getLogger("rospy.rosout") logger.error("Unable to report rosout: %s\n%s", e, traceback.format_exc()) return False
def update_graphs(self, event): """ Updates and redraws the graphs. """ self.__update_graphs_lock.acquire() if self.__draw_graphs or self.__first_update_pending: plotable_items = self.__plotable_items[min(self.__current_selected_combo_box_index * self.__items_per_group, len(self.__plotable_items)):min((self.__current_selected_combo_box_index + 1) * self.__items_per_group, len(self.__plotable_items))] plotable_data = self.__model.get_root_item().get_items_younger_than( Time.now() - (Duration(secs=self.__combo_box_index_to_seconds(self.__current_range_combo_box_index)) if int(Duration(secs=self.__combo_box_index_to_seconds(self.__current_range_combo_box_index)).to_sec()) <= int(Time.now().to_sec()) else Time(0) ), "window_stop", *plotable_items) temp_time = [] temp_content = [] if plotable_data["window_stop"]: modulo = (len(plotable_data["window_stop"]) / 200) + 1 length = len(plotable_data["window_stop"]) else: length = 0 modulo = 1 for i in range(0, length, modulo): # now having maximally 100 items to plot :) temp_time.append(int(str(plotable_data["window_stop"][i]))/1000000000) x = np.array(temp_time) for key in plotable_items: for i in range(0, length, modulo): temp_content.append(plotable_data[key][i]) y = np.array(temp_content) del temp_content[:] self.__plotted_curves[key].setData(x=x, y=y) self.__first_update_pending = False self.__update_graphs_lock.release()
def __init__(self, logger, seuid, parent=None): """ Initializes the ConnectionItem. :param seuid: the seuid of the HostItem :type list: list :param logger: a logger where to log when special events occur :type logger: ModelLogger :param parent: the parent-item :type parent: AbstractItem """ AbstractItem.__init__(self, logger, seuid, parent) self.__parent = parent self._type = "host" self._attributes = [] self._attributes.extend(["cpu_temp_mean", "cpu_temp_stddev", "cpu_temp_max", "cpu_usage_mean", "cpu_usage_stddev", "cpu_usage_max", "cpu_usage_core_mean", "cpu_usage_core_stddev", "cpu_usage_core_max", "cpu_temp_core_mean", "cpu_temp_core_stddev", "cpu_temp_core_max", "gpu_temp_mean", "gpu_temp_stddev", "gpu_temp_max", "gpu_usage_mean", "gpu_usage_stddev", "gpu_usage_max", "ram_usage_mean", "ram_usage_stddev", "ram_usage_max", "interface_name", "message_frequency_mean", "message_frequency_stddev", "message_frequency_max", "bandwidth_mean", "bandwidth_stddev", "bandwidth_max", "drive_name", "drive_free_space", "drive_read", "drive_write"]) for item in self._attributes: self._add_data_list(item) for item in self._attributes: self._rated_attributes.append(item + ".actual_value") self._rated_attributes.append(item + ".expected_value") self._rated_attributes.append(item + ".state") for item in self._rated_attributes: self._add_rated_data_list(item) self._logger.log("info", Time.now(), seuid, "Created a new HostItem")
def aggregate_data(self, period): """ :param period: The amount in seconds over which the data should be aggregated. :return: """ values = {} for key in self._attributes: values[key] = 0 entries = self.get_items_younger_than(Time.now() - (Duration(secs=period) if int(Duration(secs=period).to_sec()) <= int(Time.now().to_sec()) else Time(0) )) length = len(entries["window_stop"]) if entries["window_stop"] else 0 if length > 0: for key in self.add_keys: for i in range(0, length): values[key] += entries[key][i] for key in self.max_keys: if type(entries[key][-1]) == genpy.rostime.Time or type(entries[key][-1]) == genpy.rostime.Duration: for i in range(0, length): if entries[key][i].to_sec() > values[key]: values[key] = entries[key][i].to_sec() else: for i in range(0, length): if entries[key][i] > values[key]: values[key] = entries[key][i] for key in self.avg_keys: if type(entries[key][0]) is genpy.rostime.Time or type(entries[key][0]) is genpy.rostime.Duration: for i in range(0, length): values[key] += entries[key][i].to_sec() else: for i in range(0, length): values[key] += entries[key][i] values[key] = values[key] / length return values
def get_detailed_data(self): """ Returns the detailed data of the ConnectionItem. :returns: str """ data_dict = self.get_latest_data() if Time.now() - data_dict["window_stop"] > Duration(secs=5): return "No recent data" content = "<p class=\"detailed_data\">" content += self.get_erroneous_entries() if "frequency" in self._attributes: content += self.tr("frequency") + ": " + prepare_number_for_representation(data_dict["frequency"]) \ + " " + self.tr("frequency_unit") + " <br>" content += self.tr("dropped_msgs") + ": " + prepare_number_for_representation(data_dict["dropped_msgs"]) + " " \ + self.tr("dropped_msgs_unit") + " <br>" content += self.tr("bandwidth") + ": " + prepare_number_for_representation(data_dict["bandwidth"]) + " " \ + " " + self.tr("bandwidth_unit") + " <br>" content += self.tr("period_mean") + ": " + prepare_number_for_representation(data_dict["period_mean"]) \ + " " + self.tr("period_mean_unit") + " <br>" content += self.tr("period_stddev") + ": " + prepare_number_for_representation(data_dict["period_stddev"]) \ + " " + self.tr("period_stddev_unit") + " <br>" content += self.tr("period_max") + ": " + prepare_number_for_representation(data_dict["period_max"]) + " " \ + self.tr("period_max_unit") + " <br>" content += self.tr("stamp_age_mean") + ": " + prepare_number_for_representation(data_dict["stamp_age_mean"]) \ + " " + self.tr("stamp_age_mean_unit") + " <br>" content += self.tr("stamp_age_stddev") + ": " + prepare_number_for_representation(data_dict["stamp_age_stddev"]) \ + " " + self.tr("stamp_age_stddev_unit") + " <br>" content += self.tr("stamp_age_max") + ": " + prepare_number_for_representation(data_dict["stamp_age_max"]) \ + " " + self.tr("stamp_age_max_unit") + " <br>" content += "</p>" return content
def get_or_add_item_by_seuid(self, seuid, node1="", node2=""): """ Takes a seuid, checks if it already exists. If it does, the item is simply returned. If it does not a new item is generated and added to the tree. Does return the GUI items which is equal to the model items for host and node but different for topic and connections (2 gui items are created, whereas they access one model item) :param seuid: :return: """ if seuid is None: raise UserWarning("seuid was None!") if seuid not in self.__identifier_dict or seuid[0] is 't': parent = None item = None if seuid[0] == "h": item = HostItem(self.__logger, seuid, self.__root_item) parent = self.__root_item parent.append_child(item) elif seuid[0] == "n": # does host exist # call helper to get the host node = self.__seuid_helper.get_field("n", seuid) host = self.__find_host.get_host(node) if host is None: self.__logger.log("Warning", Time.now(), "RosModel", "The node " + node + " does probably no longer" " exist (Cannot find its host)." " Therefore it was not added to the GUI.") item = None else: host_seuid = self.__seuid_helper.from_string("h", host) parent = self.get_or_add_item_by_seuid(host_seuid) if parent is None: return None item = NodeItem(self.__logger, seuid, parent) parent.append_child(item) elif seuid[0] == "t": if node1 == "" or node2 == "": raise UserWarning("node was empty - topic does not know its parent!") else: # use node information - first add publisher node_seuid = self.__seuid_helper.from_string("n", node1) parent = self.get_or_add_item_by_seuid(node_seuid) if parent is None: return None if seuid not in self.__identifier_dict: item = TopicItem(self.__logger, seuid, None, parent) else: item = self.__identifier_dict[seuid] found = False for child in parent.get_childs(): # add it if child.seuid == seuid: found = True if not found: topic_item1 = TreeTopicItem(parent, item, False) parent.append_child(topic_item1) item.tree_items.append(topic_item1) node_seuid = self.__seuid_helper.from_string("n", node2) parent = self.get_or_add_item_by_seuid(node_seuid) if parent is None: return None found = False for child in parent.get_childs(): # add it if child.seuid == seuid: found = True if not found: topic_item2 = TreeTopicItem(parent, item, False) parent.append_child(topic_item2) item.tree_items.append(topic_item2) elif seuid[0] == "c": topic_seuid = self.__seuid_helper.from_string("t", self.__seuid_helper.get_field("t", seuid)) if self.__seuid_helper.publisher is None: raise UserWarning() # getting back the logical parent - a TopicItem pub = self.__seuid_helper.publisher sub = self.__seuid_helper.subscriber parent = self.get_or_add_item_by_seuid(topic_seuid, pub, sub) if parent is None: return None item = ConnectionItem(self.__logger, seuid, None, parent) parent.append_child(item) found = 0 for tree_item in parent.tree_items: # item is a TreeTopicItem if tree_item.parent().seuid == self.__seuid_helper.from_string("n", pub): found += 1 tree_item.tree_item1 = TreeConnectionItem(tree_item, item, False) tree_item.append_child(tree_item.tree_item1) if tree_item.parent().seuid == self.__seuid_helper.from_string("n", sub): found += 1 tree_item.tree_item2 = TreeConnectionItem(tree_item, item, True) tree_item.append_child(tree_item.tree_item2) if found != 2: raise UserWarning() if item is not None: self.__identifier_dict[seuid] = item return item else: return self.__identifier_dict[seuid]
def callback(msg, topic): # self.info('callback %s' % topic) what = (topic, msg, Time.now(), {}) self.queue.put(what)
def update_model(self): """ Updates the model by using the items of the list. The items will be of the message types. :param rated_statistics: the rated_statistics buffer :type rated_statistics: list :param topic_statistics: the topic_statistics buffer :type topic_statistics: list :param node_statistics: the node_statistics buffer :type node_statistics: list :param host_statistics: the host_statistics buffer :type host_statistics: list :param master_api_data: data from the master api :type master_api_data: MasterApi """ self.__model_lock.acquire() self.layoutAboutToBeChanged.emit() if self.__buffer_thread: rated_statistics, topic_statistics, host_statistics, node_statistics, master_api_data = self.__buffer_thread.get_state() amount_of_entries = 0 for item in self.__identifier_dict.values(): if item is not self.__root_item: amount_of_entries += item.get_amount_of_entries() # enables "intelligent" updates when there are only few elements in the model so that most of the history is kept # maybe use something loglike for the range for i in range(5, 0, -1): if amount_of_entries > MAXIMUM_AMOUNT_OF_ENTRIES: for item in self.__identifier_dict.values(): if item is not self.__root_item: item.delete_items_older_than(Time.now() - (Duration(secs=i * MINIMUM_RECORDING_TIME) if int( Duration(secs=i * MINIMUM_RECORDING_TIME).to_sec()) <= int(Time.now().to_sec()) else Time( 0))) if self.__root_item.get_amount_of_entries() > MAXIMUM_AMOUNT_OF_ENTRIES: self.__root_item.delete_items_older_than(Time.now() - ( Duration(secs=360) if int(Duration(secs=360).to_sec()) <= int(Time.now().to_sec()) else Time(0))) # in order of their appearance in the treeview for always having valid parents for item in host_statistics: self.__transform_host_statistics_item(item) for item in node_statistics: self.__transform_node_statistics_item(item) for item in topic_statistics: self.__transform_topic_statistics_item(item) if master_api_data is not None: self.__transform_master_api_data(master_api_data) # rating last because it needs the time of the items before for item in rated_statistics: self.__transform_rated_statistics_item(item) data_dict = { "state": "ok", "total_traffic": 0, "connected_hosts": 0, "connected_nodes": 0, "topic_counter": 0, "connection_counter": 0, "cpu_usage_max": 0, "cpu_temp_mean": 0, "ram_usage_mean": 0, "cpu_usage_mean": 0, "cpu_temp_max": 0, "ram_usage_max": 0, } connected_hosts = 0 connected_nodes = 0 topic_counter = 0 connection_counter = 0 state = "ok" # generate the general information for host_item in self.__root_item.get_childs(): # hostinfo connected_hosts += 1 if host_item.get_state() is "warning" and state is not "error": state = "warning" elif host_item.get_state() is "error": state = "error" last_entry = {} data = host_item.get_items_younger_than(Time.now() - ( Duration(secs=10) if int(Duration(secs=10).to_sec()) <= int(Time.now().to_sec()) else Time(0)), "bandwidth_mean", "cpu_usage_max", "cpu_temp_mean", "cpu_usage_mean", "cpu_temp_max", "ram_usage_max", "ram_usage_mean") if data["window_stop"]: for key in data: if key is not "window_stop": last_entry[key] = data[key][-1] else: data = host_item.get_latest_data("bandwidth_mean", "cpu_usage_max", "cpu_temp_mean", "cpu_usage_mean", "cpu_temp_max", "ram_usage_max", "ram_usage_mean") for key in data: last_entry[key] = data[key] for key in last_entry: if last_entry[key]: if key is "bandwidth_mean": for entry in last_entry[key]: if type(entry) is not unicode: if entry is not 0: data_dict["total_traffic"] += entry elif key is "cpu_temp_max" or key is "ram_usage_max": # very unprobably the temp might be 0 then the programm is not showing this value! if type(last_entry[key]) is not unicode: if last_entry[key] is not 0: if data_dict[key] < last_entry[key]: data_dict[key] = last_entry[key] else: if type(last_entry[key]) is not unicode: if last_entry[key] is not 0: data_dict[key] += last_entry[key] for node_item in host_item.get_childs(): # nodeinfo connected_nodes += 1 if node_item.get_state() is "warning" and state is not "error": state = "warning" elif node_item.get_state() is "error": state = "error" for topic_item in node_item.get_childs(): # topic info topic_counter += 1 if topic_item.get_state() is "warning" and state is not "error": state = "warning" elif topic_item.get_state() is "error": state = "error" for connection_item in topic_item.get_childs(): # connection info connection_counter += 1 if connection_item.get_state() is "warning" and state is not "error": state = "warning" elif connection_item.get_state() is "error": state = "error" for key in data_dict: if key != "state" and key != "cpu_temp_max" and key != "total_traffic" and key != "ram_usage_max" \ and self.__root_item.child_count(): data_dict[key] /= self.__root_item.child_count() data_dict["connected_hosts"] = connected_hosts data_dict["connected_nodes"] = connected_nodes data_dict["topic_counter"] = topic_counter data_dict["connection_counter"] = connection_counter data_dict["state"] = state data_dict["window_end"] = Time.now() # now give this information to the root :) self.__root_item.append_data_dict(data_dict) self.__model_lock.release() # self.__checkIfAlive() self.layoutChanged.emit()
def __on_recording_push_button_clicked(self): storage = [] if self.__recording_running: # stop now self.recording_push_button.setText("Start recording") print("Stopping the recording and saving the data") self.__recording_running = False abort = False for seuid, item in self.__marked_items_map.iteritems(): storage.append({}) storage[-1][seuid] = {} plotable_items = item.get_plotable_items() plotable_data = item.get_items_younger_than(self.start_time, "window_stop", *plotable_items) list_entries = item.get_list_items() time_entries = item.get_time_items() if plotable_data["window_stop"]: length = len(plotable_data["window_stop"]) for key in plotable_items: if key not in list_entries: min = sys.maxint max = 0 if key in list_entries: # todo: currently not possible to track these! pass else: if key in time_entries: for i in range(0, length): value = float(str(plotable_data[key][i])) / 1000000000.0 if value < min: min = value if value > max: max = value else: for i in range(0, length): value = plotable_data[key][i] if value < min: min = value if value > max: max = value # add new min/max pair to the storage storage[-1][seuid][key] = [min, max] filename = QFileDialog.getSaveFileName(self) else: abort = True QMessageBox.warning(self, "Warning", "Not enough data for elements provided. " "Please try recording for a longer period of time" " or start further components. ") if not abort and filename[0] is not u"": with open(filename[0], u"w") as outfile: outfile.write(yaml.dump(storage, default_flow_style=False)) else: # start now if len(self.__marked_items_map) == 0: QMessageBox.warning(self, "Warning", "You did not mark any items for recording. Please do so " "before pushing the button. Aborting the recording.") else: print("Started recording") self.recording_push_button.setText("Stop recording") self.start_time = Time.now() self.__recording_running = True