Skip to content

Commit f79a3fb

Browse files
VIC-7154 VIC-7167 VIC-3189 Add update.py script and victor-proto submodule (anki#18)
1 parent f2e73e9 commit f79a3fb

25 files changed

Lines changed: 430 additions & 361 deletions

anki_vector/behavior.py

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,14 @@
6464
MAX_LIFT_HEIGHT = util.distance_mm(MAX_LIFT_HEIGHT_MM)
6565

6666

67+
# TODO: Expose is_active and priority states of the SDK behavior control from this class.
6768
class BehaviorComponent(util.Component):
6869
"""Run behaviors on Vector"""
6970

7071
_next_action_id = protocol.FIRST_SDK_TAG
7172

7273
def __init__(self, robot):
7374
super().__init__(robot)
74-
self._current_priority = None
75-
self._is_active = False
76-
7775
self._motion_profile_map = {}
7876

7977
# TODO Make the motion_profile_map into a class.
@@ -131,17 +129,6 @@ def _motion_profile_for_proto(self) -> protocol.PathMotionProfile:
131129

132130
return protocol.PathMotionProfile(**default_motion_profile)
133131

134-
# @property
135-
# def current_priority(self):
136-
# # TODO implement
137-
# return self._current_priority
138-
139-
# @property
140-
# def is_active(self) -> bool:
141-
# # TODO implement
142-
# """True if the behavior is currently active and may run on the robot."""
143-
# return self._is_active
144-
145132
@classmethod
146133
def _get_next_action_id(cls):
147134
# Post increment _current_action_id (and loop within the SDK_TAG range)
@@ -237,9 +224,10 @@ async def go_to_pose(self,
237224
.. testcode::
238225
239226
import anki_vector
227+
from anki_vector.util import degrees, Pose
240228
241229
with anki_vector.Robot() as robot:
242-
pose = anki_vector.util.Pose(x=50, y=0, z=0, angle_z=anki_vector.util.Angle(degrees=0))
230+
pose = Pose(x=50, y=0, z=0, angle_z=anki_vector.util.Angle(degrees=0))
243231
robot.behavior.go_to_pose(pose)
244232
"""
245233
if relative_to_robot and self.robot.pose:

anki_vector/camera.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,8 @@ class CameraComponent(util.Component):
6060
.. testcode::
6161
6262
import anki_vector
63-
import time
6463
6564
with anki_vector.Robot(enable_camera_feed=True) as robot:
66-
time.sleep(1)
6765
image = robot.camera.latest_image
6866
image.show()
6967
@@ -76,8 +74,10 @@ def __init__(self, robot):
7674
self._latest_image: Image.Image = None
7775
self._latest_image_id: int = None
7876
self._camera_feed_task: asyncio.Task = None
77+
self._enabled = False
7978

8079
@property
80+
@util.block_while_none()
8181
def latest_image(self) -> Image.Image:
8282
""":class:`Image.Image`: The most recently processed image received from the robot.
8383
@@ -86,17 +86,17 @@ def latest_image(self) -> Image.Image:
8686
.. testcode::
8787
8888
import anki_vector
89-
import time
9089
9190
with anki_vector.Robot(enable_camera_feed=True) as robot:
92-
time.sleep(1)
9391
image = robot.camera.latest_image
9492
image.show()
9593
"""
96-
94+
if not self._camera_feed_task:
95+
raise Exception("Camera feed not open!") # TODO: Use a VectorException
9796
return self._latest_image
9897

9998
@property
99+
@util.block_while_none()
100100
def latest_image_id(self) -> int:
101101
"""The most recently processed image's id received from the robot.
102102
@@ -107,27 +107,30 @@ def latest_image_id(self) -> int:
107107
.. testcode::
108108
109109
import anki_vector
110-
import time
111110
112111
with anki_vector.Robot(enable_camera_feed=True) as robot:
113-
time.sleep(1)
114112
image = robot.camera.latest_image
115113
image.show()
116114
print(f"latest_image_id: {robot.camera.latest_image_id}")
117115
"""
116+
if not self._camera_feed_task:
117+
raise Exception("Camera feed not open!") # TODO: Use a VectorException
118118
return self._latest_image_id
119119

120120
def init_camera_feed(self) -> None:
121121
"""Begin camera feed task."""
122122
if not self._camera_feed_task or self._camera_feed_task.done():
123+
self._enabled = True
123124
self._camera_feed_task = self.conn.loop.create_task(self._request_and_handle_images())
124125

125126
def close_camera_feed(self) -> None:
126127
"""Cancel camera feed task."""
127128
if self._camera_feed_task:
129+
self._enabled = False
128130
self._camera_feed_task.cancel()
129131
future = self.conn.run_coroutine(self._camera_feed_task)
130132
future.result()
133+
self._camera_feed_task = None
131134

132135
def _unpack_image(self, msg: protocol.CameraFeedResponse) -> None:
133136
"""Processes raw data from the robot into a more more useful image structure."""
@@ -154,7 +157,7 @@ async def _request_and_handle_images(self) -> None:
154157
async for evt in self.grpc_interface.CameraFeed(req):
155158
# If the camera feed is disabled after stream is setup, exit the stream
156159
# (the camera feed on the robot is disabled internally on stream exit)
157-
if not self.robot.enable_camera_feed:
160+
if not self._enabled:
158161
self.logger.warning('Camera feed has been disabled. Enable the feed to start/continue receiving camera feed data')
159162
return
160163
self._unpack_image(evt)

anki_vector/connection.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
from .messaging import client, protocol
4343
from .version import __version__
4444

45-
CLIENT_VERSION = 1
45+
CLIENT_VERSION = 2
4646
MIN_HOST_VERSION = 0
4747

4848

@@ -339,7 +339,7 @@ def control_granted_event(self) -> asyncio.Event:
339339
340340
async def wait_for_control(conn: anki_vector.connection.Connection):
341341
await conn.control_granted_event.wait()
342-
// Run commands that require behavior control
342+
# Run commands that require behavior control
343343
"""
344344
return self._control_events.granted_event
345345

@@ -389,7 +389,7 @@ def release_control(self, timeout: float = 10.0):
389389
390390
async def wait_for_control(conn: anki_vector.connection.Connection):
391391
await conn.control_granted_event.wait()
392-
// Run commands that require behavior control
392+
# Run commands that require behavior control
393393
conn.release_control()
394394
395395
:param timeout: The time allotted to attempt to release control, in seconds.
@@ -536,11 +536,11 @@ async def _open_connections(self):
536536
async for response in self._interface.BehaviorControl(self._request_handler()):
537537
response_type = response.WhichOneof("response_type")
538538
if response_type == 'control_granted_response':
539-
self._logger.debug(response)
539+
self._logger.info(response)
540540
self._control_events.update(True)
541541
elif response_type == 'control_lost_event':
542542
self._cancel_active()
543-
self._logger.debug(response)
543+
self._logger.info(response)
544544
self._control_events.update(False)
545545
except futures.CancelledError:
546546
self._logger.debug('Behavior handler task was cancelled. This is expected during disconnection.')
@@ -591,6 +591,7 @@ def run_soon(self, coro: Awaitable) -> None:
591591
.. testcode::
592592
593593
import anki_vector
594+
import time
594595
595596
async def my_coroutine():
596597
print("Running on the connection thread")
@@ -628,7 +629,6 @@ async def my_coroutine():
628629
629630
with anki_vector.Robot() as robot:
630631
result = robot.conn.run_coroutine(my_coroutine())
631-
print(result)
632632
633633
:param coro: The coroutine, task or any other awaitable which should be executed.
634634
:returns: The result of the awaitable's execution.
@@ -665,7 +665,7 @@ def on_connection_thread(log_messaging: bool = True, requires_control: bool = Tr
665665
class MyComponent(anki_vector.util.Component):
666666
@connection._on_connection_thread()
667667
async def on_connection_thread(self):
668-
// Do work on the connection thread
668+
# Do work on the connection thread
669669
670670
:param log_messaging: True if the log output should include the entire message or just the size. Recommended for
671671
large binary return values.
@@ -703,7 +703,7 @@ async def log_handler(conn: Connection, func: Coroutine, logger: logging.Logger,
703703
if requires_control and not control.is_set():
704704
if not conn.requires_behavior_control:
705705
raise VectorControlException(func.__name__)
706-
logger.debug(f"Delaying {func.__name__} until behavior control is granted")
706+
logger.info(f"Delaying {func.__name__} until behavior control is granted")
707707
await conn.control_granted_event.wait()
708708
logger.debug(f'Outgoing {func.__name__}: {args[1:] if log_messaging else "size = {} bytes".format(sys.getsizeof(args[1:]))}')
709709
try:

anki_vector/messaging/alexa.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,5 @@
1717
syntax = "proto3";
1818

1919
package Anki.Vector.external_interface;
20+
21+

anki_vector/messaging/behavior.proto

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,4 @@ message BehaviorControlResponse {
6161
ControlLostResponse control_lost_event = 2;
6262
KeepAlivePing keep_alive = 3;
6363
}
64-
}
64+
}

anki_vector/messaging/extensions.proto

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ import "google/protobuf/descriptor.proto";
2222

2323
extend google.protobuf.MessageOptions {
2424
bool streamed = 60000;
25-
}
25+
}

anki_vector/messaging/external_interface.proto

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,5 +403,6 @@ service ExternalInterface {
403403
post: "/v1/nav_map_feed",
404404
body: "*"
405405
};
406-
}
407-
}
406+
}
407+
408+
}

anki_vector/messaging/messages.proto

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ package Anki.Vector.external_interface;
2020

2121
import "anki_vector/messaging/response_status.proto";
2222
import "anki_vector/messaging/extensions.proto";
23-
import "anki_vector/messaging/onboardingSteps.proto";
23+
import "anki_vector/messaging/onboarding_steps.proto";
2424

2525
// A null message used by streams to verify that the client is
2626
// still connected.
@@ -896,3 +896,4 @@ message SDKInitializationRequest {
896896
message SDKInitializationResponse {
897897
ResponseStatus status = 1;
898898
}
899+

anki_vector/messaging/messages_pb2.py

Lines changed: 255 additions & 255 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

anki_vector/messaging/onboardingSteps.proto renamed to anki_vector/messaging/onboarding_steps.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717
syntax = "proto3";
1818

1919
package Anki.Vector.external_interface;
20+

0 commit comments

Comments
 (0)