$search
00001 # -*- coding: utf-8 -*- 00002 # kate: replace-tabs off; indent-width 4; indent-mode normal 00003 # vim: ts=4:sw=4:noexpandtab 00004 00005 import sys 00006 import os 00007 core_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'core') 00008 sys.path.append(core_path) 00009 import teer as core 00010 import threading 00011 import rospy 00012 00013 # ------------------------------------------------------------ 00014 # === Scheduler working with ROS' time and threading === 00015 # ------------------------------------------------------------ 00016 class Scheduler(core.Scheduler): 00017 """ A scheduler supporting multi-threading access and ROS time """ 00018 def __init__(self): 00019 super(Scheduler, self).__init__() 00020 self.wake_cond = threading.Condition() 00021 self.running = True 00022 self.in_timer_count = 0 00023 def stop_run(): 00024 self.wake_cond.acquire() 00025 self.running = False 00026 self.wake_cond.notify() 00027 self.wake_cond.release() 00028 rospy.on_shutdown(stop_run) 00029 00030 # Public API, these functions are safe to be called from within a task or from outside 00031 00032 def current_time(self): 00033 return rospy.Time.now().to_sec() 00034 00035 # Public API, these funtions must be called outside a task 00036 00037 def run(self): 00038 self.wake_cond.acquire() 00039 self.step() 00040 while not rospy.is_shutdown() and self.running and ((self.in_timer_count != 0) or self.cond_waiting or self.ready): 00041 self.wake_cond.wait() 00042 self.step() 00043 00044 # Protected implementations, these functions can only be called by functions from this object 00045 00046 def _sleep(self, duration): 00047 rospy.sleep(duration) 00048 00049 def _set_timer_callback(self, t, f): 00050 def timer_callback(event): 00051 self.wake_cond.acquire() 00052 self.in_timer_count -= 1 00053 f() 00054 self.wake_cond.notify() 00055 self.wake_cond.release() 00056 self.in_timer_count += 1 00057 rospy.Timer(rospy.Duration(t - self.current_time()), timer_callback, True) 00058 00059 # ------------------------------------------------------------ 00060 # === Conditional Variables working with ROS' threading === 00061 # ------------------------------------------------------------ 00062 class ConditionVariable(core.ConditionVariable): 00063 """ A conditional variable working with ROS' Scheduler """ 00064 def __init__(self, initval=None): 00065 super(ConditionVariable, self).__init__(initval) 00066 def __get__(self, obj, objtype): 00067 return self.val 00068 def __set__(self, obj, val): 00069 obj.wake_cond.acquire() 00070 self.val = val 00071 self._set_name(type(obj)) 00072 obj._test_conditions(self.myname) 00073 obj.wake_cond.notify() 00074 obj.wake_cond.release() 00075 00076 # ------------------------------------------------------------ 00077 # === Alias for other objects === 00078 # ------------------------------------------------------------ 00079 00080 Task = core.Task 00081 Rate = core.Rate 00082 Pass = core.Pass 00083 GetScheduler = core.GetScheduler 00084 WaitTask = core.WaitTask 00085 WaitAllTasks = core.WaitAllTasks 00086 WaitAnyTasks = core.WaitAnyTasks 00087 WaitDuration = core.WaitDuration 00088 WaitCondition = core.WaitCondition 00089 Sleep = core.Sleep