Go to the documentation of this file.00001
00002
00003
00004 class PeriodicLogger():
00005
00006
00007
00008
00009
00010
00011 def __init__(self, callback, rate=0.01, args=None):
00012 self.ret = []
00013 self.cb = callback
00014 self.rate = rate
00015 self.args = args
00016 self.is_running = False
00017 self.max_calls = None
00018 self.num_calls = 0
00019 self.beg_time = 0.
00020 self.thread = None
00021
00022
00023
00024
00025 def start(self, max_calls=None):
00026 if self.is_running:
00027 return
00028 self.max_calls = max_calls
00029 self.is_running = True
00030 self.num_calls = 0
00031 self.beg_time = rospy.Time.now().to_sec()
00032 self.thread = threading.Timer(self.rate, self._run)
00033 self.thread.start()
00034
00035 def _run(self):
00036 if not self.is_running:
00037 return
00038
00039 act_time = self.beg_time + self.rate * (self.num_calls + 2)
00040 interval = act_time - rospy.Time.now().to_sec()
00041 self.thread = threading.Timer(interval, self._run)
00042 self.thread.start()
00043
00044 if self.args is None:
00045 retval = self.cb()
00046 else:
00047 retval = self.cb(*self.args)
00048 self.ret += [retval]
00049
00050 self.num_calls += 1
00051
00052 if self.max_calls is not None:
00053 if self.num_calls == self.max_calls:
00054 self.is_running = False
00055 return
00056
00057
00058
00059
00060 def stop(self):
00061 self.thread.cancel()
00062 if not self.is_running:
00063 return None
00064 self.is_running = False
00065 return self.ret
00066
00067
00068
00069 def get_ret_vals(self):
00070 if self.is_running:
00071 return None
00072 return self.ret
00073
00074
00075
00076
00077
00078 class PeriodicMonitor():
00079
00080
00081
00082
00083
00084
00085 def __init__(self, callback, rate=0.01, args=None):
00086 self.ret = []
00087 self.cb = callback
00088 self.rate = rate
00089 self.args = args
00090 self.is_running = False
00091 self.num_calls = 0
00092 self.beg_time = 0.
00093 self.thread = None
00094 self.mean_model = None
00095 self.variance_model = None
00096 self.std_devs = 0.
00097 self.failure = False
00098
00099
00100
00101
00102
00103 def start(self, mean_model, variance_model, std_devs=2.5, max_calls=None,
00104 contingency=None, contingency_args=None):
00105 if len(mean_model) != len(variance_model):
00106 log("Models must be of same length")
00107 return
00108 if self.is_running:
00109 return
00110 self.is_running = True
00111 self.mean_model = mean_model
00112 self.variance_model = variance_model
00113 self.std_devs = std_devs
00114 self.max_calls = max_calls
00115 self.contingency = contingency
00116 self.contincency_args = contingency_args
00117 self.model_index = 0
00118 self.failure = False
00119
00120 self.num_calls = 0
00121 self.beg_time = rospy.Time.now().to_sec()
00122 self.thread = threading.Timer(self.rate, self._run)
00123 self.thread.start()
00124
00125 def _run(self):
00126 if not self.is_running:
00127 return
00128
00129 act_time = self.beg_time + self.rate * (self.num_calls + 2)
00130 interval = act_time - rospy.Time.now().to_sec()
00131 self.thread = threading.Timer(interval, self._run)
00132 self.thread.start()
00133
00134 if self.args is None:
00135 retval = self.cb()
00136 else:
00137 retval = self.cb(*self.args)
00138
00139
00140 for coord_i in len(retval[1]):
00141 diff = abs(retval[1][coord_i] - self.mean_model[self.model_index][coord_i])
00142 deviation = np.sqrt(self.variance_model[self.model_index][coord_i])
00143 if diff > self.std_devs * deviation:
00144
00145 self.failure = True
00146 self.is_running = False
00147
00148 if contingency_args is None:
00149 self.contingency()
00150 else:
00151 self.contingency(*contingency_args)
00152 return
00153 self.ret += [retval]
00154 self.model_index += 1
00155 if self.model_index == len(self.mean_model):
00156 self.is_running = False
00157 return
00158
00159
00160 if not self.max_calls is None:
00161 self.max_calls -= 1
00162 if self.max_calls == 0:
00163 self.is_running = False
00164 return
00165
00166
00167
00168
00169 def stop(self):
00170 self.thread.cancel()
00171 if not self.is_running:
00172 return None
00173 self.is_running = False
00174 return self.ret
00175
00176
00177
00178 def get_ret_vals(self):
00179 if self.is_running:
00180 return None
00181 return self.ret
00182
00183
00184 def has_failed():
00185 return self.failure
00186
00187
00188 def wait_for_completion(rate=0.01):
00189 while self.is_running and not rospy.is_shutdown():
00190 rospy.sleep(rate)
00191 return not self.failure