async def _handle_audio_complete(self, name): """subscribe and wait for an audio complete event""" async def _wait_one(sp: SubPayload): return sp.data.message.metaData.name == name event = EventCallback(_wait_one) try: async with self.api.ws.sub_unsub(SubType.audio_play_complete, event): await event except asyncio.CancelledError: event.set() raise
async def wave2(l_or_r: str = 'l', position=120, velocity=60, n_times=8): positions = position, 0 uv = UnchangedValue(5, debug=True) ecb = EventCallback(uv) async with api.ws.sub_unsub(Actuator.left_arm, ecb, 10): for i in range(n_times): position = positions[i & 1] kwargs = {f'{l_or_r}_position': position, f'{l_or_r}_velocity': velocity} await api.movement.move_arms(**kwargs) ecb.clear() uv.clear() await ecb print(position) await api.movement.move_arms(l_position=0, r_position=0, l_velocity=velocity, r_velocity=velocity)
async def wait_for_key_phrase(self): async def _wait_one(_: SubPayload): return True ecb = EventCallback(_wait_one) await self.start_key_phrase_recognition(ecb) await ecb
async def wait_for_training(self, face_id: str): """blocking call to wait for face training""" async def _wait(sp: SubPayload): m = sp.data.message.message log.info(m) return m == FTMsgs.complete.value ecb = EventCallback(_wait) async with self.api.ws.sub_unsub(SubType.face_training, ecb): await asyncio.gather(self.start_training(face_id), ecb)
class _SlamHelper(PartialAPI, ABC): """ context manager to handle initializing and stopping slam functionality used by the NavigationAPI """ def __init__(self, api, endpoint: str, timeout_secs=15.0): super().__init__(api) self._endpoint = endpoint self._num_current_slam_streams = 0 self._ready_cb = EventCallback(self._sensor_ready, timeout_secs) @abstractmethod async def _sensor_ready(self, sp: SubPayload): """handler func that indicates when the sensor is ready""" async def start(self): self._ready_cb.clear() await self._post(f'slam/{self._endpoint}/start') async def stop(self): return await self._post(f'slam/{self._endpoint}/stop') async def reset(self): return await self._post('slam/reset') async def __aenter__(self): self._num_current_slam_streams += 1 if self._num_current_slam_streams == 1: await self.start() async with self.api.ws.sub_unsub(SubType.self_state, self._ready_cb): await self._ready_cb async def __aexit__(self, exc_type, exc_val, exc_tb): self._num_current_slam_streams -= 1 if self._num_current_slam_streams == 0: await self.stop()
async def run(): print('started') await asyncio.sleep(1) print('starting face recognition') await api.faces.start_recognition() t = asyncio.create_task(search(do_reset=False)) try: ec = EventCallback(HandleFaceRecognition(t)) await api.ws.subscribe(SubType.face_recognition, ec) await ec await api.faces.stop_recognition() except asyncio.CancelledError: t.cancel() print('done')
async def get_actuator_values(self, *actuators: Actuator, normalize=True, force=False) -> ActuatorVals: """ get actuator values from misty and, if set, normalize to values between -100 and 100 based on calibrations `force` will make sure we go to misty to get the values """ orig_actuators = actuators or tuple(Actuator) actuators = tuple(Actuator) if not force and not _actuator_cache.update_needed: return _actuator_cache.by_actuators(*orig_actuators) async def _wait_one(sp: SubPayload): await submitted.wait() with suppress(Exception): res[sp.sub_id.sub] = sp.data.message.value with suppress(KeyError): expected_sub_ids.remove(sp.sub_id) asyncio.create_task(sp.sub_id.unsubscribe()) return not expected_sub_ids res: ActuatorVals = {} submitted = asyncio.Event() ecb = EventCallback(_wait_one) subscriptions = (self.api.ws.subscribe(a, ecb, 100) for a in (actuators if normalize else orig_actuators)) expected_sub_ids = set(await asyncio.gather(*subscriptions)) submitted.set() await ecb res = {Actuator(first(sub.ec).value): v for sub, v in res.items()} if not normalize: return res calibrations = _get_calibrated_actuator_positions() res = {k: calibrations[k].normalize(v) for k, v in res.items()} _actuator_cache.set(res) return {k: res[k] for k in orig_actuators}
def __init__(self, api, endpoint: str, timeout_secs=15.0): super().__init__(api) self._endpoint = endpoint self._num_current_slam_streams = 0 self._ready_cb = EventCallback(self._sensor_ready, timeout_secs)
async def _init_face_recognition() -> EventCallback: print('starting face recognition') await api.faces.start_recognition() eh = EventCallback(_handle_face_recognition) await api.ws.subscribe(SubType.face_recognition, eh) return eh
async def _handle_head_movement(yaw): ecb = EventCallback(UnchangedValue()) await api.movement.move_head(yaw=yaw) async with api.ws.sub_unsub(Actuator.yaw.sub, ecb, 400): await ecb