├── .github └── CODEOWNERS ├── .gitignore ├── CODESTYLE.md ├── CONTRIBUTING.md ├── LICENSE.txt ├── Makefile ├── README.md ├── anki_vector ├── __init__.py ├── animation.py ├── annotate.py ├── audio.py ├── behavior.py ├── camera.py ├── camera_viewer │ └── __init__.py ├── color.py ├── configure │ └── __main__.py ├── connection.py ├── events.py ├── exceptions.py ├── faces.py ├── lights.py ├── mdns.py ├── messaging │ ├── __init__.py │ ├── alexa.proto │ ├── alexa_pb2.py │ ├── alexa_pb2_grpc.py │ ├── behavior.proto │ ├── behavior_pb2.py │ ├── behavior_pb2_grpc.py │ ├── client.py │ ├── cube.proto │ ├── cube_pb2.py │ ├── cube_pb2_grpc.py │ ├── extensions.proto │ ├── extensions_pb2.py │ ├── extensions_pb2_grpc.py │ ├── external_interface.proto │ ├── external_interface_pb2.py │ ├── external_interface_pb2_grpc.py │ ├── messages.proto │ ├── messages_pb2.py │ ├── messages_pb2_grpc.py │ ├── nav_map.proto │ ├── nav_map_pb2.py │ ├── nav_map_pb2_grpc.py │ ├── protocol.py │ ├── response_status.proto │ ├── response_status_pb2.py │ ├── response_status_pb2_grpc.py │ ├── settings.proto │ ├── settings_pb2.py │ ├── settings_pb2_grpc.py │ ├── shared.proto │ ├── shared_pb2.py │ └── shared_pb2_grpc.py ├── motors.py ├── nav_map.py ├── objects.py ├── opengl │ ├── __init__.py │ ├── assets │ │ ├── LICENSE.txt │ │ ├── cube.jpg │ │ ├── cube.mtl │ │ ├── cube.obj │ │ ├── vector.mtl │ │ └── vector.obj │ ├── opengl.py │ ├── opengl_vector.py │ └── opengl_viewer.py ├── photos.py ├── proximity.py ├── reserve_control │ └── __main__.py ├── robot.py ├── screen.py ├── status.py ├── touch.py ├── user_intent.py ├── util.py ├── version.py ├── viewer.py ├── vision.py └── world.py ├── docs ├── Makefile ├── README.md ├── ext │ ├── __init__.py │ ├── custopoleon │ │ └── __init__.py │ └── verlink.py ├── requirements.txt └── source │ ├── .gitignore │ ├── _static │ └── .gitignore │ ├── _templates │ └── layout.html │ ├── advanced-tips.rst │ ├── api.rst │ ├── conf.py │ ├── downloads.rst │ ├── getstarted.rst │ ├── images │ ├── annotate.png │ ├── custom_markers │ │ ├── LICENSE.txt │ │ ├── SDK_2Circles.png │ │ ├── SDK_2Diamonds.png │ │ ├── SDK_2Hexagons.png │ │ ├── SDK_2Triangles.png │ │ ├── SDK_3Circles.png │ │ ├── SDK_3Diamonds.png │ │ ├── SDK_3Hexagons.png │ │ ├── SDK_3Triangles.png │ │ ├── SDK_4Circles.png │ │ ├── SDK_4Diamonds.png │ │ ├── SDK_4Hexagons.png │ │ ├── SDK_4Triangles.png │ │ ├── SDK_5Circles.png │ │ ├── SDK_5Diamonds.png │ │ ├── SDK_5Hexagons.png │ │ └── SDK_5Triangles.png │ └── vector-sdk-alpha.jpg │ ├── index.rst │ ├── initial.rst │ ├── install-linux.rst │ ├── install-macos.rst │ ├── install-windows.rst │ ├── proto.html │ ├── proto.rst │ ├── template.tmpl │ └── troubleshooting.rst ├── examples ├── README.md ├── apps │ ├── 3d_viewer │ │ └── 3d_viewer.py │ ├── interactive_shell │ │ └── interactive_shell.py │ ├── proximity_mapper │ │ ├── lib │ │ │ └── proximity_mapper_state.py │ │ └── proximity_mapper.py │ └── remote_control │ │ ├── lib │ │ ├── __init__.py │ │ └── flask_helpers.py │ │ └── remote_control.py ├── experimental │ └── sign_language_recognition_system │ │ ├── README.md │ │ ├── data_gen.py │ │ ├── dataset.zip │ │ ├── example.png │ │ ├── recognizer.py │ │ └── util.py ├── face_images │ └── cozmo_image.jpg ├── scripts │ ├── take_control.bat │ └── take_control.command ├── sounds │ ├── vector_alert.wav │ └── vector_bell_whistle.wav └── tutorials │ ├── 01_hello_world.py │ ├── 02_drive_square.py │ ├── 03_motors.py │ ├── 04_animation.py │ ├── 05_drive_on_off_charger.py │ ├── 06_face_image.py │ ├── 07_dock_with_cube.py │ ├── 08_show_photo.py │ ├── 09_eye_color.py │ ├── 10_play_audio.py │ ├── 11_drive_to_cliff_and_back_up.py │ ├── 12_control_priority_level.py │ ├── 13_wake_word_subscription.py │ ├── 14_user_intent_subscription.py │ ├── 15_face_event_subscription.py │ ├── 16_face_follower.py │ ├── 17_custom_objects.py │ ├── 18_create_wall.py │ ├── 19_annotate.py │ └── 20_exposure.py ├── requirements.txt └── setup.py /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # https://help.github.com/articles/about-codeowners/ 2 | 3 | # These owners will be the default owners for everything in the repo. 4 | * @anki/cozmo-sdk-admins 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | generated/ 4 | *.py[cod] 5 | *$py.class 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Distribution / packaging 11 | .Python 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | 53 | # Translations 54 | *.mo 55 | *.pot 56 | 57 | # Django stuff: 58 | *.log 59 | local_settings.py 60 | db.sqlite3 61 | 62 | # Flask stuff: 63 | instance/ 64 | .webassets-cache 65 | 66 | # Scrapy stuff: 67 | .scrapy 68 | 69 | # Sphinx documentation 70 | docs/_build/ 71 | 72 | # PyBuilder 73 | target/ 74 | 75 | # Jupyter Notebook 76 | .ipynb_checkpoints 77 | 78 | # IPython 79 | profile_default/ 80 | ipython_config.py 81 | 82 | # pyenv 83 | .python-version 84 | 85 | # celery beat schedule file 86 | celerybeat-schedule 87 | 88 | # SageMath parsed files 89 | *.sage.py 90 | 91 | # Environments 92 | .env 93 | .venv 94 | env/ 95 | venv/ 96 | ENV/ 97 | env.bak/ 98 | venv.bak/ 99 | 100 | # Spyder project settings 101 | .spyderproject 102 | .spyproject 103 | 104 | # Rope project settings 105 | .ropeproject 106 | 107 | # mkdocs documentation 108 | /site 109 | 110 | # mypy 111 | .mypy_cache/ 112 | .dmypy.json 113 | dmypy.json 114 | 115 | # Pyre type checker 116 | .pyre/ -------------------------------------------------------------------------------- /CODESTYLE.md: -------------------------------------------------------------------------------- 1 | # Code Style Guide 2 | 3 | The code should generally follow [PEP8](https://www.python.org/dev/peps/pep-0008/) 4 | 5 | Code documentation should be written using Google style, which can be extracted 6 | using Sphinx: 7 | * https://google.github.io/styleguide/pyguide.html 8 | * https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html 9 | 10 | 11 | Main style points to consider: 12 | 13 | ## Line Length 14 | 15 | PEP8 recommends a maximum line length of 80 characters. While some lines 16 | are easier to read if they're a bit longer than that, generally try to stay 17 | within the 80 character limit. 18 | 19 | Parameter lists can be wrapped and long strings can be split by enclosing them 20 | in parentheses: 21 | 22 | ````python 23 | long_string = ('First long line...' 24 | 'Second long line') 25 | ```` 26 | 27 | or by using triple quotes. 28 | 29 | ## White Space 30 | 31 | Indentation should be made using 4 space characters. 32 | 33 | * Two blank lines between class definitions and top-level functions 34 | * One blank line between methods (generally) 35 | 36 | Follow [PEP8 guidelines](https://www.python.org/dev/peps/pep-0008/#whitespace-in-expressions-and-statements) 37 | for whitespace in expressions and statements. 38 | 39 | ## Imports 40 | 41 | Import statements should be arranged in three blocks at the head of the file 42 | (though after the module documentation). Each block of imports should be in 43 | alphabetical order. 44 | 45 | 1. The first block should be Python-provided packages (eg. `sys`) 46 | 2. The second block should be third-party packages (eg. `numpy`) 47 | 3. The final block should be local packages and module (eg. `from . import camera`) 48 | 49 | ````python 50 | import os 51 | import sys 52 | 53 | import numpy 54 | 55 | from . import camera 56 | from . import event 57 | ```` 58 | 59 | Wildcard imports (`from module import *`) should not be used outside of tests. 60 | 61 | Additionally it is generally useful to avoid importing variables from modules 62 | directly into the local namespace (`from module import some_object`) - Doing 63 | so means you now have two references to to the same thing, which impedes 64 | mocking during unit tests. 65 | 66 | Better instead to import the module and reference a qualified name (`import module` 67 | and `module.some_object`). 68 | 69 | ## Names 70 | 71 | * Module level constants should be in CAPS 72 | * Class names should be CamelCase 73 | * Variables, attributes, functions, methods and properties should be lowercase_with_underscores 74 | * Variables, attributes, functions, methods and properties can be named with a 75 | leading underscore to indicate that they're "private" 76 | 77 | ## Documentation 78 | 79 | See https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html 80 | for documentation examples. 81 | 82 | * Module-level documentation should appear first in the file, before imports 83 | * All public-facing classes, functions, methods etc should be documented 84 | * The first line of a docstring should contain the summary of what the item does. 85 | This should be followed by a blank line and the extended description, if any. 86 | * Use Sphinx-friendly markup (per the Google guide above) so that cross-references 87 | work automatically and examples are formatted correctly. 88 | 89 | ### Documenting properties and attributes 90 | 91 | For class and object attributes, use the `#:` comment syntax rather than a 92 | trailing docstring. Instance attributes can be documented in the `__init__` 93 | constructor. 94 | 95 | Properties should use a docstring like any other method, but should be 96 | written in the same style as an attribute, as that's how they'll be presented 97 | in Sphinx (ie. as `return_type: description`). 98 | 99 | Properties with setters must have the docstring on the getter rather than 100 | the setter. 101 | 102 | 103 | ```python 104 | class MyClass: 105 | """One line summary of class. 106 | 107 | Docstring for constructor should appear in the class description 108 | 109 | :param default_timeout: Default number of seconds for operations to 110 | wait for timeout. 111 | """ 112 | #: string: Description of a class-level attribute. The description 113 | #: may span multiple lines as long as they all begin with #: 114 | class_level_attr = '' 115 | 116 | def __init__(self, default_timeout: int = None): 117 | #: int: The default number of seconds for operations to wait for timeout. 118 | self.default_timeout = default_timeout 119 | 120 | @property 121 | def timeout_enabled(self): 122 | """bool: True if a value for :attr:`default_timeout` has been set.""" 123 | return self.default_timeout is not None 124 | ``` 125 | 126 | 127 | ## Exceptions 128 | 129 | Wherever practical, catch explicit exception classes rather than using 130 | a bare try/except statement (or matching `Exception`). 131 | 132 | To re-raise the original exception use `raise` by itself or 133 | `raise MyException() from exc` 134 | (rather than `raise exc`) to maintain the original stack trace. 135 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | We accept contributions from 3rd parties as long as you first complete an individual CLA (Contributor License Agreement): 2 | 3 | http://go.anki.com/individual-cla 4 | 5 | If your employer(s) have rights to intellectual property that you create, and that includes your contributions, then we also require a separate Corporate CLA from them: 6 | 7 | http://go.anki.com/corporate-cla 8 | 9 | Please also review our: [Code Style Guide](CODESTYLE.md) 10 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean dist examples license wheel installer 2 | 3 | version = $(shell perl -ne '/__version__ = "([^"]+)/ && print $$1;' anki_vector/version.py) 4 | 5 | license_targets = anki_vector/LICENSE.txt examples/LICENSE.txt 6 | example_targets = dist/anki_vector_sdk_examples.tar.gz dist/anki_vector_sdk_examples.zip 7 | 8 | example_filenames = $(shell cd examples && find . -name '*.py' -o -name '*.txt' -o -name '*.png' -o -name '*.jpg' -o -name '*.md' -o -name '*.json') 9 | example_pathnames = $(shell find examples -name '*.py' -o -name '*.txt' -o -name '*.png' -o -name '*.jpg' -o -name '*.md' -o -name '*.json') 10 | sdist_filename = dist/anki_vector-$(version).tar.gz 11 | wheel_filename = dist/anki_vector-$(version)-py3-none-any.whl 12 | 13 | license: $(license_targets) 14 | 15 | $(license_targets): LICENSE.txt 16 | for fn in $(license_targets); do \ 17 | cp LICENSE.txt $$fn; \ 18 | done 19 | 20 | $(sdist_filename): anki_vector/LICENSE.txt anki_vector/opengl/assets/LICENSE.txt $(shell find anki_vector -name '*.py' -o -name '*.mtl' -o -name '*.obj' -o -name '*.jpg') 21 | python3 setup.py sdist 22 | 23 | $(wheel_filename): anki_vector/LICENSE.txt anki_vector/opengl/assets/LICENSE.txt $(shell find anki_vector -name '*.py' -o -name '*.mtl' -o -name '*.obj' -o -name '*.jpg') 24 | python3 setup.py bdist_wheel 25 | 26 | dist/anki_vector_sdk_examples.zip: examples/LICENSE.txt $(example_pathnames) 27 | rm -f dist/anki_vector_sdk_examples.zip dist/anki_vector_sdk_examples_$(version).zip 28 | rm -rf dist/anki_vector_sdk_examples_$(version) 29 | mkdir dist/anki_vector_sdk_examples_$(version) 30 | tar -C examples -c $(example_filenames) | tar -C dist/anki_vector_sdk_examples_$(version) -xv 31 | cd dist && zip -r anki_vector_sdk_examples.zip anki_vector_sdk_examples_$(version) 32 | cd dist && zip -r anki_vector_sdk_examples_$(version).zip anki_vector_sdk_examples_$(version) 33 | 34 | dist/anki_vector_sdk_examples.tar.gz: examples/LICENSE.txt $(example_pathnames) 35 | rm -f dist/anki_vector_sdk_examples.tar.gz dist/anki_vector_sdk_examples_$(version).tar.gz 36 | rm -rf dist/anki_vector_sdk_examples_$(version) 37 | mkdir dist/anki_vector_sdk_examples_$(version) 38 | tar -C examples -c $(example_filenames) | tar -C dist/anki_vector_sdk_examples_$(version) -xv 39 | cd dist && tar -cvzf anki_vector_sdk_examples.tar.gz anki_vector_sdk_examples_$(version) 40 | cp -a dist/anki_vector_sdk_examples.tar.gz dist/anki_vector_sdk_examples_$(version).tar.gz 41 | 42 | examples: dist/anki_vector_sdk_examples.tar.gz dist/anki_vector_sdk_examples.zip 43 | 44 | dist: $(sdist_filename) $(wheel_filename) examples 45 | 46 | clean: 47 | rm -rf dist 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |  2 | # Anki/DDL Vector - Python SDK 3 | 4 | ## With support for any bot on wire-pod! 5 | (theoretically) Compatible with Ubuntu 16.04 - 22.04 and Python 3.6.1 - 3.12 6 | 7 | This is the extended fork of the original Anki Vector Python SDK. 8 | 9 | Originally forked by [cyb3rdog](https://github.com/cyb3rdog/vector_python_sdk), then forked by [MoonDog83](https://github.com/MoonDog82/vector-python-sdk) who added 3.11 support and regenerated the proto, and finally forked by me (kercre123). 10 | 11 | ![Vector](docs/source/images/vector-sdk-alpha.jpg) 12 | 13 | 14 | ## Getting Started 15 | 16 | I am hosting SDK documentation here: [https://keriganc.com/sdkdocs](https://keriganc.com/sdkdocs) 17 | 18 | The documentation contains installation guides, helpful tips, walkthroughs, and function descriptions which will help you use the thing. 19 | 20 | ### Python Installation 21 | 22 | #### Windows: 23 | 24 | If you dont have python installed yet, download and install it from the [Python.org](https://www.python.org/downloads/windows/). 25 | Make sure to tick the “Add Python 3.X to PATH” checkbox on the Setup screen. 26 | 27 | To avoid dificulties during the SDK install on your existing python installation, open the command line and run: 28 | 29 | ``` 30 | py -m pip install -U pip 31 | py -m pip install --upgrade setuptools 32 | ``` 33 | 34 | #### Linux: 35 | 36 | Open the Terminal and run following commands to install and update the Python, and packages required by SDK: 37 | 38 | ``` 39 | sudo apt-get update 40 | sudo apt-get install -y python3 python3-pip python3-tk python3-pil.imagetk build-essential libssl-dev libffi-dev freeglut3 41 | ``` 42 | 43 | If you are using Python 3.11 or abnove, create a file at ~/.config/pip/pip.conf with the following text: 44 | 45 | ``` 46 | [global] 47 | break-system-packages = true 48 | ``` 49 | 50 | ### SDK Installation 51 | 52 | - Note: Use either **```pip```** or **```pip3```** correspondingly to the Python version you are using. 53 | 54 | In case you have previously installed the original ***Anki*** or ***Ikkez*** SDK, uninstall it/them with following command(s): 55 | 56 | - ```pip uninstall anki_vector``` or ```pip3 uninstall anki_vector``` 57 | - ```pip uninstall ikkez_vector``` or ```pip3 uninstall ikkez_vector``` 58 | - ```pip uninstall cyb3r_vector_sdk``` or ```pip3 uninstall cyb3r_vector_sdk``` 59 | 60 | To install this new SDK, run: 61 | 62 | - ```pip install wirepod_vector_sdk``` or ```pip3 install wirepod_vector_sdk``` 63 | and 64 | - ```pip install "wirepod_vector_sdk[3dviewer]"``` or ```pip3 install "wirepod_vector_sdk[3dviewer]"``` 65 | 66 | 67 | To upgrade this SDK to its latest version, use: 68 | 69 | - ```pip install wirepod_vector_sdk --upgrade``` or ```pip3 install wirepod_vector_sdk --upgrade``` 70 | 71 | 72 | If you want to know where the SDK files are installed, use following command: 73 | 74 | - Windows: ```py -c "import anki_vector as _; print(_.__path__)"``` 75 | - Linux: ```python3 -c "import anki_vector as _; print(_.__path__)"``` 76 | 77 | 78 | ### SDK Configuration 79 | 80 | To authenticate a bot with the SDK (works when bot is connected to wire-pod): 81 | 82 | - Windows: **```py -m anki_vector.configure```** 83 | - Linux: **```python3 -m anki_vector.configure```** 84 | 85 | ### Log Level 86 | 87 | In order to change the log level to other then default value of `INFO`, set the `VECTOR_LOG_LEVEL` enviroment variable: 88 | 89 | Allowed values are: 90 | ``` 91 | CRITICAL = 50 92 | FATAL = CRITICAL 93 | ERROR = 40 94 | WARNING = 30 95 | WARN = WARNING 96 | INFO = 20 97 | DEBUG = 10 98 | ``` 99 | 100 | Example: 101 | 102 | - Windows: ```SET VECTOR_LOG_LEVEL=DEBUG``` 103 | - Lunux: ```VECTOR_LOG_LEVEL="DEBUG"``` 104 | 105 | 106 | ### Documentation 107 | 108 | You can generate a local copy of the SDK documetation by 109 | following the instructions in the `docs` folder of this project. 110 | 111 | I am hosting SDK documentation here: [https://keriganc.com/sdkdocs](https://keriganc.com/sdkdocs) 112 | 113 | Learn more about how Vector works: [Vector Bible](https://github.com/GooeyChickenman/victor/blob/master/documentation/Vector-TRM.pdf) 114 | 115 | 116 | ## Privacy Policy and Terms and Conditions 117 | 118 | Use of Vector and the Vector SDK is subject to Anki's [Privacy Policy](https://www.anki.com/en-us/company/privacy) and [Terms and Conditions](https://www.anki.com/en-us/company/terms-and-conditions). 119 | -------------------------------------------------------------------------------- /anki_vector/__init__.py: -------------------------------------------------------------------------------- 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 | 19 | import sys 20 | import logging 21 | 22 | from . import messaging 23 | from .robot import Robot, AsyncRobot 24 | from .version import __version__ 25 | 26 | logger = logging.getLogger('vector') # pylint: disable=invalid-name 27 | 28 | if sys.version_info < (3, 6, 1): 29 | sys.exit('anki_vector requires Python 3.6.1 or later') 30 | 31 | __all__ = ['Robot', 'AsyncRobot', 'logger', 'messaging', '__version__'] 32 | -------------------------------------------------------------------------------- /anki_vector/camera_viewer/__init__.py: -------------------------------------------------------------------------------- 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 | # http://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 | """This module provides the camera viewer's render process. 16 | 17 | It should be launched in a separate process to allow Vector to run freely while 18 | the viewer is rendering. 19 | 20 | It uses Tkinter, a standard Python GUI package. 21 | It also depends on the Pillow library for image processing. 22 | """ 23 | 24 | import multiprocessing as mp 25 | import sys 26 | import tkinter as tk 27 | 28 | try: 29 | from PIL import ImageTk 30 | except ImportError: 31 | sys.exit('Cannot import from PIL: Do `pip3 install --user "wirepod_vector_sdk[3dviewer]"` to install') 32 | 33 | 34 | class TkCameraViewer: # pylint: disable=too-few-public-methods 35 | """A Tkinter based camera video feed. 36 | 37 | :param queue: A queue to send frames between the user's main thread and the viewer process. 38 | :param event: An event to signal that the viewer process has closed. 39 | :param overlays: Overlays to be drawn on the images of the renderer. 40 | :param timeout: The time without a new frame before the process will exit. 41 | :param force_on_top: Specifies whether the window should be forced on top of all others. 42 | """ 43 | 44 | def __init__(self, queue: mp.Queue, event: mp.Event, overlays: list = None, timeout: float = 10.0, force_on_top: bool = True): 45 | self.tk_root = tk.Tk() 46 | self.width = None 47 | self.height = None 48 | self.queue = queue 49 | self.event = event 50 | self.overlays = overlays 51 | self.timeout = timeout 52 | self.tk_root.title("Vector Camera Feed") 53 | self.tk_root.protocol("WM_DELETE_WINDOW", self._delete_window) 54 | self.tk_root.bind("", self._resize_window) 55 | if force_on_top: 56 | self.tk_root.wm_attributes("-topmost", 1) 57 | self.label = tk.Label(self.tk_root, borderwidth=0) 58 | self.label.pack(fill=tk.BOTH, expand=True) 59 | 60 | def _delete_window(self) -> None: 61 | """Handle window close event.""" 62 | self.event.set() 63 | self.tk_root.destroy() 64 | 65 | def _resize_window(self, evt: tk.Event) -> None: 66 | """Handle window resize event. 67 | 68 | :param evt: A Tkinter window event (keyboard, mouse events, etc). 69 | """ 70 | self.width = evt.width 71 | self.height = evt.height 72 | 73 | def draw_frame(self) -> None: 74 | """Display an image on to a Tkinter label widget.""" 75 | try: 76 | image = self.queue.get(True, timeout=self.timeout) 77 | except: 78 | return 79 | self.width, self.height = image.size 80 | while image: 81 | if self.event.is_set(): 82 | break 83 | if self.overlays: 84 | for overlay in self.overlays: 85 | overlay.apply_overlay(image) 86 | if (self.width, self.height) != image.size: 87 | image = image.resize((self.width, self.height)) 88 | tk_image = ImageTk.PhotoImage(image) 89 | self.label.config(image=tk_image) 90 | self.label.image = tk_image 91 | self.tk_root.update_idletasks() 92 | self.tk_root.update() 93 | try: 94 | image = self.queue.get(True, timeout=self.timeout) 95 | except: 96 | return 97 | 98 | 99 | def main(queue: mp.Queue, event: mp.Event, overlays: list = None, timeout: float = 10.0, force_on_top: bool = False) -> None: 100 | """Rendering the frames in another process. This allows the UI to have the 101 | main thread of its process while the user code continues to execute. 102 | 103 | :param queue: A queue to send frames between the user's main thread and the viewer process. 104 | :param event: An event to signal that the viewer process has closed. 105 | :param overlays: Overlays to be drawn on the images of the renderer. 106 | :param timeout: The time without a new frame before the process will exit. 107 | :param force_on_top: Specifies whether the window should be forced on top of all others. 108 | """ 109 | 110 | try: 111 | tk_viewer = TkCameraViewer(queue, event, overlays, timeout, force_on_top) 112 | tk_viewer.draw_frame() 113 | except TimeoutError: 114 | pass 115 | except KeyboardInterrupt: 116 | pass 117 | finally: 118 | event.set() 119 | 120 | 121 | __all__ = ['TkCameraViewer', 'main'] 122 | -------------------------------------------------------------------------------- /anki_vector/color.py: -------------------------------------------------------------------------------- 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 | Colors to be used with a light or Vector's screen. 17 | """ 18 | 19 | 20 | class Color: 21 | """A Color to be used with a Light or Vector's screen. 22 | 23 | Either int_color or rgb may be used to specify the actual color. 24 | Any alpha components (from int_color) are ignored - all colors are fully opaque. 25 | 26 | :param int_color: A 32 bit value holding the binary RGBA value (where A 27 | is ignored and forced to be fully opaque). 28 | :param rgb: A tuple holding the integer values from 0-255 for (reg, green, blue) 29 | :param name: A name to assign to this color. 30 | """ 31 | 32 | def __init__(self, int_color: int = None, rgb: tuple = None, name: str = None): 33 | self.name = name 34 | self._int_color = 0 35 | if int_color is not None: 36 | self._int_color = int_color | 0xff 37 | elif rgb is not None: 38 | self._int_color = (rgb[0] << 24) | (rgb[1] << 16) | (rgb[2] << 8) | 0xff 39 | 40 | @property 41 | def int_color(self) -> int: 42 | """The encoded integer value of the color.""" 43 | return self._int_color 44 | 45 | @property 46 | def rgb565_bytepair(self): 47 | """bytes[]: Two bytes representing an int16 color with rgb565 encoding. 48 | 49 | This format reflects the robot's Screen color range, and performing this 50 | conversion will reduce network traffic when sending Screen data. 51 | """ 52 | 53 | red5 = ((self._int_color >> 24) & 0xff) >> 3 54 | green6 = ((self._int_color >> 16) & 0xff) >> 2 55 | blue5 = ((self._int_color >> 8) & 0xff) >> 3 56 | 57 | green3_hi = green6 >> 3 58 | green3_low = green6 & 0x07 59 | 60 | int_565_color_lowbyte = (green3_low << 5) | blue5 61 | int_565_color_highbyte = (red5 << 3) | green3_hi 62 | 63 | return [int_565_color_highbyte, int_565_color_lowbyte] 64 | 65 | 66 | #: :class:`Color`: Green color instance. 67 | green = Color(name="green", int_color=0x00ff00ff) 68 | 69 | #: :class:`Color`: Red color instance. 70 | red = Color(name="red", int_color=0xff0000ff) 71 | 72 | #: :class:`Color`: Blue color instance. 73 | blue = Color(name="blue", int_color=0x0000ffff) 74 | 75 | #: :class:`Color`: Cyan color instance. 76 | cyan = Color(name="cyan", int_color=0x00ffffff) 77 | 78 | #: :class:`Color`: Magenta color instance. 79 | magenta = Color(name="magenta", int_color=0xff00ffff) 80 | 81 | #: :class:`Color`: Yellow color instance. 82 | yellow = Color(name="yellow", int_color=0xffff00ff) 83 | 84 | #: :class:`Color`: White color instance. 85 | white = Color(name="white", int_color=0xffffffff) 86 | 87 | #: :class:`Color`: Instance representing no color (i.e., lights off). 88 | off = Color(name="off") 89 | -------------------------------------------------------------------------------- /anki_vector/mdns.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019 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 | This contains the :class:`VectorMdns` class for discovering Vector (without already knowing 17 | the IP address) on a LAN (Local Area Network) over mDNS. 18 | 19 | mDNS (multicast DNS) is a protocol for sending UDP packets containing a DNS query to all 20 | devices on your Local Area Network. If a device knows how to answer the DNS query, it 21 | will respond by multicasting a UDP packet containing the relevant DNS records. 22 | """ 23 | from threading import Condition 24 | import sys 25 | 26 | 27 | class VectorMdns: # pylint: disable=too-few-public-methods 28 | """`VectorMdns` provides a static method for discovering a Vector on the same LAN as 29 | the SDK program and retrieving its IP address. 30 | """ 31 | 32 | @staticmethod 33 | def find_vector(name: str, timeout=5): 34 | """ 35 | :param name: A name like `"Vector-A1B2"`. If :code:`None`, will search for any Vector. 36 | :param timeout: The discovery will timeout in :code:`timeout` seconds. Default value is :code:`5`. 37 | :returns: **dict** or **None** -- if Vector found, **dict** contains keys `"name"` and `"ipv4"` 38 | 39 | .. testcode:: 40 | 41 | import anki_vector 42 | vector_mdns = anki_vector.mdns.VectorMdns.find_vector("Vector-A1B2") 43 | 44 | if vector_mdns is not None: 45 | print(vector_mdns['ipv4']) 46 | else: 47 | print("No Vector found on your local network!") 48 | """ 49 | 50 | # synchronously search for Vector for up to 5 seconds 51 | vector_name = name # should be like 'Vector-V3C7' 52 | return VectorMdns._start_mdns_listener(vector_name, timeout) 53 | 54 | @staticmethod 55 | def _start_mdns_listener(name, timeout): 56 | try: 57 | from zeroconf import ServiceBrowser, Zeroconf 58 | except ImportError: 59 | sys.exit("Cannot import from Zeroconf: Do `pip3 install --user zeroconf` to install") 60 | 61 | # create a Condition object and acquire the underlying lock 62 | cond = Condition() 63 | cond.acquire() 64 | 65 | # instantiate zeroconf and our MdnsListner object for listening to events 66 | zeroconf = Zeroconf() 67 | vector_fullname = None 68 | 69 | if name is not None: 70 | vector_fullname = name + ".local." 71 | 72 | listener = _MdnsListener(vector_fullname, cond) 73 | 74 | # browse for the _ankivector TCP MDNS service, sending events to our listener 75 | ServiceBrowser(zeroconf, "_ankivector._tcp.local.", listener) 76 | 77 | # block until 'timeout' seconds or until we discover vector 78 | cond.wait(timeout) 79 | 80 | # close zeroconf 81 | zeroconf.close() 82 | 83 | # return an IPv4 string (or None) 84 | if listener.ipv4 is None: 85 | return None 86 | 87 | return {'ipv4': listener.ipv4, 'name': listener.name} 88 | 89 | 90 | class _MdnsListener: 91 | """_MdnsListener is an internal helper class which listens for mDNS messages. 92 | 93 | :param name_filter: A String to filter the mDNS responses by name (e.g., `"Vector-A1B2"`). 94 | :param condition: A Condition object to be used for signaling to caller when robot has been discovered. 95 | """ 96 | 97 | def __init__(self, name_filter: str, condition): 98 | self.name_filter = name_filter 99 | self.cond = condition 100 | self.ipv4 = None 101 | self.name = "" 102 | 103 | @staticmethod 104 | def _bytes_to_str_ipv4(ip_bytes): 105 | return str(ip_bytes[0]) + "." + \ 106 | str(ip_bytes[1]) + "." + \ 107 | str(ip_bytes[2]) + "." + \ 108 | str(ip_bytes[3]) 109 | 110 | def remove_service(self, zeroconf, mdns_type, name): 111 | # detect service removal 112 | pass 113 | 114 | def add_service(self, zeroconf, mdns_type, name): 115 | # detect service 116 | info = zeroconf.get_service_info(mdns_type, name) 117 | 118 | if (self.name_filter is None) or (info.server.lower() == self.name_filter.lower()): 119 | # found a match for our filter or there is no filter 120 | self.cond.acquire() 121 | self.ipv4 = _MdnsListener._bytes_to_str_ipv4(info.addresses[0]) # info.addresses[0] is IPv4 (DNS record type 'A') 122 | self.name = info.server 123 | 124 | # cause anything waiting for this condition to end waiting 125 | # and release so the other thread can continue 126 | self.cond.notify() 127 | self.cond.release() 128 | 129 | def update_service(self, zeroconf, mdns_type, name): 130 | # detect service update 131 | pass -------------------------------------------------------------------------------- /anki_vector/messaging/__init__.py: -------------------------------------------------------------------------------- 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 | # http://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 | Protobuf and gRPC messages exposed to the Vector Python SDK. 17 | 18 | .. warning:: 19 | 20 | This package is provided to understand the messages passed between the SDK and Vector, 21 | and it should not be necessary for writing code that uses the SDK. 22 | 23 | .. code-block:: 24 | python 25 | 26 | from anki_vector.messaging import client, protocol 27 | 28 | async def send_version_request(interface: client.ExternalInterfaceStub, client_version, min_host_version): 29 | \"\"\"This function needs to be executed and awaited in the same event loop 30 | as the interface is created. 31 | \"\"\" 32 | # Create a protocol version request message 33 | version = protocol.ProtocolVersionRequest(client_version=client_version, 34 | min_host_version=min_host_version) 35 | 36 | # Send the protocol version to the external interface and await the result 37 | protocol_version = await interface.ProtocolVersion(version) 38 | 39 | For information about individual messages and their parameters, see :doc:`the protobuf documentation `. 40 | """ 41 | 42 | from . import protocol 43 | from . import client 44 | 45 | __all__ = ['protocol', 'client'] 46 | -------------------------------------------------------------------------------- /anki_vector/messaging/alexa.proto: -------------------------------------------------------------------------------- 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 | // http://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 | // Alexa messages 16 | 17 | syntax = "proto3"; 18 | 19 | package Anki.Vector.external_interface; 20 | 21 | import "anki_vector/messaging/response_status.proto"; 22 | 23 | 24 | enum AlexaAuthState { 25 | // Invalid/error/versioning issue 26 | ALEXA_AUTH_INVALID = 0; 27 | 28 | // Not opted in, or opt-in attempted but failed 29 | ALEXA_AUTH_UNINITIALIZED = 1; 30 | // Opted in, and attempting to authorize 31 | ALEXA_AUTH_REQUESTING_AUTH = 2; 32 | // Opted in, and waiting on the user to enter a code 33 | ALEXA_AUTH_WAITING_FOR_CODE = 3; 34 | // Opted in, and authorized / in use 35 | ALEXA_AUTH_AUTHORIZED = 4; 36 | } 37 | 38 | message AlexaAuthStateRequest { 39 | } 40 | 41 | message AlexaAuthStateResponse { 42 | ResponseStatus status = 1; 43 | AlexaAuthState auth_state = 2; 44 | string extra = 3; 45 | } 46 | 47 | message AlexaOptInRequest { 48 | bool opt_in = 1; 49 | } 50 | 51 | message AlexaOptInResponse{ 52 | ResponseStatus status = 1; 53 | } 54 | 55 | message AlexaAuthEvent { 56 | AlexaAuthState auth_state = 1; 57 | string extra = 2; 58 | } 59 | -------------------------------------------------------------------------------- /anki_vector/messaging/alexa_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # source: anki_vector/messaging/alexa.proto 4 | """Generated protocol buffer code.""" 5 | from google.protobuf.internal import builder as _builder 6 | from google.protobuf import descriptor as _descriptor 7 | from google.protobuf import descriptor_pool as _descriptor_pool 8 | from google.protobuf import symbol_database as _symbol_database 9 | # @@protoc_insertion_point(imports) 10 | 11 | _sym_db = _symbol_database.Default() 12 | 13 | 14 | from anki_vector.messaging import response_status_pb2 as anki__vector_dot_messaging_dot_response__status__pb2 15 | 16 | 17 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!anki_vector/messaging/alexa.proto\x12\x1e\x41nki.Vector.external_interface\x1a+anki_vector/messaging/response_status.proto\"\x17\n\x15\x41lexaAuthStateRequest\"\xab\x01\n\x16\x41lexaAuthStateResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12\x42\n\nauth_state\x18\x02 \x01(\x0e\x32..Anki.Vector.external_interface.AlexaAuthState\x12\r\n\x05\x65xtra\x18\x03 \x01(\t\"#\n\x11\x41lexaOptInRequest\x12\x0e\n\x06opt_in\x18\x01 \x01(\x08\"T\n\x12\x41lexaOptInResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"c\n\x0e\x41lexaAuthEvent\x12\x42\n\nauth_state\x18\x01 \x01(\x0e\x32..Anki.Vector.external_interface.AlexaAuthState\x12\r\n\x05\x65xtra\x18\x02 \x01(\t*\xa2\x01\n\x0e\x41lexaAuthState\x12\x16\n\x12\x41LEXA_AUTH_INVALID\x10\x00\x12\x1c\n\x18\x41LEXA_AUTH_UNINITIALIZED\x10\x01\x12\x1e\n\x1a\x41LEXA_AUTH_REQUESTING_AUTH\x10\x02\x12\x1f\n\x1b\x41LEXA_AUTH_WAITING_FOR_CODE\x10\x03\x12\x19\n\x15\x41LEXA_AUTH_AUTHORIZED\x10\x04\x62\x06proto3') 18 | 19 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) 20 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'anki_vector.messaging.alexa_pb2', globals()) 21 | if _descriptor._USE_C_DESCRIPTORS == False: 22 | 23 | DESCRIPTOR._options = None 24 | _ALEXAAUTHSTATE._serialized_start=538 25 | _ALEXAAUTHSTATE._serialized_end=700 26 | _ALEXAAUTHSTATEREQUEST._serialized_start=114 27 | _ALEXAAUTHSTATEREQUEST._serialized_end=137 28 | _ALEXAAUTHSTATERESPONSE._serialized_start=140 29 | _ALEXAAUTHSTATERESPONSE._serialized_end=311 30 | _ALEXAOPTINREQUEST._serialized_start=313 31 | _ALEXAOPTINREQUEST._serialized_end=348 32 | _ALEXAOPTINRESPONSE._serialized_start=350 33 | _ALEXAOPTINRESPONSE._serialized_end=434 34 | _ALEXAAUTHEVENT._serialized_start=436 35 | _ALEXAAUTHEVENT._serialized_end=535 36 | # @@protoc_insertion_point(module_scope) 37 | -------------------------------------------------------------------------------- /anki_vector/messaging/alexa_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | import grpc 3 | 4 | -------------------------------------------------------------------------------- /anki_vector/messaging/behavior.proto: -------------------------------------------------------------------------------- 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 | // http://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 | // Behavior related messages 16 | 17 | syntax = "proto3"; 18 | 19 | package Anki.Vector.external_interface; 20 | 21 | import "anki_vector/messaging/messages.proto"; 22 | 23 | // Tell the behavior stream to release control from the SDK. 24 | // The stream may stay alive, but Vector will be allowed to run 25 | // his normal behaviors. 26 | message ControlRelease {} 27 | 28 | // Request control of the behavior system at a given priority. 29 | // Currently there is only one priority level. 30 | message ControlRequest { 31 | // Where in the behavior tree the SDK code should be executed. 32 | enum Priority { 33 | // Unknown priority. Used for versions that don't understand old priority levels. 34 | UNKNOWN = 0; 35 | // Highest priority level. Suppresses most automatic physical reactions, use with caution. 36 | OVERRIDE_BEHAVIORS = 10; 37 | // Normal priority level. Directly under mandatory physical reactions. 38 | DEFAULT = 20; 39 | // Enable long-running SDK control between script execution. Not to be used for regular behavior control. 40 | RESERVE_CONTROL = 30; 41 | } 42 | // Where in the behavior tree the SDK code should be executed. 43 | Priority priority = 1; 44 | } 45 | 46 | // Messages that can be sent to the behavior stream. Explicitly 47 | // requesting or releasing control. 48 | message BehaviorControlRequest { 49 | oneof request_type { 50 | // Release control of the behavior system back to Vector. 51 | ControlRelease control_release = 1; 52 | // Request control of the behavior system for the SDK. 53 | ControlRequest control_request = 2; 54 | } 55 | } 56 | 57 | // The SDK user is now free to run any actions and behaviors they like. 58 | // Until a ControlLostResponse is received, they are directly in control 59 | // of Vector's behavior system. 60 | message ControlGrantedResponse {} 61 | 62 | // This informs the user that they lost control of the behavior system. 63 | // All direct actions will be unavailable via the sdk until control is regained. 64 | // Regaining control can be either through a call to ControlRequest, or 65 | // can be as a result of conditions passed to the original ControlRequest. 66 | message ControlLostResponse {} 67 | 68 | // The ability to reserve control before/after SDK scripts has been lost. 69 | // This control can be regained through another ControlRequest. 70 | message ReservedControlLostResponse {} 71 | 72 | // Responses from the behavior stream. 73 | message BehaviorControlResponse { 74 | oneof response_type { 75 | // The SDK user is now free to directly control Vector. 76 | ControlGrantedResponse control_granted_response = 1; 77 | // Control of the behavior system has been lost to a higher priority behavior. 78 | ControlLostResponse control_lost_event = 2; 79 | // Used by Vector to verify the connection is still alive. 80 | KeepAlivePing keep_alive = 3; 81 | // Behavior system lock has been lost to another connection 82 | ReservedControlLostResponse reserved_control_lost_event = 4; 83 | } 84 | } -------------------------------------------------------------------------------- /anki_vector/messaging/behavior_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # source: anki_vector/messaging/behavior.proto 4 | """Generated protocol buffer code.""" 5 | from google.protobuf.internal import builder as _builder 6 | from google.protobuf import descriptor as _descriptor 7 | from google.protobuf import descriptor_pool as _descriptor_pool 8 | from google.protobuf import symbol_database as _symbol_database 9 | # @@protoc_insertion_point(imports) 10 | 11 | _sym_db = _symbol_database.Default() 12 | 13 | 14 | from anki_vector.messaging import messages_pb2 as anki__vector_dot_messaging_dot_messages__pb2 15 | 16 | 17 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$anki_vector/messaging/behavior.proto\x12\x1e\x41nki.Vector.external_interface\x1a$anki_vector/messaging/messages.proto\"\x10\n\x0e\x43ontrolRelease\"\xae\x01\n\x0e\x43ontrolRequest\x12I\n\x08priority\x18\x01 \x01(\x0e\x32\x37.Anki.Vector.external_interface.ControlRequest.Priority\"Q\n\x08Priority\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x16\n\x12OVERRIDE_BEHAVIORS\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x14\x12\x13\n\x0fRESERVE_CONTROL\x10\x1e\"\xbe\x01\n\x16\x42\x65haviorControlRequest\x12I\n\x0f\x63ontrol_release\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ControlReleaseH\x00\x12I\n\x0f\x63ontrol_request\x18\x02 \x01(\x0b\x32..Anki.Vector.external_interface.ControlRequestH\x00\x42\x0e\n\x0crequest_type\"\x18\n\x16\x43ontrolGrantedResponse\"\x15\n\x13\x43ontrolLostResponse\"\x1d\n\x1bReservedControlLostResponse\"\x82\x03\n\x17\x42\x65haviorControlResponse\x12Z\n\x18\x63ontrol_granted_response\x18\x01 \x01(\x0b\x32\x36.Anki.Vector.external_interface.ControlGrantedResponseH\x00\x12Q\n\x12\x63ontrol_lost_event\x18\x02 \x01(\x0b\x32\x33.Anki.Vector.external_interface.ControlLostResponseH\x00\x12\x43\n\nkeep_alive\x18\x03 \x01(\x0b\x32-.Anki.Vector.external_interface.KeepAlivePingH\x00\x12\x62\n\x1breserved_control_lost_event\x18\x04 \x01(\x0b\x32;.Anki.Vector.external_interface.ReservedControlLostResponseH\x00\x42\x0f\n\rresponse_typeb\x06proto3') 18 | 19 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) 20 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'anki_vector.messaging.behavior_pb2', globals()) 21 | if _descriptor._USE_C_DESCRIPTORS == False: 22 | 23 | DESCRIPTOR._options = None 24 | _CONTROLRELEASE._serialized_start=110 25 | _CONTROLRELEASE._serialized_end=126 26 | _CONTROLREQUEST._serialized_start=129 27 | _CONTROLREQUEST._serialized_end=303 28 | _CONTROLREQUEST_PRIORITY._serialized_start=222 29 | _CONTROLREQUEST_PRIORITY._serialized_end=303 30 | _BEHAVIORCONTROLREQUEST._serialized_start=306 31 | _BEHAVIORCONTROLREQUEST._serialized_end=496 32 | _CONTROLGRANTEDRESPONSE._serialized_start=498 33 | _CONTROLGRANTEDRESPONSE._serialized_end=522 34 | _CONTROLLOSTRESPONSE._serialized_start=524 35 | _CONTROLLOSTRESPONSE._serialized_end=545 36 | _RESERVEDCONTROLLOSTRESPONSE._serialized_start=547 37 | _RESERVEDCONTROLLOSTRESPONSE._serialized_end=576 38 | _BEHAVIORCONTROLRESPONSE._serialized_start=579 39 | _BEHAVIORCONTROLRESPONSE._serialized_end=965 40 | # @@protoc_insertion_point(module_scope) 41 | -------------------------------------------------------------------------------- /anki_vector/messaging/behavior_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | import grpc 3 | 4 | -------------------------------------------------------------------------------- /anki_vector/messaging/client.py: -------------------------------------------------------------------------------- 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 | # http://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 | # pylint: skip-file 16 | 17 | """ 18 | Protobuf messages exposed to the Vector Python SDK. 19 | """ 20 | import sys 21 | import inspect 22 | 23 | from .alexa_pb2_grpc import * 24 | from .behavior_pb2_grpc import * 25 | from .cube_pb2_grpc import * 26 | from .messages_pb2_grpc import * 27 | from .nav_map_pb2_grpc import * 28 | from .response_status_pb2_grpc import * 29 | from .settings_pb2_grpc import * 30 | from .shared_pb2_grpc import * 31 | from .external_interface_pb2_grpc import * 32 | 33 | __all__ = [obj.__name__ for _, obj in inspect.getmembers(sys.modules[__name__]) if inspect.isclass(obj)] 34 | -------------------------------------------------------------------------------- /anki_vector/messaging/cube_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | import grpc 3 | 4 | -------------------------------------------------------------------------------- /anki_vector/messaging/extensions.proto: -------------------------------------------------------------------------------- 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 | // http://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 | // Add a decorator for streamed message handling in app 16 | 17 | syntax = "proto3"; 18 | 19 | package Anki.Vector.external_interface; 20 | 21 | import "google/protobuf/descriptor.proto"; 22 | 23 | extend google.protobuf.MessageOptions { 24 | bool streamed = 60000; 25 | } -------------------------------------------------------------------------------- /anki_vector/messaging/extensions_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # source: anki_vector/messaging/extensions.proto 4 | """Generated protocol buffer code.""" 5 | from google.protobuf.internal import builder as _builder 6 | from google.protobuf import descriptor as _descriptor 7 | from google.protobuf import descriptor_pool as _descriptor_pool 8 | from google.protobuf import symbol_database as _symbol_database 9 | # @@protoc_insertion_point(imports) 10 | 11 | _sym_db = _symbol_database.Default() 12 | 13 | 14 | from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 15 | 16 | 17 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&anki_vector/messaging/extensions.proto\x12\x1e\x41nki.Vector.external_interface\x1a google/protobuf/descriptor.proto:3\n\x08streamed\x12\x1f.google.protobuf.MessageOptions\x18\xe0\xd4\x03 \x01(\x08\x62\x06proto3') 18 | 19 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) 20 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'anki_vector.messaging.extensions_pb2', globals()) 21 | if _descriptor._USE_C_DESCRIPTORS == False: 22 | google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(streamed) 23 | 24 | DESCRIPTOR._options = None 25 | # @@protoc_insertion_point(module_scope) 26 | -------------------------------------------------------------------------------- /anki_vector/messaging/extensions_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | import grpc 3 | 4 | -------------------------------------------------------------------------------- /anki_vector/messaging/messages_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | import grpc 3 | 4 | -------------------------------------------------------------------------------- /anki_vector/messaging/nav_map.proto: -------------------------------------------------------------------------------- 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 | // http://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 | // External interface for robot <-> app and robot <-> sdk communication 16 | // about the robot's navigational memory map. 17 | 18 | syntax = "proto3"; 19 | 20 | package Anki.Vector.external_interface; 21 | 22 | // Every tile in the nav map will be tagged with a content key referring to 23 | // the different environmental elements that Vector can identify. 24 | enum NavNodeContentType 25 | { 26 | NAV_NODE_UNKNOWN = 0; 27 | NAV_NODE_CLEAR_OF_OBSTACLE = 1; 28 | NAV_NODE_CLEAR_OF_CLIFF = 2; 29 | NAV_NODE_OBSTACLE_CUBE = 3; 30 | NAV_NODE_OBSTACLE_PROXIMITY = 4; 31 | NAV_NODE_OBSTACLE_PROXIMITY_EXPLORED = 5; 32 | NAV_NODE_OBSTACLE_UNRECOGNIZED = 6; 33 | NAV_NODE_CLIFF = 7; 34 | NAV_NODE_INTERESTING_EDGE = 8; 35 | NAV_NODE_NON_INTERESTING_EDGE = 9; 36 | } 37 | 38 | // An individual sample of vector's nav map. This quad's size will vary and 39 | // depends on the resolution the map requires to effectively identify 40 | // boundaries in the environment. 41 | message NavMapQuadInfo 42 | { 43 | NavNodeContentType content = 1; 44 | uint32 depth = 2; 45 | uint32 color_rgba = 3; 46 | } 47 | 48 | // General information about the nav map as a whole. 49 | message NavMapInfo 50 | { 51 | int32 root_depth = 1; 52 | float root_size_mm = 2; 53 | float root_center_x = 3; 54 | float root_center_y = 4; 55 | float root_center_z = 5; 56 | } 57 | 58 | // Requests nav map data from the robot at a specified maximum update frequency. 59 | // Responses in the nav map stream may be sent less frequently if the robot does 60 | // not consider there to be relevant new information. 61 | message NavMapFeedRequest 62 | { 63 | float frequency = 1; 64 | } 65 | 66 | // A full nav map sent from the robot. It contains an origin_id that 67 | // which can be compared against the robot's current origin_id, general 68 | // info about the map, and a collection of quads representing the map's 69 | // content. 70 | message NavMapFeedResponse 71 | { 72 | uint32 origin_id = 1; 73 | NavMapInfo map_info = 2; 74 | repeated NavMapQuadInfo quad_infos = 3; 75 | } 76 | -------------------------------------------------------------------------------- /anki_vector/messaging/nav_map_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # source: anki_vector/messaging/nav_map.proto 4 | """Generated protocol buffer code.""" 5 | from google.protobuf.internal import builder as _builder 6 | from google.protobuf import descriptor as _descriptor 7 | from google.protobuf import descriptor_pool as _descriptor_pool 8 | from google.protobuf import symbol_database as _symbol_database 9 | # @@protoc_insertion_point(imports) 10 | 11 | _sym_db = _symbol_database.Default() 12 | 13 | 14 | 15 | 16 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#anki_vector/messaging/nav_map.proto\x12\x1e\x41nki.Vector.external_interface\"x\n\x0eNavMapQuadInfo\x12\x43\n\x07\x63ontent\x18\x01 \x01(\x0e\x32\x32.Anki.Vector.external_interface.NavNodeContentType\x12\r\n\x05\x64\x65pth\x18\x02 \x01(\r\x12\x12\n\ncolor_rgba\x18\x03 \x01(\r\"{\n\nNavMapInfo\x12\x12\n\nroot_depth\x18\x01 \x01(\x05\x12\x14\n\x0croot_size_mm\x18\x02 \x01(\x02\x12\x15\n\rroot_center_x\x18\x03 \x01(\x02\x12\x15\n\rroot_center_y\x18\x04 \x01(\x02\x12\x15\n\rroot_center_z\x18\x05 \x01(\x02\"&\n\x11NavMapFeedRequest\x12\x11\n\tfrequency\x18\x01 \x01(\x02\"\xa9\x01\n\x12NavMapFeedResponse\x12\x11\n\torigin_id\x18\x01 \x01(\r\x12<\n\x08map_info\x18\x02 \x01(\x0b\x32*.Anki.Vector.external_interface.NavMapInfo\x12\x42\n\nquad_infos\x18\x03 \x03(\x0b\x32..Anki.Vector.external_interface.NavMapQuadInfo*\xc8\x02\n\x12NavNodeContentType\x12\x14\n\x10NAV_NODE_UNKNOWN\x10\x00\x12\x1e\n\x1aNAV_NODE_CLEAR_OF_OBSTACLE\x10\x01\x12\x1b\n\x17NAV_NODE_CLEAR_OF_CLIFF\x10\x02\x12\x1a\n\x16NAV_NODE_OBSTACLE_CUBE\x10\x03\x12\x1f\n\x1bNAV_NODE_OBSTACLE_PROXIMITY\x10\x04\x12(\n$NAV_NODE_OBSTACLE_PROXIMITY_EXPLORED\x10\x05\x12\"\n\x1eNAV_NODE_OBSTACLE_UNRECOGNIZED\x10\x06\x12\x12\n\x0eNAV_NODE_CLIFF\x10\x07\x12\x1d\n\x19NAV_NODE_INTERESTING_EDGE\x10\x08\x12!\n\x1dNAV_NODE_NON_INTERESTING_EDGE\x10\tb\x06proto3') 17 | 18 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) 19 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'anki_vector.messaging.nav_map_pb2', globals()) 20 | if _descriptor._USE_C_DESCRIPTORS == False: 21 | 22 | DESCRIPTOR._options = None 23 | _NAVNODECONTENTTYPE._serialized_start=531 24 | _NAVNODECONTENTTYPE._serialized_end=859 25 | _NAVMAPQUADINFO._serialized_start=71 26 | _NAVMAPQUADINFO._serialized_end=191 27 | _NAVMAPINFO._serialized_start=193 28 | _NAVMAPINFO._serialized_end=316 29 | _NAVMAPFEEDREQUEST._serialized_start=318 30 | _NAVMAPFEEDREQUEST._serialized_end=356 31 | _NAVMAPFEEDRESPONSE._serialized_start=359 32 | _NAVMAPFEEDRESPONSE._serialized_end=528 33 | # @@protoc_insertion_point(module_scope) 34 | -------------------------------------------------------------------------------- /anki_vector/messaging/nav_map_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | import grpc 3 | 4 | -------------------------------------------------------------------------------- /anki_vector/messaging/protocol.py: -------------------------------------------------------------------------------- 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 | # http://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 | # pylint: skip-file 16 | 17 | """ 18 | Protobuf messages exposed to the Vector Python SDK 19 | """ 20 | import sys 21 | import inspect 22 | 23 | from .alexa_pb2 import * 24 | from .behavior_pb2 import * 25 | from .cube_pb2 import * 26 | from .messages_pb2 import * 27 | from .nav_map_pb2 import * 28 | from .response_status_pb2 import * 29 | from .settings_pb2 import * 30 | from .shared_pb2 import * 31 | from .external_interface_pb2 import * 32 | 33 | __all__ = [obj.__name__ for _, obj in inspect.getmembers(sys.modules[__name__]) if inspect.isclass(obj)] 34 | -------------------------------------------------------------------------------- /anki_vector/messaging/response_status.proto: -------------------------------------------------------------------------------- 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 | // http://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 | // Response status 16 | 17 | syntax = "proto3"; 18 | 19 | package Anki.Vector.external_interface; 20 | 21 | // A shared response message sent back as part of most requests. 22 | // This will indicate the generic state of the request. 23 | message ResponseStatus { 24 | enum StatusCode { 25 | UNKNOWN = 0; 26 | // The message has completed as expected. 27 | RESPONSE_RECEIVED = 1; 28 | // The message has been sent to the robot. 29 | REQUEST_PROCESSING = 2; 30 | // The message has been handled successfully at the interface level. 31 | OK = 3; 32 | // The user was not authorizied. 33 | FORBIDDEN = 100; 34 | // The requested attribute was not found. 35 | NOT_FOUND = 101; 36 | // Currently updating values from another call. 37 | ERROR_UPDATE_IN_PROGRESS = 102; 38 | } 39 | // The generic status code to give high-level insight into the progress of a given message. 40 | StatusCode code = 1; 41 | } 42 | -------------------------------------------------------------------------------- /anki_vector/messaging/response_status_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # source: anki_vector/messaging/response_status.proto 4 | """Generated protocol buffer code.""" 5 | from google.protobuf.internal import builder as _builder 6 | from google.protobuf import descriptor as _descriptor 7 | from google.protobuf import descriptor_pool as _descriptor_pool 8 | from google.protobuf import symbol_database as _symbol_database 9 | # @@protoc_insertion_point(imports) 10 | 11 | _sym_db = _symbol_database.Default() 12 | 13 | 14 | 15 | 16 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n+anki_vector/messaging/response_status.proto\x12\x1e\x41nki.Vector.external_interface\"\xe8\x01\n\x0eResponseStatus\x12G\n\x04\x63ode\x18\x01 \x01(\x0e\x32\x39.Anki.Vector.external_interface.ResponseStatus.StatusCode\"\x8c\x01\n\nStatusCode\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x15\n\x11RESPONSE_RECEIVED\x10\x01\x12\x16\n\x12REQUEST_PROCESSING\x10\x02\x12\x06\n\x02OK\x10\x03\x12\r\n\tFORBIDDEN\x10\x64\x12\r\n\tNOT_FOUND\x10\x65\x12\x1c\n\x18\x45RROR_UPDATE_IN_PROGRESS\x10\x66\x62\x06proto3') 17 | 18 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) 19 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'anki_vector.messaging.response_status_pb2', globals()) 20 | if _descriptor._USE_C_DESCRIPTORS == False: 21 | 22 | DESCRIPTOR._options = None 23 | _RESPONSESTATUS._serialized_start=80 24 | _RESPONSESTATUS._serialized_end=312 25 | _RESPONSESTATUS_STATUSCODE._serialized_start=172 26 | _RESPONSESTATUS_STATUSCODE._serialized_end=312 27 | # @@protoc_insertion_point(module_scope) 28 | -------------------------------------------------------------------------------- /anki_vector/messaging/response_status_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | import grpc 3 | 4 | -------------------------------------------------------------------------------- /anki_vector/messaging/settings.proto: -------------------------------------------------------------------------------- 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 | // http://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 | // Settings definition 16 | 17 | syntax = "proto3"; 18 | 19 | package Anki.Vector.external_interface; 20 | 21 | import "anki_vector/messaging/response_status.proto"; 22 | 23 | // Updated by wayne@codaris.com 24 | message RobotSettingsConfig { 25 | bool clock_24_hour = 1; 26 | EyeColor eye_color = 2; 27 | string default_location = 3; 28 | bool dist_is_metric = 4; 29 | string locale = 5; 30 | Volume master_volume = 6; 31 | bool temp_is_fahrenheit = 7; 32 | string time_zone = 8; 33 | ButtonWakeWord button_wakeword = 9; 34 | } 35 | 36 | 37 | message AccountSettingsConfig { 38 | oneof oneof_data_collection { 39 | bool data_collection = 1; 40 | } 41 | 42 | oneof oneof_app_locale { 43 | string app_locale = 2; 44 | } 45 | } 46 | 47 | message UserEntitlementsConfig { 48 | oneof oneof_kickstarter_eyes { 49 | bool kickstarter_eyes = 1; 50 | } 51 | } 52 | 53 | message Jdoc { 54 | uint64 doc_version = 1; 55 | uint64 fmt_version = 2; 56 | string client_metadata = 3; 57 | string json_doc = 4; 58 | } 59 | 60 | message NamedJdoc { 61 | JdocType jdoc_type = 1; 62 | Jdoc doc = 2; 63 | } 64 | 65 | message PullJdocsRequest { 66 | repeated JdocType jdoc_types = 1; 67 | } 68 | 69 | message PullJdocsResponse { 70 | ResponseStatus status = 1; 71 | repeated NamedJdoc named_jdocs = 2; 72 | } 73 | 74 | message UpdateSettingsRequest { 75 | RobotSettingsConfig settings = 1; 76 | } 77 | 78 | message UpdateSettingsResponse { 79 | ResponseStatus status = 1; 80 | ResultCode code = 2; 81 | Jdoc doc = 3; 82 | } 83 | 84 | message UpdateAccountSettingsRequest { 85 | AccountSettingsConfig account_settings = 1; 86 | } 87 | 88 | message UpdateAccountSettingsResponse { 89 | ResponseStatus status = 1; 90 | ResultCode code = 2; 91 | Jdoc doc = 3; 92 | } 93 | 94 | message UpdateUserEntitlementsRequest { 95 | UserEntitlementsConfig user_entitlements = 1; 96 | } 97 | 98 | message UpdateUserEntitlementsResponse { 99 | ResponseStatus status = 1; 100 | ResultCode code = 2; 101 | Jdoc doc = 3; 102 | } 103 | 104 | message JdocsChanged { 105 | repeated JdocType jdoc_types = 1; 106 | } 107 | 108 | enum ApiVersion { 109 | INVALID = 0; 110 | LATEST = 1; 111 | } 112 | 113 | enum Volume { 114 | MUTE = 0; 115 | LOW = 1; 116 | MEDIUM_LOW = 2; 117 | MEDIUM = 3; 118 | MEDIUM_HIGH = 4; 119 | HIGH = 5; 120 | } 121 | 122 | enum JdocType { 123 | ROBOT_SETTINGS = 0; 124 | ROBOT_LIFETIME_STATS = 1; 125 | ACCOUNT_SETTINGS = 2; 126 | USER_ENTITLEMENTS = 3; 127 | } 128 | 129 | enum JdocResolveMethod { 130 | PUSH_TO_CLOUD = 0; 131 | PULL_FROM_CLOUD = 1; 132 | } 133 | 134 | // RobotSetting enum values are not in all caps for historical reasons. 135 | // Changing that now would involve a format migration because we're now 136 | // saving robot settings jdocs in the cloud. 137 | enum RobotSetting { 138 | clock_24_hour = 0; 139 | eye_color = 1; 140 | default_location = 2; 141 | dist_is_metric = 3; 142 | locale = 4; 143 | master_volume = 5; 144 | temp_is_fahrenheit = 6; 145 | time_zone = 7; 146 | button_wakeword = 8; 147 | } 148 | 149 | enum EyeColor { 150 | TIP_OVER_TEAL = 0; 151 | OVERFIT_ORANGE = 1; 152 | UNCANNY_YELLOW = 2; 153 | NON_LINEAR_LIME = 3; 154 | SINGULARITY_SAPPHIRE = 4; 155 | FALSE_POSITIVE_PURPLE = 5; 156 | CONFUSION_MATRIX_GREEN = 6; 157 | } 158 | 159 | enum ButtonWakeWord { 160 | BUTTON_WAKEWORD_HEY_VECTOR = 0; 161 | BUTTON_WAKEWORD_ALEXA = 1; 162 | } 163 | 164 | enum AccountSetting { 165 | DATA_COLLECTION = 0; 166 | APP_LOCALE = 1; 167 | } 168 | 169 | enum UserEntitlement { 170 | KICKSTARTER_EYES = 0; 171 | } 172 | 173 | enum ResultCode { 174 | SETTINGS_ACCEPTED = 0; 175 | ERROR_UPDATE_IN_PROGRESS = 1; 176 | } 177 | -------------------------------------------------------------------------------- /anki_vector/messaging/settings_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | import grpc 3 | 4 | -------------------------------------------------------------------------------- /anki_vector/messaging/shared.proto: -------------------------------------------------------------------------------- 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 | // http://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 | // External interface for robot <-> app and robot <-> sdk communication 16 | 17 | syntax = "proto3"; 18 | 19 | package Anki.Vector.external_interface; 20 | 21 | import "anki_vector/messaging/behavior.proto"; 22 | import "anki_vector/messaging/cube.proto"; 23 | import "anki_vector/messaging/alexa.proto"; 24 | import "anki_vector/messaging/messages.proto"; 25 | import "anki_vector/messaging/settings.proto"; 26 | import "anki_vector/messaging/extensions.proto"; 27 | import "anki_vector/messaging/response_status.proto"; 28 | 29 | message ProtocolVersionRequest { 30 | int64 client_version = 1; 31 | int64 min_host_version = 2; 32 | } 33 | 34 | message ProtocolVersionResponse { 35 | enum Result { 36 | UNSUPPORTED = 0; 37 | SUCCESS = 1; 38 | } 39 | Result result = 1; 40 | int64 host_version = 2; 41 | } 42 | 43 | message ConnectionResponse { 44 | ResponseStatus status = 1; 45 | bool is_primary = 2; 46 | } 47 | 48 | // Messages originating from the engine 49 | message Event { 50 | oneof event_type { 51 | TimeStampedStatus time_stamped_status = 1; 52 | WakeWord wake_word = 3; 53 | AttentionTransfer attention_transfer = 4; 54 | RobotObservedFace robot_observed_face = 5; 55 | RobotChangedObservedFaceID robot_changed_observed_face_id = 6; 56 | ObjectEvent object_event = 7; 57 | StimulationInfo stimulation_info = 8; 58 | PhotoTaken photo_taken = 9; 59 | RobotState robot_state = 10; 60 | CubeBattery cube_battery = 11; 61 | KeepAlivePing keep_alive = 12; // Used by Vector to verify the connection is still alive. 62 | ConnectionResponse connection_response = 13; 63 | JdocsChanged jdocs_changed = 14; 64 | AlexaAuthEvent alexa_auth_event = 15; 65 | MirrorModeDisabled mirror_mode_disabled = 16; 66 | VisionModesAutoDisabled vision_modes_auto_disabled = 17; 67 | CheckUpdateStatusResponse check_update_status_response = 18; 68 | UserIntent user_intent = 19; 69 | RobotObservedMotion robot_observed_motion = 20; 70 | RobotErasedEnrolledFace robot_erased_enrolled_face = 21; 71 | RobotRenamedEnrolledFace robot_renamed_enrolled_face = 22; 72 | CameraSettingsUpdate camera_settings_update = 23; 73 | UnexpectedMovement unexpected_movement = 24; 74 | } 75 | } 76 | 77 | message FilterList { 78 | repeated string list = 1; 79 | } 80 | 81 | message EventRequest { 82 | oneof list_type { 83 | FilterList white_list = 1; 84 | FilterList black_list = 2; 85 | } 86 | string connection_id = 3; 87 | } 88 | 89 | message EventResponse { 90 | option (streamed) = true; 91 | ResponseStatus status = 1; 92 | Event event = 2; 93 | } 94 | 95 | message UserAuthenticationRequest { 96 | bytes user_session_id = 1; 97 | bytes client_name = 2; 98 | } 99 | 100 | message UserAuthenticationResponse { 101 | ResponseStatus status = 1; 102 | enum Code { 103 | UNAUTHORIZED = 0; 104 | AUTHORIZED = 1; 105 | } 106 | Code code = 2; 107 | bytes client_token_guid = 3; 108 | } 109 | 110 | -------------------------------------------------------------------------------- /anki_vector/messaging/shared_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | import grpc 3 | 4 | -------------------------------------------------------------------------------- /anki_vector/motors.py: -------------------------------------------------------------------------------- 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 | Control the motors of Vector. 17 | """ 18 | 19 | # __all__ should order by constants, event classes, other classes, functions. 20 | __all__ = ['MotorComponent'] 21 | 22 | from . import connection, util 23 | from .messaging import protocol 24 | 25 | 26 | class MotorComponent(util.Component): 27 | """Controls the low-level motor functions.""" 28 | @connection.on_connection_thread() 29 | async def set_wheel_motors(self, 30 | left_wheel_speed: float, 31 | right_wheel_speed: float, 32 | left_wheel_accel: float = 0.0, 33 | right_wheel_accel: float = 0.0): 34 | """Tell Vector to move his wheels / treads at a given speed. 35 | 36 | The wheels will continue to move at that speed until commanded to drive 37 | at a new speed, or if :meth:`stop_all_motors` is called. 38 | 39 | To unlock the wheel track, call `set_wheel_motors(0, 0)`. 40 | 41 | .. testcode:: 42 | 43 | import anki_vector 44 | import time 45 | 46 | with anki_vector.Robot() as robot: 47 | robot.motors.set_wheel_motors(25, 50) 48 | time.sleep(3.0) 49 | 50 | :param left_wheel_speed: Speed of the left tread (in millimeters per second). 51 | :param right_wheel_speed: Speed of the right tread (in millimeters per second). 52 | :param left_wheel_accel: Acceleration of left tread (in millimeters per second squared) 53 | ``None`` value defaults this to the same as l_wheel_speed. 54 | :param right_wheel_accel: Acceleration of right tread (in millimeters per second squared) 55 | ``None`` value defaults this to the same as r_wheel_speed. 56 | """ 57 | motors = protocol.DriveWheelsRequest(left_wheel_mmps=left_wheel_speed, 58 | right_wheel_mmps=right_wheel_speed, 59 | left_wheel_mmps2=left_wheel_accel, 60 | right_wheel_mmps2=right_wheel_accel) 61 | return await self.grpc_interface.DriveWheels(motors) 62 | 63 | @connection.on_connection_thread() 64 | async def set_head_motor(self, 65 | speed: float): 66 | """Tell Vector's head motor to move with a certain speed. 67 | 68 | Positive speed for up, negative speed for down. Measured in radians per second. 69 | 70 | To unlock the head track, call `set_head_motor(0)`. 71 | 72 | .. testcode:: 73 | 74 | import anki_vector 75 | 76 | with anki_vector.Robot() as robot: 77 | robot.motors.set_head_motor(-5.0) 78 | 79 | :param speed: Motor speed for Vector's head, measured in radians per second. 80 | """ 81 | set_head_request = protocol.MoveHeadRequest(speed_rad_per_sec=speed) 82 | return await self.grpc_interface.MoveHead(set_head_request) 83 | 84 | @connection.on_connection_thread() 85 | async def set_lift_motor(self, 86 | speed: float): 87 | """Tell Vector's lift motor to move with a certain speed. 88 | 89 | Positive speed for up, negative speed for down. Measured in radians per second. 90 | 91 | To unlock the lift track, call `set_lift_motor(0)`. 92 | 93 | .. testcode:: 94 | 95 | import anki_vector 96 | import time 97 | 98 | with anki_vector.Robot() as robot: 99 | robot.motors.set_lift_motor(-5.0) 100 | time.sleep(3.0) 101 | robot.motors.set_lift_motor(5.0) 102 | time.sleep(3.0) 103 | 104 | :param speed: Motor speed for Vector's lift, measured in radians per second. 105 | """ 106 | set_lift_request = protocol.MoveLiftRequest(speed_rad_per_sec=speed) 107 | return await self.grpc_interface.MoveLift(set_lift_request) 108 | 109 | @connection.on_connection_thread() 110 | async def stop_all_motors(self): 111 | """Tell Vector to stop all motors. 112 | 113 | .. testcode:: 114 | 115 | import anki_vector 116 | import time 117 | 118 | with anki_vector.Robot() as robot: 119 | robot.motors.set_wheel_motors(25, 50) 120 | 121 | # wait a short time to observe the motors moving 122 | time.sleep(0.5) 123 | 124 | robot.motors.stop_all_motors() 125 | """ 126 | stop_all_motors_request = protocol.StopAllMotorsRequest() 127 | return await self.grpc_interface.StopAllMotors(stop_all_motors_request) 128 | -------------------------------------------------------------------------------- /anki_vector/opengl/__init__.py: -------------------------------------------------------------------------------- 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 | # http://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 | """This module provides 3D classes for running the OpenGL Viewer. 16 | 17 | It should be launched in a separate process to allow Vector to run freely while 18 | the viewer is rendering. 19 | 20 | It uses PyOpenGL, a Python OpenGL 3D graphics library which is available on most 21 | platforms. It also depends on the Pillow library for image processing. 22 | 23 | Warning: 24 | This package requires Python to have the PyOpenGL package installed, along 25 | with an implementation of GLUT (OpenGL Utility Toolkit). 26 | 27 | To install the Python packages on Mac and Linux do ``python3 -m pip install --user "wirepod_vector_sdk[3dviewer]"`` 28 | 29 | To install the Python packages on Windows do ``py -3 -m pip install --user "wirepod_vector_sdk[3dviewer]"`` 30 | 31 | On Windows and Linux you must also install freeglut (macOS / OSX has one 32 | preinstalled). 33 | 34 | On Linux: ``sudo apt-get install freeglut3`` 35 | 36 | On Windows: Go to http://freeglut.sourceforge.net/ to get a ``freeglut.dll`` 37 | file. It's included in any of the `Windows binaries` downloads. Place the DLL 38 | next to your Python script, or install it somewhere in your PATH to allow any 39 | script to use it." 40 | """ 41 | 42 | import multiprocessing as mp 43 | 44 | from . import opengl_viewer 45 | 46 | 47 | def main(close_event: mp.Event, 48 | input_intent_queue: mp.Queue, 49 | nav_map_queue: mp.Queue, 50 | world_frame_queue: mp.Queue, 51 | extra_render_function_queue: mp.Queue, 52 | user_data_queue: mp.Queue, 53 | show_viewer_controls: bool = True): 54 | """Run the 3D Viewer window. This is intended to run on a background process. 55 | 56 | .. code-block:: python 57 | 58 | import multiprocessing as mp 59 | 60 | from anki_vector import opengl 61 | 62 | ctx = mp.get_context('spawn') 63 | close_event = ctx.Event() 64 | input_intent_queue = ctx.Queue(maxsize=10) 65 | nav_map_queue = ctx.Queue(maxsize=10) 66 | world_frame_queue = ctx.Queue(maxsize=10) 67 | extra_render_function_queue = ctx.Queue(maxsize=1) 68 | user_data_queue = ctx.Queue() 69 | process = ctx.Process(target=opengl.main, 70 | args=(close_event, 71 | input_intent_queue, 72 | nav_map_queue, 73 | world_frame_queue, 74 | extra_render_function_queue, 75 | user_data_queue), 76 | daemon=True) 77 | process.start() 78 | 79 | :param close_event: Used to notify each process when done rendering. 80 | :type close_event: multiprocessing.Event 81 | :param input_intent_queue: Sends key commands from the 3D viewer process to the main process. 82 | :type input_intent_queue: multiprocessing.Queue 83 | :param nav_map_queue: Updates the 3D viewer process with the latest navigation map. 84 | :type nav_map_queue: multiprocessing.Queue 85 | :param world_frame_queue: Provides the 3D viewer with details about the world. 86 | :type world_frame_queue: multiprocessing.Queue 87 | :param extra_render_function_queue: Functions to be executed in the 3D viewer process. 88 | :type extra_render_function_queue: multiprocessing.Queue 89 | :param user_data_queue: A queue that may be used outside the SDK to pass information to the viewer process. 90 | May be used by ``extra_render_function_queue`` functions. 91 | :param show_viewer_controls: Specifies whether to draw controls on the view. 92 | """ 93 | viewer = opengl_viewer.OpenGLViewer(close_event, 94 | input_intent_queue, 95 | nav_map_queue, 96 | world_frame_queue, 97 | extra_render_function_queue, 98 | user_data_queue, 99 | show_viewer_controls=show_viewer_controls) 100 | viewer.run() 101 | 102 | 103 | __all__ = ['main'] 104 | -------------------------------------------------------------------------------- /anki_vector/opengl/assets/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Anki, Inc. Image and 3D Model License Agreement Version 1.1 (last updated November 15, 2018) 2 | 3 | This Image and 3D Model License Agreement (this "Agreement") governs the terms and conditions of your access to and use of Licensed Materials (as defined below), and is made between you, as an individual or entity ("you"), and Anki, Inc. ("we," "us" or "Licensor"). You accept and agree to be bound by this Agreement by your access to or use of any of the Licensed Materials. 4 | 5 | The "Licensed Materials" are the digital images, and 3D models, that we make available to you from time to time in connection with this Agreement. 6 | 7 | 1. License. Subject to the terms and conditions of this Agreement, we hereby grant you a limited, revocable, worldwide, fully-paid, royalty free, non-exclusive, non-transferable copyright license during the term of this Agreement to access, copy, display, perform, modify the size of, and distribute, in any of the Licensed Materials, in each case: (A) solely in connection with your use of the Vector SDK in accordance with our separate SDK license agreement(s) or the applicable Anki hardware products (e.g. Vector) and/or the Vector App, and (B) only provided that you comply with the Anki Terms of Use at www.anki.com/terms and any other terms that may apply to the Vector device and/or Vector mobile application and that we may from time to time modify. Licensee may not sublicense any of the foregoing rights, except for the right to access, copy, display perform and distribute the Licensed Materials only in connection with the SDK in an app created by the Licensee. For clarity, this license does not include the right to commercially distribute the Licensed Materials in print form. 8 | 9 | 2. Reservation. Licensor (or its suppliers) owns and retains all right, title, and interest in and to each of the Licensed Materials worldwide including, but not limited to, ownership of all copyrights and other intellectual property rights therein. We reserve all rights not explicitly licensed in this Agreement. 10 | 11 | 3. DISCLAIMER OF WARRANTY AND LIMITATION OF LIABILITY. THE LICENSED MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NONINFRINGEMENT. IN NO EVENT WILL LICENSOR BE LIABLE TO YOU OR TO ANY THIRD PARTY FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, OR LOST REVENUE, SAVINGS OR PROFITS, WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE) OR OTHERWISE, ARISING FROM OR IN CONNECTION WITH ANY OF THE LICENSED MATERIALS, WHETHER OR NOT THAT PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | 13 | 4. Indemnification. You will defend, indemnify and hold harmless Licensor and its officers, directors, shareholders, employees, and agents from any loss, liability, cost or expense, including attorneys' fees ("Liabilities") that arises from any claim, action or proceeding in connection with your use of the Licensed Materials or your breach of this Agreement. You shall have control of the defense and all related settlement negotiations for such claim, action or proceeding; provided that we shall have the right to consent to any settlement or entry of judgment, such consent not to be unreasonably withheld, and we may participate in such defense using our own counsel at our own expense. 14 | 15 | 5. Termination. You may terminate this Agreement at any time by deleting or destroying all copies of the Licensed Materials that you possess or control. We may terminate this Agreement and/or your license to any or all of the Licensed Materials at any time without prior notice to you. In case of termination, you must cease all access and use of, and delete or destroy, all copies of the Licensed Materials that you possess or control. Sections 2 through 8 of this Agreement will survive termination of this Agreement. 16 | 17 | 6. Modifications to this Agreement and Licensed Materials. We may amend this Agreement at any time by posting an amended version online and/or sending information regarding the amendment to your email address of record with us. You shall be deemed to have accepted such amendments by continuing to access and/or use any Licensed Materials after such amendments have been posted or information regarding such amendments has been sent to you. If you do not agree to any of such changes, you may terminate this Agreement and immediately cease all access to and use of Licensed Materials. You agree that such termination will be your exclusive remedy in such event. No other waiver or modification of this Agreement shall be valid unless in writing and signed by both parties. We also reserve the right at any time and from time to time to modify or discontinue all or any portion of any Licensed Materials without notice to you. We shall not be liable to you or any third party should we exercise such rights. 18 | 19 | 7. Assignment. You may not assign this Agreement, in whole or in part, without our prior written consent, and any attempt by you to assign this Agreement without such consent shall be void. Subject to the foregoing, this Agreement shall benefit and bind both parties, and their successors and permitted assigns. 20 | 21 | 8. General. You shall comply with all laws, rules and regulations applicable to your activities under this Agreement. This Agreement shall be governed by and construed in accordance with the laws of the State of California, U.S.A., except for its conflicts of laws principles. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. This Agreement will not be construed to create or imply any partnership, agency or joint venture between the parties. If any provision of this Agreement is found illegal or unenforceable, it will be enforced to the maximum extent permissible, and the legality and enforceability of the other provisions of this Agreement will not be affected. This Agreement is the complete agreement between the parties with respect to its subject matter, and supersedes any prior agreements and communications (both written and oral) regarding such subject matter. 22 | -------------------------------------------------------------------------------- /anki_vector/opengl/assets/cube.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/anki_vector/opengl/assets/cube.jpg -------------------------------------------------------------------------------- /anki_vector/opengl/assets/cube.mtl: -------------------------------------------------------------------------------- 1 | newmtl cube_mtl 2 | map_Kd cube.jpg 3 | illum 4 4 | Kd 0.15 0.15 0.15 5 | Ka 0.15 0.15 0.15 6 | Tf 1.00 1.00 1.00 7 | Ni 1.00 8 | Ks 0.99 0.99 0.99 9 | Ns 10 10 | -------------------------------------------------------------------------------- /anki_vector/opengl/assets/vector.mtl: -------------------------------------------------------------------------------- 1 | # rim around the screen 2 | newmtl ScreenOp_matSG 3 | illum 4 4 | Kd 0.00 0.00 0.00 0.2 5 | Ka 0.00 0.00 0.00 0.2 6 | Tf 1.00 1.00 1.00 7 | Ni 1.00 8 | Ks 0.08 0.08 0.08 0.2 9 | Ns 10 10 | 11 | # glass screen 12 | newmtl anisotropic1SG 13 | illum 4 14 | Kd 0.00 0.00 0.00 0.2 15 | Ka 0.00 0.00 0.00 0.2 16 | Tf 0.09 0.09 0.09 17 | Ni 1.00 18 | Ks 0.1 0.1 0.1 0.2 19 | Ns 10 20 | 21 | # head, arms+fork, wheels (but not treads) 22 | newmtl blinn2SG 23 | illum 4 24 | Kd 0.15 0.15 0.15 25 | Ka 0.00 0.00 0.00 26 | Tf 1.00 1.00 1.00 27 | Ni 1.00 28 | Ks 0.50 0.50 0.50 29 | Ns 10 30 | 31 | # Treads 32 | newmtl blinn3SG 33 | illum 4 34 | Kd 0.10 0.10 0.10 35 | Ka 0.00 0.00 0.00 36 | Tf 1.00 1.00 1.00 37 | Ni 1.00 38 | Ks 0.5 0.5 0.5 39 | Ns 10 40 | 41 | # Body and wheel-spacers 42 | newmtl blinn4SG 43 | illum 4 44 | Kd 0.15 0.15 0.15 45 | Ka 0.00 0.00 0.00 46 | Tf 1.00 1.00 1.00 47 | Ni 1.00 48 | Ks 0.50 0.50 0.50 49 | Ns 10 50 | 51 | # Eyelids 52 | newmtl lambert2SG 53 | illum 4 54 | Kd 0.00 0.00 0.00 55 | Ka 0.00 0.00 0.00 56 | Tf 1.00 1.00 1.00 57 | Ni 1.00 58 | Ks 0.50 0.50 0.50 59 | Ns 10 60 | 61 | # eyes 62 | newmtl shadingMap1SG 63 | illum 4 64 | Kd 0.00 0.60 1.00 65 | Ka 0.00 0.60 1.00 66 | Tf 1.00 1.00 1.00 67 | Ni 0.00 68 | -------------------------------------------------------------------------------- /anki_vector/photos.py: -------------------------------------------------------------------------------- 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 | Photo related classes, functions, events and values. 17 | """ 18 | 19 | # __all__ should order by constants, event classes, other classes, functions. 20 | __all__ = ["PhotographComponent"] 21 | 22 | import concurrent 23 | from typing import List 24 | 25 | from . import connection, util 26 | from .messaging import protocol 27 | 28 | 29 | class PhotographComponent(util.Component): 30 | """Access the photos on Vector. 31 | 32 | .. testcode:: 33 | 34 | import anki_vector 35 | import io 36 | from PIL import Image 37 | 38 | with anki_vector.Robot() as robot: 39 | for photo_info in robot.photos.photo_info: 40 | print(f"Opening photo {photo_info.photo_id}") 41 | photo = robot.photos.get_photo(photo_info.photo_id) 42 | image = Image.open(io.BytesIO(photo.image)) 43 | image.show() 44 | 45 | :param anki_vector.Robot robot: A reference to an instance of the Robot class. Used to make rpc calls. 46 | """ 47 | 48 | def __init__(self, robot): 49 | super().__init__(robot) 50 | self._photo_info: List[protocol.PhotoInfo] = [] 51 | 52 | @property 53 | def photo_info(self) -> List[protocol.PhotoInfo]: 54 | """The information about what photos are stored on Vector. 55 | 56 | If the photo info hasn't been loaded yet, accessing this property will request it from the robot. 57 | 58 | .. testcode:: 59 | 60 | import anki_vector 61 | 62 | with anki_vector.Robot() as robot: 63 | for photo_info in robot.photos.photo_info: 64 | print(f"photo_info.photo_id: {photo_info.photo_id}") # the id to use to grab a photo from the robot 65 | print(f"photo_info.timestamp_utc: {photo_info.timestamp_utc}") # utc timestamp of when the photo was taken (according to the robot) 66 | """ 67 | if not self._photo_info: 68 | self.logger.debug("Photo list was empty. Lazy-loading photo list now.") 69 | result = self.load_photo_info() 70 | if isinstance(result, concurrent.futures.Future): 71 | result.result() 72 | return self._photo_info 73 | 74 | @connection.on_connection_thread() 75 | async def load_photo_info(self) -> protocol.PhotosInfoResponse: 76 | """Request the photo information from the robot. 77 | 78 | .. testcode:: 79 | 80 | import anki_vector 81 | 82 | with anki_vector.Robot() as robot: 83 | photo_info = robot.photos.load_photo_info() 84 | print(f"photo_info: {photo_info}") 85 | 86 | :return: UTC timestamp of the photo and additional data. 87 | """ 88 | req = protocol.PhotosInfoRequest() 89 | result = await self.grpc_interface.PhotosInfo(req) 90 | self._photo_info = result.photo_infos 91 | return result 92 | 93 | @connection.on_connection_thread(log_messaging=False) 94 | async def get_photo(self, photo_id: int) -> protocol.PhotoResponse: 95 | """Download a full-resolution photo from the robot's storage. 96 | 97 | .. testcode:: 98 | 99 | import anki_vector 100 | import io 101 | from PIL import Image 102 | 103 | with anki_vector.Robot() as robot: 104 | for photo_info in robot.photos.photo_info: 105 | print(f"Opening photo {photo_info.photo_id}") 106 | photo = robot.photos.get_photo(photo_info.photo_id) 107 | image = Image.open(io.BytesIO(photo.image)) 108 | image.show() 109 | 110 | :param photo_id: The id of the photo to download. It's recommended to get this 111 | value from the photo_info list first. 112 | 113 | :return: A response containing all of the photo bytes which may be rendered using 114 | another library (like :mod:`PIL`) 115 | """ 116 | req = protocol.PhotoRequest(photo_id=photo_id) 117 | return await self.grpc_interface.Photo(req) 118 | 119 | @connection.on_connection_thread(log_messaging=False) 120 | async def get_thumbnail(self, photo_id: int) -> protocol.ThumbnailResponse: 121 | """Download a thumbnail of a given photo from the robot's storage. 122 | 123 | You may use this function to pull all of the images off the robot in a smaller format, and 124 | then determine which one to download as full resolution. 125 | 126 | .. testcode:: 127 | 128 | import anki_vector 129 | from PIL import Image 130 | import io 131 | 132 | with anki_vector.Robot() as robot: 133 | for photo_info in robot.photos.photo_info: 134 | photo = robot.photos.get_thumbnail(photo_info.photo_id) 135 | image = Image.open(io.BytesIO(photo.image)) 136 | image.show() 137 | 138 | :param photo_id: The id of the thumbnail to download. It's recommended to get this 139 | value from the photo_info list first. 140 | 141 | :return: A response containing all of the thumbnail bytes which may be rendered using 142 | another library (like :mod:`PIL`) 143 | """ 144 | req = protocol.ThumbnailRequest(photo_id=photo_id) 145 | return await self.grpc_interface.Thumbnail(req) 146 | -------------------------------------------------------------------------------- /anki_vector/reserve_control/__main__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2019 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """ Reserve SDK Behavior Control 18 | 19 | While this script runs, other SDK scripts may run and Vector will not perform most 20 | default behaviors before/after they complete. This will keep Vector still. 21 | 22 | High priority behaviors like returning to the charger in a low battery situation, 23 | or retreating from a cliff will still take precedence. 24 | """ 25 | 26 | from anki_vector import behavior, util 27 | 28 | 29 | def hold_control(): 30 | args = util.parse_command_args() 31 | with behavior.ReserveBehaviorControl(args.serial): 32 | input("Vector behavior control reserved for SDK. Hit 'Enter' to release control.") 33 | 34 | 35 | if __name__ == "__main__": 36 | hold_control() 37 | -------------------------------------------------------------------------------- /anki_vector/touch.py: -------------------------------------------------------------------------------- 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 | Support for Vector's touch sensor. 17 | 18 | The robot will forward a raw sensor reading representing the capacitance detected 19 | on its back sensor. Accompanied with this value is a true/false flag that takes into 20 | account other aspects of the robot's state to evaluate whether the robot thinks it is 21 | being touched or not. This flag is the same value used internally for petting detection. 22 | """ 23 | 24 | # __all__ should order by constants, event classes, other classes, functions. 25 | __all__ = ["TouchComponent", "TouchSensorData"] 26 | 27 | from . import util 28 | from .events import Events 29 | from .messaging import protocol 30 | 31 | 32 | class TouchSensorData: 33 | """A touch sample from the capacitive touch sensor, accompanied with the robot's 34 | conclusion on whether this is considered a valid touch. 35 | """ 36 | 37 | def __init__(self, proto_data: protocol.TouchData): 38 | self._raw_touch_value = proto_data.raw_touch_value 39 | self._is_being_touched = proto_data.is_being_touched 40 | 41 | @property 42 | def raw_touch_value(self) -> int: 43 | """The detected sensitivity from the touch sensor. 44 | 45 | This will not map to a constant raw value, as it may be impacted by various 46 | environmental factors such as whether the robot is on its charger, being held, humidity, etc. 47 | 48 | .. testcode:: 49 | 50 | import anki_vector 51 | 52 | with anki_vector.Robot() as robot: 53 | touch_data = robot.touch.last_sensor_reading 54 | if touch_data is not None: 55 | raw_touch_value = touch_data.raw_touch_value 56 | """ 57 | return self._raw_touch_value 58 | 59 | @property 60 | def is_being_touched(self) -> bool: 61 | """The robot's conclusion on whether the current value is considered 62 | a valid touch. 63 | 64 | .. testcode:: 65 | 66 | import anki_vector 67 | 68 | with anki_vector.Robot() as robot: 69 | touch_data = robot.touch.last_sensor_reading 70 | if touch_data is not None: 71 | is_being_touched = touch_data.is_being_touched 72 | """ 73 | return self._is_being_touched 74 | 75 | 76 | class TouchComponent(util.Component): 77 | """Maintains the most recent touch sensor data 78 | 79 | This will be updated with every broadcast RobotState, and can be queried at any time. 80 | 81 | .. testcode:: 82 | 83 | import anki_vector 84 | 85 | with anki_vector.Robot() as robot: 86 | touch_data = robot.touch.last_sensor_reading 87 | if touch_data is not None: 88 | print('Touch sensor value: {0}, is being touched: {1}'.format(touch_data.raw_touch_value, touch_data.is_being_touched)) 89 | """ 90 | 91 | def __init__(self, robot): 92 | super().__init__(robot) 93 | self._last_sensor_reading = None 94 | 95 | # Subscribe to a callback that updates the robot's local properties - which includes touch data. 96 | self._robot.events.subscribe(self._on_robot_state, 97 | Events.robot_state, 98 | _on_connection_thread=True) 99 | 100 | def close(self): 101 | """Closing the touch component will unsubscribe from robot state updates.""" 102 | self._robot.events.unsubscribe(self._on_robot_state, 103 | Events.robot_state) 104 | 105 | @property 106 | def last_sensor_reading(self) -> TouchSensorData: 107 | """:class:`anki_vector.touch.TouchSensorData`: The last reported sensor data. 108 | 109 | .. testcode:: 110 | 111 | import anki_vector 112 | 113 | with anki_vector.Robot() as robot: 114 | touch_data = robot.touch.last_sensor_reading 115 | """ 116 | return self._last_sensor_reading 117 | 118 | def _on_robot_state(self, _robot, _event_type, msg): 119 | self._last_sensor_reading = TouchSensorData(msg.touch_data) 120 | -------------------------------------------------------------------------------- /anki_vector/version.py: -------------------------------------------------------------------------------- 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 | __version__ = "0.8.1" 16 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Vector Python SDK Documentation 2 | 3 | The scripts and source here will build the documentation for the SDK. 4 | 5 | The majority of the documentation is built from inline text included in the SDK Python source, 6 | so changes to the source code will be reflected in docs builds. 7 | 8 | To update and build the docs, follow the steps below. 9 | 10 | ## Installing sphinx 11 | 12 | The 13 | [Sphinx Documetation Generator](https://www.sphinx-doc.org/en/master/) 14 | is used to build the docs. You'll need to have it installed on your 15 | system with `pip install -r requirements.txt` using the 16 | `requirements.txt` file in this directory and not the main project directory. 17 | 18 | ## Updating the Docs 19 | 20 | There are a few files that are not automatically generated and reside in `source`. For example, 21 | the top-level list of API elements are in ```source/api.rst``` and will need to be updated whenever 22 | a new user-facing class is added to the SDK. 23 | 24 | ## Building the Docs 25 | 26 | The makefile can be used to build different documentation targets. The usual usage is to make 27 | the html version of the docs. 28 | 29 | ```bash 30 | make clean 31 | make html 32 | ``` 33 | 34 | You will now have an offline copy of the documetation that can be 35 | accessed by opening `.build/html/index.html` 36 | -------------------------------------------------------------------------------- /docs/ext/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/ext/__init__.py -------------------------------------------------------------------------------- /docs/ext/custopoleon/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Due to deficiencies in the design of Sphinx, two modules cannot both 3 | observe the same event. Napaleon hooks the autodoc-skip-member event 4 | to determine which members to show.. We want to use the same thing 5 | to special case the AnimTriggers and BehaviorTypes classes so that 6 | their undocumented members show up in the docs. 7 | 8 | As a workaround this module monkey patches Napoleon to wrap their 9 | autodoc-skip-member implementation and special case the response for 10 | our classes. 11 | """ 12 | 13 | 14 | import sphinx.ext.napoleon 15 | 16 | 17 | _org_skip_member = sphinx.ext.napoleon._skip_member 18 | 19 | # TODO: determine if this is still necessary 20 | def _skip_member(app, what, name, obj, skip, options): 21 | clsname = obj.__class__.__name__ 22 | if clsname in ('_AnimTrigger', '_BehaviorType'): 23 | return False 24 | if name in ('GatewayWrapper', 'FindInitializationErrors', 'IsInitialized', 'SetInParent', 'WhichOneof'): 25 | return True 26 | return _org_skip_member(app, what, name, obj, skip, options) 27 | 28 | sphinx.ext.napoleon._skip_member = _skip_member 29 | 30 | def setup(app): 31 | return sphinx.ext.napoleon.setup(app) 32 | 33 | -------------------------------------------------------------------------------- /docs/ext/verlink.py: -------------------------------------------------------------------------------- 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 | """Generate versioned links for example files. 16 | 17 | This extension adds a new role to generate links to the correct version 18 | of files referenced by the documentation. 19 | 20 | It substitutes the string "0.0.0" with a version number defined by the 21 | "verlink_version" configuration value. 22 | 23 | Roles can optionally include text to use for the link, else it defaults 24 | to the supplied filename. the URL is prefixed with the 25 | "verlink_base_url" value to make a complete URL. 26 | 27 | For example, if verlink_base_url="https://example.com/files/0.0.0/" 28 | and verlink_version="1.2.3" then 29 | 30 | :verlink:`examples-0.0.0.zip` will display "examples-1.2.3.zip" and link 31 | to https:/example.com/files/1.2.3/examples-1.2.3.zip 32 | 33 | :verlink:`Examples for 0.0.0 ` will display 34 | "Examples for 1.2.3" and link to https:/example.com/files/1.2.3/examples-1.2.3.zip 35 | """ 36 | 37 | 38 | from docutils import nodes, utils 39 | 40 | import sphinx 41 | from sphinx.util.nodes import split_explicit_title 42 | 43 | 44 | def replace_version(app, str): 45 | try: 46 | ver = app.config.verlink_version 47 | except AttributeError as err: 48 | raise ValueError("verlink_version configuration value is not set") 49 | return str.replace('0.0.0', ver) 50 | 51 | 52 | def verlink_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): 53 | app = inliner.document.settings.env.app 54 | try: 55 | base_url = app.config.verlink_base_url 56 | except AttributeError as err: 57 | raise ValueError("verlink_base_url configuration value is not set") 58 | 59 | text = utils.unescape(text) 60 | has_explicit_title, title, fn = split_explicit_title(text) 61 | full_url = replace_version(app, base_url + fn) 62 | if not has_explicit_title: 63 | title = fn 64 | title = replace_version(app, title) 65 | pnode = nodes.reference(title, title, internal=False, refuri=full_url) 66 | return [pnode], [] 67 | 68 | 69 | def setup(app): 70 | app.add_role('verlink', verlink_role) 71 | app.add_config_value('verlink_base_url', None, {}) 72 | app.add_config_value('verlink_version', None, {}) 73 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx 2 | sphinx-autodoc-typehints 3 | sphinx_rtd_theme 4 | -------------------------------------------------------------------------------- /docs/source/.gitignore: -------------------------------------------------------------------------------- 1 | generated/ 2 | -------------------------------------------------------------------------------- /docs/source/_static/.gitignore: -------------------------------------------------------------------------------- 1 | # No files should be checked into this directory 2 | * 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /docs/source/_templates/layout.html: -------------------------------------------------------------------------------- 1 | {% extends "!layout.html" %} 2 | {% block extrahead %} 3 | 68 | 81 | 82 | {{ super() }} 83 | {% endblock %} 84 | -------------------------------------------------------------------------------- /docs/source/advanced-tips.rst: -------------------------------------------------------------------------------- 1 | .. _advanced-tips: 2 | 3 | ############# 4 | Advanced Tips 5 | ############# 6 | 7 | .. _moving_between_wifi: 8 | 9 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 10 | Moving Vector between WiFi networks 11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 12 | 13 | When you move Vector from one WiFi network to another, 14 | or if your Vector's IP changes, the SDK will need to determine Vector's new IP address. 15 | There are two ways to accomplish this. 16 | 17 | **************************** 18 | 1. Automatic: mDNS Discovery 19 | **************************** 20 | 21 | The SDK will automatically discover your Vector, even on a new WiFi network, 22 | when you connect as follows:: 23 | 24 | import anki_vector 25 | 26 | with anki_vector.Robot(name="Vector-A1B2") as robot: 27 | # The sdk will try to connect to 'Vector A1B2', 28 | # even if its IP address has changed. 29 | pass 30 | 31 | You will need to install the ``zeroconf`` package to use this feature:: 32 | 33 | pip3 install --user zeroconf 34 | 35 | ******************************* 36 | 2. Manual: Update Configuration 37 | ******************************* 38 | 39 | Alternatively, you can manually make changes to your SDK setup. To assist in this migration, the ``anki_vector.configure`` 40 | executable submodule provides a ``-u`` parameter to quickly reconnect to Vector. 41 | 42 | To update your connection, you will need to find the IP address on 43 | Vector's face, and the serial number of the robot you are updating. 44 | Then from your terminal run:: 45 | 46 | python3 -m anki_vector.configure -u "" -s "" 47 | 48 | 49 | ^^^^^^^^^^^^^^^^^^^^^^ 50 | Using multiple Vectors 51 | ^^^^^^^^^^^^^^^^^^^^^^ 52 | 53 | If your device is configured to use more than one robot, you can specify 54 | which robot you want to use by passing its serial number as a parameter 55 | to the Robot constructor:: 56 | 57 | 58 | with anki_vector.Robot("00e20142") as robot: 59 | robot.anim.play_animation_trigger("GreetAfterLongTime") 60 | 61 | 62 | Alternatively, you can pass a ``--serial`` flag on the command 63 | line, and ``anki_vector.util.parse_command_args`` will parse out 64 | the serial number:: 65 | 66 | ./01_hello_world.py --serial 00e20142 67 | 68 | 69 | ^^^^^^^^^^^^^^^^^^^^^ 70 | Set ANKI_ROBOT_SERIAL 71 | ^^^^^^^^^^^^^^^^^^^^^ 72 | 73 | In order to avoid entering Vector's serial number for each program run, 74 | you can create environment variable ``ANKI_ROBOT_SERIAL`` 75 | and set it to Vector's serial number:: 76 | 77 | export ANKI_ROBOT_SERIAL=00e20100 78 | 79 | 80 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 81 | Set ANKI_ROBOT_HOST and VECTOR_ROBOT_NAME 82 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 83 | 84 | When running the ``anki_vector.configure`` executable submodule, you must provide Vector's ip and name. 85 | To avoid typing these in, you can instead create environment variables 86 | ANKI_ROBOT_HOST and VECTOR_ROBOT_NAME. Then ``anki_vector.configure`` will automatically pick 87 | up those settings:: 88 | 89 | export ANKI_ROBOT_HOST="192.168.42.42" 90 | export VECTOR_ROBOT_NAME=Vector-A1B2 91 | 92 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 93 | Keeping Vector Still Between SDK Scripts 94 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 95 | 96 | Vector can be controlled so that (like Cozmo) he will not move between SDK scripts. There are three options for entering this mode of operation: 97 | 98 | * Control can be reserved from the command prompt: ``python3 -m anki_vector.reserve_control`` Vector will remain still between SDK scripts until the script/process is exited. 99 | * There are OS-specific scripts (Mac/Win) in the ``examples/scripts/`` folder that can be double-clicked to more easily reserve behavior control. The script will open in a new window; closing the window or otherwise stopping the script will release control back to the built-in robot behaviors. 100 | * A single Python file can explicitly reserve control using the ``ReserveBehaviorControl`` object. Consult the ``anki_vector.connection`` `documentation `_ for more information. 101 | 102 | While normal robot behaviors are suppressed, Vector may look 'broken'. Closing the SDK scripts, disconnecting from the 103 | robot, or restarting the robot will all release behavior control. 104 | 105 | 106 | 107 | ---- 108 | 109 | Anki, modified by kercre123 110 | 111 | -------------------------------------------------------------------------------- /docs/source/api.rst: -------------------------------------------------------------------------------- 1 | The API 2 | ======= 3 | 4 | 5 | .. autosummary:: 6 | :nosignatures: 7 | :toctree: generated 8 | 9 | anki_vector 10 | anki_vector.animation 11 | anki_vector.annotate 12 | anki_vector.audio 13 | anki_vector.behavior 14 | anki_vector.camera 15 | anki_vector.camera_viewer 16 | anki_vector.color 17 | anki_vector.connection 18 | anki_vector.events 19 | anki_vector.exceptions 20 | anki_vector.faces 21 | anki_vector.lights 22 | anki_vector.mdns 23 | anki_vector.messaging 24 | anki_vector.motors 25 | anki_vector.nav_map 26 | anki_vector.objects 27 | anki_vector.opengl 28 | anki_vector.opengl.opengl 29 | anki_vector.opengl.opengl_vector 30 | anki_vector.opengl.opengl_viewer 31 | anki_vector.photos 32 | anki_vector.proximity 33 | anki_vector.robot 34 | anki_vector.screen 35 | anki_vector.status 36 | anki_vector.touch 37 | anki_vector.user_intent 38 | anki_vector.util 39 | anki_vector.viewer 40 | anki_vector.vision 41 | anki_vector.world 42 | 43 | .. 44 | 45 | For documentation about protobuf objects, please see :doc:`the protobuf documentation `. 46 | 47 | ---- 48 | 49 | Anki, modified by kercre123 50 | -------------------------------------------------------------------------------- /docs/source/downloads.rst: -------------------------------------------------------------------------------- 1 | ######### 2 | Downloads 3 | ######### 4 | 5 | ------------ 6 | SDK Examples 7 | ------------ 8 | 9 | Download Python example scripts that use the Vector SDK. 10 | 11 | :verlink:`macOS/Linux SDK Examples ` 12 | 13 | :verlink:`Windows SDK Examples ` 14 | 15 | ------ 16 | GitHub 17 | ------ 18 | 19 | Clone, fork, or report issues on the `GitHub wirepod_vector_sdk repository `_. 20 | 21 | ---- 22 | 23 | Anki, modified by kercre123 24 | -------------------------------------------------------------------------------- /docs/source/getstarted.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Getting Started With the Vector SDK 3 | =================================== 4 | 5 | To make sure you get the best experience possible out of the SDK, please ensure you have followed the steps in the :doc:`Initial Setup `. 6 | 7 | --------------------- 8 | DDL Discord 9 | --------------------- 10 | 11 | If you'd like to, visit the `Unofficial DDL Discord `_ where you can: 12 | 13 | * Get assistance with your code 14 | 15 | * Hear about upcoming SDK additions 16 | 17 | * Share your work 18 | 19 | * Join discussion about the SDK 20 | 21 | * Be a part of the Vector Community! 22 | 23 | 24 | ------------- 25 | Prerequisites 26 | ------------- 27 | 28 | * You have completed the Installation steps, found here: :ref:`initial` 29 | * You have downloaded and extracted the example programs, found here: :doc:`Downloads ` 30 | * Vector is set up with wire-pod. 31 | * Vector is connected to the same network as your computer. 32 | * You can see Vector's eyes on his screen. 33 | 34 | ------------------- 35 | Starting Up the SDK 36 | ------------------- 37 | 38 | On the computer, open Terminal (macOS/Linux) or Command Prompt (Windows) and type ``cd anki_vector_sdk_examples``, where *anki_vector_sdk_examples* is the directory you extracted the examples into, and press **Enter**. 39 | 40 | ---------------- 41 | Example Program 42 | ---------------- 43 | 44 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 45 | First Steps - "Hello, World!" 46 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 47 | 48 | Let's test your new setup by running a very simple program. This program instructs Vector to say "Hello, World!" - a perfect way to introduce him and you to the world of programming. 49 | 50 | """"""""""" 51 | The Program 52 | """"""""""" 53 | 54 | 1. Run the program using the same Terminal (macOS/Linux) / Command Prompt (Windows) window mentioned above. First, change to the ``tutorials`` sub-directory:: 55 | 56 | cd tutorials 57 | 58 | Then, run the program. 59 | 60 | a. For macOS and Ubuntu 22.04 systems, type the following and press **Enter**:: 61 | 62 | ./01_hello_world.py 63 | 64 | The same can also be achieved with:: 65 | 66 | python3 01_hello_world.py 67 | 68 | b. For Windows systems, type the following and press **Enter**:: 69 | 70 | py 01_hello_world.py 71 | 72 | 73 | 2. If done correctly, Vector will say "Hello, World!" 74 | 75 | .. warning:: If Vector does not perform as expected, look at the first Terminal window and make sure no error messages appeared. If you continue to have issues, please seek help in the Forums. 76 | 77 | .. note:: If you have more than one Vector configured on your device, you can pass the serial number of the Vector you want to use at the command line: 78 | ``./01_hello_world.py --serial {robot_serial_number}`` 79 | 80 | 81 | You are now all set up to run Python programs which communicate with your Vector. 82 | 83 | 84 | 85 | Now that you have run your own Vector program, take a look at the rest of the Vector SDK and at the many other example programs to get more ideas. 86 | 87 | Anki, modified by kercre123 88 | 89 | -------------------------------------------------------------------------------- /docs/source/images/annotate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/annotate.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Anki, Inc. Image License Agreement Version 1.1 (last updated November 15, 2018) 2 | 3 | This Image License Agreement (this "Agreement") governs the terms and conditions of your access to and use of Licensed Materials (as defined below), and is made between you, as an individual or entity ("you"), and Anki, Inc. ("we," "us" or "Licensor"). You accept and agree to be bound by this Agreement by your access to or use of any of the Licensed Materials. 4 | 5 | The "Licensed Materials" are the digital images that we make available to you from time to time in connection with this Agreement. 6 | 7 | 1. License. Subject to the terms and conditions of this Agreement, we hereby grant you a limited, revocable, worldwide, fully-paid, royalty free, non-exclusive, non-transferable copyright license during the term of this Agreement to access, copy, display, perform, modify the size of, and distribute, in any of the Licensed Materials, in each case: (A) solely in connection with your use of the Vector SDK in accordance with our separate SDK license agreement(s) or the applicable Anki hardware products (e.g. Vector) and/or the Vector App, and (B) only provided that you comply with the Anki Terms of Use at www.anki.com/terms and any other terms that may apply to the Vector device and/or Vector mobile application and that we may from time to time modify. Licensee may not sublicense any of the foregoing rights, except for the right to access, copy, display perform and distribute the Licensed Materials only in connection with the SDK in an app created by the Licensee. For clarity, this license does not include the right to commercially distribute the Licensed Materials in print form. 8 | 9 | 2. Reservation. Licensor (or its suppliers) owns and retains all right, title, and interest in and to each of the Licensed Materials worldwide including, but not limited to, ownership of all copyrights and other intellectual property rights therein. We reserve all rights not explicitly licensed in this Agreement. 10 | 11 | 3. DISCLAIMER OF WARRANTY AND LIMITATION OF LIABILITY. THE LICENSED MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NONINFRINGEMENT. IN NO EVENT WILL LICENSOR BE LIABLE TO YOU OR TO ANY THIRD PARTY FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, OR LOST REVENUE, SAVINGS OR PROFITS, WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE) OR OTHERWISE, ARISING FROM OR IN CONNECTION WITH ANY OF THE LICENSED MATERIALS, WHETHER OR NOT THAT PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | 13 | 4. Indemnification. You will defend, indemnify and hold harmless Licensor and its officers, directors, shareholders, employees, and agents from any loss, liability, cost or expense, including attorneys' fees ("Liabilities") that arises from any claim, action or proceeding in connection with your use of the Licensed Materials or your breach of this Agreement. You shall have control of the defense and all related settlement negotiations for such claim, action or proceeding; provided that we shall have the right to consent to any settlement or entry of judgment, such consent not to be unreasonably withheld, and we may participate in such defense using our own counsel at our own expense. 14 | 15 | 5. Termination. You may terminate this Agreement at any time by deleting or destroying all copies of the Licensed Materials that you possess or control. We may terminate this Agreement and/or your license to any or all of the Licensed Materials at any time without prior notice to you. In case of termination, you must cease all access and use of, and delete or destroy, all copies of the Licensed Materials that you possess or control. Sections 2 through 8 of this Agreement will survive termination of this Agreement. 16 | 17 | 6. Modifications to this Agreement and Licensed Materials. We may amend this Agreement at any time by posting an amended version online and/or sending information regarding the amendment to your email address of record with us. You shall be deemed to have accepted such amendments by continuing to access and/or use any Licensed Materials after such amendments have been posted or information regarding such amendments has been sent to you. If you do not agree to any of such changes, you may terminate this Agreement and immediately cease all access to and use of Licensed Materials. You agree that such termination will be your exclusive remedy in such event. No other waiver or modification of this Agreement shall be valid unless in writing and signed by both parties. We also reserve the right at any time and from time to time to modify or discontinue all or any portion of any Licensed Materials without notice to you. We shall not be liable to you or any third party should we exercise such rights. 18 | 19 | 7. Assignment. You may not assign this Agreement, in whole or in part, without our prior written consent, and any attempt by you to assign this Agreement without such consent shall be void. Subject to the foregoing, this Agreement shall benefit and bind both parties, and their successors and permitted assigns. 20 | 21 | 8. General. You shall comply with all laws, rules and regulations applicable to your activities under this Agreement. This Agreement shall be governed by and construed in accordance with the laws of the State of California, U.S.A., except for its conflicts of laws principles. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. This Agreement will not be construed to create or imply any partnership, agency or joint venture between the parties. If any provision of this Agreement is found illegal or unenforceable, it will be enforced to the maximum extent permissible, and the legality and enforceability of the other provisions of this Agreement will not be affected. This Agreement is the complete agreement between the parties with respect to its subject matter, and supersedes any prior agreements and communications (both written and oral) regarding such subject matter. 22 | -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_2Circles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_2Circles.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_2Diamonds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_2Diamonds.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_2Hexagons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_2Hexagons.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_2Triangles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_2Triangles.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_3Circles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_3Circles.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_3Diamonds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_3Diamonds.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_3Hexagons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_3Hexagons.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_3Triangles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_3Triangles.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_4Circles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_4Circles.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_4Diamonds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_4Diamonds.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_4Hexagons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_4Hexagons.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_4Triangles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_4Triangles.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_5Circles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_5Circles.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_5Diamonds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_5Diamonds.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_5Hexagons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_5Hexagons.png -------------------------------------------------------------------------------- /docs/source/images/custom_markers/SDK_5Triangles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/custom_markers/SDK_5Triangles.png -------------------------------------------------------------------------------- /docs/source/images/vector-sdk-alpha.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/docs/source/images/vector-sdk-alpha.jpg -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. image:: images/vector-sdk-alpha.jpg 2 | 3 | | 4 | 5 | =============================== 6 | Welcome to the Vector SDK Alpha 7 | =============================== 8 | 9 | The Vector SDK gives you direct access to Vector's unprecedented set of advanced sensors, AI capabilities, and robotics technologies including computer vision, intelligent mapping and navigation, and a groundbreaking collection of expressive animations. 10 | 11 | It's powerful but easy to use, complex but not complicated, and versatile enough to be used across a wide range of domains including enterprise, research, and entertainment. 12 | 13 | Please note this is an alpha version of the Vector SDK that is not yet feature complete, but already provides access to many of Vector's hardware and software features. 14 | 15 | .. toctree:: 16 | :maxdepth: 1 17 | :caption: Installation 18 | 19 | initial 20 | install-macos.rst 21 | install-windows.rst 22 | install-linux.rst 23 | troubleshooting.rst 24 | advanced-tips.rst 25 | 26 | .. toctree:: 27 | :maxdepth: 2 28 | :caption: Downloads 29 | 30 | downloads.rst 31 | 32 | .. toctree:: 33 | :maxdepth: 2 34 | :caption: Get Started 35 | 36 | getstarted.rst 37 | 38 | .. toctree:: 39 | :maxdepth: 2 40 | :caption: API Reference 41 | 42 | api 43 | 44 | ------------------ 45 | Indices and tables 46 | ------------------ 47 | 48 | * :ref:`genindex` 49 | * :ref:`modindex` 50 | * :ref:`search` 51 | 52 | ---- 53 | 54 | Anki, modified by kercre123 55 | -------------------------------------------------------------------------------- /docs/source/initial.rst: -------------------------------------------------------------------------------- 1 | .. _initial: 2 | 3 | ############# 4 | Initial Setup 5 | ############# 6 | 7 | ------------ 8 | Installation 9 | ------------ 10 | 11 | To install the SDK on your system, select the instructions for your computer's operating system. 12 | 13 | * :ref:`install-macos` 14 | * :ref:`install-windows` 15 | * :ref:`install-linux` 16 | 17 | 18 | -------------------- 19 | SDK Example Programs 20 | -------------------- 21 | 22 | There are example programs for novice and advanced users to run with the SDK. Download the SDK example programs here: 23 | 24 | * :verlink:`macOS/Linux SDK Examples ` 25 | 26 | * :verlink:`Windows SDK Examples ` 27 | 28 | Once downloaded, extract the packaged files to a new directory. 29 | 30 | .. 31 | 32 | .. _trouble: 33 | 34 | ^^^^^^^^^^^ 35 | DDL Discord 36 | ^^^^^^^^^^^ 37 | 38 | Please visit the `Unofficial DDL Discord `_ to ask questions, find solutions and for general discussion. 39 | 40 | ---- 41 | 42 | Anki, modified by kercre123 -------------------------------------------------------------------------------- /docs/source/install-linux.rst: -------------------------------------------------------------------------------- 1 | .. _install-linux: 2 | 3 | #################### 4 | Installation - Linux 5 | #################### 6 | 7 | ^^^^^^^^^^^^^ 8 | Prerequisites 9 | ^^^^^^^^^^^^^ 10 | 11 | * Vector is powered on. 12 | * Vector has been set up with wire-pod. 13 | * Vector is connected to the same network as your computer. 14 | * You can see Vector's eyes on his screen. 15 | 16 | 17 | This guide provides instructions on installing the Vector SDK for computers running with an Ubuntu Linux operating system. 18 | 19 | .. warning:: The Vector SDK is tested and and supported on Ubuntu 22.04. Anki makes no guarantee the Vector SDK will work on other versions of Linux. If you wish to try the Vector SDK on versions of Linux *other than* Ubuntu 22.04, please ensure the following dependencies are installed: 20 | 21 | * Python 3.9 or later 22 | * pip for Python 3 (Python package installer) 23 | 24 | 25 | 26 | ^^^^^^^^^^^^ 27 | Ubuntu 22.04 28 | ^^^^^^^^^^^^ 29 | 30 | """"""""""""""""""" 31 | Python Installation 32 | """"""""""""""""""" 33 | 34 | 1. Type the following into your Terminal window to install Python:: 35 | 36 | sudo apt-get update 37 | sudo apt-get install python3 38 | 39 | 2. Then install pip by typing in the following into the Terminal window:: 40 | 41 | sudo apt install python3-pip 42 | 43 | 3. Last, install Tkinter:: 44 | 45 | sudo apt-get install python3-pil.imagetk 46 | 47 | """"""""""""""""""""""""""""""""""""""""""""""""""""""" 48 | SDK Installation - Ubuntu 22.04 (Python 3.10 and below) 49 | """"""""""""""""""""""""""""""""""""""""""""""""""""""" 50 | 51 | If you have any other Vector SDK installed, uninstall it by running these commands in the Terminal window:: 52 | 53 | python3 -m pip uninstall -y anki_vector 54 | python3 -m pip uninstall -y ikkez_vector 55 | python3 -m pip uninstall -y cyb3r_vector_sdk 56 | 57 | To install the SDK, type the following into the Terminal window:: 58 | 59 | python3 -m pip install --user wirepod_vector_sdk 60 | 61 | If you want to use the 3D viewer, type the following as well:: 62 | 63 | python3 -m pip install --user wirepod_vector_sdk[3dviewer] 64 | 65 | Now move on to Vector Authentication. 66 | 67 | """"""""""""""""""""""""""""""""""""""""""""""""""""" 68 | SDK Installation - Arch Linux (Python 3.11 and above) 69 | """"""""""""""""""""""""""""""""""""""""""""""""""""" 70 | 71 | If you have any other Vector SDK installed, uninstall it by running these commands in the Terminal window:: 72 | 73 | python3 -m pip uninstall --break-system-packages -y anki_vector 74 | python3 -m pip uninstall --break-system-packages -y ikkez_vector 75 | python3 -m pip uninstall --break-system-packages -y cyb3r_vector_sdk 76 | 77 | To install the SDK, type the following into the Terminal window:: 78 | 79 | python3 -m pip install --break-system-packages --user wirepod_vector_sdk 80 | 81 | If you want to use the 3D viewer, type the following as well:: 82 | 83 | python3 -m pip install --break-system-packages --user wirepod_vector_sdk[3dviewer] 84 | 85 | Now move on to Vector Authentication. 86 | 87 | """"""""""" 88 | SDK Upgrade 89 | """"""""""" 90 | 91 | To upgrade the SDK from a previous install, enter this command:: 92 | 93 | python3 -m pip install --break-system-packages --user --upgrade wirepod_vector_sdk 94 | 95 | ^^^^^^^^^^^^^^^^^^^^^ 96 | Vector Authentication 97 | ^^^^^^^^^^^^^^^^^^^^^ 98 | 99 | First, in case it exists, make sure your .anki_vector folder is accessible by the user. To do this, type the following commands into the Terminal window. It may ask for your password. Note that as a security measure, your password will not show up as you are typing it:: 100 | 101 | sudo chmod +rwx ~/.anki_vector 102 | sudo chown -R $USER ~/.anki_vector 103 | 104 | To authenticate with the robot, type the following into the Terminal window:: 105 | 106 | python3 -m anki_vector.configure 107 | 108 | You will be prompted for your robot's name, ip address and serial number. You will also be asked to provide the IP address of your wire-pod instance. You can have it try to find the instance automatically if that is more convenient. 109 | 110 | You will see "SUCCESS!" when this script successfully completes. 111 | 112 | .. note:: By running the ``anki_vector.configure`` executable submodule, you will be asked to provide the IP address of your wire-pod instance (you can also have the script automatically try to find the wire-pod instance), and the script will automatically download an authentication token and certificate to your computer that will grant you access to the robot and his capabilities (such as camera and audio) as well as data stored on the robot (such as faces and photos). 113 | 114 | The downloaded access token is equivalent to your account credentials. It will be stored in your user directory (~/.anki_vector) along with a robot identity certificate and other useful data for establishing a connection. Do not share your access token. 115 | 116 | .. warning:: These credentials give full access to your robot, including camera stream, audio stream and data. Do not share these credentials. 117 | 118 | 119 | 120 | ^^^^^^^^^^^^^^^ 121 | Troubleshooting 122 | ^^^^^^^^^^^^^^^ 123 | 124 | Please see the :doc:`Troubleshooting ` page for tips, or visit the `Unofficial DDL Discord `_ to ask questions, find solutions, or for general discussion. 125 | 126 | ---- 127 | 128 | Anki, modified by kercre123 129 | 130 | -------------------------------------------------------------------------------- /docs/source/install-macos.rst: -------------------------------------------------------------------------------- 1 | .. _install-macos: 2 | 3 | ########################### 4 | Installation - macOS / OS X 5 | ########################### 6 | 7 | This guide provides instructions on installing the Vector SDK for computers running with a macOS operating system. 8 | 9 | ^^^^^^^^^^^^^ 10 | Prerequisites 11 | ^^^^^^^^^^^^^ 12 | 13 | * Vector is powered on. 14 | * Vector has been set up with wire-pod. 15 | * Vector is connected to the same network as your computer. 16 | * You can see Vector's eyes on his screen. 17 | 18 | 19 | ^^^^^^^^^^^^^^^^^^^ 20 | Python Installation 21 | ^^^^^^^^^^^^^^^^^^^ 22 | 23 | 1. Install `Homebrew `_ on your system according to the latest instructions. If you already had brew installed then update it by opening a Terminal window and typing in the following:: 24 | 25 | brew update 26 | 27 | 2. Once Homebrew is installed and updated, type the following into the Terminal window to install the latest version of Python 3:: 28 | 29 | brew install python3 30 | 31 | The Vector SDK supports Python 3.9 or later. 32 | 33 | 34 | ^^^^^^^^^^^^^^^^ 35 | SDK Installation 36 | ^^^^^^^^^^^^^^^^ 37 | 38 | If you have any other Vector SDK installed, uninstall it by running these commands in the Terminal window:: 39 | 40 | python3 -m pip uninstall anki_vector 41 | python3 -m pip uninstall ikkez_vector 42 | python3 -m pip uninstall cyb3r_vector_sdk 43 | 44 | To install the SDK, type the following into the Terminal window:: 45 | 46 | python3 -m pip install --user wirepod_vector_sdk 47 | 48 | """"""""""" 49 | SDK Upgrade 50 | """"""""""" 51 | 52 | To upgrade the SDK from a previous install, enter this command:: 53 | 54 | python3 -m pip install --user --upgrade wirepod_vector_sdk 55 | 56 | ^^^^^^^^^^^^^^^^^^^^^ 57 | Vector Authentication 58 | ^^^^^^^^^^^^^^^^^^^^^ 59 | 60 | To authenticate with the robot, type the following into the Terminal window. Note that during this configure step, your password will not show by design as a security precaution:: 61 | 62 | python3 -m anki_vector.configure 63 | 64 | You will be prompted for your robot's name, ip address and serial number. You will also be asked to provide the IP address of your wire-pod instance. You can have it try to find the instance automatically if that is more convenient. 65 | 66 | You will see "SUCCESS!" when this script successfully completes. 67 | 68 | .. note:: By running the ``anki_vector.configure`` executable submodule, you will be asked to provide your wire-pod instance IP address (you can also have the script automatically try to find the wire-pod instance), and the script will automatically download an authentication token and certificate to your computer that will grant you access to the robot and his capabilities (such as camera and audio) as well as data stored on the robot (such as faces and photos). 69 | 70 | The downloaded access token is equivalent to your account credentials. It will be stored in your user directory (~/.anki_vector) along with a robot identity certificate and other useful data for establishing a connection. Do not share your access token. 71 | 72 | .. warning:: These credentials give full access to your robot, including camera stream, audio stream and data. Do not share these credentials. 73 | 74 | ^^^^^^^^^^^^^^^ 75 | Troubleshooting 76 | ^^^^^^^^^^^^^^^ 77 | 78 | Please see the :doc:`Troubleshooting ` page for tips, or visit the `Unofficial DDL Discord `_ to ask questions, find solutions, or for general discussion. 79 | 80 | ---- 81 | 82 | Anki, modified by kercre123 83 | 84 | -------------------------------------------------------------------------------- /docs/source/install-windows.rst: -------------------------------------------------------------------------------- 1 | .. _install-windows: 2 | 3 | ###################### 4 | Installation - Windows 5 | ###################### 6 | 7 | This guide provides instructions on installing the Vector SDK for computers running with a Windows operating system. 8 | 9 | ^^^^^^^^^^^^^ 10 | Prerequisites 11 | ^^^^^^^^^^^^^ 12 | 13 | * Vector is powered on. 14 | * Vector has been set up with wire-pod. 15 | * Vector is connected to the same network as your computer. 16 | * You can see Vector's eyes on his screen. 17 | 18 | 19 | ^^^^^^^^^^^^^^^^^^^ 20 | Python Installation 21 | ^^^^^^^^^^^^^^^^^^^ 22 | 23 | Download the `Python 3.9 (or later) executable file from Python.org `_ and 24 | run it on your computer. 25 | 26 | .. important:: Be sure to tick the "Add Python 3.X to PATH" checkbox on the Setup screen. Then tap "Install Now" and complete the Python installation. 27 | 28 | ^^^^^^^^^^^^^^^^ 29 | SDK Installation 30 | ^^^^^^^^^^^^^^^^ 31 | 32 | If you have any other Vector SDK installed, uninstall it by running these commands in the Terminal window:: 33 | 34 | py -m pip uninstall anki_vector 35 | py -m pip uninstall ikkez_vector 36 | py -m pip uninstall cyb3r_vector_sdk 37 | 38 | To install the SDK, type the following into the Command Prompt window:: 39 | 40 | py -m pip install --user wirepod_vector_sdk 41 | 42 | .. note:: If you encounter an error during SDK installation, you may need to upgrade your pip install. Try ``python -m pip install --upgrade pip`` or ``py -3 -m pip install --upgrade pip`` 43 | 44 | .. note:: If you encounter an error during SDK installation, you may need to upgrade your Python Setuptools. Try ``py -3 -m pip install --upgrade setuptools`` 45 | 46 | """"""""""" 47 | SDK Upgrade 48 | """"""""""" 49 | 50 | To upgrade the SDK from a previous install, enter this command:: 51 | 52 | py -m pip install --user --upgrade wirepod_vector_sdk 53 | 54 | ^^^^^^^^^^^^^^^^^^^^^ 55 | Vector Authentication 56 | ^^^^^^^^^^^^^^^^^^^^^ 57 | 58 | .. important:: If you are installing the SDK on the same machine your wire-pod instance is running on, there is no need to do this. The bot will be automatically configured. 59 | 60 | If the SDK machine and the wire-pod machine are different, then to authenticate with the robot, type the following into the Command Prompt window:: 61 | 62 | py -m anki_vector.configure 63 | 64 | You will be prompted for your robot's name, ip address and serial number. You will also be asked for your wire-pod instance's IP address. You can have it try to find your instance automatically, but it doesn't tend to work well on Windows. 65 | 66 | You will see "SUCCESS!" when this script successfully completes. 67 | 68 | .. note:: By running the ``anki_vector.configure`` executable submodule, you will be asked to provide your wire-pod instance IP address (you can also have the script automatically try to find the wire-pod instance), and the script will automatically download an authentication token and certificate to your computer that will grant you access to the robot and his capabilities (such as camera and audio) as well as data stored on the robot (such as faces and photos). 69 | 70 | The downloaded access token is equivalent to your account credentials. It will be stored in your user directory (~/.anki_vector) along with a robot identity certificate and other useful data for establishing a connection. Do not share your access token. 71 | 72 | .. warning:: These credentials give full access to your robot, including camera stream, audio stream and data. Do not share these credentials. 73 | 74 | ^^^^^^^^^^^^^^^ 75 | Troubleshooting 76 | ^^^^^^^^^^^^^^^ 77 | 78 | Please see the :doc:`Troubleshooting ` page for tips, or visit the `Unofficial DDL Discord `_ to ask questions, find solutions, or for general discussion. 79 | 80 | ---- 81 | 82 | Anki, modified by kercre123 83 | -------------------------------------------------------------------------------- /docs/source/proto.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | Protobuf Documentation 4 | ====================== 5 | 6 | **PLEASE NOTE: The Vector Python SDK is supported by Anki. Using protocol buffer messages directly is not supported. The proto messages are subject to change without warning. Use with caution.** 7 | 8 | .. raw:: html 9 | :file: proto.html 10 | 11 | ---- 12 | 13 | Anki, modified by kercre123 14 | -------------------------------------------------------------------------------- /docs/source/troubleshooting.rst: -------------------------------------------------------------------------------- 1 | .. _troubleshooting: 2 | 3 | ############### 4 | Troubleshooting 5 | ############### 6 | 7 | 8 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 9 | Failure to Install Python Package 10 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 11 | 12 | If you run into trouble installing Python packages, please upgrade your pip install as follows: 13 | 14 | On macOS and Linux:: 15 | 16 | pip3 install -U pip 17 | 18 | On Windows:: 19 | 20 | python -m pip install --upgrade pip 21 | 22 | Alternatively on Windows, try:: 23 | 24 | py -3 -m pip install --upgrade pip 25 | 26 | You may also need to update Python setuptools (for instance, for error ``AttributeError: '_NamespacePath' object has no attribute 'sort'``):: 27 | 28 | pip install --upgrade setuptools 29 | 30 | After applying these updates, retry your Python package installation. 31 | 32 | 33 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 34 | Tutorial program does not run 35 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 36 | 37 | Before running a Python program, be sure you can see Vector's eyes. If instead you see an image of a mobile device, the Customer Care Info screen, a missing Wifi icon, or something else, please complete setup of your Vector first and then you will be ready set up the SDK. 38 | 39 | Also, check whether Vector's IP address has changed since the last time you ran ``anki_vector.configure``. If so, see :ref:`moving_between_wifi` to set up the robot with the new IP address. 40 | 41 | 42 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 43 | Failure to run anki_vector.configure 44 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 45 | 46 | The prerequisites to run the ``anki_vector.configure`` executable submodule successfully are: 47 | 48 | * wire-pod is running. 49 | * Vector has been set up with wire-pod. 50 | * Vector is connected to the same network as your computer. 51 | * The ``anki_vector`` Python package must be installed. 52 | * You can see Vector's eyes on his screen. 53 | 54 | 55 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 56 | Vector behaves unexpectedly 57 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 58 | 59 | You may need to reboot your robot when you are finished running programs with the pre-alpha Vector SDK. 60 | 61 | 62 | ^^^^^^^^^^^^^^^^^^^^^ 63 | Can't find robot name 64 | ^^^^^^^^^^^^^^^^^^^^^ 65 | 66 | Your Vector robot name looks like "Vector-E5S6". Find your robot name by placing Vector on the charger and double-clicking Vector's backpack button. 67 | 68 | 69 | ^^^^^^^^^^^^^^^^^^^^^^^^ 70 | Can't find serial number 71 | ^^^^^^^^^^^^^^^^^^^^^^^^ 72 | 73 | Your Vector's serial number looks like "00e20142". Find your robot serial number on the underside of Vector. Or, find the serial number from Vector's debug screen: double-click his backpack, move his arms up and down, then look for "ESN" on his screen. 74 | 75 | 76 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 77 | Can't find Vector's IP address 78 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 79 | 80 | Your Vector IP address looks like "192.168.40.134". Find the IP address from Vector's debug screen: double-click his backpack, move his arms up and down, then look for "IP" on his screen. 81 | 82 | 83 | ^^^^^^^^^^^ 84 | DDL Discord 85 | ^^^^^^^^^^^ 86 | 87 | Please visit the `Unofficial DDL Discord `_ to ask questions, find solutions and for general discussion. 88 | 89 | ---- 90 | 91 | Anki, modified by kercre123 92 | 93 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Example programs for the anki_vector Python SDK 2 | 3 | See the [tutorials](tutorials) directory for a progression of example programs all the way from [hello_world](tutorials/01_hello_world.py) through to more advanced examples. 4 | 5 | See the [apps](apps) directory for some fun fully-featured programs like a remote control. 6 | -------------------------------------------------------------------------------- /examples/apps/3d_viewer/3d_viewer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """3d Viewer example, with remote control. 18 | 19 | This is an example of how you can use the 3D viewer with a program, and the 20 | 3D Viewer and controls will work automatically. 21 | """ 22 | 23 | import time 24 | 25 | import anki_vector 26 | 27 | 28 | def main(): 29 | args = anki_vector.util.parse_command_args() 30 | with anki_vector.Robot(args.serial, 31 | show_viewer=True, 32 | show_3d_viewer=True, 33 | enable_face_detection=True, 34 | enable_custom_object_detection=True, 35 | enable_nav_map_feed=True): 36 | print("Starting 3D Viewer. Use Ctrl+C to quit.") 37 | try: 38 | while True: 39 | time.sleep(0.5) 40 | except KeyboardInterrupt: 41 | pass 42 | 43 | 44 | if __name__ == "__main__": 45 | main() 46 | -------------------------------------------------------------------------------- /examples/apps/interactive_shell/interactive_shell.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Command Line Interface for Vector 18 | 19 | This is an example of integrating Vector with an ipython-based command line interface. 20 | """ 21 | 22 | import sys 23 | 24 | try: 25 | from IPython.terminal.embed import InteractiveShellEmbed 26 | except ImportError: 27 | sys.exit('Cannot import from ipython: Do `pip3 install ipython` to install') 28 | 29 | import anki_vector 30 | 31 | usage = """Use the [tab] key to auto-complete commands, and see all available methods and properties. 32 | 33 | For example, type 'robot.' then press the [tab] key and you'll see all the robot functions. 34 | Keep pressing tab to cycle through all of the available options. 35 | 36 | All IPython commands work as usual. 37 | Here's some useful syntax: 38 | robot? -> Details about 'robot'. 39 | robot?? -> More detailed information including code for 'robot'. 40 | These commands will work on all objects inside of the shell. 41 | 42 | You can even call the functions that send messages to Vector, and he'll respond just like he would in a script. 43 | Try it out! Type: 44 | robot.anim.play_animation_trigger('GreetAfterLongTime') 45 | """ 46 | 47 | args = anki_vector.util.parse_command_args() 48 | 49 | ipyshell = InteractiveShellEmbed(banner1='\nWelcome to the Vector Interactive Shell!', 50 | exit_msg='Goodbye\n') 51 | 52 | if __name__ == "__main__": 53 | with anki_vector.Robot(args.serial, 54 | show_viewer=True) as robot: 55 | # Invoke the ipython shell while connected to Vector 56 | ipyshell(usage) 57 | -------------------------------------------------------------------------------- /examples/apps/remote_control/lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/examples/apps/remote_control/lib/__init__.py -------------------------------------------------------------------------------- /examples/apps/remote_control/lib/flask_helpers.py: -------------------------------------------------------------------------------- 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 | """Wrappers and helpers for using Flask with Vector. 16 | 17 | Flask is a Python web framework. remote_control_vector.py and other scripts may use 18 | these utility functions to interact with a web browser. 19 | """ 20 | 21 | import logging 22 | import sys 23 | from threading import Thread 24 | import webbrowser 25 | from time import sleep 26 | from io import BytesIO 27 | try: 28 | from flask import make_response, Response, send_file 29 | except ImportError: 30 | sys.exit("Cannot import from flask: Do `pip3 install --user flask` to install") 31 | 32 | 33 | def _delayed_open_web_browser(url, delay, new=0, autoraise=True, specific_browser=None): 34 | """ 35 | Spawn a thread and call sleep_and_open_web_browser from within it so that main thread can keep executing at the 36 | same time. Insert a small sleep before opening a web-browser 37 | this gives Flask a chance to start running before the browser starts requesting data from Flask. 38 | """ 39 | 40 | def _sleep_and_open_web_browser(url, delay, new, autoraise, specific_browser): 41 | sleep(delay) 42 | browser = webbrowser 43 | 44 | # E.g. On OSX the following would use the Chrome browser app from that location 45 | # specific_browser = 'open -a /Applications/Google\ Chrome.app %s' 46 | if specific_browser: 47 | browser = webbrowser.get(specific_browser) 48 | 49 | browser.open(url, new=new, autoraise=autoraise) 50 | 51 | thread = Thread(target=_sleep_and_open_web_browser, 52 | kwargs=dict(url=url, new=new, autoraise=autoraise, delay=delay, specific_browser=specific_browser)) 53 | thread.daemon = True # Force to quit on main quitting 54 | thread.start() 55 | 56 | 57 | def run_flask(flask_app, host_ip="127.0.0.1", host_port=5000, enable_flask_logging=False, 58 | open_page=True, open_page_delay=1.0): 59 | """ 60 | Run the Flask webserver on specified host and port 61 | optionally also open that same host:port page in your browser to connect 62 | """ 63 | 64 | if not enable_flask_logging: 65 | # disable logging in Flask (it's enabled by default) 66 | log = logging.getLogger('werkzeug') 67 | log.setLevel(logging.ERROR) 68 | 69 | if open_page: 70 | # we add a delay (dispatched in another thread) to open the page so that the flask webserver is open 71 | # before the webpage requests any data 72 | _delayed_open_web_browser("http://" + host_ip + ":" + str(host_port), delay=open_page_delay) 73 | 74 | flask_app.run(host=host_ip, port=host_port, use_evalex=False, threaded=True) 75 | 76 | 77 | def shutdown_flask(request): 78 | func = request.environ.get('werkzeug.server.shutdown') 79 | if func is None: 80 | sys.exit('SDK Shutdown') 81 | func() 82 | 83 | 84 | def stream_video(streaming_function): 85 | return Response(streaming_function(), mimetype='multipart/x-mixed-replace; boundary=frame') 86 | 87 | 88 | def make_uncached_response(in_file): 89 | response = make_response(in_file) 90 | response.headers['Pragma-Directive'] = 'no-cache' 91 | response.headers['Cache-Directive'] = 'no-cache' 92 | response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate' 93 | response.headers['Pragma'] = 'no-cache' 94 | response.headers['Expires'] = '0' 95 | return response 96 | 97 | 98 | def serve_pil_image(pil_img, serve_as_jpeg=False, jpeg_quality=70): 99 | """Convert PIL image to relevant image file and send it""" 100 | img_io = BytesIO() 101 | 102 | if serve_as_jpeg: 103 | pil_img.save(img_io, 'JPEG', quality=jpeg_quality) 104 | img_io.seek(0) 105 | return make_uncached_response(send_file(img_io, mimetype='image/jpeg', 106 | add_etags=False)) 107 | pil_img.save(img_io, 'PNG') 108 | img_io.seek(0) 109 | return make_uncached_response(send_file(img_io, mimetype='image/png', 110 | add_etags=False)) 111 | -------------------------------------------------------------------------------- /examples/experimental/sign_language_recognition_system/README.md: -------------------------------------------------------------------------------- 1 | # Overview: 2 | 3 | This project passes the robot's camera feed through a [Convolutional Neural Network](https://en.wikipedia.org/wiki/Convolutional_neural_network) (CNN) built to recognize American Sign Language hand signs. The network is built using [Keras](https://keras.io/) with a [TensorFlow](https://www.tensorflow.org/guide/keras) Backend. It predicts the sign visible (if any) per frame and therefore cannot predict more complex sign language gestures. 4 | 5 | >Network Architecture: 6 | >ConvLayer -> MaxPoolLayer -> ConvLayer -> MaxPoolLayer -> ConvLayer -> Dropout -> Flatten -> Dense -> Dropout -> Dense 7 | 8 | The network is built as a Keras [Sequential](https://keras.io/getting-started/sequential-model-guide/) model which consists of a linear stack of layers of the following types: 9 | 10 | ConvLayer (Convolutional layer): https://keras.io/layers/convolutional/ 11 | 12 | MaxPoolLayer (Max Pooling layer): https://keras.io/layers/pooling/ 13 | 14 | Flatten, Dense, Dropout layers: https://keras.io/layers/core/ 15 | 16 | The `data_gen.py` script can be used to build/expand the dataset to train and test the model. Each image captured is used to generate a multiplier number of other images to expand the dataset. The images are translated to 200x200 black and white images to reduce the complexity of the network. While capturing images from the feed ensure that your hand is positioned within the red square which represents the cropped image dimensions. 17 | 18 | >Note: This project has not been tested on Windows and Linux environments. Currently the `data_gen.py` script will not run on Windows due to its dependency on the `curses` library. 19 | 20 | 21 | # Additional Dependencies: 22 | 23 | Install the additional dependencies required for the project: 24 | ``` 25 | pip3 install keras 26 | pip3 install numpy 27 | pip3 install scipy 28 | pip3 install scikit-learn 29 | pip3 install tensorflow 30 | ``` 31 | 32 | # Dataset: 33 | 34 | ### Import Dataset: 35 | 36 | This project includes a sample dataset that can be used as a starting point to train and test the neural network. 37 | 38 | Unpack the dataset: 39 | ``` 40 | unzip dataset.zip 41 | ``` 42 | 43 | >Note: This dataset contains 200x200 black-and-white images of two hand signs ("a", "b"). Additionally, the `stats.json` file provides the number of images of each alphabet type. 44 | 45 | ### Generate Dataset: 46 | 47 | ![hand-sign](./example.png) 48 | 49 | Use the following command to capture more images and expand the dataset. Expanding the dataset to include more images can help improve the network's performance since: 50 | 51 | 1. The network may not have seen any reference images to help distinguish your background. Especially if you are testing against a noisy background. 52 | 53 | 2. The dataset only contains images of the same hand and might not identify others that look significantly different. 54 | 55 | 56 | ```python3 data_gen.py --dataset_root_folder ``` 57 | 58 | >Note: In order to capture an image, display the hand sign within the red frame on the camera feed displayed and press the key corresponding to the label representing the hand sign. Dimensions of images in the dataset are 200x200. 59 | 60 | >Note: Along with capturing images of hand signs it is also important to capture images of the background without any hand sign in the frame. This ensures that while predicting a frame without any hand signs, it is correctly classified. Use the space bar on your keyboard to record a background image. 61 | 62 | 63 | # Run Project: 64 | 65 | ### Project Phases: 66 | 67 | There are two main phases: `train` and `predict`. In the training phase, the neural network is given a set of labeled hand sign images. Once the network has been trained to classify the images we move to the prediction phase. The `predict` option launches the robot's camera feed and looks to classify any visible hand signs. If a frame is classified the recognized letter is spoken out loud. 68 | 69 | ### Training: 70 | 71 | Train the neural network using an image dataset to classify different hand signs. 72 | 73 | ``` 74 | python3 recognizer.py --train --dataset_root_folder [--model_config ] [--model_weights ] 75 | ``` 76 | 77 | >Note: Use the `model_config` and `model_weights` flags to save the model's configurations after it has been trained. This way the model does not need to be re-trained before predicting. 78 | 79 | ### Prediction: 80 | 81 | Use a trained neural network to predict any visible hand signs in the robot's field of view (within the region of interest marked with a red square). 82 | 83 | ``` 84 | python3 recognizer.py --predict --model_config --model_weights 85 | ``` 86 | 87 | >Note: Use the `model_config` and `model_weights` flags to load an existing model's configuration. If not using an existing model's configuration, train the model first. 88 | 89 | ### Train and Predict: 90 | 91 | ``` 92 | python3 recognizer.py --train --predict --dataset_root_folder 93 | ``` -------------------------------------------------------------------------------- /examples/experimental/sign_language_recognition_system/dataset.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/examples/experimental/sign_language_recognition_system/dataset.zip -------------------------------------------------------------------------------- /examples/experimental/sign_language_recognition_system/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/examples/experimental/sign_language_recognition_system/example.png -------------------------------------------------------------------------------- /examples/experimental/sign_language_recognition_system/util.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019 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 | """Utility functions and classes for the sign language recognition system.""" 16 | 17 | import argparse 18 | 19 | from anki_vector import util 20 | 21 | try: 22 | from PIL import Image 23 | except ImportError: 24 | sys.exit("Cannot import from PIL: Do `pip3 install --user Pillow` to install") 25 | 26 | 27 | class NetworkConstants(): # pylint: disable=too-few-public-methods 28 | """Constant values used as image and network parameters.""" 29 | 30 | # Width of images passed to the network 31 | IMAGE_WIDTH: int = 200 32 | 33 | # Height of images passed to the network 34 | IMAGE_HEIGHT: int = 200 35 | 36 | # Currently set to 2 alphabet images and 1 background image class 37 | # Number of classes that the network can categorize 38 | NUM_CLASSES: int = 27 39 | 40 | # The fraction of images passed to the network during training that should 41 | # be used as a validation set. Range: 0 to 1 42 | VALIDATION_SPLIT: float = 0.1 43 | 44 | # The fraction of images passed to the network during training that should 45 | # be used as a test set. Range: 0 to 1 46 | TEST_SPLIT: float = 0.2 47 | 48 | # Number of epochs on which to train the network 49 | EPOCHS: int = 5 50 | 51 | 52 | def parse_command_args(): 53 | """Parses command line args""" 54 | parser = argparse.ArgumentParser() 55 | parser.add_argument("--train", action="store_true") 56 | parser.add_argument("--predict", action="store_true") 57 | parser.add_argument("--dataset_root_folder", nargs='?', default=None) 58 | parser.add_argument("--model_config", nargs='?', default=None) 59 | parser.add_argument("--model_weights", nargs='?', default=None) 60 | 61 | return util.parse_command_args(parser) 62 | 63 | 64 | def crop_image(image: Image.Image, target_width: int, target_height: int) -> Image.Image: 65 | """Crops an image to the target width and height""" 66 | image_width, image_height = image.size 67 | 68 | remaining_width = image_width - target_width 69 | remaining_height = image_height - target_height 70 | 71 | return image.crop(((remaining_width // 2), 72 | (remaining_height // 2), 73 | (image_width - (remaining_width // 2)), 74 | (image_height - (remaining_height // 2)))) 75 | -------------------------------------------------------------------------------- /examples/face_images/cozmo_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/examples/face_images/cozmo_image.jpg -------------------------------------------------------------------------------- /examples/scripts/take_control.bat: -------------------------------------------------------------------------------- 1 | :: This file is provided as a convenience for initiating reserved behavior 2 | :: control for SDK scripts. Windows users can double-click on this file in 3 | :: Windows Explorer to open a cmd.exe window and execute a Python script so 4 | :: that most default behaviors will be suppressed before/after other SDK 5 | :: scripts execute. This will keep Vector still between SDK scripts. 6 | :: 7 | :: Allowing the script to complete or closing the cmd.exe window will 8 | :: restore behavior control to the robot. 9 | 10 | start python -m anki_vector.reserve_control 11 | -------------------------------------------------------------------------------- /examples/scripts/take_control.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This file is provided as a convenience for initiating reserved behavior 3 | # control for SDK scripts. Mac users can double-click on this file in 4 | # the Finder to open a Terminal window and execute a Python script so 5 | # that most default behaviors will be suppressed before/after other SDK 6 | # scripts execute. This will keep Vector still between SDK scripts. 7 | # 8 | # Allowing the script to complete or closing the Terminal window will 9 | # restore behavior control to the robot. 10 | 11 | python3 -m anki_vector.reserve_control 12 | -------------------------------------------------------------------------------- /examples/sounds/vector_alert.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/examples/sounds/vector_alert.wav -------------------------------------------------------------------------------- /examples/sounds/vector_bell_whistle.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercre123/wirepod-vector-python-sdk/065fc197d592d76a164d64dcf0a768183ab37855/examples/sounds/vector_bell_whistle.wav -------------------------------------------------------------------------------- /examples/tutorials/01_hello_world.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Hello World 18 | 19 | Make Vector say 'Hello World' in this simple Vector SDK example program. 20 | """ 21 | 22 | import anki_vector 23 | 24 | 25 | def main(): 26 | args = anki_vector.util.parse_command_args() 27 | with anki_vector.Robot(args.serial) as robot: 28 | print("Say 'Hello World'...") 29 | robot.behavior.say_text("Hello World") 30 | 31 | 32 | if __name__ == "__main__": 33 | main() 34 | -------------------------------------------------------------------------------- /examples/tutorials/02_drive_square.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Make Vector drive in a square. 18 | 19 | Make Vector drive in a square by going forward and turning left 4 times in a row. 20 | """ 21 | 22 | import anki_vector 23 | from anki_vector.util import degrees, distance_mm, speed_mmps 24 | 25 | 26 | def main(): 27 | args = anki_vector.util.parse_command_args() 28 | 29 | # The robot drives straight, stops and then turns around 30 | with anki_vector.Robot(args.serial) as robot: 31 | robot.behavior.drive_off_charger() 32 | 33 | # Use a "for loop" to repeat the indented code 4 times 34 | # Note: the _ variable name can be used when you don't need the value 35 | for _ in range(4): 36 | print("Drive Vector straight...") 37 | robot.behavior.drive_straight(distance_mm(200), speed_mmps(50)) 38 | 39 | print("Turn Vector in place...") 40 | robot.behavior.turn_in_place(degrees(90)) 41 | 42 | 43 | if __name__ == "__main__": 44 | main() 45 | -------------------------------------------------------------------------------- /examples/tutorials/03_motors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Drive Vector's wheels, lift and head motors directly 18 | 19 | This is an example of how you can also have low-level control of Vector's motors 20 | (wheels, lift and head) for fine-grained control and ease of controlling 21 | multiple things at once. 22 | """ 23 | 24 | import time 25 | import anki_vector 26 | 27 | 28 | def main(): 29 | args = anki_vector.util.parse_command_args() 30 | with anki_vector.Robot(args.serial) as robot: 31 | robot.behavior.drive_off_charger() 32 | 33 | # Tell the head motor to start lowering the head (at 5 radians per second) 34 | print("Lower Vector's head...") 35 | robot.motors.set_head_motor(-5.0) 36 | 37 | # Tell the lift motor to start lowering the lift (at 5 radians per second) 38 | print("Lower Vector's lift...") 39 | robot.motors.set_lift_motor(-5.0) 40 | 41 | # Tell Vector to drive the left wheel at 25 mmps (millimeters per second), 42 | # and the right wheel at 50 mmps (so Vector will drive Forwards while also 43 | # turning to the left 44 | print("Set Vector's wheel motors...") 45 | robot.motors.set_wheel_motors(25, 50) 46 | 47 | # wait for 3 seconds (the head, lift and wheels will move while we wait) 48 | time.sleep(3) 49 | 50 | # Tell the head motor to start raising the head (at 5 radians per second) 51 | print("Raise Vector's head...") 52 | robot.motors.set_head_motor(5) 53 | 54 | # Tell the lift motor to start raising the lift (at 5 radians per second) 55 | print("Raise Vector's lift...") 56 | robot.motors.set_lift_motor(5) 57 | 58 | # Tell Vector to drive the left wheel at 50 mmps (millimeters per second), 59 | # and the right wheel at -50 mmps (so Vector will turn in-place to the right) 60 | print("Set Vector's wheel motors...") 61 | robot.motors.set_wheel_motors(50, -50) 62 | 63 | # Wait for 3 seconds (the head, lift and wheels will move while we wait) 64 | time.sleep(3) 65 | 66 | # Stop the motors, which unlocks the tracks 67 | robot.motors.set_wheel_motors(0, 0) 68 | robot.motors.set_lift_motor(0) 69 | robot.motors.set_head_motor(0) 70 | 71 | 72 | if __name__ == "__main__": 73 | main() 74 | -------------------------------------------------------------------------------- /examples/tutorials/04_animation.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Play animations on Vector 18 | 19 | Play an animation using a trigger, and then another animation by name. 20 | """ 21 | 22 | import anki_vector 23 | 24 | 25 | def main(): 26 | args = anki_vector.util.parse_command_args() 27 | with anki_vector.Robot(args.serial) as robot: 28 | robot.behavior.drive_off_charger() 29 | 30 | # Play an animation via a trigger. 31 | # A trigger can pick from several appropriate animations for variety. 32 | print("Playing Animation Trigger 1:") 33 | robot.anim.play_animation_trigger('GreetAfterLongTime') 34 | 35 | # Play the same trigger, but this time ignore the track that plays on the 36 | # body (i.e. don't move the wheels). See the play_animation_trigger documentation 37 | # for other available settings. 38 | print("Playing Animation Trigger 2: (Ignoring the body track)") 39 | robot.anim.play_animation_trigger('GreetAfterLongTime', ignore_body_track=True) 40 | 41 | # Play an animation via its name. 42 | # 43 | # Warning: Future versions of the app might change these, so for future-proofing 44 | # we recommend using play_animation_trigger above instead. 45 | # 46 | # See the remote_control.py example in apps for an easy way to see 47 | # the available animations. 48 | animation = 'anim_pounce_success_02' 49 | print("Playing animation by name: " + animation) 50 | robot.anim.play_animation(animation) 51 | 52 | 53 | if __name__ == "__main__": 54 | main() 55 | -------------------------------------------------------------------------------- /examples/tutorials/05_drive_on_off_charger.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Tell Vector to drive on and off the charger. 18 | """ 19 | 20 | import anki_vector 21 | 22 | 23 | def main(): 24 | args = anki_vector.util.parse_command_args() 25 | 26 | with anki_vector.Robot(args.serial) as robot: 27 | print("Drive Vector onto charger...") 28 | robot.behavior.drive_on_charger() 29 | 30 | print("Drive Vector off of charger...") 31 | robot.behavior.drive_off_charger() 32 | 33 | 34 | if __name__ == '__main__': 35 | main() 36 | -------------------------------------------------------------------------------- /examples/tutorials/06_face_image.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Display an image on Vector's face 18 | """ 19 | 20 | import os 21 | import sys 22 | import time 23 | 24 | try: 25 | from PIL import Image 26 | except ImportError: 27 | sys.exit("Cannot import from PIL: Do `pip3 install --user Pillow` to install") 28 | 29 | import anki_vector 30 | from anki_vector.util import degrees 31 | 32 | 33 | def main(): 34 | args = anki_vector.util.parse_command_args() 35 | 36 | with anki_vector.Robot(args.serial) as robot: 37 | # If necessary, move Vector's Head and Lift to make it easy to see his face 38 | robot.behavior.set_head_angle(degrees(45.0)) 39 | robot.behavior.set_lift_height(0.0) 40 | 41 | current_directory = os.path.dirname(os.path.realpath(__file__)) 42 | image_path = os.path.join(current_directory, "..", "face_images", "cozmo_image.jpg") 43 | 44 | # Load an image 45 | image_file = Image.open(image_path) 46 | 47 | # Convert the image to the format used by the Screen 48 | print("Display image on Vector's face...") 49 | screen_data = anki_vector.screen.convert_image_to_screen_data(image_file) 50 | 51 | duration_s = 4.0 52 | robot.screen.set_screen_with_image_data(screen_data, duration_s) 53 | time.sleep(duration_s) 54 | 55 | 56 | if __name__ == "__main__": 57 | main() 58 | -------------------------------------------------------------------------------- /examples/tutorials/07_dock_with_cube.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Tell Vector to drive up to a seen cube. 18 | 19 | This example demonstrates Vector driving to and docking with a cube, without 20 | picking it up. Vector will line his arm hooks up with the cube so that they are 21 | inserted into the cube's corners. 22 | 23 | You must place a cube in front of Vector so that he can see it. 24 | """ 25 | 26 | import anki_vector 27 | from anki_vector.util import degrees 28 | 29 | 30 | def main(): 31 | args = anki_vector.util.parse_command_args() 32 | 33 | docking_result = None 34 | with anki_vector.Robot(args.serial) as robot: 35 | robot.behavior.drive_off_charger() 36 | 37 | # If necessary, move Vector's Head and Lift down 38 | robot.behavior.set_head_angle(degrees(-5.0)) 39 | robot.behavior.set_lift_height(0.0) 40 | 41 | print("Connecting to a cube...") 42 | robot.world.connect_cube() 43 | 44 | if robot.world.connected_light_cube: 45 | print("Begin cube docking...") 46 | dock_response = robot.behavior.dock_with_cube( 47 | robot.world.connected_light_cube, 48 | num_retries=3) 49 | if dock_response: 50 | docking_result = dock_response.result 51 | 52 | robot.world.disconnect_cube() 53 | 54 | if docking_result: 55 | if docking_result.code != anki_vector.messaging.protocol.ActionResult.ACTION_RESULT_SUCCESS: 56 | print("Cube docking failed with code {0} ({1})".format(str(docking_result).rstrip('\n\r'), docking_result.code)) 57 | else: 58 | print("Cube docking failed.") 59 | 60 | 61 | if __name__ == "__main__": 62 | main() 63 | -------------------------------------------------------------------------------- /examples/tutorials/08_show_photo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Show a photo taken by Vector. 18 | 19 | Grabs the pictures off of Vector and open them via PIL. 20 | 21 | Before running this script, please make sure you have successfully 22 | had Vector take a photo by saying, "Hey Vector! Take a photo." 23 | """ 24 | 25 | import io 26 | import sys 27 | 28 | try: 29 | from PIL import Image 30 | except ImportError: 31 | sys.exit("Cannot import from PIL: Do `pip3 install --user Pillow` to install") 32 | 33 | import anki_vector 34 | 35 | 36 | def main(): 37 | args = anki_vector.util.parse_command_args() 38 | with anki_vector.Robot(args.serial) as robot: 39 | if len(robot.photos.photo_info) == 0: 40 | print('\n\nNo photos found on Vector. Ask him to take a photo first by saying, "Hey Vector! Take a photo."\n\n') 41 | return 42 | for photo in robot.photos.photo_info: 43 | print(f"Opening photo {photo.photo_id}") 44 | val = robot.photos.get_photo(photo.photo_id) 45 | image = Image.open(io.BytesIO(val.image)) 46 | image.show() 47 | 48 | 49 | if __name__ == "__main__": 50 | main() 51 | -------------------------------------------------------------------------------- /examples/tutorials/09_eye_color.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Set Vector's eye color. 18 | """ 19 | 20 | import time 21 | import anki_vector 22 | 23 | 24 | def main(): 25 | args = anki_vector.util.parse_command_args() 26 | 27 | with anki_vector.Robot(args.serial) as robot: 28 | print("Set Vector's eye color to purple...") 29 | robot.behavior.set_eye_color(hue=0.83, saturation=0.76) 30 | 31 | print("Sleep 5 seconds...") 32 | time.sleep(5) 33 | 34 | 35 | if __name__ == '__main__': 36 | main() 37 | -------------------------------------------------------------------------------- /examples/tutorials/10_play_audio.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License isvi distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Play audio files through Vector's speaker. 18 | """ 19 | 20 | import anki_vector 21 | 22 | 23 | def main(): 24 | args = anki_vector.util.parse_command_args() 25 | with anki_vector.Robot(args.serial) as robot: 26 | # You can find these sounds files here: 27 | # https://github.com/anki/vector-python-sdk/blob/master/examples/sounds/vector_alert.wav 28 | # https://github.com/anki/vector-python-sdk/blob/master/examples/sounds/vector_bell_whistle.wav 29 | # 30 | # Paste these two wav files next to this tutorial to play sounds. 31 | robot.audio.stream_wav_file("../sounds/vector_bell_whistle.wav", 75) 32 | robot.audio.stream_wav_file("../sounds/vector_alert.wav", 75) 33 | 34 | 35 | if __name__ == "__main__": 36 | main() 37 | -------------------------------------------------------------------------------- /examples/tutorials/11_drive_to_cliff_and_back_up.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Make Vector drive to a cliff and back up. 18 | 19 | Place the robot about a foot from a "cliff" (such as a tabletop edge), 20 | then run this script. 21 | 22 | This tutorial is an advanced example that shows the SDK's integration 23 | with the Vector behavior system. 24 | 25 | The Vector behavior system uses an order of prioritizations to determine 26 | what the robot will do next. The highest priorities in the behavior 27 | system including the following: 28 | * When Vector reaches a cliff, he will back up to avoid falling. 29 | * When Vector is low on battery, he will start searching for his charger 30 | and self-dock. 31 | 32 | When the SDK is running at a lower priority level than high priorities 33 | like cliff and low battery, an SDK program can lose its ability to 34 | control the robot when a cliff if reached or when battery is low. 35 | 36 | This example shows how, after reaching a cliff, the SDK program can 37 | re-request control so it can continue controlling the robot after 38 | reaching the cliff. 39 | """ 40 | 41 | import anki_vector 42 | from anki_vector.util import distance_mm, speed_mmps 43 | 44 | 45 | def main(): 46 | args = anki_vector.util.parse_command_args() 47 | 48 | with anki_vector.Robot(args.serial) as robot: 49 | print("Vector SDK has behavior control...") 50 | robot.behavior.drive_off_charger() 51 | 52 | print("Drive Vector straight until he reaches cliff...") 53 | # Once robot reaches cliff, he will play his typical cliff reactions. 54 | robot.behavior.drive_straight(distance_mm(5000), speed_mmps(100)) 55 | 56 | robot.conn.run_coroutine(robot.conn.control_lost_event.wait()).result() 57 | 58 | print("Lost SDK behavior control. Request SDK behavior control again...") 59 | robot.conn.request_control() 60 | 61 | print("Drive Vector backward away from the cliff...") 62 | robot.behavior.drive_straight(distance_mm(-300), speed_mmps(100)) 63 | 64 | 65 | if __name__ == "__main__": 66 | main() 67 | -------------------------------------------------------------------------------- /examples/tutorials/12_control_priority_level.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2019 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Vector maintains SDK behavior control after being picked up 18 | 19 | During normal operation, SDK programs cannot maintain control over Vector 20 | when he is at a cliff, stuck on an edge or obstacle, tilted or inclined, 21 | picked up, in darkness, etc. 22 | 23 | This script demonstrates how to use the highest level SDK behavior control 24 | ControlPriorityLevel.OVERRIDE_BEHAVIORS_PRIORITY to make Vector perform 25 | actions that normally take priority over the SDK. These commands will not 26 | succeed at ControlPriorityLevel.DEFAULT. 27 | """ 28 | 29 | import sys 30 | import time 31 | import anki_vector 32 | from anki_vector.connection import ControlPriorityLevel 33 | 34 | 35 | def main(): 36 | args = anki_vector.util.parse_command_args() 37 | with anki_vector.Robot(args.serial, behavior_control_level=ControlPriorityLevel.OVERRIDE_BEHAVIORS_PRIORITY) as robot: 38 | robot.behavior.say_text("Pick me up!") 39 | pickup_countdown = 20 40 | 41 | print("------ waiting for Vector to be picked up, press ctrl+c to exit early ------") 42 | 43 | try: 44 | while not robot.status.is_picked_up and pickup_countdown: 45 | time.sleep(0.5) 46 | pickup_countdown -= 1 47 | 48 | if not pickup_countdown: 49 | print("Did not get picked up") 50 | sys.exit() 51 | 52 | print("Vector is picked up...") 53 | robot.behavior.say_text("Hold on tight") 54 | print("Setting wheel motors...") 55 | robot.motors.set_wheel_motors(75, -75) 56 | time.sleep(0.5) 57 | robot.motors.set_wheel_motors(-75, 75) 58 | time.sleep(0.5) 59 | robot.motors.set_wheel_motors(0, 0) 60 | 61 | except KeyboardInterrupt: 62 | pass 63 | 64 | 65 | if __name__ == '__main__': 66 | main() 67 | -------------------------------------------------------------------------------- /examples/tutorials/13_wake_word_subscription.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Wait for Vector to hear "Hey Vector!" and then play an animation. 18 | 19 | The wake_word event only is dispatched when the SDK program has 20 | not requested behavior control. After the robot hears "Hey Vector!" 21 | and the event is received, you can then request behavior control 22 | and control the robot. See the 'requires_behavior_control' method in 23 | connection.py for more information. 24 | """ 25 | 26 | import threading 27 | 28 | import anki_vector 29 | from anki_vector.events import Events 30 | 31 | wake_word_heard = False 32 | 33 | 34 | def main(): 35 | def on_wake_word(robot, event_type, event, done): 36 | robot.conn.request_control() 37 | 38 | global wake_word_heard 39 | if not wake_word_heard: 40 | wake_word_heard = True 41 | robot.behavior.say_text("Hello") 42 | done.set() 43 | 44 | args = anki_vector.util.parse_command_args() 45 | with anki_vector.Robot(args.serial, behavior_control_level=None) as robot: 46 | done = threading.Event() 47 | robot.events.subscribe(on_wake_word, Events.wake_word, done) 48 | 49 | print('------ Vector is waiting to hear "Hey Vector!" Press ctrl+c to exit early ------') 50 | 51 | try: 52 | if not done.wait(timeout=10): 53 | print('------ Vector never heard "Hey Vector!" ------') 54 | except KeyboardInterrupt: 55 | pass 56 | 57 | 58 | if __name__ == '__main__': 59 | main() 60 | -------------------------------------------------------------------------------- /examples/tutorials/14_user_intent_subscription.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2019 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Return information about a voice commands given to Vector 18 | 19 | The user_intent event is only dispatched when the SDK program has 20 | requested behavior control and Vector gets a voice command. 21 | 22 | After the robot hears "Hey Vector! ..." and a valid voice command is given 23 | (for example "...what time is it?") the event will be dispatched and displayed. 24 | """ 25 | 26 | import threading 27 | 28 | import anki_vector 29 | from anki_vector.events import Events 30 | from anki_vector.user_intent import UserIntent 31 | 32 | 33 | def main(): 34 | def on_user_intent(robot, event_type, event, done): 35 | user_intent = UserIntent(event) 36 | print(f"Received {user_intent.intent_event}") 37 | print(user_intent.intent_data) 38 | done.set() 39 | 40 | args = anki_vector.util.parse_command_args() 41 | with anki_vector.Robot(args.serial) as robot: 42 | done = threading.Event() 43 | robot.events.subscribe(on_user_intent, Events.user_intent, done) 44 | 45 | print('------ Vector is waiting for a voice command like "Hey Vector! What time is it?" Press ctrl+c to exit early ------') 46 | 47 | try: 48 | if not done.wait(timeout=10): 49 | print('------ Vector never heard a voice command ------') 50 | except KeyboardInterrupt: 51 | pass 52 | 53 | 54 | if __name__ == '__main__': 55 | main() 56 | -------------------------------------------------------------------------------- /examples/tutorials/15_face_event_subscription.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Wait for Vector to see a face, and then print output to the console. 18 | 19 | This script demonstrates how to set up a listener for an event. It 20 | subscribes to event 'robot_observed_face'. When that event is dispatched, 21 | method 'on_robot_observed_face' is called, which prints text to the console. 22 | Vector will also say "I see a face" one time, and the program will exit when 23 | he finishes speaking. 24 | """ 25 | 26 | import threading 27 | 28 | import anki_vector 29 | from anki_vector.events import Events 30 | from anki_vector.util import degrees 31 | 32 | said_text = False 33 | 34 | 35 | def main(): 36 | def on_robot_observed_face(robot, event_type, event, done): 37 | print("Vector sees a face") 38 | global said_text 39 | if not said_text: 40 | said_text = True 41 | robot.behavior.say_text("I see a face!") 42 | done.set() 43 | 44 | args = anki_vector.util.parse_command_args() 45 | with anki_vector.Robot(args.serial, enable_face_detection=True) as robot: 46 | 47 | # If necessary, move Vector's Head and Lift to make it easy to see his face 48 | robot.behavior.set_head_angle(degrees(45.0)) 49 | robot.behavior.set_lift_height(0.0) 50 | 51 | done = threading.Event() 52 | robot.events.subscribe(on_robot_observed_face, Events.robot_observed_face, done) 53 | 54 | print("------ waiting for face events, press ctrl+c to exit early ------") 55 | 56 | try: 57 | if not done.wait(timeout=5): 58 | print("------ Vector never saw your face! ------") 59 | except KeyboardInterrupt: 60 | pass 61 | 62 | robot.events.unsubscribe(on_robot_observed_face, Events.robot_observed_face) 63 | 64 | 65 | if __name__ == '__main__': 66 | main() 67 | -------------------------------------------------------------------------------- /examples/tutorials/16_face_follower.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2019 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Make Vector turn toward a face. 18 | 19 | This script shows off the turn_towards_face behavior. It will wait for a face 20 | and then constantly turn towards it to keep it in frame. 21 | """ 22 | 23 | import anki_vector 24 | from anki_vector.events import Events 25 | from anki_vector.util import degrees 26 | import time 27 | 28 | def main(): 29 | args = anki_vector.util.parse_command_args() 30 | with anki_vector.AsyncRobot(args.serial, enable_face_detection=True, show_viewer=True) as robot: 31 | robot.behavior.drive_off_charger() 32 | 33 | # If necessary, move Vector's Head and Lift to make it easy to see his face 34 | robot.behavior.set_head_angle(degrees(45.0)) 35 | robot.behavior.set_lift_height(0.0) 36 | 37 | face_to_follow = None 38 | 39 | print("------ show vector your face, press ctrl+c to exit early ------") 40 | try: 41 | while True: 42 | turn_future = None 43 | if face_to_follow: 44 | # start turning towards the face 45 | turn_future = robot.behavior.turn_towards_face(face_to_follow) 46 | 47 | if not (face_to_follow and face_to_follow.is_visible): 48 | # find a visible face, timeout if nothing found after a short while 49 | for face in robot.world.visible_faces: 50 | face_to_follow = face 51 | break 52 | 53 | if turn_future != None: 54 | # Complete the turn action if one was in progress 55 | turn_future.result() 56 | 57 | time.sleep(.1) 58 | except KeyboardInterrupt: 59 | pass 60 | 61 | if __name__ == "__main__": 62 | main() 63 | -------------------------------------------------------------------------------- /examples/tutorials/17_custom_objects.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """This example demonstrates how you can define custom objects. 18 | 19 | The example defines several custom objects (2 cubes, a wall and a box). When 20 | Vector sees the markers for those objects he will report that he observed an 21 | object of that size and shape there. 22 | 23 | You can adjust the markers, marker sizes, and object sizes to fit whatever 24 | object you have and the exact size of the markers that you print out. 25 | """ 26 | 27 | import time 28 | 29 | import anki_vector 30 | from anki_vector.objects import CustomObjectMarkers, CustomObjectTypes 31 | 32 | 33 | def handle_object_appeared(robot, event_type, event): 34 | # This will be called whenever an EvtObjectAppeared is dispatched - 35 | # whenever an Object comes into view. 36 | print(f"--------- Vector started seeing an object --------- \n{event.obj}") 37 | 38 | 39 | def handle_object_disappeared(robot, event_type, event): 40 | # This will be called whenever an EvtObjectDisappeared is dispatched - 41 | # whenever an Object goes out of view. 42 | print(f"--------- Vector stopped seeing an object --------- \n{event.obj}") 43 | 44 | 45 | def main(): 46 | args = anki_vector.util.parse_command_args() 47 | with anki_vector.Robot(args.serial, 48 | default_logging=False, 49 | show_viewer=True, 50 | show_3d_viewer=True, 51 | enable_custom_object_detection=True, 52 | enable_nav_map_feed=True) as robot: 53 | # Add event handlers for whenever Vector sees a new object 54 | robot.events.subscribe(handle_object_appeared, anki_vector.events.Events.object_appeared) 55 | robot.events.subscribe(handle_object_disappeared, anki_vector.events.Events.object_disappeared) 56 | 57 | # define a unique cube (44mm x 44mm x 44mm) (approximately the same size as Vector's light cube) 58 | # with a 50mm x 50mm Circles2 image on every face. Note that marker_width_mm and marker_height_mm 59 | # parameter values must match the dimensions of the printed marker. 60 | cube_obj = robot.world.define_custom_cube(custom_object_type=CustomObjectTypes.CustomType00, 61 | marker=CustomObjectMarkers.Circles2, 62 | size_mm=44.0, 63 | marker_width_mm=50.0, 64 | marker_height_mm=50.0, 65 | is_unique=True) 66 | 67 | # define a unique cube (88mm x 88mm x 88mm) (approximately 2x the size of Vector's light cube) 68 | # with a 50mm x 50mm Circles3 image on every face. 69 | big_cube_obj = robot.world.define_custom_cube(custom_object_type=CustomObjectTypes.CustomType01, 70 | marker=CustomObjectMarkers.Circles3, 71 | size_mm=88.0, 72 | marker_width_mm=50.0, 73 | marker_height_mm=50.0, 74 | is_unique=True) 75 | 76 | # define a unique wall (150mm x 120mm (x10mm thick for all walls) 77 | # with a 50mm x 30mm Triangles2 image on front and back 78 | wall_obj = robot.world.define_custom_wall(custom_object_type=CustomObjectTypes.CustomType02, 79 | marker=CustomObjectMarkers.Triangles2, 80 | width_mm=150, 81 | height_mm=120, 82 | marker_width_mm=50, 83 | marker_height_mm=30, 84 | is_unique=True) 85 | 86 | # define a unique box (20mm deep x 20mm width x20mm tall) 87 | # with a different 50mm x 50mm image on each of the 6 faces 88 | box_obj = robot.world.define_custom_box(custom_object_type=CustomObjectTypes.CustomType03, 89 | marker_front=CustomObjectMarkers.Diamonds2, # front 90 | marker_back=CustomObjectMarkers.Hexagons2, # back 91 | marker_top=CustomObjectMarkers.Hexagons3, # top 92 | marker_bottom=CustomObjectMarkers.Hexagons4, # bottom 93 | marker_left=CustomObjectMarkers.Triangles3, # left 94 | marker_right=CustomObjectMarkers.Triangles4, # right 95 | depth_mm=20.0, 96 | width_mm=20.0, 97 | height_mm=20.0, 98 | marker_width_mm=50.0, 99 | marker_height_mm=50.0, 100 | is_unique=True) 101 | 102 | if ((cube_obj is not None) and (big_cube_obj is not None) and 103 | (wall_obj is not None) and (box_obj is not None)): 104 | print("All objects defined successfully!") 105 | else: 106 | print("One or more object definitions failed!") 107 | return 108 | 109 | print("\n\nShow a marker specified in the Python script to Vector and you will see the related 3d objects\n" 110 | "display in Vector's 3d_viewer window. You will also see messages print every time a custom object\n" 111 | "enters or exits Vector's view. Markers can be found from the docs under CustomObjectMarkers.\n\n") 112 | 113 | try: 114 | while True: 115 | time.sleep(0.5) 116 | except KeyboardInterrupt: 117 | pass 118 | 119 | 120 | if __name__ == "__main__": 121 | main() 122 | -------------------------------------------------------------------------------- /examples/tutorials/18_create_wall.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2018 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Use custom objects to create a wall in front of Vector. 18 | 19 | This example demonstrates how you can create custom objects in the world, and 20 | automatically have Vector path around them as if they are real obstacles. 21 | 22 | It creates a wall in front of Vector and tells him to drive around it. 23 | He will plan a path to drive 200mm in front of himself after these objects are created. 24 | 25 | The `show_3d_viewer=True` argument causes the 3D visualizer to open in a new 26 | window - this shows where Vector believes this imaginary object is. 27 | """ 28 | 29 | import anki_vector 30 | from anki_vector.util import Pose, degrees 31 | 32 | 33 | def main(): 34 | args = anki_vector.util.parse_command_args() 35 | with anki_vector.Robot(args.serial, 36 | show_3d_viewer=True, 37 | enable_nav_map_feed=True) as robot: 38 | robot.behavior.drive_off_charger() 39 | 40 | fixed_object = robot.world.create_custom_fixed_object(Pose(100, 0, 0, angle_z=degrees(0)), 41 | 10, 100, 100, relative_to_robot=True) 42 | if fixed_object: 43 | print("fixed custom object created successfully") 44 | 45 | robot.behavior.go_to_pose(Pose(200, 0, 0, angle_z=degrees(0)), relative_to_robot=True) 46 | robot.world.delete_custom_objects() 47 | 48 | 49 | if __name__ == "__main__": 50 | main() 51 | -------------------------------------------------------------------------------- /examples/tutorials/19_annotate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2019 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | '''Display a GUI window showing an annotated camera view. 18 | 19 | Note: 20 | This example requires Python to have Tkinter installed to display the GUI. 21 | 22 | This example uses tkinter to display the annotated camera feed on the screen 23 | and adds a couple of custom annotations of its own using two different methods. 24 | ''' 25 | 26 | import asyncio 27 | import sys 28 | import time 29 | 30 | from PIL import ImageDraw 31 | 32 | import anki_vector 33 | from anki_vector import annotate 34 | 35 | 36 | # Define an annotator using the annotator decorator 37 | @annotate.annotator 38 | def clock(image, scale, annotator=None, world=None, **kw): 39 | d = ImageDraw.Draw(image) 40 | bounds = (0, 0, image.width, image.height) 41 | text = annotate.ImageText(time.strftime("%H:%m:%S"), 42 | position=annotate.AnnotationPosition.TOP_LEFT, 43 | outline_color="black") 44 | text.render(d, bounds) 45 | 46 | # Define a new annotator by inheriting the base annotator class 47 | class Battery(annotate.Annotator): 48 | def __init__(self, img_annotator, box_color=None): 49 | super().__init__(img_annotator) 50 | self.battery_state = None 51 | self.battery_state_task = None 52 | if box_color is not None: 53 | self.box_color = box_color 54 | 55 | def apply(self, image, scale): 56 | d = ImageDraw.Draw(image) 57 | bounds = (0, 0, image.width, image.height) 58 | 59 | if not self.battery_state_task: 60 | self.battery_state_task = self.world.robot.get_battery_state() 61 | 62 | if asyncio.isfuture(self.battery_state_task) and self.battery_state_task.done(): 63 | self.battery_state = self.battery_state_task.result() 64 | self.battery_state_task = self.world.robot.get_battery_state() 65 | 66 | if self.battery_state: 67 | batt = self.battery_state.battery_volts 68 | text = annotate.ImageText(f"BATT {batt:.1f}v", color="green", outline_color="black") 69 | text.render(d, bounds) 70 | 71 | 72 | def main(): 73 | args = anki_vector.util.parse_command_args() 74 | with anki_vector.Robot(args.serial, show_viewer=True, enable_face_detection=True) as robot: 75 | robot.camera.image_annotator.add_static_text("text", "Vec-Cam", position=annotate.AnnotationPosition.TOP_RIGHT) 76 | robot.camera.image_annotator.add_annotator("clock", clock) 77 | robot.camera.image_annotator.add_annotator("battery", Battery) 78 | 79 | time.sleep(10) 80 | 81 | print("Turning off all annotations for 5 seconds") 82 | robot.camera.image_annotator.annotation_enabled = False 83 | time.sleep(5) 84 | 85 | print("Re-enabling all annotations") 86 | robot.camera.image_annotator.annotation_enabled = True 87 | 88 | print("------ Press ctrl+c to exit early ------") 89 | 90 | try: 91 | # Shutdown the program after 30 seconds 92 | time.sleep(30) 93 | except KeyboardInterrupt: 94 | pass 95 | 96 | 97 | if __name__ == "__main__": 98 | main() 99 | -------------------------------------------------------------------------------- /examples/tutorials/20_exposure.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2019 Anki, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License in the file LICENSE.txt or at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | '''Demonstrate the manual and auto exposure settings of Vector's camera. 18 | 19 | This example demonstrates the use of auto exposure and manual exposure for 20 | Vector's camera. The current camera settings are overlaid onto the camera 21 | viewer window. 22 | ''' 23 | 24 | 25 | import sys 26 | import time 27 | 28 | try: 29 | from PIL import ImageDraw 30 | import numpy as np 31 | except ImportError: 32 | sys.exit('run `pip3 install --user Pillow numpy` to run this example') 33 | 34 | import anki_vector 35 | from anki_vector import annotate 36 | 37 | 38 | # Global values to display in the camera viewer window 39 | example_mode = "" 40 | 41 | 42 | def demo_camera_exposure(robot: anki_vector.Robot): 43 | """ 44 | Run through camera exposure settings 45 | """ 46 | global example_mode 47 | 48 | # Ensure camera is in auto exposure mode and demonstrate auto exposure for 5 seconds 49 | camera = robot.camera 50 | camera.enable_auto_exposure() 51 | example_mode = "Auto Exposure" 52 | time.sleep(5) 53 | 54 | # Demonstrate manual exposure, linearly increasing the exposure time, while 55 | # keeping the gain fixed at a medium value. 56 | example_mode = "Manual Exposure - Increasing Exposure, Fixed Gain" 57 | fixed_gain = (camera.config.min_gain + camera.config.max_gain) * 0.5 58 | for exposure in range(camera.config.min_exposure_time_ms, camera.config.max_exposure_time_ms+1, 1): 59 | camera.set_manual_exposure(exposure, fixed_gain) 60 | time.sleep(0.1) 61 | 62 | # Demonstrate manual exposure, linearly increasing the gain, while keeping 63 | # the exposure fixed at a relatively low value. 64 | example_mode = "Manual Exposure - Increasing Gain, Fixed Exposure" 65 | fixed_exposure_ms = 10 66 | for gain in np.arange(camera.config.min_gain, camera.config.max_gain, 0.05): 67 | camera.set_manual_exposure(fixed_exposure_ms, gain) 68 | time.sleep(0.1) 69 | 70 | # Switch back to auto exposure, demo for a final 5 seconds and then return 71 | camera.enable_auto_exposure() 72 | example_mode = "Mode: Auto Exposure" 73 | time.sleep(5) 74 | 75 | 76 | class CameraSettings(annotate.Annotator): 77 | """ 78 | An annotator for live-display of camera settings on top of the camera 79 | viewer window. 80 | """ 81 | def apply(self, image, scale): 82 | d = ImageDraw.Draw(image) 83 | bounds = (0, 0, image.width, image.height) 84 | camera = self.world.robot.camera 85 | 86 | text_to_display = "Example Mode: " + example_mode + "\n\n" 87 | text_to_display += "Fixed Camera Settings (Calibrated for this Robot):\n" 88 | text_to_display += ' focal_length: %s\n' % camera.config.focal_length 89 | text_to_display += ' center: %s\n' % camera.config.center 90 | text_to_display += ' fov: <%.3f, %.3f> degrees\n' % (camera.config.fov_x.degrees, 91 | camera.config.fov_y.degrees) 92 | text_to_display += "\nValid exposure and gain ranges:\n" 93 | text_to_display += ' Exposure: %s..%s\n' % (camera.config.min_exposure_time_ms, 94 | camera.config.max_exposure_time_ms) 95 | text_to_display += ' Gain: %.2f..%.2f\n' % (camera.config.min_gain, 96 | camera.config.max_gain) 97 | text_to_display += "\nCurrent settings:\n" 98 | text_to_display += ' Auto Exposure Enabled: %s\n' % camera.is_auto_exposure_enabled 99 | text_to_display += ' Exposure: %s ms\n' % camera.exposure_ms 100 | text_to_display += ' Gain: %.2f\n' % camera.gain 101 | 102 | text = annotate.ImageText(text_to_display, 103 | position=annotate.AnnotationPosition.TOP_LEFT, 104 | color="yellow", 105 | outline_color="black") 106 | text.render(d, bounds) 107 | 108 | 109 | def main(): 110 | args = anki_vector.util.parse_command_args() 111 | with anki_vector.Robot(args.serial, show_viewer=True) as robot: 112 | robot.camera.image_annotator.add_annotator("camera_settings", CameraSettings) 113 | demo_camera_exposure(robot) 114 | 115 | 116 | if __name__ == "__main__": 117 | main() 118 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | aiogrpc>=1.4 2 | cryptography 3 | flask 4 | googleapis-common-protos 5 | numpy>=1.11 6 | Pillow>=3.3 7 | requests 8 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 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 | Anki/DDL Vector - Python SDK: 17 | by cyb3rdog 18 | 19 | ## With support for Production, wire-pod and OSKR robots! ## 20 | This is the extended fork of the original Anki Vector Python SDK. 21 | 22 | For more information, please visit the project Github site: https://github.com/cyb3rdog/vector-python-sdk 23 | 24 | The Vector SDK gives you direct access to Vector's unprecedented set of advanced sensors, AI capabilities, and robotics technologies including computer vision, intelligent mapping and navigation, and a groundbreaking collection of expressive animations. 25 | 26 | It's powerful but easy to use, complex but not complicated, and versatile enough to be used across a wide range of domains including enterprise, research, and entertainment. Find out more at https://developer.anki.com 27 | 28 | Vector SDK documentation: https://developer.anki.com/vector/docs/ 29 | 30 | Official developer forum: https://forums.anki.com/ 31 | 32 | Requirements: 33 | * Python 3.7 34 | * Python 3.8 35 | * Python 3.9 36 | * Python 3.10 37 | * Python 3.11 38 | """ 39 | 40 | import os.path 41 | import sys 42 | from setuptools import setup 43 | 44 | if sys.version_info < (3, 6, 1): 45 | sys.exit('The Vector SDK requires Python 3.6.1 or later') 46 | 47 | HERE = os.path.abspath(os.path.dirname(__file__)) 48 | 49 | def fetch_version(): 50 | """Get the version from the package""" 51 | with open(os.path.join(HERE, 'anki_vector', 'version.py')) as version_file: 52 | versions = {} 53 | exec(version_file.read(), versions) 54 | return versions 55 | 56 | VERSION_DATA = fetch_version() 57 | VERSION = VERSION_DATA['__version__'] 58 | 59 | def get_requirements(): 60 | """Load the requirements from requirements.txt into a list""" 61 | reqs = [] 62 | with open(os.path.join(HERE, 'requirements.txt')) as requirements_file: 63 | for line in requirements_file: 64 | reqs.append(line.strip()) 65 | return reqs 66 | 67 | setup( 68 | name='wirepod_vector_sdk', 69 | version=VERSION, 70 | description="The Vector SDK is a connected vision- and character-based robotics platform for everyone.", 71 | long_description=__doc__, 72 | url='https://github.com/kercre123/wirepod-vector-python-sdk', 73 | author='Anki, Inc', 74 | author_email='developer@anki.com', 75 | license='Apache License, Version 2.0', 76 | # See https://pypi.python.org/pypi?%3Aaction=list_classifiers 77 | classifiers=[ 78 | 'Development Status :: 3 - Alpha', 79 | 'Intended Audience :: Developers', 80 | 'Topic :: Software Development :: Libraries', 81 | 'License :: OSI Approved :: Apache Software License', 82 | 'Programming Language :: Python :: 3.6', 83 | 'Programming Language :: Python :: 3.7', 84 | 'Programming Language :: Python :: 3.8', 85 | 'Programming Language :: Python :: 3.11', 86 | ], 87 | zip_safe=True, 88 | keywords='anki wire pod wire-pod vector robot robotics sdk ai vision'.split(), 89 | packages=['anki_vector', 'anki_vector.camera_viewer', 'anki_vector.configure', 'anki_vector.messaging', 'anki_vector.opengl', 'anki_vector.reserve_control'], 90 | package_data={ 91 | 'anki_vector': ['LICENSE.txt', 'opengl/assets/*.obj', 'opengl/assets/*.mtl', 'opengl/assets/*.jpg', 92 | 'opengl/assets/LICENSE.txt'] 93 | }, 94 | install_requires=get_requirements(), 95 | extras_require={ 96 | '3dviewer': ['PyOpenGL>=3.1'], 97 | 'docs': ['sphinx', 'sphinx_rtd_theme', 'sphinx_autodoc_typehints'], 98 | 'experimental': ['keras', 'scikit-learn', 'scipy', 'tensorflow'], 99 | 'test': ['pytest', 'requests', 'requests_toolbelt'], 100 | } 101 | ) 102 | --------------------------------------------------------------------------------