def make_async_controller(base): """ allows to instantiate the motor controller as thread or as process :param base: options are Thread|Process :return: """ class AsyncController(base): def __init__(self, queue): super(AsyncController, self).__init__() self.queue = queue self.robot = Controller() self.last_action_time = time.time() self.last_action = [] def run(self): keep_running = True while keep_running: if not self.queue.empty(): action = self.queue.get() if action == "quit": keep_running = False self.robot.list_action([0, 0]) self.robot.rgb_off() else: ik = self.robot.ik_action(v=action[0], omega=action[1]) if len(action) == 5: self.robot.rgb_action(action[2:]) self.last_action_time = time.time() self.last_action = ik else: # check if it's time to break delta = time.time( ) - self.last_action_time - DECELERATION_TIMEOUT if 0 <= delta < DECELERATION_BREAK_TIME: # decelerate if len(self.last_action) == 2: new_action = ease_out_action( self.last_action, delta) self.robot.list_action(new_action) time.sleep(1 / DECELERATION_STEPS) elif delta >= DECELERATION_BREAK_TIME and len( self.last_action) == 2: # this is run only once after decel to # make sure the robot comes to a full stop # and doesn't continue to move at 0.00001 speed self.last_action = [] self.robot.stop() queue = get_right_queue(base) return AsyncController, queue
def make_async_camera(base): """ allows to instantiate the camera as thread or as process :param base: options are Thread|Process :return: """ class AsyncPubCamera(base): def __init__(self, queue): super(AsyncPubCamera, self).__init__() # Thread.__init__(self) self.queue = queue self.publisher_socket = None self.cam = Camera(res=(160, 120)) self.context = zmq.Context() def run(self): # wait for first subscriber # then create socket # get camera image # broadcast image keep_running = True while keep_running: if not self.queue.empty(): cmd = self.queue.get() if cmd == "kill": keep_running = False break # redundant I guess else: if self.publisher_socket is None: self.publisher_socket = make_pub_socket( for_images=True, context_=self.context ) # the pub / send_array method only works once the first subscriber is connected if self.publisher_socket is not None: img = self.cam.observe() # on the real robot we are sending 0 reward, in simulation the reward is a float # we also send done=False because the real robot doesn't know when to stop ^^ send_gym(self.publisher_socket, img, 0, False) queue = get_right_queue(base) return AsyncPubCamera, queue