5252
5353class CONTROL_PRIORITY_LEVEL (Enum ):
5454 """Enum used to specify the priority level for the program."""
55-
55+ #: Runs above mandatory physical reactions, will drive off table, perform while on a slope,
56+ #: in the dark, etc.
57+ OVERRIDE_BEHAVIORS_PRIORITY = protocol .ControlRequest .OVERRIDE_BEHAVIORS # pylint: disable=no-member
5658 #: Runs below Mandatory Physical Reactions such as tucking Vector's head and arms during a fall,
57- #: yet above Trigger-Word Detection.
58- TOP_PRIORITY_AI = protocol .ControlRequest .TOP_PRIORITY_AI # pylint: disable=no-member
59+ #: yet above Trigger-Word Detection. Default for normal operation.
60+ DEFAULT_PRIORITY = protocol .ControlRequest .DEFAULT # pylint: disable=no-member
5961
6062
6163class _ControlEventManager :
@@ -109,7 +111,7 @@ def is_shutdown(self) -> bool:
109111 """Detect if the behavior control stream is supposed to shut down."""
110112 return self ._is_shutdown
111113
112- def request (self , priority : CONTROL_PRIORITY_LEVEL = CONTROL_PRIORITY_LEVEL .TOP_PRIORITY_AI ) -> None :
114+ def request (self , priority : CONTROL_PRIORITY_LEVEL = CONTROL_PRIORITY_LEVEL .DEFAULT_PRIORITY ) -> None :
113115 """Tell the behavior stream to request control via setting the :class:`request_event`.
114116
115117 This will signal Connection's :func:`_request_handler` generator to send a request control message on the BehaviorControl stream.
@@ -192,10 +194,11 @@ async def play_animation():
192194 :param host: The IP address and port of Vector in the format "XX.XX.XX.XX:443".
193195 :param cert_file: The location of the certificate file on disk.
194196 :param guid: Your robot's unique secret key.
195- :param requires_behavior_control: True if the connection requires behavior control.
197+ :param behavior_control_level: pass one of :class:`CONTROL_PRIORITY_LEVEL` priority levels if the connection
198+ requires behavior control, or None to decline control.
196199 """
197200
198- def __init__ (self , name : str , host : str , cert_file : str , guid : str , requires_behavior_control : bool = True ):
201+ def __init__ (self , name : str , host : str , cert_file : str , guid : str , behavior_control_level : CONTROL_PRIORITY_LEVEL = CONTROL_PRIORITY_LEVEL . DEFAULT_PRIORITY ):
199202 if cert_file is None :
200203 raise VectorConfigurationException ("Must provide a cert file to authenticate to Vector." )
201204 self ._loop : asyncio .BaseEventLoop = None
@@ -213,7 +216,7 @@ def __init__(self, name: str, host: str, cert_file: str, guid: str, requires_beh
213216 self ._ready_signal : threading .Event = threading .Event ()
214217 self ._done_signal : asyncio .Event = None
215218 self ._conn_exception = False
216- self ._requires_behavior_control = requires_behavior_control
219+ self ._behavior_control_level = behavior_control_level
217220 self .active_commands = []
218221
219222 @property
@@ -285,6 +288,27 @@ async def play_animation():
285288 """
286289 return self ._interface
287290
291+ @property
292+ def behavior_control_level (self ) -> CONTROL_PRIORITY_LEVEL :
293+ """Returns the specific :class:`CONTROL_PRIORITY_LEVEL` requested for behavior control.
294+
295+ To be able to directly control Vector's motors, override his screen, play an animation, etc.,
296+ the :class:`Connection` will need behavior control. This property identifies the enumerated
297+ level of behavior control that the SDK will maintain over the robot.
298+
299+ For more information about behavior control, see :ref:`behavior <behavior>`.
300+
301+ .. code-block:: python
302+
303+ import anki_vector
304+
305+ with anki_vector.Robot() as robot:
306+ print(robot.conn.behavior_control_level) # Will print CONTROL_PRIORITY_LEVEL.DEFAULT_PRIORITY
307+ robot.conn.release_control()
308+ print(robot.conn.behavior_control_level) # Will print None
309+ """
310+ return self ._behavior_control_level
311+
288312 @property
289313 def requires_behavior_control (self ) -> bool :
290314 """True if the :class:`Connection` requires behavior control.
@@ -308,14 +332,14 @@ def callback(robot, event_type, event):
308332 robot.anim.play_animation_trigger('GreetAfterLongTime')
309333 robot.conn.release_control()
310334
311- with anki_vector.Robot(requires_behavior_control=False ) as robot:
335+ with anki_vector.Robot(behavior_control_level=None ) as robot:
312336 print(robot.conn.requires_behavior_control) # Will print False
313337 robot.events.subscribe(callback, anki_vector.events.Events.robot_observed_face)
314338
315339 # Waits 10 seconds. Show Vector your face.
316340 time.sleep(10)
317341 """
318- return self ._requires_behavior_control
342+ return self ._behavior_control_level is not None
319343
320344 @property
321345 def control_lost_event (self ) -> asyncio .Event :
@@ -347,7 +371,7 @@ async def wait_for_control(conn: anki_vector.connection.Connection):
347371 """
348372 return self ._control_events .granted_event
349373
350- def request_control (self , timeout : float = 10.0 ):
374+ def request_control (self , behavior_control_level : CONTROL_PRIORITY_LEVEL = CONTROL_PRIORITY_LEVEL . DEFAULT_PRIORITY , timeout : float = 10.0 ):
351375 """Explicitly request behavior control. Typically used after detecting :func:`control_lost_event`.
352376
353377 To be able to directly control Vector's motors, override his screen, play an animation, etc.,
@@ -366,14 +390,18 @@ async def auto_reconnect(conn: anki_vector.connection.Connection):
366390 conn.request_control(timeout=5.0)
367391
368392 :param timeout: The time allotted to attempt a connection, in seconds.
393+ :param behavior_control_level: request control of Vector's behavior system at a specific level of control.
394+ See :class:`CONTROL_PRIORITY_LEVEL` for more information.
369395 """
396+ if not isinstance (behavior_control_level , CONTROL_PRIORITY_LEVEL ):
397+ raise TypeError ("behavior_control_level must be of type CONTROL_PRIORITY_LEVEL" )
370398 if self ._thread is threading .current_thread ():
371- return asyncio .ensure_future (self ._request_control (timeout = timeout ), loop = self ._loop )
372- return self .run_coroutine (self ._request_control (timeout = timeout ))
399+ return asyncio .ensure_future (self ._request_control (behavior_control_level = behavior_control_level , timeout = timeout ), loop = self ._loop )
400+ return self .run_coroutine (self ._request_control (behavior_control_level = behavior_control_level , timeout = timeout ))
373401
374- async def _request_control (self , timeout : float = 10.0 ):
375- self ._requires_behavior_control = True
376- self ._control_events .request ()
402+ async def _request_control (self , behavior_control_level : CONTROL_PRIORITY_LEVEL = CONTROL_PRIORITY_LEVEL . DEFAULT_PRIORITY , timeout : float = 10.0 ):
403+ self ._behavior_control_level = behavior_control_level
404+ self ._control_events .request (self . _behavior_control_level )
377405 try :
378406 self ._has_control = await asyncio .wait_for (self .control_granted_event .wait (), timeout )
379407 except futures .TimeoutError as e :
@@ -403,7 +431,7 @@ async def wait_for_control(conn: anki_vector.connection.Connection):
403431 return self .run_coroutine (self ._release_control (timeout = timeout ))
404432
405433 async def _release_control (self , timeout : float = 10.0 ):
406- self ._requires_behavior_control = False
434+ self ._behavior_control_level = None
407435 self ._control_events .release ()
408436 try :
409437 self ._has_control = await asyncio .wait_for (self .control_lost_event .wait (), timeout )
@@ -456,10 +484,10 @@ def _connect(self, timeout: float) -> None:
456484 self ._loop = asyncio .new_event_loop ()
457485 asyncio .set_event_loop (self ._loop )
458486 self ._done_signal = asyncio .Event ()
459- if not self ._requires_behavior_control :
487+ if not self ._behavior_control_level :
460488 self ._control_events = _ControlEventManager (self ._loop )
461489 else :
462- self ._control_events = _ControlEventManager (self ._loop , priority = CONTROL_PRIORITY_LEVEL . TOP_PRIORITY_AI )
490+ self ._control_events = _ControlEventManager (self ._loop , priority = self . _behavior_control_level )
463491 trusted_certs = None
464492 with open (self .cert_file , 'rb' ) as cert :
465493 trusted_certs = cert .read ()
@@ -505,8 +533,8 @@ def _connect(self, timeout: float) -> None:
505533 cpu_version = cpu_version )
506534 self ._loop .run_until_complete (self ._interface .SDKInitialization (initialize ))
507535
508- if self ._requires_behavior_control :
509- self ._loop .run_until_complete (self ._request_control (timeout = timeout ))
536+ if self ._behavior_control_level :
537+ self ._loop .run_until_complete (self ._request_control (behavior_control_level = self . _behavior_control_level , timeout = timeout ))
510538 except Exception as e : # pylint: disable=broad-except
511539 # Propagate the errors to the calling thread
512540 setattr (self ._ready_signal , "exception" , e )
0 commit comments