def __init__(self, config, use_global_subscriber): """ Constructor to create a object of TimingTopicGroup that exists per topic-pair. The callback methods are defined depending on callerid filters. :param config: Configuration from yaml file """ # topics that should be subscribed self.topicA = Config.get_param(config, 'topicA') self.topicB = Config.get_param(config, 'topicB') self._callerA = Config.get_param(config, 'calleridA') self._callerB = Config.get_param(config, 'calleridB') self._base = TimingBase(config) # callbacks and subscriptions to given topics self.cb_a = self._cb_a_with_callerid if len( self._callerA) else self._cb_a_without_callerid self.cb_b = self._cb_b_with_callerid if len( self._callerB) else self._cb_b_without_callerid if not use_global_subscriber: self.sub_a = rospy.Subscriber(self.topicA, rospy.AnyMsg, self.cb_a, queue_size=1) self.sub_b = rospy.Subscriber(self.topicB, rospy.AnyMsg, self.cb_b, queue_size=1)
def initialize(self, config): """ Setup depending on the given config. For each topic a 'HzSubs'-object is created. In addition it start the main thread of this plugin. :param config: Configuration from yaml file """ self.rate = rospy.Rate(Config.get_param(config, 'main_loop_rate')) try: use_global_subscriber = Config.get_param(config, 'use_global_subscriber') except KeyError: use_global_subscriber = False for topic_config in Config.get_param(config, 'topics'): try: self.subs.append( TimingTopicGroup(topic_config, use_global_subscriber)) except (KeyError, StandardError) as e: rospy.logerr(e) sub_dict = dict() if use_global_subscriber: for sub in self.subs: # print sub sub_dict[sub.topicA] = sub.cb_a sub_dict[sub.topicB] = sub.cb_b self.start() return sub_dict
def instantiate_rule(config): is_single_shot = False if YamlHelper.has_param(config, 'single_shot'): is_single_shot = YamlHelper.get_param(config, 'single_shot') host = YamlHelper.get_param(config, 'host') port = YamlHelper.get_param(config, 'port') username = YamlHelper.get_param(config, 'username') password = YamlHelper.get_param(config, 'password') subject = YamlHelper.get_param(config, 'subject') to_address = YamlHelper.get_param(config, 'to_address') from_address = YamlHelper.get_param(config, 'from_address') content = YamlHelper.get_param(config, 'content') positive_observations = RuleFactory.pars_positive_observations(config) negative_observations = RuleFactory.pars_negative_observations(config) positive_possible_faulty_resources = RuleFactory.pars_positive_possible_faulty_resources( config) negative_possible_faulty_resources = RuleFactory.pars_negative_possible_faulty_resources( config) recall_duration = None if YamlHelper.has_param(config, 'recall_duration'): recall_duration = rospy.Duration( YamlHelper.get_param(config, 'recall_duration')) return EMailRule(positive_observations, negative_observations, positive_possible_faulty_resources, negative_possible_faulty_resources, recall_duration, is_single_shot, host, port, username, password, subject, to_address, from_address, content)
def __init__(self, config): """ Constructor for gaussian verification. Uses mean and standard deviation. :param config: Configuration from yaml file """ NominalValue.__init__(self) self._mean = Config.get_param(config, 'mean') self._std_deviation = Config.get_param(config, 'std_deviation')
def __init__(self, config): """ Constructor for k-mean filter object. Uses a ringbuffer of given size and take the mean of window. :param config: Configuration from yaml file """ from collections import deque ValueFilter.__init__(self) self.k_half = Config.get_param(config, 'k_size') / 2 self.window_size = Config.get_param(config, 'window_size') self._ring_buffer = deque(maxlen=self.window_size)
def __init__(self, config): """ Constructor of a new state. It reads the config used for this state and create a new hypothesis check instance. :param config: Configuration from yaml file """ self.name = Config.get_param(config, 'state') self.number = Config.get_param(config, 'number') delay = Config.get_param(config, 'delay') self.hypothesis_check = SingleValueHypothesisCheckFactory.create_single_value_hypothesis_check( delay)
def __init__(self, config): """ Constructor for not in between verification. :param config: Configuration from yaml file """ NominalValue.__init__(self) self._lower_bound = Config.get_param(config, 'lower_bound') self._upper_bound = Config.get_param(config, 'upper_bound') if self._lower_bound > self._lower_bound: rospy.logwarn( "lower bound is bigger than upper bound. 'NotInBetweenValue' will not work correctly!" )
def __init__(self, config): """ Constructor for a new hypothesis by using the student t test. It includes the value, the deviation and the number of samples. :param config: Configuration from yaml file """ self._true_mean = Config.get_param(config, 'true_mean') if Config.has_key(config, 'std_deviation'): self._std_deviation = Config.get_param(config, 'std_deviation') else: self._std_deviation = None self._significance_level = Config.get_param(config, 'significance_level')
def pars_diag(resources): result = set() for res in resources: the_res = DiagnosisContainer() the_res.resource = YamlHelper.get_param(res, 'resource') if YamlHelper.has_param(res, 'occurrences'): the_res.occurrences = YamlHelper.get_param(res, 'occurrences') else: the_res.occurrences = None if YamlHelper.has_param(res, 'window_size'): the_res.window_size = YamlHelper.get_param(res, 'window_size') else: the_res.window_size = None result.add(the_res) return result
def create_nominal_value(config): """ Decode verification type and return new corresponding object. :param config: Configuration from yaml file :return: New instance of a corresponding verification object """ type = Config.get_param(config, 'type') if type == "gauss": return GaussNominalValue(config) elif type == "exact": return ExactValue(config) elif type == "not": return NotValue(config) elif type == "greather_than": return GreaterThanValue(config) elif type == "less_than": return LessThanValue(config) elif type == "in_between": return InBetweenValue(config) elif type == "not_in_between": return NotInBetweenValue(config) else: rospy.logwarn("nominal value type '" + str(type) + "' not found") # return None return NominalValue()
def add_callerid(self, callerid): """ Add a new object for a new callerid and add it to list :param callerid: name of the callerid :return: the new object created for the given callerid """ print 'new callerid should be added' best_config = self._config_for_unknown new_base = None for callerid_config in self._callerids_config: try: if callerid in Config.get_param(callerid_config, 'callerid'): best_config = callerid_config break except KeyError as e: rospy.logerr(e) # print best_config if best_config: new_base = TimestampBase(self.topic, callerid, best_config) self._bases[callerid] = new_base return new_base
def __init__(self, config): """ Constructor for less than verification. :param config: Configuration from yaml file """ NominalValue.__init__(self) self._less_than = Config.get_param(config, 'less_than')
def __init__(self, config): """ Constructor for exact verification. :param config: Configuration from yaml file """ NominalValue.__init__(self) self._exact = Config.get_param(config, 'exact')
def instantiate_rule(config): is_single_shot = False if YamlHelper.has_param(config, 'single_shot'): is_single_shot = YamlHelper.get_param(config, 'single_shot') process = YamlHelper.get_param(config, 'process') positive_observations = RuleFactory.pars_positive_observations(config) negative_observations = RuleFactory.pars_negative_observations(config) positive_possible_faulty_resources = RuleFactory.pars_positive_possible_faulty_resources( config) negative_possible_faulty_resources = RuleFactory.pars_negative_possible_faulty_resources( config) recall_duration = None if YamlHelper.has_param(config, 'recall_duration'): recall_duration = rospy.Duration( YamlHelper.get_param(config, 'recall_duration')) return ProcessRule(positive_observations, negative_observations, positive_possible_faulty_resources, negative_possible_faulty_resources, recall_duration, is_single_shot, process)
def __init__(self, config): """ Constructor for exponentially weighted moving average (EWMA) filter object. Applies new values weighted to history. :param config: Configuration from yaml file """ ValueFilter.__init__(self) self._decay_rate = Config.get_param(config, 'decay_rate') if Config.has_key(config, 'window_size'): from collections import deque self.window_size = Config.get_param(config, 'window_size') self._ring_buffer = deque(maxlen=self.window_size) self.update = self.update_buffered self.get_value = self.get_value_buffered self.reset = self.reset_buffered else: self._current_value = None self.update = self.update_unbuffered self.get_value = self.get_value_unbuffered self.reset = self.reset_unbuffered
def instantiate_rule(config): is_single_shot = False if YamlHelper.has_param(config, 'single_shot'): is_single_shot = YamlHelper.get_param(config, 'single_shot') log_file = YamlHelper.get_param(config, 'log_file') log_entry = YamlHelper.get_param(config, 'log_entry') positive_observations = RuleFactory.pars_positive_observations(config) negative_observations = RuleFactory.pars_negative_observations(config) positive_possible_faulty_resources = RuleFactory.pars_positive_possible_faulty_resources( config) negative_possible_faulty_resources = RuleFactory.pars_negative_possible_faulty_resources( config) recall_duration = None if YamlHelper.has_param(config, 'recall_duration'): recall_duration = rospy.Duration( YamlHelper.get_param(config, 'recall_duration')) return LogFileRule(positive_observations, negative_observations, positive_possible_faulty_resources, negative_possible_faulty_resources, recall_duration, is_single_shot, log_file, log_entry)
def __init__(self, config, use_global_subscriber): """ Constructor to create a object of TimeoutSubs that exists per topic. The last callerid-config that defines no callerid exactly is used as default config for new callerids that are not explicitly named in the config. If there is no callerid-config that can be used as default config, unknown callerids are ignored. :param config: Configuration from yaml file """ # topic that should be subscribed self.topic = Config.get_param(config, 'name') # store all callerids of this topic separately self._bases = dict() self._bases_lock = Lock() # define necessary stuff to handle combinations of callerid self._callerids_config = Config.get_param(config, 'callerids') self._merged_bases = [] self._config_for_unknown = None # init all states per callerid-combination and detect a possible # config that can be used as default config. for callerid_config in self._callerids_config: try: callerid_list = Config.get_param(callerid_config, 'callerid') self._merged_bases.append( TimestampMergedBase(self.topic, callerid_config)) if not len(callerid_list): self._config_for_unknown = callerid_config except KeyError as e: rospy.logerr(e) # get topic class and subscribe if not use_global_subscriber: msg_class, real_topic, msg_eval = rostopic.get_topic_class( self.topic) self.sub = rospy.Subscriber(self.topic, msg_class, self.cb, queue_size=1)
def __init__(self, topic, config): """ Constructor that defines which callerids should be merged. Also all states for this combination of callerids are defined depending on the config. :param topic: name of topic that is subscribed :param config: Configuration from yaml file """ # public variables self.callerids = Config.get_param(config, 'callerid') self.use_all_bases = True if not len(self.callerids) else False # Try to load and setup all states as defined in the yaml-file self._states = [] for state_config in Config.get_param(config, 'states'): try: self._states.append(TimestampState(state_config)) except KeyError as e: rospy.logerr(e) # create a predefined msgs for info and error self._observation_info = observation_info( type='timestamp', resource=str(topic + ' ' + str(self.callerids)))
def __init__(self, topic, callerid, config): """ Constructor of the TimeoutBase class. :param topic: name of topic that is subscribed :param callerid: name of the node that publish on the topic :param config: Configuration from yaml file """ # create a filter and lock self._filter_lock = Lock() self._filter = Filter(Config.get_param(config, 'filter')) # create a predefined error msg # self._observation_info = observation_info(type='timestemp', resource=str(topic + '[' + str(callerid)) + ']') self._topic = topic
def instantiate_rule(config): is_single_shot = False if YamlHelper.has_param(config, 'single_shot'): is_single_shot = YamlHelper.get_param(config, 'single_shot') service_name = YamlHelper.get_param(config, 'service_name') service_type = YamlHelper.get_param(config, 'service_type') call_msg = YamlHelper.get_param(config, 'call_msg') positive_observations = RuleFactory.pars_positive_observations(config) negative_observations = RuleFactory.pars_negative_observations(config) positive_possible_faulty_resources = RuleFactory.pars_positive_possible_faulty_resources( config) negative_possible_faulty_resources = RuleFactory.pars_negative_possible_faulty_resources( config) recall_duration = None if YamlHelper.has_param(config, 'recall_duration'): recall_duration = rospy.Duration( YamlHelper.get_param(config, 'recall_duration')) return ServiceRule(positive_observations, negative_observations, positive_possible_faulty_resources, negative_possible_faulty_resources, recall_duration, is_single_shot, service_name, service_type, call_msg)
def __init__(self, config): """ Constructor for a new nominal value hypothesis. It includes the value and the deviation(s) :param config: Configuration from yaml file """ SingleValueHypothesisCheck.__init__(self) self._value_check = NominalValueFactory.create_nominal_value(config) self._deviation_checks = [] if not Config.has_key(config, 'deviation'): return for deviation_config in Config.get_param(config, 'deviation'): self._deviation_checks.append( NominalValueFactory.create_nominal_value(deviation_config))
def instantiate_rule(config): is_single_shot = False if YamlHelper.has_param(config, 'single_shot'): is_single_shot = YamlHelper.get_param(config, 'single_shot') node_name = YamlHelper.get_param(config, 'node_name') paramter_name = YamlHelper.get_param(config, 'paramter_name') paramter_value = YamlHelper.get_param(config, 'paramter_value') positive_observations = RuleFactory.pars_positive_observations(config) negative_observations = RuleFactory.pars_negative_observations(config) positive_possible_faulty_resources = RuleFactory.pars_positive_possible_faulty_resources( config) negative_possible_faulty_resources = RuleFactory.pars_negative_possible_faulty_resources( config) recall_duration = None if YamlHelper.has_param(config, 'recall_duration'): recall_duration = rospy.Duration( YamlHelper.get_param(config, 'recall_duration')) return DynamicParameterRule(positive_observations, negative_observations, positive_possible_faulty_resources, negative_possible_faulty_resources, recall_duration, is_single_shot, node_name, paramter_name, paramter_value)
def __init__(self): self._observer_sub = rospy.Subscriber("/observer/info", observer_info, self.observer_callback) self._diagnosis_sub = rospy.Subscriber("/diagnosis", diagnosis_set, self.diagnosis_callback) self._observation_store = ObservationStore() self._diagnosis_store = DiagnosisStore() self._trigger_condition = threading.Condition() self._rules = [] rule_configs = rospy.get_param(rospy.get_name() + "/rules") for rule_config in rule_configs: rule_type = YamlHelper.get_param(rule_config, "type") self._rules.append(RuleFactory.create_rule(rule_type, rule_config)) for rule in self._rules: self._observation_store.observations_used(rule.observations_to_use()) self._diagnosis_store.resources_used(rule.resources_to_use()) self._background_thread = thread.start_new_thread(self.run, tuple())
def __init__(self, config): """ Constructor to create StdDeviationFilter object. It reads and setup the buffer (defined or not defined buffer size) :param config: Configuration from yaml file """ DeviationFilter.__init__(self) from math import sqrt self.sqrt = sqrt if Config.has_key(config, 'window_size'): from collections import deque self.window_size = Config.get_param(config, 'window_size') self._buffer = deque(maxlen=self.window_size) self.reset = self.reset_buffered else: self._buffer = [] self.reset = self.reset_unbuffered
def create_value_filter(config): """ Decode filter type from config and return new instance of corresponding filter. :param config: Configuration from yaml file :return: New instance of a corresponding filter """ value_filter_type = Config.get_param(config, 'type') if value_filter_type == "mean": return MeanValueFilter(config) elif value_filter_type == "median": return MedianValueFilter(config) elif value_filter_type == "kmeans": return KMeansValueFilter(config) elif value_filter_type == "ewma": return ExponentiallyWeightedMovingAverageValueFilter(config) elif value_filter_type == "nofilter": return NoValueFilter(config) else: return ValueFilter()
def create_single_value_hypothesis_check(config): """ Decode single value hypothesis type from config and return new instance of corresponding hypothesis check. :param config: Configuration from yaml file :return: New instance of a corresponding hypothesis check """ hypothesis_type = Config.get_param(config, 'type') if hypothesis_type in [ 'gauss', 'exact', 'not', 'greather_than', 'less_than', 'in_between', 'not_in_between' ]: return NominalValueHypothesis(config) elif hypothesis_type == 'student_t': return StudentTTest(config) else: rospy.logwarn("single value hypothesis check type '" + str(hypothesis_type) + "' not found") return SingleValueHypothesisCheck()
def __init__(self, config): """ Constructor to create min-max deviation object. It reads and setup the buffer (defined or not defined buffer size) :param config: Configuration from yaml file """ DeviationFilter.__init__(self) if Config.has_key(config, 'window_size'): from collections import deque self.window_size = Config.get_param(config, 'window_size') self._ring_buffer = deque(maxlen=self.window_size) self.update = self.update_buffered self.get_deviation = self.get_deviation_buffered self.reset = self.reset_buffered else: self._min = float("nan") self._max = float("nan") self.update = self.update_unbuffered self.get_deviation = self.get_deviation_unbuffered self.reset = self.reset_unbuffered
def __init__(self, config): """ Constructor of the TimingBase class. It manages the filter, creates and setups the states and initialize stuff for the delay calculation. :param config: Configuration from yaml file """ # topics and callerids topicA = Config.get_param(config, 'topicA') topicB = Config.get_param(config, 'topicB') calleridA = Config.get_param(config, 'calleridA') calleridB = Config.get_param(config, 'calleridB') try: self._single_shot_mode = Config.get_param(config, 'single_shot_mode') except KeyError: self._single_shot_mode = False # necessary stuff to calculate time between topics self._first_topic_time_a = None if not self._single_shot_mode else 0 self._first_topic_time_a_lock = Lock() # Try to load and setup all states as defined in the yaml-file self._states = [] for state_config in Config.get_param(config, 'states'): try: self._states.append(TimingState(state_config)) except KeyError as e: rospy.logerr(e) # create a predefined msgs for info and error self._observation_info = observation_info( type='timing', resource=str(topicA + ' ' + str(calleridA) + ' ' + topicB + ' ' + str(calleridB))) # create a filter self._filter = Filter(Config.get_param(config, 'filter'))
def pars_observation(observations): result = set() for obs in observations: the_obs = ObservationContainer() the_obs.type = YamlHelper.get_param(obs, 'type') the_obs.resource = YamlHelper.get_param(obs, 'resource') if YamlHelper.has_param(obs, 'observation'): the_obs.observation = ObservationWithNumber( YamlHelper.get_param(obs, 'observation')) else: the_obs.observation = ObservationWithString( YamlHelper.get_param(obs, 'observation_msg')) if YamlHelper.has_param(obs, 'occurrences'): the_obs.occurrences = YamlHelper.get_param(obs, 'occurrences') else: the_obs.occurrences = None if YamlHelper.has_param(obs, 'window_size'): the_obs.window_size = YamlHelper.get_param(obs, 'window_size') else: the_obs.window_size = None result.add(the_obs) return result
from tug_python_utils import YamlHelper from tug_diagnosis_msgs.msg import configuration, node_configuration, observer_configuration from tug_diagnosis_msgs.srv import * if __name__ == "__main__": rospy.init_node('tug_diagnosis_initialization', anonymous=False) rospy.loginfo("tug_diagnosis_initialization: starting") rospy.loginfo("tug_diagnosis_initialization: load config") configs = rospy.get_param('/tug_diagnosis_initialization_node') model_configuration = configuration() rospy.loginfo("tug_diagnosis_initialization: load nodes") for node in YamlHelper.get_param(configs, 'nodes'): name = YamlHelper.get_param(node, 'name') sub_topic = YamlHelper.get_param(node, 'sub_topic', []) pub_topic = YamlHelper.get_param(node, 'pub_topic', []) model_configuration.nodes.append( node_configuration(name=str(name), pub_topic=list(pub_topic), sub_topic=list(sub_topic))) rospy.loginfo("tug_diagnosis_initialization: load observers") for observation in YamlHelper.get_param(configs, 'observations'): type = YamlHelper.get_param(observation, 'type') resource = [] if YamlHelper.has_key(observation, 'nodes'):