wirepod-vector-sdk-audio 0.9.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- anki_vector/__init__.py +43 -0
- anki_vector/animation.py +272 -0
- anki_vector/annotate.py +590 -0
- anki_vector/audio.py +212 -0
- anki_vector/audio_stream.py +335 -0
- anki_vector/behavior.py +1135 -0
- anki_vector/camera.py +670 -0
- anki_vector/camera_viewer/__init__.py +121 -0
- anki_vector/color.py +88 -0
- anki_vector/configure/__main__.py +331 -0
- anki_vector/connection.py +838 -0
- anki_vector/events.py +420 -0
- anki_vector/exceptions.py +185 -0
- anki_vector/faces.py +819 -0
- anki_vector/lights.py +210 -0
- anki_vector/mdns.py +131 -0
- anki_vector/messaging/__init__.py +45 -0
- anki_vector/messaging/alexa_pb2.py +36 -0
- anki_vector/messaging/alexa_pb2_grpc.py +3 -0
- anki_vector/messaging/behavior_pb2.py +40 -0
- anki_vector/messaging/behavior_pb2_grpc.py +3 -0
- anki_vector/messaging/client.py +33 -0
- anki_vector/messaging/cube_pb2.py +113 -0
- anki_vector/messaging/cube_pb2_grpc.py +3 -0
- anki_vector/messaging/extensions_pb2.py +25 -0
- anki_vector/messaging/extensions_pb2_grpc.py +3 -0
- anki_vector/messaging/external_interface_pb2.py +169 -0
- anki_vector/messaging/external_interface_pb2_grpc.py +1267 -0
- anki_vector/messaging/messages_pb2.py +431 -0
- anki_vector/messaging/messages_pb2_grpc.py +3 -0
- anki_vector/messaging/nav_map_pb2.py +33 -0
- anki_vector/messaging/nav_map_pb2_grpc.py +3 -0
- anki_vector/messaging/protocol.py +33 -0
- anki_vector/messaging/response_status_pb2.py +27 -0
- anki_vector/messaging/response_status_pb2_grpc.py +3 -0
- anki_vector/messaging/settings_pb2.py +72 -0
- anki_vector/messaging/settings_pb2_grpc.py +3 -0
- anki_vector/messaging/shared_pb2.py +54 -0
- anki_vector/messaging/shared_pb2_grpc.py +3 -0
- anki_vector/motors.py +127 -0
- anki_vector/nav_map.py +409 -0
- anki_vector/objects.py +1782 -0
- anki_vector/opengl/__init__.py +103 -0
- anki_vector/opengl/assets/LICENSE.txt +21 -0
- anki_vector/opengl/assets/cube.jpg +0 -0
- anki_vector/opengl/assets/cube.mtl +9 -0
- anki_vector/opengl/assets/cube.obj +1000 -0
- anki_vector/opengl/assets/vector.mtl +67 -0
- anki_vector/opengl/assets/vector.obj +13220 -0
- anki_vector/opengl/opengl.py +864 -0
- anki_vector/opengl/opengl_vector.py +620 -0
- anki_vector/opengl/opengl_viewer.py +689 -0
- anki_vector/photos.py +145 -0
- anki_vector/proximity.py +176 -0
- anki_vector/reserve_control/__main__.py +36 -0
- anki_vector/robot.py +930 -0
- anki_vector/screen.py +201 -0
- anki_vector/status.py +322 -0
- anki_vector/touch.py +119 -0
- anki_vector/user_intent.py +186 -0
- anki_vector/util.py +1132 -0
- anki_vector/version.py +15 -0
- anki_vector/viewer.py +403 -0
- anki_vector/vision.py +202 -0
- anki_vector/world.py +899 -0
- wirepod_vector_sdk_audio-0.9.0.dist-info/METADATA +80 -0
- wirepod_vector_sdk_audio-0.9.0.dist-info/RECORD +71 -0
- wirepod_vector_sdk_audio-0.9.0.dist-info/WHEEL +5 -0
- wirepod_vector_sdk_audio-0.9.0.dist-info/licenses/LICENSE.txt +180 -0
- wirepod_vector_sdk_audio-0.9.0.dist-info/top_level.txt +1 -0
- wirepod_vector_sdk_audio-0.9.0.dist-info/zip-safe +1 -0
anki_vector/__init__.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Copyright (c) 2018 Anki, Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License in the file LICENSE.txt or at
|
|
6
|
+
#
|
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
SDK for programming with the Anki Vector robot.
|
|
17
|
+
|
|
18
|
+
This fork includes audio streaming support via wirepod's websocket API.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import sys
|
|
22
|
+
import logging
|
|
23
|
+
|
|
24
|
+
from . import messaging
|
|
25
|
+
from .robot import Robot, AsyncRobot
|
|
26
|
+
from .version import __version__
|
|
27
|
+
from .audio_stream import AudioStreamClient, AudioStreamError, check_wirepod_audio_support
|
|
28
|
+
|
|
29
|
+
logger = logging.getLogger('vector') # pylint: disable=invalid-name
|
|
30
|
+
|
|
31
|
+
if sys.version_info < (3, 6, 1):
|
|
32
|
+
sys.exit('anki_vector requires Python 3.6.1 or later')
|
|
33
|
+
|
|
34
|
+
__all__ = [
|
|
35
|
+
'Robot',
|
|
36
|
+
'AsyncRobot',
|
|
37
|
+
'AudioStreamClient',
|
|
38
|
+
'AudioStreamError',
|
|
39
|
+
'check_wirepod_audio_support',
|
|
40
|
+
'logger',
|
|
41
|
+
'messaging',
|
|
42
|
+
'__version__'
|
|
43
|
+
]
|
anki_vector/animation.py
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# Copyright (c) 2018 Anki, Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License in the file LICENSE.txt or at
|
|
6
|
+
#
|
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
Animation related classes, functions, events and values.
|
|
17
|
+
|
|
18
|
+
Animations represent a sequence of highly coordinated movements, faces, lights, and sounds used to demonstrate an emotion or reaction.
|
|
19
|
+
|
|
20
|
+
Animations can control the following tracks: head, lift, treads, face, audio and backpack lights.
|
|
21
|
+
|
|
22
|
+
There are two ways to play an animation on Vector: play_animation_trigger and play_animation. For play_animation_trigger, you select
|
|
23
|
+
a pre-defined group of animations, and the robot will choose which animation from the group to run when you execute the method. When
|
|
24
|
+
calling play_animation, you select the specific animation you want the robot to run. We advise you to use play_animation_trigger instead
|
|
25
|
+
of play_animation, since individual animations can be deleted between Vector OS versions.
|
|
26
|
+
|
|
27
|
+
By default, when an SDK program starts, the SDK will request a list of known animation triggers and animations from the robot, which will be loaded
|
|
28
|
+
and available from anim_list_triggers and anim_list, respectively, in the AnimationComponent.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
# __all__ should order by constants, event classes, other classes, functions.
|
|
32
|
+
__all__ = ["AnimationComponent"]
|
|
33
|
+
|
|
34
|
+
import concurrent
|
|
35
|
+
|
|
36
|
+
from google.protobuf import text_format
|
|
37
|
+
|
|
38
|
+
from . import connection, exceptions, util
|
|
39
|
+
from .messaging import protocol
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class AnimationComponent(util.Component):
|
|
43
|
+
"""Play animations on the robot"""
|
|
44
|
+
|
|
45
|
+
def __init__(self, robot):
|
|
46
|
+
super().__init__(robot)
|
|
47
|
+
self._anim_dict = {}
|
|
48
|
+
self._anim_trigger_dict = {}
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def anim_list(self):
|
|
52
|
+
"""
|
|
53
|
+
Holds the set of animation names (strings) returned from the robot.
|
|
54
|
+
|
|
55
|
+
Animation names are dynamically retrieved from the robot when the Python
|
|
56
|
+
script connects to it.
|
|
57
|
+
|
|
58
|
+
Warning: Specific animations may be renamed or removed in future updates of the app.
|
|
59
|
+
If you want your program to work more reliably across all versions
|
|
60
|
+
we recommend using anim_trigger_list and :meth:`play_animation_trigger` instead.
|
|
61
|
+
|
|
62
|
+
.. testcode::
|
|
63
|
+
|
|
64
|
+
import anki_vector
|
|
65
|
+
|
|
66
|
+
with anki_vector.Robot() as robot:
|
|
67
|
+
print("List all animation names:")
|
|
68
|
+
anim_names = robot.anim.anim_list
|
|
69
|
+
for anim_name in anim_names:
|
|
70
|
+
print(anim_name)
|
|
71
|
+
"""
|
|
72
|
+
if not self._anim_dict:
|
|
73
|
+
self.logger.warning("Anim list was empty. Lazy-loading anim list now.")
|
|
74
|
+
result = self.load_animation_list()
|
|
75
|
+
if isinstance(result, concurrent.futures.Future):
|
|
76
|
+
result.result()
|
|
77
|
+
return list(self._anim_dict.keys())
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def anim_trigger_list(self):
|
|
81
|
+
"""
|
|
82
|
+
Holds the set of animation trigger names (strings) returned from the robot.
|
|
83
|
+
|
|
84
|
+
Animation trigger names are dynamically retrieved from the robot when the Python
|
|
85
|
+
script connects to it.
|
|
86
|
+
|
|
87
|
+
Playing an animation trigger causes the robot to play an animation of a particular type.
|
|
88
|
+
|
|
89
|
+
The robot may pick one of a number of actual animations to play based on
|
|
90
|
+
Vector's mood or emotion, or with random weighting. Thus playing the same
|
|
91
|
+
trigger twice may not result in the exact same underlying animation playing
|
|
92
|
+
twice.
|
|
93
|
+
|
|
94
|
+
To play an exact animation, use :meth:`play_animation`.
|
|
95
|
+
|
|
96
|
+
This property holds the set of defined animations triggers to pass to :meth:`play_animation_trigger`.
|
|
97
|
+
|
|
98
|
+
.. testcode::
|
|
99
|
+
|
|
100
|
+
import anki_vector
|
|
101
|
+
|
|
102
|
+
with anki_vector.Robot() as robot:
|
|
103
|
+
print("List all animation trigger names:")
|
|
104
|
+
anim_trigger_names = robot.anim.anim_trigger_list
|
|
105
|
+
for anim_trigger_name in anim_trigger_names:
|
|
106
|
+
print(anim_trigger_name)
|
|
107
|
+
"""
|
|
108
|
+
if not self._anim_trigger_dict:
|
|
109
|
+
self.logger.warning("Anim trigger list was empty. Lazy-loading anim trigger list now.")
|
|
110
|
+
result = self.load_animation_trigger_list()
|
|
111
|
+
if isinstance(result, concurrent.futures.Future):
|
|
112
|
+
result.result()
|
|
113
|
+
return list(self._anim_trigger_dict.keys())
|
|
114
|
+
|
|
115
|
+
async def _ensure_loaded(self):
|
|
116
|
+
"""
|
|
117
|
+
This is an optimization for the case where a user doesn't
|
|
118
|
+
need the animation_trigger_list or the animation_list. This way,
|
|
119
|
+
connections aren't delayed by the load_animation_triggers_list and
|
|
120
|
+
load_animation_list calls.
|
|
121
|
+
|
|
122
|
+
If this is invoked inside another async function then we
|
|
123
|
+
explicitly await the result.
|
|
124
|
+
"""
|
|
125
|
+
if not self._anim_dict:
|
|
126
|
+
self.logger.warning("Anim list was empty. Lazy-loading anim list now.")
|
|
127
|
+
await self._load_animation_list()
|
|
128
|
+
if not self._anim_trigger_dict:
|
|
129
|
+
self.logger.warning("Anim trigger list was empty. Lazy-loading anim trigger list now.")
|
|
130
|
+
await self._load_animation_trigger_list()
|
|
131
|
+
|
|
132
|
+
async def _load_animation_list(self):
|
|
133
|
+
req = protocol.ListAnimationsRequest()
|
|
134
|
+
result = await self.grpc_interface.ListAnimations(req, timeout=10)
|
|
135
|
+
self.logger.debug(f"Animation List status={text_format.MessageToString(result.status, as_one_line=True)}, number of animations={len(result.animation_names)}")
|
|
136
|
+
self._anim_dict = {a.name: a for a in result.animation_names}
|
|
137
|
+
return result
|
|
138
|
+
|
|
139
|
+
async def _load_animation_trigger_list(self):
|
|
140
|
+
req = protocol.ListAnimationTriggersRequest()
|
|
141
|
+
result = await self.grpc_interface.ListAnimationTriggers(req, timeout=10)
|
|
142
|
+
self.logger.debug(f"Animation Triggers List status={text_format.MessageToString(result.status, as_one_line=True)}, number of animation_triggers={len(result.animation_trigger_names)}")
|
|
143
|
+
self._anim_trigger_dict = {a.name: a for a in result.animation_trigger_names}
|
|
144
|
+
return result
|
|
145
|
+
|
|
146
|
+
@connection.on_connection_thread(log_messaging=False, requires_control=False)
|
|
147
|
+
async def load_animation_list(self):
|
|
148
|
+
"""Request the list of animations from the robot.
|
|
149
|
+
|
|
150
|
+
When the request has completed, anim_list will be populated with
|
|
151
|
+
the list of animations the robot knows how to run.
|
|
152
|
+
|
|
153
|
+
Warning: Specific animations may be renamed or removed in future updates of the app.
|
|
154
|
+
If you want your program to work more reliably across all versions
|
|
155
|
+
we recommend using animation triggers instead. See :meth:`play_animation_trigger`.
|
|
156
|
+
|
|
157
|
+
.. testcode::
|
|
158
|
+
|
|
159
|
+
import anki_vector
|
|
160
|
+
|
|
161
|
+
with anki_vector.AsyncRobot() as robot:
|
|
162
|
+
anim_request = robot.anim.load_animation_list()
|
|
163
|
+
anim_request.result()
|
|
164
|
+
anim_names = robot.anim.anim_list
|
|
165
|
+
for anim_name in anim_names:
|
|
166
|
+
print(anim_name)
|
|
167
|
+
"""
|
|
168
|
+
try:
|
|
169
|
+
return await self._load_animation_list()
|
|
170
|
+
except:
|
|
171
|
+
return await self._load_animation_list()
|
|
172
|
+
|
|
173
|
+
@connection.on_connection_thread(log_messaging=False, requires_control=False)
|
|
174
|
+
async def load_animation_trigger_list(self):
|
|
175
|
+
"""Request the list of animation triggers from the robot.
|
|
176
|
+
|
|
177
|
+
When the request has completed, anim_trigger_list will be populated with
|
|
178
|
+
the list of animation triggers the robot knows how to run.
|
|
179
|
+
|
|
180
|
+
Playing a trigger requests that an animation of a certain class starts playing, rather than an exact
|
|
181
|
+
animation name.
|
|
182
|
+
|
|
183
|
+
.. testcode::
|
|
184
|
+
|
|
185
|
+
import anki_vector
|
|
186
|
+
|
|
187
|
+
with anki_vector.AsyncRobot() as robot:
|
|
188
|
+
anim_trigger_request = robot.anim.load_animation_trigger_list()
|
|
189
|
+
anim_trigger_request.result()
|
|
190
|
+
anim_trigger_names = robot.anim.anim_trigger_list
|
|
191
|
+
for anim_trigger_name in anim_trigger_names:
|
|
192
|
+
print(anim_trigger_name)
|
|
193
|
+
"""
|
|
194
|
+
try:
|
|
195
|
+
return await self._load_animation_trigger_list()
|
|
196
|
+
except:
|
|
197
|
+
return await self._load_animation_trigger_list()
|
|
198
|
+
|
|
199
|
+
# TODO: add return type hint
|
|
200
|
+
@connection.on_connection_thread()
|
|
201
|
+
async def play_animation_trigger(self, anim_trigger: str, loop_count: int = 1, use_lift_safe: bool = False, ignore_body_track: bool = False, ignore_head_track: bool = False, ignore_lift_track: bool = False): # START
|
|
202
|
+
"""Starts an animation trigger playing on a robot.
|
|
203
|
+
|
|
204
|
+
Playing a trigger requests that an animation of a certain class starts playing, rather than an exact
|
|
205
|
+
animation name.
|
|
206
|
+
|
|
207
|
+
Vector must be off of the charger to play an animation.
|
|
208
|
+
|
|
209
|
+
.. testcode::
|
|
210
|
+
|
|
211
|
+
import anki_vector
|
|
212
|
+
|
|
213
|
+
with anki_vector.Robot() as robot:
|
|
214
|
+
robot.anim.play_animation_trigger('GreetAfterLongTime')
|
|
215
|
+
|
|
216
|
+
:param trigger: The animation trigger to play. Can be of type str or :class:`anki_vector.protocol.AnimationTrigger`.
|
|
217
|
+
:param loop_count: Number of times to play the animation.
|
|
218
|
+
:param use_lift_safe: True to automatically ignore the lift track if Vector is currently carrying an object.
|
|
219
|
+
:param ignore_body_track: True to ignore the animation track for Vector's body (i.e. the wheels / treads).
|
|
220
|
+
:param ignore_head_track: True to ignore the animation track for Vector's head.
|
|
221
|
+
:param ignore_lift_track: True to ignore the animation track for Vector's lift.
|
|
222
|
+
"""
|
|
223
|
+
animation_trigger = anim_trigger
|
|
224
|
+
if not isinstance(anim_trigger, protocol.AnimationTrigger):
|
|
225
|
+
await self._ensure_loaded()
|
|
226
|
+
if anim_trigger not in self.anim_trigger_list:
|
|
227
|
+
raise exceptions.VectorException(f"Unknown animation trigger: {anim_trigger}")
|
|
228
|
+
animation_trigger = self._anim_trigger_dict[anim_trigger]
|
|
229
|
+
req = protocol.PlayAnimationTriggerRequest(animation_trigger=animation_trigger,
|
|
230
|
+
loops=loop_count,
|
|
231
|
+
use_lift_safe=use_lift_safe,
|
|
232
|
+
ignore_body_track=ignore_body_track,
|
|
233
|
+
ignore_head_track=ignore_head_track,
|
|
234
|
+
ignore_lift_track=ignore_lift_track)
|
|
235
|
+
return await self.grpc_interface.PlayAnimationTrigger(req)
|
|
236
|
+
|
|
237
|
+
# TODO: add return type hint
|
|
238
|
+
@connection.on_connection_thread()
|
|
239
|
+
async def play_animation(self, anim: str, loop_count: int = 1, ignore_body_track: bool = False, ignore_head_track: bool = False, ignore_lift_track: bool = False):
|
|
240
|
+
"""Starts an animation playing on a robot.
|
|
241
|
+
|
|
242
|
+
Vector must be off of the charger to play an animation.
|
|
243
|
+
|
|
244
|
+
Warning: Specific animations may be renamed or removed in future updates of the app.
|
|
245
|
+
If you want your program to work more reliably across all versions
|
|
246
|
+
we recommend using :meth:`play_animation_trigger` instead.
|
|
247
|
+
|
|
248
|
+
.. testcode::
|
|
249
|
+
|
|
250
|
+
import anki_vector
|
|
251
|
+
|
|
252
|
+
with anki_vector.Robot() as robot:
|
|
253
|
+
robot.anim.play_animation('anim_turn_left_01')
|
|
254
|
+
|
|
255
|
+
:param anim: The animation to play. Can be of type str or :class:`anki_vector.protocol.Animation`.
|
|
256
|
+
:param loop_count: Number of times to play the animation.
|
|
257
|
+
:param ignore_body_track: True to ignore the animation track for Vector's body (i.e. the wheels / treads).
|
|
258
|
+
:param ignore_head_track: True to ignore the animation track for Vector's head.
|
|
259
|
+
:param ignore_lift_track: True to ignore the animation track for Vector's lift.
|
|
260
|
+
"""
|
|
261
|
+
animation = anim
|
|
262
|
+
if not isinstance(anim, protocol.Animation):
|
|
263
|
+
await self._ensure_loaded()
|
|
264
|
+
if anim not in self.anim_list:
|
|
265
|
+
raise exceptions.VectorException(f"Unknown animation: {anim}")
|
|
266
|
+
animation = self._anim_dict[anim]
|
|
267
|
+
req = protocol.PlayAnimationRequest(animation=animation,
|
|
268
|
+
loops=loop_count,
|
|
269
|
+
ignore_body_track=ignore_body_track,
|
|
270
|
+
ignore_head_track=ignore_head_track,
|
|
271
|
+
ignore_lift_track=ignore_lift_track)
|
|
272
|
+
return await self.grpc_interface.PlayAnimation(req)
|