diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index efe1780..0000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1,4 +0,0 @@ -# https://help.github.com/articles/about-codeowners/ - -# These owners will be the default owners for everything in the repo. -* @anki/cozmo-sdk-admins diff --git a/.gitignore b/.gitignore index 22b5e3d..11f475e 100644 --- a/.gitignore +++ b/.gitignore @@ -15,8 +15,6 @@ dist/ downloads/ eggs/ .eggs/ -lib/ -lib64/ parts/ sdist/ var/ @@ -113,4 +111,11 @@ venv.bak/ dmypy.json # Pyre type checker -.pyre/ \ No newline at end of file +.pyre/ + +# pipenv +Pipfile +Pipfile.lock + +# VSCode +.vscode/ \ No newline at end of file diff --git a/Makefile b/Makefile deleted file mode 100644 index ecd3565..0000000 --- a/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -.PHONY: clean dist examples license wheel installer - -version = $(shell perl -ne '/__version__ = "([^"]+)/ && print $$1;' anki_vector/version.py) - -license_targets = anki_vector/LICENSE.txt examples/LICENSE.txt -example_targets = dist/anki_vector_sdk_examples.tar.gz dist/anki_vector_sdk_examples.zip - -example_filenames = $(shell cd examples && find . -name '*.py' -o -name '*.txt' -o -name '*.png' -o -name '*.jpg' -o -name '*.md' -o -name '*.json') -example_pathnames = $(shell find examples -name '*.py' -o -name '*.txt' -o -name '*.png' -o -name '*.jpg' -o -name '*.md' -o -name '*.json') -sdist_filename = dist/anki_vector-$(version).tar.gz -wheel_filename = dist/anki_vector-$(version)-py3-none-any.whl - -license: $(license_targets) - -$(license_targets): LICENSE.txt - for fn in $(license_targets); do \ - cp LICENSE.txt $$fn; \ - done - -$(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') - python3 setup.py sdist - -$(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') - python3 setup.py bdist_wheel - -dist/anki_vector_sdk_examples.zip: examples/LICENSE.txt $(example_pathnames) - rm -f dist/anki_vector_sdk_examples.zip dist/anki_vector_sdk_examples_$(version).zip - rm -rf dist/anki_vector_sdk_examples_$(version) - mkdir dist/anki_vector_sdk_examples_$(version) - tar -C examples -c $(example_filenames) | tar -C dist/anki_vector_sdk_examples_$(version) -xv - cd dist && zip -r anki_vector_sdk_examples.zip anki_vector_sdk_examples_$(version) - cd dist && zip -r anki_vector_sdk_examples_$(version).zip anki_vector_sdk_examples_$(version) - -dist/anki_vector_sdk_examples.tar.gz: examples/LICENSE.txt $(example_pathnames) - rm -f dist/anki_vector_sdk_examples.tar.gz dist/anki_vector_sdk_examples_$(version).tar.gz - rm -rf dist/anki_vector_sdk_examples_$(version) - mkdir dist/anki_vector_sdk_examples_$(version) - tar -C examples -c $(example_filenames) | tar -C dist/anki_vector_sdk_examples_$(version) -xv - cd dist && tar -cvzf anki_vector_sdk_examples.tar.gz anki_vector_sdk_examples_$(version) - cp -a dist/anki_vector_sdk_examples.tar.gz dist/anki_vector_sdk_examples_$(version).tar.gz - -examples: dist/anki_vector_sdk_examples.tar.gz dist/anki_vector_sdk_examples.zip - -dist: $(sdist_filename) $(wheel_filename) examples - -clean: - rm -rf dist diff --git a/README.md b/README.md index 4c37c1a..c16d793 100644 --- a/README.md +++ b/README.md @@ -1,21 +1 @@ -# Anki Vector - Python SDK - -![Vector](docs/source/images/vector-sdk-alpha.jpg) - -Learn more about Vector: https://www.anki.com/vector - -Learn more about the SDK: https://developer.anki.com/ - -SDK documentation: http://developer.anki.com/vector/docs/ - -Forums: https://forums.anki.com/ - - -## Getting Started - -You can follow steps [here](http://developer.anki.com/vector/docs/) to set up your Vector robot with the SDK. - - -## Privacy Policy and Terms and Conditions - -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). +# Vector Remote Controller diff --git a/anki_vector/__init__.py b/anki_vector/__init__.py deleted file mode 100755 index e4cbc9a..0000000 --- a/anki_vector/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -SDK for programming with the Anki Vector robot. -""" - -import sys -import logging - -from . import messaging -from .robot import Robot, AsyncRobot -from .version import __version__ - -logger = logging.getLogger('vector') # pylint: disable=invalid-name - -if sys.version_info < (3, 6, 1): - sys.exit('anki_vector requires Python 3.6.1 or later') - -__all__ = ['Robot', 'AsyncRobot', 'logger', 'messaging', '__version__'] diff --git a/anki_vector/animation.py b/anki_vector/animation.py deleted file mode 100644 index d7ad9b4..0000000 --- a/anki_vector/animation.py +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Animation related classes, functions, events and values. - -Animations represent a sequence of highly coordinated movements, faces, lights, and sounds used to demonstrate an emotion or reaction. - -Animations can control the following tracks: head, lift, treads, face, audio and backpack lights. - -There are two ways to play an animation on Vector: play_animation and play_animation_trigger (not yet implemented). When calling play_animation, -you select the specific animation you want the robot to run. For play_animation_trigger, you select a group of animations, and the robot -will choose which animation from the group to run when you execute the method. - -By default, when an SDK program starts, the SDK will request a list of known animations from the robot, which will be loaded into anim_list -in the AnimationComponent. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ["AnimationComponent"] - -import concurrent - -from . import connection, exceptions, util -from .messaging import protocol - - -class AnimationComponent(util.Component): - """Play animations on the robot""" - - def __init__(self, robot): - super().__init__(robot) - self._anim_dict = {} - - @property - def anim_list(self): - """ - Holds the set of animation names (strings) returned from the robot. - - Animation names are dynamically retrieved from the robot when the Python - script connects to it. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - print("List all animation names:") - anim_names = robot.anim.anim_list - for anim_name in anim_names: - print(anim_name) - """ - if not self._anim_dict: - self.logger.warning("Anim list was empty. Lazy-loading anim list now.") - result = self.load_animation_list() - if isinstance(result, concurrent.futures.Future): - result.result() - return list(self._anim_dict.keys()) - - async def _ensure_loaded(self): - """ - This is an optimization for the case where a user doesn't - need the animation_list. This way, connections aren't delayed - by the load_animation_list call. - - If this is invoked inside another async function then we - explicitly await the result. - """ - if not self._anim_dict: - self.logger.warning("Anim list was empty. Lazy-loading anim list now.") - await self._load_animation_list() - - async def _load_animation_list(self): - req = protocol.ListAnimationsRequest() - result = await self.grpc_interface.ListAnimations(req) - self.logger.debug(f"status: {result.status}, number_of_animations:{len(result.animation_names)}") - self._anim_dict = {a.name: a for a in result.animation_names} - return result - - @connection.on_connection_thread(log_messaging=False, requires_control=False) - async def load_animation_list(self): - """Request the list of animations from the robot - - When the request has completed, anim_list will be populated with - the list of animations the robot knows how to run. - - .. testcode:: - - import anki_vector - - with anki_vector.AsyncRobot() as robot: - anim_request = robot.anim.load_animation_list() - anim_request.result() - anim_names = robot.anim.anim_list - for anim_name in anim_names: - print(anim_name) - """ - return await self._load_animation_list() - - @connection.on_connection_thread() - async def play_animation(self, anim: str, loop_count: int = 1, ignore_body_track: bool = False, ignore_head_track: bool = False, ignore_lift_track: bool = False): - """Starts an animation playing on a robot. - - Vector must be off of the charger to play an animation. - - Warning: Specific animations may be renamed or removed in future updates of the app. - If you want your program to work more reliably across all versions - we recommend using :meth:`play_animation_trigger` instead. (:meth:`play_animation_trigger` is still in development.) - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.anim.play_animation('anim_turn_left_01') - - :param anim: The animation to play. Can be of type str or :class:`anki_vector.protocol.Animation`. - :param loop_count: Number of times to play the animation. - :param ignore_body_track: True to ignore the animation track for Vector's body (i.e. the wheels / treads). - :param ignore_head_track: True to ignore the animation track for Vector's head. - :param ignore_lift_track: True to ignore the animation track for Vector's lift. - """ - animation = anim - if not isinstance(anim, protocol.Animation): - await self._ensure_loaded() - if anim not in self.anim_list: - raise exceptions.VectorException(f"Unknown animation: {anim}") - animation = self._anim_dict[anim] - req = protocol.PlayAnimationRequest(animation=animation, - loops=loop_count, - ignore_body_track=ignore_body_track, - ignore_head_track=ignore_head_track, - ignore_lift_track=ignore_lift_track) - return await self.grpc_interface.PlayAnimation(req) diff --git a/anki_vector/audio.py b/anki_vector/audio.py deleted file mode 100644 index 553e62c..0000000 --- a/anki_vector/audio.py +++ /dev/null @@ -1,177 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Support for Vector's audio. - -Vector has multiple built-in microphones which can detect sound and the direction -it originated from. The robot then processing this data into a single-channel -audio feed available to the SDK. - -The :class:`AudioComponent` class defined in this module is made available as -:attr:`anki_vector.robot.Robot.audio` and can be used to enable/disable audio -sending and process audio data being sent by the robot. -""" - -# TODO Not yet supported. Audio from robot does not yet reach Python. - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['AudioComponent'] - -import asyncio -from concurrent.futures import CancelledError -import sys - -from . import util -from .events import Events -from .messaging import protocol - -try: - import numpy as np -except ImportError: - sys.exit("Cannot import numpy: Do `pip3 install numpy` to install") - - -class AudioComponent(util.Component): - """Represents Vector's audio feed. - - The AudioComponent object receives audio data from Vector's microphones. - - The :class:`anki_vector.robot.Robot` or :class:`anki_vector.robot.AsyncRobot` instance owns this audio component. - - .. code-block:: python - - import time - - try: - from scipy.io import wavfile - except ImportError as exc: - sys.exit("Cannot import scipy: Do `pip3 install scipy` to install") - - with anki_vector.Robot(enable_audio_feed=True) as robot: - time.sleep(5.0) - wavfile.write("outputfile.wav", anki_vector.protocol.PROCESSED_SAMPLE_RATE, robot.audio.raw_audio_waveform_history) - - :param robot: A reference to the owner Robot object. - """ - # TODO When audio is ready, convert `.. code-block:: python` to `.. testcode::` - - def __init__(self, robot): - super().__init__(robot) - - # @TODO: Add a variable tracking the current audio send mode once that is implemented - self._raw_audio_waveform_history = np.empty(0, dtype=np.int16) - self._latest_sample_id = None - - self._audio_processing_mode = None - - self._audio_feed_task: asyncio.Task = None - - # Subscribe to callbacks related to objects - robot.events.subscribe(self._on_audio_send_mode_changed_event, - Events.audio_send_mode_changed) - - # @TODO: Implement audio history as ringbuffer, caching only recent audio - # @TODO: Add function to return a recent chunk of the audio history in a standardized python audio package format - # @TODO: Add hook for feeding audio stream into external voice processing library - - @property - def raw_audio_waveform_history(self) -> np.array: - """:class:`np.array`: The most recent processed image received from the robot. - - Audio history as signed-16-bit-int waveform data - - The sample rate from the microphones is 15625, which the robot processes at 16khz. As a result the pitch is - altered by 2.4%. The last 16000 values of the array represent the last second of audio amplitude. - - .. code-block:: python - - import time - - try: - from scipy.io import wavfile - except ImportError as exc: - sys.exit("Cannot import scipy: Do `pip3 install scipy` to install") - - with anki_vector.Robot(enable_audio_feed=True) as robot: - time.sleep(5.0) - wavfile.write("outputfile.wav", anki_vector.protocol.PROCESSED_SAMPLE_RATE, robot.audio.raw_audio_waveform_history) - - :getter: Returns the numpy array representing the audio history - """ - # TODO When audio is ready, convert `.. code-block:: python` to `.. testcode::` - return self._raw_audio_waveform_history - - @property - def latest_sample_id(self) -> int: - """The most recent received audio sample from the robot. - - :getter: Returns the id for the latest audio sample - """ - return self._latest_sample_id - - @property - def audio_processing_mode(self) -> protocol.AudioProcessingMode: - """The current mode which the robot is processing audio. - - :getter: Returns the most recently received audio processing mode on the robot - """ - return self._audio_processing_mode - - def init_audio_feed(self) -> None: - """Begin audio feed task""" - if not self._audio_feed_task or self._audio_feed_task.done(): - self._audio_feed_task = self.robot.loop.create_task(self._request_and_handle_audio()) - - def close_audio_feed(self) -> None: - """Cancel audio feed task""" - if self._audio_feed_task: - self._audio_feed_task.cancel() - self.robot.loop.run_until_complete(self._audio_feed_task) - - def _on_audio_send_mode_changed_event(self, msg: protocol.AudioSendModeChanged) -> None: - """Callback for changes in the robot's audio processing mode""" - self._audio_processing_mode = msg.mode - self.logger.info('Audio processing mode changed to {0}'.format(self._audio_processing_mode)) - - def _process_audio(self, msg: protocol.AudioFeedResponse) -> None: - """Processes raw data from the robot into a more more useful image structure.""" - audio_data = msg.signal_power - - expected_size = protocol.SAMPLE_COUNTS_PER_SDK_MESSAGE - received_size = int(len(audio_data) / 2) - if expected_size != received_size: - self.logger.warning('WARNING: audio stream received {0} bytes while {1} were expected'.format(received_size, expected_size)) - - # Constuct numpy array out of source data - array = np.frombuffer(audio_data, dtype=np.int16, count=received_size, offset=0) - - # Append to audio history - self._raw_audio_waveform_history = np.append(self._raw_audio_waveform_history, array) - - self._latest_sample_id = len(self._raw_audio_waveform_history) - 1 - - async def _request_and_handle_audio(self) -> None: - """Queries and listens for audio feed events from the robot. - Received events are parsed by a helper function.""" - try: - req = protocol.AudioFeedRequest() - async for evt in self.grpc_interface.AudioFeed(req): - # If the audio feed is disabled after stream is setup, exit the stream - # (the audio feed on the robot is disabled internally on stream exit) - if not self.robot.enable_audio_feed: - self.logger.warning('Audio feed has been disabled. Enable the feed to start/continue receiving audio feed data') - return - self._process_audio(evt) - except CancelledError: - self.logger.debug('Audio feed task was cancelled. This is expected during disconnection.') diff --git a/anki_vector/behavior.py b/anki_vector/behavior.py deleted file mode 100644 index eb652fc..0000000 --- a/anki_vector/behavior.py +++ /dev/null @@ -1,488 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -.. _behavior: - -Behavior related classes and functions. - -Behaviors represent a complex task which requires Vector's -internal logic to determine how long it will take. This -may include combinations of animation, path planning or -other functionality. Examples include :meth:`drive_on_charger`, -:meth:`set_lift_height`, etc. - -For commands such as :meth:`go_to_pose`, :meth:`drive_on_charger` and :meth:`dock_with_cube`, -Vector uses path planning, which refers to the problem of -navigating the robot from point A to B without collisions. Vector -loads known obstacles from his map, creates a path to navigate -around those objects, then starts following the path. If a new obstacle -is found while following the path, a new plan may be created. - -The :class:`BehaviorComponent` class in this module contains -functions for all the behaviors. -""" - -__all__ = ["MAX_HEAD_ANGLE", "MIN_HEAD_ANGLE", - "MAX_LIFT_HEIGHT", "MAX_LIFT_HEIGHT_MM", "MIN_LIFT_HEIGHT", "MIN_LIFT_HEIGHT_MM", - "BehaviorComponent"] - - -from . import connection, objects, util -from .messaging import protocol - -# Constants - -#: The minimum angle the robot's head can be set to. -MIN_HEAD_ANGLE = util.degrees(-22.0) - -#: The maximum angle the robot's head can be set to -MAX_HEAD_ANGLE = util.degrees(45.0) - -# The lowest height-above-ground that lift can be moved to in millimeters. -MIN_LIFT_HEIGHT_MM = 32.0 - -#: The lowest height-above-ground that lift can be moved to -MIN_LIFT_HEIGHT = util.distance_mm(MIN_LIFT_HEIGHT_MM) - -# The largest height-above-ground that lift can be moved to in millimeters. -MAX_LIFT_HEIGHT_MM = 92.0 - -#: The largest height-above-ground that lift can be moved to -MAX_LIFT_HEIGHT = util.distance_mm(MAX_LIFT_HEIGHT_MM) - - -# TODO: Expose is_active and priority states of the SDK behavior control from this class. -class BehaviorComponent(util.Component): - """Run behaviors on Vector""" - - _next_action_id = protocol.FIRST_SDK_TAG - - def __init__(self, robot): - super().__init__(robot) - self._motion_profile_map = {} - - # TODO Make the motion_profile_map into a class. - @property - def motion_profile_map(self) -> dict: - """Tells Vector how to drive when receiving navigation and movement actions - such as go_to_pose and dock_with_cube. - - motion_prof_map values are as follows: - | speed_mmps (float) - | accel_mmps2 (float) - | decel_mmps2 (float) - | point_turn_speed_rad_per_sec (float) - | point_turn_accel_rad_per_sec2 (float) - | point_turn_decel_rad_per_sec2 (float) - | dock_speed_mmps (float) - | dock_accel_mmps2 (float) - | dock_decel_mmps2 (float) - | reverse_speed_mmps (float) - | is_custom (bool) - - :getter: Returns the motion profile map - :setter: Sets the motion profile map - - :param motion_prof_map: Provide custom speed, acceleration and deceleration - values with which the robot goes to the given pose. - """ - return self._motion_profile_map - - @motion_profile_map.setter - def motion_profile_map(self, motion_profile_map: dict): - self._motion_profile_map = motion_profile_map - - def _motion_profile_for_proto(self) -> protocol.PathMotionProfile: - """Packages the current motion profile into a proto object - - Returns: - A profile object describing motion which can be passed with any proto action message. - """ - # TODO: This should be made into its own class - default_motion_profile = { - "speed_mmps": 100.0, - "accel_mmps2": 200.0, - "decel_mmps2": 500.0, - "point_turn_speed_rad_per_sec": 2.0, - "point_turn_accel_rad_per_sec2": 10.0, - "point_turn_decel_rad_per_sec2": 10.0, - "dock_speed_mmps": 60.0, - "dock_accel_mmps2": 200.0, - "dock_decel_mmps2": 500.0, - "reverse_speed_mmps": 80.0, - "is_custom": 1 if self._motion_profile_map else 0 - } - default_motion_profile.update(self._motion_profile_map) - - return protocol.PathMotionProfile(**default_motion_profile) - - @classmethod - def _get_next_action_id(cls): - # Post increment _current_action_id (and loop within the SDK_TAG range) - next_action_id = cls._next_action_id - if cls._next_action_id == protocol.LAST_SDK_TAG: - cls._next_action_id = protocol.FIRST_SDK_TAG - else: - cls._next_action_id += 1 - return next_action_id - - # Navigation actions - @connection.on_connection_thread() - async def drive_off_charger(self): - """Drive Vector off the charger - - If Vector is on the charger, drives him off the charger. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.behavior.drive_off_charger() - """ - drive_off_charger_request = protocol.DriveOffChargerRequest() - return await self.grpc_interface.DriveOffCharger(drive_off_charger_request) - - @connection.on_connection_thread() - async def drive_on_charger(self): - """Drive Vector onto the charger - - Vector will attempt to find the charger and, if successful, he will - back onto it and start charging. - - Vector's charger has a visual marker so that the robot can locate it - for self-docking. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.behavior.drive_on_charger() - """ - drive_on_charger_request = protocol.DriveOnChargerRequest() - return await self.grpc_interface.DriveOnCharger(drive_on_charger_request) - - @connection.on_connection_thread() - async def set_eye_color(self, hue: float, saturation: float) -> protocol.SetEyeColorResponse: - """Set Vector's eye color. - - .. testcode:: - - import anki_vector - import time - - with anki_vector.Robot() as robot: - print("Set Vector's eye color to purple...") - robot.behavior.set_eye_color(0.83, 0.76) - time.sleep(5) - - :param hue: The hue to use for Vector's eyes. - :param saturation: The saturation to use for Vector's eyes. - """ - eye_color_request = protocol.SetEyeColorRequest(hue=hue, saturation=saturation) - return await self.conn.grpc_interface.SetEyeColor(eye_color_request) - - @connection.on_connection_thread() - async def go_to_pose(self, - pose: util.Pose, - relative_to_robot: bool = False, - num_retries: int = 0) -> protocol.GoToPoseResponse: - """Tells Vector to drive to the specified pose and orientation. - - In navigating to the requested pose, Vector will use path planning. - - If relative_to_robot is set to True, the given pose will assume the - robot's pose as its origin. - - Since the robot understands position by monitoring its tread movement, - it does not understand movement in the z axis. This means that the only - applicable elements of pose in this situation are position.x position.y - and rotation.angle_z. - - :param pose: The destination pose. - :param relative_to_robot: Whether the given pose is relative to - the robot's pose. - :param num_retries: Number of times to re-attempt action in case of a failure. - - Returns: - A response from the robot with status information sent when this request successfully completes or fails. - - .. testcode:: - - import anki_vector - from anki_vector.util import degrees, Pose - - with anki_vector.Robot() as robot: - pose = Pose(x=50, y=0, z=0, angle_z=anki_vector.util.Angle(degrees=0)) - robot.behavior.go_to_pose(pose) - """ - if relative_to_robot and self.robot.pose: - pose = self.robot.pose.define_pose_relative_this(pose) - - motion_prof = self._motion_profile_for_proto() - # @TODO: the id_tag we supply can be used to cancel this action, - # however when we implement that we will need some way to get the id_tag - # out of this function. - go_to_pose_request = protocol.GoToPoseRequest(x_mm=pose.position.x, - y_mm=pose.position.y, - rad=pose.rotation.angle_z.radians, - motion_prof=motion_prof, - id_tag=self._get_next_action_id(), - num_retries=num_retries) - - return await self.grpc_interface.GoToPose(go_to_pose_request) - - # TODO alignment_type coming out ugly in the docs without real values - @connection.on_connection_thread() - async def dock_with_cube(self, - target_object: objects.LightCube, - approach_angle: util.Angle = None, - alignment_type: protocol.AlignmentType = protocol.ALIGNMENT_TYPE_LIFT_PLATE, - distance_from_marker: util.Distance = None, - num_retries: int = 0) -> protocol.DockWithCubeResponse: - """Tells Vector to dock with a light cube, optionally using a given approach angle and distance. - - While docking with the cube, Vector will use path planning. - - :param target_object: The LightCube object to dock with. - :param approach_angle: Angle to approach the dock with. - :param alignment_type: Which part of the robot to align with the object. - :param distance_from_marker: How far from the object to approach (0 to dock) - :param num_retries: Number of times to re-attempt action in case of a failure. - - Returns: - A response from the robot with status information sent when this request successfully completes or fails. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.world.connect_cube() - - if robot.world.connected_light_cube: - dock_response = robot.behavior.dock_with_cube(robot.world.connected_light_cube) - docking_result = dock_response.result - """ - if target_object is None: - raise Exception("Must supply a target_object to dock_with_cube") - - motion_prof = self._motion_profile_for_proto() - - # @TODO: the id_tag we supply can be used to cancel this action, - # however when we implement that we will need some way to get the id_tag - # out of this function. - dock_request = protocol.DockWithCubeRequest(object_id=target_object.object_id, - alignment_type=alignment_type, - motion_prof=motion_prof, - id_tag=self._get_next_action_id(), - num_retries=num_retries) - if approach_angle is not None: - dock_request.use_approach_angle = True - dock_request.use_pre_dock_pose = True - dock_request.approach_angle = approach_angle.radians - if distance_from_marker is not None: - dock_request.distance_from_marker = distance_from_marker.distance_mm - - return await self.grpc_interface.DockWithCube(dock_request) - - # Movement actions - @connection.on_connection_thread() - async def drive_straight(self, - distance: util.Distance, - speed: util.Speed, - should_play_anim: bool = True, - num_retries: int = 0) -> protocol.DriveStraightResponse: - """Tells Vector to drive in a straight line. - - Vector will drive for the specified distance (forwards or backwards) - - Vector must be off of the charger for this movement action. - - :param distance: The distance to drive - (>0 for forwards, <0 for backwards) - :param speed: The speed to drive at - (should always be >0, the abs(speed) is used internally) - :param should_play_anim: Whether to play idle animations whilst driving - (tilt head, hum, animated eyes, etc.) - :param num_retries: Number of times to re-attempt action in case of a failure. - - Returns: - A response from the robot with status information sent when this request successfully completes or fails. - - .. testcode:: - - import anki_vector - from anki_vector.util import degrees, distance_mm, speed_mmps - - with anki_vector.Robot() as robot: - robot.behavior.drive_straight(distance_mm(200), speed_mmps(100)) - """ - - # @TODO: the id_tag we supply can be used to cancel this action, - # however when we implement that we will need some way to get the id_tag - # out of this function. - drive_straight_request = protocol.DriveStraightRequest(speed_mmps=speed.speed_mmps, - dist_mm=distance.distance_mm, - should_play_animation=should_play_anim, - id_tag=self._get_next_action_id(), - num_retries=num_retries) - - return await self.grpc_interface.DriveStraight(drive_straight_request) - - @connection.on_connection_thread() - async def turn_in_place(self, - angle: util.Angle, - speed: util.Angle = util.Angle(0.0), - accel: util.Angle = util.Angle(0.0), - angle_tolerance: util.Angle = util.Angle(0.0), - is_absolute: bool = 0, - num_retries: int = 0) -> protocol.TurnInPlaceResponse: - """Turn the robot around its current position. - - Vector must be off of the charger for this movement action. - - :param angle: The angle to turn. Positive - values turn to the left, negative values to the right. - :param speed: Angular turn speed (per second). - :param accel: Acceleration of angular turn - (per second squared). - :param angle_tolerance: angular tolerance - to consider the action complete (this is clamped to a minimum - of 2 degrees internally). - :param is_absolute: True to turn to a specific angle, False to - turn relative to the current pose. - :param num_retries: Number of times to re-attempt the turn in case of a failure. - - Returns: - A response from the robot with status information sent when this request successfully completes or fails. - - .. testcode:: - - import anki_vector - from anki_vector.util import degrees - - with anki_vector.Robot() as robot: - robot.behavior.turn_in_place(degrees(90)) - """ - turn_in_place_request = protocol.TurnInPlaceRequest(angle_rad=angle.radians, - speed_rad_per_sec=speed.radians, - accel_rad_per_sec2=accel.radians, - tol_rad=angle_tolerance.radians, - is_absolute=is_absolute, - id_tag=self._get_next_action_id(), - num_retries=num_retries) - - return await self.grpc_interface.TurnInPlace(turn_in_place_request) - - @connection.on_connection_thread() - async def set_head_angle(self, - angle: util.Angle, - accel: float = 10.0, - max_speed: float = 10.0, - duration: float = 0.0, - num_retries: int = 0) -> protocol.SetHeadAngleResponse: - """Tell Vector's head to move to a given angle. - - :param angle: Desired angle for Vector's head. - (:const:`MIN_HEAD_ANGLE` to :const:`MAX_HEAD_ANGLE`). - (we clamp it to this range internally). - :param accel: Acceleration of Vector's head in radians per second squared. - :param max_speed: Maximum speed of Vector's head in radians per second. - :param duration: Time for Vector's head to move in seconds. A value - of zero will make Vector try to do it as quickly as possible. - :param num_retries: Number of times to re-attempt the action in case of a failure. - - Returns: - A response from the robot with status information sent when this request successfully completes or fails. - - .. testcode:: - - import anki_vector - from anki_vector.util import degrees - from anki_vector.behavior import MIN_HEAD_ANGLE, MAX_HEAD_ANGLE - - with anki_vector.Robot() as robot: - # move head from minimum to maximum angle - robot.behavior.set_head_angle(MIN_HEAD_ANGLE) - robot.behavior.set_head_angle(MAX_HEAD_ANGLE) - # move head to middle - robot.behavior.set_head_angle(degrees(35.0)) - """ - if angle < MIN_HEAD_ANGLE: - self.logger.warning("head angle %s too small, should be in %f..%f range - clamping", - angle.degrees, MIN_HEAD_ANGLE.degrees, MAX_HEAD_ANGLE.degrees) - angle = MIN_HEAD_ANGLE - elif angle > MAX_HEAD_ANGLE: - self.logger.warning("head angle %s too large, should be in %f..%f range - clamping", - angle.degrees, MIN_HEAD_ANGLE.degrees, MAX_HEAD_ANGLE.degrees) - angle = MAX_HEAD_ANGLE - - set_head_angle_request = protocol.SetHeadAngleRequest(angle_rad=angle.radians, - max_speed_rad_per_sec=max_speed, - accel_rad_per_sec2=accel, - duration_sec=duration, - id_tag=self._get_next_action_id(), - num_retries=num_retries) - - return await self.grpc_interface.SetHeadAngle(set_head_angle_request) - - @connection.on_connection_thread() - async def set_lift_height(self, - height: float, - accel: float = 10.0, - max_speed: float = 10.0, - duration: float = 0.0, - num_retries: int = 0) -> protocol.SetLiftHeightResponse: - """Tell Vector's lift to move to a given height. - - :param height: desired height for Vector's lift 0.0 (bottom) to - 1.0 (top) (we clamp it to this range internally). - :param accel: Acceleration of Vector's lift in radians per - second squared. - :param max_speed: Maximum speed of Vector's lift in radians per second. - :param duration: Time for Vector's lift to move in seconds. A value - of zero will make Vector try to do it as quickly as possible. - :param num_retries: Number of times to re-attempt the action in case of a failure. - - Returns: - A response from the robot with status information sent when this request successfully completes or fails. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.behavior.set_lift_height(1.0) - """ - - if height < 0.0: - self.logger.warning("lift height %s too small, should be in 0..1 range - clamping", height) - height = MIN_LIFT_HEIGHT_MM - elif height > 1.0: - self.logger.warning("lift height %s too large, should be in 0..1 range - clamping", height) - height = MAX_LIFT_HEIGHT_MM - else: - height = MIN_LIFT_HEIGHT_MM + (height * (MAX_LIFT_HEIGHT_MM - MIN_LIFT_HEIGHT_MM)) - - set_lift_height_request = protocol.SetLiftHeightRequest(height_mm=height, - max_speed_rad_per_sec=max_speed, - accel_rad_per_sec2=accel, - duration_sec=duration, - id_tag=self._get_next_action_id(), - num_retries=num_retries) - - return await self.grpc_interface.SetLiftHeight(set_lift_height_request) diff --git a/anki_vector/camera.py b/anki_vector/camera.py deleted file mode 100644 index 64bf499..0000000 --- a/anki_vector/camera.py +++ /dev/null @@ -1,165 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Support for Vector's camera. - -Vector has a built-in camera which he uses to observe the world around him. - -The :class:`CameraComponent` class defined in this module is made available as -:attr:`anki_vector.robot.Robot.camera` and can be used to enable/disable image -sending and observe images being sent by the robot. - -The camera resolution is 1280 x 720 with a field of view of 90 deg (H) x 50 deg (V). -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['CameraComponent'] - -import asyncio -from concurrent.futures import CancelledError -import sys - -try: - import cv2 -except ImportError: - sys.exit("Cannot import opencv-python: Do `pip3 install opencv-python` to install") - -from . import util -from .messaging import protocol - -try: - import numpy as np -except ImportError: - sys.exit("Cannot import numpy: Do `pip3 install numpy` to install") - -try: - from PIL import Image -except ImportError: - sys.exit("Cannot import from PIL: Do `pip3 install --user Pillow` to install") - - -class CameraComponent(util.Component): - """Represents Vector's camera. - - The CameraComponent object receives images from Vector's camera, unpacks the data, - composes it and makes it available as latest_image. - - The :class:`anki_vector.robot.Robot` or :class:`anki_vector.robot.AsyncRobot` instance observes the camera. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_camera_feed=True) as robot: - image = robot.camera.latest_image - image.show() - - :param robot: A reference to the owner Robot object. - """ - - def __init__(self, robot): - super().__init__(robot) - - self._latest_image: Image.Image = None - self._latest_image_id: int = None - self._camera_feed_task: asyncio.Task = None - self._enabled = False - - @property - @util.block_while_none() - def latest_image(self) -> Image.Image: - """:class:`Image.Image`: The most recently processed image received from the robot. - - :getter: Returns the Pillow Image representing the latest image - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_camera_feed=True) as robot: - image = robot.camera.latest_image - image.show() - """ - if not self._camera_feed_task: - raise Exception("Camera feed not open!") # TODO: Use a VectorException - return self._latest_image - - @property - @util.block_while_none() - def latest_image_id(self) -> int: - """The most recently processed image's id received from the robot. - - Used only to track chunks of the same image. - - :getter: Returns the id for the latest image - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_camera_feed=True) as robot: - image = robot.camera.latest_image - image.show() - print(f"latest_image_id: {robot.camera.latest_image_id}") - """ - if not self._camera_feed_task: - raise Exception("Camera feed not open!") # TODO: Use a VectorException - return self._latest_image_id - - def init_camera_feed(self) -> None: - """Begin camera feed task.""" - if not self._camera_feed_task or self._camera_feed_task.done(): - self._enabled = True - self._camera_feed_task = self.conn.loop.create_task(self._request_and_handle_images()) - - def close_camera_feed(self) -> None: - """Cancel camera feed task.""" - if self._camera_feed_task: - self._enabled = False - self._camera_feed_task.cancel() - future = self.conn.run_coroutine(self._camera_feed_task) - future.result() - self._camera_feed_task = None - - def _unpack_image(self, msg: protocol.CameraFeedResponse) -> None: - """Processes raw data from the robot into a more more useful image structure.""" - size = len(msg.data) - - # Constuct numpy array out of source data - array = np.empty(size, dtype=np.uint8) - array[0:size] = list(msg.data) - - # Decode compressed source data into uncompressed image data - imageArray = cv2.imdecode(array, -1) - imageArray = cv2.cvtColor(imageArray, cv2.COLOR_BGR2RGB) - - # Convert to Pillow Image - self._latest_image = Image.fromarray(imageArray) - self._latest_image_id = msg.image_id - self.robot.viewer.enqueue_frame(self._latest_image) - - async def _request_and_handle_images(self) -> None: - """Queries and listens for camera feed events from the robot. - Received events are parsed by a helper function.""" - try: - req = protocol.CameraFeedRequest() - async for evt in self.grpc_interface.CameraFeed(req): - # If the camera feed is disabled after stream is setup, exit the stream - # (the camera feed on the robot is disabled internally on stream exit) - if not self._enabled: - self.logger.warning('Camera feed has been disabled. Enable the feed to start/continue receiving camera feed data') - return - self._unpack_image(evt) - except CancelledError: - self.logger.debug('Camera feed task was cancelled. This is expected during disconnection.') diff --git a/anki_vector/color.py b/anki_vector/color.py deleted file mode 100755 index c492339..0000000 --- a/anki_vector/color.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Colors to be used with a light or Vector's screen. -""" - - -class Color: - """A Color to be used with a Light or Vector's screen. - - Either int_color or rgb may be used to specify the actual color. - Any alpha components (from int_color) are ignored - all colors are fully opaque. - - :param int_color: A 32 bit value holding the binary RGBA value (where A - is ignored and forced to be fully opaque). - :param rgb: A tuple holding the integer values from 0-255 for (reg, green, blue) - :param name: A name to assign to this color. - """ - - def __init__(self, int_color: int = None, rgb: tuple = None, name: str = None): - self.name = name - self._int_color = 0 - if int_color is not None: - self._int_color = int_color | 0xff - elif rgb is not None: - self._int_color = (rgb[0] << 24) | (rgb[1] << 16) | (rgb[2] << 8) | 0xff - - @property - def int_color(self) -> int: - """The encoded integer value of the color.""" - return self._int_color - - @property - def rgb565_bytepair(self): - """bytes[]: Two bytes representing an int16 color with rgb565 encoding. - - This format reflects the robot's Screen color range, and performing this - conversion will reduce network traffic when sending Screen data. - """ - - red5 = ((self._int_color >> 24) & 0xff) >> 3 - green6 = ((self._int_color >> 16) & 0xff) >> 2 - blue5 = ((self._int_color >> 8) & 0xff) >> 3 - - green3_hi = green6 >> 3 - green3_low = green6 & 0x07 - - int_565_color_lowbyte = (green3_low << 5) | blue5 - int_565_color_highbyte = (red5 << 3) | green3_hi - - return [int_565_color_highbyte, int_565_color_lowbyte] - - -#: :class:`Color`: Green color instance. -green = Color(name="green", int_color=0x00ff00ff) - -#: :class:`Color`: Red color instance. -red = Color(name="red", int_color=0xff0000ff) - -#: :class:`Color`: Blue color instance. -blue = Color(name="blue", int_color=0x0000ffff) - -#: :class:`Color`: Cyan color instance. -cyan = Color(name="cyan", int_color=0x00ffffff) - -#: :class:`Color`: Magenta color instance. -magenta = Color(name="magenta", int_color=0xff00ffff) - -#: :class:`Color`: Yellow color instance. -yellow = Color(name="yellow", int_color=0xffff00ff) - -#: :class:`Color`: White color instance. -white = Color(name="white", int_color=0xffffffff) - -#: :class:`Color`: Instance representing no color (i.e., lights off). -off = Color(name="off") diff --git a/anki_vector/configure/__main__.py b/anki_vector/configure/__main__.py deleted file mode 100755 index 41c08cf..0000000 --- a/anki_vector/configure/__main__.py +++ /dev/null @@ -1,322 +0,0 @@ -#!/usr/bin/env python3 - -""" -***Anki Vector Python SDK Setup*** - -Vector requires all requests be authorized by an authenticated Anki user. - -This script will enable this device to authenticate with your Vector -robot for use with a Vector Python SDK program. - -Vector must be powered on and connected on the same network as your -computer. By running this script, you will be asked to provide your -Anki account credentials, and the script will download an authentication -token and cert 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). - -See the README for more information. - -Use of Vector and the Vector SDK is subject to Anki's Privacy Policy and Terms and Conditions. - -https://www.anki.com/en-us/company/privacy -https://www.anki.com/en-us/company/terms-and-conditions - -""" - -import argparse -import configparser -from getpass import getpass -import json -import os -from pathlib import Path -import re -import socket -import sys - -from cryptography import x509 -from cryptography.hazmat.backends import default_backend -import grpc -import requests -try: - from termcolor import colored # pylint: disable=import-error -except: # pylint: disable=bare-except - def colored(text, color=None, on_color=None, attrs=None): # pylint: disable=unused-argument - return text - -import anki_vector -from anki_vector import messaging - - -class ApiHandler: - def __init__(self, headers: dict, url: str): - self._headers = headers - self._url = url - - @property - def headers(self): - return self._headers - - @property - def url(self): - return self._url - - -class Api: - def __init__(self): - self._handler = ApiHandler( - headers={ - 'User-Agent': f'Vector-sdk/{anki_vector.__version__}', - 'Anki-App-Key': 'aung2ieCho3aiph7Een3Ei' - }, - url='https://accounts.api.anki.com/1/sessions' - ) - - @property - def name(self): - return "Anki Cloud" - - @property - def handler(self): - return self._handler - - -def get_serial(serial=None): - if not serial: - serial = os.environ.get('ANKI_ROBOT_SERIAL') - if not serial: - print("\n\nPlease find your robot serial number (ex. 00e20100) located on the underside of Vector, or accessible from Vector's debug screen.") - serial = input('Enter robot serial number: ') - else: - print("Found robot serial number in environment variable '{}'".format(colored("ANKI_ROBOT_SERIAL", "green"))) - serial = serial.lower() - print("Using robot serial number: {}".format(colored(serial, "cyan"))) - return serial - - -def get_cert(serial=None): - serial = get_serial(serial) - print("\nDownloading Vector certificate from Anki...", end="") - sys.stdout.flush() - r = requests.get('https://session-certs.token.global.anki-services.com/vic/{}'.format(serial)) - if r.status_code != 200: - print(colored(" ERROR", "red")) - sys.exit(r.content) - print(colored(" DONE", "green")) - cert = r.content - return cert, serial - - -def user_authentication(session_id: bytes, cert: bytes, ip: str, name: str) -> str: - # Pin the robot certificate for opening the channel - creds = grpc.ssl_channel_credentials(root_certificates=cert) - - print("Attempting to download guid from {} at {}:443...".format(colored(name, "cyan"), colored(ip, "cyan")), end="") - sys.stdout.flush() - channel = grpc.secure_channel("{}:443".format(ip), creds, - options=(("grpc.ssl_target_name_override", name,),)) - - # Verify the connection to Vector is able to be established (client-side) - try: - # Explicitly grab _channel._channel to test the underlying grpc channel directly - grpc.channel_ready_future(channel).result(timeout=15) - except grpc.FutureTimeoutError: - print(colored(" ERROR", "red")) - sys.exit("\nUnable to connect to Vector\n" - "Please be sure to connect via the Vector companion app first, and connect your computer to the same network as your Vector.") - - try: - interface = messaging.client.ExternalInterfaceStub(channel) - request = messaging.protocol.UserAuthenticationRequest( - user_session_id=session_id.encode('utf-8'), - client_name=socket.gethostname().encode('utf-8')) - response = interface.UserAuthentication(request) - if response.code != messaging.protocol.UserAuthenticationResponse.AUTHORIZED: # pylint: disable=no-member - print(colored(" ERROR", "red")) - sys.exit("\nFailed to authorize request:\n" - "Please be sure to first set up Vector using the companion app.") - except grpc.RpcError as e: - print(colored(" ERROR", "red")) - sys.exit("\nFailed to authorize request:\n" - "An unknown error occurred '{}'".format(e)) - - print(colored(" DONE\n", "green")) - return response.client_token_guid - - -def get_session_token(api, username=None): - print("Enter your email and password. Make sure to use the same account that was used to set up your Vector.") - if not username: - username = input("Enter Email: ") - else: - print("Using email from command line: {}".format(colored(username, "cyan"))) - password = getpass("Enter Password: ") - payload = {'username': username, 'password': password} - - print("\nAuthenticating with {}...".format(api.name), end="") - sys.stdout.flush() - r = requests.post(api.handler.url, data=payload, headers=api.handler.headers) - if r.status_code != 200: - print(colored(" ERROR", "red")) - sys.exit(r.content) - print(colored(" DONE\n", "green")) - return json.loads(r.content) - - -def standardize_name(robot_name): - # Extend the name if not enough is provided - if len(robot_name) == 4: - robot_name = "Vector-{}".format(robot_name.upper()) - # Fix possible capitalization and space/dash/etc. - if re.match("[Vv]ector.[A-Za-z0-9]{4}", robot_name): - robot_name = "V{}-{}".format(robot_name[1:-5], robot_name[-4:].upper()) - # Check that the end is valid - if re.match("Vector-[A-Z0-9]{4}", robot_name): - return robot_name - print(colored(" ERROR", "red")) - sys.exit("Invalid robot name. Please match the format exactly. Example: Vector-A1B2") - - -def get_name_and_ip(robot_name=None, ip=None): - if not robot_name: - robot_name = os.environ.get('VECTOR_ROBOT_NAME') - if not robot_name: - print("\n\nFind your robot name (ex. Vector-A1B2) by placing Vector on the charger and double-clicking Vector's backpack button.") - robot_name = input("Enter robot name: ") - else: - print("Found robot name in environment variable '{}'".format(colored("VECTOR_ROBOT_NAME", "green"))) - robot_name = standardize_name(robot_name) - print("Using robot name: {}".format(colored(robot_name, "cyan"))) - if not ip: - ip = os.environ.get('ANKI_ROBOT_HOST') - if not ip: - print("\n\nFind your robot ip address (ex. 192.168.42.42) by placing Vector on the charger, double-clicking Vector's backpack button,\n" - "then raising and lowering his arms. If you see {} on his face, reconnect Vector to your WiFi using the Vector Companion App.".format(colored("XX.XX.XX.XX", "red"))) - ip = input("Enter robot ip: ") - else: - print("Found robot ip address in environment variable '{}'".format(colored("ANKI_ROBOT_HOST", "green"))) - print("Using IP: {}".format(colored(ip, "cyan"))) - return robot_name, ip - - -def save_cert(cert, name, serial, anki_dir): - """Write Vector's certificate to a file located in the user's home directory""" - os.makedirs(str(anki_dir), exist_ok=True) - cert_file = str(anki_dir / "{name}-{serial}.cert".format(name=name, serial=serial)) - print("Writing certificate file to '{}'...\n".format(colored(cert_file, "cyan"))) - with os.fdopen(os.open(cert_file, os.O_WRONLY | os.O_CREAT, 0o600), 'wb') as f: - f.write(cert) - return cert_file - - -def validate_cert_name(cert_file, robot_name): - """Validate the name on Vector's certificate against the user-provided name""" - with open(cert_file, "rb") as f: - cert_file = f.read() - cert = x509.load_pem_x509_certificate(cert_file, default_backend()) - for fields in cert.subject: - current = str(fields.oid) - if "commonName" in current: - common_name = fields.value - if common_name != robot_name: - print(colored(" ERROR", "red")) - sys.exit("The name of the certificate ({}) does not match the name provided ({}).\n" - "Please verify the name, and try again.".format(common_name, robot_name)) - else: - return - - -def write_config(serial, cert_file=None, ip=None, name=None, guid=None, clear=True): - home = Path.home() - config_file = str(home / ".anki_vector" / "sdk_config.ini") - print("Writing config file to '{}'...".format(colored(config_file, "cyan"))) - - config = configparser.ConfigParser(strict=False) - - try: - config.read(config_file) - except configparser.ParsingError: - if os.path.exists(config_file): - os.rename(config_file, config_file + "-error") - if clear: - config[serial] = {} - if cert_file: - config[serial]["cert"] = cert_file - if ip: - config[serial]["ip"] = ip - if name: - config[serial]["name"] = name - if guid: - config[serial]["guid"] = guid.decode("utf-8") - temp_file = config_file + "-temp" - if os.path.exists(config_file): - os.rename(config_file, temp_file) - try: - with os.fdopen(os.open(config_file, os.O_WRONLY | os.O_CREAT, 0o600), 'w') as f: - config.write(f) - except Exception as e: - if os.path.exists(temp_file): - os.rename(temp_file, config_file) - raise e - else: - if os.path.exists(temp_file): - os.remove(temp_file) - - -def main(api): - parser = argparse.ArgumentParser(description=("Vector requires all requests be authorized by an authenticated Anki user. " - "This script will enable this device to authenticate with your Vector " - "robot for use with a Vector Python SDK program."), - epilog=("See the README for more information. " - "Use of Vector and the Vector SDK is subject to Anki's Privacy Policy and Terms and Conditions. " - "https://www.anki.com/en-us/company/privacy and " - "https://www.anki.com/en-us/company/terms-and-conditions")) - parser.add_argument("-e", "--email", help="The email used by your Anki account.") - parser.add_argument("-i", "--ip", help=("Your robot ip address (ex. 192.168.42.42). " - "It may be found by placing Vector on the charger, " - "double-clicking Vector's backpack button, " - "then raising and lowering his arms. " - "If you see {} on his face, " - "reconnect Vector to your WiFi using the Vector Companion App.".format(colored("XX.XX.XX.XX", "red")))) - parser.add_argument("-n", "--name", help=("Your robot name (ex. Vector-A1B2). " - "It may be found by placing Vector on the charger and double-clicking Vector's backpack button.")) - parser.add_argument("-s", "--serial", help=("Your robot serial number (ex. 00e20100). " - "It is located on the underside of Vector, or accessible from Vector's debug screen.")) - parser.add_argument("-u", "--update", dest="new_ip", help=("Update the stored ip for Vector. This makes it easier to transfer between networks.")) - args = parser.parse_args() - - if args.new_ip: - serial = get_serial(args.serial) - write_config(serial, ip=args.new_ip, clear=False) - print(colored("\nIP Updated!", "green")) - sys.exit() - - print(__doc__) - - valid = ["y", "Y", "yes", "YES"] - environ = input("Do you wish to proceed? (y/n) ") - if environ not in valid: - sys.exit("Stopping...") - - name, ip = get_name_and_ip(args.name, args.ip) - cert, serial = get_cert(args.serial) - - home = Path.home() - anki_dir = home / ".anki_vector" - - cert_file = save_cert(cert, name, serial, anki_dir) - validate_cert_name(cert_file, name) - - token = get_session_token(api, args.email) - if not token.get("session"): - sys.exit("Session error: {}".format(token)) - - guid = user_authentication(token["session"]["session_token"], cert, ip, name) - - # Store credentials in the .anki_vector directory's sdk_config.ini file - write_config(serial, cert_file, ip, name, guid) - print(colored("\nSUCCESS!", "green")) - - -if __name__ == "__main__": - main(Api()) diff --git a/anki_vector/connection.py b/anki_vector/connection.py deleted file mode 100644 index abcb12f..0000000 --- a/anki_vector/connection.py +++ /dev/null @@ -1,757 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Management of the connection to and from Vector. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['CONTROL_PRIORITY_LEVEL', 'Connection', 'on_connection_thread'] - -import asyncio -from concurrent import futures -from enum import Enum -import functools -import inspect -import logging -import platform -import sys -import threading -from typing import Any, Awaitable, Callable, Coroutine, Dict, List - -import grpc -import aiogrpc - -from . import util -from .exceptions import (connection_error, - VectorControlException, - VectorControlTimeoutException, - VectorInvalidVersionException, - VectorNotFoundException) -from .messaging import client, protocol -from .version import __version__ - -CLIENT_VERSION = 2 -MIN_HOST_VERSION = 0 - - -class CONTROL_PRIORITY_LEVEL(Enum): - """Enum used to specify the priority level for the program.""" - - #: Runs below Mandatory Physical Reactions such as tucking Vector's head and arms during a fall, - #: yet above Trigger-Word Detection. - TOP_PRIORITY_AI = protocol.ControlRequest.TOP_PRIORITY_AI # pylint: disable=no-member - - -class _ControlEventManager: - """This manages every :class:`asyncio.Event` that handles the behavior control - system. - - These include three events: granted, lost, and request. - - :class:`granted_event` represents the behavior system handing control to the SDK. - - :class:`lost_event` represents a higher priority behavior taking control away from the SDK. - - :class:`request_event` Is a way of alerting :class:`Connection` to request control. - """ - - def __init__(self, loop: asyncio.BaseEventLoop = None, priority: CONTROL_PRIORITY_LEVEL = None): - self._granted_event = asyncio.Event(loop=loop) - self._lost_event = asyncio.Event(loop=loop) - self._request_event = asyncio.Event(loop=loop) - self._has_control = False - self._priority = priority - self._is_shutdown = False - - @property - def granted_event(self) -> asyncio.Event: - """This event is used to notify listeners that control has been granted to the SDK.""" - return self._granted_event - - @property - def lost_event(self) -> asyncio.Event: - """Represents a higher priority behavior taking control away from the SDK.""" - return self._lost_event - - @property - def request_event(self) -> asyncio.Event: - """Used to alert :class:`Connection` to request control.""" - return self._request_event - - @property - def has_control(self) -> bool: - """Check to see that the behavior system has control (without blocking by checking :class:`granted_event`)""" - return self._has_control - - @property - def priority(self) -> CONTROL_PRIORITY_LEVEL: - """The currently desired priority for the SDK.""" - return self._priority - - @property - def is_shutdown(self) -> bool: - """Detect if the behavior control stream is supposed to shut down.""" - return self._is_shutdown - - def request(self, priority: CONTROL_PRIORITY_LEVEL = CONTROL_PRIORITY_LEVEL.TOP_PRIORITY_AI) -> None: - """Tell the behavior stream to request control via setting the :class:`request_event`. - - This will signal Connection's :func:`_request_handler` generator to send a request control message on the BehaviorControl stream. - This signal happens asynchronously, and can be tracked using the :class:`granted_event` parameter. - - :param priority: The level of control in the behavior system. This determines which actions are allowed to - interrupt the SDK execution. See :class:`CONTROL_PRIORITY_LEVEL` for more information. - """ - if priority is None: - raise Exception("Must provide a priority level to request. To disable control, use :func:`release()`.") - self._priority = priority - self._request_event.set() - - def release(self) -> None: - """Tell the behavior stream to release control via setting the :class:`request_event` while priority is ``None``. - - This will signal Connection's :func:`_request_handler` generator to send a release control message on the BehaviorControl stream. - This signal happens asynchronously, and can be tracked using the :class:`lost_event` parameter. - """ - self._priority = None - self._request_event.set() - - def update(self, enabled: bool) -> None: - """Update the current state of control (either enabled or disabled) - - :param enabled: Used to enable/disable behavior control - """ - self._has_control = enabled - if enabled: - self._granted_event.set() - self._lost_event.clear() - else: - self._lost_event.set() - self._granted_event.clear() - - def shutdown(self) -> None: - """Tells the control stream to shut down. - - This will return control to the rest of the behavior system. - """ - self._has_control = False - self._granted_event.set() - self._lost_event.set() - self._is_shutdown = True - self._request_event.set() - - -class Connection: - """Creates and maintains a aiogrpc connection including managing the connection thread. - The connection thread decouples the actual messaging layer from the user's main thread, - and requires any network requests to be ran using :func:`asyncio.run_coroutine_threadsafe` - to make them run on the other thread. Connection provides two helper functions for running - a function on the connection thread: :func:`~Connection.run_coroutine` and - :func:`~Connection.run_soon`. - - This class may be used to bypass the structures of the python sdk handled by - :class:`~anki_vector.robot.Robot`, and instead talk to aiogrpc more directly. - - The values for the cert_file location and the guid can be found in your home directory in - the sdk_config.ini file. - - .. code-block:: python - - import anki_vector - - # Connect to your Vector - conn = anki_vector.connection.Connection("Vector-XXXX", "XX.XX.XX.XX:443", "/path/to/file.cert", "") - conn.connect() - # Run your commands - async def play_animation(): - # Run your commands - anim = anki_vector.messaging.protocol.Animation(name="anim_pounce_success_02") - anim_request = anki_vector.messaging.protocol.PlayAnimationRequest(animation=anim) - return await conn.grpc_interface.PlayAnimation(anim_request) # This needs to be run in an asyncio loop - conn.run_coroutine(play_animation()).result() - # Close the connection - conn.close() - - :param name: Vector's name in the format of "Vector-XXXX". - :param host: The IP address and port of Vector in the format "XX.XX.XX.XX:443". - :param cert_file: The location of the certificate file on disk. - :param guid: Your robot's unique secret key. - :param requires_behavior_control: True if the connection requires behavior control. - """ - - def __init__(self, name: str, host: str, cert_file: str, guid: str, requires_behavior_control: bool = True): - if cert_file is None: - raise Exception("Must provide a cert file") - self._loop: asyncio.BaseEventLoop = None - self.name = name - self.host = host - self.cert_file = cert_file - self._interface = None - self._channel = None - self._has_control = False - self._logger = util.get_class_logger(__name__, self) - self._control_stream_task = None - self._control_events: _ControlEventManager = None - self._guid = guid - self._thread: threading.Thread = None - self._ready_signal: threading.Event = threading.Event() - self._done_signal: asyncio.Event = None - self._conn_exception = False - self._requires_behavior_control = requires_behavior_control - self.active_commands = [] - - @property - def loop(self) -> asyncio.BaseEventLoop: - """A direct reference to the loop on the connection thread. - Can be used to run functions in on thread. - - .. testcode:: - - import anki_vector - import asyncio - - async def connection_function(): - print("I'm running in the connection thread event loop.") - - with anki_vector.Robot() as robot: - asyncio.run_coroutine_threadsafe(connection_function(), robot.conn.loop) - - :returns: The loop running inside the connection thread - """ - if self._loop is None: - raise Exception("Attempted to access the connection loop before it was ready") - return self._loop - - @property - def thread(self) -> threading.Thread: - """A direct reference to the connection thread. Available to callers to determine if the - current thread is the connection thread. - - .. testcode:: - - import anki_vector - import threading - - with anki_vector.Robot() as robot: - if threading.current_thread() is robot.conn.thread: - print("This code is running on the connection thread") - else: - print("This code is not running on the connection thread") - - :returns: The connection thread where all of the grpc messages are being processed. - """ - if self._thread is None: - raise Exception("Attempted to access the connection loop before it was ready") - return self._thread - - @property - def grpc_interface(self) -> client.ExternalInterfaceStub: - """A direct reference to the connected aiogrpc interface. - - This may be used to directly call grpc messages bypassing :class:`anki_vector.Robot` - - .. code-block:: python - - import anki_vector - - # Connect to your Vector - conn = anki_vector.connection.Connection("Vector-XXXX", "XX.XX.XX.XX:443", "/path/to/file.cert", "") - conn.connect() - # Run your commands - async def play_animation(): - # Run your commands - anim = anki_vector.messaging.protocol.Animation(name="anim_pounce_success_02") - anim_request = anki_vector.messaging.protocol.PlayAnimationRequest(animation=anim) - return await conn.grpc_interface.PlayAnimation(anim_request) # This needs to be run in an asyncio loop - conn.run_coroutine(play_animation()).result() - # Close the connection - conn.close() - """ - return self._interface - - @property - def requires_behavior_control(self) -> bool: - """True if the :class:`Connection` requires behavior control. - - To be able to directly control Vector's motors, override his screen, play an animation, etc., - the :class:`Connection` will need behavior control. This boolean signifies that - the :class:`Connection` will try to maintain control of Vector's behavior system even after losing - control to higher priority robot behaviors such as returning home to charge a low battery. - - For more information about behavior control, see :ref:`behavior `. - - .. code-block:: python - - import time - - import anki_vector - - with anki_vector.Robot(requires_behavior_control=False) as robot: - async def callback(event_type, event): - await robot.conn.request_control() - print(robot.conn.requires_behavior_control) # Will print True - await robot.anim.play_animation('anim_pounce_success_02') - await robot.conn.release_control() - - print(robot.conn.requires_behavior_control) # Will print False - robot.events.subscribe(callback, anki_vector.events.Events.robot_observed_face) - - # Waits 10 seconds. Show Vector your face. - time.sleep(10) - """ - return self._requires_behavior_control - - @property - def control_lost_event(self) -> asyncio.Event: - """This provides an :class:`asyncio.Event` that a user may :func:`wait()` upon to - detect when Vector has taken control of the behavior system at a higher priority. - - .. testcode:: - - import anki_vector - - async def auto_reconnect(conn: anki_vector.connection.Connection): - await conn.control_lost_event.wait() - conn.request_control() - """ - return self._control_events.lost_event - - @property - def control_granted_event(self) -> asyncio.Event: - """This provides an :class:`asyncio.Event` that a user may :func:`wait()` upon to - detect when Vector has given control of the behavior system to the SDK program. - - .. testcode:: - - import anki_vector - - async def wait_for_control(conn: anki_vector.connection.Connection): - await conn.control_granted_event.wait() - # Run commands that require behavior control - """ - return self._control_events.granted_event - - def request_control(self, timeout: float = 10.0): - """Explicitly request behavior control. Typically used after detecting :func:`control_lost_event`. - - To be able to directly control Vector's motors, override his screen, play an animation, etc., - the :class:`Connection` will need behavior control. This function will acquire control - of Vector's behavior system. This will raise a :class:`VectorControlTimeoutException` if it fails - to gain control before the timeout. - - For more information about behavior control, see :ref:`behavior ` - - .. testcode:: - - import anki_vector - - async def auto_reconnect(conn: anki_vector.connection.Connection): - await conn.control_lost_event.wait() - conn.request_control(timeout=5.0) - - :param timeout: The time allotted to attempt a connection, in seconds. - """ - if self._thread is threading.current_thread(): - return asyncio.ensure_future(self._request_control(timeout=timeout), loop=self._loop) - return self.run_coroutine(self._request_control(timeout=timeout)) - - async def _request_control(self, timeout: float = 10.0): - self._requires_behavior_control = True - self._control_events.request() - try: - self._has_control = await asyncio.wait_for(self.control_granted_event.wait(), timeout) - except futures.TimeoutError as e: - raise VectorControlTimeoutException(f"Surpassed timeout of {timeout}s") from e - - def release_control(self, timeout: float = 10.0): - """Explicitly request control. Typically used after detecting :func:`control_lost_event`. - - To be able to directly control Vector's motors, override his screen, play an animation, etc., - the :class:`Connection` will need behavior control. This function will acquire control - of Vector's behavior system. This will raise a :class:`VectorControlTimeoutException` if it fails - to receive a control_lost event before the timeout. - - .. testcode:: - - import anki_vector - - async def wait_for_control(conn: anki_vector.connection.Connection): - await conn.control_granted_event.wait() - # Run commands that require behavior control - conn.release_control() - - :param timeout: The time allotted to attempt to release control, in seconds. - """ - if self._thread is threading.current_thread(): - return asyncio.ensure_future(self._release_control(timeout=timeout), loop=self._loop) - return self.run_coroutine(self._release_control(timeout=timeout)) - - async def _release_control(self, timeout: float = 10.0): - self._requires_behavior_control = False - self._control_events.release() - try: - self._has_control = await asyncio.wait_for(self.control_lost_event.wait(), timeout) - except futures.TimeoutError as e: - raise VectorControlTimeoutException(f"Surpassed timeout of {timeout}s") from e - - def connect(self, timeout: float = 10.0) -> None: - """Connect to Vector. This will start the connection thread which handles all messages - between Vector and Python. - - .. code-block:: python - - import anki_vector - - # Connect to your Vector - conn = anki_vector.connection.Connection("Vector-XXXX", "XX.XX.XX.XX:443", "/path/to/file.cert", "") - conn.connect() - # Run your commands - async def play_animation(): - # Run your commands - anim = anki_vector.messaging.protocol.Animation(name="anim_pounce_success_02") - anim_request = anki_vector.messaging.protocol.PlayAnimationRequest(animation=anim) - return await conn.grpc_interface.PlayAnimation(anim_request) # This needs to be run in an asyncio loop - conn.run_coroutine(play_animation()).result() - # Close the connection - conn.close() - - :param timeout: The time allotted to attempt a connection, in seconds. - """ - if self._thread: - raise Exception("\n\nRepeated connections made to open Connection.") - self._ready_signal.clear() - self._thread = threading.Thread(target=self._connect, args=(timeout,), daemon=True, name="gRPC Connection Handler Thread") - self._thread.start() - ready = self._ready_signal.wait(timeout=2 * timeout) - if not ready: - raise VectorNotFoundException() - if hasattr(self._ready_signal, "exception"): - e = getattr(self._ready_signal, "exception") - delattr(self._ready_signal, "exception") - raise e - - def _connect(self, timeout: float) -> None: - """The function that runs on the connection thread. This will connect to Vector, - and establish the BehaviorControl stream. - """ - try: - if threading.main_thread() is threading.current_thread(): - raise Exception("\n\nConnection._connect must be run outside of the main thread.") - self._loop = asyncio.new_event_loop() - asyncio.set_event_loop(self._loop) - self._done_signal = asyncio.Event() - if not self._requires_behavior_control: - self._control_events = _ControlEventManager(self._loop) - else: - self._control_events = _ControlEventManager(self._loop, priority=CONTROL_PRIORITY_LEVEL.TOP_PRIORITY_AI) - trusted_certs = None - with open(self.cert_file, 'rb') as cert: - trusted_certs = cert.read() - - # Pin the robot certificate for opening the channel - channel_credentials = aiogrpc.ssl_channel_credentials(root_certificates=trusted_certs) - # Add authorization header for all the calls - call_credentials = aiogrpc.access_token_call_credentials(self._guid) - - credentials = aiogrpc.composite_channel_credentials(channel_credentials, call_credentials) - - self._logger.info(f"Connecting to {self.host} for {self.name} using {self.cert_file}") - self._channel = aiogrpc.secure_channel(self.host, credentials, - options=(("grpc.ssl_target_name_override", self.name,),)) - - # Verify the connection to Vector is able to be established (client-side) - try: - # Explicitly grab _channel._channel to test the underlying grpc channel directly - grpc.channel_ready_future(self._channel._channel).result(timeout=timeout) # pylint: disable=protected-access - except grpc.FutureTimeoutError as e: - raise VectorNotFoundException() from e - - self._interface = client.ExternalInterfaceStub(self._channel) - - # Verify Vector and the SDK have compatible protocol versions - version = protocol.ProtocolVersionRequest(client_version=CLIENT_VERSION, min_host_version=MIN_HOST_VERSION) - protocol_version = self._loop.run_until_complete(self._interface.ProtocolVersion(version)) - if protocol_version.result != protocol.ProtocolVersionResponse.SUCCESS or MIN_HOST_VERSION > protocol_version.host_version: # pylint: disable=no-member - raise VectorInvalidVersionException(version, protocol_version) - - self._control_stream_task = self._loop.create_task(self._open_connections()) - - # Initialze SDK - sdk_module_version = __version__ - python_version = platform.python_version() - python_implementation = platform.python_implementation() - os_version = platform.platform() - cpu_version = platform.machine() - initialize = protocol.SDKInitializationRequest(sdk_module_version=sdk_module_version, - python_version=python_version, - python_implementation=python_implementation, - os_version=os_version, - cpu_version=cpu_version) - self._loop.run_until_complete(self._interface.SDKInitialization(initialize)) - - if self._requires_behavior_control: - self._loop.run_until_complete(self._request_control(timeout=timeout)) - except Exception as e: # pylint: disable=broad-except - # Propagate the errors to the calling thread - setattr(self._ready_signal, "exception", e) - self._loop.close() - return - finally: - self._ready_signal.set() - - try: - async def wait_until_done(): - return await self._done_signal.wait() - self._loop.run_until_complete(wait_until_done()) - finally: - self._loop.close() - - async def _request_handler(self): - """Handles generating messages for the BehaviorControl stream.""" - while await self._control_events.request_event.wait(): - self._control_events.request_event.clear() - if self._control_events.is_shutdown: - return - priority = self._control_events.priority - if priority is None: - msg = protocol.ControlRelease() - msg = protocol.BehaviorControlRequest(control_release=msg) - else: - msg = protocol.ControlRequest(priority=priority.value) - msg = protocol.BehaviorControlRequest(control_request=msg) - self._logger.debug(f"Sending: {msg}") - yield msg - - async def _open_connections(self): - """Starts the BehaviorControl stream, and handles the messages coming back from the robot.""" - try: - async for response in self._interface.BehaviorControl(self._request_handler()): - response_type = response.WhichOneof("response_type") - if response_type == 'control_granted_response': - self._logger.info(response) - self._control_events.update(True) - elif response_type == 'control_lost_event': - self._cancel_active() - self._logger.info(response) - self._control_events.update(False) - except futures.CancelledError: - self._logger.debug('Behavior handler task was cancelled. This is expected during disconnection.') - - def _cancel_active(self): - for fut in self.active_commands: - if not fut.done(): - fut.cancel() - self.active_commands = [] - - def close(self): - """Cleanup the connection, and shutdown all the even handlers. - - Usually this should be invoked by the Robot class when it closes. - - .. code-block:: python - - import anki_vector - - # Connect to your Vector - conn = anki_vector.connection.Connection("Vector-XXXX", "XX.XX.XX.XX:443", "/path/to/file.cert", "") - conn.connect() - # Run your commands - async def play_animation(): - # Run your commands - anim = anki_vector.messaging.protocol.Animation(name="anim_pounce_success_02") - anim_request = anki_vector.messaging.protocol.PlayAnimationRequest(animation=anim) - return await conn.grpc_interface.PlayAnimation(anim_request) # This needs to be run in an asyncio loop - conn.run_coroutine(play_animation()).result() - # Close the connection - conn.close() - """ - if self._control_events: - self._control_events.shutdown() - if self._control_stream_task: - self._control_stream_task.cancel() - self.run_coroutine(self._control_stream_task).result() - self._cancel_active() - if self._channel: - self.run_coroutine(self._channel.close()).result() - self.run_coroutine(self._done_signal.set) - self._thread.join(timeout=5) - self._thread = None - - def run_soon(self, coro: Awaitable) -> None: - """Schedules the given awaitable to run on the event loop for the connection thread. - - .. testcode:: - - import anki_vector - import time - - async def my_coroutine(): - print("Running on the connection thread") - - with anki_vector.Robot() as robot: - robot.conn.run_soon(my_coroutine()) - time.sleep(1) - - :param coro: The coroutine, task or any awaitable to schedule for execution on the connection thread. - """ - if coro is None or not inspect.isawaitable(coro): - raise Exception(f"\n\n{coro.__name__ if hasattr(coro, '__name__') else coro} is not awaitable, so cannot be ran with run_soon.\n") - - def soon(): - try: - asyncio.ensure_future(coro) - except TypeError as e: - raise Exception(f"\n\n{coro.__name__ if hasattr(coro, '__name__') else coro} could not be ensured as a future.\n") from e - if threading.current_thread() is self._thread: - self._loop.call_soon(soon) - else: - self._loop.call_soon_threadsafe(soon) - - def run_coroutine(self, coro: Awaitable) -> Any: - """Runs a given awaitable on the connection thread's event loop. - Cannot be called from within the connection thread. - - .. testcode:: - - import anki_vector - - async def my_coroutine(): - print("Running on the connection thread") - return "Finished" - - with anki_vector.Robot() as robot: - result = robot.conn.run_coroutine(my_coroutine()) - - :param coro: The coroutine, task or any other awaitable which should be executed. - :returns: The result of the awaitable's execution. - """ - if threading.current_thread() is self._thread: - raise Exception("Attempting to invoke async from same thread." - "Instead you may want to use 'run_soon'") - if asyncio.iscoroutinefunction(coro) or asyncio.iscoroutine(coro): - return self._run_coroutine(coro) - if asyncio.isfuture(coro): - async def future_coro(): - return await coro - return self._run_coroutine(future_coro()) - if callable(coro): - async def wrapped_coro(): - return coro() - return self._run_coroutine(wrapped_coro()) - raise Exception("\n\nInvalid parameter to run_coroutine: {}\n" - "This function expects a coroutine, task, or awaitable.".format(type(coro))) - - def _run_coroutine(self, coro): - return asyncio.run_coroutine_threadsafe(coro, self._loop) - - -def on_connection_thread(log_messaging: bool = True, requires_control: bool = True) -> Callable[[Coroutine[util.Component, Any, None]], Any]: - """A decorator generator used internally to denote which functions will run on - the connection thread. This unblocks the caller of the wrapped function - and allows them to continue running while the messages are being processed. - - .. code-block:: python - - import anki_vector - - class MyComponent(anki_vector.util.Component): - @connection._on_connection_thread() - async def on_connection_thread(self): - # Do work on the connection thread - - :param log_messaging: True if the log output should include the entire message or just the size. Recommended for - large binary return values. - :param requires_control: True if the function should wait until behavior control is granted before executing. - :returns: A decorator which has 3 possible returns based on context: the result of the decorated function, - the :class:`concurrent.futures.Future` which points to the decorated function, or the - :class:`asyncio.Future` which points to the decorated function. - These contexts are: when the robot is a :class:`~anki_vector.robot.Robot`, - when the robot is an :class:`~anki_vector.robot.AsyncRobot`, and when - called from the connection thread respectively. - """ - def _on_connection_thread_decorator(func: Coroutine) -> Any: - """A decorator which specifies a function to be executed on the connection thread - - :params func: The function to be decorated - :returns: There are 3 possible returns based on context: the result of the decorated function, - the :class:`concurrent.futures.Future` which points to the decorated function, or the - :class:`asyncio.Future` which points to the decorated function. - These contexts are: when the robot is a :class:`anki_vector.robot.Robot`, - when the robot is an :class:`anki_vector.robot.AsyncRobot`, and when - called from the connection thread respectively. - """ - if not asyncio.iscoroutinefunction(func): - raise Exception("\n\nCannot define non-coroutine function '{}' to run on connection thread.\n" - "Make sure the function is defined using 'async def'.".format(func.__name__ if hasattr(func, "__name__") else func)) - - @functools.wraps(func) - async def log_handler(conn: Connection, func: Coroutine, logger: logging.Logger, *args: List[Any], **kwargs: Dict[str, Any]) -> Coroutine: - """Wrap the provided coroutine to better express exceptions as specific :class:`anki_vector.exceptions.VectorException`s, and - adds logging to incoming (from the robot) and outgoing (to the robot) messages. - """ - result = None - # TODO: only have the request wait for control if we're not done. If done raise an exception. - control = conn.control_granted_event - if requires_control and not control.is_set(): - if not conn.requires_behavior_control: - raise VectorControlException(func.__name__) - logger.info(f"Delaying {func.__name__} until behavior control is granted") - await asyncio.wait([conn.control_granted_event.wait()], timeout=10) - logger.debug(f'Outgoing {func.__name__}: {args[1:] if log_messaging else "size = {} bytes".format(sys.getsizeof(args[1:]))}') - try: - result = await func(*args, **kwargs) - except grpc.RpcError as rpc_error: - raise connection_error(rpc_error) from rpc_error - logger.debug(f'Incoming {func.__name__}: {type(result).__name__} ({str(result).strip() if log_messaging else "size = {} bytes".format(sys.getsizeof(result))})') - return result - - @functools.wraps(func) - def result(*args: List[Any], **kwargs: Dict[str, Any]) -> Any: - """The function that is the result of the decorator. Provides a wrapped function. - - :param _return_future: A hidden parameter which allows the wrapped function to explicitly - return a future (default for AsyncRobot) or not (default for Robot). - :returns: Based on context this can return the result of the decorated function, - the :class:`concurrent.futures.Future` which points to the decorated function, or the - :class:`asyncio.Future` which points to the decorated function. - These contexts are: when the robot is a :class:`anki_vector.robot.Robot`, - when the robot is an :class:`anki_vector.robot.AsyncRobot`, and when - called from the connection thread respectively.""" - self = args[0] # Get the self reference from the function call - # if the call supplies a _return_future parameter then override force_async with that. - _return_future = kwargs.pop('_return_future', self.force_async) - wrapped_coroutine = log_handler(self.conn, func, self.logger, *args, **kwargs) - if threading.current_thread() == self.conn.thread: - if self.conn.loop.is_running(): - return asyncio.ensure_future(wrapped_coroutine, loop=self.conn.loop) - raise Exception("\n\nThe connection thread loop is not running, but a " - "function '{}' is being invoked on that thread.\n".format(func.__name__ if hasattr(func, "__name__") else func)) - future = asyncio.run_coroutine_threadsafe(wrapped_coroutine, self.conn.loop) - if requires_control: - self.conn.active_commands.append(future) - - def clear_when_done(fut): - if fut in self.conn.active_commands: - self.conn.active_commands.remove(fut) - future.add_done_callback(clear_when_done) - if _return_future: - return future - try: - return future.result() - except futures.CancelledError: - self.logger.warning(f"{func.__name__} cancelled because behavior control was lost") - return None - return result - return _on_connection_thread_decorator diff --git a/anki_vector/events.py b/anki_vector/events.py deleted file mode 100644 index 9c50a7d..0000000 --- a/anki_vector/events.py +++ /dev/null @@ -1,392 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Event handler used to make functions subscribe to robot events. -""" - -__all__ = ['EventHandler', 'Events'] - -import asyncio -from concurrent.futures import CancelledError -from enum import Enum -import threading -from typing import Callable -import uuid - -from .connection import Connection -from . import util -from .messaging import protocol - - -class Events(Enum): - """List of events available.""" - - # Robot - robot_state = "robot_state" #: Robot event containing changes to the robot's state. - mirror_mode_disabled = "mirror_mode_disabled" # : Robot event triggered when mirror mode (camera feed displayed on robot's face) is automatically disabled due to SDK no longer having control of the robot. - vision_modes_auto_disabled = "vision_modes_auto_disabled" # : Robot event triggered when all vision modes are automatically disabled due to the SDK no longer having control of the robot. - - # Objects - object_available = "object_available" #: After the ConnectCube process is started, all available light cubes in range will broadcast an availability message through the Robot. - object_connection_state = "object_connection_state" # : Robot event for an object with the ability to connect to the robot digitally changing its connection state. - object_moved = "object_moved" #: Robot event triggered when an object starts moving. - object_stopped_moving = "object_stopped_moving" #: Robot event triggered when an object stops moving. - object_up_axis_changed = "object_up_axis_changed" #: Robot event triggered when an object's orientation changed. - object_tapped = "object_tapped" #: Robot event triggered when an object is tapped. - robot_observed_object = "robot_observed_object" #: Robot event triggered when an object is observed by the robot. - cube_connection_lost = "cube_connection_lost" #: Robot event triggered when an object's subscribed connection has been lost. - - robot_observed_face = "robot_observed_face" #: Robot event for when a face is observed by the robot. - robot_changed_observed_face_id = "robot_changed_observed_face_id" # : Robot event for when a known face changes its id. - - wake_word = "wake_word" #: Robot event triggered when Vector hears "Hey Vector" - - # Audio - audio_send_mode_changed = "audio_send_mode_changed" #: Robot event containing changes to the robot's audio stream source data processing mode. - - # Generated by SDK - object_observed = "object_observed" #: Python event triggered in response to robot_observed_object with sdk metadata. - object_appeared = "object_appeared" #: Python event triggered when an object first receives robot_observed_object. - object_disappeared = "object_disappeared" #: Python event triggered when an object has not received a robot_observed_object for a specified time. - object_finished_move = "object_finished_move" #: Python event triggered in response to object_stopped_moving with duration data. - nav_map_update = "nav_map_update" #: Python event containing nav map data. - - -class _EventCallback: - def __init__(self, callback, on_connection_thread: bool = False): - self._callback = callback - self._on_connection_thread = on_connection_thread - - @property - def on_connection_thread(self): - return self._on_connection_thread - - @property - def callback(self): - return self._callback - - def __eq__(self, other): - other_cb = other - if hasattr(other, "callback"): - other_cb = other.callback - return other_cb == self.callback - - def __hash__(self): - return self._callback.__hash__() - - -class EventHandler: - """Listen for Vector events.""" - - def __init__(self): - self.logger = util.get_class_logger(__name__, self) - self._conn = None - self._conn_id = None - self.listening_for_events = False - self.event_future = None - self._thread: threading.Thread = None - self._loop: asyncio.BaseEventLoop = None - self.subscribers = {} - self._done_signal: asyncio.Event = None - - def start(self, connection: Connection): - """Start listening for events. Automatically called by the :class:`anki_vector.robot.Robot` class. - - :param connection: A reference to the connection from the SDK to the robot. - :param loop: The loop to run the event task on. - """ - self._conn = connection - self.listening_for_events = True - self._thread = threading.Thread(target=self._run_thread, daemon=True, name="Event Stream Handler Thread") - self._thread.start() - - def _run_thread(self): - try: - self._loop = asyncio.new_event_loop() - asyncio.set_event_loop(self._loop) - self._done_signal = asyncio.Event(loop=self._loop) - # create an event stream handler on the connection thread - self.event_future = asyncio.run_coroutine_threadsafe(self._handle_event_stream(), self._conn.loop) - - async def wait_until_done(): - return await self._done_signal.wait() - self._loop.run_until_complete(wait_until_done()) - finally: - self._loop.close() - - def close(self): - """Stop listening for events. Automatically called by the :class:`anki_vector.robot.Robot` class. - """ - self.listening_for_events = False - try: - self.event_future.cancel() - self.event_future.result() - except CancelledError: - pass - self._loop.call_soon_threadsafe(self._done_signal.set) - self._thread.join(timeout=5) - self._thread = None - - def _notify(self, event_callback, event_name, event_data): - loop = self._loop - thread = self._thread - # For high priority events that shouldn't be blocked by user callbacks - # they will run directly on the connection thread. This should typically - # be used when setting robot properties from events. - if event_callback.on_connection_thread: - loop = self._conn.loop - thread = self._conn.thread - callback = event_callback.callback - if threading.current_thread() is thread: - if asyncio.iscoroutinefunction(callback): - asyncio.ensure_future(callback(event_name, event_data), loop=loop) - elif asyncio.iscoroutine(callback): - asyncio.ensure_future(callback, loop=loop) - else: - loop.call_soon(callback, event_name, event_data) - else: - if asyncio.iscoroutinefunction(callback): - asyncio.run_coroutine_threadsafe(callback(event_name, event_data), loop=loop) - elif asyncio.iscoroutine(callback): - asyncio.run_coroutine_threadsafe(callback, loop=loop) - else: - loop.call_soon_threadsafe(callback, event_name, event_data) - - async def dispatch_event_by_name(self, event_data, event_name: str = None): - """Dispatches event to event listeners by name. - - .. testcode:: - - import anki_vector - - def event_listener(name, msg): - print(name) # will print 'my_event' - print(msg) # will print 'my_event dispatched' - - with anki_vector.Robot() as robot: - robot.events.subscribe_by_name(event_listener, event_name='my_event') - robot.conn.run_coroutine(robot.events.dispatch_event_by_name('my_event dispatched', event_name='my_event')) - - :param event_data: Data to accompany the event. - :param event_name: The name of the event that will result in func being called. - """ - if not event_name: - self.logger.error('Bad event_name in dispatch_event.') - - if event_name in self.subscribers.keys(): - subscribers = self.subscribers[event_name].copy() - for callback in subscribers: - self._notify(callback, event_name, event_data) - - async def dispatch_event(self, event_data, event_type: Events): - """Dispatches event to event listeners.""" - if not event_type: - self.logger.error('Bad event_type in dispatch_event.') - - event_name = event_type.value - - await self.dispatch_event_by_name(event_data, event_name) - - def _unpackage_event(self, enum_key: str, event): - event_key = event.WhichOneof(enum_key) - event_data = getattr(event, event_key) - if getattr(event_data, 'WhichOneof'): - # Object events are automatically unpackaged into their sub-event classes. - try: - return self._unpackage_event('object_event_type', event_data) - except ValueError: - pass - except TypeError: - pass - - return event_key, event_data - - async def _handle_event_stream(self): - self._conn_id = bytes(uuid.uuid4().hex, "utf-8") - try: - req = protocol.EventRequest(connection_id=self._conn_id) - async for evt in self._conn.grpc_interface.EventStream(req): - if not self.listening_for_events: - break - try: - unpackaged_event_key, unpackaged_event_data = self._unpackage_event('event_type', evt.event) - await self.dispatch_event_by_name(unpackaged_event_data, unpackaged_event_key) - except TypeError: - self.logger.warning('Unknown Event type') - except CancelledError: - self.logger.debug('Event handler task was cancelled. This is expected during disconnection.') - - def subscribe_by_name(self, func: Callable, event_name: str = None, **kwargs): - """Receive a method call when the specified event occurs. - - .. testcode:: - - import anki_vector - - def event_listener(name, msg): - print(name) # will print 'my_event' - print(msg) # will print 'my_event dispatched' - - with anki_vector.Robot() as robot: - robot.events.subscribe_by_name(event_listener, event_name='my_event') - robot.conn.run_coroutine(robot.events.dispatch_event_by_name('my_event dispatched', event_name='my_event')) - - :param func: A method implemented in your code that will be called when the event is fired. - :param event_name: The name of the event that will result in func being called. - """ - if not event_name: - self.logger.error('Bad event_name in subscribe.') - on_connection_thread = kwargs["on_connection_thread"] if "on_connection_thread" in kwargs else False - - if event_name not in self.subscribers.keys(): - self.subscribers[event_name] = set() - self.subscribers[event_name].add(_EventCallback(func, on_connection_thread)) - - def subscribe(self, func: Callable, event_type: Events = None, **kwargs): - """Receive a method call when the specified event occurs. - - .. testcode:: - - import anki_vector - from anki_vector.events import Events - from anki_vector.util import degrees - import functools - import threading - - said_text = False - evt = threading.Event() - - def on_robot_observed_face(robot, event_type, event): - print("Vector sees a face") - global said_text - if not said_text: - said_text = True - robot.say_text("I see a face!") - evt.set() - - args = anki_vector.util.parse_command_args() - with anki_vector.Robot(enable_face_detection=True) as robot: - - # If necessary, move Vector's Head and Lift to make it easy to see his face - robot.behavior.set_head_angle(degrees(45.0)) - robot.behavior.set_lift_height(0.0) - - on_robot_observed_face = functools.partial(on_robot_observed_face, robot) - robot.events.subscribe(on_robot_observed_face, Events.robot_observed_face) - - print("------ waiting for face events, press ctrl+c to exit early ------") - - try: - if not evt.wait(timeout=5): - print("------ Vector never saw your face! ------") - except KeyboardInterrupt: - pass - - robot.events.unsubscribe(on_robot_observed_face, Events.robot_observed_face) - - :param func: A method implemented in your code that will be called when the event is fired. - :param event_type: The enum type of the event that will result in func being called. - """ - if not event_type: - self.logger.error('Bad event_type in subscribe.') - - event_name = event_type.value - - self.subscribe_by_name(func, event_name, **kwargs) - - def unsubscribe_by_name(self, func: Callable, event_name: str = None): - """Unregister a previously subscribed method from an event. - - .. testcode:: - - import anki_vector - - def event_listener(name, msg): - print(name) # will print 'my_event' - print(msg) # will print 'my_event dispatched' - - with anki_vector.Robot() as robot: - robot.events.subscribe_by_name(event_listener, event_name='my_event') - robot.conn.run_coroutine(robot.events.dispatch_event_by_name('my_event dispatched', event_name='my_event')) - - :param func: The method you no longer wish to be called when an event fires. - :param event_name: The name of the event for which you no longer want to receive a method call. - """ - if not event_name: - self.logger.error('Bad event_key in unsubscribe.') - - if event_name in self.subscribers.keys(): - event_subscribers = self.subscribers[event_name] - if func in event_subscribers: - event_subscribers.remove(func) - if not event_subscribers: - self.subscribers.pop(event_name, None) - else: - self.logger.error(f"The function '{func.__name__}' is not subscribed to '{event_name}'") - else: - self.logger.error(f"Cannot unsubscribe from event_type '{event_name}'. " - "It has no subscribers.") - - def unsubscribe(self, func: Callable, event_type: Events = None): - """Unregister a previously subscribed method from an event. - - .. testcode:: - - import anki_vector - from anki_vector.events import Events - from anki_vector.util import degrees - import functools - import threading - - said_text = False - evt = threading.Event() - - def on_robot_observed_face(robot, event_type, event): - print("Vector sees a face") - global said_text - if not said_text: - said_text = True - robot.say_text("I see a face!") - evt.set() - - args = anki_vector.util.parse_command_args() - with anki_vector.Robot(enable_face_detection=True) as robot: - - # If necessary, move Vector's Head and Lift to make it easy to see his face - robot.behavior.set_head_angle(degrees(45.0)) - robot.behavior.set_lift_height(0.0) - - on_robot_observed_face = functools.partial(on_robot_observed_face, robot) - robot.events.subscribe(on_robot_observed_face, Events.robot_observed_face) - - print("------ waiting for face events, press ctrl+c to exit early ------") - - try: - if not evt.wait(timeout=5): - print("------ Vector never saw your face! ------") - except KeyboardInterrupt: - pass - - robot.events.unsubscribe(on_robot_observed_face, Events.robot_observed_face) - - :param func: The enum type of the event you no longer wish to be called when an event fires. - :param event_type: The name of the event for which you no longer want to receive a method call. - """ - if not event_type: - self.logger.error('Bad event_type in unsubscribe.') - - event_name = event_type.value - - self.unsubscribe_by_name(func, event_name) diff --git a/anki_vector/exceptions.py b/anki_vector/exceptions.py deleted file mode 100644 index 6c25130..0000000 --- a/anki_vector/exceptions.py +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -SDK-specific exception classes for Vector. -""" - -from grpc import RpcError, StatusCode - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['VectorCameraFeedDisabledException', - 'VectorConnectionException', - 'VectorControlException', - 'VectorControlTimeoutException', - 'VectorException', - 'VectorInvalidVersionException', - 'VectorNotFoundException', - 'VectorNotReadyException', - 'VectorTimeoutException', - 'VectorUnauthenticatedException', - 'VectorUnavailableException', - 'VectorUnimplementedException', - 'connection_error'] - - -class VectorException(Exception): - """Base class of all Vector SDK exceptions.""" - - -class VectorInvalidVersionException(VectorException): - """Your SDK version is not compatible with Vector's version.""" - - def __init__(self, version_request, version_response): - host = version_response.host_version - min_host = version_request.min_host_version - client = version_request.client_version - if min_host > host: - error_message = (f"{self.__class__.__doc__}\n\n" - f"Your Vector is an older version that is not supported by the SDK: min={min_host} > host={host}\n" - f"Use your app to make sure that Vector is on the internet, and able to download the latest update.") - else: - error_message = (f"{self.__class__.__doc__}\n\n" - f"Your SDK is an older version that is not supported by Vector: {host} > {client}\n" - f"Please install the latest SDK to continue.") - super().__init__(error_message) - - -class VectorControlException(VectorException): - """Unable to run a function which requires behavior control.""" - - def __init__(self, function): - msg = (f"Unable to run '{function}' because it requires behavior control.\n\n" - "Make sure to request control from Vector either by providing the 'enable_behavior_control' parameter to Robot, " - "or directly call 'request_control()' on your connection.") - super().__init__(msg) - - -class VectorConnectionException(VectorException): - def __init__(self, cause): - doc_str = self.__class__.__doc__ - if cause is not None: - self._status = cause.code() - self._details = cause.details() - msg = (f"{self._status}: {self._details}" - f"\n\n{doc_str if doc_str else 'Unknown error'}") - super().__init__(msg) - else: - super().__init__(doc_str) - - @property - def status(self): - return self._status - - @property - def details(self): - return self._details - - -class VectorUnauthenticatedException(VectorConnectionException): - """Failed to authenticate request.""" - - -class VectorUnavailableException(VectorConnectionException): - """Unable to reach Vector.""" - - -class VectorUnimplementedException(VectorConnectionException): - """Vector does not handle this message.""" - - -class VectorTimeoutException(VectorConnectionException): - """Message took too long to complete.""" - - -def connection_error(rpc_error: RpcError) -> VectorConnectionException: - """Translates grpc-specific errors to user-friendly :class:`VectorConnectionException`.""" - code = rpc_error.code() - if code is StatusCode.UNAUTHENTICATED: - return VectorUnauthenticatedException(rpc_error) - if code is StatusCode.UNAVAILABLE: - return VectorUnavailableException(rpc_error) - if code is StatusCode.UNIMPLEMENTED: - return VectorUnimplementedException(rpc_error) - if code is StatusCode.DEADLINE_EXCEEDED: - return VectorTimeoutException(rpc_error) - return VectorConnectionException(rpc_error) - - -class _VectorGenericException(VectorException): - def __init__(self, cause=None): - msg = (f"{self.__class__.__doc__}\n{cause if cause is not None else ''}") - super().__init__(msg) - - -class VectorNotFoundException(_VectorGenericException): - """Unable to establish a connection to Vector. - -Make sure you're on the same network, and Vector is connected to the internet. -""" - - -class VectorNotReadyException(_VectorGenericException): - """Vector tried to do something before it was ready.""" - - -class VectorControlTimeoutException(_VectorGenericException): - """Failed to get control of Vector. - -Please verify that Vector is connected to the internet, is on a flat surface, and is fully charged. -""" - - -class VectorCameraFeedDisabledException(VectorException): - """Failed to render video because camera feed was disabled.""" diff --git a/anki_vector/faces.py b/anki_vector/faces.py deleted file mode 100644 index c8d276f..0000000 --- a/anki_vector/faces.py +++ /dev/null @@ -1,388 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Face recognition and enrollment. - -Vector is capable of recognizing human faces, tracking their position and rotation -("pose") and assigning names to them via an enrollment process. - -The :class:`anki_vector.world.World` object keeps track of faces the robot currently -knows about, along with those that are currently visible to the camera. - -Each face is assigned a :class:`Face` object, which generates a number of -observable events whenever the face is observed, has its ID updated. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['Expression', 'Face', 'FaceComponent'] - -from enum import Enum -from typing import List - -from . import connection, util, objects, events -from .messaging import protocol - - -class Expression(Enum): - """Facial expressions that Vector can distinguish. - - Facial expression not recognized. - Call :func:`anki_vector.robot.Robot.vision.enable_face_detection(detect_faces=True)` to enable recognition. - """ - UNKNOWN = protocol.FacialExpression.Value("EXPRESSION_UNKNOWN") - #: Facial expression neutral - NEUTRAL = protocol.FacialExpression.Value("EXPRESSION_NEUTRAL") - #: Facial expression happiness - HAPPINESS = protocol.FacialExpression.Value("EXPRESSION_HAPPINESS") - #: Facial expression surprise - SURPRISE = protocol.FacialExpression.Value("EXPRESSION_SURPRISE") - #: Facial expression anger - ANGER = protocol.FacialExpression.Value("EXPRESSION_ANGER") - #: Facial expression sadness - SADNESS = protocol.FacialExpression.Value("EXPRESSION_SADNESS") - - -class Face(objects.ObservableObject): - """A single face that Vector has detected. - - May represent a face that has previously been enrolled, in which case - :attr:`name` will hold the name that it was enrolled with. - - Each Face instance has a :attr:`face_id` integer - This may change if - Vector later gets an improved view and makes a different prediction about - which face he is looking at. - """ - - def __init__(self, - robot, - pose: util.Pose, - image_rect: util.ImageRect, - face_id: int, - name: str, - expression: str, - expression_score: List[int], - left_eye: List[protocol.CladPoint], - right_eye: List[protocol.CladPoint], - nose: List[protocol.CladPoint], - mouth: List[protocol.CladPoint], - instantiation_timestamp: float, - **kw): - - super(Face, self).__init__(robot, **kw) - - self._face_id = face_id - self._updated_face_id = None - self._name = name - self._expression = expression - - # Individual expression values histogram, sums to 100 - # (Exception: all zero if expression=Unknown) - self._expression_score = expression_score - - # Face landmarks - self._left_eye = left_eye - self._right_eye = right_eye - self._nose = nose - self._mouth = mouth - - self._on_observed(pose, image_rect, instantiation_timestamp) - - self._robot.events.subscribe( - self._on_face_observed, - events.Events.robot_observed_face) - - self._robot.events.subscribe( - self._on_face_id_changed, - events.Events.robot_changed_observed_face_id) - - def __repr__(self): - return (f"<{self.__class__.__name__} Face id: {self.face_id} " - f"Updated face id: {self.updated_face_id} Name: {self.name} " - f"Expression: {protocol.FacialExpression.Name(self.expression)}>") - - def teardown(self): - """All faces will be torn down by the world when no longer needed.""" - self._robot.events.unsubscribe( - self._on_face_observed, - events.Events.robot_observed_face) - - self._robot.events.unsubscribe( - self._on_face_id_changed, - events.Events.robot_changed_observed_face_id) - - @property - def face_id(self) -> int: - """The internal ID assigned to the face. - - This value can only be assigned once as it is static in the engine. - - :getter: Returns the face ID - :setter: Sets the face ID - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_face_detection=True) as robot: - # Print the visible face ids - for face in robot.world.visible_faces: - print(f"Visible id: {face.face_id}") - """ - return self._face_id if self._updated_face_id is None else self._updated_face_id - - @face_id.setter - def face_id(self, face_id: str): - if self._face_id is not None: - raise ValueError(f"Cannot change face ID once set (from {self._face_id} to {face_id})") - self._face_id = face_id - - @property - def has_updated_face_id(self) -> bool: - """True if this face been updated / superseded by a face with a new ID. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_face_detection=True) as robot: - for face in robot.world.visible_faces: - was_face_originally_unrecognized_but_is_now_recognized = face.has_updated_face_id - """ - return self._updated_face_id is not None - - @property - def updated_face_id(self) -> int: - """The ID for the face that superseded this one (if any, otherwise :meth:`face_id`) - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_face_detection=True) as robot: - for face in robot.world.visible_faces: - print(f"updated_face_id: {face.updated_face_id}") - """ - if self._updated_face_id: - return self._updated_face_id - return self._face_id - - @property - def name(self) -> str: - """The name Vector has associated with the face. - - This string will be empty if the face is not recognized or enrolled. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_face_detection=True) as robot: - for face in robot.world.visible_faces: - print(f"Face name: {face.name}") - """ - return self._name - - @property - def expression(self) -> str: - """The facial expression Vector has recognized on the face. - - Will be :attr:`Expression.UNKNOWN` by default if you haven't called - :meth:`anki_vector.robot.Robot.vision.enable_face_detection(detect_faces=True, estimate_emotion=True)` to enable - the facial expression estimation. Otherwise it will be equal to one of: - :attr:`Expression.NEUTRAL`, :attr:`Expression.HAPPINESS`, - :attr:`Expression.SURPRISE`, :attr:`Expression.ANGER`, - or :attr:`Expression.SADNESS`. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_face_detection=True) as robot: - for face in robot.world.visible_faces: - print(f"expression: {face.expression}") - """ - return self._expression - - @property - def expression_score(self) -> List[int]: - """The score/confidence that :attr:`expression` was correct. - - Will be 0 if expression is :attr:`Expression.UNKNOWN` (e.g. if - :meth:`anki_vector.robot.Robot.vision.enable_face_detection(detect_faces=True, estimate_emotion=True)` wasn't - called yet). The maximum possible score is 100. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_face_detection=True) as robot: - for face in robot.world.visible_faces: - print(f"expression_score: {face.expression_score}") - """ - return self._expression_score - - @property - def left_eye(self) -> List[protocol.CladPoint]: - """sequence of tuples of float (x,y): points representing the outline of the left eye. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_face_detection=True) as robot: - for face in robot.world.visible_faces: - print(f"left_eye: {face.left_eye}") - """ - return self._left_eye - - @property - def right_eye(self) -> List[protocol.CladPoint]: - """sequence of tuples of float (x,y): points representing the outline of the right eye. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_face_detection=True) as robot: - for face in robot.world.visible_faces: - print(f"right_eye: {face.right_eye}") - """ - return self._right_eye - - @property - def nose(self) -> List[protocol.CladPoint]: - """sequence of tuples of float (x,y): points representing the outline of the nose. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_face_detection=True) as robot: - for face in robot.world.visible_faces: - print(f"nose: {face.nose}") - """ - return self._nose - - @property - def mouth(self) -> List[protocol.CladPoint]: - """sequence of tuples of float (x,y): points representing the outline of the mouth. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_face_detection=True) as robot: - for face in robot.world.visible_faces: - print(f"mouth: {face.mouth}") - """ - return self._mouth - - #### Private Event Handlers #### - - def _on_face_observed(self, _, msg): - """Unpacks the face observed stream data from Vector into a Face instance.""" - if self._face_id == msg.face_id: - - pose = util.Pose(x=msg.pose.x, y=msg.pose.y, z=msg.pose.z, - q0=msg.pose.q0, q1=msg.pose.q1, - q2=msg.pose.q2, q3=msg.pose.q3, - origin_id=msg.pose.origin_id) - image_rect = util.ImageRect(msg.img_rect.x_top_left, - msg.img_rect.y_top_left, - msg.img_rect.width, - msg.img_rect.height) - - self._name = msg.name - - self._expression = msg.expression - self._expression_score = msg.expression_values - self._left_eye = msg.left_eye - self._right_eye = msg.right_eye - self._nose = msg.nose - self._mouth = msg.mouth - self._on_observed(pose, image_rect, msg.timestamp) - - def _on_face_id_changed(self, _, msg): - """Updates the face id when a tracked face (negative ID) is recognized and - receives a positive ID or when face records get merged""" - if self._face_id == msg.old_id: - self._updated_face_id = msg.new_id - - -class FaceComponent(util.Component): - """Manage the state of the faces on the robot.""" - - @connection.on_connection_thread(requires_control=False) - async def request_enrolled_names(self) -> protocol.RequestEnrolledNamesRequest: - """Asks the robot for the list of names attached to faces that it can identify. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - name_data_list = robot.faces.request_enrolled_names() - print(f"{name_data_list}") - """ - req = protocol.RequestEnrolledNamesRequest() - return await self.grpc_interface.RequestEnrolledNames(req) - - @connection.on_connection_thread(requires_control=False) - async def update_enrolled_face_by_id(self, face_id: int, old_name: str, new_name: str): - """Update the name enrolled for a given face. - - :param face_id: The ID of the face to rename. - :param old_name: The old name of the face (must be correct, otherwise message is ignored). - :param new_name: The new name for the face. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.faces.update_enrolled_face_by_id(1, 'Hanns', 'Boris') - """ - req = protocol.UpdateEnrolledFaceByIDRequest(face_id=face_id, - old_name=old_name, new_name=new_name) - return await self.grpc_interface.UpdateEnrolledFaceByID(req) - - @connection.on_connection_thread(requires_control=False) - async def erase_enrolled_face_by_id(self, face_id: int): - """Erase the enrollment (name) record for the face with this ID. - - :param face_id: The ID of the face to erase. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.faces.erase_enrolled_face_by_id(1) - """ - req = protocol.EraseEnrolledFaceByIDRequest(face_id=face_id) - return await self.grpc_interface.EraseEnrolledFaceByID(req) - - @connection.on_connection_thread(requires_control=False) - async def erase_all_enrolled_faces(self): - """Erase the enrollment (name) records for all faces. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.faces.erase_all_enrolled_faces() - """ - req = protocol.EraseAllEnrolledFacesRequest() - return await self.grpc_interface.EraseAllEnrolledFaces(req) diff --git a/anki_vector/lights.py b/anki_vector/lights.py deleted file mode 100755 index 8ea84e6..0000000 --- a/anki_vector/lights.py +++ /dev/null @@ -1,210 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Helper routines for dealing with Vector's lights and colors.""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['MAX_COLOR_PROFILE', 'WHITE_BALANCED_CUBE_PROFILE', - 'blue_light', 'cyan_light', 'green_light', 'magenta_light', 'off_light', - 'red_light', 'white_light', 'yellow_light', - 'Color', 'ColorProfile', 'Light', 'package_request_params'] - -from .color import Color, green, red, blue, cyan, magenta, yellow, white, off - - -class ColorProfile: - """Applies transforms to make Vector's lights and colors appear as - intended, by limiting maximum channel intensity. - - :param red_multiplier: Scaling value for the brightness of red Lights - :param green_multiplier: Scaling value for the brightness of green Lights - :param blue_multiplier: Scaling value for the brightness of blue Lights - """ - - def __init__(self, red_multiplier: float, green_multiplier: float, blue_multiplier: float): - self._red_multiplier = red_multiplier - self._green_multiplier = green_multiplier - self._blue_multiplier = blue_multiplier - - # TODO Needs docs, param types, sample code - def augment_color(self, original_color): - rgb = [ - (original_color.int_color >> 24) & 0xff, - (original_color.int_color >> 16) & 0xff, - (original_color.int_color >> 8) & 0xff - ] - - rgb[0] = int(self._red_multiplier * rgb[0]) - rgb[1] = int(self._green_multiplier * rgb[1]) - rgb[2] = int(self._blue_multiplier * rgb[2]) - - result_int_code = (rgb[0] << 24) | (rgb[1] << 16) | (rgb[2] << 8) | 0xff - return Color(result_int_code) - - # TODO Needs example code, more descriptive docs - @property - def red_multiplier(self): - """float: The multiplier used on the red channel.""" - return self._red_multiplier - - # TODO Needs example code, more descriptive docs - @property - def green_multiplier(self): - """float: The multiplier used on the red channel.""" - return self._green_multiplier - - # TODO Needs example code, more descriptive docs - @property - def blue_multiplier(self): - """float: The multiplier used on the red channel.""" - return self._blue_multiplier - - -#: :class:`ColorProfile`: Color profile to get the maximum possible brightness out of each LED. -MAX_COLOR_PROFILE = ColorProfile(red_multiplier=1.0, - green_multiplier=1.0, - blue_multiplier=1.0) - -#: :class:`ColorProfile`: Color profile balanced so that a max color value more closely resembles pure white. -# TODO: Balance this more carefully once robots with proper color pipe -# hardware becomes available -WHITE_BALANCED_CUBE_PROFILE = ColorProfile(red_multiplier=1.0, - green_multiplier=0.95, - blue_multiplier=0.7) - - -class Light: - """Lights are used with Vector's Cube. - - Lights may either be "on" or "off", though in practice any colors may be - assigned to either state (including no color/light). - """ - - def __init__(self, - on_color: Color = off, - off_color: Color = off, - on_period_ms: int = 250, - off_period_ms: int = 0, - transition_on_period_ms: int = 0, - transition_off_period_ms: int = 0): - self._on_color = on_color - self._off_color = off_color - self._on_period_ms = on_period_ms - self._off_period_ms = off_period_ms - self._transition_on_period_ms = transition_on_period_ms - self._transition_off_period_ms = transition_off_period_ms - - @property - def on_color(self) -> Color: - """The color shown when the light is on.""" - return self._on_color - - @on_color.setter - def on_color(self, color): - if not isinstance(color, Color): - raise TypeError("Must specify a Color") - self._on_color = color - - @property - def off_color(self) -> Color: - """The color shown when the light is off.""" - return self._off_color - - @off_color.setter - def off_color(self, color): - if not isinstance(color, Color): - raise TypeError("Must specify a Color") - self._off_color = color - - @property - def on_period_ms(self) -> int: - """The number of milliseconds the light should be "on" for for each cycle.""" - return self._on_period_ms - - @on_period_ms.setter - def on_period_ms(self, ms): - if not 0 < ms < 2**32: - raise ValueError("Invalid value") - self._on_period_ms = ms - - @property - def off_period_ms(self) -> int: - """The number of milliseconds the light should be "off" for for each cycle.""" - return self._off_period_ms - - @off_period_ms.setter - def off_period_ms(self, ms): - if not 0 < ms < 2**32: - raise ValueError("Invalid value") - self._off_period_ms = ms - - @property - def transition_on_period_ms(self) -> int: - """The number of milliseconds to take to transition the light to the on color.""" - return self._transition_on_period_ms - - @transition_on_period_ms.setter - def transition_on_period_ms(self, ms): - if not 0 < ms < 2**32: - raise ValueError("Invalid value") - self._transition_on_period_ms = ms - - @property - def transition_off_period_ms(self) -> int: - """The number of milliseconds to take to transition the light to the off color.""" - return self._transition_off_period_ms - - @transition_off_period_ms.setter - def transition_off_period_ms(self, ms): - if not 0 < ms < 2**32: - raise ValueError("Invalid value") - self._transition_off_period_ms = ms - - -# TODO needs docs, param types. Should this be private? Maybe a more descriptive name? -def package_request_params(lights, color_profile): - merged_params = {} - for light in lights: - for attr_name in vars(light): - attr_name = attr_name[1:] - attr_val = getattr(light, attr_name) - if isinstance(attr_val, Color): - attr_val = color_profile.augment_color(attr_val).int_color - merged_params.setdefault(attr_name, []).append(attr_val) - return merged_params - - -#: :class:`Light`: A steady green colored LED light. -green_light = Light(on_color=green) - -#: :class:`Light`: A steady red colored LED light. -red_light = Light(on_color=red) - -#: :class:`Light`: A steady blue colored LED light. -blue_light = Light(on_color=blue) - -#: :class:`Light`: A steady cyan colored LED light. -cyan_light = Light(on_color=cyan) - -#: :class:`Light`: A steady magenta colored LED light. -magenta_light = Light(on_color=magenta) - -#: :class:`Light`: A steady yellow colored LED light. -yellow_light = Light(on_color=yellow) - -#: :class:`Light`: A steady white colored LED light. -white_light = Light(on_color=white) - -#: :class:`Light`: A steady off (non-illuminated LED light). -off_light = Light(on_color=off) diff --git a/anki_vector/messaging/__init__.py b/anki_vector/messaging/__init__.py deleted file mode 100644 index a08083b..0000000 --- a/anki_vector/messaging/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Protobuf and gRPC messages exposed to the Vector Python SDK -""" - -from . import protocol -from . import client - -__all__ = ['protocol', 'client'] diff --git a/anki_vector/messaging/alexa.proto b/anki_vector/messaging/alexa.proto deleted file mode 100644 index d4397d7..0000000 --- a/anki_vector/messaging/alexa.proto +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2018 Anki, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License in the file LICENSE.txt or at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Alexa messages - -syntax = "proto3"; - -package Anki.Vector.external_interface; - - diff --git a/anki_vector/messaging/alexa_pb2.py b/anki_vector/messaging/alexa_pb2.py deleted file mode 100644 index bcb059d..0000000 --- a/anki_vector/messaging/alexa_pb2.py +++ /dev/null @@ -1,30 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: anki_vector/messaging/alexa.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='anki_vector/messaging/alexa.proto', - package='Anki.Vector.external_interface', - syntax='proto3', - serialized_pb=_b('\n!anki_vector/messaging/alexa.proto\x12\x1e\x41nki.Vector.external_interfaceb\x06proto3') -) - - - -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - - -# @@protoc_insertion_point(module_scope) diff --git a/anki_vector/messaging/alexa_pb2_grpc.py b/anki_vector/messaging/alexa_pb2_grpc.py deleted file mode 100644 index a894352..0000000 --- a/anki_vector/messaging/alexa_pb2_grpc.py +++ /dev/null @@ -1,3 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - diff --git a/anki_vector/messaging/behavior.proto b/anki_vector/messaging/behavior.proto deleted file mode 100644 index 2d1faf7..0000000 --- a/anki_vector/messaging/behavior.proto +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2018 Anki, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License in the file LICENSE.txt or at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Behavior related messages - -syntax = "proto3"; - -package Anki.Vector.external_interface; - -import "anki_vector/messaging/messages.proto"; - -message ControlRelease {} - -// Request control of the behavior system at a given priority -message ControlRequest { - enum Priority { - UNKNOWN = 0; - // Request control above mandatory physical reactions. Not recommended. - OVERRIDE_ALL = 10; - // Highest priority level. Directly under mandatory physical reactions. - TOP_PRIORITY_AI = 20; - } - Priority priority = 1; -} - -// Messages that can be sent to the behavior stream. Explicitly -// requesting or releasing control. -message BehaviorControlRequest { - oneof request_type { - ControlRelease control_release = 1; - ControlRequest control_request = 2; - } -} - -// The SDK user is now free to run any actions and behaviors they like. -// Until a ControlLostResponse is received, they are directly in control -// of Vector's behavior system. -message ControlGrantedResponse {} - -// This informs the user that they lost control of the behavior system. -// All direct actions will be unavailable via the sdk until control is regained. -// Regaining control can be either through a call to ControlRequest, or -// can be as a result of conditions passed to the original ControlRequest. -message ControlLostResponse {} - -// Responses from the behavior stream. -message BehaviorControlResponse { - oneof response_type { - ControlGrantedResponse control_granted_response = 1; - ControlLostResponse control_lost_event = 2; - KeepAlivePing keep_alive = 3; - } -} \ No newline at end of file diff --git a/anki_vector/messaging/behavior_pb2.py b/anki_vector/messaging/behavior_pb2.py deleted file mode 100644 index 0e708b0..0000000 --- a/anki_vector/messaging/behavior_pb2.py +++ /dev/null @@ -1,321 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: anki_vector/messaging/behavior.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from anki_vector.messaging import messages_pb2 as anki__vector_dot_messaging_dot_messages__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='anki_vector/messaging/behavior.proto', - package='Anki.Vector.external_interface', - syntax='proto3', - serialized_pb=_b('\n$anki_vector/messaging/behavior.proto\x12\x1e\x41nki.Vector.external_interface\x1a$anki_vector/messaging/messages.proto\"\x10\n\x0e\x43ontrolRelease\"\x9b\x01\n\x0e\x43ontrolRequest\x12I\n\x08priority\x18\x01 \x01(\x0e\x32\x37.Anki.Vector.external_interface.ControlRequest.Priority\">\n\x08Priority\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x10\n\x0cOVERRIDE_ALL\x10\n\x12\x13\n\x0fTOP_PRIORITY_AI\x10\x14\"\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\"\x9e\x02\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\x42\x0f\n\rresponse_typeb\x06proto3') - , - dependencies=[anki__vector_dot_messaging_dot_messages__pb2.DESCRIPTOR,]) - - - -_CONTROLREQUEST_PRIORITY = _descriptor.EnumDescriptor( - name='Priority', - full_name='Anki.Vector.external_interface.ControlRequest.Priority', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='UNKNOWN', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='OVERRIDE_ALL', index=1, number=10, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='TOP_PRIORITY_AI', index=2, number=20, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=222, - serialized_end=284, -) -_sym_db.RegisterEnumDescriptor(_CONTROLREQUEST_PRIORITY) - - -_CONTROLRELEASE = _descriptor.Descriptor( - name='ControlRelease', - full_name='Anki.Vector.external_interface.ControlRelease', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=110, - serialized_end=126, -) - - -_CONTROLREQUEST = _descriptor.Descriptor( - name='ControlRequest', - full_name='Anki.Vector.external_interface.ControlRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='priority', full_name='Anki.Vector.external_interface.ControlRequest.priority', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _CONTROLREQUEST_PRIORITY, - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=129, - serialized_end=284, -) - - -_BEHAVIORCONTROLREQUEST = _descriptor.Descriptor( - name='BehaviorControlRequest', - full_name='Anki.Vector.external_interface.BehaviorControlRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='control_release', full_name='Anki.Vector.external_interface.BehaviorControlRequest.control_release', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='control_request', full_name='Anki.Vector.external_interface.BehaviorControlRequest.control_request', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='request_type', full_name='Anki.Vector.external_interface.BehaviorControlRequest.request_type', - index=0, containing_type=None, fields=[]), - ], - serialized_start=287, - serialized_end=477, -) - - -_CONTROLGRANTEDRESPONSE = _descriptor.Descriptor( - name='ControlGrantedResponse', - full_name='Anki.Vector.external_interface.ControlGrantedResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=479, - serialized_end=503, -) - - -_CONTROLLOSTRESPONSE = _descriptor.Descriptor( - name='ControlLostResponse', - full_name='Anki.Vector.external_interface.ControlLostResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=505, - serialized_end=526, -) - - -_BEHAVIORCONTROLRESPONSE = _descriptor.Descriptor( - name='BehaviorControlResponse', - full_name='Anki.Vector.external_interface.BehaviorControlResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='control_granted_response', full_name='Anki.Vector.external_interface.BehaviorControlResponse.control_granted_response', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='control_lost_event', full_name='Anki.Vector.external_interface.BehaviorControlResponse.control_lost_event', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='keep_alive', full_name='Anki.Vector.external_interface.BehaviorControlResponse.keep_alive', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='response_type', full_name='Anki.Vector.external_interface.BehaviorControlResponse.response_type', - index=0, containing_type=None, fields=[]), - ], - serialized_start=529, - serialized_end=815, -) - -_CONTROLREQUEST.fields_by_name['priority'].enum_type = _CONTROLREQUEST_PRIORITY -_CONTROLREQUEST_PRIORITY.containing_type = _CONTROLREQUEST -_BEHAVIORCONTROLREQUEST.fields_by_name['control_release'].message_type = _CONTROLRELEASE -_BEHAVIORCONTROLREQUEST.fields_by_name['control_request'].message_type = _CONTROLREQUEST -_BEHAVIORCONTROLREQUEST.oneofs_by_name['request_type'].fields.append( - _BEHAVIORCONTROLREQUEST.fields_by_name['control_release']) -_BEHAVIORCONTROLREQUEST.fields_by_name['control_release'].containing_oneof = _BEHAVIORCONTROLREQUEST.oneofs_by_name['request_type'] -_BEHAVIORCONTROLREQUEST.oneofs_by_name['request_type'].fields.append( - _BEHAVIORCONTROLREQUEST.fields_by_name['control_request']) -_BEHAVIORCONTROLREQUEST.fields_by_name['control_request'].containing_oneof = _BEHAVIORCONTROLREQUEST.oneofs_by_name['request_type'] -_BEHAVIORCONTROLRESPONSE.fields_by_name['control_granted_response'].message_type = _CONTROLGRANTEDRESPONSE -_BEHAVIORCONTROLRESPONSE.fields_by_name['control_lost_event'].message_type = _CONTROLLOSTRESPONSE -_BEHAVIORCONTROLRESPONSE.fields_by_name['keep_alive'].message_type = anki__vector_dot_messaging_dot_messages__pb2._KEEPALIVEPING -_BEHAVIORCONTROLRESPONSE.oneofs_by_name['response_type'].fields.append( - _BEHAVIORCONTROLRESPONSE.fields_by_name['control_granted_response']) -_BEHAVIORCONTROLRESPONSE.fields_by_name['control_granted_response'].containing_oneof = _BEHAVIORCONTROLRESPONSE.oneofs_by_name['response_type'] -_BEHAVIORCONTROLRESPONSE.oneofs_by_name['response_type'].fields.append( - _BEHAVIORCONTROLRESPONSE.fields_by_name['control_lost_event']) -_BEHAVIORCONTROLRESPONSE.fields_by_name['control_lost_event'].containing_oneof = _BEHAVIORCONTROLRESPONSE.oneofs_by_name['response_type'] -_BEHAVIORCONTROLRESPONSE.oneofs_by_name['response_type'].fields.append( - _BEHAVIORCONTROLRESPONSE.fields_by_name['keep_alive']) -_BEHAVIORCONTROLRESPONSE.fields_by_name['keep_alive'].containing_oneof = _BEHAVIORCONTROLRESPONSE.oneofs_by_name['response_type'] -DESCRIPTOR.message_types_by_name['ControlRelease'] = _CONTROLRELEASE -DESCRIPTOR.message_types_by_name['ControlRequest'] = _CONTROLREQUEST -DESCRIPTOR.message_types_by_name['BehaviorControlRequest'] = _BEHAVIORCONTROLREQUEST -DESCRIPTOR.message_types_by_name['ControlGrantedResponse'] = _CONTROLGRANTEDRESPONSE -DESCRIPTOR.message_types_by_name['ControlLostResponse'] = _CONTROLLOSTRESPONSE -DESCRIPTOR.message_types_by_name['BehaviorControlResponse'] = _BEHAVIORCONTROLRESPONSE -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -ControlRelease = _reflection.GeneratedProtocolMessageType('ControlRelease', (_message.Message,), dict( - DESCRIPTOR = _CONTROLRELEASE, - __module__ = 'anki_vector.messaging.behavior_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ControlRelease) - )) -_sym_db.RegisterMessage(ControlRelease) - -ControlRequest = _reflection.GeneratedProtocolMessageType('ControlRequest', (_message.Message,), dict( - DESCRIPTOR = _CONTROLREQUEST, - __module__ = 'anki_vector.messaging.behavior_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ControlRequest) - )) -_sym_db.RegisterMessage(ControlRequest) - -BehaviorControlRequest = _reflection.GeneratedProtocolMessageType('BehaviorControlRequest', (_message.Message,), dict( - DESCRIPTOR = _BEHAVIORCONTROLREQUEST, - __module__ = 'anki_vector.messaging.behavior_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.BehaviorControlRequest) - )) -_sym_db.RegisterMessage(BehaviorControlRequest) - -ControlGrantedResponse = _reflection.GeneratedProtocolMessageType('ControlGrantedResponse', (_message.Message,), dict( - DESCRIPTOR = _CONTROLGRANTEDRESPONSE, - __module__ = 'anki_vector.messaging.behavior_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ControlGrantedResponse) - )) -_sym_db.RegisterMessage(ControlGrantedResponse) - -ControlLostResponse = _reflection.GeneratedProtocolMessageType('ControlLostResponse', (_message.Message,), dict( - DESCRIPTOR = _CONTROLLOSTRESPONSE, - __module__ = 'anki_vector.messaging.behavior_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ControlLostResponse) - )) -_sym_db.RegisterMessage(ControlLostResponse) - -BehaviorControlResponse = _reflection.GeneratedProtocolMessageType('BehaviorControlResponse', (_message.Message,), dict( - DESCRIPTOR = _BEHAVIORCONTROLRESPONSE, - __module__ = 'anki_vector.messaging.behavior_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.BehaviorControlResponse) - )) -_sym_db.RegisterMessage(BehaviorControlResponse) - - -# @@protoc_insertion_point(module_scope) diff --git a/anki_vector/messaging/behavior_pb2_grpc.py b/anki_vector/messaging/behavior_pb2_grpc.py deleted file mode 100644 index a894352..0000000 --- a/anki_vector/messaging/behavior_pb2_grpc.py +++ /dev/null @@ -1,3 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - diff --git a/anki_vector/messaging/client.py b/anki_vector/messaging/client.py deleted file mode 100644 index dc39d52..0000000 --- a/anki_vector/messaging/client.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# pylint: skip-file - -""" -Protobuf messages exposed to the Vector Python SDK. -""" -import sys -import inspect - -from .alexa_pb2_grpc import * -from .behavior_pb2_grpc import * -from .cube_pb2_grpc import * -from .messages_pb2_grpc import * -from .nav_map_pb2_grpc import * -from .response_status_pb2_grpc import * -from .settings_pb2_grpc import * -from .shared_pb2_grpc import * -from .external_interface_pb2_grpc import * - -__all__ = [obj.__name__ for _, obj in inspect.getmembers(sys.modules[__name__]) if inspect.isclass(obj)] diff --git a/anki_vector/messaging/cube.proto b/anki_vector/messaging/cube.proto deleted file mode 100644 index 7fced85..0000000 --- a/anki_vector/messaging/cube.proto +++ /dev/null @@ -1,366 +0,0 @@ -// Copyright (c) 2018 Anki, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License in the file LICENSE.txt or at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// External interface for robot <-> app and robot <-> sdk communication - -syntax = "proto3"; - -package Anki.Vector.external_interface; - -import "anki_vector/messaging/messages.proto"; -import "anki_vector/messaging/response_status.proto"; - -// Attempt to connect to a cube. If a cube is currently connected, -// this will do nothing. -message ConnectCubeRequest { -} - -message ConnectCubeResponse { - ResponseStatus status = 1; - bool success = 2; - uint32 object_id = 3; - string factory_id = 4; -} - -message CubesAvailableRequest { -} - -message CubesAvailableResponse { - ResponseStatus status = 1; - repeated string factory_ids = 2; -} - -// Requests a disconnection from the currently connected cube. -message DisconnectCubeRequest { -} - -message DisconnectCubeResponse { - ResponseStatus status = 1; -} - -// Plays the default cube connection animation on the currently -// connected cube's lights. This is intended for app level user -// surfacing of cube connectivity, not for sdk cube light control. -message FlashCubeLightsRequest { -} - -message FlashCubeLightsResponse { - ResponseStatus status = 1; -} - -// Forget the robot's preferred cube. This will cause the robot to -// connect to the cube with the highest RSSI (signal strength) next -// time a connection is requested. Saves this preference to disk. -// The next cube that the robot connects to will become its -// preferred cube. -message ForgetPreferredCubeRequest { -} - -message ForgetPreferredCubeResponse { - ResponseStatus status = 1; -} - -// Set the robot's preferred cube and save it to disk. The robot -// will always attempt to connect to this cube if it is available. -// This is only used in simulation for now. -message SetPreferredCubeRequest { - string factory_id = 1; -} - -message SetPreferredCubeResponse { - ResponseStatus status = 1; -} - -// Sets each LED on victor's cube. Two states are specified -// designated 'on' and 'off', each with a color, duration, -// and state transition time -message SetCubeLightsRequest { - // This is a uint_8 internally. - enum MakeRelativeMode - { - UNKNOWN = 0; - OFF = 1; - BY_CORNER = 2; - BY_SIDE = 3; - } - - uint32 object_id = 1; - repeated uint32 on_color = 2; - repeated uint32 off_color = 3; - repeated uint32 on_period_ms = 4; - repeated uint32 off_period_ms = 5; - repeated uint32 transition_on_period_ms = 6; - repeated uint32 transition_off_period_ms = 7; - repeated int32 offset = 8; - float relative_to_x = 9; - float relative_to_y = 10; - bool rotate = 11; - MakeRelativeMode make_relative = 12; -} -message SetCubeLightsResponse { - ResponseStatus status = 1; -} - -enum ObjectType -{ - INVALID_OBJECT = 0; - UNKNOWN_OBJECT = 1; - - ////////////////////////////////////////////////////////////////////////// - // Light Cube (a.k.a. Active Block) - // - BLOCK_LIGHTCUBE1 = 2; - - FIRST_CUSTOM_OBJECT_TYPE = 15; - - OBJECT_TYPE_COUNT = 38; -} - -enum CustomType -{ - option allow_alias = true; - - INVALID_CUSTOM_TYPE = 0; - - CUSTOM_TYPE_00 = 1; - CUSTOM_TYPE_01 = 2; - CUSTOM_TYPE_02 = 3; - CUSTOM_TYPE_03 = 4; - CUSTOM_TYPE_04 = 5; - CUSTOM_TYPE_05 = 6; - CUSTOM_TYPE_06 = 7; - CUSTOM_TYPE_07 = 8; - CUSTOM_TYPE_08 = 9; - CUSTOM_TYPE_09 = 10; - CUSTOM_TYPE_10 = 11; - CUSTOM_TYPE_11 = 12; - CUSTOM_TYPE_12 = 13; - CUSTOM_TYPE_13 = 14; - CUSTOM_TYPE_14 = 15; - CUSTOM_TYPE_15 = 16; - CUSTOM_TYPE_16 = 17; - CUSTOM_TYPE_17 = 18; - CUSTOM_TYPE_18 = 19; - CUSTOM_TYPE_19 = 20; - - CUSTOM_TYPE_COUNT = 20; -} - -enum ObjectFamily { - option allow_alias = true; - - INVALID_FAMILY = 0; - UNKNOWN_FAMILY = 1; - BLOCK = 2; - LIGHT_CUBE = 3; - CHARGER = 4; - CUSTOM_OBJECT = 7; - - OBJECT_FAMILY_COUNT = 7; -} - -message ObjectAvailable { - string factory_id = 1; -} - -// Indicates that a cube has connected or disconnected to the robot. -// This message will be sent for any connects or disconnects regardless -// of whether it originated from us or underlying robot behavior. -message ObjectConnectionState { - uint32 object_id = 1; - string factory_id = 2; - ObjectType object_type = 3; - bool connected = 4; -} - -message ObjectMoved { - uint32 timestamp = 1; - uint32 object_id = 2; -} - -message ObjectStoppedMoving { - uint32 timestamp = 1; - uint32 object_id = 2; -} - -enum UpAxis { - INVALID_AXIS = 0; - X_NEGATIVE = 1; - X_POSITIVE = 2; - Y_NEGATIVE = 3; - Y_POSITIVE = 4; - Z_NEGATIVE = 5; - Z_POSITIVE = 6; - NUM_AXES = 7; -} - -message ObjectUpAxisChanged { - uint32 timestamp = 1; - uint32 object_id = 2; - UpAxis up_axis = 3; -} - -message ObjectTapped { - uint32 timestamp = 1; - uint32 object_id = 2; -} - -// RobotObservedObject for signaling that an object -// with specified ID/Type/Family was seen at a particular location in the image -// and the world -message RobotObservedObject { - uint32 timestamp = 1; - ObjectFamily object_family = 2; - ObjectType object_type = 3; - int32 object_id = 4; // signed to match U2G::PickAndPlaceObject which has the option to have objectID<0 - CladRect img_rect = 5; // position in image coords - PoseStruct pose = 6; - float top_face_orientation_rad = 7; // absolute orienation of top face, iff isActive==true - uint32 is_active = 8; -} - -// Indicates that a the connection subscribed through ConnectCube has -// been lost. -message CubeConnectionLost { -} - -// Constants associated with the audio feed -enum ObjectConstants { - OBJECT_CONSTANTS_NULL = 0; // error value - FIXED_CUSTOM_WALL_THICKNESS_MM = 10; // The depth of custom walls used in the engine -} - -enum CustomObjectMarker { - option allow_alias = true; - - CUSTOM_MARKER_UNKNOWN = 0; - - CUSTOM_MARKER_CIRCLES_2 = 1; - CUSTOM_MARKER_CIRCLES_3 = 2; - CUSTOM_MARKER_CIRCLES_4 = 3; - CUSTOM_MARKER_CIRCLES_5 = 4; - - CUSTOM_MARKER_DIAMONDS_2 = 5; - CUSTOM_MARKER_DIAMONDS_3 = 6; - CUSTOM_MARKER_DIAMONDS_4 = 7; - CUSTOM_MARKER_DIAMONDS_5 = 8; - - CUSTOM_MARKER_HEXAGONS_2 = 9; - CUSTOM_MARKER_HEXAGONS_3 = 10; - CUSTOM_MARKER_HEXAGONS_4 = 11; - CUSTOM_MARKER_HEXAGONS_5 = 12; - - CUSTOM_MARKER_TRIANGLES_2 = 13; - CUSTOM_MARKER_TRIANGLES_3 = 14; - CUSTOM_MARKER_TRIANGLES_4 = 15; - CUSTOM_MARKER_TRIANGLES_5 = 16; - - CUSTOM_MARKER_COUNT = 16; -} - -enum CustomObjectDeletionMode { - DELETION_MASK_UNKNOWN = 0; - DELETION_MASK_FIXED_CUSTOM_OBJECTS = 1; - DELETION_MASK_CUSTOM_MARKER_OBJECTS = 2; - DELETION_MASK_ARCHETYPES = 3; -} - -// Deletes all custom objects matching a given deletion mode. -message DeleteCustomObjectsRequest { - CustomObjectDeletionMode mode = 1; -} - -message DeleteCustomObjectsResponse { - ResponseStatus status = 1; -} - -// Creates a CustomObject at the specific pose with no markers associated with it -// Since this object has no markers with which to be observed, it will remain in the -// specified pose as an obstacle forever (or until deleted with a deletion message above) -message CreateFixedCustomObjectRequest { - PoseStruct pose = 1; - float x_size_mm = 2; - float y_size_mm = 3; - float z_size_mm = 4; -} - -message CreateFixedCustomObjectResponse { - ResponseStatus status = 1; - uint32 object_id = 2; -} - -// Defines a custom object of the given size with the given markers centered on each side -// If isUnique=true, there is guaranteed to be no more than one object of this type present in the world -message CustomBoxDefinition { - CustomObjectMarker marker_front = 1; - CustomObjectMarker marker_back = 2; - CustomObjectMarker marker_top = 3; - CustomObjectMarker marker_bottom = 4; - CustomObjectMarker marker_left = 5; - CustomObjectMarker marker_right = 6; - float x_size_mm = 7; - float y_size_mm = 8; - float z_size_mm = 9; - float marker_width_mm = 10; - float marker_height_mm = 11; -} - -// Defines a custom cube of the given size. The cube will have the same marker centered on all faces. -// If isUnique=true, there is guaranteed to be no more than one cube of this type present in the world at a time. -message CustomCubeDefinition { - CustomObjectMarker marker = 1; - float size_mm = 2; - float marker_width_mm = 3; - float marker_height_mm = 4; -} - -// Defines a custom wall of the given height and width, with the same marker centered on both sides (front and back). -// The wall's thickness is assumed to be 1cm (and thus there are no markers on its left, right, top, or bottom) -// If isUnique=true, there is guaranteed to be no more than one wall of this type present in the world at a time. -message CustomWallDefinition { - CustomObjectMarker marker = 1; - float width_mm = 2; - float height_mm = 3; - float marker_width_mm = 4; - float marker_height_mm = 5; -} - -message DefineCustomObjectRequest { - CustomType custom_type = 1; - bool is_unique = 2; - - oneof custom_object_definition { - CustomBoxDefinition custom_box = 3; - CustomCubeDefinition custom_cube = 4; - CustomWallDefinition custom_wall = 5; - } -} - -message DefineCustomObjectResponse { - ResponseStatus status = 1; - bool success = 2; -} - -message ObjectEvent { - oneof object_event_type { - ObjectAvailable object_available = 1; - ObjectConnectionState object_connection_state = 2; - ObjectMoved object_moved = 3; - ObjectStoppedMoving object_stopped_moving = 4; - ObjectUpAxisChanged object_up_axis_changed = 5; - ObjectTapped object_tapped = 6; - RobotObservedObject robot_observed_object = 7; - CubeConnectionLost cube_connection_lost = 8; - } -} diff --git a/anki_vector/messaging/cube_pb2.py b/anki_vector/messaging/cube_pb2.py deleted file mode 100644 index c50f9ac..0000000 --- a/anki_vector/messaging/cube_pb2.py +++ /dev/null @@ -1,2239 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: anki_vector/messaging/cube.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from anki_vector.messaging import messages_pb2 as anki__vector_dot_messaging_dot_messages__pb2 -from anki_vector.messaging import response_status_pb2 as anki__vector_dot_messaging_dot_response__status__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='anki_vector/messaging/cube.proto', - package='Anki.Vector.external_interface', - syntax='proto3', - serialized_pb=_b('\n anki_vector/messaging/cube.proto\x12\x1e\x41nki.Vector.external_interface\x1a$anki_vector/messaging/messages.proto\x1a+anki_vector/messaging/response_status.proto\"\x14\n\x12\x43onnectCubeRequest\"\x8d\x01\n\x13\x43onnectCubeResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\x11\n\tobject_id\x18\x03 \x01(\r\x12\x12\n\nfactory_id\x18\x04 \x01(\t\"\x17\n\x15\x43ubesAvailableRequest\"m\n\x16\x43ubesAvailableResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12\x13\n\x0b\x66\x61\x63tory_ids\x18\x02 \x03(\t\"\x17\n\x15\x44isconnectCubeRequest\"X\n\x16\x44isconnectCubeResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"\x18\n\x16\x46lashCubeLightsRequest\"Y\n\x17\x46lashCubeLightsResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"\x1c\n\x1a\x46orgetPreferredCubeRequest\"]\n\x1b\x46orgetPreferredCubeResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"-\n\x17SetPreferredCubeRequest\x12\x12\n\nfactory_id\x18\x01 \x01(\t\"Z\n\x18SetPreferredCubeResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"\xb0\x03\n\x14SetCubeLightsRequest\x12\x11\n\tobject_id\x18\x01 \x01(\r\x12\x10\n\x08on_color\x18\x02 \x03(\r\x12\x11\n\toff_color\x18\x03 \x03(\r\x12\x14\n\x0con_period_ms\x18\x04 \x03(\r\x12\x15\n\roff_period_ms\x18\x05 \x03(\r\x12\x1f\n\x17transition_on_period_ms\x18\x06 \x03(\r\x12 \n\x18transition_off_period_ms\x18\x07 \x03(\r\x12\x0e\n\x06offset\x18\x08 \x03(\x05\x12\x15\n\rrelative_to_x\x18\t \x01(\x02\x12\x15\n\rrelative_to_y\x18\n \x01(\x02\x12\x0e\n\x06rotate\x18\x0b \x01(\x08\x12\\\n\rmake_relative\x18\x0c \x01(\x0e\x32\x45.Anki.Vector.external_interface.SetCubeLightsRequest.MakeRelativeMode\"D\n\x10MakeRelativeMode\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x07\n\x03OFF\x10\x01\x12\r\n\tBY_CORNER\x10\x02\x12\x0b\n\x07\x42Y_SIDE\x10\x03\"W\n\x15SetCubeLightsResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"%\n\x0fObjectAvailable\x12\x12\n\nfactory_id\x18\x01 \x01(\t\"\x92\x01\n\x15ObjectConnectionState\x12\x11\n\tobject_id\x18\x01 \x01(\r\x12\x12\n\nfactory_id\x18\x02 \x01(\t\x12?\n\x0bobject_type\x18\x03 \x01(\x0e\x32*.Anki.Vector.external_interface.ObjectType\x12\x11\n\tconnected\x18\x04 \x01(\x08\"3\n\x0bObjectMoved\x12\x11\n\ttimestamp\x18\x01 \x01(\r\x12\x11\n\tobject_id\x18\x02 \x01(\r\";\n\x13ObjectStoppedMoving\x12\x11\n\ttimestamp\x18\x01 \x01(\r\x12\x11\n\tobject_id\x18\x02 \x01(\r\"t\n\x13ObjectUpAxisChanged\x12\x11\n\ttimestamp\x18\x01 \x01(\r\x12\x11\n\tobject_id\x18\x02 \x01(\r\x12\x37\n\x07up_axis\x18\x03 \x01(\x0e\x32&.Anki.Vector.external_interface.UpAxis\"4\n\x0cObjectTapped\x12\x11\n\ttimestamp\x18\x01 \x01(\r\x12\x11\n\tobject_id\x18\x02 \x01(\r\"\xec\x02\n\x13RobotObservedObject\x12\x11\n\ttimestamp\x18\x01 \x01(\r\x12\x43\n\robject_family\x18\x02 \x01(\x0e\x32,.Anki.Vector.external_interface.ObjectFamily\x12?\n\x0bobject_type\x18\x03 \x01(\x0e\x32*.Anki.Vector.external_interface.ObjectType\x12\x11\n\tobject_id\x18\x04 \x01(\x05\x12:\n\x08img_rect\x18\x05 \x01(\x0b\x32(.Anki.Vector.external_interface.CladRect\x12\x38\n\x04pose\x18\x06 \x01(\x0b\x32*.Anki.Vector.external_interface.PoseStruct\x12 \n\x18top_face_orientation_rad\x18\x07 \x01(\x02\x12\x11\n\tis_active\x18\x08 \x01(\r\"\x14\n\x12\x43ubeConnectionLost\"d\n\x1a\x44\x65leteCustomObjectsRequest\x12\x46\n\x04mode\x18\x01 \x01(\x0e\x32\x38.Anki.Vector.external_interface.CustomObjectDeletionMode\"]\n\x1b\x44\x65leteCustomObjectsResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"\x93\x01\n\x1e\x43reateFixedCustomObjectRequest\x12\x38\n\x04pose\x18\x01 \x01(\x0b\x32*.Anki.Vector.external_interface.PoseStruct\x12\x11\n\tx_size_mm\x18\x02 \x01(\x02\x12\x11\n\ty_size_mm\x18\x03 \x01(\x02\x12\x11\n\tz_size_mm\x18\x04 \x01(\x02\"t\n\x1f\x43reateFixedCustomObjectResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12\x11\n\tobject_id\x18\x02 \x01(\r\"\xba\x04\n\x13\x43ustomBoxDefinition\x12H\n\x0cmarker_front\x18\x01 \x01(\x0e\x32\x32.Anki.Vector.external_interface.CustomObjectMarker\x12G\n\x0bmarker_back\x18\x02 \x01(\x0e\x32\x32.Anki.Vector.external_interface.CustomObjectMarker\x12\x46\n\nmarker_top\x18\x03 \x01(\x0e\x32\x32.Anki.Vector.external_interface.CustomObjectMarker\x12I\n\rmarker_bottom\x18\x04 \x01(\x0e\x32\x32.Anki.Vector.external_interface.CustomObjectMarker\x12G\n\x0bmarker_left\x18\x05 \x01(\x0e\x32\x32.Anki.Vector.external_interface.CustomObjectMarker\x12H\n\x0cmarker_right\x18\x06 \x01(\x0e\x32\x32.Anki.Vector.external_interface.CustomObjectMarker\x12\x11\n\tx_size_mm\x18\x07 \x01(\x02\x12\x11\n\ty_size_mm\x18\x08 \x01(\x02\x12\x11\n\tz_size_mm\x18\t \x01(\x02\x12\x17\n\x0fmarker_width_mm\x18\n \x01(\x02\x12\x18\n\x10marker_height_mm\x18\x0b \x01(\x02\"\x9e\x01\n\x14\x43ustomCubeDefinition\x12\x42\n\x06marker\x18\x01 \x01(\x0e\x32\x32.Anki.Vector.external_interface.CustomObjectMarker\x12\x0f\n\x07size_mm\x18\x02 \x01(\x02\x12\x17\n\x0fmarker_width_mm\x18\x03 \x01(\x02\x12\x18\n\x10marker_height_mm\x18\x04 \x01(\x02\"\xb2\x01\n\x14\x43ustomWallDefinition\x12\x42\n\x06marker\x18\x01 \x01(\x0e\x32\x32.Anki.Vector.external_interface.CustomObjectMarker\x12\x10\n\x08width_mm\x18\x02 \x01(\x02\x12\x11\n\theight_mm\x18\x03 \x01(\x02\x12\x17\n\x0fmarker_width_mm\x18\x04 \x01(\x02\x12\x18\n\x10marker_height_mm\x18\x05 \x01(\x02\"\xf0\x02\n\x19\x44\x65\x66ineCustomObjectRequest\x12?\n\x0b\x63ustom_type\x18\x01 \x01(\x0e\x32*.Anki.Vector.external_interface.CustomType\x12\x11\n\tis_unique\x18\x02 \x01(\x08\x12I\n\ncustom_box\x18\x03 \x01(\x0b\x32\x33.Anki.Vector.external_interface.CustomBoxDefinitionH\x00\x12K\n\x0b\x63ustom_cube\x18\x04 \x01(\x0b\x32\x34.Anki.Vector.external_interface.CustomCubeDefinitionH\x00\x12K\n\x0b\x63ustom_wall\x18\x05 \x01(\x0b\x32\x34.Anki.Vector.external_interface.CustomWallDefinitionH\x00\x42\x1a\n\x18\x63ustom_object_definition\"m\n\x1a\x44\x65\x66ineCustomObjectResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12\x0f\n\x07success\x18\x02 \x01(\x08\"\xac\x05\n\x0bObjectEvent\x12K\n\x10object_available\x18\x01 \x01(\x0b\x32/.Anki.Vector.external_interface.ObjectAvailableH\x00\x12X\n\x17object_connection_state\x18\x02 \x01(\x0b\x32\x35.Anki.Vector.external_interface.ObjectConnectionStateH\x00\x12\x43\n\x0cobject_moved\x18\x03 \x01(\x0b\x32+.Anki.Vector.external_interface.ObjectMovedH\x00\x12T\n\x15object_stopped_moving\x18\x04 \x01(\x0b\x32\x33.Anki.Vector.external_interface.ObjectStoppedMovingH\x00\x12U\n\x16object_up_axis_changed\x18\x05 \x01(\x0b\x32\x33.Anki.Vector.external_interface.ObjectUpAxisChangedH\x00\x12\x45\n\robject_tapped\x18\x06 \x01(\x0b\x32,.Anki.Vector.external_interface.ObjectTappedH\x00\x12T\n\x15robot_observed_object\x18\x07 \x01(\x0b\x32\x33.Anki.Vector.external_interface.RobotObservedObjectH\x00\x12R\n\x14\x63ube_connection_lost\x18\x08 \x01(\x0b\x32\x32.Anki.Vector.external_interface.CubeConnectionLostH\x00\x42\x13\n\x11object_event_type*\x7f\n\nObjectType\x12\x12\n\x0eINVALID_OBJECT\x10\x00\x12\x12\n\x0eUNKNOWN_OBJECT\x10\x01\x12\x14\n\x10\x42LOCK_LIGHTCUBE1\x10\x02\x12\x1c\n\x18\x46IRST_CUSTOM_OBJECT_TYPE\x10\x0f\x12\x15\n\x11OBJECT_TYPE_COUNT\x10&*\xd0\x03\n\nCustomType\x12\x17\n\x13INVALID_CUSTOM_TYPE\x10\x00\x12\x12\n\x0e\x43USTOM_TYPE_00\x10\x01\x12\x12\n\x0e\x43USTOM_TYPE_01\x10\x02\x12\x12\n\x0e\x43USTOM_TYPE_02\x10\x03\x12\x12\n\x0e\x43USTOM_TYPE_03\x10\x04\x12\x12\n\x0e\x43USTOM_TYPE_04\x10\x05\x12\x12\n\x0e\x43USTOM_TYPE_05\x10\x06\x12\x12\n\x0e\x43USTOM_TYPE_06\x10\x07\x12\x12\n\x0e\x43USTOM_TYPE_07\x10\x08\x12\x12\n\x0e\x43USTOM_TYPE_08\x10\t\x12\x12\n\x0e\x43USTOM_TYPE_09\x10\n\x12\x12\n\x0e\x43USTOM_TYPE_10\x10\x0b\x12\x12\n\x0e\x43USTOM_TYPE_11\x10\x0c\x12\x12\n\x0e\x43USTOM_TYPE_12\x10\r\x12\x12\n\x0e\x43USTOM_TYPE_13\x10\x0e\x12\x12\n\x0e\x43USTOM_TYPE_14\x10\x0f\x12\x12\n\x0e\x43USTOM_TYPE_15\x10\x10\x12\x12\n\x0e\x43USTOM_TYPE_16\x10\x11\x12\x12\n\x0e\x43USTOM_TYPE_17\x10\x12\x12\x12\n\x0e\x43USTOM_TYPE_18\x10\x13\x12\x12\n\x0e\x43USTOM_TYPE_19\x10\x14\x12\x15\n\x11\x43USTOM_TYPE_COUNT\x10\x14\x1a\x02\x10\x01*\x8e\x01\n\x0cObjectFamily\x12\x12\n\x0eINVALID_FAMILY\x10\x00\x12\x12\n\x0eUNKNOWN_FAMILY\x10\x01\x12\t\n\x05\x42LOCK\x10\x02\x12\x0e\n\nLIGHT_CUBE\x10\x03\x12\x0b\n\x07\x43HARGER\x10\x04\x12\x11\n\rCUSTOM_OBJECT\x10\x07\x12\x17\n\x13OBJECT_FAMILY_COUNT\x10\x07\x1a\x02\x10\x01*\x88\x01\n\x06UpAxis\x12\x10\n\x0cINVALID_AXIS\x10\x00\x12\x0e\n\nX_NEGATIVE\x10\x01\x12\x0e\n\nX_POSITIVE\x10\x02\x12\x0e\n\nY_NEGATIVE\x10\x03\x12\x0e\n\nY_POSITIVE\x10\x04\x12\x0e\n\nZ_NEGATIVE\x10\x05\x12\x0e\n\nZ_POSITIVE\x10\x06\x12\x0c\n\x08NUM_AXES\x10\x07*P\n\x0fObjectConstants\x12\x19\n\x15OBJECT_CONSTANTS_NULL\x10\x00\x12\"\n\x1e\x46IXED_CUSTOM_WALL_THICKNESS_MM\x10\n*\xac\x04\n\x12\x43ustomObjectMarker\x12\x19\n\x15\x43USTOM_MARKER_UNKNOWN\x10\x00\x12\x1b\n\x17\x43USTOM_MARKER_CIRCLES_2\x10\x01\x12\x1b\n\x17\x43USTOM_MARKER_CIRCLES_3\x10\x02\x12\x1b\n\x17\x43USTOM_MARKER_CIRCLES_4\x10\x03\x12\x1b\n\x17\x43USTOM_MARKER_CIRCLES_5\x10\x04\x12\x1c\n\x18\x43USTOM_MARKER_DIAMONDS_2\x10\x05\x12\x1c\n\x18\x43USTOM_MARKER_DIAMONDS_3\x10\x06\x12\x1c\n\x18\x43USTOM_MARKER_DIAMONDS_4\x10\x07\x12\x1c\n\x18\x43USTOM_MARKER_DIAMONDS_5\x10\x08\x12\x1c\n\x18\x43USTOM_MARKER_HEXAGONS_2\x10\t\x12\x1c\n\x18\x43USTOM_MARKER_HEXAGONS_3\x10\n\x12\x1c\n\x18\x43USTOM_MARKER_HEXAGONS_4\x10\x0b\x12\x1c\n\x18\x43USTOM_MARKER_HEXAGONS_5\x10\x0c\x12\x1d\n\x19\x43USTOM_MARKER_TRIANGLES_2\x10\r\x12\x1d\n\x19\x43USTOM_MARKER_TRIANGLES_3\x10\x0e\x12\x1d\n\x19\x43USTOM_MARKER_TRIANGLES_4\x10\x0f\x12\x1d\n\x19\x43USTOM_MARKER_TRIANGLES_5\x10\x10\x12\x17\n\x13\x43USTOM_MARKER_COUNT\x10\x10\x1a\x02\x10\x01*\xa4\x01\n\x18\x43ustomObjectDeletionMode\x12\x19\n\x15\x44\x45LETION_MASK_UNKNOWN\x10\x00\x12&\n\"DELETION_MASK_FIXED_CUSTOM_OBJECTS\x10\x01\x12\'\n#DELETION_MASK_CUSTOM_MARKER_OBJECTS\x10\x02\x12\x1c\n\x18\x44\x45LETION_MASK_ARCHETYPES\x10\x03\x62\x06proto3') - , - dependencies=[anki__vector_dot_messaging_dot_messages__pb2.DESCRIPTOR,anki__vector_dot_messaging_dot_response__status__pb2.DESCRIPTOR,]) - -_OBJECTTYPE = _descriptor.EnumDescriptor( - name='ObjectType', - full_name='Anki.Vector.external_interface.ObjectType', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='INVALID_OBJECT', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='UNKNOWN_OBJECT', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='BLOCK_LIGHTCUBE1', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='FIRST_CUSTOM_OBJECT_TYPE', index=3, number=15, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='OBJECT_TYPE_COUNT', index=4, number=38, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=4885, - serialized_end=5012, -) -_sym_db.RegisterEnumDescriptor(_OBJECTTYPE) - -ObjectType = enum_type_wrapper.EnumTypeWrapper(_OBJECTTYPE) -_CUSTOMTYPE = _descriptor.EnumDescriptor( - name='CustomType', - full_name='Anki.Vector.external_interface.CustomType', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='INVALID_CUSTOM_TYPE', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_00', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_01', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_02', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_03', index=4, number=4, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_04', index=5, number=5, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_05', index=6, number=6, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_06', index=7, number=7, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_07', index=8, number=8, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_08', index=9, number=9, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_09', index=10, number=10, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_10', index=11, number=11, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_11', index=12, number=12, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_12', index=13, number=13, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_13', index=14, number=14, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_14', index=15, number=15, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_15', index=16, number=16, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_16', index=17, number=17, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_17', index=18, number=18, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_18', index=19, number=19, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_19', index=20, number=20, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_TYPE_COUNT', index=21, number=20, - options=None, - type=None), - ], - containing_type=None, - options=_descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\020\001')), - serialized_start=5015, - serialized_end=5479, -) -_sym_db.RegisterEnumDescriptor(_CUSTOMTYPE) - -CustomType = enum_type_wrapper.EnumTypeWrapper(_CUSTOMTYPE) -_OBJECTFAMILY = _descriptor.EnumDescriptor( - name='ObjectFamily', - full_name='Anki.Vector.external_interface.ObjectFamily', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='INVALID_FAMILY', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='UNKNOWN_FAMILY', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='BLOCK', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='LIGHT_CUBE', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CHARGER', index=4, number=4, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_OBJECT', index=5, number=7, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='OBJECT_FAMILY_COUNT', index=6, number=7, - options=None, - type=None), - ], - containing_type=None, - options=_descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\020\001')), - serialized_start=5482, - serialized_end=5624, -) -_sym_db.RegisterEnumDescriptor(_OBJECTFAMILY) - -ObjectFamily = enum_type_wrapper.EnumTypeWrapper(_OBJECTFAMILY) -_UPAXIS = _descriptor.EnumDescriptor( - name='UpAxis', - full_name='Anki.Vector.external_interface.UpAxis', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='INVALID_AXIS', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='X_NEGATIVE', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='X_POSITIVE', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='Y_NEGATIVE', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='Y_POSITIVE', index=4, number=4, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='Z_NEGATIVE', index=5, number=5, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='Z_POSITIVE', index=6, number=6, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NUM_AXES', index=7, number=7, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=5627, - serialized_end=5763, -) -_sym_db.RegisterEnumDescriptor(_UPAXIS) - -UpAxis = enum_type_wrapper.EnumTypeWrapper(_UPAXIS) -_OBJECTCONSTANTS = _descriptor.EnumDescriptor( - name='ObjectConstants', - full_name='Anki.Vector.external_interface.ObjectConstants', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='OBJECT_CONSTANTS_NULL', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='FIXED_CUSTOM_WALL_THICKNESS_MM', index=1, number=10, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=5765, - serialized_end=5845, -) -_sym_db.RegisterEnumDescriptor(_OBJECTCONSTANTS) - -ObjectConstants = enum_type_wrapper.EnumTypeWrapper(_OBJECTCONSTANTS) -_CUSTOMOBJECTMARKER = _descriptor.EnumDescriptor( - name='CustomObjectMarker', - full_name='Anki.Vector.external_interface.CustomObjectMarker', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_UNKNOWN', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_CIRCLES_2', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_CIRCLES_3', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_CIRCLES_4', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_CIRCLES_5', index=4, number=4, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_DIAMONDS_2', index=5, number=5, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_DIAMONDS_3', index=6, number=6, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_DIAMONDS_4', index=7, number=7, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_DIAMONDS_5', index=8, number=8, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_HEXAGONS_2', index=9, number=9, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_HEXAGONS_3', index=10, number=10, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_HEXAGONS_4', index=11, number=11, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_HEXAGONS_5', index=12, number=12, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_TRIANGLES_2', index=13, number=13, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_TRIANGLES_3', index=14, number=14, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_TRIANGLES_4', index=15, number=15, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_TRIANGLES_5', index=16, number=16, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CUSTOM_MARKER_COUNT', index=17, number=16, - options=None, - type=None), - ], - containing_type=None, - options=_descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\020\001')), - serialized_start=5848, - serialized_end=6404, -) -_sym_db.RegisterEnumDescriptor(_CUSTOMOBJECTMARKER) - -CustomObjectMarker = enum_type_wrapper.EnumTypeWrapper(_CUSTOMOBJECTMARKER) -_CUSTOMOBJECTDELETIONMODE = _descriptor.EnumDescriptor( - name='CustomObjectDeletionMode', - full_name='Anki.Vector.external_interface.CustomObjectDeletionMode', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='DELETION_MASK_UNKNOWN', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='DELETION_MASK_FIXED_CUSTOM_OBJECTS', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='DELETION_MASK_CUSTOM_MARKER_OBJECTS', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='DELETION_MASK_ARCHETYPES', index=3, number=3, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=6407, - serialized_end=6571, -) -_sym_db.RegisterEnumDescriptor(_CUSTOMOBJECTDELETIONMODE) - -CustomObjectDeletionMode = enum_type_wrapper.EnumTypeWrapper(_CUSTOMOBJECTDELETIONMODE) -INVALID_OBJECT = 0 -UNKNOWN_OBJECT = 1 -BLOCK_LIGHTCUBE1 = 2 -FIRST_CUSTOM_OBJECT_TYPE = 15 -OBJECT_TYPE_COUNT = 38 -INVALID_CUSTOM_TYPE = 0 -CUSTOM_TYPE_00 = 1 -CUSTOM_TYPE_01 = 2 -CUSTOM_TYPE_02 = 3 -CUSTOM_TYPE_03 = 4 -CUSTOM_TYPE_04 = 5 -CUSTOM_TYPE_05 = 6 -CUSTOM_TYPE_06 = 7 -CUSTOM_TYPE_07 = 8 -CUSTOM_TYPE_08 = 9 -CUSTOM_TYPE_09 = 10 -CUSTOM_TYPE_10 = 11 -CUSTOM_TYPE_11 = 12 -CUSTOM_TYPE_12 = 13 -CUSTOM_TYPE_13 = 14 -CUSTOM_TYPE_14 = 15 -CUSTOM_TYPE_15 = 16 -CUSTOM_TYPE_16 = 17 -CUSTOM_TYPE_17 = 18 -CUSTOM_TYPE_18 = 19 -CUSTOM_TYPE_19 = 20 -CUSTOM_TYPE_COUNT = 20 -INVALID_FAMILY = 0 -UNKNOWN_FAMILY = 1 -BLOCK = 2 -LIGHT_CUBE = 3 -CHARGER = 4 -CUSTOM_OBJECT = 7 -OBJECT_FAMILY_COUNT = 7 -INVALID_AXIS = 0 -X_NEGATIVE = 1 -X_POSITIVE = 2 -Y_NEGATIVE = 3 -Y_POSITIVE = 4 -Z_NEGATIVE = 5 -Z_POSITIVE = 6 -NUM_AXES = 7 -OBJECT_CONSTANTS_NULL = 0 -FIXED_CUSTOM_WALL_THICKNESS_MM = 10 -CUSTOM_MARKER_UNKNOWN = 0 -CUSTOM_MARKER_CIRCLES_2 = 1 -CUSTOM_MARKER_CIRCLES_3 = 2 -CUSTOM_MARKER_CIRCLES_4 = 3 -CUSTOM_MARKER_CIRCLES_5 = 4 -CUSTOM_MARKER_DIAMONDS_2 = 5 -CUSTOM_MARKER_DIAMONDS_3 = 6 -CUSTOM_MARKER_DIAMONDS_4 = 7 -CUSTOM_MARKER_DIAMONDS_5 = 8 -CUSTOM_MARKER_HEXAGONS_2 = 9 -CUSTOM_MARKER_HEXAGONS_3 = 10 -CUSTOM_MARKER_HEXAGONS_4 = 11 -CUSTOM_MARKER_HEXAGONS_5 = 12 -CUSTOM_MARKER_TRIANGLES_2 = 13 -CUSTOM_MARKER_TRIANGLES_3 = 14 -CUSTOM_MARKER_TRIANGLES_4 = 15 -CUSTOM_MARKER_TRIANGLES_5 = 16 -CUSTOM_MARKER_COUNT = 16 -DELETION_MASK_UNKNOWN = 0 -DELETION_MASK_FIXED_CUSTOM_OBJECTS = 1 -DELETION_MASK_CUSTOM_MARKER_OBJECTS = 2 -DELETION_MASK_ARCHETYPES = 3 - - -_SETCUBELIGHTSREQUEST_MAKERELATIVEMODE = _descriptor.EnumDescriptor( - name='MakeRelativeMode', - full_name='Anki.Vector.external_interface.SetCubeLightsRequest.MakeRelativeMode', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='UNKNOWN', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='OFF', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='BY_CORNER', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='BY_SIDE', index=3, number=3, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=1314, - serialized_end=1382, -) -_sym_db.RegisterEnumDescriptor(_SETCUBELIGHTSREQUEST_MAKERELATIVEMODE) - - -_CONNECTCUBEREQUEST = _descriptor.Descriptor( - name='ConnectCubeRequest', - full_name='Anki.Vector.external_interface.ConnectCubeRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=151, - serialized_end=171, -) - - -_CONNECTCUBERESPONSE = _descriptor.Descriptor( - name='ConnectCubeResponse', - full_name='Anki.Vector.external_interface.ConnectCubeResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.ConnectCubeResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='success', full_name='Anki.Vector.external_interface.ConnectCubeResponse.success', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_id', full_name='Anki.Vector.external_interface.ConnectCubeResponse.object_id', index=2, - number=3, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='factory_id', full_name='Anki.Vector.external_interface.ConnectCubeResponse.factory_id', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=174, - serialized_end=315, -) - - -_CUBESAVAILABLEREQUEST = _descriptor.Descriptor( - name='CubesAvailableRequest', - full_name='Anki.Vector.external_interface.CubesAvailableRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=317, - serialized_end=340, -) - - -_CUBESAVAILABLERESPONSE = _descriptor.Descriptor( - name='CubesAvailableResponse', - full_name='Anki.Vector.external_interface.CubesAvailableResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.CubesAvailableResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='factory_ids', full_name='Anki.Vector.external_interface.CubesAvailableResponse.factory_ids', index=1, - number=2, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=342, - serialized_end=451, -) - - -_DISCONNECTCUBEREQUEST = _descriptor.Descriptor( - name='DisconnectCubeRequest', - full_name='Anki.Vector.external_interface.DisconnectCubeRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=453, - serialized_end=476, -) - - -_DISCONNECTCUBERESPONSE = _descriptor.Descriptor( - name='DisconnectCubeResponse', - full_name='Anki.Vector.external_interface.DisconnectCubeResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.DisconnectCubeResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=478, - serialized_end=566, -) - - -_FLASHCUBELIGHTSREQUEST = _descriptor.Descriptor( - name='FlashCubeLightsRequest', - full_name='Anki.Vector.external_interface.FlashCubeLightsRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=568, - serialized_end=592, -) - - -_FLASHCUBELIGHTSRESPONSE = _descriptor.Descriptor( - name='FlashCubeLightsResponse', - full_name='Anki.Vector.external_interface.FlashCubeLightsResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.FlashCubeLightsResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=594, - serialized_end=683, -) - - -_FORGETPREFERREDCUBEREQUEST = _descriptor.Descriptor( - name='ForgetPreferredCubeRequest', - full_name='Anki.Vector.external_interface.ForgetPreferredCubeRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=685, - serialized_end=713, -) - - -_FORGETPREFERREDCUBERESPONSE = _descriptor.Descriptor( - name='ForgetPreferredCubeResponse', - full_name='Anki.Vector.external_interface.ForgetPreferredCubeResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.ForgetPreferredCubeResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=715, - serialized_end=808, -) - - -_SETPREFERREDCUBEREQUEST = _descriptor.Descriptor( - name='SetPreferredCubeRequest', - full_name='Anki.Vector.external_interface.SetPreferredCubeRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='factory_id', full_name='Anki.Vector.external_interface.SetPreferredCubeRequest.factory_id', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=810, - serialized_end=855, -) - - -_SETPREFERREDCUBERESPONSE = _descriptor.Descriptor( - name='SetPreferredCubeResponse', - full_name='Anki.Vector.external_interface.SetPreferredCubeResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.SetPreferredCubeResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=857, - serialized_end=947, -) - - -_SETCUBELIGHTSREQUEST = _descriptor.Descriptor( - name='SetCubeLightsRequest', - full_name='Anki.Vector.external_interface.SetCubeLightsRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='object_id', full_name='Anki.Vector.external_interface.SetCubeLightsRequest.object_id', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='on_color', full_name='Anki.Vector.external_interface.SetCubeLightsRequest.on_color', index=1, - number=2, type=13, cpp_type=3, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='off_color', full_name='Anki.Vector.external_interface.SetCubeLightsRequest.off_color', index=2, - number=3, type=13, cpp_type=3, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='on_period_ms', full_name='Anki.Vector.external_interface.SetCubeLightsRequest.on_period_ms', index=3, - number=4, type=13, cpp_type=3, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='off_period_ms', full_name='Anki.Vector.external_interface.SetCubeLightsRequest.off_period_ms', index=4, - number=5, type=13, cpp_type=3, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='transition_on_period_ms', full_name='Anki.Vector.external_interface.SetCubeLightsRequest.transition_on_period_ms', index=5, - number=6, type=13, cpp_type=3, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='transition_off_period_ms', full_name='Anki.Vector.external_interface.SetCubeLightsRequest.transition_off_period_ms', index=6, - number=7, type=13, cpp_type=3, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='offset', full_name='Anki.Vector.external_interface.SetCubeLightsRequest.offset', index=7, - number=8, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='relative_to_x', full_name='Anki.Vector.external_interface.SetCubeLightsRequest.relative_to_x', index=8, - number=9, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='relative_to_y', full_name='Anki.Vector.external_interface.SetCubeLightsRequest.relative_to_y', index=9, - number=10, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='rotate', full_name='Anki.Vector.external_interface.SetCubeLightsRequest.rotate', index=10, - number=11, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='make_relative', full_name='Anki.Vector.external_interface.SetCubeLightsRequest.make_relative', index=11, - number=12, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _SETCUBELIGHTSREQUEST_MAKERELATIVEMODE, - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=950, - serialized_end=1382, -) - - -_SETCUBELIGHTSRESPONSE = _descriptor.Descriptor( - name='SetCubeLightsResponse', - full_name='Anki.Vector.external_interface.SetCubeLightsResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.SetCubeLightsResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1384, - serialized_end=1471, -) - - -_OBJECTAVAILABLE = _descriptor.Descriptor( - name='ObjectAvailable', - full_name='Anki.Vector.external_interface.ObjectAvailable', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='factory_id', full_name='Anki.Vector.external_interface.ObjectAvailable.factory_id', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1473, - serialized_end=1510, -) - - -_OBJECTCONNECTIONSTATE = _descriptor.Descriptor( - name='ObjectConnectionState', - full_name='Anki.Vector.external_interface.ObjectConnectionState', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='object_id', full_name='Anki.Vector.external_interface.ObjectConnectionState.object_id', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='factory_id', full_name='Anki.Vector.external_interface.ObjectConnectionState.factory_id', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_type', full_name='Anki.Vector.external_interface.ObjectConnectionState.object_type', index=2, - number=3, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='connected', full_name='Anki.Vector.external_interface.ObjectConnectionState.connected', index=3, - number=4, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1513, - serialized_end=1659, -) - - -_OBJECTMOVED = _descriptor.Descriptor( - name='ObjectMoved', - full_name='Anki.Vector.external_interface.ObjectMoved', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='timestamp', full_name='Anki.Vector.external_interface.ObjectMoved.timestamp', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_id', full_name='Anki.Vector.external_interface.ObjectMoved.object_id', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1661, - serialized_end=1712, -) - - -_OBJECTSTOPPEDMOVING = _descriptor.Descriptor( - name='ObjectStoppedMoving', - full_name='Anki.Vector.external_interface.ObjectStoppedMoving', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='timestamp', full_name='Anki.Vector.external_interface.ObjectStoppedMoving.timestamp', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_id', full_name='Anki.Vector.external_interface.ObjectStoppedMoving.object_id', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1714, - serialized_end=1773, -) - - -_OBJECTUPAXISCHANGED = _descriptor.Descriptor( - name='ObjectUpAxisChanged', - full_name='Anki.Vector.external_interface.ObjectUpAxisChanged', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='timestamp', full_name='Anki.Vector.external_interface.ObjectUpAxisChanged.timestamp', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_id', full_name='Anki.Vector.external_interface.ObjectUpAxisChanged.object_id', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='up_axis', full_name='Anki.Vector.external_interface.ObjectUpAxisChanged.up_axis', index=2, - number=3, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1775, - serialized_end=1891, -) - - -_OBJECTTAPPED = _descriptor.Descriptor( - name='ObjectTapped', - full_name='Anki.Vector.external_interface.ObjectTapped', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='timestamp', full_name='Anki.Vector.external_interface.ObjectTapped.timestamp', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_id', full_name='Anki.Vector.external_interface.ObjectTapped.object_id', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1893, - serialized_end=1945, -) - - -_ROBOTOBSERVEDOBJECT = _descriptor.Descriptor( - name='RobotObservedObject', - full_name='Anki.Vector.external_interface.RobotObservedObject', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='timestamp', full_name='Anki.Vector.external_interface.RobotObservedObject.timestamp', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_family', full_name='Anki.Vector.external_interface.RobotObservedObject.object_family', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_type', full_name='Anki.Vector.external_interface.RobotObservedObject.object_type', index=2, - number=3, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_id', full_name='Anki.Vector.external_interface.RobotObservedObject.object_id', index=3, - number=4, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='img_rect', full_name='Anki.Vector.external_interface.RobotObservedObject.img_rect', index=4, - number=5, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='pose', full_name='Anki.Vector.external_interface.RobotObservedObject.pose', index=5, - number=6, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='top_face_orientation_rad', full_name='Anki.Vector.external_interface.RobotObservedObject.top_face_orientation_rad', index=6, - number=7, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='is_active', full_name='Anki.Vector.external_interface.RobotObservedObject.is_active', index=7, - number=8, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1948, - serialized_end=2312, -) - - -_CUBECONNECTIONLOST = _descriptor.Descriptor( - name='CubeConnectionLost', - full_name='Anki.Vector.external_interface.CubeConnectionLost', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2314, - serialized_end=2334, -) - - -_DELETECUSTOMOBJECTSREQUEST = _descriptor.Descriptor( - name='DeleteCustomObjectsRequest', - full_name='Anki.Vector.external_interface.DeleteCustomObjectsRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='mode', full_name='Anki.Vector.external_interface.DeleteCustomObjectsRequest.mode', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2336, - serialized_end=2436, -) - - -_DELETECUSTOMOBJECTSRESPONSE = _descriptor.Descriptor( - name='DeleteCustomObjectsResponse', - full_name='Anki.Vector.external_interface.DeleteCustomObjectsResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.DeleteCustomObjectsResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2438, - serialized_end=2531, -) - - -_CREATEFIXEDCUSTOMOBJECTREQUEST = _descriptor.Descriptor( - name='CreateFixedCustomObjectRequest', - full_name='Anki.Vector.external_interface.CreateFixedCustomObjectRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='pose', full_name='Anki.Vector.external_interface.CreateFixedCustomObjectRequest.pose', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='x_size_mm', full_name='Anki.Vector.external_interface.CreateFixedCustomObjectRequest.x_size_mm', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='y_size_mm', full_name='Anki.Vector.external_interface.CreateFixedCustomObjectRequest.y_size_mm', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='z_size_mm', full_name='Anki.Vector.external_interface.CreateFixedCustomObjectRequest.z_size_mm', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2534, - serialized_end=2681, -) - - -_CREATEFIXEDCUSTOMOBJECTRESPONSE = _descriptor.Descriptor( - name='CreateFixedCustomObjectResponse', - full_name='Anki.Vector.external_interface.CreateFixedCustomObjectResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.CreateFixedCustomObjectResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_id', full_name='Anki.Vector.external_interface.CreateFixedCustomObjectResponse.object_id', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2683, - serialized_end=2799, -) - - -_CUSTOMBOXDEFINITION = _descriptor.Descriptor( - name='CustomBoxDefinition', - full_name='Anki.Vector.external_interface.CustomBoxDefinition', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='marker_front', full_name='Anki.Vector.external_interface.CustomBoxDefinition.marker_front', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='marker_back', full_name='Anki.Vector.external_interface.CustomBoxDefinition.marker_back', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='marker_top', full_name='Anki.Vector.external_interface.CustomBoxDefinition.marker_top', index=2, - number=3, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='marker_bottom', full_name='Anki.Vector.external_interface.CustomBoxDefinition.marker_bottom', index=3, - number=4, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='marker_left', full_name='Anki.Vector.external_interface.CustomBoxDefinition.marker_left', index=4, - number=5, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='marker_right', full_name='Anki.Vector.external_interface.CustomBoxDefinition.marker_right', index=5, - number=6, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='x_size_mm', full_name='Anki.Vector.external_interface.CustomBoxDefinition.x_size_mm', index=6, - number=7, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='y_size_mm', full_name='Anki.Vector.external_interface.CustomBoxDefinition.y_size_mm', index=7, - number=8, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='z_size_mm', full_name='Anki.Vector.external_interface.CustomBoxDefinition.z_size_mm', index=8, - number=9, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='marker_width_mm', full_name='Anki.Vector.external_interface.CustomBoxDefinition.marker_width_mm', index=9, - number=10, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='marker_height_mm', full_name='Anki.Vector.external_interface.CustomBoxDefinition.marker_height_mm', index=10, - number=11, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2802, - serialized_end=3372, -) - - -_CUSTOMCUBEDEFINITION = _descriptor.Descriptor( - name='CustomCubeDefinition', - full_name='Anki.Vector.external_interface.CustomCubeDefinition', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='marker', full_name='Anki.Vector.external_interface.CustomCubeDefinition.marker', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='size_mm', full_name='Anki.Vector.external_interface.CustomCubeDefinition.size_mm', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='marker_width_mm', full_name='Anki.Vector.external_interface.CustomCubeDefinition.marker_width_mm', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='marker_height_mm', full_name='Anki.Vector.external_interface.CustomCubeDefinition.marker_height_mm', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3375, - serialized_end=3533, -) - - -_CUSTOMWALLDEFINITION = _descriptor.Descriptor( - name='CustomWallDefinition', - full_name='Anki.Vector.external_interface.CustomWallDefinition', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='marker', full_name='Anki.Vector.external_interface.CustomWallDefinition.marker', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='width_mm', full_name='Anki.Vector.external_interface.CustomWallDefinition.width_mm', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='height_mm', full_name='Anki.Vector.external_interface.CustomWallDefinition.height_mm', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='marker_width_mm', full_name='Anki.Vector.external_interface.CustomWallDefinition.marker_width_mm', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='marker_height_mm', full_name='Anki.Vector.external_interface.CustomWallDefinition.marker_height_mm', index=4, - number=5, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3536, - serialized_end=3714, -) - - -_DEFINECUSTOMOBJECTREQUEST = _descriptor.Descriptor( - name='DefineCustomObjectRequest', - full_name='Anki.Vector.external_interface.DefineCustomObjectRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='custom_type', full_name='Anki.Vector.external_interface.DefineCustomObjectRequest.custom_type', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='is_unique', full_name='Anki.Vector.external_interface.DefineCustomObjectRequest.is_unique', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='custom_box', full_name='Anki.Vector.external_interface.DefineCustomObjectRequest.custom_box', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='custom_cube', full_name='Anki.Vector.external_interface.DefineCustomObjectRequest.custom_cube', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='custom_wall', full_name='Anki.Vector.external_interface.DefineCustomObjectRequest.custom_wall', index=4, - number=5, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='custom_object_definition', full_name='Anki.Vector.external_interface.DefineCustomObjectRequest.custom_object_definition', - index=0, containing_type=None, fields=[]), - ], - serialized_start=3717, - serialized_end=4085, -) - - -_DEFINECUSTOMOBJECTRESPONSE = _descriptor.Descriptor( - name='DefineCustomObjectResponse', - full_name='Anki.Vector.external_interface.DefineCustomObjectResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.DefineCustomObjectResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='success', full_name='Anki.Vector.external_interface.DefineCustomObjectResponse.success', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4087, - serialized_end=4196, -) - - -_OBJECTEVENT = _descriptor.Descriptor( - name='ObjectEvent', - full_name='Anki.Vector.external_interface.ObjectEvent', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='object_available', full_name='Anki.Vector.external_interface.ObjectEvent.object_available', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_connection_state', full_name='Anki.Vector.external_interface.ObjectEvent.object_connection_state', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_moved', full_name='Anki.Vector.external_interface.ObjectEvent.object_moved', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_stopped_moving', full_name='Anki.Vector.external_interface.ObjectEvent.object_stopped_moving', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_up_axis_changed', full_name='Anki.Vector.external_interface.ObjectEvent.object_up_axis_changed', index=4, - number=5, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_tapped', full_name='Anki.Vector.external_interface.ObjectEvent.object_tapped', index=5, - number=6, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='robot_observed_object', full_name='Anki.Vector.external_interface.ObjectEvent.robot_observed_object', index=6, - number=7, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='cube_connection_lost', full_name='Anki.Vector.external_interface.ObjectEvent.cube_connection_lost', index=7, - number=8, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='object_event_type', full_name='Anki.Vector.external_interface.ObjectEvent.object_event_type', - index=0, containing_type=None, fields=[]), - ], - serialized_start=4199, - serialized_end=4883, -) - -_CONNECTCUBERESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_CUBESAVAILABLERESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_DISCONNECTCUBERESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_FLASHCUBELIGHTSRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_FORGETPREFERREDCUBERESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_SETPREFERREDCUBERESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_SETCUBELIGHTSREQUEST.fields_by_name['make_relative'].enum_type = _SETCUBELIGHTSREQUEST_MAKERELATIVEMODE -_SETCUBELIGHTSREQUEST_MAKERELATIVEMODE.containing_type = _SETCUBELIGHTSREQUEST -_SETCUBELIGHTSRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_OBJECTCONNECTIONSTATE.fields_by_name['object_type'].enum_type = _OBJECTTYPE -_OBJECTUPAXISCHANGED.fields_by_name['up_axis'].enum_type = _UPAXIS -_ROBOTOBSERVEDOBJECT.fields_by_name['object_family'].enum_type = _OBJECTFAMILY -_ROBOTOBSERVEDOBJECT.fields_by_name['object_type'].enum_type = _OBJECTTYPE -_ROBOTOBSERVEDOBJECT.fields_by_name['img_rect'].message_type = anki__vector_dot_messaging_dot_messages__pb2._CLADRECT -_ROBOTOBSERVEDOBJECT.fields_by_name['pose'].message_type = anki__vector_dot_messaging_dot_messages__pb2._POSESTRUCT -_DELETECUSTOMOBJECTSREQUEST.fields_by_name['mode'].enum_type = _CUSTOMOBJECTDELETIONMODE -_DELETECUSTOMOBJECTSRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_CREATEFIXEDCUSTOMOBJECTREQUEST.fields_by_name['pose'].message_type = anki__vector_dot_messaging_dot_messages__pb2._POSESTRUCT -_CREATEFIXEDCUSTOMOBJECTRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_CUSTOMBOXDEFINITION.fields_by_name['marker_front'].enum_type = _CUSTOMOBJECTMARKER -_CUSTOMBOXDEFINITION.fields_by_name['marker_back'].enum_type = _CUSTOMOBJECTMARKER -_CUSTOMBOXDEFINITION.fields_by_name['marker_top'].enum_type = _CUSTOMOBJECTMARKER -_CUSTOMBOXDEFINITION.fields_by_name['marker_bottom'].enum_type = _CUSTOMOBJECTMARKER -_CUSTOMBOXDEFINITION.fields_by_name['marker_left'].enum_type = _CUSTOMOBJECTMARKER -_CUSTOMBOXDEFINITION.fields_by_name['marker_right'].enum_type = _CUSTOMOBJECTMARKER -_CUSTOMCUBEDEFINITION.fields_by_name['marker'].enum_type = _CUSTOMOBJECTMARKER -_CUSTOMWALLDEFINITION.fields_by_name['marker'].enum_type = _CUSTOMOBJECTMARKER -_DEFINECUSTOMOBJECTREQUEST.fields_by_name['custom_type'].enum_type = _CUSTOMTYPE -_DEFINECUSTOMOBJECTREQUEST.fields_by_name['custom_box'].message_type = _CUSTOMBOXDEFINITION -_DEFINECUSTOMOBJECTREQUEST.fields_by_name['custom_cube'].message_type = _CUSTOMCUBEDEFINITION -_DEFINECUSTOMOBJECTREQUEST.fields_by_name['custom_wall'].message_type = _CUSTOMWALLDEFINITION -_DEFINECUSTOMOBJECTREQUEST.oneofs_by_name['custom_object_definition'].fields.append( - _DEFINECUSTOMOBJECTREQUEST.fields_by_name['custom_box']) -_DEFINECUSTOMOBJECTREQUEST.fields_by_name['custom_box'].containing_oneof = _DEFINECUSTOMOBJECTREQUEST.oneofs_by_name['custom_object_definition'] -_DEFINECUSTOMOBJECTREQUEST.oneofs_by_name['custom_object_definition'].fields.append( - _DEFINECUSTOMOBJECTREQUEST.fields_by_name['custom_cube']) -_DEFINECUSTOMOBJECTREQUEST.fields_by_name['custom_cube'].containing_oneof = _DEFINECUSTOMOBJECTREQUEST.oneofs_by_name['custom_object_definition'] -_DEFINECUSTOMOBJECTREQUEST.oneofs_by_name['custom_object_definition'].fields.append( - _DEFINECUSTOMOBJECTREQUEST.fields_by_name['custom_wall']) -_DEFINECUSTOMOBJECTREQUEST.fields_by_name['custom_wall'].containing_oneof = _DEFINECUSTOMOBJECTREQUEST.oneofs_by_name['custom_object_definition'] -_DEFINECUSTOMOBJECTRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_OBJECTEVENT.fields_by_name['object_available'].message_type = _OBJECTAVAILABLE -_OBJECTEVENT.fields_by_name['object_connection_state'].message_type = _OBJECTCONNECTIONSTATE -_OBJECTEVENT.fields_by_name['object_moved'].message_type = _OBJECTMOVED -_OBJECTEVENT.fields_by_name['object_stopped_moving'].message_type = _OBJECTSTOPPEDMOVING -_OBJECTEVENT.fields_by_name['object_up_axis_changed'].message_type = _OBJECTUPAXISCHANGED -_OBJECTEVENT.fields_by_name['object_tapped'].message_type = _OBJECTTAPPED -_OBJECTEVENT.fields_by_name['robot_observed_object'].message_type = _ROBOTOBSERVEDOBJECT -_OBJECTEVENT.fields_by_name['cube_connection_lost'].message_type = _CUBECONNECTIONLOST -_OBJECTEVENT.oneofs_by_name['object_event_type'].fields.append( - _OBJECTEVENT.fields_by_name['object_available']) -_OBJECTEVENT.fields_by_name['object_available'].containing_oneof = _OBJECTEVENT.oneofs_by_name['object_event_type'] -_OBJECTEVENT.oneofs_by_name['object_event_type'].fields.append( - _OBJECTEVENT.fields_by_name['object_connection_state']) -_OBJECTEVENT.fields_by_name['object_connection_state'].containing_oneof = _OBJECTEVENT.oneofs_by_name['object_event_type'] -_OBJECTEVENT.oneofs_by_name['object_event_type'].fields.append( - _OBJECTEVENT.fields_by_name['object_moved']) -_OBJECTEVENT.fields_by_name['object_moved'].containing_oneof = _OBJECTEVENT.oneofs_by_name['object_event_type'] -_OBJECTEVENT.oneofs_by_name['object_event_type'].fields.append( - _OBJECTEVENT.fields_by_name['object_stopped_moving']) -_OBJECTEVENT.fields_by_name['object_stopped_moving'].containing_oneof = _OBJECTEVENT.oneofs_by_name['object_event_type'] -_OBJECTEVENT.oneofs_by_name['object_event_type'].fields.append( - _OBJECTEVENT.fields_by_name['object_up_axis_changed']) -_OBJECTEVENT.fields_by_name['object_up_axis_changed'].containing_oneof = _OBJECTEVENT.oneofs_by_name['object_event_type'] -_OBJECTEVENT.oneofs_by_name['object_event_type'].fields.append( - _OBJECTEVENT.fields_by_name['object_tapped']) -_OBJECTEVENT.fields_by_name['object_tapped'].containing_oneof = _OBJECTEVENT.oneofs_by_name['object_event_type'] -_OBJECTEVENT.oneofs_by_name['object_event_type'].fields.append( - _OBJECTEVENT.fields_by_name['robot_observed_object']) -_OBJECTEVENT.fields_by_name['robot_observed_object'].containing_oneof = _OBJECTEVENT.oneofs_by_name['object_event_type'] -_OBJECTEVENT.oneofs_by_name['object_event_type'].fields.append( - _OBJECTEVENT.fields_by_name['cube_connection_lost']) -_OBJECTEVENT.fields_by_name['cube_connection_lost'].containing_oneof = _OBJECTEVENT.oneofs_by_name['object_event_type'] -DESCRIPTOR.message_types_by_name['ConnectCubeRequest'] = _CONNECTCUBEREQUEST -DESCRIPTOR.message_types_by_name['ConnectCubeResponse'] = _CONNECTCUBERESPONSE -DESCRIPTOR.message_types_by_name['CubesAvailableRequest'] = _CUBESAVAILABLEREQUEST -DESCRIPTOR.message_types_by_name['CubesAvailableResponse'] = _CUBESAVAILABLERESPONSE -DESCRIPTOR.message_types_by_name['DisconnectCubeRequest'] = _DISCONNECTCUBEREQUEST -DESCRIPTOR.message_types_by_name['DisconnectCubeResponse'] = _DISCONNECTCUBERESPONSE -DESCRIPTOR.message_types_by_name['FlashCubeLightsRequest'] = _FLASHCUBELIGHTSREQUEST -DESCRIPTOR.message_types_by_name['FlashCubeLightsResponse'] = _FLASHCUBELIGHTSRESPONSE -DESCRIPTOR.message_types_by_name['ForgetPreferredCubeRequest'] = _FORGETPREFERREDCUBEREQUEST -DESCRIPTOR.message_types_by_name['ForgetPreferredCubeResponse'] = _FORGETPREFERREDCUBERESPONSE -DESCRIPTOR.message_types_by_name['SetPreferredCubeRequest'] = _SETPREFERREDCUBEREQUEST -DESCRIPTOR.message_types_by_name['SetPreferredCubeResponse'] = _SETPREFERREDCUBERESPONSE -DESCRIPTOR.message_types_by_name['SetCubeLightsRequest'] = _SETCUBELIGHTSREQUEST -DESCRIPTOR.message_types_by_name['SetCubeLightsResponse'] = _SETCUBELIGHTSRESPONSE -DESCRIPTOR.message_types_by_name['ObjectAvailable'] = _OBJECTAVAILABLE -DESCRIPTOR.message_types_by_name['ObjectConnectionState'] = _OBJECTCONNECTIONSTATE -DESCRIPTOR.message_types_by_name['ObjectMoved'] = _OBJECTMOVED -DESCRIPTOR.message_types_by_name['ObjectStoppedMoving'] = _OBJECTSTOPPEDMOVING -DESCRIPTOR.message_types_by_name['ObjectUpAxisChanged'] = _OBJECTUPAXISCHANGED -DESCRIPTOR.message_types_by_name['ObjectTapped'] = _OBJECTTAPPED -DESCRIPTOR.message_types_by_name['RobotObservedObject'] = _ROBOTOBSERVEDOBJECT -DESCRIPTOR.message_types_by_name['CubeConnectionLost'] = _CUBECONNECTIONLOST -DESCRIPTOR.message_types_by_name['DeleteCustomObjectsRequest'] = _DELETECUSTOMOBJECTSREQUEST -DESCRIPTOR.message_types_by_name['DeleteCustomObjectsResponse'] = _DELETECUSTOMOBJECTSRESPONSE -DESCRIPTOR.message_types_by_name['CreateFixedCustomObjectRequest'] = _CREATEFIXEDCUSTOMOBJECTREQUEST -DESCRIPTOR.message_types_by_name['CreateFixedCustomObjectResponse'] = _CREATEFIXEDCUSTOMOBJECTRESPONSE -DESCRIPTOR.message_types_by_name['CustomBoxDefinition'] = _CUSTOMBOXDEFINITION -DESCRIPTOR.message_types_by_name['CustomCubeDefinition'] = _CUSTOMCUBEDEFINITION -DESCRIPTOR.message_types_by_name['CustomWallDefinition'] = _CUSTOMWALLDEFINITION -DESCRIPTOR.message_types_by_name['DefineCustomObjectRequest'] = _DEFINECUSTOMOBJECTREQUEST -DESCRIPTOR.message_types_by_name['DefineCustomObjectResponse'] = _DEFINECUSTOMOBJECTRESPONSE -DESCRIPTOR.message_types_by_name['ObjectEvent'] = _OBJECTEVENT -DESCRIPTOR.enum_types_by_name['ObjectType'] = _OBJECTTYPE -DESCRIPTOR.enum_types_by_name['CustomType'] = _CUSTOMTYPE -DESCRIPTOR.enum_types_by_name['ObjectFamily'] = _OBJECTFAMILY -DESCRIPTOR.enum_types_by_name['UpAxis'] = _UPAXIS -DESCRIPTOR.enum_types_by_name['ObjectConstants'] = _OBJECTCONSTANTS -DESCRIPTOR.enum_types_by_name['CustomObjectMarker'] = _CUSTOMOBJECTMARKER -DESCRIPTOR.enum_types_by_name['CustomObjectDeletionMode'] = _CUSTOMOBJECTDELETIONMODE -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -ConnectCubeRequest = _reflection.GeneratedProtocolMessageType('ConnectCubeRequest', (_message.Message,), dict( - DESCRIPTOR = _CONNECTCUBEREQUEST, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ConnectCubeRequest) - )) -_sym_db.RegisterMessage(ConnectCubeRequest) - -ConnectCubeResponse = _reflection.GeneratedProtocolMessageType('ConnectCubeResponse', (_message.Message,), dict( - DESCRIPTOR = _CONNECTCUBERESPONSE, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ConnectCubeResponse) - )) -_sym_db.RegisterMessage(ConnectCubeResponse) - -CubesAvailableRequest = _reflection.GeneratedProtocolMessageType('CubesAvailableRequest', (_message.Message,), dict( - DESCRIPTOR = _CUBESAVAILABLEREQUEST, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.CubesAvailableRequest) - )) -_sym_db.RegisterMessage(CubesAvailableRequest) - -CubesAvailableResponse = _reflection.GeneratedProtocolMessageType('CubesAvailableResponse', (_message.Message,), dict( - DESCRIPTOR = _CUBESAVAILABLERESPONSE, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.CubesAvailableResponse) - )) -_sym_db.RegisterMessage(CubesAvailableResponse) - -DisconnectCubeRequest = _reflection.GeneratedProtocolMessageType('DisconnectCubeRequest', (_message.Message,), dict( - DESCRIPTOR = _DISCONNECTCUBEREQUEST, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DisconnectCubeRequest) - )) -_sym_db.RegisterMessage(DisconnectCubeRequest) - -DisconnectCubeResponse = _reflection.GeneratedProtocolMessageType('DisconnectCubeResponse', (_message.Message,), dict( - DESCRIPTOR = _DISCONNECTCUBERESPONSE, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DisconnectCubeResponse) - )) -_sym_db.RegisterMessage(DisconnectCubeResponse) - -FlashCubeLightsRequest = _reflection.GeneratedProtocolMessageType('FlashCubeLightsRequest', (_message.Message,), dict( - DESCRIPTOR = _FLASHCUBELIGHTSREQUEST, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.FlashCubeLightsRequest) - )) -_sym_db.RegisterMessage(FlashCubeLightsRequest) - -FlashCubeLightsResponse = _reflection.GeneratedProtocolMessageType('FlashCubeLightsResponse', (_message.Message,), dict( - DESCRIPTOR = _FLASHCUBELIGHTSRESPONSE, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.FlashCubeLightsResponse) - )) -_sym_db.RegisterMessage(FlashCubeLightsResponse) - -ForgetPreferredCubeRequest = _reflection.GeneratedProtocolMessageType('ForgetPreferredCubeRequest', (_message.Message,), dict( - DESCRIPTOR = _FORGETPREFERREDCUBEREQUEST, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ForgetPreferredCubeRequest) - )) -_sym_db.RegisterMessage(ForgetPreferredCubeRequest) - -ForgetPreferredCubeResponse = _reflection.GeneratedProtocolMessageType('ForgetPreferredCubeResponse', (_message.Message,), dict( - DESCRIPTOR = _FORGETPREFERREDCUBERESPONSE, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ForgetPreferredCubeResponse) - )) -_sym_db.RegisterMessage(ForgetPreferredCubeResponse) - -SetPreferredCubeRequest = _reflection.GeneratedProtocolMessageType('SetPreferredCubeRequest', (_message.Message,), dict( - DESCRIPTOR = _SETPREFERREDCUBEREQUEST, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SetPreferredCubeRequest) - )) -_sym_db.RegisterMessage(SetPreferredCubeRequest) - -SetPreferredCubeResponse = _reflection.GeneratedProtocolMessageType('SetPreferredCubeResponse', (_message.Message,), dict( - DESCRIPTOR = _SETPREFERREDCUBERESPONSE, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SetPreferredCubeResponse) - )) -_sym_db.RegisterMessage(SetPreferredCubeResponse) - -SetCubeLightsRequest = _reflection.GeneratedProtocolMessageType('SetCubeLightsRequest', (_message.Message,), dict( - DESCRIPTOR = _SETCUBELIGHTSREQUEST, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SetCubeLightsRequest) - )) -_sym_db.RegisterMessage(SetCubeLightsRequest) - -SetCubeLightsResponse = _reflection.GeneratedProtocolMessageType('SetCubeLightsResponse', (_message.Message,), dict( - DESCRIPTOR = _SETCUBELIGHTSRESPONSE, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SetCubeLightsResponse) - )) -_sym_db.RegisterMessage(SetCubeLightsResponse) - -ObjectAvailable = _reflection.GeneratedProtocolMessageType('ObjectAvailable', (_message.Message,), dict( - DESCRIPTOR = _OBJECTAVAILABLE, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ObjectAvailable) - )) -_sym_db.RegisterMessage(ObjectAvailable) - -ObjectConnectionState = _reflection.GeneratedProtocolMessageType('ObjectConnectionState', (_message.Message,), dict( - DESCRIPTOR = _OBJECTCONNECTIONSTATE, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ObjectConnectionState) - )) -_sym_db.RegisterMessage(ObjectConnectionState) - -ObjectMoved = _reflection.GeneratedProtocolMessageType('ObjectMoved', (_message.Message,), dict( - DESCRIPTOR = _OBJECTMOVED, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ObjectMoved) - )) -_sym_db.RegisterMessage(ObjectMoved) - -ObjectStoppedMoving = _reflection.GeneratedProtocolMessageType('ObjectStoppedMoving', (_message.Message,), dict( - DESCRIPTOR = _OBJECTSTOPPEDMOVING, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ObjectStoppedMoving) - )) -_sym_db.RegisterMessage(ObjectStoppedMoving) - -ObjectUpAxisChanged = _reflection.GeneratedProtocolMessageType('ObjectUpAxisChanged', (_message.Message,), dict( - DESCRIPTOR = _OBJECTUPAXISCHANGED, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ObjectUpAxisChanged) - )) -_sym_db.RegisterMessage(ObjectUpAxisChanged) - -ObjectTapped = _reflection.GeneratedProtocolMessageType('ObjectTapped', (_message.Message,), dict( - DESCRIPTOR = _OBJECTTAPPED, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ObjectTapped) - )) -_sym_db.RegisterMessage(ObjectTapped) - -RobotObservedObject = _reflection.GeneratedProtocolMessageType('RobotObservedObject', (_message.Message,), dict( - DESCRIPTOR = _ROBOTOBSERVEDOBJECT, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.RobotObservedObject) - )) -_sym_db.RegisterMessage(RobotObservedObject) - -CubeConnectionLost = _reflection.GeneratedProtocolMessageType('CubeConnectionLost', (_message.Message,), dict( - DESCRIPTOR = _CUBECONNECTIONLOST, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.CubeConnectionLost) - )) -_sym_db.RegisterMessage(CubeConnectionLost) - -DeleteCustomObjectsRequest = _reflection.GeneratedProtocolMessageType('DeleteCustomObjectsRequest', (_message.Message,), dict( - DESCRIPTOR = _DELETECUSTOMOBJECTSREQUEST, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DeleteCustomObjectsRequest) - )) -_sym_db.RegisterMessage(DeleteCustomObjectsRequest) - -DeleteCustomObjectsResponse = _reflection.GeneratedProtocolMessageType('DeleteCustomObjectsResponse', (_message.Message,), dict( - DESCRIPTOR = _DELETECUSTOMOBJECTSRESPONSE, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DeleteCustomObjectsResponse) - )) -_sym_db.RegisterMessage(DeleteCustomObjectsResponse) - -CreateFixedCustomObjectRequest = _reflection.GeneratedProtocolMessageType('CreateFixedCustomObjectRequest', (_message.Message,), dict( - DESCRIPTOR = _CREATEFIXEDCUSTOMOBJECTREQUEST, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.CreateFixedCustomObjectRequest) - )) -_sym_db.RegisterMessage(CreateFixedCustomObjectRequest) - -CreateFixedCustomObjectResponse = _reflection.GeneratedProtocolMessageType('CreateFixedCustomObjectResponse', (_message.Message,), dict( - DESCRIPTOR = _CREATEFIXEDCUSTOMOBJECTRESPONSE, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.CreateFixedCustomObjectResponse) - )) -_sym_db.RegisterMessage(CreateFixedCustomObjectResponse) - -CustomBoxDefinition = _reflection.GeneratedProtocolMessageType('CustomBoxDefinition', (_message.Message,), dict( - DESCRIPTOR = _CUSTOMBOXDEFINITION, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.CustomBoxDefinition) - )) -_sym_db.RegisterMessage(CustomBoxDefinition) - -CustomCubeDefinition = _reflection.GeneratedProtocolMessageType('CustomCubeDefinition', (_message.Message,), dict( - DESCRIPTOR = _CUSTOMCUBEDEFINITION, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.CustomCubeDefinition) - )) -_sym_db.RegisterMessage(CustomCubeDefinition) - -CustomWallDefinition = _reflection.GeneratedProtocolMessageType('CustomWallDefinition', (_message.Message,), dict( - DESCRIPTOR = _CUSTOMWALLDEFINITION, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.CustomWallDefinition) - )) -_sym_db.RegisterMessage(CustomWallDefinition) - -DefineCustomObjectRequest = _reflection.GeneratedProtocolMessageType('DefineCustomObjectRequest', (_message.Message,), dict( - DESCRIPTOR = _DEFINECUSTOMOBJECTREQUEST, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DefineCustomObjectRequest) - )) -_sym_db.RegisterMessage(DefineCustomObjectRequest) - -DefineCustomObjectResponse = _reflection.GeneratedProtocolMessageType('DefineCustomObjectResponse', (_message.Message,), dict( - DESCRIPTOR = _DEFINECUSTOMOBJECTRESPONSE, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DefineCustomObjectResponse) - )) -_sym_db.RegisterMessage(DefineCustomObjectResponse) - -ObjectEvent = _reflection.GeneratedProtocolMessageType('ObjectEvent', (_message.Message,), dict( - DESCRIPTOR = _OBJECTEVENT, - __module__ = 'anki_vector.messaging.cube_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ObjectEvent) - )) -_sym_db.RegisterMessage(ObjectEvent) - - -_CUSTOMTYPE.has_options = True -_CUSTOMTYPE._options = _descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\020\001')) -_OBJECTFAMILY.has_options = True -_OBJECTFAMILY._options = _descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\020\001')) -_CUSTOMOBJECTMARKER.has_options = True -_CUSTOMOBJECTMARKER._options = _descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\020\001')) -# @@protoc_insertion_point(module_scope) diff --git a/anki_vector/messaging/cube_pb2_grpc.py b/anki_vector/messaging/cube_pb2_grpc.py deleted file mode 100644 index a894352..0000000 --- a/anki_vector/messaging/cube_pb2_grpc.py +++ /dev/null @@ -1,3 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - diff --git a/anki_vector/messaging/extensions.proto b/anki_vector/messaging/extensions.proto deleted file mode 100644 index 20015ad..0000000 --- a/anki_vector/messaging/extensions.proto +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2018 Anki, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License in the file LICENSE.txt or at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Add a decorator for streamed message handling in app - -syntax = "proto3"; - -package Anki.Vector.external_interface; - -import "google/protobuf/descriptor.proto"; - -extend google.protobuf.MessageOptions { - bool streamed = 60000; -} \ No newline at end of file diff --git a/anki_vector/messaging/extensions_pb2.py b/anki_vector/messaging/extensions_pb2.py deleted file mode 100644 index 1b5cae5..0000000 --- a/anki_vector/messaging/extensions_pb2.py +++ /dev/null @@ -1,42 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: anki_vector/messaging/extensions.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='anki_vector/messaging/extensions.proto', - package='Anki.Vector.external_interface', - syntax='proto3', - serialized_pb=_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') - , - dependencies=[google_dot_protobuf_dot_descriptor__pb2.DESCRIPTOR,]) - - -STREAMED_FIELD_NUMBER = 60000 -streamed = _descriptor.FieldDescriptor( - name='streamed', full_name='Anki.Vector.external_interface.streamed', index=0, - number=60000, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=True, extension_scope=None, - options=None, file=DESCRIPTOR) - -DESCRIPTOR.extensions_by_name['streamed'] = streamed -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(streamed) - -# @@protoc_insertion_point(module_scope) diff --git a/anki_vector/messaging/extensions_pb2_grpc.py b/anki_vector/messaging/extensions_pb2_grpc.py deleted file mode 100644 index a894352..0000000 --- a/anki_vector/messaging/extensions_pb2_grpc.py +++ /dev/null @@ -1,3 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - diff --git a/anki_vector/messaging/external_interface.proto b/anki_vector/messaging/external_interface.proto deleted file mode 100644 index 2c60104..0000000 --- a/anki_vector/messaging/external_interface.proto +++ /dev/null @@ -1,408 +0,0 @@ -// Copyright (c) 2018 Anki, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License in the file LICENSE.txt or at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// External interface for robot <-> app and robot <-> sdk communication - -syntax = "proto3"; - -package Anki.Vector.external_interface; - -import "google/api/annotations.proto"; -import "anki_vector/messaging/behavior.proto"; -import "anki_vector/messaging/cube.proto"; -import "anki_vector/messaging/messages.proto"; -import "anki_vector/messaging/nav_map.proto"; -import "anki_vector/messaging/shared.proto"; - -// The grpc-defined connection between the SDK and Anki's Vector robot. -service ExternalInterface { - // Checks the supported protocol version by passing in the client version and - // minimum host version and receiving a response to see whether the versions are supported. - rpc ProtocolVersion(ProtocolVersionRequest) returns (ProtocolVersionResponse) { - option (google.api.http) = { - post: "/v1/protocol_version", - body: "*" - }; - } - - // SDK-only message to pass version info for device OS, Python version, etc. - rpc SDKInitialization(SDKInitializationRequest) returns (SDKInitializationResponse) { - option (google.api.http) = { - post: "/v1/sdk_initialization", - body: "*" - }; - } - - // Sets the speed and acceleration for Vector's wheel motors. - rpc DriveWheels(DriveWheelsRequest) returns (DriveWheelsResponse) {} - - // Requests that Vector play an animation. - rpc PlayAnimation(PlayAnimationRequest) returns (PlayAnimationResponse) {} - - // Constructs and returns a list of animations. - rpc ListAnimations(ListAnimationsRequest) returns (ListAnimationsResponse) { - option (google.api.http) = { - post: "/v1/list_animations", - body: "*" - }; - } - - // Moves Vector's head. - rpc MoveHead(MoveHeadRequest) returns (MoveHeadResponse) {} - - // Moves Vector's lift. - rpc MoveLift(MoveLiftRequest) returns (MoveLiftResponse) {} - - // Sets screen (Vector's face) to a solid color. - rpc DisplayFaceImageRGB(DisplayFaceImageRGBRequest) returns (DisplayFaceImageRGBResponse) { - option (google.api.http) = { - post: "/v1/display_face_image_rgb", - body: "*" - }; - } - - // Streaming events endpoint - rpc EventStream(EventRequest) returns (stream EventResponse) { - option (google.api.http) = { - post: "/v1/event_stream", - additional_bindings { - get: "/v1/event_stream" - }, - body: "*" - }; - } - - // Integrate with and acquire control of Vector's AI system. - rpc BehaviorControl(stream BehaviorControlRequest) returns (stream BehaviorControlResponse) { - } - - // Acquire control of Vector's AI system. - rpc AssumeBehaviorControl(BehaviorControlRequest) returns (stream BehaviorControlResponse) { - option (google.api.http) = { - post: "/v1/assume_behavior_control", - body: "*" - }; - } - - rpc CancelFaceEnrollment(CancelFaceEnrollmentRequest) returns (CancelFaceEnrollmentResponse) { - option (google.api.http) = { - post: "/v1/cancel_face_enrollment", - body: "*" - }; - } - - // Get a list of names and their IDs. - rpc RequestEnrolledNames(RequestEnrolledNamesRequest) returns (RequestEnrolledNamesResponse) { - option (google.api.http) = { - post: "/v1/request_enrolled_names", - body: "*" - }; - } - - // Update the name enrolled for a given face. - rpc UpdateEnrolledFaceByID(UpdateEnrolledFaceByIDRequest) returns (UpdateEnrolledFaceByIDResponse) { - option (google.api.http) = { - post: "/v1/update_enrolled_face_by_id", - body: "*" - }; - } - - // Erase the enrollment (name) record for the face with this ID. - rpc EraseEnrolledFaceByID(EraseEnrolledFaceByIDRequest) returns (EraseEnrolledFaceByIDResponse) { - option (google.api.http) = { - post: "/v1/erase_enrolled_face_by_id", - body: "*" - }; - } - - // Erase the enrollment (name) records for all faces. - rpc EraseAllEnrolledFaces(EraseAllEnrolledFacesRequest) returns (EraseAllEnrolledFacesResponse) { - option (google.api.http) = { - post: "/v1/erase_all_enrolled_faces", - body: "*" - }; - } - - rpc SetFaceToEnroll(SetFaceToEnrollRequest) returns (SetFaceToEnrollResponse) { - option (google.api.http) = { - post: "/v1/set_face_to_enroll", - body: "*" - }; - } - - rpc EnableMarkerDetection(EnableMarkerDetectionRequest) returns (EnableMarkerDetectionResponse) { - option (google.api.http) = { - post: "/v1/enable_marker_detection", - body: "*" - }; - } - - rpc EnableFaceDetection(EnableFaceDetectionRequest) returns (EnableFaceDetectionResponse) { - option (google.api.http) = { - post: "/v1/enable_face_detection", - body: "*" - }; - } - - rpc EnableMotionDetection(EnableMotionDetectionRequest) returns (EnableMotionDetectionResponse) { - option (google.api.http) = { - post: "/v1/enable_motion_detection", - body: "*" - }; - } - - rpc EnableMirrorMode(EnableMirrorModeRequest) returns (EnableMirrorModeResponse) { - option (google.api.http) = { - post: "/v1/enable_mirror_mode", - body: "*" - }; - } - - rpc EnableImageStreaming(EnableImageStreamingRequest) returns (EnableImageStreamingResponse) { - option (google.api.http) = { - post: "/v1/enable_image_streaming", - body: "*" - }; - } - - // Tells Vector to drive to the specified pose and orientation. - rpc GoToPose(GoToPoseRequest) returns (GoToPoseResponse) { - option (google.api.http) = { - post: "/v1/go_to_pose", - body: "*" - }; - } - - // Tells Vector to dock with a light cube with a given approach angle and distance. - rpc DockWithCube(DockWithCubeRequest) returns (DockWithCubeResponse) { - option (google.api.http) = { - post: "/v1/dock_with_cube", - body: "*" - }; - } - - // Drive Vector off the charger. - rpc DriveOffCharger(DriveOffChargerRequest) returns (DriveOffChargerResponse) { - option (google.api.http) = { - post: "/v1/drive_off_charger", - body: "*" - }; - } - - // Drive Vector onto the charger. - rpc DriveOnCharger(DriveOnChargerRequest) returns (DriveOnChargerResponse) { - option (google.api.http) = { - post: "/v1/drive_on_charger", - body: "*" - }; - } - - // Get the photos info. - rpc PhotosInfo(PhotosInfoRequest) returns (PhotosInfoResponse) { - option (google.api.http) = { - post: "/v1/photos_info", - body: "*" - }; - } - - // Get a photo by ID. - rpc Photo(PhotoRequest) returns (PhotoResponse) { - option (google.api.http) = { - post: "/v1/photo", - body: "*" - }; - } - - // Get a thumbnail by ID. - rpc Thumbnail(ThumbnailRequest) returns (ThumbnailResponse) { - option (google.api.http) = { - post: "/v1/thumbnail", - body: "*" - }; - } - - // Delete a photo by ID. - rpc DeletePhoto(DeletePhotoRequest) returns (DeletePhotoResponse) { - option (google.api.http) = { - post: "/v1/delete_photo", - body: "*" - }; - } - - // Tells Vector to drive in a straight line. - rpc DriveStraight(DriveStraightRequest) returns (DriveStraightResponse) {} - - // Turn the robot around its current position. - rpc TurnInPlace(TurnInPlaceRequest) returns (TurnInPlaceResponse) {} - - // Tell Vector's head to move to a given angle. - rpc SetHeadAngle(SetHeadAngleRequest) returns (SetHeadAngleResponse) {} - - // Tell Vector's lift to move to a given height. - rpc SetLiftHeight(SetLiftHeightRequest) returns (SetLiftHeightResponse) {} - - rpc UserAuthentication(UserAuthenticationRequest) returns (UserAuthenticationResponse) { - option (google.api.http) = { - post: "/v1/user_authentication", - body: "*" - }; - } - - // Check the current state of the battery. - rpc BatteryState(BatteryStateRequest) returns (BatteryStateResponse) { - option (google.api.http) = { - post: "/v1/battery_state", - body: "*" - }; - } - - // Get the versioning information for Vector. - rpc VersionState(VersionStateRequest) returns (VersionStateResponse) { - option (google.api.http) = { - post: "/v1/version_state", - body: "*" - }; - } - - // Get the network information for Vector. - rpc NetworkState(NetworkStateRequest) returns (NetworkStateResponse) { - option (google.api.http) = { - post: "/v1/network_state", - body: "*" - }; - } - - // Make Vector speak text. - rpc SayText(SayTextRequest) returns (SayTextResponse) { - option (google.api.http) = { - post: "/v1/say_text", - body: "*" - }; - } - - // Attempt to connect to a cube. If a cube is currently connected, - // this will do nothing. - rpc ConnectCube(ConnectCubeRequest) returns (ConnectCubeResponse) { - option (google.api.http) = { - post: "/v1/connect_cube", - body: "*" - }; - } - - // Requests a disconnection from the currently connected cube. - rpc DisconnectCube(DisconnectCubeRequest) returns (DisconnectCubeResponse) { - option (google.api.http) = { - post: "/v1/disconnect_cube", - body: "*" - }; - } - - rpc CubesAvailable(CubesAvailableRequest) returns (CubesAvailableResponse) { - option (google.api.http) = { - post: "/v1/cubes_available", - body: "*" - }; - } - - // Signal a connected cube to flash its lights using the default cube - // flash animation. - rpc FlashCubeLights(FlashCubeLightsRequest) returns (FlashCubeLightsResponse) { - option (google.api.http) = { - post: "/v1/flash_cube_lights", - body: "*" - }; - } - - // Forget the robot's preferred cube. This will cause the robot to - // connect to the cube with the highest RSSI (signal strength) next - // time a connection is requested. Saves this preference to disk. - // The next cube that the robot connects to will become its - // preferred cube. - rpc ForgetPreferredCube(ForgetPreferredCubeRequest) returns (ForgetPreferredCubeResponse) { - option (google.api.http) = { - post: "/v1/forget_preferred_cube", - body: "*" - }; - } - - // Set the robot's preferred cube and save it to disk. The robot - // will always attempt to connect to this cube if it is available. - // This is only used in simulation for now. - rpc SetPreferredCube(SetPreferredCubeRequest) returns (SetPreferredCubeResponse) { - option (google.api.http) = { - post: "/v1/set_preferred_cube", - body: "*" - }; - } - - // Causes the robot to forget about custom objects it currently knows about. - rpc DeleteCustomObjects(DeleteCustomObjectsRequest) returns (DeleteCustomObjectsResponse) { - option (google.api.http) = { - post: "/v1/delete_custom_objects", - body: "*" - }; - } - - // Creates a permanent custom object instance in the robot's world, with no connection to the vision system. - rpc CreateFixedCustomObject(CreateFixedCustomObjectRequest) returns (CreateFixedCustomObjectResponse) { - option (google.api.http) = { - post: "/v1/create_fixed_custom_object", - body: "*" - }; - } - - // Creates a custom object with distinct custom marker(s). - rpc DefineCustomObject(DefineCustomObjectRequest) returns (DefineCustomObjectResponse) { - option (google.api.http) = { - post: "/v1/define_custom_object", - body: "*" - }; - } - - // Set each of the lights on the currently connected cube based on two - // rgb values each and timing data for how to transition between them. - rpc SetCubeLights(SetCubeLightsRequest) returns (SetCubeLightsResponse) {} - - // Request an audio feed from the robot. - rpc AudioFeed(AudioFeedRequest) returns (stream AudioFeedResponse) { - option (google.api.http) = { - post: "/v1/audio_feed", - body: "*" - }; - } - - // Request a camera feed from the robot. - rpc CameraFeed(CameraFeedRequest) returns (stream CameraFeedResponse) { - option (google.api.http) = { - post: "/v1/camera_feed", - body: "*" - }; - } - - // Set Vector's eye color. - rpc SetEyeColor(SetEyeColorRequest) returns (SetEyeColorResponse) { - option (google.api.http) = { - post: "/v1/set_eye_color", - body: "*" - }; - } - - rpc NavMapFeed(NavMapFeedRequest) returns (stream NavMapFeedResponse) { - option (google.api.http) = { - post: "/v1/nav_map_feed", - body: "*" - }; - } - -} \ No newline at end of file diff --git a/anki_vector/messaging/external_interface_pb2.py b/anki_vector/messaging/external_interface_pb2.py deleted file mode 100644 index 7ceff3b..0000000 --- a/anki_vector/messaging/external_interface_pb2.py +++ /dev/null @@ -1,529 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: anki_vector/messaging/external_interface.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 -from anki_vector.messaging import behavior_pb2 as anki__vector_dot_messaging_dot_behavior__pb2 -from anki_vector.messaging import cube_pb2 as anki__vector_dot_messaging_dot_cube__pb2 -from anki_vector.messaging import messages_pb2 as anki__vector_dot_messaging_dot_messages__pb2 -from anki_vector.messaging import nav_map_pb2 as anki__vector_dot_messaging_dot_nav__map__pb2 -from anki_vector.messaging import shared_pb2 as anki__vector_dot_messaging_dot_shared__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='anki_vector/messaging/external_interface.proto', - package='Anki.Vector.external_interface', - syntax='proto3', - serialized_pb=_b('\n.anki_vector/messaging/external_interface.proto\x12\x1e\x41nki.Vector.external_interface\x1a\x1cgoogle/api/annotations.proto\x1a$anki_vector/messaging/behavior.proto\x1a anki_vector/messaging/cube.proto\x1a$anki_vector/messaging/messages.proto\x1a#anki_vector/messaging/nav_map.proto\x1a\"anki_vector/messaging/shared.proto2\xff\x41\n\x11\x45xternalInterface\x12\xa3\x01\n\x0fProtocolVersion\x12\x36.Anki.Vector.external_interface.ProtocolVersionRequest\x1a\x37.Anki.Vector.external_interface.ProtocolVersionResponse\"\x1f\x82\xd3\xe4\x93\x02\x19\"\x14/v1/protocol_version:\x01*\x12\xab\x01\n\x11SDKInitialization\x12\x38.Anki.Vector.external_interface.SDKInitializationRequest\x1a\x39.Anki.Vector.external_interface.SDKInitializationResponse\"!\x82\xd3\xe4\x93\x02\x1b\"\x16/v1/sdk_initialization:\x01*\x12x\n\x0b\x44riveWheels\x12\x32.Anki.Vector.external_interface.DriveWheelsRequest\x1a\x33.Anki.Vector.external_interface.DriveWheelsResponse\"\x00\x12~\n\rPlayAnimation\x12\x34.Anki.Vector.external_interface.PlayAnimationRequest\x1a\x35.Anki.Vector.external_interface.PlayAnimationResponse\"\x00\x12\x9f\x01\n\x0eListAnimations\x12\x35.Anki.Vector.external_interface.ListAnimationsRequest\x1a\x36.Anki.Vector.external_interface.ListAnimationsResponse\"\x1e\x82\xd3\xe4\x93\x02\x18\"\x13/v1/list_animations:\x01*\x12o\n\x08MoveHead\x12/.Anki.Vector.external_interface.MoveHeadRequest\x1a\x30.Anki.Vector.external_interface.MoveHeadResponse\"\x00\x12o\n\x08MoveLift\x12/.Anki.Vector.external_interface.MoveLiftRequest\x1a\x30.Anki.Vector.external_interface.MoveLiftResponse\"\x00\x12\xb5\x01\n\x13\x44isplayFaceImageRGB\x12:.Anki.Vector.external_interface.DisplayFaceImageRGBRequest\x1a;.Anki.Vector.external_interface.DisplayFaceImageRGBResponse\"%\x82\xd3\xe4\x93\x02\x1f\"\x1a/v1/display_face_image_rgb:\x01*\x12\x9d\x01\n\x0b\x45ventStream\x12,.Anki.Vector.external_interface.EventRequest\x1a-.Anki.Vector.external_interface.EventResponse\"/\x82\xd3\xe4\x93\x02)\"\x10/v1/event_stream:\x01*Z\x12\x12\x10/v1/event_stream0\x01\x12\x88\x01\n\x0f\x42\x65haviorControl\x12\x36.Anki.Vector.external_interface.BehaviorControlRequest\x1a\x37.Anki.Vector.external_interface.BehaviorControlResponse\"\x00(\x01\x30\x01\x12\xb2\x01\n\x15\x41ssumeBehaviorControl\x12\x36.Anki.Vector.external_interface.BehaviorControlRequest\x1a\x37.Anki.Vector.external_interface.BehaviorControlResponse\"&\x82\xd3\xe4\x93\x02 \"\x1b/v1/assume_behavior_control:\x01*0\x01\x12\xb8\x01\n\x14\x43\x61ncelFaceEnrollment\x12;.Anki.Vector.external_interface.CancelFaceEnrollmentRequest\x1a<.Anki.Vector.external_interface.CancelFaceEnrollmentResponse\"%\x82\xd3\xe4\x93\x02\x1f\"\x1a/v1/cancel_face_enrollment:\x01*\x12\xb8\x01\n\x14RequestEnrolledNames\x12;.Anki.Vector.external_interface.RequestEnrolledNamesRequest\x1a<.Anki.Vector.external_interface.RequestEnrolledNamesResponse\"%\x82\xd3\xe4\x93\x02\x1f\"\x1a/v1/request_enrolled_names:\x01*\x12\xc2\x01\n\x16UpdateEnrolledFaceByID\x12=.Anki.Vector.external_interface.UpdateEnrolledFaceByIDRequest\x1a>.Anki.Vector.external_interface.UpdateEnrolledFaceByIDResponse\")\x82\xd3\xe4\x93\x02#\"\x1e/v1/update_enrolled_face_by_id:\x01*\x12\xbe\x01\n\x15\x45raseEnrolledFaceByID\x12<.Anki.Vector.external_interface.EraseEnrolledFaceByIDRequest\x1a=.Anki.Vector.external_interface.EraseEnrolledFaceByIDResponse\"(\x82\xd3\xe4\x93\x02\"\"\x1d/v1/erase_enrolled_face_by_id:\x01*\x12\xbd\x01\n\x15\x45raseAllEnrolledFaces\x12<.Anki.Vector.external_interface.EraseAllEnrolledFacesRequest\x1a=.Anki.Vector.external_interface.EraseAllEnrolledFacesResponse\"\'\x82\xd3\xe4\x93\x02!\"\x1c/v1/erase_all_enrolled_faces:\x01*\x12\xa5\x01\n\x0fSetFaceToEnroll\x12\x36.Anki.Vector.external_interface.SetFaceToEnrollRequest\x1a\x37.Anki.Vector.external_interface.SetFaceToEnrollResponse\"!\x82\xd3\xe4\x93\x02\x1b\"\x16/v1/set_face_to_enroll:\x01*\x12\xbc\x01\n\x15\x45nableMarkerDetection\x12<.Anki.Vector.external_interface.EnableMarkerDetectionRequest\x1a=.Anki.Vector.external_interface.EnableMarkerDetectionResponse\"&\x82\xd3\xe4\x93\x02 \"\x1b/v1/enable_marker_detection:\x01*\x12\xb4\x01\n\x13\x45nableFaceDetection\x12:.Anki.Vector.external_interface.EnableFaceDetectionRequest\x1a;.Anki.Vector.external_interface.EnableFaceDetectionResponse\"$\x82\xd3\xe4\x93\x02\x1e\"\x19/v1/enable_face_detection:\x01*\x12\xbc\x01\n\x15\x45nableMotionDetection\x12<.Anki.Vector.external_interface.EnableMotionDetectionRequest\x1a=.Anki.Vector.external_interface.EnableMotionDetectionResponse\"&\x82\xd3\xe4\x93\x02 \"\x1b/v1/enable_motion_detection:\x01*\x12\xa8\x01\n\x10\x45nableMirrorMode\x12\x37.Anki.Vector.external_interface.EnableMirrorModeRequest\x1a\x38.Anki.Vector.external_interface.EnableMirrorModeResponse\"!\x82\xd3\xe4\x93\x02\x1b\"\x16/v1/enable_mirror_mode:\x01*\x12\xb8\x01\n\x14\x45nableImageStreaming\x12;.Anki.Vector.external_interface.EnableImageStreamingRequest\x1a<.Anki.Vector.external_interface.EnableImageStreamingResponse\"%\x82\xd3\xe4\x93\x02\x1f\"\x1a/v1/enable_image_streaming:\x01*\x12\x88\x01\n\x08GoToPose\x12/.Anki.Vector.external_interface.GoToPoseRequest\x1a\x30.Anki.Vector.external_interface.GoToPoseResponse\"\x19\x82\xd3\xe4\x93\x02\x13\"\x0e/v1/go_to_pose:\x01*\x12\x98\x01\n\x0c\x44ockWithCube\x12\x33.Anki.Vector.external_interface.DockWithCubeRequest\x1a\x34.Anki.Vector.external_interface.DockWithCubeResponse\"\x1d\x82\xd3\xe4\x93\x02\x17\"\x12/v1/dock_with_cube:\x01*\x12\xa4\x01\n\x0f\x44riveOffCharger\x12\x36.Anki.Vector.external_interface.DriveOffChargerRequest\x1a\x37.Anki.Vector.external_interface.DriveOffChargerResponse\" \x82\xd3\xe4\x93\x02\x1a\"\x15/v1/drive_off_charger:\x01*\x12\xa0\x01\n\x0e\x44riveOnCharger\x12\x35.Anki.Vector.external_interface.DriveOnChargerRequest\x1a\x36.Anki.Vector.external_interface.DriveOnChargerResponse\"\x1f\x82\xd3\xe4\x93\x02\x19\"\x14/v1/drive_on_charger:\x01*\x12\x8f\x01\n\nPhotosInfo\x12\x31.Anki.Vector.external_interface.PhotosInfoRequest\x1a\x32.Anki.Vector.external_interface.PhotosInfoResponse\"\x1a\x82\xd3\xe4\x93\x02\x14\"\x0f/v1/photos_info:\x01*\x12z\n\x05Photo\x12,.Anki.Vector.external_interface.PhotoRequest\x1a-.Anki.Vector.external_interface.PhotoResponse\"\x14\x82\xd3\xe4\x93\x02\x0e\"\t/v1/photo:\x01*\x12\x8a\x01\n\tThumbnail\x12\x30.Anki.Vector.external_interface.ThumbnailRequest\x1a\x31.Anki.Vector.external_interface.ThumbnailResponse\"\x18\x82\xd3\xe4\x93\x02\x12\"\r/v1/thumbnail:\x01*\x12\x93\x01\n\x0b\x44\x65letePhoto\x12\x32.Anki.Vector.external_interface.DeletePhotoRequest\x1a\x33.Anki.Vector.external_interface.DeletePhotoResponse\"\x1b\x82\xd3\xe4\x93\x02\x15\"\x10/v1/delete_photo:\x01*\x12~\n\rDriveStraight\x12\x34.Anki.Vector.external_interface.DriveStraightRequest\x1a\x35.Anki.Vector.external_interface.DriveStraightResponse\"\x00\x12x\n\x0bTurnInPlace\x12\x32.Anki.Vector.external_interface.TurnInPlaceRequest\x1a\x33.Anki.Vector.external_interface.TurnInPlaceResponse\"\x00\x12{\n\x0cSetHeadAngle\x12\x33.Anki.Vector.external_interface.SetHeadAngleRequest\x1a\x34.Anki.Vector.external_interface.SetHeadAngleResponse\"\x00\x12~\n\rSetLiftHeight\x12\x34.Anki.Vector.external_interface.SetLiftHeightRequest\x1a\x35.Anki.Vector.external_interface.SetLiftHeightResponse\"\x00\x12\xaf\x01\n\x12UserAuthentication\x12\x39.Anki.Vector.external_interface.UserAuthenticationRequest\x1a:.Anki.Vector.external_interface.UserAuthenticationResponse\"\"\x82\xd3\xe4\x93\x02\x1c\"\x17/v1/user_authentication:\x01*\x12\x97\x01\n\x0c\x42\x61tteryState\x12\x33.Anki.Vector.external_interface.BatteryStateRequest\x1a\x34.Anki.Vector.external_interface.BatteryStateResponse\"\x1c\x82\xd3\xe4\x93\x02\x16\"\x11/v1/battery_state:\x01*\x12\x97\x01\n\x0cVersionState\x12\x33.Anki.Vector.external_interface.VersionStateRequest\x1a\x34.Anki.Vector.external_interface.VersionStateResponse\"\x1c\x82\xd3\xe4\x93\x02\x16\"\x11/v1/version_state:\x01*\x12\x97\x01\n\x0cNetworkState\x12\x33.Anki.Vector.external_interface.NetworkStateRequest\x1a\x34.Anki.Vector.external_interface.NetworkStateResponse\"\x1c\x82\xd3\xe4\x93\x02\x16\"\x11/v1/network_state:\x01*\x12\x83\x01\n\x07SayText\x12..Anki.Vector.external_interface.SayTextRequest\x1a/.Anki.Vector.external_interface.SayTextResponse\"\x17\x82\xd3\xe4\x93\x02\x11\"\x0c/v1/say_text:\x01*\x12\x93\x01\n\x0b\x43onnectCube\x12\x32.Anki.Vector.external_interface.ConnectCubeRequest\x1a\x33.Anki.Vector.external_interface.ConnectCubeResponse\"\x1b\x82\xd3\xe4\x93\x02\x15\"\x10/v1/connect_cube:\x01*\x12\x9f\x01\n\x0e\x44isconnectCube\x12\x35.Anki.Vector.external_interface.DisconnectCubeRequest\x1a\x36.Anki.Vector.external_interface.DisconnectCubeResponse\"\x1e\x82\xd3\xe4\x93\x02\x18\"\x13/v1/disconnect_cube:\x01*\x12\x9f\x01\n\x0e\x43ubesAvailable\x12\x35.Anki.Vector.external_interface.CubesAvailableRequest\x1a\x36.Anki.Vector.external_interface.CubesAvailableResponse\"\x1e\x82\xd3\xe4\x93\x02\x18\"\x13/v1/cubes_available:\x01*\x12\xa4\x01\n\x0f\x46lashCubeLights\x12\x36.Anki.Vector.external_interface.FlashCubeLightsRequest\x1a\x37.Anki.Vector.external_interface.FlashCubeLightsResponse\" \x82\xd3\xe4\x93\x02\x1a\"\x15/v1/flash_cube_lights:\x01*\x12\xb4\x01\n\x13\x46orgetPreferredCube\x12:.Anki.Vector.external_interface.ForgetPreferredCubeRequest\x1a;.Anki.Vector.external_interface.ForgetPreferredCubeResponse\"$\x82\xd3\xe4\x93\x02\x1e\"\x19/v1/forget_preferred_cube:\x01*\x12\xa8\x01\n\x10SetPreferredCube\x12\x37.Anki.Vector.external_interface.SetPreferredCubeRequest\x1a\x38.Anki.Vector.external_interface.SetPreferredCubeResponse\"!\x82\xd3\xe4\x93\x02\x1b\"\x16/v1/set_preferred_cube:\x01*\x12\xb4\x01\n\x13\x44\x65leteCustomObjects\x12:.Anki.Vector.external_interface.DeleteCustomObjectsRequest\x1a;.Anki.Vector.external_interface.DeleteCustomObjectsResponse\"$\x82\xd3\xe4\x93\x02\x1e\"\x19/v1/delete_custom_objects:\x01*\x12\xc5\x01\n\x17\x43reateFixedCustomObject\x12>.Anki.Vector.external_interface.CreateFixedCustomObjectRequest\x1a?.Anki.Vector.external_interface.CreateFixedCustomObjectResponse\")\x82\xd3\xe4\x93\x02#\"\x1e/v1/create_fixed_custom_object:\x01*\x12\xb0\x01\n\x12\x44\x65\x66ineCustomObject\x12\x39.Anki.Vector.external_interface.DefineCustomObjectRequest\x1a:.Anki.Vector.external_interface.DefineCustomObjectResponse\"#\x82\xd3\xe4\x93\x02\x1d\"\x18/v1/define_custom_object:\x01*\x12~\n\rSetCubeLights\x12\x34.Anki.Vector.external_interface.SetCubeLightsRequest\x1a\x35.Anki.Vector.external_interface.SetCubeLightsResponse\"\x00\x12\x8d\x01\n\tAudioFeed\x12\x30.Anki.Vector.external_interface.AudioFeedRequest\x1a\x31.Anki.Vector.external_interface.AudioFeedResponse\"\x19\x82\xd3\xe4\x93\x02\x13\"\x0e/v1/audio_feed:\x01*0\x01\x12\x91\x01\n\nCameraFeed\x12\x31.Anki.Vector.external_interface.CameraFeedRequest\x1a\x32.Anki.Vector.external_interface.CameraFeedResponse\"\x1a\x82\xd3\xe4\x93\x02\x14\"\x0f/v1/camera_feed:\x01*0\x01\x12\x94\x01\n\x0bSetEyeColor\x12\x32.Anki.Vector.external_interface.SetEyeColorRequest\x1a\x33.Anki.Vector.external_interface.SetEyeColorResponse\"\x1c\x82\xd3\xe4\x93\x02\x16\"\x11/v1/set_eye_color:\x01*\x12\x92\x01\n\nNavMapFeed\x12\x31.Anki.Vector.external_interface.NavMapFeedRequest\x1a\x32.Anki.Vector.external_interface.NavMapFeedResponse\"\x1b\x82\xd3\xe4\x93\x02\x15\"\x10/v1/nav_map_feed:\x01*0\x01\x62\x06proto3') - , - dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,anki__vector_dot_messaging_dot_behavior__pb2.DESCRIPTOR,anki__vector_dot_messaging_dot_cube__pb2.DESCRIPTOR,anki__vector_dot_messaging_dot_messages__pb2.DESCRIPTOR,anki__vector_dot_messaging_dot_nav__map__pb2.DESCRIPTOR,anki__vector_dot_messaging_dot_shared__pb2.DESCRIPTOR,]) - - - -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - - - -_EXTERNALINTERFACE = _descriptor.ServiceDescriptor( - name='ExternalInterface', - full_name='Anki.Vector.external_interface.ExternalInterface', - file=DESCRIPTOR, - index=0, - options=None, - serialized_start=296, - serialized_end=8743, - methods=[ - _descriptor.MethodDescriptor( - name='ProtocolVersion', - full_name='Anki.Vector.external_interface.ExternalInterface.ProtocolVersion', - index=0, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_shared__pb2._PROTOCOLVERSIONREQUEST, - output_type=anki__vector_dot_messaging_dot_shared__pb2._PROTOCOLVERSIONRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\031\"\024/v1/protocol_version:\001*')), - ), - _descriptor.MethodDescriptor( - name='SDKInitialization', - full_name='Anki.Vector.external_interface.ExternalInterface.SDKInitialization', - index=1, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._SDKINITIALIZATIONREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._SDKINITIALIZATIONRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\033\"\026/v1/sdk_initialization:\001*')), - ), - _descriptor.MethodDescriptor( - name='DriveWheels', - full_name='Anki.Vector.external_interface.ExternalInterface.DriveWheels', - index=2, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._DRIVEWHEELSREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._DRIVEWHEELSRESPONSE, - options=None, - ), - _descriptor.MethodDescriptor( - name='PlayAnimation', - full_name='Anki.Vector.external_interface.ExternalInterface.PlayAnimation', - index=3, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._PLAYANIMATIONREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._PLAYANIMATIONRESPONSE, - options=None, - ), - _descriptor.MethodDescriptor( - name='ListAnimations', - full_name='Anki.Vector.external_interface.ExternalInterface.ListAnimations', - index=4, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._LISTANIMATIONSREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._LISTANIMATIONSRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\030\"\023/v1/list_animations:\001*')), - ), - _descriptor.MethodDescriptor( - name='MoveHead', - full_name='Anki.Vector.external_interface.ExternalInterface.MoveHead', - index=5, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._MOVEHEADREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._MOVEHEADRESPONSE, - options=None, - ), - _descriptor.MethodDescriptor( - name='MoveLift', - full_name='Anki.Vector.external_interface.ExternalInterface.MoveLift', - index=6, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._MOVELIFTREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._MOVELIFTRESPONSE, - options=None, - ), - _descriptor.MethodDescriptor( - name='DisplayFaceImageRGB', - full_name='Anki.Vector.external_interface.ExternalInterface.DisplayFaceImageRGB', - index=7, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._DISPLAYFACEIMAGERGBREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._DISPLAYFACEIMAGERGBRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\037\"\032/v1/display_face_image_rgb:\001*')), - ), - _descriptor.MethodDescriptor( - name='EventStream', - full_name='Anki.Vector.external_interface.ExternalInterface.EventStream', - index=8, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_shared__pb2._EVENTREQUEST, - output_type=anki__vector_dot_messaging_dot_shared__pb2._EVENTRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002)\"\020/v1/event_stream:\001*Z\022\022\020/v1/event_stream')), - ), - _descriptor.MethodDescriptor( - name='BehaviorControl', - full_name='Anki.Vector.external_interface.ExternalInterface.BehaviorControl', - index=9, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_behavior__pb2._BEHAVIORCONTROLREQUEST, - output_type=anki__vector_dot_messaging_dot_behavior__pb2._BEHAVIORCONTROLRESPONSE, - options=None, - ), - _descriptor.MethodDescriptor( - name='AssumeBehaviorControl', - full_name='Anki.Vector.external_interface.ExternalInterface.AssumeBehaviorControl', - index=10, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_behavior__pb2._BEHAVIORCONTROLREQUEST, - output_type=anki__vector_dot_messaging_dot_behavior__pb2._BEHAVIORCONTROLRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002 \"\033/v1/assume_behavior_control:\001*')), - ), - _descriptor.MethodDescriptor( - name='CancelFaceEnrollment', - full_name='Anki.Vector.external_interface.ExternalInterface.CancelFaceEnrollment', - index=11, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._CANCELFACEENROLLMENTREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._CANCELFACEENROLLMENTRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\037\"\032/v1/cancel_face_enrollment:\001*')), - ), - _descriptor.MethodDescriptor( - name='RequestEnrolledNames', - full_name='Anki.Vector.external_interface.ExternalInterface.RequestEnrolledNames', - index=12, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._REQUESTENROLLEDNAMESREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._REQUESTENROLLEDNAMESRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\037\"\032/v1/request_enrolled_names:\001*')), - ), - _descriptor.MethodDescriptor( - name='UpdateEnrolledFaceByID', - full_name='Anki.Vector.external_interface.ExternalInterface.UpdateEnrolledFaceByID', - index=13, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._UPDATEENROLLEDFACEBYIDREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._UPDATEENROLLEDFACEBYIDRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002#\"\036/v1/update_enrolled_face_by_id:\001*')), - ), - _descriptor.MethodDescriptor( - name='EraseEnrolledFaceByID', - full_name='Anki.Vector.external_interface.ExternalInterface.EraseEnrolledFaceByID', - index=14, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._ERASEENROLLEDFACEBYIDREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._ERASEENROLLEDFACEBYIDRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\"\"\035/v1/erase_enrolled_face_by_id:\001*')), - ), - _descriptor.MethodDescriptor( - name='EraseAllEnrolledFaces', - full_name='Anki.Vector.external_interface.ExternalInterface.EraseAllEnrolledFaces', - index=15, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._ERASEALLENROLLEDFACESREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._ERASEALLENROLLEDFACESRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002!\"\034/v1/erase_all_enrolled_faces:\001*')), - ), - _descriptor.MethodDescriptor( - name='SetFaceToEnroll', - full_name='Anki.Vector.external_interface.ExternalInterface.SetFaceToEnroll', - index=16, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._SETFACETOENROLLREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._SETFACETOENROLLRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\033\"\026/v1/set_face_to_enroll:\001*')), - ), - _descriptor.MethodDescriptor( - name='EnableMarkerDetection', - full_name='Anki.Vector.external_interface.ExternalInterface.EnableMarkerDetection', - index=17, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._ENABLEMARKERDETECTIONREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._ENABLEMARKERDETECTIONRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002 \"\033/v1/enable_marker_detection:\001*')), - ), - _descriptor.MethodDescriptor( - name='EnableFaceDetection', - full_name='Anki.Vector.external_interface.ExternalInterface.EnableFaceDetection', - index=18, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._ENABLEFACEDETECTIONREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._ENABLEFACEDETECTIONRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\036\"\031/v1/enable_face_detection:\001*')), - ), - _descriptor.MethodDescriptor( - name='EnableMotionDetection', - full_name='Anki.Vector.external_interface.ExternalInterface.EnableMotionDetection', - index=19, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._ENABLEMOTIONDETECTIONREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._ENABLEMOTIONDETECTIONRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002 \"\033/v1/enable_motion_detection:\001*')), - ), - _descriptor.MethodDescriptor( - name='EnableMirrorMode', - full_name='Anki.Vector.external_interface.ExternalInterface.EnableMirrorMode', - index=20, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._ENABLEMIRRORMODEREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._ENABLEMIRRORMODERESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\033\"\026/v1/enable_mirror_mode:\001*')), - ), - _descriptor.MethodDescriptor( - name='EnableImageStreaming', - full_name='Anki.Vector.external_interface.ExternalInterface.EnableImageStreaming', - index=21, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._ENABLEIMAGESTREAMINGREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._ENABLEIMAGESTREAMINGRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\037\"\032/v1/enable_image_streaming:\001*')), - ), - _descriptor.MethodDescriptor( - name='GoToPose', - full_name='Anki.Vector.external_interface.ExternalInterface.GoToPose', - index=22, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._GOTOPOSEREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._GOTOPOSERESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\023\"\016/v1/go_to_pose:\001*')), - ), - _descriptor.MethodDescriptor( - name='DockWithCube', - full_name='Anki.Vector.external_interface.ExternalInterface.DockWithCube', - index=23, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._DOCKWITHCUBEREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._DOCKWITHCUBERESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\027\"\022/v1/dock_with_cube:\001*')), - ), - _descriptor.MethodDescriptor( - name='DriveOffCharger', - full_name='Anki.Vector.external_interface.ExternalInterface.DriveOffCharger', - index=24, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._DRIVEOFFCHARGERREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._DRIVEOFFCHARGERRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\032\"\025/v1/drive_off_charger:\001*')), - ), - _descriptor.MethodDescriptor( - name='DriveOnCharger', - full_name='Anki.Vector.external_interface.ExternalInterface.DriveOnCharger', - index=25, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._DRIVEONCHARGERREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._DRIVEONCHARGERRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\031\"\024/v1/drive_on_charger:\001*')), - ), - _descriptor.MethodDescriptor( - name='PhotosInfo', - full_name='Anki.Vector.external_interface.ExternalInterface.PhotosInfo', - index=26, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._PHOTOSINFOREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._PHOTOSINFORESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\024\"\017/v1/photos_info:\001*')), - ), - _descriptor.MethodDescriptor( - name='Photo', - full_name='Anki.Vector.external_interface.ExternalInterface.Photo', - index=27, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._PHOTOREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._PHOTORESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\016\"\t/v1/photo:\001*')), - ), - _descriptor.MethodDescriptor( - name='Thumbnail', - full_name='Anki.Vector.external_interface.ExternalInterface.Thumbnail', - index=28, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._THUMBNAILREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._THUMBNAILRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\022\"\r/v1/thumbnail:\001*')), - ), - _descriptor.MethodDescriptor( - name='DeletePhoto', - full_name='Anki.Vector.external_interface.ExternalInterface.DeletePhoto', - index=29, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._DELETEPHOTOREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._DELETEPHOTORESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\025\"\020/v1/delete_photo:\001*')), - ), - _descriptor.MethodDescriptor( - name='DriveStraight', - full_name='Anki.Vector.external_interface.ExternalInterface.DriveStraight', - index=30, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._DRIVESTRAIGHTREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._DRIVESTRAIGHTRESPONSE, - options=None, - ), - _descriptor.MethodDescriptor( - name='TurnInPlace', - full_name='Anki.Vector.external_interface.ExternalInterface.TurnInPlace', - index=31, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._TURNINPLACEREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._TURNINPLACERESPONSE, - options=None, - ), - _descriptor.MethodDescriptor( - name='SetHeadAngle', - full_name='Anki.Vector.external_interface.ExternalInterface.SetHeadAngle', - index=32, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._SETHEADANGLEREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._SETHEADANGLERESPONSE, - options=None, - ), - _descriptor.MethodDescriptor( - name='SetLiftHeight', - full_name='Anki.Vector.external_interface.ExternalInterface.SetLiftHeight', - index=33, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._SETLIFTHEIGHTREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._SETLIFTHEIGHTRESPONSE, - options=None, - ), - _descriptor.MethodDescriptor( - name='UserAuthentication', - full_name='Anki.Vector.external_interface.ExternalInterface.UserAuthentication', - index=34, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_shared__pb2._USERAUTHENTICATIONREQUEST, - output_type=anki__vector_dot_messaging_dot_shared__pb2._USERAUTHENTICATIONRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\034\"\027/v1/user_authentication:\001*')), - ), - _descriptor.MethodDescriptor( - name='BatteryState', - full_name='Anki.Vector.external_interface.ExternalInterface.BatteryState', - index=35, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._BATTERYSTATEREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._BATTERYSTATERESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\026\"\021/v1/battery_state:\001*')), - ), - _descriptor.MethodDescriptor( - name='VersionState', - full_name='Anki.Vector.external_interface.ExternalInterface.VersionState', - index=36, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._VERSIONSTATEREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._VERSIONSTATERESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\026\"\021/v1/version_state:\001*')), - ), - _descriptor.MethodDescriptor( - name='NetworkState', - full_name='Anki.Vector.external_interface.ExternalInterface.NetworkState', - index=37, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._NETWORKSTATEREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._NETWORKSTATERESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\026\"\021/v1/network_state:\001*')), - ), - _descriptor.MethodDescriptor( - name='SayText', - full_name='Anki.Vector.external_interface.ExternalInterface.SayText', - index=38, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._SAYTEXTREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._SAYTEXTRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\021\"\014/v1/say_text:\001*')), - ), - _descriptor.MethodDescriptor( - name='ConnectCube', - full_name='Anki.Vector.external_interface.ExternalInterface.ConnectCube', - index=39, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_cube__pb2._CONNECTCUBEREQUEST, - output_type=anki__vector_dot_messaging_dot_cube__pb2._CONNECTCUBERESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\025\"\020/v1/connect_cube:\001*')), - ), - _descriptor.MethodDescriptor( - name='DisconnectCube', - full_name='Anki.Vector.external_interface.ExternalInterface.DisconnectCube', - index=40, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_cube__pb2._DISCONNECTCUBEREQUEST, - output_type=anki__vector_dot_messaging_dot_cube__pb2._DISCONNECTCUBERESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\030\"\023/v1/disconnect_cube:\001*')), - ), - _descriptor.MethodDescriptor( - name='CubesAvailable', - full_name='Anki.Vector.external_interface.ExternalInterface.CubesAvailable', - index=41, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_cube__pb2._CUBESAVAILABLEREQUEST, - output_type=anki__vector_dot_messaging_dot_cube__pb2._CUBESAVAILABLERESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\030\"\023/v1/cubes_available:\001*')), - ), - _descriptor.MethodDescriptor( - name='FlashCubeLights', - full_name='Anki.Vector.external_interface.ExternalInterface.FlashCubeLights', - index=42, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_cube__pb2._FLASHCUBELIGHTSREQUEST, - output_type=anki__vector_dot_messaging_dot_cube__pb2._FLASHCUBELIGHTSRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\032\"\025/v1/flash_cube_lights:\001*')), - ), - _descriptor.MethodDescriptor( - name='ForgetPreferredCube', - full_name='Anki.Vector.external_interface.ExternalInterface.ForgetPreferredCube', - index=43, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_cube__pb2._FORGETPREFERREDCUBEREQUEST, - output_type=anki__vector_dot_messaging_dot_cube__pb2._FORGETPREFERREDCUBERESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\036\"\031/v1/forget_preferred_cube:\001*')), - ), - _descriptor.MethodDescriptor( - name='SetPreferredCube', - full_name='Anki.Vector.external_interface.ExternalInterface.SetPreferredCube', - index=44, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_cube__pb2._SETPREFERREDCUBEREQUEST, - output_type=anki__vector_dot_messaging_dot_cube__pb2._SETPREFERREDCUBERESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\033\"\026/v1/set_preferred_cube:\001*')), - ), - _descriptor.MethodDescriptor( - name='DeleteCustomObjects', - full_name='Anki.Vector.external_interface.ExternalInterface.DeleteCustomObjects', - index=45, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_cube__pb2._DELETECUSTOMOBJECTSREQUEST, - output_type=anki__vector_dot_messaging_dot_cube__pb2._DELETECUSTOMOBJECTSRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\036\"\031/v1/delete_custom_objects:\001*')), - ), - _descriptor.MethodDescriptor( - name='CreateFixedCustomObject', - full_name='Anki.Vector.external_interface.ExternalInterface.CreateFixedCustomObject', - index=46, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_cube__pb2._CREATEFIXEDCUSTOMOBJECTREQUEST, - output_type=anki__vector_dot_messaging_dot_cube__pb2._CREATEFIXEDCUSTOMOBJECTRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002#\"\036/v1/create_fixed_custom_object:\001*')), - ), - _descriptor.MethodDescriptor( - name='DefineCustomObject', - full_name='Anki.Vector.external_interface.ExternalInterface.DefineCustomObject', - index=47, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_cube__pb2._DEFINECUSTOMOBJECTREQUEST, - output_type=anki__vector_dot_messaging_dot_cube__pb2._DEFINECUSTOMOBJECTRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\035\"\030/v1/define_custom_object:\001*')), - ), - _descriptor.MethodDescriptor( - name='SetCubeLights', - full_name='Anki.Vector.external_interface.ExternalInterface.SetCubeLights', - index=48, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_cube__pb2._SETCUBELIGHTSREQUEST, - output_type=anki__vector_dot_messaging_dot_cube__pb2._SETCUBELIGHTSRESPONSE, - options=None, - ), - _descriptor.MethodDescriptor( - name='AudioFeed', - full_name='Anki.Vector.external_interface.ExternalInterface.AudioFeed', - index=49, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._AUDIOFEEDREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._AUDIOFEEDRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\023\"\016/v1/audio_feed:\001*')), - ), - _descriptor.MethodDescriptor( - name='CameraFeed', - full_name='Anki.Vector.external_interface.ExternalInterface.CameraFeed', - index=50, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._CAMERAFEEDREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._CAMERAFEEDRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\024\"\017/v1/camera_feed:\001*')), - ), - _descriptor.MethodDescriptor( - name='SetEyeColor', - full_name='Anki.Vector.external_interface.ExternalInterface.SetEyeColor', - index=51, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_messages__pb2._SETEYECOLORREQUEST, - output_type=anki__vector_dot_messaging_dot_messages__pb2._SETEYECOLORRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\026\"\021/v1/set_eye_color:\001*')), - ), - _descriptor.MethodDescriptor( - name='NavMapFeed', - full_name='Anki.Vector.external_interface.ExternalInterface.NavMapFeed', - index=52, - containing_service=None, - input_type=anki__vector_dot_messaging_dot_nav__map__pb2._NAVMAPFEEDREQUEST, - output_type=anki__vector_dot_messaging_dot_nav__map__pb2._NAVMAPFEEDRESPONSE, - options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\025\"\020/v1/nav_map_feed:\001*')), - ), -]) -_sym_db.RegisterServiceDescriptor(_EXTERNALINTERFACE) - -DESCRIPTOR.services_by_name['ExternalInterface'] = _EXTERNALINTERFACE - -# @@protoc_insertion_point(module_scope) diff --git a/anki_vector/messaging/external_interface_pb2_grpc.py b/anki_vector/messaging/external_interface_pb2_grpc.py deleted file mode 100644 index 6f3ed72..0000000 --- a/anki_vector/messaging/external_interface_pb2_grpc.py +++ /dev/null @@ -1,944 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - -from anki_vector.messaging import behavior_pb2 as anki__vector_dot_messaging_dot_behavior__pb2 -from anki_vector.messaging import cube_pb2 as anki__vector_dot_messaging_dot_cube__pb2 -from anki_vector.messaging import messages_pb2 as anki__vector_dot_messaging_dot_messages__pb2 -from anki_vector.messaging import nav_map_pb2 as anki__vector_dot_messaging_dot_nav__map__pb2 -from anki_vector.messaging import shared_pb2 as anki__vector_dot_messaging_dot_shared__pb2 - - -class ExternalInterfaceStub(object): - """The grpc-defined connection between the SDK and Anki's Vector robot. - """ - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.ProtocolVersion = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/ProtocolVersion', - request_serializer=anki__vector_dot_messaging_dot_shared__pb2.ProtocolVersionRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_shared__pb2.ProtocolVersionResponse.FromString, - ) - self.SDKInitialization = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/SDKInitialization', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.SDKInitializationRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.SDKInitializationResponse.FromString, - ) - self.DriveWheels = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/DriveWheels', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.DriveWheelsRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.DriveWheelsResponse.FromString, - ) - self.PlayAnimation = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/PlayAnimation', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.PlayAnimationRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.PlayAnimationResponse.FromString, - ) - self.ListAnimations = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/ListAnimations', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.ListAnimationsRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.ListAnimationsResponse.FromString, - ) - self.MoveHead = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/MoveHead', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.MoveHeadRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.MoveHeadResponse.FromString, - ) - self.MoveLift = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/MoveLift', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.MoveLiftRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.MoveLiftResponse.FromString, - ) - self.DisplayFaceImageRGB = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/DisplayFaceImageRGB', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.DisplayFaceImageRGBRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.DisplayFaceImageRGBResponse.FromString, - ) - self.EventStream = channel.unary_stream( - '/Anki.Vector.external_interface.ExternalInterface/EventStream', - request_serializer=anki__vector_dot_messaging_dot_shared__pb2.EventRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_shared__pb2.EventResponse.FromString, - ) - self.BehaviorControl = channel.stream_stream( - '/Anki.Vector.external_interface.ExternalInterface/BehaviorControl', - request_serializer=anki__vector_dot_messaging_dot_behavior__pb2.BehaviorControlRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_behavior__pb2.BehaviorControlResponse.FromString, - ) - self.AssumeBehaviorControl = channel.unary_stream( - '/Anki.Vector.external_interface.ExternalInterface/AssumeBehaviorControl', - request_serializer=anki__vector_dot_messaging_dot_behavior__pb2.BehaviorControlRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_behavior__pb2.BehaviorControlResponse.FromString, - ) - self.CancelFaceEnrollment = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/CancelFaceEnrollment', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.CancelFaceEnrollmentRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.CancelFaceEnrollmentResponse.FromString, - ) - self.RequestEnrolledNames = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/RequestEnrolledNames', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.RequestEnrolledNamesRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.RequestEnrolledNamesResponse.FromString, - ) - self.UpdateEnrolledFaceByID = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/UpdateEnrolledFaceByID', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.UpdateEnrolledFaceByIDRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.UpdateEnrolledFaceByIDResponse.FromString, - ) - self.EraseEnrolledFaceByID = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/EraseEnrolledFaceByID', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.EraseEnrolledFaceByIDRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.EraseEnrolledFaceByIDResponse.FromString, - ) - self.EraseAllEnrolledFaces = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/EraseAllEnrolledFaces', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.EraseAllEnrolledFacesRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.EraseAllEnrolledFacesResponse.FromString, - ) - self.SetFaceToEnroll = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/SetFaceToEnroll', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.SetFaceToEnrollRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.SetFaceToEnrollResponse.FromString, - ) - self.EnableMarkerDetection = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/EnableMarkerDetection', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.EnableMarkerDetectionRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.EnableMarkerDetectionResponse.FromString, - ) - self.EnableFaceDetection = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/EnableFaceDetection', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.EnableFaceDetectionRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.EnableFaceDetectionResponse.FromString, - ) - self.EnableMotionDetection = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/EnableMotionDetection', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.EnableMotionDetectionRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.EnableMotionDetectionResponse.FromString, - ) - self.EnableMirrorMode = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/EnableMirrorMode', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.EnableMirrorModeRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.EnableMirrorModeResponse.FromString, - ) - self.EnableImageStreaming = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/EnableImageStreaming', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.EnableImageStreamingRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.EnableImageStreamingResponse.FromString, - ) - self.GoToPose = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/GoToPose', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.GoToPoseRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.GoToPoseResponse.FromString, - ) - self.DockWithCube = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/DockWithCube', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.DockWithCubeRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.DockWithCubeResponse.FromString, - ) - self.DriveOffCharger = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/DriveOffCharger', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.DriveOffChargerRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.DriveOffChargerResponse.FromString, - ) - self.DriveOnCharger = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/DriveOnCharger', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.DriveOnChargerRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.DriveOnChargerResponse.FromString, - ) - self.PhotosInfo = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/PhotosInfo', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.PhotosInfoRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.PhotosInfoResponse.FromString, - ) - self.Photo = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/Photo', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.PhotoRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.PhotoResponse.FromString, - ) - self.Thumbnail = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/Thumbnail', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.ThumbnailRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.ThumbnailResponse.FromString, - ) - self.DeletePhoto = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/DeletePhoto', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.DeletePhotoRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.DeletePhotoResponse.FromString, - ) - self.DriveStraight = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/DriveStraight', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.DriveStraightRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.DriveStraightResponse.FromString, - ) - self.TurnInPlace = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/TurnInPlace', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.TurnInPlaceRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.TurnInPlaceResponse.FromString, - ) - self.SetHeadAngle = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/SetHeadAngle', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.SetHeadAngleRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.SetHeadAngleResponse.FromString, - ) - self.SetLiftHeight = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/SetLiftHeight', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.SetLiftHeightRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.SetLiftHeightResponse.FromString, - ) - self.UserAuthentication = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/UserAuthentication', - request_serializer=anki__vector_dot_messaging_dot_shared__pb2.UserAuthenticationRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_shared__pb2.UserAuthenticationResponse.FromString, - ) - self.BatteryState = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/BatteryState', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.BatteryStateRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.BatteryStateResponse.FromString, - ) - self.VersionState = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/VersionState', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.VersionStateRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.VersionStateResponse.FromString, - ) - self.NetworkState = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/NetworkState', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.NetworkStateRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.NetworkStateResponse.FromString, - ) - self.SayText = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/SayText', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.SayTextRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.SayTextResponse.FromString, - ) - self.ConnectCube = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/ConnectCube', - request_serializer=anki__vector_dot_messaging_dot_cube__pb2.ConnectCubeRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_cube__pb2.ConnectCubeResponse.FromString, - ) - self.DisconnectCube = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/DisconnectCube', - request_serializer=anki__vector_dot_messaging_dot_cube__pb2.DisconnectCubeRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_cube__pb2.DisconnectCubeResponse.FromString, - ) - self.CubesAvailable = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/CubesAvailable', - request_serializer=anki__vector_dot_messaging_dot_cube__pb2.CubesAvailableRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_cube__pb2.CubesAvailableResponse.FromString, - ) - self.FlashCubeLights = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/FlashCubeLights', - request_serializer=anki__vector_dot_messaging_dot_cube__pb2.FlashCubeLightsRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_cube__pb2.FlashCubeLightsResponse.FromString, - ) - self.ForgetPreferredCube = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/ForgetPreferredCube', - request_serializer=anki__vector_dot_messaging_dot_cube__pb2.ForgetPreferredCubeRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_cube__pb2.ForgetPreferredCubeResponse.FromString, - ) - self.SetPreferredCube = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/SetPreferredCube', - request_serializer=anki__vector_dot_messaging_dot_cube__pb2.SetPreferredCubeRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_cube__pb2.SetPreferredCubeResponse.FromString, - ) - self.DeleteCustomObjects = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/DeleteCustomObjects', - request_serializer=anki__vector_dot_messaging_dot_cube__pb2.DeleteCustomObjectsRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_cube__pb2.DeleteCustomObjectsResponse.FromString, - ) - self.CreateFixedCustomObject = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/CreateFixedCustomObject', - request_serializer=anki__vector_dot_messaging_dot_cube__pb2.CreateFixedCustomObjectRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_cube__pb2.CreateFixedCustomObjectResponse.FromString, - ) - self.DefineCustomObject = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/DefineCustomObject', - request_serializer=anki__vector_dot_messaging_dot_cube__pb2.DefineCustomObjectRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_cube__pb2.DefineCustomObjectResponse.FromString, - ) - self.SetCubeLights = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/SetCubeLights', - request_serializer=anki__vector_dot_messaging_dot_cube__pb2.SetCubeLightsRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_cube__pb2.SetCubeLightsResponse.FromString, - ) - self.AudioFeed = channel.unary_stream( - '/Anki.Vector.external_interface.ExternalInterface/AudioFeed', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.AudioFeedRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.AudioFeedResponse.FromString, - ) - self.CameraFeed = channel.unary_stream( - '/Anki.Vector.external_interface.ExternalInterface/CameraFeed', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.CameraFeedRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.CameraFeedResponse.FromString, - ) - self.SetEyeColor = channel.unary_unary( - '/Anki.Vector.external_interface.ExternalInterface/SetEyeColor', - request_serializer=anki__vector_dot_messaging_dot_messages__pb2.SetEyeColorRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_messages__pb2.SetEyeColorResponse.FromString, - ) - self.NavMapFeed = channel.unary_stream( - '/Anki.Vector.external_interface.ExternalInterface/NavMapFeed', - request_serializer=anki__vector_dot_messaging_dot_nav__map__pb2.NavMapFeedRequest.SerializeToString, - response_deserializer=anki__vector_dot_messaging_dot_nav__map__pb2.NavMapFeedResponse.FromString, - ) - - -class ExternalInterfaceServicer(object): - """The grpc-defined connection between the SDK and Anki's Vector robot. - """ - - def ProtocolVersion(self, request, context): - """Checks the supported protocol version by passing in the client version and - minimum host version and receiving a response to see whether the versions are supported. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SDKInitialization(self, request, context): - """SDK-only message to pass version info for device OS, Python version, etc. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DriveWheels(self, request, context): - """Sets the speed and acceleration for Vector's wheel motors. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def PlayAnimation(self, request, context): - """Requests that Vector play an animation. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListAnimations(self, request, context): - """Constructs and returns a list of animations. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def MoveHead(self, request, context): - """Moves Vector's head. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def MoveLift(self, request, context): - """Moves Vector's lift. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DisplayFaceImageRGB(self, request, context): - """Sets screen (Vector's face) to a solid color. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def EventStream(self, request, context): - """Streaming events endpoint - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def BehaviorControl(self, request_iterator, context): - """Integrate with and acquire control of Vector's AI system. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def AssumeBehaviorControl(self, request, context): - """Acquire control of Vector's AI system. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def CancelFaceEnrollment(self, request, context): - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def RequestEnrolledNames(self, request, context): - """Get a list of names and their IDs. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def UpdateEnrolledFaceByID(self, request, context): - """Update the name enrolled for a given face. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def EraseEnrolledFaceByID(self, request, context): - """Erase the enrollment (name) record for the face with this ID. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def EraseAllEnrolledFaces(self, request, context): - """Erase the enrollment (name) records for all faces. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SetFaceToEnroll(self, request, context): - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def EnableMarkerDetection(self, request, context): - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def EnableFaceDetection(self, request, context): - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def EnableMotionDetection(self, request, context): - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def EnableMirrorMode(self, request, context): - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def EnableImageStreaming(self, request, context): - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GoToPose(self, request, context): - """Tells Vector to drive to the specified pose and orientation. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DockWithCube(self, request, context): - """Tells Vector to dock with a light cube with a given approach angle and distance. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DriveOffCharger(self, request, context): - """Drive Vector off the charger. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DriveOnCharger(self, request, context): - """Drive Vector onto the charger. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def PhotosInfo(self, request, context): - """Get the photos info. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def Photo(self, request, context): - """Get a photo by ID. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def Thumbnail(self, request, context): - """Get a thumbnail by ID. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeletePhoto(self, request, context): - """Delete a photo by ID. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DriveStraight(self, request, context): - """Tells Vector to drive in a straight line. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def TurnInPlace(self, request, context): - """Turn the robot around its current position. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SetHeadAngle(self, request, context): - """Tell Vector's head to move to a given angle. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SetLiftHeight(self, request, context): - """Tell Vector's lift to move to a given height. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def UserAuthentication(self, request, context): - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def BatteryState(self, request, context): - """Check the current state of the battery. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def VersionState(self, request, context): - """Get the versioning information for Vector. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def NetworkState(self, request, context): - """Get the network information for Vector. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SayText(self, request, context): - """Make Vector speak text. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ConnectCube(self, request, context): - """Attempt to connect to a cube. If a cube is currently connected, - this will do nothing. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DisconnectCube(self, request, context): - """Requests a disconnection from the currently connected cube. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def CubesAvailable(self, request, context): - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def FlashCubeLights(self, request, context): - """Signal a connected cube to flash its lights using the default cube - flash animation. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ForgetPreferredCube(self, request, context): - """Forget the robot's preferred cube. This will cause the robot to - connect to the cube with the highest RSSI (signal strength) next - time a connection is requested. Saves this preference to disk. - The next cube that the robot connects to will become its - preferred cube. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SetPreferredCube(self, request, context): - """Set the robot's preferred cube and save it to disk. The robot - will always attempt to connect to this cube if it is available. - This is only used in simulation for now. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteCustomObjects(self, request, context): - """Causes the robot to forget about custom objects it currently knows about. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def CreateFixedCustomObject(self, request, context): - """Creates a permanent custom object instance in the robot's world, with no connection to the vision system. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DefineCustomObject(self, request, context): - """Creates a custom object with distinct custom marker(s). - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SetCubeLights(self, request, context): - """Set each of the lights on the currently connected cube based on two - rgb values each and timing data for how to transition between them. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def AudioFeed(self, request, context): - """Request an audio feed from the robot. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def CameraFeed(self, request, context): - """Request a camera feed from the robot. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SetEyeColor(self, request, context): - """Set Vector's eye color. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def NavMapFeed(self, request, context): - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_ExternalInterfaceServicer_to_server(servicer, server): - rpc_method_handlers = { - 'ProtocolVersion': grpc.unary_unary_rpc_method_handler( - servicer.ProtocolVersion, - request_deserializer=anki__vector_dot_messaging_dot_shared__pb2.ProtocolVersionRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_shared__pb2.ProtocolVersionResponse.SerializeToString, - ), - 'SDKInitialization': grpc.unary_unary_rpc_method_handler( - servicer.SDKInitialization, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.SDKInitializationRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.SDKInitializationResponse.SerializeToString, - ), - 'DriveWheels': grpc.unary_unary_rpc_method_handler( - servicer.DriveWheels, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.DriveWheelsRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.DriveWheelsResponse.SerializeToString, - ), - 'PlayAnimation': grpc.unary_unary_rpc_method_handler( - servicer.PlayAnimation, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.PlayAnimationRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.PlayAnimationResponse.SerializeToString, - ), - 'ListAnimations': grpc.unary_unary_rpc_method_handler( - servicer.ListAnimations, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.ListAnimationsRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.ListAnimationsResponse.SerializeToString, - ), - 'MoveHead': grpc.unary_unary_rpc_method_handler( - servicer.MoveHead, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.MoveHeadRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.MoveHeadResponse.SerializeToString, - ), - 'MoveLift': grpc.unary_unary_rpc_method_handler( - servicer.MoveLift, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.MoveLiftRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.MoveLiftResponse.SerializeToString, - ), - 'DisplayFaceImageRGB': grpc.unary_unary_rpc_method_handler( - servicer.DisplayFaceImageRGB, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.DisplayFaceImageRGBRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.DisplayFaceImageRGBResponse.SerializeToString, - ), - 'EventStream': grpc.unary_stream_rpc_method_handler( - servicer.EventStream, - request_deserializer=anki__vector_dot_messaging_dot_shared__pb2.EventRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_shared__pb2.EventResponse.SerializeToString, - ), - 'BehaviorControl': grpc.stream_stream_rpc_method_handler( - servicer.BehaviorControl, - request_deserializer=anki__vector_dot_messaging_dot_behavior__pb2.BehaviorControlRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_behavior__pb2.BehaviorControlResponse.SerializeToString, - ), - 'AssumeBehaviorControl': grpc.unary_stream_rpc_method_handler( - servicer.AssumeBehaviorControl, - request_deserializer=anki__vector_dot_messaging_dot_behavior__pb2.BehaviorControlRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_behavior__pb2.BehaviorControlResponse.SerializeToString, - ), - 'CancelFaceEnrollment': grpc.unary_unary_rpc_method_handler( - servicer.CancelFaceEnrollment, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.CancelFaceEnrollmentRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.CancelFaceEnrollmentResponse.SerializeToString, - ), - 'RequestEnrolledNames': grpc.unary_unary_rpc_method_handler( - servicer.RequestEnrolledNames, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.RequestEnrolledNamesRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.RequestEnrolledNamesResponse.SerializeToString, - ), - 'UpdateEnrolledFaceByID': grpc.unary_unary_rpc_method_handler( - servicer.UpdateEnrolledFaceByID, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.UpdateEnrolledFaceByIDRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.UpdateEnrolledFaceByIDResponse.SerializeToString, - ), - 'EraseEnrolledFaceByID': grpc.unary_unary_rpc_method_handler( - servicer.EraseEnrolledFaceByID, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.EraseEnrolledFaceByIDRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.EraseEnrolledFaceByIDResponse.SerializeToString, - ), - 'EraseAllEnrolledFaces': grpc.unary_unary_rpc_method_handler( - servicer.EraseAllEnrolledFaces, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.EraseAllEnrolledFacesRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.EraseAllEnrolledFacesResponse.SerializeToString, - ), - 'SetFaceToEnroll': grpc.unary_unary_rpc_method_handler( - servicer.SetFaceToEnroll, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.SetFaceToEnrollRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.SetFaceToEnrollResponse.SerializeToString, - ), - 'EnableMarkerDetection': grpc.unary_unary_rpc_method_handler( - servicer.EnableMarkerDetection, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.EnableMarkerDetectionRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.EnableMarkerDetectionResponse.SerializeToString, - ), - 'EnableFaceDetection': grpc.unary_unary_rpc_method_handler( - servicer.EnableFaceDetection, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.EnableFaceDetectionRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.EnableFaceDetectionResponse.SerializeToString, - ), - 'EnableMotionDetection': grpc.unary_unary_rpc_method_handler( - servicer.EnableMotionDetection, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.EnableMotionDetectionRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.EnableMotionDetectionResponse.SerializeToString, - ), - 'EnableMirrorMode': grpc.unary_unary_rpc_method_handler( - servicer.EnableMirrorMode, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.EnableMirrorModeRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.EnableMirrorModeResponse.SerializeToString, - ), - 'EnableImageStreaming': grpc.unary_unary_rpc_method_handler( - servicer.EnableImageStreaming, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.EnableImageStreamingRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.EnableImageStreamingResponse.SerializeToString, - ), - 'GoToPose': grpc.unary_unary_rpc_method_handler( - servicer.GoToPose, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.GoToPoseRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.GoToPoseResponse.SerializeToString, - ), - 'DockWithCube': grpc.unary_unary_rpc_method_handler( - servicer.DockWithCube, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.DockWithCubeRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.DockWithCubeResponse.SerializeToString, - ), - 'DriveOffCharger': grpc.unary_unary_rpc_method_handler( - servicer.DriveOffCharger, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.DriveOffChargerRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.DriveOffChargerResponse.SerializeToString, - ), - 'DriveOnCharger': grpc.unary_unary_rpc_method_handler( - servicer.DriveOnCharger, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.DriveOnChargerRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.DriveOnChargerResponse.SerializeToString, - ), - 'PhotosInfo': grpc.unary_unary_rpc_method_handler( - servicer.PhotosInfo, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.PhotosInfoRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.PhotosInfoResponse.SerializeToString, - ), - 'Photo': grpc.unary_unary_rpc_method_handler( - servicer.Photo, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.PhotoRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.PhotoResponse.SerializeToString, - ), - 'Thumbnail': grpc.unary_unary_rpc_method_handler( - servicer.Thumbnail, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.ThumbnailRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.ThumbnailResponse.SerializeToString, - ), - 'DeletePhoto': grpc.unary_unary_rpc_method_handler( - servicer.DeletePhoto, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.DeletePhotoRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.DeletePhotoResponse.SerializeToString, - ), - 'DriveStraight': grpc.unary_unary_rpc_method_handler( - servicer.DriveStraight, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.DriveStraightRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.DriveStraightResponse.SerializeToString, - ), - 'TurnInPlace': grpc.unary_unary_rpc_method_handler( - servicer.TurnInPlace, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.TurnInPlaceRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.TurnInPlaceResponse.SerializeToString, - ), - 'SetHeadAngle': grpc.unary_unary_rpc_method_handler( - servicer.SetHeadAngle, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.SetHeadAngleRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.SetHeadAngleResponse.SerializeToString, - ), - 'SetLiftHeight': grpc.unary_unary_rpc_method_handler( - servicer.SetLiftHeight, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.SetLiftHeightRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.SetLiftHeightResponse.SerializeToString, - ), - 'UserAuthentication': grpc.unary_unary_rpc_method_handler( - servicer.UserAuthentication, - request_deserializer=anki__vector_dot_messaging_dot_shared__pb2.UserAuthenticationRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_shared__pb2.UserAuthenticationResponse.SerializeToString, - ), - 'BatteryState': grpc.unary_unary_rpc_method_handler( - servicer.BatteryState, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.BatteryStateRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.BatteryStateResponse.SerializeToString, - ), - 'VersionState': grpc.unary_unary_rpc_method_handler( - servicer.VersionState, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.VersionStateRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.VersionStateResponse.SerializeToString, - ), - 'NetworkState': grpc.unary_unary_rpc_method_handler( - servicer.NetworkState, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.NetworkStateRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.NetworkStateResponse.SerializeToString, - ), - 'SayText': grpc.unary_unary_rpc_method_handler( - servicer.SayText, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.SayTextRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.SayTextResponse.SerializeToString, - ), - 'ConnectCube': grpc.unary_unary_rpc_method_handler( - servicer.ConnectCube, - request_deserializer=anki__vector_dot_messaging_dot_cube__pb2.ConnectCubeRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_cube__pb2.ConnectCubeResponse.SerializeToString, - ), - 'DisconnectCube': grpc.unary_unary_rpc_method_handler( - servicer.DisconnectCube, - request_deserializer=anki__vector_dot_messaging_dot_cube__pb2.DisconnectCubeRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_cube__pb2.DisconnectCubeResponse.SerializeToString, - ), - 'CubesAvailable': grpc.unary_unary_rpc_method_handler( - servicer.CubesAvailable, - request_deserializer=anki__vector_dot_messaging_dot_cube__pb2.CubesAvailableRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_cube__pb2.CubesAvailableResponse.SerializeToString, - ), - 'FlashCubeLights': grpc.unary_unary_rpc_method_handler( - servicer.FlashCubeLights, - request_deserializer=anki__vector_dot_messaging_dot_cube__pb2.FlashCubeLightsRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_cube__pb2.FlashCubeLightsResponse.SerializeToString, - ), - 'ForgetPreferredCube': grpc.unary_unary_rpc_method_handler( - servicer.ForgetPreferredCube, - request_deserializer=anki__vector_dot_messaging_dot_cube__pb2.ForgetPreferredCubeRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_cube__pb2.ForgetPreferredCubeResponse.SerializeToString, - ), - 'SetPreferredCube': grpc.unary_unary_rpc_method_handler( - servicer.SetPreferredCube, - request_deserializer=anki__vector_dot_messaging_dot_cube__pb2.SetPreferredCubeRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_cube__pb2.SetPreferredCubeResponse.SerializeToString, - ), - 'DeleteCustomObjects': grpc.unary_unary_rpc_method_handler( - servicer.DeleteCustomObjects, - request_deserializer=anki__vector_dot_messaging_dot_cube__pb2.DeleteCustomObjectsRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_cube__pb2.DeleteCustomObjectsResponse.SerializeToString, - ), - 'CreateFixedCustomObject': grpc.unary_unary_rpc_method_handler( - servicer.CreateFixedCustomObject, - request_deserializer=anki__vector_dot_messaging_dot_cube__pb2.CreateFixedCustomObjectRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_cube__pb2.CreateFixedCustomObjectResponse.SerializeToString, - ), - 'DefineCustomObject': grpc.unary_unary_rpc_method_handler( - servicer.DefineCustomObject, - request_deserializer=anki__vector_dot_messaging_dot_cube__pb2.DefineCustomObjectRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_cube__pb2.DefineCustomObjectResponse.SerializeToString, - ), - 'SetCubeLights': grpc.unary_unary_rpc_method_handler( - servicer.SetCubeLights, - request_deserializer=anki__vector_dot_messaging_dot_cube__pb2.SetCubeLightsRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_cube__pb2.SetCubeLightsResponse.SerializeToString, - ), - 'AudioFeed': grpc.unary_stream_rpc_method_handler( - servicer.AudioFeed, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.AudioFeedRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.AudioFeedResponse.SerializeToString, - ), - 'CameraFeed': grpc.unary_stream_rpc_method_handler( - servicer.CameraFeed, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.CameraFeedRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.CameraFeedResponse.SerializeToString, - ), - 'SetEyeColor': grpc.unary_unary_rpc_method_handler( - servicer.SetEyeColor, - request_deserializer=anki__vector_dot_messaging_dot_messages__pb2.SetEyeColorRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_messages__pb2.SetEyeColorResponse.SerializeToString, - ), - 'NavMapFeed': grpc.unary_stream_rpc_method_handler( - servicer.NavMapFeed, - request_deserializer=anki__vector_dot_messaging_dot_nav__map__pb2.NavMapFeedRequest.FromString, - response_serializer=anki__vector_dot_messaging_dot_nav__map__pb2.NavMapFeedResponse.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'Anki.Vector.external_interface.ExternalInterface', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) diff --git a/anki_vector/messaging/messages.proto b/anki_vector/messaging/messages.proto deleted file mode 100644 index 5792cbe..0000000 --- a/anki_vector/messaging/messages.proto +++ /dev/null @@ -1,920 +0,0 @@ -// Copyright (c) 2018 Anki, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License in the file LICENSE.txt or at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// External interface for robot <-> app and robot <-> sdk communication - -syntax = "proto3"; - -package Anki.Vector.external_interface; - -import "anki_vector/messaging/response_status.proto"; -import "anki_vector/messaging/extensions.proto"; - -// A null message used by streams to verify that the client is -// still connected. -message KeepAlivePing {} - -message Animation { - string name = 1; -} - -message DriveWheelsRequest { - float left_wheel_mmps = 1; - float right_wheel_mmps = 2; - float left_wheel_mmps2 = 3; - float right_wheel_mmps2 = 4; -} - -message DriveWheelsResponse { - ResponseStatus status = 1; -} - -message MoveHeadRequest { - float speed_rad_per_sec = 1; -} - -message MoveHeadResponse { - ResponseStatus status = 1; -} - -message MoveLiftRequest { - float speed_rad_per_sec = 1; -} - -message MoveLiftResponse { - ResponseStatus status = 1; -} - -message PlayAnimationRequest { - Animation animation = 1; - uint32 loops = 2; - bool ignore_body_track = 3; - bool ignore_head_track = 4; - bool ignore_lift_track = 5; -} - -message PlayAnimationResponse { - ResponseStatus status = 1; - BehaviorResults result = 2; -} - -message ListAnimationsRequest {} - -message ListAnimationsResponse { - ResponseStatus status = 1; - repeated Animation animation_names = 2; -} - -message DisplayFaceImageRGBRequest { - bytes face_data = 1; - uint32 duration_ms = 2; - bool interrupt_running = 3; -} - -message DisplayFaceImageRGBResponse { - ResponseStatus status = 1; -} - -message MeetVictorFaceScanStarted -{ -} - -message MeetVictorFaceScanComplete -{ -} - -message Status { - oneof status_type { - MeetVictorFaceScanStarted meet_victor_face_scan_started = 2; - MeetVictorFaceScanComplete meet_victor_face_scan_complete = 3; - FaceEnrollmentCompleted face_enrollment_completed = 4; - } -} - -message WakeWord { - oneof wake_word_type { - WakeWordBegin wake_word_begin = 1; - WakeWordEnd wake_word_end = 2; - } -} - -message TimeStampedStatus { - Status status = 1; - uint32 timestamp_utc = 2; -} - -message PoseStruct { - // Translation - float x = 1; - float y = 2; - float z = 3; - - // Rotation quaternion - float q0 = 4; - float q1 = 5; - float q2 = 6; - float q3 = 7; - - uint32 origin_id = 8; // Which coordinate frame this pose is in (0 for none or unknown) -} - -message AccelData { - float x = 1; // mm/s^2 - float y = 2; - float z = 3; -} - -message GyroData { - float x = 1; // rad/s - float y = 2; - float z = 3; -} - -message ProxData { - uint32 distance_mm = 1; - float signal_quality = 2; - bool is_in_valid_range = 3; // Distance is within valid range - bool is_valid_signal_quality = 4; // Signal quality is sufficiently strong to trust that something was detected - bool is_lift_in_fov = 5; // Lift (or object on lift) is occluding the sensor - bool is_too_pitched = 6; // Robot is too far pitched up or down -} - -message TouchData { - uint32 raw_touch_value = 1; // Raw input from the touch sensor - bool is_being_touched = 2; // Robot's context aware evaluation of whether it currently is or isn't being touched -} - -message RobotState { - PoseStruct pose = 1; - float pose_angle_rad = 2; - float pose_pitch_rad = 3; - float left_wheel_speed_mmps = 4; - float right_wheel_speed_mmps = 5; - float head_angle_rad = 6; - float lift_height_mm = 7; - AccelData accel = 8; - GyroData gyro = 9; - int32 carrying_object_id = 10; - int32 carrying_object_on_top_id = 11; // Not supported by engine - int32 head_tracking_object_id = 12; - int32 localized_to_object_id = 13; - uint32 last_image_time_stamp = 14; - uint32 status = 15; - ProxData prox_data = 16; - TouchData touch_data = 17; -} - -enum RobotStatus -{ - ROBOT_STATUS_NONE = 0x0; - ROBOT_STATUS_IS_MOVING = 0x1; - ROBOT_STATUS_IS_CARRYING_BLOCK = 0x2; - ROBOT_STATUS_IS_PICKING_OR_PLACING = 0x4; - ROBOT_STATUS_IS_PICKED_UP = 0x8; - ROBOT_STATUS_IS_BUTTON_PRESSED = 0x10; - ROBOT_STATUS_IS_FALLING = 0x20; - ROBOT_STATUS_IS_ANIMATING = 0x40; - ROBOT_STATUS_IS_PATHING = 0x80; - ROBOT_STATUS_LIFT_IN_POS = 0x100; - ROBOT_STATUS_HEAD_IN_POS = 0x200; - ROBOT_STATUS_CALM_POWER_MODE = 0x400; - ROBOT_STATUS_IS_ON_CHARGER = 0x1000; - ROBOT_STATUS_IS_CHARGING = 0x2000; - ROBOT_STATUS_CLIFF_DETECTED = 0x4000; - ROBOT_STATUS_ARE_WHEELS_MOVING = 0x8000; - ROBOT_STATUS_IS_BEING_HELD = 0x10000; - ROBOT_STATUS_IS_MOTION_DETECTED = 0x20000; -} - -message CladPoint -{ - float x = 1; - float y = 2; -} - -message CladRect -{ - float x_top_left = 1; - float y_top_left = 2; - float width = 3; - float height = 4; -} - -// This is an int8 on the clad side. -// Proto field names are prefixed with "EXPRESSION_" -enum FacialExpression -{ - option allow_alias = true; - EXPRESSION_UNKNOWN = 0; // e.g. expression estimation disabled. - - EXPRESSION_NEUTRAL = 1; - EXPRESSION_HAPPINESS = 2; - EXPRESSION_SURPRISE = 3; - EXPRESSION_ANGER = 4; - EXPRESSION_SADNESS = 5; - - // Clad does not account for "Unknown" in the count. - EXPRESSION_COUNT = 5; -} - -message RobotObservedFace { - int32 face_id = 1; // negative: tracked but not recognized; positive: recognized face - uint32 timestamp = 2; - PoseStruct pose = 3; - CladRect img_rect = 4; // position in image coords - string name = 5; // Empty if none assigned yet - - FacialExpression expression = 6; - - // Individual expression values histogram, sums to 100 (Exception: all zero if expression=Unknown) - repeated uint32 expression_values = 7; - - // Face landmarks - repeated CladPoint left_eye = 8; - repeated CladPoint right_eye = 9; - repeated CladPoint nose = 10; - repeated CladPoint mouth = 11; -} - -// RobotChangedObservedFaceID -// This generally happens when a tracked face (negative ID) is recognized and -// receives a positive ID or when face records get merged -message RobotChangedObservedFaceID { - int32 old_id = 1; - int32 new_id = 2; -} - -message AppIntentRequest { - string intent = 1; - string param = 2; -} - -enum FaceEnrollmentResult -{ - SUCCESS = 0; - - // Failures: - SAW_WRONG_FACE = 1; - SAW_MULTIPLE_FACES = 2; - TIMED_OUT = 3; - SAVE_FAILED = 4; - INCOMPLETE = 5; - CANCELLED = 6; - NAME_IN_USE = 7; - NAMED_STORAGE_FULL = 8; - UNKNOWN_FAILURE = 9; -} - -message AppDisconnected{} - -message AppIntentResponse { - ResponseStatus status = 1; -} - -message FaceEnrollmentCompleted { - FaceEnrollmentResult result = 1; - int32 face_id = 2; - string name = 3; -} - -message CancelFaceEnrollmentRequest { -} - -message CancelFaceEnrollmentResponse { - ResponseStatus status = 1; -} - -message RequestEnrolledNamesRequest { -} - -message LoadedKnownFace { - int64 seconds_since_first_enrolled = 1; - int64 seconds_since_last_updated = 2; - int64 seconds_since_last_seen = 3; - int64 last_seen_seconds_since_epoch = 4; - int32 face_id = 5; - string name = 6; -} - -message RobotRenamedEnrolledFace { - int32 face_id = 1; - string name = 2; -} - -message RequestEnrolledNamesResponse { - ResponseStatus status = 1; - repeated LoadedKnownFace faces = 2; -} - -message UpdateEnrolledFaceByIDRequest { - int32 face_id = 1; - string old_name = 2; - string new_name = 3; -} - -message UpdateEnrolledFaceByIDResponse { - ResponseStatus status = 1; -} - -message EraseEnrolledFaceByIDRequest { - int32 face_id = 1; -} - -message EraseEnrolledFaceByIDResponse { - ResponseStatus status = 1; -} - -message EraseAllEnrolledFacesRequest { -} - -message EraseAllEnrolledFacesResponse { - ResponseStatus status = 1; -} - -message SetFaceToEnrollRequest { - string name = 1; - - int32 observed_id = 2; // The ID of a specific observed face to enroll (0 for next one we see) - int32 save_id = 3; // The ID of an existing face to merge final enrollment into (0 for none, - // i.e. use observedID) - - bool save_to_robot = 4; // Save to robot's NVStorage when done (NOTE: will (re)save everyone enrolled!) - bool say_name = 5; // Play say-name/celebration animations on success before completing - bool use_music = 6; // Starts special music during say-name animations (will leave music playing!) -} -message SetFaceToEnrollResponse { - ResponseStatus status = 1; -} - -enum BehaviorResults -{ - BEHAVIOR_INVALID_STATE = 0; - BEHAVIOR_COMPLETE_STATE = 1; - BEHAVIOR_WONT_ACTIVATE_STATE = 2; -} - -message DriveOffChargerRequest { -} - -message DriveOffChargerResponse { - ResponseStatus status = 1; - BehaviorResults result = 2; -} - -message DriveOnChargerRequest { -} - -message DriveOnChargerResponse { - ResponseStatus status = 1; - BehaviorResults result = 2; -} - - -message WakeWordBegin { -} - -message WakeWordEnd { - bool intent_heard = 1; - string intent_json = 2; -} - -message PhotoInfo { - uint32 photo_id = 1; - uint32 timestamp_utc = 2; - bool photo_copied_to_app = 3; - bool thumb_copied_to_app = 4; -} - -message PhotosInfoRequest { -} - -message PhotosInfoResponse { - ResponseStatus status = 1; - repeated PhotoInfo photo_infos = 2; -} - -message PhotoRequest { - uint32 photo_id = 1; -} - -message PhotoPathMessage { - bool success = 1; - string full_path = 2; -} - -message PhotoResponse { - ResponseStatus status = 1; - bool success = 2; - bytes image = 3; -} - -message ThumbnailRequest { - uint32 photo_id = 1; -} - -message ThumbnailPathMessage { - bool success = 1; - string full_path = 2; -} - -message ThumbnailResponse { - ResponseStatus status = 1; - bool success = 2; - bytes image = 3; -} - -message DeletePhotoRequest { - uint32 photo_id = 1; -} - -message DeletePhotoResponse { - ResponseStatus status = 1; - bool success = 2; -} - -message PhotoTaken { - uint32 photo_id = 1; -} - -// Struct containing all the information relevant to how a -// path should be modified or traversed. -message PathMotionProfile { - float speed_mmps = 1; - float accel_mmps2 = 2; - float decel_mmps2 = 3; - float point_turn_speed_rad_per_sec = 4; - float point_turn_accel_rad_per_sec2 = 5; - float point_turn_decel_rad_per_sec2 = 6; - float dock_speed_mmps = 7; - float dock_accel_mmps2 = 8; - float dock_decel_mmps2 = 9; - float reverse_speed_mmps = 10; - bool is_custom = 11; -} - -// These codes are duplicated from actionResults.clad file and need to be kept in sync -message ActionResult { - enum ActionResultCode { - ACTION_RESULT_SUCCESS = 0; - ACTION_RESULT_RUNNING = 16777216; - - ACTION_RESULT_CANCELLED_WHILE_RUNNING = 33554432; - NOT_STARTED = 33554433; - - ABORT = 50331648; - ANIM_ABORTED = 50331649; - BAD_MARKER = 50331650; - BAD_MESSAGE_TAG = 50331651; - BAD_OBJECT = 50331652; - BAD_POSE = 50331653; - BAD_TAG = 50331654; - CHARGER_UNPLUGGED_ABORT = 50331655; - CLIFF_ALIGN_FAILED_TIMEOUT = 50331656; - CLIFF_ALIGN_FAILED_NO_TURNING = 50331657; - CLIFF_ALIGN_FAILED_OVER_TURNING = 50331658; - CLIFF_ALIGN_FAILED_NO_WHITE = 50331659; - CLIFF_ALIGN_FAILED_STOPPED = 50331660; - FAILED_SETTING_CALIBRATION = 50331661; - FOLLOWING_PATH_BUT_NOT_TRAVERSING = 50331662; - INTERRUPTED = 50331663; - INVALID_OFF_TREADS_STATE = 50331664; - MISMATCHED_UP_AXIS = 50331665; - NO_ANIM_NAME = 50331666; - NO_DISTANCE_SET = 50331667; - NO_FACE = 50331668; - NO_GOAL_SET = 50331669; - NO_PREACTION_POSES = 50331670; - NOT_CARRYING_OBJECT_ABORT = 50331671; - NOT_ON_CHARGER_ABORT = 50331672; - NULL_SUBACTION = 50331673; - PATH_PLANNING_FAILED_ABORT = 50331674; - PICKUP_OBJECT_UNEXPECTEDLY_MOVING = 50331675; - SEND_MESSAGE_TO_ROBOT_FAILED = 50331676; - STILL_CARRYING_OBJECT = 50331677; - TIMEOUT = 50331678; - TRACKS_LOCKED = 50331679; - UNEXPECTED_DOCK_ACTION = 50331680; - UNKNOWN_TOOL_CODE = 50331681; - UPDATE_DERIVED_FAILED = 50331682; - VISUAL_OBSERVATION_FAILED = 50331683; - SHOULDNT_DRIVE_ON_CHARGER = 50331684; - - RETRY = 67108864; - DID_NOT_REACH_PREACTION_POSE = 67108865; - FAILED_TRAVERSING_PATH = 67108866; - LAST_PICK_AND_PLACE_FAILED = 67108867; - MOTOR_STOPPED_MAKING_PROGRESS = 67108868; - NOT_CARRYING_OBJECT_RETRY = 67108869; - NOT_ON_CHARGER_RETRY = 67108870; - PATH_PLANNING_FAILED_RETRY = 67108871; - PLACEMENT_GOAL_NOT_FREE = 67108872; - PICKUP_OBJECT_UNEXPECTEDLY_NOT_MOVING = 67108873; - STILL_ON_CHARGER = 67108874; - UNEXPECTED_PITCH_ANGLE = 67108875; - } - ActionResultCode code = 1; -} - -enum ActionTagConstants { - INVALID_SDK_TAG = 0; - FIRST_SDK_TAG = 2000001; - LAST_SDK_TAG = 3000000; -} - -// GotoPose -message GoToPoseRequest { - float x_mm = 1; - float y_mm = 2; - float rad = 3; - PathMotionProfile motion_prof = 4; - int32 id_tag = 5; - int32 num_retries = 6; -} - -message GoToPoseResponse { - ResponseStatus status = 1; - ActionResult result = 2; -} - -// This is a uint8 in CLAD -enum AlignmentType { - ALIGNMENT_TYPE_UNKNOWN = 0; - ALIGNMENT_TYPE_LIFT_FINGER = 1; // Fingers aligned with object - ALIGNMENT_TYPE_LIFT_PLATE = 2; // Lift plate aligned with object - ALIGNMENT_TYPE_BODY = 3; // Front of body aligned with object - ALIGNMENT_TYPE_CUSTOM = 4; -} - -message DockWithCubeRequest { - int32 object_id = 1; - float distance_from_marker_mm = 2; - float approach_angle_rad = 3; - AlignmentType alignment_type = 4; - bool use_approach_angle = 5; - bool use_pre_dock_pose = 6; - PathMotionProfile motion_prof = 7; - int32 id_tag = 8; - int32 num_retries = 9; -} - -message DockWithCubeResponse { - ResponseStatus status = 1; - ActionResult result = 2; -} - -message DriveStraightRequest { - float speed_mmps = 1; // Speed should be positive - float dist_mm = 2; // Use +ve for forward, -ve for backward - bool should_play_animation = 3; - int32 id_tag = 4; - int32 num_retries = 5; -} - -message DriveStraightResponse { - ResponseStatus status = 1; - ActionResult result = 2; -} - -// TurnInPlace -// If isAbsolute == 0, turns the specified number of radians, relative to the robot's current heading* -// If isAbsolute != 0, turns to the specified absolute orientation. -message TurnInPlaceRequest { - float angle_rad = 1; // relative mode: positive turns left negative turns right - float speed_rad_per_sec = 2; - float accel_rad_per_sec2 = 3; - float tol_rad = 4; // This should be no smaller than POINT_TURN_ANGLE_TOL (DEG_TO_RAD(2.f)). - // Smaller values are ignored except 0 which is interpreted to mean - // default tolerance of POINT_TURN_ANGLE_TOL. - uint32 is_absolute = 5; // 0: angle_rad is relative to current orientation, 1: angle_rad is absolute angle to turn to - int32 id_tag = 6; - int32 num_retries = 7; -} - -message TurnInPlaceResponse { - ResponseStatus status = 1; - ActionResult result = 2; -} - -// SetHeadAngle -message SetHeadAngleRequest { - float angle_rad = 1; - float max_speed_rad_per_sec = 2; - float accel_rad_per_sec2 = 3; - float duration_sec = 4; - int32 id_tag = 5; - int32 num_retries = 6; -} - -message SetHeadAngleResponse { - ResponseStatus status = 1; - ActionResult result = 2; -} - -// SetLiftHeight -message SetLiftHeightRequest { - float height_mm = 1; - float max_speed_rad_per_sec = 2; - float accel_rad_per_sec2 = 3; - float duration_sec = 4; - int32 id_tag = 5; - int32 num_retries = 6; -} - -message SetLiftHeightResponse { - ResponseStatus status = 1; - ActionResult result = 2; -} - -enum BatteryLevel { - BATTERY_LEVEL_UNKNOWN = 0; - BATTERY_LEVEL_LOW = 1; - BATTERY_LEVEL_NOMINAL = 2; - BATTERY_LEVEL_FULL = 3; -} - -message NetworkStats { - int32 g_net_stat1_num_connections = 1; - float g_net_stat2_latency_avg = 2; - float g_net_stat3_latency_sd = 3; - float g_net_stat4_latency_min = 4; - float g_net_stat5_latency_max = 5; - float g_net_stat6_ping_arrived_pc = 6; - float g_net_stat7_ext_queued_avg_ms = 7; - float g_net_stat8_ext_queued_min_ms = 8; - float g_net_stat9_ext_queued_max_ms = 9; - float g_net_stata_queued_avg_ms = 10; - float g_net_statb_queued_min_ms = 11; - float g_net_statc_queued_max_ms = 12; -} - -message BatteryStateRequest {} - -message BatteryStateResponse { - ResponseStatus status = 1; - BatteryLevel battery_level = 2; - float battery_volts = 3; - bool is_charging = 4; - bool is_on_charger_platform = 5; - float suggested_charger_sec = 6; - CubeBattery cube_battery = 7; -} - -message CubeBattery { - enum CubeBatteryLevel { - Low = 0; - Normal = 1; - } - CubeBatteryLevel level = 1; - string factory_id = 2; - float battery_volts = 3; - float time_since_last_reading_sec = 4; -} - -message VersionStateRequest {} - -message VersionStateResponse { - ResponseStatus status = 1; - string os_version = 2; - string engine_build_id = 3; -} - -message NetworkStateRequest {} - -message NetworkStateResponse { - ResponseStatus status = 1; - NetworkStats network_stats = 2; -} - -message SayTextRequest { - string text = 1; - bool use_vector_voice = 2; - float duration_scalar = 3; -} - -message SayTextResponse { - enum UtteranceState - { - INVALID = 0; - GENERATING = 1; - READY = 2; - PLAYING = 3; - FINISHED = 4; - } - ResponseStatus status = 1; - UtteranceState state = 2; -} - -message StimulationInfo { - repeated string emotion_events = 1; // may be empty - float value = 2; - float velocity = 3; // value per second - float accel = 4; // value per sec per sec - float value_before_event = 5; // matches value if there were no emotion events - float min_value = 6; - float max_value = 7; -} - -// Constants associated with the audio feed -enum AudioConstants { - AUDIO_CONSTANTS_NULL = 0; // error value - MIC_DETECTION_DIRECTIONS = 12; // The number of audio directions the four microphones can isolate - SAMPLE_COUNTS_PER_ENGINE_MESSAGE = 160; // The number of audio samples in each internal audio chunk - SAMPLE_COUNTS_PER_SDK_MESSAGE = 1600; // The number of audio samples delivered in each audio feed response - MICROPHONE_SAMPLE_RATE = 15625; // The sampling rate victor's microphones record at - PROCESSED_SAMPLE_RATE = 16000; // The sampling rate the robot processes audio at -} - -// The robot can process audio in a variety of ways -enum AudioProcessingMode { - AUDIO_UNKNOWN = 0; // error value - AUDIO_OFF = 1; // deactivates audio SDK mode - AUDIO_FAST_MODE = 2; // unprocessed single microphone data - most performant on robot - AUDIO_DIRECTIONAL_MODE = 3; // beamforming support for focusing on specific direction - sounds cleanest - AUDIO_VOICE_DETECT_MODE = 4; // multi-microphone non-beamforming - best for voice detection programs -} - -// Request how the robot should process and send audio -message AudioSendModeRequest { - AudioProcessingMode mode = 1; -} - -// Event sent when the robot changes the mode it's processing and sending audio -message AudioSendModeChanged { - AudioProcessingMode mode = 1; -} - -// One frame of audio data and associated metadata -message AudioChunk { - uint32 robot_time_stamp = 1; // robot time at the final chunk of this audio sample group transmission - uint32 group_id = 2; // the id of this sample transmission group - uint32 chunk_id = 3; // the current batched chunk id within in this group id - uint32 audio_chunk_count = 4; // number of chunks batched within this group id - bytes signal_power = 5; // mono audio amplitude samples - bytes direction_strengths = 6; // histogram data of which directions this audio chunk came from - uint32 source_direction = 7; // 0-11, with 12 representing "invalid" - uint32 source_confidence = 8; // accuracy of the calculated source_direction - uint32 noise_floor_power = 9; // power value, convert to db with log_10(value) -} - -// Request the robot to send audio data -message AudioFeedRequest {} - -// Streamed audio data from the robot -message AudioFeedResponse { - option (streamed) = true; - - uint32 robot_time_stamp = 1; // robot time at the transmission of this audio sample group - uint32 group_id = 2; // the index of this audio feed response - bytes signal_power = 3; // mono audio amplitude samples - bytes direction_strengths = 4; // histogram data of which directions this audio chunk came from - uint32 source_direction = 5; // 0-11, with 12 representing "invalid" - uint32 source_confidence = 6; // accuracy of the calculated source_direction - uint32 noise_floor_power = 7; // power value, convert to db with log_10(value) -} - - -// When enabled, RobotObservedObject messages will be produced -message EnableMarkerDetectionRequest -{ - bool enable = 1; -} - -message EnableMarkerDetectionResponse -{ - ResponseStatus status = 1; -} - -// When enabled, RobotObservedFace messages will be produced -message EnableFaceDetectionRequest -{ - bool enable = 1; - - bool enable_smile_detection = 2; - bool enable_expression_estimation = 3; - bool enable_blink_detection = 4; - bool enable_gaze_detection = 5; -} - -message EnableFaceDetectionResponse -{ - ResponseStatus status = 1; -} - -// When enabled, RobotObservedMotion messages will be produced -message EnableMotionDetectionRequest -{ - bool enable = 1; -} - -message EnableMotionDetectionResponse -{ - ResponseStatus status = 1; -} - -// When enabled, camera feed will appear on the robot's face, along with any -// detections that are enabled from above messages -message EnableMirrorModeRequest -{ - bool enable = 1; -} - -message EnableMirrorModeResponse -{ - ResponseStatus status = 1; -} - -// Sent if MirrorMode (camera feed displayed on face) is currently enabled but is automatically -// being disabled -message MirrorModeDisabled -{ - -} - -// Toggle image streaming at the given resolution -message EnableImageStreamingRequest -{ - bool enable = 1; -} - -message EnableImageStreamingResponse -{ - ResponseStatus status = 1; -} - -// Sent when vision modes are automatically disabled due to the SDK no longer having control -// of the robot -message VisionModesAutoDisabled -{ - -} - -// One frame of image data and associated metadata -message ImageChunk { - enum ImageEncoding - { - NONE_IMAGE_ENCODING = 0; - RAW_GRAY = 1; // no compression - RAW_RGB = 2; // no compression, just [RGBRGBRG...] - YUYV = 3; - YUV420SP = 4; - BAYER = 5; - JPEG_GRAY = 6; - JPEG_COLOR = 7; - JPEG_COLOR_HALF_WIDTH = 8; - JPEG_MINIMIZED_GRAY = 9; // Minimized grayscale JPEG - no header, no footer, no byte stuffing - JPEG_MINIMIZED_COLOR = 10; // Minimized grayscale JPEG - no header, no footer, no byte stuffing, with added color data - } - uint32 frame_time_stamp = 1; - uint32 image_id = 2; - uint32 width = 3; - uint32 height = 4; - ImageEncoding image_encoding = 5; - uint32 display_index = 6; - uint32 image_chunk_count = 7; - uint32 chunk_id = 8; - bytes data = 9; -} - -message CameraFeedRequest {} - -message CameraFeedResponse { - option (streamed) = true; - - uint32 frame_time_stamp = 1; - uint32 image_id = 2; - ImageChunk.ImageEncoding image_encoding = 3; - bytes data = 4; -} - -message SetEyeColorRequest { - float hue = 1; - float saturation = 2; -} - -message SetEyeColorResponse { - ResponseStatus status = 1; -} - -message SDKInitializationRequest { - string sdk_module_version = 1; - string python_version = 2; - string python_implementation = 3; - string os_version = 4; - string cpu_version = 5; -} - -message SDKInitializationResponse { - ResponseStatus status = 1; -} - diff --git a/anki_vector/messaging/messages_pb2.py b/anki_vector/messaging/messages_pb2.py deleted file mode 100644 index 7133b77..0000000 --- a/anki_vector/messaging/messages_pb2.py +++ /dev/null @@ -1,6715 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: anki_vector/messaging/messages.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from anki_vector.messaging import response_status_pb2 as anki__vector_dot_messaging_dot_response__status__pb2 -from anki_vector.messaging import extensions_pb2 as anki__vector_dot_messaging_dot_extensions__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='anki_vector/messaging/messages.proto', - package='Anki.Vector.external_interface', - syntax='proto3', - serialized_pb=_b('\n$anki_vector/messaging/messages.proto\x12\x1e\x41nki.Vector.external_interface\x1a+anki_vector/messaging/response_status.proto\x1a&anki_vector/messaging/extensions.proto\"\x0f\n\rKeepAlivePing\"\x19\n\tAnimation\x12\x0c\n\x04name\x18\x01 \x01(\t\"|\n\x12\x44riveWheelsRequest\x12\x17\n\x0fleft_wheel_mmps\x18\x01 \x01(\x02\x12\x18\n\x10right_wheel_mmps\x18\x02 \x01(\x02\x12\x18\n\x10left_wheel_mmps2\x18\x03 \x01(\x02\x12\x19\n\x11right_wheel_mmps2\x18\x04 \x01(\x02\"U\n\x13\x44riveWheelsResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\",\n\x0fMoveHeadRequest\x12\x19\n\x11speed_rad_per_sec\x18\x01 \x01(\x02\"R\n\x10MoveHeadResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\",\n\x0fMoveLiftRequest\x12\x19\n\x11speed_rad_per_sec\x18\x01 \x01(\x02\"R\n\x10MoveLiftResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"\xb4\x01\n\x14PlayAnimationRequest\x12<\n\tanimation\x18\x01 \x01(\x0b\x32).Anki.Vector.external_interface.Animation\x12\r\n\x05loops\x18\x02 \x01(\r\x12\x19\n\x11ignore_body_track\x18\x03 \x01(\x08\x12\x19\n\x11ignore_head_track\x18\x04 \x01(\x08\x12\x19\n\x11ignore_lift_track\x18\x05 \x01(\x08\"\x98\x01\n\x15PlayAnimationResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12?\n\x06result\x18\x02 \x01(\x0e\x32/.Anki.Vector.external_interface.BehaviorResults\"\x17\n\x15ListAnimationsRequest\"\x9c\x01\n\x16ListAnimationsResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12\x42\n\x0f\x61nimation_names\x18\x02 \x03(\x0b\x32).Anki.Vector.external_interface.Animation\"_\n\x1a\x44isplayFaceImageRGBRequest\x12\x11\n\tface_data\x18\x01 \x01(\x0c\x12\x13\n\x0b\x64uration_ms\x18\x02 \x01(\r\x12\x19\n\x11interrupt_running\x18\x03 \x01(\x08\"]\n\x1b\x44isplayFaceImageRGBResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"\x1b\n\x19MeetVictorFaceScanStarted\"\x1c\n\x1aMeetVictorFaceScanComplete\"\xbf\x02\n\x06Status\x12\x62\n\x1dmeet_victor_face_scan_started\x18\x02 \x01(\x0b\x32\x39.Anki.Vector.external_interface.MeetVictorFaceScanStartedH\x00\x12\x64\n\x1emeet_victor_face_scan_complete\x18\x03 \x01(\x0b\x32:.Anki.Vector.external_interface.MeetVictorFaceScanCompleteH\x00\x12\\\n\x19\x66\x61\x63\x65_enrollment_completed\x18\x04 \x01(\x0b\x32\x37.Anki.Vector.external_interface.FaceEnrollmentCompletedH\x00\x42\r\n\x0bstatus_type\"\xac\x01\n\x08WakeWord\x12H\n\x0fwake_word_begin\x18\x01 \x01(\x0b\x32-.Anki.Vector.external_interface.WakeWordBeginH\x00\x12\x44\n\rwake_word_end\x18\x02 \x01(\x0b\x32+.Anki.Vector.external_interface.WakeWordEndH\x00\x42\x10\n\x0ewake_word_type\"b\n\x11TimeStampedStatus\x12\x36\n\x06status\x18\x01 \x01(\x0b\x32&.Anki.Vector.external_interface.Status\x12\x15\n\rtimestamp_utc\x18\x02 \x01(\r\"p\n\nPoseStruct\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\x12\t\n\x01z\x18\x03 \x01(\x02\x12\n\n\x02q0\x18\x04 \x01(\x02\x12\n\n\x02q1\x18\x05 \x01(\x02\x12\n\n\x02q2\x18\x06 \x01(\x02\x12\n\n\x02q3\x18\x07 \x01(\x02\x12\x11\n\torigin_id\x18\x08 \x01(\r\",\n\tAccelData\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\x12\t\n\x01z\x18\x03 \x01(\x02\"+\n\x08GyroData\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\x12\t\n\x01z\x18\x03 \x01(\x02\"\xa3\x01\n\x08ProxData\x12\x13\n\x0b\x64istance_mm\x18\x01 \x01(\r\x12\x16\n\x0esignal_quality\x18\x02 \x01(\x02\x12\x19\n\x11is_in_valid_range\x18\x03 \x01(\x08\x12\x1f\n\x17is_valid_signal_quality\x18\x04 \x01(\x08\x12\x16\n\x0eis_lift_in_fov\x18\x05 \x01(\x08\x12\x16\n\x0eis_too_pitched\x18\x06 \x01(\x08\">\n\tTouchData\x12\x17\n\x0fraw_touch_value\x18\x01 \x01(\r\x12\x18\n\x10is_being_touched\x18\x02 \x01(\x08\"\x82\x05\n\nRobotState\x12\x38\n\x04pose\x18\x01 \x01(\x0b\x32*.Anki.Vector.external_interface.PoseStruct\x12\x16\n\x0epose_angle_rad\x18\x02 \x01(\x02\x12\x16\n\x0epose_pitch_rad\x18\x03 \x01(\x02\x12\x1d\n\x15left_wheel_speed_mmps\x18\x04 \x01(\x02\x12\x1e\n\x16right_wheel_speed_mmps\x18\x05 \x01(\x02\x12\x16\n\x0ehead_angle_rad\x18\x06 \x01(\x02\x12\x16\n\x0elift_height_mm\x18\x07 \x01(\x02\x12\x38\n\x05\x61\x63\x63\x65l\x18\x08 \x01(\x0b\x32).Anki.Vector.external_interface.AccelData\x12\x36\n\x04gyro\x18\t \x01(\x0b\x32(.Anki.Vector.external_interface.GyroData\x12\x1a\n\x12\x63\x61rrying_object_id\x18\n \x01(\x05\x12!\n\x19\x63\x61rrying_object_on_top_id\x18\x0b \x01(\x05\x12\x1f\n\x17head_tracking_object_id\x18\x0c \x01(\x05\x12\x1e\n\x16localized_to_object_id\x18\r \x01(\x05\x12\x1d\n\x15last_image_time_stamp\x18\x0e \x01(\r\x12\x0e\n\x06status\x18\x0f \x01(\r\x12;\n\tprox_data\x18\x10 \x01(\x0b\x32(.Anki.Vector.external_interface.ProxData\x12=\n\ntouch_data\x18\x11 \x01(\x0b\x32).Anki.Vector.external_interface.TouchData\"!\n\tCladPoint\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\"Q\n\x08\x43ladRect\x12\x12\n\nx_top_left\x18\x01 \x01(\x02\x12\x12\n\ny_top_left\x18\x02 \x01(\x02\x12\r\n\x05width\x18\x03 \x01(\x02\x12\x0e\n\x06height\x18\x04 \x01(\x02\"\x8a\x04\n\x11RobotObservedFace\x12\x0f\n\x07\x66\x61\x63\x65_id\x18\x01 \x01(\x05\x12\x11\n\ttimestamp\x18\x02 \x01(\r\x12\x38\n\x04pose\x18\x03 \x01(\x0b\x32*.Anki.Vector.external_interface.PoseStruct\x12:\n\x08img_rect\x18\x04 \x01(\x0b\x32(.Anki.Vector.external_interface.CladRect\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x44\n\nexpression\x18\x06 \x01(\x0e\x32\x30.Anki.Vector.external_interface.FacialExpression\x12\x19\n\x11\x65xpression_values\x18\x07 \x03(\r\x12;\n\x08left_eye\x18\x08 \x03(\x0b\x32).Anki.Vector.external_interface.CladPoint\x12<\n\tright_eye\x18\t \x03(\x0b\x32).Anki.Vector.external_interface.CladPoint\x12\x37\n\x04nose\x18\n \x03(\x0b\x32).Anki.Vector.external_interface.CladPoint\x12\x38\n\x05mouth\x18\x0b \x03(\x0b\x32).Anki.Vector.external_interface.CladPoint\"<\n\x1aRobotChangedObservedFaceID\x12\x0e\n\x06old_id\x18\x01 \x01(\x05\x12\x0e\n\x06new_id\x18\x02 \x01(\x05\"1\n\x10\x41ppIntentRequest\x12\x0e\n\x06intent\x18\x01 \x01(\t\x12\r\n\x05param\x18\x02 \x01(\t\"\x11\n\x0f\x41ppDisconnected\"S\n\x11\x41ppIntentResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"~\n\x17\x46\x61\x63\x65\x45nrollmentCompleted\x12\x44\n\x06result\x18\x01 \x01(\x0e\x32\x34.Anki.Vector.external_interface.FaceEnrollmentResult\x12\x0f\n\x07\x66\x61\x63\x65_id\x18\x02 \x01(\x05\x12\x0c\n\x04name\x18\x03 \x01(\t\"\x1d\n\x1b\x43\x61ncelFaceEnrollmentRequest\"^\n\x1c\x43\x61ncelFaceEnrollmentResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"\x1d\n\x1bRequestEnrolledNamesRequest\"\xc2\x01\n\x0fLoadedKnownFace\x12$\n\x1cseconds_since_first_enrolled\x18\x01 \x01(\x03\x12\"\n\x1aseconds_since_last_updated\x18\x02 \x01(\x03\x12\x1f\n\x17seconds_since_last_seen\x18\x03 \x01(\x03\x12%\n\x1dlast_seen_seconds_since_epoch\x18\x04 \x01(\x03\x12\x0f\n\x07\x66\x61\x63\x65_id\x18\x05 \x01(\x05\x12\x0c\n\x04name\x18\x06 \x01(\t\"9\n\x18RobotRenamedEnrolledFace\x12\x0f\n\x07\x66\x61\x63\x65_id\x18\x01 \x01(\x05\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x9e\x01\n\x1cRequestEnrolledNamesResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12>\n\x05\x66\x61\x63\x65s\x18\x02 \x03(\x0b\x32/.Anki.Vector.external_interface.LoadedKnownFace\"T\n\x1dUpdateEnrolledFaceByIDRequest\x12\x0f\n\x07\x66\x61\x63\x65_id\x18\x01 \x01(\x05\x12\x10\n\x08old_name\x18\x02 \x01(\t\x12\x10\n\x08new_name\x18\x03 \x01(\t\"`\n\x1eUpdateEnrolledFaceByIDResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"/\n\x1c\x45raseEnrolledFaceByIDRequest\x12\x0f\n\x07\x66\x61\x63\x65_id\x18\x01 \x01(\x05\"_\n\x1d\x45raseEnrolledFaceByIDResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"\x1e\n\x1c\x45raseAllEnrolledFacesRequest\"_\n\x1d\x45raseAllEnrolledFacesResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"\x88\x01\n\x16SetFaceToEnrollRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0bobserved_id\x18\x02 \x01(\x05\x12\x0f\n\x07save_id\x18\x03 \x01(\x05\x12\x15\n\rsave_to_robot\x18\x04 \x01(\x08\x12\x10\n\x08say_name\x18\x05 \x01(\x08\x12\x11\n\tuse_music\x18\x06 \x01(\x08\"Y\n\x17SetFaceToEnrollResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"\x18\n\x16\x44riveOffChargerRequest\"\x9a\x01\n\x17\x44riveOffChargerResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12?\n\x06result\x18\x02 \x01(\x0e\x32/.Anki.Vector.external_interface.BehaviorResults\"\x17\n\x15\x44riveOnChargerRequest\"\x99\x01\n\x16\x44riveOnChargerResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12?\n\x06result\x18\x02 \x01(\x0e\x32/.Anki.Vector.external_interface.BehaviorResults\"\x0f\n\rWakeWordBegin\"8\n\x0bWakeWordEnd\x12\x14\n\x0cintent_heard\x18\x01 \x01(\x08\x12\x13\n\x0bintent_json\x18\x02 \x01(\t\"n\n\tPhotoInfo\x12\x10\n\x08photo_id\x18\x01 \x01(\r\x12\x15\n\rtimestamp_utc\x18\x02 \x01(\r\x12\x1b\n\x13photo_copied_to_app\x18\x03 \x01(\x08\x12\x1b\n\x13thumb_copied_to_app\x18\x04 \x01(\x08\"\x13\n\x11PhotosInfoRequest\"\x94\x01\n\x12PhotosInfoResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12>\n\x0bphoto_infos\x18\x02 \x03(\x0b\x32).Anki.Vector.external_interface.PhotoInfo\" \n\x0cPhotoRequest\x12\x10\n\x08photo_id\x18\x01 \x01(\r\"6\n\x10PhotoPathMessage\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x11\n\tfull_path\x18\x02 \x01(\t\"o\n\rPhotoResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\r\n\x05image\x18\x03 \x01(\x0c\"$\n\x10ThumbnailRequest\x12\x10\n\x08photo_id\x18\x01 \x01(\r\":\n\x14ThumbnailPathMessage\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x11\n\tfull_path\x18\x02 \x01(\t\"s\n\x11ThumbnailResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\r\n\x05image\x18\x03 \x01(\x0c\"&\n\x12\x44\x65letePhotoRequest\x12\x10\n\x08photo_id\x18\x01 \x01(\r\"f\n\x13\x44\x65letePhotoResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12\x0f\n\x07success\x18\x02 \x01(\x08\"\x1e\n\nPhotoTaken\x12\x10\n\x08photo_id\x18\x01 \x01(\r\"\xc1\x02\n\x11PathMotionProfile\x12\x12\n\nspeed_mmps\x18\x01 \x01(\x02\x12\x13\n\x0b\x61\x63\x63\x65l_mmps2\x18\x02 \x01(\x02\x12\x13\n\x0b\x64\x65\x63\x65l_mmps2\x18\x03 \x01(\x02\x12$\n\x1cpoint_turn_speed_rad_per_sec\x18\x04 \x01(\x02\x12%\n\x1dpoint_turn_accel_rad_per_sec2\x18\x05 \x01(\x02\x12%\n\x1dpoint_turn_decel_rad_per_sec2\x18\x06 \x01(\x02\x12\x17\n\x0f\x64ock_speed_mmps\x18\x07 \x01(\x02\x12\x18\n\x10\x64ock_accel_mmps2\x18\x08 \x01(\x02\x12\x18\n\x10\x64ock_decel_mmps2\x18\t \x01(\x02\x12\x1a\n\x12reverse_speed_mmps\x18\n \x01(\x02\x12\x11\n\tis_custom\x18\x0b \x01(\x08\"\xf8\x0c\n\x0c\x41\x63tionResult\x12K\n\x04\x63ode\x18\x01 \x01(\x0e\x32=.Anki.Vector.external_interface.ActionResult.ActionResultCode\"\x9a\x0c\n\x10\x41\x63tionResultCode\x12\x19\n\x15\x41\x43TION_RESULT_SUCCESS\x10\x00\x12\x1c\n\x15\x41\x43TION_RESULT_RUNNING\x10\x80\x80\x80\x08\x12,\n%ACTION_RESULT_CANCELLED_WHILE_RUNNING\x10\x80\x80\x80\x10\x12\x12\n\x0bNOT_STARTED\x10\x81\x80\x80\x10\x12\x0c\n\x05\x41\x42ORT\x10\x80\x80\x80\x18\x12\x13\n\x0c\x41NIM_ABORTED\x10\x81\x80\x80\x18\x12\x11\n\nBAD_MARKER\x10\x82\x80\x80\x18\x12\x16\n\x0f\x42\x41\x44_MESSAGE_TAG\x10\x83\x80\x80\x18\x12\x11\n\nBAD_OBJECT\x10\x84\x80\x80\x18\x12\x0f\n\x08\x42\x41\x44_POSE\x10\x85\x80\x80\x18\x12\x0e\n\x07\x42\x41\x44_TAG\x10\x86\x80\x80\x18\x12\x1e\n\x17\x43HARGER_UNPLUGGED_ABORT\x10\x87\x80\x80\x18\x12!\n\x1a\x43LIFF_ALIGN_FAILED_TIMEOUT\x10\x88\x80\x80\x18\x12$\n\x1d\x43LIFF_ALIGN_FAILED_NO_TURNING\x10\x89\x80\x80\x18\x12&\n\x1f\x43LIFF_ALIGN_FAILED_OVER_TURNING\x10\x8a\x80\x80\x18\x12\"\n\x1b\x43LIFF_ALIGN_FAILED_NO_WHITE\x10\x8b\x80\x80\x18\x12!\n\x1a\x43LIFF_ALIGN_FAILED_STOPPED\x10\x8c\x80\x80\x18\x12!\n\x1a\x46\x41ILED_SETTING_CALIBRATION\x10\x8d\x80\x80\x18\x12(\n!FOLLOWING_PATH_BUT_NOT_TRAVERSING\x10\x8e\x80\x80\x18\x12\x12\n\x0bINTERRUPTED\x10\x8f\x80\x80\x18\x12\x1f\n\x18INVALID_OFF_TREADS_STATE\x10\x90\x80\x80\x18\x12\x19\n\x12MISMATCHED_UP_AXIS\x10\x91\x80\x80\x18\x12\x13\n\x0cNO_ANIM_NAME\x10\x92\x80\x80\x18\x12\x16\n\x0fNO_DISTANCE_SET\x10\x93\x80\x80\x18\x12\x0e\n\x07NO_FACE\x10\x94\x80\x80\x18\x12\x12\n\x0bNO_GOAL_SET\x10\x95\x80\x80\x18\x12\x19\n\x12NO_PREACTION_POSES\x10\x96\x80\x80\x18\x12 \n\x19NOT_CARRYING_OBJECT_ABORT\x10\x97\x80\x80\x18\x12\x1b\n\x14NOT_ON_CHARGER_ABORT\x10\x98\x80\x80\x18\x12\x15\n\x0eNULL_SUBACTION\x10\x99\x80\x80\x18\x12!\n\x1aPATH_PLANNING_FAILED_ABORT\x10\x9a\x80\x80\x18\x12(\n!PICKUP_OBJECT_UNEXPECTEDLY_MOVING\x10\x9b\x80\x80\x18\x12#\n\x1cSEND_MESSAGE_TO_ROBOT_FAILED\x10\x9c\x80\x80\x18\x12\x1c\n\x15STILL_CARRYING_OBJECT\x10\x9d\x80\x80\x18\x12\x0e\n\x07TIMEOUT\x10\x9e\x80\x80\x18\x12\x14\n\rTRACKS_LOCKED\x10\x9f\x80\x80\x18\x12\x1d\n\x16UNEXPECTED_DOCK_ACTION\x10\xa0\x80\x80\x18\x12\x18\n\x11UNKNOWN_TOOL_CODE\x10\xa1\x80\x80\x18\x12\x1c\n\x15UPDATE_DERIVED_FAILED\x10\xa2\x80\x80\x18\x12 \n\x19VISUAL_OBSERVATION_FAILED\x10\xa3\x80\x80\x18\x12 \n\x19SHOULDNT_DRIVE_ON_CHARGER\x10\xa4\x80\x80\x18\x12\x0c\n\x05RETRY\x10\x80\x80\x80 \x12#\n\x1c\x44ID_NOT_REACH_PREACTION_POSE\x10\x81\x80\x80 \x12\x1d\n\x16\x46\x41ILED_TRAVERSING_PATH\x10\x82\x80\x80 \x12!\n\x1aLAST_PICK_AND_PLACE_FAILED\x10\x83\x80\x80 \x12$\n\x1dMOTOR_STOPPED_MAKING_PROGRESS\x10\x84\x80\x80 \x12 \n\x19NOT_CARRYING_OBJECT_RETRY\x10\x85\x80\x80 \x12\x1b\n\x14NOT_ON_CHARGER_RETRY\x10\x86\x80\x80 \x12!\n\x1aPATH_PLANNING_FAILED_RETRY\x10\x87\x80\x80 \x12\x1e\n\x17PLACEMENT_GOAL_NOT_FREE\x10\x88\x80\x80 \x12,\n%PICKUP_OBJECT_UNEXPECTEDLY_NOT_MOVING\x10\x89\x80\x80 \x12\x17\n\x10STILL_ON_CHARGER\x10\x8a\x80\x80 \x12\x1d\n\x16UNEXPECTED_PITCH_ANGLE\x10\x8b\x80\x80 \"\xa7\x01\n\x0fGoToPoseRequest\x12\x0c\n\x04x_mm\x18\x01 \x01(\x02\x12\x0c\n\x04y_mm\x18\x02 \x01(\x02\x12\x0b\n\x03rad\x18\x03 \x01(\x02\x12\x46\n\x0bmotion_prof\x18\x04 \x01(\x0b\x32\x31.Anki.Vector.external_interface.PathMotionProfile\x12\x0e\n\x06id_tag\x18\x05 \x01(\x05\x12\x13\n\x0bnum_retries\x18\x06 \x01(\x05\"\x90\x01\n\x10GoToPoseResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12<\n\x06result\x18\x02 \x01(\x0b\x32,.Anki.Vector.external_interface.ActionResult\"\xd0\x02\n\x13\x44ockWithCubeRequest\x12\x11\n\tobject_id\x18\x01 \x01(\x05\x12\x1f\n\x17\x64istance_from_marker_mm\x18\x02 \x01(\x02\x12\x1a\n\x12\x61pproach_angle_rad\x18\x03 \x01(\x02\x12\x45\n\x0e\x61lignment_type\x18\x04 \x01(\x0e\x32-.Anki.Vector.external_interface.AlignmentType\x12\x1a\n\x12use_approach_angle\x18\x05 \x01(\x08\x12\x19\n\x11use_pre_dock_pose\x18\x06 \x01(\x08\x12\x46\n\x0bmotion_prof\x18\x07 \x01(\x0b\x32\x31.Anki.Vector.external_interface.PathMotionProfile\x12\x0e\n\x06id_tag\x18\x08 \x01(\x05\x12\x13\n\x0bnum_retries\x18\t \x01(\x05\"\x94\x01\n\x14\x44ockWithCubeResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12<\n\x06result\x18\x02 \x01(\x0b\x32,.Anki.Vector.external_interface.ActionResult\"\x7f\n\x14\x44riveStraightRequest\x12\x12\n\nspeed_mmps\x18\x01 \x01(\x02\x12\x0f\n\x07\x64ist_mm\x18\x02 \x01(\x02\x12\x1d\n\x15should_play_animation\x18\x03 \x01(\x08\x12\x0e\n\x06id_tag\x18\x04 \x01(\x05\x12\x13\n\x0bnum_retries\x18\x05 \x01(\x05\"\x95\x01\n\x15\x44riveStraightResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12<\n\x06result\x18\x02 \x01(\x0b\x32,.Anki.Vector.external_interface.ActionResult\"\xa9\x01\n\x12TurnInPlaceRequest\x12\x11\n\tangle_rad\x18\x01 \x01(\x02\x12\x19\n\x11speed_rad_per_sec\x18\x02 \x01(\x02\x12\x1a\n\x12\x61\x63\x63\x65l_rad_per_sec2\x18\x03 \x01(\x02\x12\x0f\n\x07tol_rad\x18\x04 \x01(\x02\x12\x13\n\x0bis_absolute\x18\x05 \x01(\r\x12\x0e\n\x06id_tag\x18\x06 \x01(\x05\x12\x13\n\x0bnum_retries\x18\x07 \x01(\x05\"\x93\x01\n\x13TurnInPlaceResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12<\n\x06result\x18\x02 \x01(\x0b\x32,.Anki.Vector.external_interface.ActionResult\"\x9e\x01\n\x13SetHeadAngleRequest\x12\x11\n\tangle_rad\x18\x01 \x01(\x02\x12\x1d\n\x15max_speed_rad_per_sec\x18\x02 \x01(\x02\x12\x1a\n\x12\x61\x63\x63\x65l_rad_per_sec2\x18\x03 \x01(\x02\x12\x14\n\x0c\x64uration_sec\x18\x04 \x01(\x02\x12\x0e\n\x06id_tag\x18\x05 \x01(\x05\x12\x13\n\x0bnum_retries\x18\x06 \x01(\x05\"\x94\x01\n\x14SetHeadAngleResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12<\n\x06result\x18\x02 \x01(\x0b\x32,.Anki.Vector.external_interface.ActionResult\"\x9f\x01\n\x14SetLiftHeightRequest\x12\x11\n\theight_mm\x18\x01 \x01(\x02\x12\x1d\n\x15max_speed_rad_per_sec\x18\x02 \x01(\x02\x12\x1a\n\x12\x61\x63\x63\x65l_rad_per_sec2\x18\x03 \x01(\x02\x12\x14\n\x0c\x64uration_sec\x18\x04 \x01(\x02\x12\x0e\n\x06id_tag\x18\x05 \x01(\x05\x12\x13\n\x0bnum_retries\x18\x06 \x01(\x05\"\x95\x01\n\x15SetLiftHeightResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12<\n\x06result\x18\x02 \x01(\x0b\x32,.Anki.Vector.external_interface.ActionResult\"\xb9\x03\n\x0cNetworkStats\x12#\n\x1bg_net_stat1_num_connections\x18\x01 \x01(\x05\x12\x1f\n\x17g_net_stat2_latency_avg\x18\x02 \x01(\x02\x12\x1e\n\x16g_net_stat3_latency_sd\x18\x03 \x01(\x02\x12\x1f\n\x17g_net_stat4_latency_min\x18\x04 \x01(\x02\x12\x1f\n\x17g_net_stat5_latency_max\x18\x05 \x01(\x02\x12#\n\x1bg_net_stat6_ping_arrived_pc\x18\x06 \x01(\x02\x12%\n\x1dg_net_stat7_ext_queued_avg_ms\x18\x07 \x01(\x02\x12%\n\x1dg_net_stat8_ext_queued_min_ms\x18\x08 \x01(\x02\x12%\n\x1dg_net_stat9_ext_queued_max_ms\x18\t \x01(\x02\x12!\n\x19g_net_stata_queued_avg_ms\x18\n \x01(\x02\x12!\n\x19g_net_statb_queued_min_ms\x18\x0b \x01(\x02\x12!\n\x19g_net_statc_queued_max_ms\x18\x0c \x01(\x02\"\x15\n\x13\x42\x61tteryStateRequest\"\xc9\x02\n\x14\x42\x61tteryStateResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12\x43\n\rbattery_level\x18\x02 \x01(\x0e\x32,.Anki.Vector.external_interface.BatteryLevel\x12\x15\n\rbattery_volts\x18\x03 \x01(\x02\x12\x13\n\x0bis_charging\x18\x04 \x01(\x08\x12\x1e\n\x16is_on_charger_platform\x18\x05 \x01(\x08\x12\x1d\n\x15suggested_charger_sec\x18\x06 \x01(\x02\x12\x41\n\x0c\x63ube_battery\x18\x07 \x01(\x0b\x32+.Anki.Vector.external_interface.CubeBattery\"\xd3\x01\n\x0b\x43ubeBattery\x12K\n\x05level\x18\x01 \x01(\x0e\x32<.Anki.Vector.external_interface.CubeBattery.CubeBatteryLevel\x12\x12\n\nfactory_id\x18\x02 \x01(\t\x12\x15\n\rbattery_volts\x18\x03 \x01(\x02\x12#\n\x1btime_since_last_reading_sec\x18\x04 \x01(\x02\"\'\n\x10\x43ubeBatteryLevel\x12\x07\n\x03Low\x10\x00\x12\n\n\x06Normal\x10\x01\"\x15\n\x13VersionStateRequest\"\x83\x01\n\x14VersionStateResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12\x12\n\nos_version\x18\x02 \x01(\t\x12\x17\n\x0f\x65ngine_build_id\x18\x03 \x01(\t\"\x15\n\x13NetworkStateRequest\"\x9b\x01\n\x14NetworkStateResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12\x43\n\rnetwork_stats\x18\x02 \x01(\x0b\x32,.Anki.Vector.external_interface.NetworkStats\"Q\n\x0eSayTextRequest\x12\x0c\n\x04text\x18\x01 \x01(\t\x12\x18\n\x10use_vector_voice\x18\x02 \x01(\x08\x12\x17\n\x0f\x64uration_scalar\x18\x03 \x01(\x02\"\xf5\x01\n\x0fSayTextResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12M\n\x05state\x18\x02 \x01(\x0e\x32>.Anki.Vector.external_interface.SayTextResponse.UtteranceState\"S\n\x0eUtteranceState\x12\x0b\n\x07INVALID\x10\x00\x12\x0e\n\nGENERATING\x10\x01\x12\t\n\x05READY\x10\x02\x12\x0b\n\x07PLAYING\x10\x03\x12\x0c\n\x08\x46INISHED\x10\x04\"\x9b\x01\n\x0fStimulationInfo\x12\x16\n\x0e\x65motion_events\x18\x01 \x03(\t\x12\r\n\x05value\x18\x02 \x01(\x02\x12\x10\n\x08velocity\x18\x03 \x01(\x02\x12\r\n\x05\x61\x63\x63\x65l\x18\x04 \x01(\x02\x12\x1a\n\x12value_before_event\x18\x05 \x01(\x02\x12\x11\n\tmin_value\x18\x06 \x01(\x02\x12\x11\n\tmax_value\x18\x07 \x01(\x02\"Y\n\x14\x41udioSendModeRequest\x12\x41\n\x04mode\x18\x01 \x01(\x0e\x32\x33.Anki.Vector.external_interface.AudioProcessingMode\"Y\n\x14\x41udioSendModeChanged\x12\x41\n\x04mode\x18\x01 \x01(\x0e\x32\x33.Anki.Vector.external_interface.AudioProcessingMode\"\xe8\x01\n\nAudioChunk\x12\x18\n\x10robot_time_stamp\x18\x01 \x01(\r\x12\x10\n\x08group_id\x18\x02 \x01(\r\x12\x10\n\x08\x63hunk_id\x18\x03 \x01(\r\x12\x19\n\x11\x61udio_chunk_count\x18\x04 \x01(\r\x12\x14\n\x0csignal_power\x18\x05 \x01(\x0c\x12\x1b\n\x13\x64irection_strengths\x18\x06 \x01(\x0c\x12\x18\n\x10source_direction\x18\x07 \x01(\r\x12\x19\n\x11source_confidence\x18\x08 \x01(\r\x12\x19\n\x11noise_floor_power\x18\t \x01(\r\"\x12\n\x10\x41udioFeedRequest\"\xc8\x01\n\x11\x41udioFeedResponse\x12\x18\n\x10robot_time_stamp\x18\x01 \x01(\r\x12\x10\n\x08group_id\x18\x02 \x01(\r\x12\x14\n\x0csignal_power\x18\x03 \x01(\x0c\x12\x1b\n\x13\x64irection_strengths\x18\x04 \x01(\x0c\x12\x18\n\x10source_direction\x18\x05 \x01(\r\x12\x19\n\x11source_confidence\x18\x06 \x01(\r\x12\x19\n\x11noise_floor_power\x18\x07 \x01(\r:\x04\x80\xa6\x1d\x01\".\n\x1c\x45nableMarkerDetectionRequest\x12\x0e\n\x06\x65nable\x18\x01 \x01(\x08\"_\n\x1d\x45nableMarkerDetectionResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"\xb1\x01\n\x1a\x45nableFaceDetectionRequest\x12\x0e\n\x06\x65nable\x18\x01 \x01(\x08\x12\x1e\n\x16\x65nable_smile_detection\x18\x02 \x01(\x08\x12$\n\x1c\x65nable_expression_estimation\x18\x03 \x01(\x08\x12\x1e\n\x16\x65nable_blink_detection\x18\x04 \x01(\x08\x12\x1d\n\x15\x65nable_gaze_detection\x18\x05 \x01(\x08\"]\n\x1b\x45nableFaceDetectionResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\".\n\x1c\x45nableMotionDetectionRequest\x12\x0e\n\x06\x65nable\x18\x01 \x01(\x08\"_\n\x1d\x45nableMotionDetectionResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\")\n\x17\x45nableMirrorModeRequest\x12\x0e\n\x06\x65nable\x18\x01 \x01(\x08\"Z\n\x18\x45nableMirrorModeResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"\x14\n\x12MirrorModeDisabled\"-\n\x1b\x45nableImageStreamingRequest\x12\x0e\n\x06\x65nable\x18\x01 \x01(\x08\"^\n\x1c\x45nableImageStreamingResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"\x19\n\x17VisionModesAutoDisabled\"\xd1\x03\n\nImageChunk\x12\x18\n\x10\x66rame_time_stamp\x18\x01 \x01(\r\x12\x10\n\x08image_id\x18\x02 \x01(\r\x12\r\n\x05width\x18\x03 \x01(\r\x12\x0e\n\x06height\x18\x04 \x01(\r\x12P\n\x0eimage_encoding\x18\x05 \x01(\x0e\x32\x38.Anki.Vector.external_interface.ImageChunk.ImageEncoding\x12\x15\n\rdisplay_index\x18\x06 \x01(\r\x12\x19\n\x11image_chunk_count\x18\x07 \x01(\r\x12\x10\n\x08\x63hunk_id\x18\x08 \x01(\r\x12\x0c\n\x04\x64\x61ta\x18\t \x01(\x0c\"\xd3\x01\n\rImageEncoding\x12\x17\n\x13NONE_IMAGE_ENCODING\x10\x00\x12\x0c\n\x08RAW_GRAY\x10\x01\x12\x0b\n\x07RAW_RGB\x10\x02\x12\x08\n\x04YUYV\x10\x03\x12\x0c\n\x08YUV420SP\x10\x04\x12\t\n\x05\x42\x41YER\x10\x05\x12\r\n\tJPEG_GRAY\x10\x06\x12\x0e\n\nJPEG_COLOR\x10\x07\x12\x19\n\x15JPEG_COLOR_HALF_WIDTH\x10\x08\x12\x17\n\x13JPEG_MINIMIZED_GRAY\x10\t\x12\x18\n\x14JPEG_MINIMIZED_COLOR\x10\n\"\x13\n\x11\x43\x61meraFeedRequest\"\xa6\x01\n\x12\x43\x61meraFeedResponse\x12\x18\n\x10\x66rame_time_stamp\x18\x01 \x01(\r\x12\x10\n\x08image_id\x18\x02 \x01(\r\x12P\n\x0eimage_encoding\x18\x03 \x01(\x0e\x32\x38.Anki.Vector.external_interface.ImageChunk.ImageEncoding\x12\x0c\n\x04\x64\x61ta\x18\x04 \x01(\x0c:\x04\x80\xa6\x1d\x01\"5\n\x12SetEyeColorRequest\x12\x0b\n\x03hue\x18\x01 \x01(\x02\x12\x12\n\nsaturation\x18\x02 \x01(\x02\"U\n\x13SetEyeColorResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\"\x96\x01\n\x18SDKInitializationRequest\x12\x1a\n\x12sdk_module_version\x18\x01 \x01(\t\x12\x16\n\x0epython_version\x18\x02 \x01(\t\x12\x1d\n\x15python_implementation\x18\x03 \x01(\t\x12\x12\n\nos_version\x18\x04 \x01(\t\x12\x13\n\x0b\x63pu_version\x18\x05 \x01(\t\"[\n\x19SDKInitializationResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus*\xdc\x04\n\x0bRobotStatus\x12\x15\n\x11ROBOT_STATUS_NONE\x10\x00\x12\x1a\n\x16ROBOT_STATUS_IS_MOVING\x10\x01\x12\"\n\x1eROBOT_STATUS_IS_CARRYING_BLOCK\x10\x02\x12&\n\"ROBOT_STATUS_IS_PICKING_OR_PLACING\x10\x04\x12\x1d\n\x19ROBOT_STATUS_IS_PICKED_UP\x10\x08\x12\"\n\x1eROBOT_STATUS_IS_BUTTON_PRESSED\x10\x10\x12\x1b\n\x17ROBOT_STATUS_IS_FALLING\x10 \x12\x1d\n\x19ROBOT_STATUS_IS_ANIMATING\x10@\x12\x1c\n\x17ROBOT_STATUS_IS_PATHING\x10\x80\x01\x12\x1d\n\x18ROBOT_STATUS_LIFT_IN_POS\x10\x80\x02\x12\x1d\n\x18ROBOT_STATUS_HEAD_IN_POS\x10\x80\x04\x12!\n\x1cROBOT_STATUS_CALM_POWER_MODE\x10\x80\x08\x12\x1f\n\x1aROBOT_STATUS_IS_ON_CHARGER\x10\x80 \x12\x1d\n\x18ROBOT_STATUS_IS_CHARGING\x10\x80@\x12!\n\x1bROBOT_STATUS_CLIFF_DETECTED\x10\x80\x80\x01\x12$\n\x1eROBOT_STATUS_ARE_WHEELS_MOVING\x10\x80\x80\x02\x12 \n\x1aROBOT_STATUS_IS_BEING_HELD\x10\x80\x80\x04\x12%\n\x1fROBOT_STATUS_IS_MOTION_DETECTED\x10\x80\x80\x08*\xbd\x01\n\x10\x46\x61\x63ialExpression\x12\x16\n\x12\x45XPRESSION_UNKNOWN\x10\x00\x12\x16\n\x12\x45XPRESSION_NEUTRAL\x10\x01\x12\x18\n\x14\x45XPRESSION_HAPPINESS\x10\x02\x12\x17\n\x13\x45XPRESSION_SURPRISE\x10\x03\x12\x14\n\x10\x45XPRESSION_ANGER\x10\x04\x12\x16\n\x12\x45XPRESSION_SADNESS\x10\x05\x12\x14\n\x10\x45XPRESSION_COUNT\x10\x05\x1a\x02\x10\x01*\xcc\x01\n\x14\x46\x61\x63\x65\x45nrollmentResult\x12\x0b\n\x07SUCCESS\x10\x00\x12\x12\n\x0eSAW_WRONG_FACE\x10\x01\x12\x16\n\x12SAW_MULTIPLE_FACES\x10\x02\x12\r\n\tTIMED_OUT\x10\x03\x12\x0f\n\x0bSAVE_FAILED\x10\x04\x12\x0e\n\nINCOMPLETE\x10\x05\x12\r\n\tCANCELLED\x10\x06\x12\x0f\n\x0bNAME_IN_USE\x10\x07\x12\x16\n\x12NAMED_STORAGE_FULL\x10\x08\x12\x13\n\x0fUNKNOWN_FAILURE\x10\t*l\n\x0f\x42\x65haviorResults\x12\x1a\n\x16\x42\x45HAVIOR_INVALID_STATE\x10\x00\x12\x1b\n\x17\x42\x45HAVIOR_COMPLETE_STATE\x10\x01\x12 \n\x1c\x42\x45HAVIOR_WONT_ACTIVATE_STATE\x10\x02*S\n\x12\x41\x63tionTagConstants\x12\x13\n\x0fINVALID_SDK_TAG\x10\x00\x12\x13\n\rFIRST_SDK_TAG\x10\x81\x89z\x12\x13\n\x0cLAST_SDK_TAG\x10\xc0\x8d\xb7\x01*\x9e\x01\n\rAlignmentType\x12\x1a\n\x16\x41LIGNMENT_TYPE_UNKNOWN\x10\x00\x12\x1e\n\x1a\x41LIGNMENT_TYPE_LIFT_FINGER\x10\x01\x12\x1d\n\x19\x41LIGNMENT_TYPE_LIFT_PLATE\x10\x02\x12\x17\n\x13\x41LIGNMENT_TYPE_BODY\x10\x03\x12\x19\n\x15\x41LIGNMENT_TYPE_CUSTOM\x10\x04*s\n\x0c\x42\x61tteryLevel\x12\x19\n\x15\x42\x41TTERY_LEVEL_UNKNOWN\x10\x00\x12\x15\n\x11\x42\x41TTERY_LEVEL_LOW\x10\x01\x12\x19\n\x15\x42\x41TTERY_LEVEL_NOMINAL\x10\x02\x12\x16\n\x12\x42\x41TTERY_LEVEL_FULL\x10\x03*\xcc\x01\n\x0e\x41udioConstants\x12\x18\n\x14\x41UDIO_CONSTANTS_NULL\x10\x00\x12\x1c\n\x18MIC_DETECTION_DIRECTIONS\x10\x0c\x12%\n SAMPLE_COUNTS_PER_ENGINE_MESSAGE\x10\xa0\x01\x12\"\n\x1dSAMPLE_COUNTS_PER_SDK_MESSAGE\x10\xc0\x0c\x12\x1b\n\x16MICROPHONE_SAMPLE_RATE\x10\x89z\x12\x1a\n\x15PROCESSED_SAMPLE_RATE\x10\x80}*\x85\x01\n\x13\x41udioProcessingMode\x12\x11\n\rAUDIO_UNKNOWN\x10\x00\x12\r\n\tAUDIO_OFF\x10\x01\x12\x13\n\x0f\x41UDIO_FAST_MODE\x10\x02\x12\x1a\n\x16\x41UDIO_DIRECTIONAL_MODE\x10\x03\x12\x1b\n\x17\x41UDIO_VOICE_DETECT_MODE\x10\x04\x62\x06proto3') - , - dependencies=[anki__vector_dot_messaging_dot_response__status__pb2.DESCRIPTOR,anki__vector_dot_messaging_dot_extensions__pb2.DESCRIPTOR,]) - -_ROBOTSTATUS = _descriptor.EnumDescriptor( - name='RobotStatus', - full_name='Anki.Vector.external_interface.RobotStatus', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_NONE', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_IS_MOVING', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_IS_CARRYING_BLOCK', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_IS_PICKING_OR_PLACING', index=3, number=4, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_IS_PICKED_UP', index=4, number=8, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_IS_BUTTON_PRESSED', index=5, number=16, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_IS_FALLING', index=6, number=32, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_IS_ANIMATING', index=7, number=64, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_IS_PATHING', index=8, number=128, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_LIFT_IN_POS', index=9, number=256, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_HEAD_IN_POS', index=10, number=512, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_CALM_POWER_MODE', index=11, number=1024, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_IS_ON_CHARGER', index=12, number=4096, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_IS_CHARGING', index=13, number=8192, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_CLIFF_DETECTED', index=14, number=16384, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_ARE_WHEELS_MOVING', index=15, number=32768, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_IS_BEING_HELD', index=16, number=65536, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ROBOT_STATUS_IS_MOTION_DETECTED', index=17, number=131072, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=15131, - serialized_end=15735, -) -_sym_db.RegisterEnumDescriptor(_ROBOTSTATUS) - -RobotStatus = enum_type_wrapper.EnumTypeWrapper(_ROBOTSTATUS) -_FACIALEXPRESSION = _descriptor.EnumDescriptor( - name='FacialExpression', - full_name='Anki.Vector.external_interface.FacialExpression', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='EXPRESSION_UNKNOWN', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='EXPRESSION_NEUTRAL', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='EXPRESSION_HAPPINESS', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='EXPRESSION_SURPRISE', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='EXPRESSION_ANGER', index=4, number=4, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='EXPRESSION_SADNESS', index=5, number=5, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='EXPRESSION_COUNT', index=6, number=5, - options=None, - type=None), - ], - containing_type=None, - options=_descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\020\001')), - serialized_start=15738, - serialized_end=15927, -) -_sym_db.RegisterEnumDescriptor(_FACIALEXPRESSION) - -FacialExpression = enum_type_wrapper.EnumTypeWrapper(_FACIALEXPRESSION) -_FACEENROLLMENTRESULT = _descriptor.EnumDescriptor( - name='FaceEnrollmentResult', - full_name='Anki.Vector.external_interface.FaceEnrollmentResult', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='SUCCESS', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='SAW_WRONG_FACE', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='SAW_MULTIPLE_FACES', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='TIMED_OUT', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='SAVE_FAILED', index=4, number=4, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='INCOMPLETE', index=5, number=5, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CANCELLED', index=6, number=6, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NAME_IN_USE', index=7, number=7, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NAMED_STORAGE_FULL', index=8, number=8, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='UNKNOWN_FAILURE', index=9, number=9, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=15930, - serialized_end=16134, -) -_sym_db.RegisterEnumDescriptor(_FACEENROLLMENTRESULT) - -FaceEnrollmentResult = enum_type_wrapper.EnumTypeWrapper(_FACEENROLLMENTRESULT) -_BEHAVIORRESULTS = _descriptor.EnumDescriptor( - name='BehaviorResults', - full_name='Anki.Vector.external_interface.BehaviorResults', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='BEHAVIOR_INVALID_STATE', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='BEHAVIOR_COMPLETE_STATE', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='BEHAVIOR_WONT_ACTIVATE_STATE', index=2, number=2, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=16136, - serialized_end=16244, -) -_sym_db.RegisterEnumDescriptor(_BEHAVIORRESULTS) - -BehaviorResults = enum_type_wrapper.EnumTypeWrapper(_BEHAVIORRESULTS) -_ACTIONTAGCONSTANTS = _descriptor.EnumDescriptor( - name='ActionTagConstants', - full_name='Anki.Vector.external_interface.ActionTagConstants', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='INVALID_SDK_TAG', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='FIRST_SDK_TAG', index=1, number=2000001, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='LAST_SDK_TAG', index=2, number=3000000, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=16246, - serialized_end=16329, -) -_sym_db.RegisterEnumDescriptor(_ACTIONTAGCONSTANTS) - -ActionTagConstants = enum_type_wrapper.EnumTypeWrapper(_ACTIONTAGCONSTANTS) -_ALIGNMENTTYPE = _descriptor.EnumDescriptor( - name='AlignmentType', - full_name='Anki.Vector.external_interface.AlignmentType', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='ALIGNMENT_TYPE_UNKNOWN', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ALIGNMENT_TYPE_LIFT_FINGER', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ALIGNMENT_TYPE_LIFT_PLATE', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ALIGNMENT_TYPE_BODY', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ALIGNMENT_TYPE_CUSTOM', index=4, number=4, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=16332, - serialized_end=16490, -) -_sym_db.RegisterEnumDescriptor(_ALIGNMENTTYPE) - -AlignmentType = enum_type_wrapper.EnumTypeWrapper(_ALIGNMENTTYPE) -_BATTERYLEVEL = _descriptor.EnumDescriptor( - name='BatteryLevel', - full_name='Anki.Vector.external_interface.BatteryLevel', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='BATTERY_LEVEL_UNKNOWN', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='BATTERY_LEVEL_LOW', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='BATTERY_LEVEL_NOMINAL', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='BATTERY_LEVEL_FULL', index=3, number=3, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=16492, - serialized_end=16607, -) -_sym_db.RegisterEnumDescriptor(_BATTERYLEVEL) - -BatteryLevel = enum_type_wrapper.EnumTypeWrapper(_BATTERYLEVEL) -_AUDIOCONSTANTS = _descriptor.EnumDescriptor( - name='AudioConstants', - full_name='Anki.Vector.external_interface.AudioConstants', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='AUDIO_CONSTANTS_NULL', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MIC_DETECTION_DIRECTIONS', index=1, number=12, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='SAMPLE_COUNTS_PER_ENGINE_MESSAGE', index=2, number=160, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='SAMPLE_COUNTS_PER_SDK_MESSAGE', index=3, number=1600, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MICROPHONE_SAMPLE_RATE', index=4, number=15625, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='PROCESSED_SAMPLE_RATE', index=5, number=16000, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=16610, - serialized_end=16814, -) -_sym_db.RegisterEnumDescriptor(_AUDIOCONSTANTS) - -AudioConstants = enum_type_wrapper.EnumTypeWrapper(_AUDIOCONSTANTS) -_AUDIOPROCESSINGMODE = _descriptor.EnumDescriptor( - name='AudioProcessingMode', - full_name='Anki.Vector.external_interface.AudioProcessingMode', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='AUDIO_UNKNOWN', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='AUDIO_OFF', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='AUDIO_FAST_MODE', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='AUDIO_DIRECTIONAL_MODE', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='AUDIO_VOICE_DETECT_MODE', index=4, number=4, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=16817, - serialized_end=16950, -) -_sym_db.RegisterEnumDescriptor(_AUDIOPROCESSINGMODE) - -AudioProcessingMode = enum_type_wrapper.EnumTypeWrapper(_AUDIOPROCESSINGMODE) -ROBOT_STATUS_NONE = 0 -ROBOT_STATUS_IS_MOVING = 1 -ROBOT_STATUS_IS_CARRYING_BLOCK = 2 -ROBOT_STATUS_IS_PICKING_OR_PLACING = 4 -ROBOT_STATUS_IS_PICKED_UP = 8 -ROBOT_STATUS_IS_BUTTON_PRESSED = 16 -ROBOT_STATUS_IS_FALLING = 32 -ROBOT_STATUS_IS_ANIMATING = 64 -ROBOT_STATUS_IS_PATHING = 128 -ROBOT_STATUS_LIFT_IN_POS = 256 -ROBOT_STATUS_HEAD_IN_POS = 512 -ROBOT_STATUS_CALM_POWER_MODE = 1024 -ROBOT_STATUS_IS_ON_CHARGER = 4096 -ROBOT_STATUS_IS_CHARGING = 8192 -ROBOT_STATUS_CLIFF_DETECTED = 16384 -ROBOT_STATUS_ARE_WHEELS_MOVING = 32768 -ROBOT_STATUS_IS_BEING_HELD = 65536 -ROBOT_STATUS_IS_MOTION_DETECTED = 131072 -EXPRESSION_UNKNOWN = 0 -EXPRESSION_NEUTRAL = 1 -EXPRESSION_HAPPINESS = 2 -EXPRESSION_SURPRISE = 3 -EXPRESSION_ANGER = 4 -EXPRESSION_SADNESS = 5 -EXPRESSION_COUNT = 5 -SUCCESS = 0 -SAW_WRONG_FACE = 1 -SAW_MULTIPLE_FACES = 2 -TIMED_OUT = 3 -SAVE_FAILED = 4 -INCOMPLETE = 5 -CANCELLED = 6 -NAME_IN_USE = 7 -NAMED_STORAGE_FULL = 8 -UNKNOWN_FAILURE = 9 -BEHAVIOR_INVALID_STATE = 0 -BEHAVIOR_COMPLETE_STATE = 1 -BEHAVIOR_WONT_ACTIVATE_STATE = 2 -INVALID_SDK_TAG = 0 -FIRST_SDK_TAG = 2000001 -LAST_SDK_TAG = 3000000 -ALIGNMENT_TYPE_UNKNOWN = 0 -ALIGNMENT_TYPE_LIFT_FINGER = 1 -ALIGNMENT_TYPE_LIFT_PLATE = 2 -ALIGNMENT_TYPE_BODY = 3 -ALIGNMENT_TYPE_CUSTOM = 4 -BATTERY_LEVEL_UNKNOWN = 0 -BATTERY_LEVEL_LOW = 1 -BATTERY_LEVEL_NOMINAL = 2 -BATTERY_LEVEL_FULL = 3 -AUDIO_CONSTANTS_NULL = 0 -MIC_DETECTION_DIRECTIONS = 12 -SAMPLE_COUNTS_PER_ENGINE_MESSAGE = 160 -SAMPLE_COUNTS_PER_SDK_MESSAGE = 1600 -MICROPHONE_SAMPLE_RATE = 15625 -PROCESSED_SAMPLE_RATE = 16000 -AUDIO_UNKNOWN = 0 -AUDIO_OFF = 1 -AUDIO_FAST_MODE = 2 -AUDIO_DIRECTIONAL_MODE = 3 -AUDIO_VOICE_DETECT_MODE = 4 - - -_ACTIONRESULT_ACTIONRESULTCODE = _descriptor.EnumDescriptor( - name='ActionResultCode', - full_name='Anki.Vector.external_interface.ActionResult.ActionResultCode', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='ACTION_RESULT_SUCCESS', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ACTION_RESULT_RUNNING', index=1, number=16777216, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ACTION_RESULT_CANCELLED_WHILE_RUNNING', index=2, number=33554432, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NOT_STARTED', index=3, number=33554433, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ABORT', index=4, number=50331648, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ANIM_ABORTED', index=5, number=50331649, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='BAD_MARKER', index=6, number=50331650, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='BAD_MESSAGE_TAG', index=7, number=50331651, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='BAD_OBJECT', index=8, number=50331652, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='BAD_POSE', index=9, number=50331653, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='BAD_TAG', index=10, number=50331654, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CHARGER_UNPLUGGED_ABORT', index=11, number=50331655, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CLIFF_ALIGN_FAILED_TIMEOUT', index=12, number=50331656, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CLIFF_ALIGN_FAILED_NO_TURNING', index=13, number=50331657, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CLIFF_ALIGN_FAILED_OVER_TURNING', index=14, number=50331658, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CLIFF_ALIGN_FAILED_NO_WHITE', index=15, number=50331659, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CLIFF_ALIGN_FAILED_STOPPED', index=16, number=50331660, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='FAILED_SETTING_CALIBRATION', index=17, number=50331661, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='FOLLOWING_PATH_BUT_NOT_TRAVERSING', index=18, number=50331662, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='INTERRUPTED', index=19, number=50331663, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='INVALID_OFF_TREADS_STATE', index=20, number=50331664, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MISMATCHED_UP_AXIS', index=21, number=50331665, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NO_ANIM_NAME', index=22, number=50331666, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NO_DISTANCE_SET', index=23, number=50331667, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NO_FACE', index=24, number=50331668, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NO_GOAL_SET', index=25, number=50331669, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NO_PREACTION_POSES', index=26, number=50331670, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NOT_CARRYING_OBJECT_ABORT', index=27, number=50331671, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NOT_ON_CHARGER_ABORT', index=28, number=50331672, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NULL_SUBACTION', index=29, number=50331673, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='PATH_PLANNING_FAILED_ABORT', index=30, number=50331674, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='PICKUP_OBJECT_UNEXPECTEDLY_MOVING', index=31, number=50331675, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='SEND_MESSAGE_TO_ROBOT_FAILED', index=32, number=50331676, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='STILL_CARRYING_OBJECT', index=33, number=50331677, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='TIMEOUT', index=34, number=50331678, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='TRACKS_LOCKED', index=35, number=50331679, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='UNEXPECTED_DOCK_ACTION', index=36, number=50331680, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='UNKNOWN_TOOL_CODE', index=37, number=50331681, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='UPDATE_DERIVED_FAILED', index=38, number=50331682, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='VISUAL_OBSERVATION_FAILED', index=39, number=50331683, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='SHOULDNT_DRIVE_ON_CHARGER', index=40, number=50331684, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='RETRY', index=41, number=67108864, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='DID_NOT_REACH_PREACTION_POSE', index=42, number=67108865, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='FAILED_TRAVERSING_PATH', index=43, number=67108866, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='LAST_PICK_AND_PLACE_FAILED', index=44, number=67108867, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MOTOR_STOPPED_MAKING_PROGRESS', index=45, number=67108868, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NOT_CARRYING_OBJECT_RETRY', index=46, number=67108869, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NOT_ON_CHARGER_RETRY', index=47, number=67108870, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='PATH_PLANNING_FAILED_RETRY', index=48, number=67108871, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='PLACEMENT_GOAL_NOT_FREE', index=49, number=67108872, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='PICKUP_OBJECT_UNEXPECTEDLY_NOT_MOVING', index=50, number=67108873, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='STILL_ON_CHARGER', index=51, number=67108874, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='UNEXPECTED_PITCH_ANGLE', index=52, number=67108875, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=7112, - serialized_end=8674, -) -_sym_db.RegisterEnumDescriptor(_ACTIONRESULT_ACTIONRESULTCODE) - -_CUBEBATTERY_CUBEBATTERYLEVEL = _descriptor.EnumDescriptor( - name='CubeBatteryLevel', - full_name='Anki.Vector.external_interface.CubeBattery.CubeBatteryLevel', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='Low', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='Normal', index=1, number=1, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=11684, - serialized_end=11723, -) -_sym_db.RegisterEnumDescriptor(_CUBEBATTERY_CUBEBATTERYLEVEL) - -_SAYTEXTRESPONSE_UTTERANCESTATE = _descriptor.EnumDescriptor( - name='UtteranceState', - full_name='Anki.Vector.external_interface.SayTextResponse.UtteranceState', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='INVALID', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='GENERATING', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='READY', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='PLAYING', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='FINISHED', index=4, number=4, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=12309, - serialized_end=12392, -) -_sym_db.RegisterEnumDescriptor(_SAYTEXTRESPONSE_UTTERANCESTATE) - -_IMAGECHUNK_IMAGEENCODING = _descriptor.EnumDescriptor( - name='ImageEncoding', - full_name='Anki.Vector.external_interface.ImageChunk.ImageEncoding', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='NONE_IMAGE_ENCODING', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='RAW_GRAY', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='RAW_RGB', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='YUYV', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='YUV420SP', index=4, number=4, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='BAYER', index=5, number=5, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='JPEG_GRAY', index=6, number=6, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='JPEG_COLOR', index=7, number=7, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='JPEG_COLOR_HALF_WIDTH', index=8, number=8, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='JPEG_MINIMIZED_GRAY', index=9, number=9, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='JPEG_MINIMIZED_COLOR', index=10, number=10, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=14339, - serialized_end=14550, -) -_sym_db.RegisterEnumDescriptor(_IMAGECHUNK_IMAGEENCODING) - - -_KEEPALIVEPING = _descriptor.Descriptor( - name='KeepAlivePing', - full_name='Anki.Vector.external_interface.KeepAlivePing', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=157, - serialized_end=172, -) - - -_ANIMATION = _descriptor.Descriptor( - name='Animation', - full_name='Anki.Vector.external_interface.Animation', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='Anki.Vector.external_interface.Animation.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=174, - serialized_end=199, -) - - -_DRIVEWHEELSREQUEST = _descriptor.Descriptor( - name='DriveWheelsRequest', - full_name='Anki.Vector.external_interface.DriveWheelsRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='left_wheel_mmps', full_name='Anki.Vector.external_interface.DriveWheelsRequest.left_wheel_mmps', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='right_wheel_mmps', full_name='Anki.Vector.external_interface.DriveWheelsRequest.right_wheel_mmps', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='left_wheel_mmps2', full_name='Anki.Vector.external_interface.DriveWheelsRequest.left_wheel_mmps2', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='right_wheel_mmps2', full_name='Anki.Vector.external_interface.DriveWheelsRequest.right_wheel_mmps2', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=201, - serialized_end=325, -) - - -_DRIVEWHEELSRESPONSE = _descriptor.Descriptor( - name='DriveWheelsResponse', - full_name='Anki.Vector.external_interface.DriveWheelsResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.DriveWheelsResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=327, - serialized_end=412, -) - - -_MOVEHEADREQUEST = _descriptor.Descriptor( - name='MoveHeadRequest', - full_name='Anki.Vector.external_interface.MoveHeadRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='speed_rad_per_sec', full_name='Anki.Vector.external_interface.MoveHeadRequest.speed_rad_per_sec', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=414, - serialized_end=458, -) - - -_MOVEHEADRESPONSE = _descriptor.Descriptor( - name='MoveHeadResponse', - full_name='Anki.Vector.external_interface.MoveHeadResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.MoveHeadResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=460, - serialized_end=542, -) - - -_MOVELIFTREQUEST = _descriptor.Descriptor( - name='MoveLiftRequest', - full_name='Anki.Vector.external_interface.MoveLiftRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='speed_rad_per_sec', full_name='Anki.Vector.external_interface.MoveLiftRequest.speed_rad_per_sec', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=544, - serialized_end=588, -) - - -_MOVELIFTRESPONSE = _descriptor.Descriptor( - name='MoveLiftResponse', - full_name='Anki.Vector.external_interface.MoveLiftResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.MoveLiftResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=590, - serialized_end=672, -) - - -_PLAYANIMATIONREQUEST = _descriptor.Descriptor( - name='PlayAnimationRequest', - full_name='Anki.Vector.external_interface.PlayAnimationRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='animation', full_name='Anki.Vector.external_interface.PlayAnimationRequest.animation', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='loops', full_name='Anki.Vector.external_interface.PlayAnimationRequest.loops', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='ignore_body_track', full_name='Anki.Vector.external_interface.PlayAnimationRequest.ignore_body_track', index=2, - number=3, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='ignore_head_track', full_name='Anki.Vector.external_interface.PlayAnimationRequest.ignore_head_track', index=3, - number=4, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='ignore_lift_track', full_name='Anki.Vector.external_interface.PlayAnimationRequest.ignore_lift_track', index=4, - number=5, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=675, - serialized_end=855, -) - - -_PLAYANIMATIONRESPONSE = _descriptor.Descriptor( - name='PlayAnimationResponse', - full_name='Anki.Vector.external_interface.PlayAnimationResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.PlayAnimationResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='result', full_name='Anki.Vector.external_interface.PlayAnimationResponse.result', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=858, - serialized_end=1010, -) - - -_LISTANIMATIONSREQUEST = _descriptor.Descriptor( - name='ListAnimationsRequest', - full_name='Anki.Vector.external_interface.ListAnimationsRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1012, - serialized_end=1035, -) - - -_LISTANIMATIONSRESPONSE = _descriptor.Descriptor( - name='ListAnimationsResponse', - full_name='Anki.Vector.external_interface.ListAnimationsResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.ListAnimationsResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='animation_names', full_name='Anki.Vector.external_interface.ListAnimationsResponse.animation_names', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1038, - serialized_end=1194, -) - - -_DISPLAYFACEIMAGERGBREQUEST = _descriptor.Descriptor( - name='DisplayFaceImageRGBRequest', - full_name='Anki.Vector.external_interface.DisplayFaceImageRGBRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='face_data', full_name='Anki.Vector.external_interface.DisplayFaceImageRGBRequest.face_data', index=0, - number=1, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='duration_ms', full_name='Anki.Vector.external_interface.DisplayFaceImageRGBRequest.duration_ms', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='interrupt_running', full_name='Anki.Vector.external_interface.DisplayFaceImageRGBRequest.interrupt_running', index=2, - number=3, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1196, - serialized_end=1291, -) - - -_DISPLAYFACEIMAGERGBRESPONSE = _descriptor.Descriptor( - name='DisplayFaceImageRGBResponse', - full_name='Anki.Vector.external_interface.DisplayFaceImageRGBResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.DisplayFaceImageRGBResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1293, - serialized_end=1386, -) - - -_MEETVICTORFACESCANSTARTED = _descriptor.Descriptor( - name='MeetVictorFaceScanStarted', - full_name='Anki.Vector.external_interface.MeetVictorFaceScanStarted', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1388, - serialized_end=1415, -) - - -_MEETVICTORFACESCANCOMPLETE = _descriptor.Descriptor( - name='MeetVictorFaceScanComplete', - full_name='Anki.Vector.external_interface.MeetVictorFaceScanComplete', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1417, - serialized_end=1445, -) - - -_STATUS = _descriptor.Descriptor( - name='Status', - full_name='Anki.Vector.external_interface.Status', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='meet_victor_face_scan_started', full_name='Anki.Vector.external_interface.Status.meet_victor_face_scan_started', index=0, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='meet_victor_face_scan_complete', full_name='Anki.Vector.external_interface.Status.meet_victor_face_scan_complete', index=1, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='face_enrollment_completed', full_name='Anki.Vector.external_interface.Status.face_enrollment_completed', index=2, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='status_type', full_name='Anki.Vector.external_interface.Status.status_type', - index=0, containing_type=None, fields=[]), - ], - serialized_start=1448, - serialized_end=1767, -) - - -_WAKEWORD = _descriptor.Descriptor( - name='WakeWord', - full_name='Anki.Vector.external_interface.WakeWord', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='wake_word_begin', full_name='Anki.Vector.external_interface.WakeWord.wake_word_begin', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='wake_word_end', full_name='Anki.Vector.external_interface.WakeWord.wake_word_end', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='wake_word_type', full_name='Anki.Vector.external_interface.WakeWord.wake_word_type', - index=0, containing_type=None, fields=[]), - ], - serialized_start=1770, - serialized_end=1942, -) - - -_TIMESTAMPEDSTATUS = _descriptor.Descriptor( - name='TimeStampedStatus', - full_name='Anki.Vector.external_interface.TimeStampedStatus', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.TimeStampedStatus.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='timestamp_utc', full_name='Anki.Vector.external_interface.TimeStampedStatus.timestamp_utc', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1944, - serialized_end=2042, -) - - -_POSESTRUCT = _descriptor.Descriptor( - name='PoseStruct', - full_name='Anki.Vector.external_interface.PoseStruct', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='x', full_name='Anki.Vector.external_interface.PoseStruct.x', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='y', full_name='Anki.Vector.external_interface.PoseStruct.y', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='z', full_name='Anki.Vector.external_interface.PoseStruct.z', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='q0', full_name='Anki.Vector.external_interface.PoseStruct.q0', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='q1', full_name='Anki.Vector.external_interface.PoseStruct.q1', index=4, - number=5, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='q2', full_name='Anki.Vector.external_interface.PoseStruct.q2', index=5, - number=6, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='q3', full_name='Anki.Vector.external_interface.PoseStruct.q3', index=6, - number=7, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='origin_id', full_name='Anki.Vector.external_interface.PoseStruct.origin_id', index=7, - number=8, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2044, - serialized_end=2156, -) - - -_ACCELDATA = _descriptor.Descriptor( - name='AccelData', - full_name='Anki.Vector.external_interface.AccelData', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='x', full_name='Anki.Vector.external_interface.AccelData.x', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='y', full_name='Anki.Vector.external_interface.AccelData.y', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='z', full_name='Anki.Vector.external_interface.AccelData.z', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2158, - serialized_end=2202, -) - - -_GYRODATA = _descriptor.Descriptor( - name='GyroData', - full_name='Anki.Vector.external_interface.GyroData', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='x', full_name='Anki.Vector.external_interface.GyroData.x', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='y', full_name='Anki.Vector.external_interface.GyroData.y', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='z', full_name='Anki.Vector.external_interface.GyroData.z', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2204, - serialized_end=2247, -) - - -_PROXDATA = _descriptor.Descriptor( - name='ProxData', - full_name='Anki.Vector.external_interface.ProxData', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='distance_mm', full_name='Anki.Vector.external_interface.ProxData.distance_mm', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='signal_quality', full_name='Anki.Vector.external_interface.ProxData.signal_quality', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='is_in_valid_range', full_name='Anki.Vector.external_interface.ProxData.is_in_valid_range', index=2, - number=3, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='is_valid_signal_quality', full_name='Anki.Vector.external_interface.ProxData.is_valid_signal_quality', index=3, - number=4, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='is_lift_in_fov', full_name='Anki.Vector.external_interface.ProxData.is_lift_in_fov', index=4, - number=5, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='is_too_pitched', full_name='Anki.Vector.external_interface.ProxData.is_too_pitched', index=5, - number=6, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2250, - serialized_end=2413, -) - - -_TOUCHDATA = _descriptor.Descriptor( - name='TouchData', - full_name='Anki.Vector.external_interface.TouchData', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='raw_touch_value', full_name='Anki.Vector.external_interface.TouchData.raw_touch_value', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='is_being_touched', full_name='Anki.Vector.external_interface.TouchData.is_being_touched', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2415, - serialized_end=2477, -) - - -_ROBOTSTATE = _descriptor.Descriptor( - name='RobotState', - full_name='Anki.Vector.external_interface.RobotState', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='pose', full_name='Anki.Vector.external_interface.RobotState.pose', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='pose_angle_rad', full_name='Anki.Vector.external_interface.RobotState.pose_angle_rad', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='pose_pitch_rad', full_name='Anki.Vector.external_interface.RobotState.pose_pitch_rad', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='left_wheel_speed_mmps', full_name='Anki.Vector.external_interface.RobotState.left_wheel_speed_mmps', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='right_wheel_speed_mmps', full_name='Anki.Vector.external_interface.RobotState.right_wheel_speed_mmps', index=4, - number=5, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='head_angle_rad', full_name='Anki.Vector.external_interface.RobotState.head_angle_rad', index=5, - number=6, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='lift_height_mm', full_name='Anki.Vector.external_interface.RobotState.lift_height_mm', index=6, - number=7, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='accel', full_name='Anki.Vector.external_interface.RobotState.accel', index=7, - number=8, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='gyro', full_name='Anki.Vector.external_interface.RobotState.gyro', index=8, - number=9, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='carrying_object_id', full_name='Anki.Vector.external_interface.RobotState.carrying_object_id', index=9, - number=10, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='carrying_object_on_top_id', full_name='Anki.Vector.external_interface.RobotState.carrying_object_on_top_id', index=10, - number=11, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='head_tracking_object_id', full_name='Anki.Vector.external_interface.RobotState.head_tracking_object_id', index=11, - number=12, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='localized_to_object_id', full_name='Anki.Vector.external_interface.RobotState.localized_to_object_id', index=12, - number=13, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='last_image_time_stamp', full_name='Anki.Vector.external_interface.RobotState.last_image_time_stamp', index=13, - number=14, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.RobotState.status', index=14, - number=15, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='prox_data', full_name='Anki.Vector.external_interface.RobotState.prox_data', index=15, - number=16, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='touch_data', full_name='Anki.Vector.external_interface.RobotState.touch_data', index=16, - number=17, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2480, - serialized_end=3122, -) - - -_CLADPOINT = _descriptor.Descriptor( - name='CladPoint', - full_name='Anki.Vector.external_interface.CladPoint', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='x', full_name='Anki.Vector.external_interface.CladPoint.x', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='y', full_name='Anki.Vector.external_interface.CladPoint.y', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3124, - serialized_end=3157, -) - - -_CLADRECT = _descriptor.Descriptor( - name='CladRect', - full_name='Anki.Vector.external_interface.CladRect', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='x_top_left', full_name='Anki.Vector.external_interface.CladRect.x_top_left', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='y_top_left', full_name='Anki.Vector.external_interface.CladRect.y_top_left', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='width', full_name='Anki.Vector.external_interface.CladRect.width', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='height', full_name='Anki.Vector.external_interface.CladRect.height', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3159, - serialized_end=3240, -) - - -_ROBOTOBSERVEDFACE = _descriptor.Descriptor( - name='RobotObservedFace', - full_name='Anki.Vector.external_interface.RobotObservedFace', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='face_id', full_name='Anki.Vector.external_interface.RobotObservedFace.face_id', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='timestamp', full_name='Anki.Vector.external_interface.RobotObservedFace.timestamp', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='pose', full_name='Anki.Vector.external_interface.RobotObservedFace.pose', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='img_rect', full_name='Anki.Vector.external_interface.RobotObservedFace.img_rect', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='name', full_name='Anki.Vector.external_interface.RobotObservedFace.name', index=4, - number=5, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='expression', full_name='Anki.Vector.external_interface.RobotObservedFace.expression', index=5, - number=6, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='expression_values', full_name='Anki.Vector.external_interface.RobotObservedFace.expression_values', index=6, - number=7, type=13, cpp_type=3, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='left_eye', full_name='Anki.Vector.external_interface.RobotObservedFace.left_eye', index=7, - number=8, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='right_eye', full_name='Anki.Vector.external_interface.RobotObservedFace.right_eye', index=8, - number=9, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='nose', full_name='Anki.Vector.external_interface.RobotObservedFace.nose', index=9, - number=10, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='mouth', full_name='Anki.Vector.external_interface.RobotObservedFace.mouth', index=10, - number=11, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3243, - serialized_end=3765, -) - - -_ROBOTCHANGEDOBSERVEDFACEID = _descriptor.Descriptor( - name='RobotChangedObservedFaceID', - full_name='Anki.Vector.external_interface.RobotChangedObservedFaceID', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='old_id', full_name='Anki.Vector.external_interface.RobotChangedObservedFaceID.old_id', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='new_id', full_name='Anki.Vector.external_interface.RobotChangedObservedFaceID.new_id', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3767, - serialized_end=3827, -) - - -_APPINTENTREQUEST = _descriptor.Descriptor( - name='AppIntentRequest', - full_name='Anki.Vector.external_interface.AppIntentRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='intent', full_name='Anki.Vector.external_interface.AppIntentRequest.intent', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='param', full_name='Anki.Vector.external_interface.AppIntentRequest.param', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3829, - serialized_end=3878, -) - - -_APPDISCONNECTED = _descriptor.Descriptor( - name='AppDisconnected', - full_name='Anki.Vector.external_interface.AppDisconnected', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3880, - serialized_end=3897, -) - - -_APPINTENTRESPONSE = _descriptor.Descriptor( - name='AppIntentResponse', - full_name='Anki.Vector.external_interface.AppIntentResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.AppIntentResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3899, - serialized_end=3982, -) - - -_FACEENROLLMENTCOMPLETED = _descriptor.Descriptor( - name='FaceEnrollmentCompleted', - full_name='Anki.Vector.external_interface.FaceEnrollmentCompleted', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='result', full_name='Anki.Vector.external_interface.FaceEnrollmentCompleted.result', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='face_id', full_name='Anki.Vector.external_interface.FaceEnrollmentCompleted.face_id', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='name', full_name='Anki.Vector.external_interface.FaceEnrollmentCompleted.name', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3984, - serialized_end=4110, -) - - -_CANCELFACEENROLLMENTREQUEST = _descriptor.Descriptor( - name='CancelFaceEnrollmentRequest', - full_name='Anki.Vector.external_interface.CancelFaceEnrollmentRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4112, - serialized_end=4141, -) - - -_CANCELFACEENROLLMENTRESPONSE = _descriptor.Descriptor( - name='CancelFaceEnrollmentResponse', - full_name='Anki.Vector.external_interface.CancelFaceEnrollmentResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.CancelFaceEnrollmentResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4143, - serialized_end=4237, -) - - -_REQUESTENROLLEDNAMESREQUEST = _descriptor.Descriptor( - name='RequestEnrolledNamesRequest', - full_name='Anki.Vector.external_interface.RequestEnrolledNamesRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4239, - serialized_end=4268, -) - - -_LOADEDKNOWNFACE = _descriptor.Descriptor( - name='LoadedKnownFace', - full_name='Anki.Vector.external_interface.LoadedKnownFace', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='seconds_since_first_enrolled', full_name='Anki.Vector.external_interface.LoadedKnownFace.seconds_since_first_enrolled', index=0, - number=1, type=3, cpp_type=2, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='seconds_since_last_updated', full_name='Anki.Vector.external_interface.LoadedKnownFace.seconds_since_last_updated', index=1, - number=2, type=3, cpp_type=2, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='seconds_since_last_seen', full_name='Anki.Vector.external_interface.LoadedKnownFace.seconds_since_last_seen', index=2, - number=3, type=3, cpp_type=2, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='last_seen_seconds_since_epoch', full_name='Anki.Vector.external_interface.LoadedKnownFace.last_seen_seconds_since_epoch', index=3, - number=4, type=3, cpp_type=2, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='face_id', full_name='Anki.Vector.external_interface.LoadedKnownFace.face_id', index=4, - number=5, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='name', full_name='Anki.Vector.external_interface.LoadedKnownFace.name', index=5, - number=6, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4271, - serialized_end=4465, -) - - -_ROBOTRENAMEDENROLLEDFACE = _descriptor.Descriptor( - name='RobotRenamedEnrolledFace', - full_name='Anki.Vector.external_interface.RobotRenamedEnrolledFace', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='face_id', full_name='Anki.Vector.external_interface.RobotRenamedEnrolledFace.face_id', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='name', full_name='Anki.Vector.external_interface.RobotRenamedEnrolledFace.name', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4467, - serialized_end=4524, -) - - -_REQUESTENROLLEDNAMESRESPONSE = _descriptor.Descriptor( - name='RequestEnrolledNamesResponse', - full_name='Anki.Vector.external_interface.RequestEnrolledNamesResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.RequestEnrolledNamesResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='faces', full_name='Anki.Vector.external_interface.RequestEnrolledNamesResponse.faces', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4527, - serialized_end=4685, -) - - -_UPDATEENROLLEDFACEBYIDREQUEST = _descriptor.Descriptor( - name='UpdateEnrolledFaceByIDRequest', - full_name='Anki.Vector.external_interface.UpdateEnrolledFaceByIDRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='face_id', full_name='Anki.Vector.external_interface.UpdateEnrolledFaceByIDRequest.face_id', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='old_name', full_name='Anki.Vector.external_interface.UpdateEnrolledFaceByIDRequest.old_name', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='new_name', full_name='Anki.Vector.external_interface.UpdateEnrolledFaceByIDRequest.new_name', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4687, - serialized_end=4771, -) - - -_UPDATEENROLLEDFACEBYIDRESPONSE = _descriptor.Descriptor( - name='UpdateEnrolledFaceByIDResponse', - full_name='Anki.Vector.external_interface.UpdateEnrolledFaceByIDResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.UpdateEnrolledFaceByIDResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4773, - serialized_end=4869, -) - - -_ERASEENROLLEDFACEBYIDREQUEST = _descriptor.Descriptor( - name='EraseEnrolledFaceByIDRequest', - full_name='Anki.Vector.external_interface.EraseEnrolledFaceByIDRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='face_id', full_name='Anki.Vector.external_interface.EraseEnrolledFaceByIDRequest.face_id', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4871, - serialized_end=4918, -) - - -_ERASEENROLLEDFACEBYIDRESPONSE = _descriptor.Descriptor( - name='EraseEnrolledFaceByIDResponse', - full_name='Anki.Vector.external_interface.EraseEnrolledFaceByIDResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.EraseEnrolledFaceByIDResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4920, - serialized_end=5015, -) - - -_ERASEALLENROLLEDFACESREQUEST = _descriptor.Descriptor( - name='EraseAllEnrolledFacesRequest', - full_name='Anki.Vector.external_interface.EraseAllEnrolledFacesRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=5017, - serialized_end=5047, -) - - -_ERASEALLENROLLEDFACESRESPONSE = _descriptor.Descriptor( - name='EraseAllEnrolledFacesResponse', - full_name='Anki.Vector.external_interface.EraseAllEnrolledFacesResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.EraseAllEnrolledFacesResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=5049, - serialized_end=5144, -) - - -_SETFACETOENROLLREQUEST = _descriptor.Descriptor( - name='SetFaceToEnrollRequest', - full_name='Anki.Vector.external_interface.SetFaceToEnrollRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='Anki.Vector.external_interface.SetFaceToEnrollRequest.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='observed_id', full_name='Anki.Vector.external_interface.SetFaceToEnrollRequest.observed_id', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='save_id', full_name='Anki.Vector.external_interface.SetFaceToEnrollRequest.save_id', index=2, - number=3, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='save_to_robot', full_name='Anki.Vector.external_interface.SetFaceToEnrollRequest.save_to_robot', index=3, - number=4, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='say_name', full_name='Anki.Vector.external_interface.SetFaceToEnrollRequest.say_name', index=4, - number=5, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='use_music', full_name='Anki.Vector.external_interface.SetFaceToEnrollRequest.use_music', index=5, - number=6, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=5147, - serialized_end=5283, -) - - -_SETFACETOENROLLRESPONSE = _descriptor.Descriptor( - name='SetFaceToEnrollResponse', - full_name='Anki.Vector.external_interface.SetFaceToEnrollResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.SetFaceToEnrollResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=5285, - serialized_end=5374, -) - - -_DRIVEOFFCHARGERREQUEST = _descriptor.Descriptor( - name='DriveOffChargerRequest', - full_name='Anki.Vector.external_interface.DriveOffChargerRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=5376, - serialized_end=5400, -) - - -_DRIVEOFFCHARGERRESPONSE = _descriptor.Descriptor( - name='DriveOffChargerResponse', - full_name='Anki.Vector.external_interface.DriveOffChargerResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.DriveOffChargerResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='result', full_name='Anki.Vector.external_interface.DriveOffChargerResponse.result', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=5403, - serialized_end=5557, -) - - -_DRIVEONCHARGERREQUEST = _descriptor.Descriptor( - name='DriveOnChargerRequest', - full_name='Anki.Vector.external_interface.DriveOnChargerRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=5559, - serialized_end=5582, -) - - -_DRIVEONCHARGERRESPONSE = _descriptor.Descriptor( - name='DriveOnChargerResponse', - full_name='Anki.Vector.external_interface.DriveOnChargerResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.DriveOnChargerResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='result', full_name='Anki.Vector.external_interface.DriveOnChargerResponse.result', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=5585, - serialized_end=5738, -) - - -_WAKEWORDBEGIN = _descriptor.Descriptor( - name='WakeWordBegin', - full_name='Anki.Vector.external_interface.WakeWordBegin', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=5740, - serialized_end=5755, -) - - -_WAKEWORDEND = _descriptor.Descriptor( - name='WakeWordEnd', - full_name='Anki.Vector.external_interface.WakeWordEnd', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='intent_heard', full_name='Anki.Vector.external_interface.WakeWordEnd.intent_heard', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='intent_json', full_name='Anki.Vector.external_interface.WakeWordEnd.intent_json', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=5757, - serialized_end=5813, -) - - -_PHOTOINFO = _descriptor.Descriptor( - name='PhotoInfo', - full_name='Anki.Vector.external_interface.PhotoInfo', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='photo_id', full_name='Anki.Vector.external_interface.PhotoInfo.photo_id', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='timestamp_utc', full_name='Anki.Vector.external_interface.PhotoInfo.timestamp_utc', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='photo_copied_to_app', full_name='Anki.Vector.external_interface.PhotoInfo.photo_copied_to_app', index=2, - number=3, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='thumb_copied_to_app', full_name='Anki.Vector.external_interface.PhotoInfo.thumb_copied_to_app', index=3, - number=4, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=5815, - serialized_end=5925, -) - - -_PHOTOSINFOREQUEST = _descriptor.Descriptor( - name='PhotosInfoRequest', - full_name='Anki.Vector.external_interface.PhotosInfoRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=5927, - serialized_end=5946, -) - - -_PHOTOSINFORESPONSE = _descriptor.Descriptor( - name='PhotosInfoResponse', - full_name='Anki.Vector.external_interface.PhotosInfoResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.PhotosInfoResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='photo_infos', full_name='Anki.Vector.external_interface.PhotosInfoResponse.photo_infos', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=5949, - serialized_end=6097, -) - - -_PHOTOREQUEST = _descriptor.Descriptor( - name='PhotoRequest', - full_name='Anki.Vector.external_interface.PhotoRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='photo_id', full_name='Anki.Vector.external_interface.PhotoRequest.photo_id', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=6099, - serialized_end=6131, -) - - -_PHOTOPATHMESSAGE = _descriptor.Descriptor( - name='PhotoPathMessage', - full_name='Anki.Vector.external_interface.PhotoPathMessage', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='success', full_name='Anki.Vector.external_interface.PhotoPathMessage.success', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='full_path', full_name='Anki.Vector.external_interface.PhotoPathMessage.full_path', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=6133, - serialized_end=6187, -) - - -_PHOTORESPONSE = _descriptor.Descriptor( - name='PhotoResponse', - full_name='Anki.Vector.external_interface.PhotoResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.PhotoResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='success', full_name='Anki.Vector.external_interface.PhotoResponse.success', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='image', full_name='Anki.Vector.external_interface.PhotoResponse.image', index=2, - number=3, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=6189, - serialized_end=6300, -) - - -_THUMBNAILREQUEST = _descriptor.Descriptor( - name='ThumbnailRequest', - full_name='Anki.Vector.external_interface.ThumbnailRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='photo_id', full_name='Anki.Vector.external_interface.ThumbnailRequest.photo_id', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=6302, - serialized_end=6338, -) - - -_THUMBNAILPATHMESSAGE = _descriptor.Descriptor( - name='ThumbnailPathMessage', - full_name='Anki.Vector.external_interface.ThumbnailPathMessage', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='success', full_name='Anki.Vector.external_interface.ThumbnailPathMessage.success', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='full_path', full_name='Anki.Vector.external_interface.ThumbnailPathMessage.full_path', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=6340, - serialized_end=6398, -) - - -_THUMBNAILRESPONSE = _descriptor.Descriptor( - name='ThumbnailResponse', - full_name='Anki.Vector.external_interface.ThumbnailResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.ThumbnailResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='success', full_name='Anki.Vector.external_interface.ThumbnailResponse.success', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='image', full_name='Anki.Vector.external_interface.ThumbnailResponse.image', index=2, - number=3, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=6400, - serialized_end=6515, -) - - -_DELETEPHOTOREQUEST = _descriptor.Descriptor( - name='DeletePhotoRequest', - full_name='Anki.Vector.external_interface.DeletePhotoRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='photo_id', full_name='Anki.Vector.external_interface.DeletePhotoRequest.photo_id', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=6517, - serialized_end=6555, -) - - -_DELETEPHOTORESPONSE = _descriptor.Descriptor( - name='DeletePhotoResponse', - full_name='Anki.Vector.external_interface.DeletePhotoResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.DeletePhotoResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='success', full_name='Anki.Vector.external_interface.DeletePhotoResponse.success', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=6557, - serialized_end=6659, -) - - -_PHOTOTAKEN = _descriptor.Descriptor( - name='PhotoTaken', - full_name='Anki.Vector.external_interface.PhotoTaken', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='photo_id', full_name='Anki.Vector.external_interface.PhotoTaken.photo_id', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=6661, - serialized_end=6691, -) - - -_PATHMOTIONPROFILE = _descriptor.Descriptor( - name='PathMotionProfile', - full_name='Anki.Vector.external_interface.PathMotionProfile', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='speed_mmps', full_name='Anki.Vector.external_interface.PathMotionProfile.speed_mmps', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='accel_mmps2', full_name='Anki.Vector.external_interface.PathMotionProfile.accel_mmps2', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='decel_mmps2', full_name='Anki.Vector.external_interface.PathMotionProfile.decel_mmps2', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='point_turn_speed_rad_per_sec', full_name='Anki.Vector.external_interface.PathMotionProfile.point_turn_speed_rad_per_sec', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='point_turn_accel_rad_per_sec2', full_name='Anki.Vector.external_interface.PathMotionProfile.point_turn_accel_rad_per_sec2', index=4, - number=5, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='point_turn_decel_rad_per_sec2', full_name='Anki.Vector.external_interface.PathMotionProfile.point_turn_decel_rad_per_sec2', index=5, - number=6, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='dock_speed_mmps', full_name='Anki.Vector.external_interface.PathMotionProfile.dock_speed_mmps', index=6, - number=7, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='dock_accel_mmps2', full_name='Anki.Vector.external_interface.PathMotionProfile.dock_accel_mmps2', index=7, - number=8, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='dock_decel_mmps2', full_name='Anki.Vector.external_interface.PathMotionProfile.dock_decel_mmps2', index=8, - number=9, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='reverse_speed_mmps', full_name='Anki.Vector.external_interface.PathMotionProfile.reverse_speed_mmps', index=9, - number=10, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='is_custom', full_name='Anki.Vector.external_interface.PathMotionProfile.is_custom', index=10, - number=11, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=6694, - serialized_end=7015, -) - - -_ACTIONRESULT = _descriptor.Descriptor( - name='ActionResult', - full_name='Anki.Vector.external_interface.ActionResult', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='code', full_name='Anki.Vector.external_interface.ActionResult.code', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _ACTIONRESULT_ACTIONRESULTCODE, - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=7018, - serialized_end=8674, -) - - -_GOTOPOSEREQUEST = _descriptor.Descriptor( - name='GoToPoseRequest', - full_name='Anki.Vector.external_interface.GoToPoseRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='x_mm', full_name='Anki.Vector.external_interface.GoToPoseRequest.x_mm', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='y_mm', full_name='Anki.Vector.external_interface.GoToPoseRequest.y_mm', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='rad', full_name='Anki.Vector.external_interface.GoToPoseRequest.rad', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='motion_prof', full_name='Anki.Vector.external_interface.GoToPoseRequest.motion_prof', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='id_tag', full_name='Anki.Vector.external_interface.GoToPoseRequest.id_tag', index=4, - number=5, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='num_retries', full_name='Anki.Vector.external_interface.GoToPoseRequest.num_retries', index=5, - number=6, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=8677, - serialized_end=8844, -) - - -_GOTOPOSERESPONSE = _descriptor.Descriptor( - name='GoToPoseResponse', - full_name='Anki.Vector.external_interface.GoToPoseResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.GoToPoseResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='result', full_name='Anki.Vector.external_interface.GoToPoseResponse.result', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=8847, - serialized_end=8991, -) - - -_DOCKWITHCUBEREQUEST = _descriptor.Descriptor( - name='DockWithCubeRequest', - full_name='Anki.Vector.external_interface.DockWithCubeRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='object_id', full_name='Anki.Vector.external_interface.DockWithCubeRequest.object_id', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='distance_from_marker_mm', full_name='Anki.Vector.external_interface.DockWithCubeRequest.distance_from_marker_mm', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='approach_angle_rad', full_name='Anki.Vector.external_interface.DockWithCubeRequest.approach_angle_rad', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='alignment_type', full_name='Anki.Vector.external_interface.DockWithCubeRequest.alignment_type', index=3, - number=4, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='use_approach_angle', full_name='Anki.Vector.external_interface.DockWithCubeRequest.use_approach_angle', index=4, - number=5, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='use_pre_dock_pose', full_name='Anki.Vector.external_interface.DockWithCubeRequest.use_pre_dock_pose', index=5, - number=6, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='motion_prof', full_name='Anki.Vector.external_interface.DockWithCubeRequest.motion_prof', index=6, - number=7, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='id_tag', full_name='Anki.Vector.external_interface.DockWithCubeRequest.id_tag', index=7, - number=8, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='num_retries', full_name='Anki.Vector.external_interface.DockWithCubeRequest.num_retries', index=8, - number=9, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=8994, - serialized_end=9330, -) - - -_DOCKWITHCUBERESPONSE = _descriptor.Descriptor( - name='DockWithCubeResponse', - full_name='Anki.Vector.external_interface.DockWithCubeResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.DockWithCubeResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='result', full_name='Anki.Vector.external_interface.DockWithCubeResponse.result', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=9333, - serialized_end=9481, -) - - -_DRIVESTRAIGHTREQUEST = _descriptor.Descriptor( - name='DriveStraightRequest', - full_name='Anki.Vector.external_interface.DriveStraightRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='speed_mmps', full_name='Anki.Vector.external_interface.DriveStraightRequest.speed_mmps', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='dist_mm', full_name='Anki.Vector.external_interface.DriveStraightRequest.dist_mm', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='should_play_animation', full_name='Anki.Vector.external_interface.DriveStraightRequest.should_play_animation', index=2, - number=3, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='id_tag', full_name='Anki.Vector.external_interface.DriveStraightRequest.id_tag', index=3, - number=4, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='num_retries', full_name='Anki.Vector.external_interface.DriveStraightRequest.num_retries', index=4, - number=5, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=9483, - serialized_end=9610, -) - - -_DRIVESTRAIGHTRESPONSE = _descriptor.Descriptor( - name='DriveStraightResponse', - full_name='Anki.Vector.external_interface.DriveStraightResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.DriveStraightResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='result', full_name='Anki.Vector.external_interface.DriveStraightResponse.result', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=9613, - serialized_end=9762, -) - - -_TURNINPLACEREQUEST = _descriptor.Descriptor( - name='TurnInPlaceRequest', - full_name='Anki.Vector.external_interface.TurnInPlaceRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='angle_rad', full_name='Anki.Vector.external_interface.TurnInPlaceRequest.angle_rad', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='speed_rad_per_sec', full_name='Anki.Vector.external_interface.TurnInPlaceRequest.speed_rad_per_sec', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='accel_rad_per_sec2', full_name='Anki.Vector.external_interface.TurnInPlaceRequest.accel_rad_per_sec2', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='tol_rad', full_name='Anki.Vector.external_interface.TurnInPlaceRequest.tol_rad', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='is_absolute', full_name='Anki.Vector.external_interface.TurnInPlaceRequest.is_absolute', index=4, - number=5, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='id_tag', full_name='Anki.Vector.external_interface.TurnInPlaceRequest.id_tag', index=5, - number=6, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='num_retries', full_name='Anki.Vector.external_interface.TurnInPlaceRequest.num_retries', index=6, - number=7, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=9765, - serialized_end=9934, -) - - -_TURNINPLACERESPONSE = _descriptor.Descriptor( - name='TurnInPlaceResponse', - full_name='Anki.Vector.external_interface.TurnInPlaceResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.TurnInPlaceResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='result', full_name='Anki.Vector.external_interface.TurnInPlaceResponse.result', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=9937, - serialized_end=10084, -) - - -_SETHEADANGLEREQUEST = _descriptor.Descriptor( - name='SetHeadAngleRequest', - full_name='Anki.Vector.external_interface.SetHeadAngleRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='angle_rad', full_name='Anki.Vector.external_interface.SetHeadAngleRequest.angle_rad', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='max_speed_rad_per_sec', full_name='Anki.Vector.external_interface.SetHeadAngleRequest.max_speed_rad_per_sec', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='accel_rad_per_sec2', full_name='Anki.Vector.external_interface.SetHeadAngleRequest.accel_rad_per_sec2', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='duration_sec', full_name='Anki.Vector.external_interface.SetHeadAngleRequest.duration_sec', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='id_tag', full_name='Anki.Vector.external_interface.SetHeadAngleRequest.id_tag', index=4, - number=5, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='num_retries', full_name='Anki.Vector.external_interface.SetHeadAngleRequest.num_retries', index=5, - number=6, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=10087, - serialized_end=10245, -) - - -_SETHEADANGLERESPONSE = _descriptor.Descriptor( - name='SetHeadAngleResponse', - full_name='Anki.Vector.external_interface.SetHeadAngleResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.SetHeadAngleResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='result', full_name='Anki.Vector.external_interface.SetHeadAngleResponse.result', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=10248, - serialized_end=10396, -) - - -_SETLIFTHEIGHTREQUEST = _descriptor.Descriptor( - name='SetLiftHeightRequest', - full_name='Anki.Vector.external_interface.SetLiftHeightRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='height_mm', full_name='Anki.Vector.external_interface.SetLiftHeightRequest.height_mm', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='max_speed_rad_per_sec', full_name='Anki.Vector.external_interface.SetLiftHeightRequest.max_speed_rad_per_sec', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='accel_rad_per_sec2', full_name='Anki.Vector.external_interface.SetLiftHeightRequest.accel_rad_per_sec2', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='duration_sec', full_name='Anki.Vector.external_interface.SetLiftHeightRequest.duration_sec', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='id_tag', full_name='Anki.Vector.external_interface.SetLiftHeightRequest.id_tag', index=4, - number=5, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='num_retries', full_name='Anki.Vector.external_interface.SetLiftHeightRequest.num_retries', index=5, - number=6, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=10399, - serialized_end=10558, -) - - -_SETLIFTHEIGHTRESPONSE = _descriptor.Descriptor( - name='SetLiftHeightResponse', - full_name='Anki.Vector.external_interface.SetLiftHeightResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.SetLiftHeightResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='result', full_name='Anki.Vector.external_interface.SetLiftHeightResponse.result', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=10561, - serialized_end=10710, -) - - -_NETWORKSTATS = _descriptor.Descriptor( - name='NetworkStats', - full_name='Anki.Vector.external_interface.NetworkStats', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='g_net_stat1_num_connections', full_name='Anki.Vector.external_interface.NetworkStats.g_net_stat1_num_connections', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='g_net_stat2_latency_avg', full_name='Anki.Vector.external_interface.NetworkStats.g_net_stat2_latency_avg', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='g_net_stat3_latency_sd', full_name='Anki.Vector.external_interface.NetworkStats.g_net_stat3_latency_sd', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='g_net_stat4_latency_min', full_name='Anki.Vector.external_interface.NetworkStats.g_net_stat4_latency_min', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='g_net_stat5_latency_max', full_name='Anki.Vector.external_interface.NetworkStats.g_net_stat5_latency_max', index=4, - number=5, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='g_net_stat6_ping_arrived_pc', full_name='Anki.Vector.external_interface.NetworkStats.g_net_stat6_ping_arrived_pc', index=5, - number=6, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='g_net_stat7_ext_queued_avg_ms', full_name='Anki.Vector.external_interface.NetworkStats.g_net_stat7_ext_queued_avg_ms', index=6, - number=7, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='g_net_stat8_ext_queued_min_ms', full_name='Anki.Vector.external_interface.NetworkStats.g_net_stat8_ext_queued_min_ms', index=7, - number=8, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='g_net_stat9_ext_queued_max_ms', full_name='Anki.Vector.external_interface.NetworkStats.g_net_stat9_ext_queued_max_ms', index=8, - number=9, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='g_net_stata_queued_avg_ms', full_name='Anki.Vector.external_interface.NetworkStats.g_net_stata_queued_avg_ms', index=9, - number=10, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='g_net_statb_queued_min_ms', full_name='Anki.Vector.external_interface.NetworkStats.g_net_statb_queued_min_ms', index=10, - number=11, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='g_net_statc_queued_max_ms', full_name='Anki.Vector.external_interface.NetworkStats.g_net_statc_queued_max_ms', index=11, - number=12, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=10713, - serialized_end=11154, -) - - -_BATTERYSTATEREQUEST = _descriptor.Descriptor( - name='BatteryStateRequest', - full_name='Anki.Vector.external_interface.BatteryStateRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=11156, - serialized_end=11177, -) - - -_BATTERYSTATERESPONSE = _descriptor.Descriptor( - name='BatteryStateResponse', - full_name='Anki.Vector.external_interface.BatteryStateResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.BatteryStateResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='battery_level', full_name='Anki.Vector.external_interface.BatteryStateResponse.battery_level', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='battery_volts', full_name='Anki.Vector.external_interface.BatteryStateResponse.battery_volts', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='is_charging', full_name='Anki.Vector.external_interface.BatteryStateResponse.is_charging', index=3, - number=4, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='is_on_charger_platform', full_name='Anki.Vector.external_interface.BatteryStateResponse.is_on_charger_platform', index=4, - number=5, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='suggested_charger_sec', full_name='Anki.Vector.external_interface.BatteryStateResponse.suggested_charger_sec', index=5, - number=6, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='cube_battery', full_name='Anki.Vector.external_interface.BatteryStateResponse.cube_battery', index=6, - number=7, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=11180, - serialized_end=11509, -) - - -_CUBEBATTERY = _descriptor.Descriptor( - name='CubeBattery', - full_name='Anki.Vector.external_interface.CubeBattery', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='level', full_name='Anki.Vector.external_interface.CubeBattery.level', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='factory_id', full_name='Anki.Vector.external_interface.CubeBattery.factory_id', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='battery_volts', full_name='Anki.Vector.external_interface.CubeBattery.battery_volts', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='time_since_last_reading_sec', full_name='Anki.Vector.external_interface.CubeBattery.time_since_last_reading_sec', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _CUBEBATTERY_CUBEBATTERYLEVEL, - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=11512, - serialized_end=11723, -) - - -_VERSIONSTATEREQUEST = _descriptor.Descriptor( - name='VersionStateRequest', - full_name='Anki.Vector.external_interface.VersionStateRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=11725, - serialized_end=11746, -) - - -_VERSIONSTATERESPONSE = _descriptor.Descriptor( - name='VersionStateResponse', - full_name='Anki.Vector.external_interface.VersionStateResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.VersionStateResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='os_version', full_name='Anki.Vector.external_interface.VersionStateResponse.os_version', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='engine_build_id', full_name='Anki.Vector.external_interface.VersionStateResponse.engine_build_id', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=11749, - serialized_end=11880, -) - - -_NETWORKSTATEREQUEST = _descriptor.Descriptor( - name='NetworkStateRequest', - full_name='Anki.Vector.external_interface.NetworkStateRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=11882, - serialized_end=11903, -) - - -_NETWORKSTATERESPONSE = _descriptor.Descriptor( - name='NetworkStateResponse', - full_name='Anki.Vector.external_interface.NetworkStateResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.NetworkStateResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='network_stats', full_name='Anki.Vector.external_interface.NetworkStateResponse.network_stats', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=11906, - serialized_end=12061, -) - - -_SAYTEXTREQUEST = _descriptor.Descriptor( - name='SayTextRequest', - full_name='Anki.Vector.external_interface.SayTextRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='text', full_name='Anki.Vector.external_interface.SayTextRequest.text', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='use_vector_voice', full_name='Anki.Vector.external_interface.SayTextRequest.use_vector_voice', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='duration_scalar', full_name='Anki.Vector.external_interface.SayTextRequest.duration_scalar', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=12063, - serialized_end=12144, -) - - -_SAYTEXTRESPONSE = _descriptor.Descriptor( - name='SayTextResponse', - full_name='Anki.Vector.external_interface.SayTextResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.SayTextResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='state', full_name='Anki.Vector.external_interface.SayTextResponse.state', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _SAYTEXTRESPONSE_UTTERANCESTATE, - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=12147, - serialized_end=12392, -) - - -_STIMULATIONINFO = _descriptor.Descriptor( - name='StimulationInfo', - full_name='Anki.Vector.external_interface.StimulationInfo', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='emotion_events', full_name='Anki.Vector.external_interface.StimulationInfo.emotion_events', index=0, - number=1, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='value', full_name='Anki.Vector.external_interface.StimulationInfo.value', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='velocity', full_name='Anki.Vector.external_interface.StimulationInfo.velocity', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='accel', full_name='Anki.Vector.external_interface.StimulationInfo.accel', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='value_before_event', full_name='Anki.Vector.external_interface.StimulationInfo.value_before_event', index=4, - number=5, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='min_value', full_name='Anki.Vector.external_interface.StimulationInfo.min_value', index=5, - number=6, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='max_value', full_name='Anki.Vector.external_interface.StimulationInfo.max_value', index=6, - number=7, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=12395, - serialized_end=12550, -) - - -_AUDIOSENDMODEREQUEST = _descriptor.Descriptor( - name='AudioSendModeRequest', - full_name='Anki.Vector.external_interface.AudioSendModeRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='mode', full_name='Anki.Vector.external_interface.AudioSendModeRequest.mode', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=12552, - serialized_end=12641, -) - - -_AUDIOSENDMODECHANGED = _descriptor.Descriptor( - name='AudioSendModeChanged', - full_name='Anki.Vector.external_interface.AudioSendModeChanged', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='mode', full_name='Anki.Vector.external_interface.AudioSendModeChanged.mode', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=12643, - serialized_end=12732, -) - - -_AUDIOCHUNK = _descriptor.Descriptor( - name='AudioChunk', - full_name='Anki.Vector.external_interface.AudioChunk', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='robot_time_stamp', full_name='Anki.Vector.external_interface.AudioChunk.robot_time_stamp', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='group_id', full_name='Anki.Vector.external_interface.AudioChunk.group_id', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='chunk_id', full_name='Anki.Vector.external_interface.AudioChunk.chunk_id', index=2, - number=3, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='audio_chunk_count', full_name='Anki.Vector.external_interface.AudioChunk.audio_chunk_count', index=3, - number=4, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='signal_power', full_name='Anki.Vector.external_interface.AudioChunk.signal_power', index=4, - number=5, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='direction_strengths', full_name='Anki.Vector.external_interface.AudioChunk.direction_strengths', index=5, - number=6, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='source_direction', full_name='Anki.Vector.external_interface.AudioChunk.source_direction', index=6, - number=7, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='source_confidence', full_name='Anki.Vector.external_interface.AudioChunk.source_confidence', index=7, - number=8, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='noise_floor_power', full_name='Anki.Vector.external_interface.AudioChunk.noise_floor_power', index=8, - number=9, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=12735, - serialized_end=12967, -) - - -_AUDIOFEEDREQUEST = _descriptor.Descriptor( - name='AudioFeedRequest', - full_name='Anki.Vector.external_interface.AudioFeedRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=12969, - serialized_end=12987, -) - - -_AUDIOFEEDRESPONSE = _descriptor.Descriptor( - name='AudioFeedResponse', - full_name='Anki.Vector.external_interface.AudioFeedResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='robot_time_stamp', full_name='Anki.Vector.external_interface.AudioFeedResponse.robot_time_stamp', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='group_id', full_name='Anki.Vector.external_interface.AudioFeedResponse.group_id', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='signal_power', full_name='Anki.Vector.external_interface.AudioFeedResponse.signal_power', index=2, - number=3, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='direction_strengths', full_name='Anki.Vector.external_interface.AudioFeedResponse.direction_strengths', index=3, - number=4, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='source_direction', full_name='Anki.Vector.external_interface.AudioFeedResponse.source_direction', index=4, - number=5, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='source_confidence', full_name='Anki.Vector.external_interface.AudioFeedResponse.source_confidence', index=5, - number=6, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='noise_floor_power', full_name='Anki.Vector.external_interface.AudioFeedResponse.noise_floor_power', index=6, - number=7, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\200\246\035\001')), - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=12990, - serialized_end=13190, -) - - -_ENABLEMARKERDETECTIONREQUEST = _descriptor.Descriptor( - name='EnableMarkerDetectionRequest', - full_name='Anki.Vector.external_interface.EnableMarkerDetectionRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='enable', full_name='Anki.Vector.external_interface.EnableMarkerDetectionRequest.enable', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=13192, - serialized_end=13238, -) - - -_ENABLEMARKERDETECTIONRESPONSE = _descriptor.Descriptor( - name='EnableMarkerDetectionResponse', - full_name='Anki.Vector.external_interface.EnableMarkerDetectionResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.EnableMarkerDetectionResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=13240, - serialized_end=13335, -) - - -_ENABLEFACEDETECTIONREQUEST = _descriptor.Descriptor( - name='EnableFaceDetectionRequest', - full_name='Anki.Vector.external_interface.EnableFaceDetectionRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='enable', full_name='Anki.Vector.external_interface.EnableFaceDetectionRequest.enable', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='enable_smile_detection', full_name='Anki.Vector.external_interface.EnableFaceDetectionRequest.enable_smile_detection', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='enable_expression_estimation', full_name='Anki.Vector.external_interface.EnableFaceDetectionRequest.enable_expression_estimation', index=2, - number=3, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='enable_blink_detection', full_name='Anki.Vector.external_interface.EnableFaceDetectionRequest.enable_blink_detection', index=3, - number=4, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='enable_gaze_detection', full_name='Anki.Vector.external_interface.EnableFaceDetectionRequest.enable_gaze_detection', index=4, - number=5, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=13338, - serialized_end=13515, -) - - -_ENABLEFACEDETECTIONRESPONSE = _descriptor.Descriptor( - name='EnableFaceDetectionResponse', - full_name='Anki.Vector.external_interface.EnableFaceDetectionResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.EnableFaceDetectionResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=13517, - serialized_end=13610, -) - - -_ENABLEMOTIONDETECTIONREQUEST = _descriptor.Descriptor( - name='EnableMotionDetectionRequest', - full_name='Anki.Vector.external_interface.EnableMotionDetectionRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='enable', full_name='Anki.Vector.external_interface.EnableMotionDetectionRequest.enable', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=13612, - serialized_end=13658, -) - - -_ENABLEMOTIONDETECTIONRESPONSE = _descriptor.Descriptor( - name='EnableMotionDetectionResponse', - full_name='Anki.Vector.external_interface.EnableMotionDetectionResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.EnableMotionDetectionResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=13660, - serialized_end=13755, -) - - -_ENABLEMIRRORMODEREQUEST = _descriptor.Descriptor( - name='EnableMirrorModeRequest', - full_name='Anki.Vector.external_interface.EnableMirrorModeRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='enable', full_name='Anki.Vector.external_interface.EnableMirrorModeRequest.enable', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=13757, - serialized_end=13798, -) - - -_ENABLEMIRRORMODERESPONSE = _descriptor.Descriptor( - name='EnableMirrorModeResponse', - full_name='Anki.Vector.external_interface.EnableMirrorModeResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.EnableMirrorModeResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=13800, - serialized_end=13890, -) - - -_MIRRORMODEDISABLED = _descriptor.Descriptor( - name='MirrorModeDisabled', - full_name='Anki.Vector.external_interface.MirrorModeDisabled', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=13892, - serialized_end=13912, -) - - -_ENABLEIMAGESTREAMINGREQUEST = _descriptor.Descriptor( - name='EnableImageStreamingRequest', - full_name='Anki.Vector.external_interface.EnableImageStreamingRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='enable', full_name='Anki.Vector.external_interface.EnableImageStreamingRequest.enable', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=13914, - serialized_end=13959, -) - - -_ENABLEIMAGESTREAMINGRESPONSE = _descriptor.Descriptor( - name='EnableImageStreamingResponse', - full_name='Anki.Vector.external_interface.EnableImageStreamingResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.EnableImageStreamingResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=13961, - serialized_end=14055, -) - - -_VISIONMODESAUTODISABLED = _descriptor.Descriptor( - name='VisionModesAutoDisabled', - full_name='Anki.Vector.external_interface.VisionModesAutoDisabled', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=14057, - serialized_end=14082, -) - - -_IMAGECHUNK = _descriptor.Descriptor( - name='ImageChunk', - full_name='Anki.Vector.external_interface.ImageChunk', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='frame_time_stamp', full_name='Anki.Vector.external_interface.ImageChunk.frame_time_stamp', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='image_id', full_name='Anki.Vector.external_interface.ImageChunk.image_id', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='width', full_name='Anki.Vector.external_interface.ImageChunk.width', index=2, - number=3, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='height', full_name='Anki.Vector.external_interface.ImageChunk.height', index=3, - number=4, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='image_encoding', full_name='Anki.Vector.external_interface.ImageChunk.image_encoding', index=4, - number=5, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='display_index', full_name='Anki.Vector.external_interface.ImageChunk.display_index', index=5, - number=6, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='image_chunk_count', full_name='Anki.Vector.external_interface.ImageChunk.image_chunk_count', index=6, - number=7, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='chunk_id', full_name='Anki.Vector.external_interface.ImageChunk.chunk_id', index=7, - number=8, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='data', full_name='Anki.Vector.external_interface.ImageChunk.data', index=8, - number=9, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _IMAGECHUNK_IMAGEENCODING, - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=14085, - serialized_end=14550, -) - - -_CAMERAFEEDREQUEST = _descriptor.Descriptor( - name='CameraFeedRequest', - full_name='Anki.Vector.external_interface.CameraFeedRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=14552, - serialized_end=14571, -) - - -_CAMERAFEEDRESPONSE = _descriptor.Descriptor( - name='CameraFeedResponse', - full_name='Anki.Vector.external_interface.CameraFeedResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='frame_time_stamp', full_name='Anki.Vector.external_interface.CameraFeedResponse.frame_time_stamp', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='image_id', full_name='Anki.Vector.external_interface.CameraFeedResponse.image_id', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='image_encoding', full_name='Anki.Vector.external_interface.CameraFeedResponse.image_encoding', index=2, - number=3, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='data', full_name='Anki.Vector.external_interface.CameraFeedResponse.data', index=3, - number=4, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\200\246\035\001')), - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=14574, - serialized_end=14740, -) - - -_SETEYECOLORREQUEST = _descriptor.Descriptor( - name='SetEyeColorRequest', - full_name='Anki.Vector.external_interface.SetEyeColorRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='hue', full_name='Anki.Vector.external_interface.SetEyeColorRequest.hue', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='saturation', full_name='Anki.Vector.external_interface.SetEyeColorRequest.saturation', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=14742, - serialized_end=14795, -) - - -_SETEYECOLORRESPONSE = _descriptor.Descriptor( - name='SetEyeColorResponse', - full_name='Anki.Vector.external_interface.SetEyeColorResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.SetEyeColorResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=14797, - serialized_end=14882, -) - - -_SDKINITIALIZATIONREQUEST = _descriptor.Descriptor( - name='SDKInitializationRequest', - full_name='Anki.Vector.external_interface.SDKInitializationRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='sdk_module_version', full_name='Anki.Vector.external_interface.SDKInitializationRequest.sdk_module_version', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='python_version', full_name='Anki.Vector.external_interface.SDKInitializationRequest.python_version', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='python_implementation', full_name='Anki.Vector.external_interface.SDKInitializationRequest.python_implementation', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='os_version', full_name='Anki.Vector.external_interface.SDKInitializationRequest.os_version', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='cpu_version', full_name='Anki.Vector.external_interface.SDKInitializationRequest.cpu_version', index=4, - number=5, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=14885, - serialized_end=15035, -) - - -_SDKINITIALIZATIONRESPONSE = _descriptor.Descriptor( - name='SDKInitializationResponse', - full_name='Anki.Vector.external_interface.SDKInitializationResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.SDKInitializationResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=15037, - serialized_end=15128, -) - -_DRIVEWHEELSRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_MOVEHEADRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_MOVELIFTRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_PLAYANIMATIONREQUEST.fields_by_name['animation'].message_type = _ANIMATION -_PLAYANIMATIONRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_PLAYANIMATIONRESPONSE.fields_by_name['result'].enum_type = _BEHAVIORRESULTS -_LISTANIMATIONSRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_LISTANIMATIONSRESPONSE.fields_by_name['animation_names'].message_type = _ANIMATION -_DISPLAYFACEIMAGERGBRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_STATUS.fields_by_name['meet_victor_face_scan_started'].message_type = _MEETVICTORFACESCANSTARTED -_STATUS.fields_by_name['meet_victor_face_scan_complete'].message_type = _MEETVICTORFACESCANCOMPLETE -_STATUS.fields_by_name['face_enrollment_completed'].message_type = _FACEENROLLMENTCOMPLETED -_STATUS.oneofs_by_name['status_type'].fields.append( - _STATUS.fields_by_name['meet_victor_face_scan_started']) -_STATUS.fields_by_name['meet_victor_face_scan_started'].containing_oneof = _STATUS.oneofs_by_name['status_type'] -_STATUS.oneofs_by_name['status_type'].fields.append( - _STATUS.fields_by_name['meet_victor_face_scan_complete']) -_STATUS.fields_by_name['meet_victor_face_scan_complete'].containing_oneof = _STATUS.oneofs_by_name['status_type'] -_STATUS.oneofs_by_name['status_type'].fields.append( - _STATUS.fields_by_name['face_enrollment_completed']) -_STATUS.fields_by_name['face_enrollment_completed'].containing_oneof = _STATUS.oneofs_by_name['status_type'] -_WAKEWORD.fields_by_name['wake_word_begin'].message_type = _WAKEWORDBEGIN -_WAKEWORD.fields_by_name['wake_word_end'].message_type = _WAKEWORDEND -_WAKEWORD.oneofs_by_name['wake_word_type'].fields.append( - _WAKEWORD.fields_by_name['wake_word_begin']) -_WAKEWORD.fields_by_name['wake_word_begin'].containing_oneof = _WAKEWORD.oneofs_by_name['wake_word_type'] -_WAKEWORD.oneofs_by_name['wake_word_type'].fields.append( - _WAKEWORD.fields_by_name['wake_word_end']) -_WAKEWORD.fields_by_name['wake_word_end'].containing_oneof = _WAKEWORD.oneofs_by_name['wake_word_type'] -_TIMESTAMPEDSTATUS.fields_by_name['status'].message_type = _STATUS -_ROBOTSTATE.fields_by_name['pose'].message_type = _POSESTRUCT -_ROBOTSTATE.fields_by_name['accel'].message_type = _ACCELDATA -_ROBOTSTATE.fields_by_name['gyro'].message_type = _GYRODATA -_ROBOTSTATE.fields_by_name['prox_data'].message_type = _PROXDATA -_ROBOTSTATE.fields_by_name['touch_data'].message_type = _TOUCHDATA -_ROBOTOBSERVEDFACE.fields_by_name['pose'].message_type = _POSESTRUCT -_ROBOTOBSERVEDFACE.fields_by_name['img_rect'].message_type = _CLADRECT -_ROBOTOBSERVEDFACE.fields_by_name['expression'].enum_type = _FACIALEXPRESSION -_ROBOTOBSERVEDFACE.fields_by_name['left_eye'].message_type = _CLADPOINT -_ROBOTOBSERVEDFACE.fields_by_name['right_eye'].message_type = _CLADPOINT -_ROBOTOBSERVEDFACE.fields_by_name['nose'].message_type = _CLADPOINT -_ROBOTOBSERVEDFACE.fields_by_name['mouth'].message_type = _CLADPOINT -_APPINTENTRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_FACEENROLLMENTCOMPLETED.fields_by_name['result'].enum_type = _FACEENROLLMENTRESULT -_CANCELFACEENROLLMENTRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_REQUESTENROLLEDNAMESRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_REQUESTENROLLEDNAMESRESPONSE.fields_by_name['faces'].message_type = _LOADEDKNOWNFACE -_UPDATEENROLLEDFACEBYIDRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_ERASEENROLLEDFACEBYIDRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_ERASEALLENROLLEDFACESRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_SETFACETOENROLLRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_DRIVEOFFCHARGERRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_DRIVEOFFCHARGERRESPONSE.fields_by_name['result'].enum_type = _BEHAVIORRESULTS -_DRIVEONCHARGERRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_DRIVEONCHARGERRESPONSE.fields_by_name['result'].enum_type = _BEHAVIORRESULTS -_PHOTOSINFORESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_PHOTOSINFORESPONSE.fields_by_name['photo_infos'].message_type = _PHOTOINFO -_PHOTORESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_THUMBNAILRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_DELETEPHOTORESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_ACTIONRESULT.fields_by_name['code'].enum_type = _ACTIONRESULT_ACTIONRESULTCODE -_ACTIONRESULT_ACTIONRESULTCODE.containing_type = _ACTIONRESULT -_GOTOPOSEREQUEST.fields_by_name['motion_prof'].message_type = _PATHMOTIONPROFILE -_GOTOPOSERESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_GOTOPOSERESPONSE.fields_by_name['result'].message_type = _ACTIONRESULT -_DOCKWITHCUBEREQUEST.fields_by_name['alignment_type'].enum_type = _ALIGNMENTTYPE -_DOCKWITHCUBEREQUEST.fields_by_name['motion_prof'].message_type = _PATHMOTIONPROFILE -_DOCKWITHCUBERESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_DOCKWITHCUBERESPONSE.fields_by_name['result'].message_type = _ACTIONRESULT -_DRIVESTRAIGHTRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_DRIVESTRAIGHTRESPONSE.fields_by_name['result'].message_type = _ACTIONRESULT -_TURNINPLACERESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_TURNINPLACERESPONSE.fields_by_name['result'].message_type = _ACTIONRESULT -_SETHEADANGLERESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_SETHEADANGLERESPONSE.fields_by_name['result'].message_type = _ACTIONRESULT -_SETLIFTHEIGHTRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_SETLIFTHEIGHTRESPONSE.fields_by_name['result'].message_type = _ACTIONRESULT -_BATTERYSTATERESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_BATTERYSTATERESPONSE.fields_by_name['battery_level'].enum_type = _BATTERYLEVEL -_BATTERYSTATERESPONSE.fields_by_name['cube_battery'].message_type = _CUBEBATTERY -_CUBEBATTERY.fields_by_name['level'].enum_type = _CUBEBATTERY_CUBEBATTERYLEVEL -_CUBEBATTERY_CUBEBATTERYLEVEL.containing_type = _CUBEBATTERY -_VERSIONSTATERESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_NETWORKSTATERESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_NETWORKSTATERESPONSE.fields_by_name['network_stats'].message_type = _NETWORKSTATS -_SAYTEXTRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_SAYTEXTRESPONSE.fields_by_name['state'].enum_type = _SAYTEXTRESPONSE_UTTERANCESTATE -_SAYTEXTRESPONSE_UTTERANCESTATE.containing_type = _SAYTEXTRESPONSE -_AUDIOSENDMODEREQUEST.fields_by_name['mode'].enum_type = _AUDIOPROCESSINGMODE -_AUDIOSENDMODECHANGED.fields_by_name['mode'].enum_type = _AUDIOPROCESSINGMODE -_ENABLEMARKERDETECTIONRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_ENABLEFACEDETECTIONRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_ENABLEMOTIONDETECTIONRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_ENABLEMIRRORMODERESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_ENABLEIMAGESTREAMINGRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_IMAGECHUNK.fields_by_name['image_encoding'].enum_type = _IMAGECHUNK_IMAGEENCODING -_IMAGECHUNK_IMAGEENCODING.containing_type = _IMAGECHUNK -_CAMERAFEEDRESPONSE.fields_by_name['image_encoding'].enum_type = _IMAGECHUNK_IMAGEENCODING -_SETEYECOLORRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_SDKINITIALIZATIONRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -DESCRIPTOR.message_types_by_name['KeepAlivePing'] = _KEEPALIVEPING -DESCRIPTOR.message_types_by_name['Animation'] = _ANIMATION -DESCRIPTOR.message_types_by_name['DriveWheelsRequest'] = _DRIVEWHEELSREQUEST -DESCRIPTOR.message_types_by_name['DriveWheelsResponse'] = _DRIVEWHEELSRESPONSE -DESCRIPTOR.message_types_by_name['MoveHeadRequest'] = _MOVEHEADREQUEST -DESCRIPTOR.message_types_by_name['MoveHeadResponse'] = _MOVEHEADRESPONSE -DESCRIPTOR.message_types_by_name['MoveLiftRequest'] = _MOVELIFTREQUEST -DESCRIPTOR.message_types_by_name['MoveLiftResponse'] = _MOVELIFTRESPONSE -DESCRIPTOR.message_types_by_name['PlayAnimationRequest'] = _PLAYANIMATIONREQUEST -DESCRIPTOR.message_types_by_name['PlayAnimationResponse'] = _PLAYANIMATIONRESPONSE -DESCRIPTOR.message_types_by_name['ListAnimationsRequest'] = _LISTANIMATIONSREQUEST -DESCRIPTOR.message_types_by_name['ListAnimationsResponse'] = _LISTANIMATIONSRESPONSE -DESCRIPTOR.message_types_by_name['DisplayFaceImageRGBRequest'] = _DISPLAYFACEIMAGERGBREQUEST -DESCRIPTOR.message_types_by_name['DisplayFaceImageRGBResponse'] = _DISPLAYFACEIMAGERGBRESPONSE -DESCRIPTOR.message_types_by_name['MeetVictorFaceScanStarted'] = _MEETVICTORFACESCANSTARTED -DESCRIPTOR.message_types_by_name['MeetVictorFaceScanComplete'] = _MEETVICTORFACESCANCOMPLETE -DESCRIPTOR.message_types_by_name['Status'] = _STATUS -DESCRIPTOR.message_types_by_name['WakeWord'] = _WAKEWORD -DESCRIPTOR.message_types_by_name['TimeStampedStatus'] = _TIMESTAMPEDSTATUS -DESCRIPTOR.message_types_by_name['PoseStruct'] = _POSESTRUCT -DESCRIPTOR.message_types_by_name['AccelData'] = _ACCELDATA -DESCRIPTOR.message_types_by_name['GyroData'] = _GYRODATA -DESCRIPTOR.message_types_by_name['ProxData'] = _PROXDATA -DESCRIPTOR.message_types_by_name['TouchData'] = _TOUCHDATA -DESCRIPTOR.message_types_by_name['RobotState'] = _ROBOTSTATE -DESCRIPTOR.message_types_by_name['CladPoint'] = _CLADPOINT -DESCRIPTOR.message_types_by_name['CladRect'] = _CLADRECT -DESCRIPTOR.message_types_by_name['RobotObservedFace'] = _ROBOTOBSERVEDFACE -DESCRIPTOR.message_types_by_name['RobotChangedObservedFaceID'] = _ROBOTCHANGEDOBSERVEDFACEID -DESCRIPTOR.message_types_by_name['AppIntentRequest'] = _APPINTENTREQUEST -DESCRIPTOR.message_types_by_name['AppDisconnected'] = _APPDISCONNECTED -DESCRIPTOR.message_types_by_name['AppIntentResponse'] = _APPINTENTRESPONSE -DESCRIPTOR.message_types_by_name['FaceEnrollmentCompleted'] = _FACEENROLLMENTCOMPLETED -DESCRIPTOR.message_types_by_name['CancelFaceEnrollmentRequest'] = _CANCELFACEENROLLMENTREQUEST -DESCRIPTOR.message_types_by_name['CancelFaceEnrollmentResponse'] = _CANCELFACEENROLLMENTRESPONSE -DESCRIPTOR.message_types_by_name['RequestEnrolledNamesRequest'] = _REQUESTENROLLEDNAMESREQUEST -DESCRIPTOR.message_types_by_name['LoadedKnownFace'] = _LOADEDKNOWNFACE -DESCRIPTOR.message_types_by_name['RobotRenamedEnrolledFace'] = _ROBOTRENAMEDENROLLEDFACE -DESCRIPTOR.message_types_by_name['RequestEnrolledNamesResponse'] = _REQUESTENROLLEDNAMESRESPONSE -DESCRIPTOR.message_types_by_name['UpdateEnrolledFaceByIDRequest'] = _UPDATEENROLLEDFACEBYIDREQUEST -DESCRIPTOR.message_types_by_name['UpdateEnrolledFaceByIDResponse'] = _UPDATEENROLLEDFACEBYIDRESPONSE -DESCRIPTOR.message_types_by_name['EraseEnrolledFaceByIDRequest'] = _ERASEENROLLEDFACEBYIDREQUEST -DESCRIPTOR.message_types_by_name['EraseEnrolledFaceByIDResponse'] = _ERASEENROLLEDFACEBYIDRESPONSE -DESCRIPTOR.message_types_by_name['EraseAllEnrolledFacesRequest'] = _ERASEALLENROLLEDFACESREQUEST -DESCRIPTOR.message_types_by_name['EraseAllEnrolledFacesResponse'] = _ERASEALLENROLLEDFACESRESPONSE -DESCRIPTOR.message_types_by_name['SetFaceToEnrollRequest'] = _SETFACETOENROLLREQUEST -DESCRIPTOR.message_types_by_name['SetFaceToEnrollResponse'] = _SETFACETOENROLLRESPONSE -DESCRIPTOR.message_types_by_name['DriveOffChargerRequest'] = _DRIVEOFFCHARGERREQUEST -DESCRIPTOR.message_types_by_name['DriveOffChargerResponse'] = _DRIVEOFFCHARGERRESPONSE -DESCRIPTOR.message_types_by_name['DriveOnChargerRequest'] = _DRIVEONCHARGERREQUEST -DESCRIPTOR.message_types_by_name['DriveOnChargerResponse'] = _DRIVEONCHARGERRESPONSE -DESCRIPTOR.message_types_by_name['WakeWordBegin'] = _WAKEWORDBEGIN -DESCRIPTOR.message_types_by_name['WakeWordEnd'] = _WAKEWORDEND -DESCRIPTOR.message_types_by_name['PhotoInfo'] = _PHOTOINFO -DESCRIPTOR.message_types_by_name['PhotosInfoRequest'] = _PHOTOSINFOREQUEST -DESCRIPTOR.message_types_by_name['PhotosInfoResponse'] = _PHOTOSINFORESPONSE -DESCRIPTOR.message_types_by_name['PhotoRequest'] = _PHOTOREQUEST -DESCRIPTOR.message_types_by_name['PhotoPathMessage'] = _PHOTOPATHMESSAGE -DESCRIPTOR.message_types_by_name['PhotoResponse'] = _PHOTORESPONSE -DESCRIPTOR.message_types_by_name['ThumbnailRequest'] = _THUMBNAILREQUEST -DESCRIPTOR.message_types_by_name['ThumbnailPathMessage'] = _THUMBNAILPATHMESSAGE -DESCRIPTOR.message_types_by_name['ThumbnailResponse'] = _THUMBNAILRESPONSE -DESCRIPTOR.message_types_by_name['DeletePhotoRequest'] = _DELETEPHOTOREQUEST -DESCRIPTOR.message_types_by_name['DeletePhotoResponse'] = _DELETEPHOTORESPONSE -DESCRIPTOR.message_types_by_name['PhotoTaken'] = _PHOTOTAKEN -DESCRIPTOR.message_types_by_name['PathMotionProfile'] = _PATHMOTIONPROFILE -DESCRIPTOR.message_types_by_name['ActionResult'] = _ACTIONRESULT -DESCRIPTOR.message_types_by_name['GoToPoseRequest'] = _GOTOPOSEREQUEST -DESCRIPTOR.message_types_by_name['GoToPoseResponse'] = _GOTOPOSERESPONSE -DESCRIPTOR.message_types_by_name['DockWithCubeRequest'] = _DOCKWITHCUBEREQUEST -DESCRIPTOR.message_types_by_name['DockWithCubeResponse'] = _DOCKWITHCUBERESPONSE -DESCRIPTOR.message_types_by_name['DriveStraightRequest'] = _DRIVESTRAIGHTREQUEST -DESCRIPTOR.message_types_by_name['DriveStraightResponse'] = _DRIVESTRAIGHTRESPONSE -DESCRIPTOR.message_types_by_name['TurnInPlaceRequest'] = _TURNINPLACEREQUEST -DESCRIPTOR.message_types_by_name['TurnInPlaceResponse'] = _TURNINPLACERESPONSE -DESCRIPTOR.message_types_by_name['SetHeadAngleRequest'] = _SETHEADANGLEREQUEST -DESCRIPTOR.message_types_by_name['SetHeadAngleResponse'] = _SETHEADANGLERESPONSE -DESCRIPTOR.message_types_by_name['SetLiftHeightRequest'] = _SETLIFTHEIGHTREQUEST -DESCRIPTOR.message_types_by_name['SetLiftHeightResponse'] = _SETLIFTHEIGHTRESPONSE -DESCRIPTOR.message_types_by_name['NetworkStats'] = _NETWORKSTATS -DESCRIPTOR.message_types_by_name['BatteryStateRequest'] = _BATTERYSTATEREQUEST -DESCRIPTOR.message_types_by_name['BatteryStateResponse'] = _BATTERYSTATERESPONSE -DESCRIPTOR.message_types_by_name['CubeBattery'] = _CUBEBATTERY -DESCRIPTOR.message_types_by_name['VersionStateRequest'] = _VERSIONSTATEREQUEST -DESCRIPTOR.message_types_by_name['VersionStateResponse'] = _VERSIONSTATERESPONSE -DESCRIPTOR.message_types_by_name['NetworkStateRequest'] = _NETWORKSTATEREQUEST -DESCRIPTOR.message_types_by_name['NetworkStateResponse'] = _NETWORKSTATERESPONSE -DESCRIPTOR.message_types_by_name['SayTextRequest'] = _SAYTEXTREQUEST -DESCRIPTOR.message_types_by_name['SayTextResponse'] = _SAYTEXTRESPONSE -DESCRIPTOR.message_types_by_name['StimulationInfo'] = _STIMULATIONINFO -DESCRIPTOR.message_types_by_name['AudioSendModeRequest'] = _AUDIOSENDMODEREQUEST -DESCRIPTOR.message_types_by_name['AudioSendModeChanged'] = _AUDIOSENDMODECHANGED -DESCRIPTOR.message_types_by_name['AudioChunk'] = _AUDIOCHUNK -DESCRIPTOR.message_types_by_name['AudioFeedRequest'] = _AUDIOFEEDREQUEST -DESCRIPTOR.message_types_by_name['AudioFeedResponse'] = _AUDIOFEEDRESPONSE -DESCRIPTOR.message_types_by_name['EnableMarkerDetectionRequest'] = _ENABLEMARKERDETECTIONREQUEST -DESCRIPTOR.message_types_by_name['EnableMarkerDetectionResponse'] = _ENABLEMARKERDETECTIONRESPONSE -DESCRIPTOR.message_types_by_name['EnableFaceDetectionRequest'] = _ENABLEFACEDETECTIONREQUEST -DESCRIPTOR.message_types_by_name['EnableFaceDetectionResponse'] = _ENABLEFACEDETECTIONRESPONSE -DESCRIPTOR.message_types_by_name['EnableMotionDetectionRequest'] = _ENABLEMOTIONDETECTIONREQUEST -DESCRIPTOR.message_types_by_name['EnableMotionDetectionResponse'] = _ENABLEMOTIONDETECTIONRESPONSE -DESCRIPTOR.message_types_by_name['EnableMirrorModeRequest'] = _ENABLEMIRRORMODEREQUEST -DESCRIPTOR.message_types_by_name['EnableMirrorModeResponse'] = _ENABLEMIRRORMODERESPONSE -DESCRIPTOR.message_types_by_name['MirrorModeDisabled'] = _MIRRORMODEDISABLED -DESCRIPTOR.message_types_by_name['EnableImageStreamingRequest'] = _ENABLEIMAGESTREAMINGREQUEST -DESCRIPTOR.message_types_by_name['EnableImageStreamingResponse'] = _ENABLEIMAGESTREAMINGRESPONSE -DESCRIPTOR.message_types_by_name['VisionModesAutoDisabled'] = _VISIONMODESAUTODISABLED -DESCRIPTOR.message_types_by_name['ImageChunk'] = _IMAGECHUNK -DESCRIPTOR.message_types_by_name['CameraFeedRequest'] = _CAMERAFEEDREQUEST -DESCRIPTOR.message_types_by_name['CameraFeedResponse'] = _CAMERAFEEDRESPONSE -DESCRIPTOR.message_types_by_name['SetEyeColorRequest'] = _SETEYECOLORREQUEST -DESCRIPTOR.message_types_by_name['SetEyeColorResponse'] = _SETEYECOLORRESPONSE -DESCRIPTOR.message_types_by_name['SDKInitializationRequest'] = _SDKINITIALIZATIONREQUEST -DESCRIPTOR.message_types_by_name['SDKInitializationResponse'] = _SDKINITIALIZATIONRESPONSE -DESCRIPTOR.enum_types_by_name['RobotStatus'] = _ROBOTSTATUS -DESCRIPTOR.enum_types_by_name['FacialExpression'] = _FACIALEXPRESSION -DESCRIPTOR.enum_types_by_name['FaceEnrollmentResult'] = _FACEENROLLMENTRESULT -DESCRIPTOR.enum_types_by_name['BehaviorResults'] = _BEHAVIORRESULTS -DESCRIPTOR.enum_types_by_name['ActionTagConstants'] = _ACTIONTAGCONSTANTS -DESCRIPTOR.enum_types_by_name['AlignmentType'] = _ALIGNMENTTYPE -DESCRIPTOR.enum_types_by_name['BatteryLevel'] = _BATTERYLEVEL -DESCRIPTOR.enum_types_by_name['AudioConstants'] = _AUDIOCONSTANTS -DESCRIPTOR.enum_types_by_name['AudioProcessingMode'] = _AUDIOPROCESSINGMODE -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -KeepAlivePing = _reflection.GeneratedProtocolMessageType('KeepAlivePing', (_message.Message,), dict( - DESCRIPTOR = _KEEPALIVEPING, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.KeepAlivePing) - )) -_sym_db.RegisterMessage(KeepAlivePing) - -Animation = _reflection.GeneratedProtocolMessageType('Animation', (_message.Message,), dict( - DESCRIPTOR = _ANIMATION, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.Animation) - )) -_sym_db.RegisterMessage(Animation) - -DriveWheelsRequest = _reflection.GeneratedProtocolMessageType('DriveWheelsRequest', (_message.Message,), dict( - DESCRIPTOR = _DRIVEWHEELSREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DriveWheelsRequest) - )) -_sym_db.RegisterMessage(DriveWheelsRequest) - -DriveWheelsResponse = _reflection.GeneratedProtocolMessageType('DriveWheelsResponse', (_message.Message,), dict( - DESCRIPTOR = _DRIVEWHEELSRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DriveWheelsResponse) - )) -_sym_db.RegisterMessage(DriveWheelsResponse) - -MoveHeadRequest = _reflection.GeneratedProtocolMessageType('MoveHeadRequest', (_message.Message,), dict( - DESCRIPTOR = _MOVEHEADREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.MoveHeadRequest) - )) -_sym_db.RegisterMessage(MoveHeadRequest) - -MoveHeadResponse = _reflection.GeneratedProtocolMessageType('MoveHeadResponse', (_message.Message,), dict( - DESCRIPTOR = _MOVEHEADRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.MoveHeadResponse) - )) -_sym_db.RegisterMessage(MoveHeadResponse) - -MoveLiftRequest = _reflection.GeneratedProtocolMessageType('MoveLiftRequest', (_message.Message,), dict( - DESCRIPTOR = _MOVELIFTREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.MoveLiftRequest) - )) -_sym_db.RegisterMessage(MoveLiftRequest) - -MoveLiftResponse = _reflection.GeneratedProtocolMessageType('MoveLiftResponse', (_message.Message,), dict( - DESCRIPTOR = _MOVELIFTRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.MoveLiftResponse) - )) -_sym_db.RegisterMessage(MoveLiftResponse) - -PlayAnimationRequest = _reflection.GeneratedProtocolMessageType('PlayAnimationRequest', (_message.Message,), dict( - DESCRIPTOR = _PLAYANIMATIONREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.PlayAnimationRequest) - )) -_sym_db.RegisterMessage(PlayAnimationRequest) - -PlayAnimationResponse = _reflection.GeneratedProtocolMessageType('PlayAnimationResponse', (_message.Message,), dict( - DESCRIPTOR = _PLAYANIMATIONRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.PlayAnimationResponse) - )) -_sym_db.RegisterMessage(PlayAnimationResponse) - -ListAnimationsRequest = _reflection.GeneratedProtocolMessageType('ListAnimationsRequest', (_message.Message,), dict( - DESCRIPTOR = _LISTANIMATIONSREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ListAnimationsRequest) - )) -_sym_db.RegisterMessage(ListAnimationsRequest) - -ListAnimationsResponse = _reflection.GeneratedProtocolMessageType('ListAnimationsResponse', (_message.Message,), dict( - DESCRIPTOR = _LISTANIMATIONSRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ListAnimationsResponse) - )) -_sym_db.RegisterMessage(ListAnimationsResponse) - -DisplayFaceImageRGBRequest = _reflection.GeneratedProtocolMessageType('DisplayFaceImageRGBRequest', (_message.Message,), dict( - DESCRIPTOR = _DISPLAYFACEIMAGERGBREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DisplayFaceImageRGBRequest) - )) -_sym_db.RegisterMessage(DisplayFaceImageRGBRequest) - -DisplayFaceImageRGBResponse = _reflection.GeneratedProtocolMessageType('DisplayFaceImageRGBResponse', (_message.Message,), dict( - DESCRIPTOR = _DISPLAYFACEIMAGERGBRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DisplayFaceImageRGBResponse) - )) -_sym_db.RegisterMessage(DisplayFaceImageRGBResponse) - -MeetVictorFaceScanStarted = _reflection.GeneratedProtocolMessageType('MeetVictorFaceScanStarted', (_message.Message,), dict( - DESCRIPTOR = _MEETVICTORFACESCANSTARTED, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.MeetVictorFaceScanStarted) - )) -_sym_db.RegisterMessage(MeetVictorFaceScanStarted) - -MeetVictorFaceScanComplete = _reflection.GeneratedProtocolMessageType('MeetVictorFaceScanComplete', (_message.Message,), dict( - DESCRIPTOR = _MEETVICTORFACESCANCOMPLETE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.MeetVictorFaceScanComplete) - )) -_sym_db.RegisterMessage(MeetVictorFaceScanComplete) - -Status = _reflection.GeneratedProtocolMessageType('Status', (_message.Message,), dict( - DESCRIPTOR = _STATUS, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.Status) - )) -_sym_db.RegisterMessage(Status) - -WakeWord = _reflection.GeneratedProtocolMessageType('WakeWord', (_message.Message,), dict( - DESCRIPTOR = _WAKEWORD, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.WakeWord) - )) -_sym_db.RegisterMessage(WakeWord) - -TimeStampedStatus = _reflection.GeneratedProtocolMessageType('TimeStampedStatus', (_message.Message,), dict( - DESCRIPTOR = _TIMESTAMPEDSTATUS, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.TimeStampedStatus) - )) -_sym_db.RegisterMessage(TimeStampedStatus) - -PoseStruct = _reflection.GeneratedProtocolMessageType('PoseStruct', (_message.Message,), dict( - DESCRIPTOR = _POSESTRUCT, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.PoseStruct) - )) -_sym_db.RegisterMessage(PoseStruct) - -AccelData = _reflection.GeneratedProtocolMessageType('AccelData', (_message.Message,), dict( - DESCRIPTOR = _ACCELDATA, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.AccelData) - )) -_sym_db.RegisterMessage(AccelData) - -GyroData = _reflection.GeneratedProtocolMessageType('GyroData', (_message.Message,), dict( - DESCRIPTOR = _GYRODATA, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.GyroData) - )) -_sym_db.RegisterMessage(GyroData) - -ProxData = _reflection.GeneratedProtocolMessageType('ProxData', (_message.Message,), dict( - DESCRIPTOR = _PROXDATA, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ProxData) - )) -_sym_db.RegisterMessage(ProxData) - -TouchData = _reflection.GeneratedProtocolMessageType('TouchData', (_message.Message,), dict( - DESCRIPTOR = _TOUCHDATA, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.TouchData) - )) -_sym_db.RegisterMessage(TouchData) - -RobotState = _reflection.GeneratedProtocolMessageType('RobotState', (_message.Message,), dict( - DESCRIPTOR = _ROBOTSTATE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.RobotState) - )) -_sym_db.RegisterMessage(RobotState) - -CladPoint = _reflection.GeneratedProtocolMessageType('CladPoint', (_message.Message,), dict( - DESCRIPTOR = _CLADPOINT, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.CladPoint) - )) -_sym_db.RegisterMessage(CladPoint) - -CladRect = _reflection.GeneratedProtocolMessageType('CladRect', (_message.Message,), dict( - DESCRIPTOR = _CLADRECT, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.CladRect) - )) -_sym_db.RegisterMessage(CladRect) - -RobotObservedFace = _reflection.GeneratedProtocolMessageType('RobotObservedFace', (_message.Message,), dict( - DESCRIPTOR = _ROBOTOBSERVEDFACE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.RobotObservedFace) - )) -_sym_db.RegisterMessage(RobotObservedFace) - -RobotChangedObservedFaceID = _reflection.GeneratedProtocolMessageType('RobotChangedObservedFaceID', (_message.Message,), dict( - DESCRIPTOR = _ROBOTCHANGEDOBSERVEDFACEID, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.RobotChangedObservedFaceID) - )) -_sym_db.RegisterMessage(RobotChangedObservedFaceID) - -AppIntentRequest = _reflection.GeneratedProtocolMessageType('AppIntentRequest', (_message.Message,), dict( - DESCRIPTOR = _APPINTENTREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.AppIntentRequest) - )) -_sym_db.RegisterMessage(AppIntentRequest) - -AppDisconnected = _reflection.GeneratedProtocolMessageType('AppDisconnected', (_message.Message,), dict( - DESCRIPTOR = _APPDISCONNECTED, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.AppDisconnected) - )) -_sym_db.RegisterMessage(AppDisconnected) - -AppIntentResponse = _reflection.GeneratedProtocolMessageType('AppIntentResponse', (_message.Message,), dict( - DESCRIPTOR = _APPINTENTRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.AppIntentResponse) - )) -_sym_db.RegisterMessage(AppIntentResponse) - -FaceEnrollmentCompleted = _reflection.GeneratedProtocolMessageType('FaceEnrollmentCompleted', (_message.Message,), dict( - DESCRIPTOR = _FACEENROLLMENTCOMPLETED, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.FaceEnrollmentCompleted) - )) -_sym_db.RegisterMessage(FaceEnrollmentCompleted) - -CancelFaceEnrollmentRequest = _reflection.GeneratedProtocolMessageType('CancelFaceEnrollmentRequest', (_message.Message,), dict( - DESCRIPTOR = _CANCELFACEENROLLMENTREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.CancelFaceEnrollmentRequest) - )) -_sym_db.RegisterMessage(CancelFaceEnrollmentRequest) - -CancelFaceEnrollmentResponse = _reflection.GeneratedProtocolMessageType('CancelFaceEnrollmentResponse', (_message.Message,), dict( - DESCRIPTOR = _CANCELFACEENROLLMENTRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.CancelFaceEnrollmentResponse) - )) -_sym_db.RegisterMessage(CancelFaceEnrollmentResponse) - -RequestEnrolledNamesRequest = _reflection.GeneratedProtocolMessageType('RequestEnrolledNamesRequest', (_message.Message,), dict( - DESCRIPTOR = _REQUESTENROLLEDNAMESREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.RequestEnrolledNamesRequest) - )) -_sym_db.RegisterMessage(RequestEnrolledNamesRequest) - -LoadedKnownFace = _reflection.GeneratedProtocolMessageType('LoadedKnownFace', (_message.Message,), dict( - DESCRIPTOR = _LOADEDKNOWNFACE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.LoadedKnownFace) - )) -_sym_db.RegisterMessage(LoadedKnownFace) - -RobotRenamedEnrolledFace = _reflection.GeneratedProtocolMessageType('RobotRenamedEnrolledFace', (_message.Message,), dict( - DESCRIPTOR = _ROBOTRENAMEDENROLLEDFACE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.RobotRenamedEnrolledFace) - )) -_sym_db.RegisterMessage(RobotRenamedEnrolledFace) - -RequestEnrolledNamesResponse = _reflection.GeneratedProtocolMessageType('RequestEnrolledNamesResponse', (_message.Message,), dict( - DESCRIPTOR = _REQUESTENROLLEDNAMESRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.RequestEnrolledNamesResponse) - )) -_sym_db.RegisterMessage(RequestEnrolledNamesResponse) - -UpdateEnrolledFaceByIDRequest = _reflection.GeneratedProtocolMessageType('UpdateEnrolledFaceByIDRequest', (_message.Message,), dict( - DESCRIPTOR = _UPDATEENROLLEDFACEBYIDREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.UpdateEnrolledFaceByIDRequest) - )) -_sym_db.RegisterMessage(UpdateEnrolledFaceByIDRequest) - -UpdateEnrolledFaceByIDResponse = _reflection.GeneratedProtocolMessageType('UpdateEnrolledFaceByIDResponse', (_message.Message,), dict( - DESCRIPTOR = _UPDATEENROLLEDFACEBYIDRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.UpdateEnrolledFaceByIDResponse) - )) -_sym_db.RegisterMessage(UpdateEnrolledFaceByIDResponse) - -EraseEnrolledFaceByIDRequest = _reflection.GeneratedProtocolMessageType('EraseEnrolledFaceByIDRequest', (_message.Message,), dict( - DESCRIPTOR = _ERASEENROLLEDFACEBYIDREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EraseEnrolledFaceByIDRequest) - )) -_sym_db.RegisterMessage(EraseEnrolledFaceByIDRequest) - -EraseEnrolledFaceByIDResponse = _reflection.GeneratedProtocolMessageType('EraseEnrolledFaceByIDResponse', (_message.Message,), dict( - DESCRIPTOR = _ERASEENROLLEDFACEBYIDRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EraseEnrolledFaceByIDResponse) - )) -_sym_db.RegisterMessage(EraseEnrolledFaceByIDResponse) - -EraseAllEnrolledFacesRequest = _reflection.GeneratedProtocolMessageType('EraseAllEnrolledFacesRequest', (_message.Message,), dict( - DESCRIPTOR = _ERASEALLENROLLEDFACESREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EraseAllEnrolledFacesRequest) - )) -_sym_db.RegisterMessage(EraseAllEnrolledFacesRequest) - -EraseAllEnrolledFacesResponse = _reflection.GeneratedProtocolMessageType('EraseAllEnrolledFacesResponse', (_message.Message,), dict( - DESCRIPTOR = _ERASEALLENROLLEDFACESRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EraseAllEnrolledFacesResponse) - )) -_sym_db.RegisterMessage(EraseAllEnrolledFacesResponse) - -SetFaceToEnrollRequest = _reflection.GeneratedProtocolMessageType('SetFaceToEnrollRequest', (_message.Message,), dict( - DESCRIPTOR = _SETFACETOENROLLREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SetFaceToEnrollRequest) - )) -_sym_db.RegisterMessage(SetFaceToEnrollRequest) - -SetFaceToEnrollResponse = _reflection.GeneratedProtocolMessageType('SetFaceToEnrollResponse', (_message.Message,), dict( - DESCRIPTOR = _SETFACETOENROLLRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SetFaceToEnrollResponse) - )) -_sym_db.RegisterMessage(SetFaceToEnrollResponse) - -DriveOffChargerRequest = _reflection.GeneratedProtocolMessageType('DriveOffChargerRequest', (_message.Message,), dict( - DESCRIPTOR = _DRIVEOFFCHARGERREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DriveOffChargerRequest) - )) -_sym_db.RegisterMessage(DriveOffChargerRequest) - -DriveOffChargerResponse = _reflection.GeneratedProtocolMessageType('DriveOffChargerResponse', (_message.Message,), dict( - DESCRIPTOR = _DRIVEOFFCHARGERRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DriveOffChargerResponse) - )) -_sym_db.RegisterMessage(DriveOffChargerResponse) - -DriveOnChargerRequest = _reflection.GeneratedProtocolMessageType('DriveOnChargerRequest', (_message.Message,), dict( - DESCRIPTOR = _DRIVEONCHARGERREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DriveOnChargerRequest) - )) -_sym_db.RegisterMessage(DriveOnChargerRequest) - -DriveOnChargerResponse = _reflection.GeneratedProtocolMessageType('DriveOnChargerResponse', (_message.Message,), dict( - DESCRIPTOR = _DRIVEONCHARGERRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DriveOnChargerResponse) - )) -_sym_db.RegisterMessage(DriveOnChargerResponse) - -WakeWordBegin = _reflection.GeneratedProtocolMessageType('WakeWordBegin', (_message.Message,), dict( - DESCRIPTOR = _WAKEWORDBEGIN, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.WakeWordBegin) - )) -_sym_db.RegisterMessage(WakeWordBegin) - -WakeWordEnd = _reflection.GeneratedProtocolMessageType('WakeWordEnd', (_message.Message,), dict( - DESCRIPTOR = _WAKEWORDEND, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.WakeWordEnd) - )) -_sym_db.RegisterMessage(WakeWordEnd) - -PhotoInfo = _reflection.GeneratedProtocolMessageType('PhotoInfo', (_message.Message,), dict( - DESCRIPTOR = _PHOTOINFO, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.PhotoInfo) - )) -_sym_db.RegisterMessage(PhotoInfo) - -PhotosInfoRequest = _reflection.GeneratedProtocolMessageType('PhotosInfoRequest', (_message.Message,), dict( - DESCRIPTOR = _PHOTOSINFOREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.PhotosInfoRequest) - )) -_sym_db.RegisterMessage(PhotosInfoRequest) - -PhotosInfoResponse = _reflection.GeneratedProtocolMessageType('PhotosInfoResponse', (_message.Message,), dict( - DESCRIPTOR = _PHOTOSINFORESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.PhotosInfoResponse) - )) -_sym_db.RegisterMessage(PhotosInfoResponse) - -PhotoRequest = _reflection.GeneratedProtocolMessageType('PhotoRequest', (_message.Message,), dict( - DESCRIPTOR = _PHOTOREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.PhotoRequest) - )) -_sym_db.RegisterMessage(PhotoRequest) - -PhotoPathMessage = _reflection.GeneratedProtocolMessageType('PhotoPathMessage', (_message.Message,), dict( - DESCRIPTOR = _PHOTOPATHMESSAGE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.PhotoPathMessage) - )) -_sym_db.RegisterMessage(PhotoPathMessage) - -PhotoResponse = _reflection.GeneratedProtocolMessageType('PhotoResponse', (_message.Message,), dict( - DESCRIPTOR = _PHOTORESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.PhotoResponse) - )) -_sym_db.RegisterMessage(PhotoResponse) - -ThumbnailRequest = _reflection.GeneratedProtocolMessageType('ThumbnailRequest', (_message.Message,), dict( - DESCRIPTOR = _THUMBNAILREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ThumbnailRequest) - )) -_sym_db.RegisterMessage(ThumbnailRequest) - -ThumbnailPathMessage = _reflection.GeneratedProtocolMessageType('ThumbnailPathMessage', (_message.Message,), dict( - DESCRIPTOR = _THUMBNAILPATHMESSAGE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ThumbnailPathMessage) - )) -_sym_db.RegisterMessage(ThumbnailPathMessage) - -ThumbnailResponse = _reflection.GeneratedProtocolMessageType('ThumbnailResponse', (_message.Message,), dict( - DESCRIPTOR = _THUMBNAILRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ThumbnailResponse) - )) -_sym_db.RegisterMessage(ThumbnailResponse) - -DeletePhotoRequest = _reflection.GeneratedProtocolMessageType('DeletePhotoRequest', (_message.Message,), dict( - DESCRIPTOR = _DELETEPHOTOREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DeletePhotoRequest) - )) -_sym_db.RegisterMessage(DeletePhotoRequest) - -DeletePhotoResponse = _reflection.GeneratedProtocolMessageType('DeletePhotoResponse', (_message.Message,), dict( - DESCRIPTOR = _DELETEPHOTORESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DeletePhotoResponse) - )) -_sym_db.RegisterMessage(DeletePhotoResponse) - -PhotoTaken = _reflection.GeneratedProtocolMessageType('PhotoTaken', (_message.Message,), dict( - DESCRIPTOR = _PHOTOTAKEN, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.PhotoTaken) - )) -_sym_db.RegisterMessage(PhotoTaken) - -PathMotionProfile = _reflection.GeneratedProtocolMessageType('PathMotionProfile', (_message.Message,), dict( - DESCRIPTOR = _PATHMOTIONPROFILE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.PathMotionProfile) - )) -_sym_db.RegisterMessage(PathMotionProfile) - -ActionResult = _reflection.GeneratedProtocolMessageType('ActionResult', (_message.Message,), dict( - DESCRIPTOR = _ACTIONRESULT, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ActionResult) - )) -_sym_db.RegisterMessage(ActionResult) - -GoToPoseRequest = _reflection.GeneratedProtocolMessageType('GoToPoseRequest', (_message.Message,), dict( - DESCRIPTOR = _GOTOPOSEREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.GoToPoseRequest) - )) -_sym_db.RegisterMessage(GoToPoseRequest) - -GoToPoseResponse = _reflection.GeneratedProtocolMessageType('GoToPoseResponse', (_message.Message,), dict( - DESCRIPTOR = _GOTOPOSERESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.GoToPoseResponse) - )) -_sym_db.RegisterMessage(GoToPoseResponse) - -DockWithCubeRequest = _reflection.GeneratedProtocolMessageType('DockWithCubeRequest', (_message.Message,), dict( - DESCRIPTOR = _DOCKWITHCUBEREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DockWithCubeRequest) - )) -_sym_db.RegisterMessage(DockWithCubeRequest) - -DockWithCubeResponse = _reflection.GeneratedProtocolMessageType('DockWithCubeResponse', (_message.Message,), dict( - DESCRIPTOR = _DOCKWITHCUBERESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DockWithCubeResponse) - )) -_sym_db.RegisterMessage(DockWithCubeResponse) - -DriveStraightRequest = _reflection.GeneratedProtocolMessageType('DriveStraightRequest', (_message.Message,), dict( - DESCRIPTOR = _DRIVESTRAIGHTREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DriveStraightRequest) - )) -_sym_db.RegisterMessage(DriveStraightRequest) - -DriveStraightResponse = _reflection.GeneratedProtocolMessageType('DriveStraightResponse', (_message.Message,), dict( - DESCRIPTOR = _DRIVESTRAIGHTRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.DriveStraightResponse) - )) -_sym_db.RegisterMessage(DriveStraightResponse) - -TurnInPlaceRequest = _reflection.GeneratedProtocolMessageType('TurnInPlaceRequest', (_message.Message,), dict( - DESCRIPTOR = _TURNINPLACEREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.TurnInPlaceRequest) - )) -_sym_db.RegisterMessage(TurnInPlaceRequest) - -TurnInPlaceResponse = _reflection.GeneratedProtocolMessageType('TurnInPlaceResponse', (_message.Message,), dict( - DESCRIPTOR = _TURNINPLACERESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.TurnInPlaceResponse) - )) -_sym_db.RegisterMessage(TurnInPlaceResponse) - -SetHeadAngleRequest = _reflection.GeneratedProtocolMessageType('SetHeadAngleRequest', (_message.Message,), dict( - DESCRIPTOR = _SETHEADANGLEREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SetHeadAngleRequest) - )) -_sym_db.RegisterMessage(SetHeadAngleRequest) - -SetHeadAngleResponse = _reflection.GeneratedProtocolMessageType('SetHeadAngleResponse', (_message.Message,), dict( - DESCRIPTOR = _SETHEADANGLERESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SetHeadAngleResponse) - )) -_sym_db.RegisterMessage(SetHeadAngleResponse) - -SetLiftHeightRequest = _reflection.GeneratedProtocolMessageType('SetLiftHeightRequest', (_message.Message,), dict( - DESCRIPTOR = _SETLIFTHEIGHTREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SetLiftHeightRequest) - )) -_sym_db.RegisterMessage(SetLiftHeightRequest) - -SetLiftHeightResponse = _reflection.GeneratedProtocolMessageType('SetLiftHeightResponse', (_message.Message,), dict( - DESCRIPTOR = _SETLIFTHEIGHTRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SetLiftHeightResponse) - )) -_sym_db.RegisterMessage(SetLiftHeightResponse) - -NetworkStats = _reflection.GeneratedProtocolMessageType('NetworkStats', (_message.Message,), dict( - DESCRIPTOR = _NETWORKSTATS, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.NetworkStats) - )) -_sym_db.RegisterMessage(NetworkStats) - -BatteryStateRequest = _reflection.GeneratedProtocolMessageType('BatteryStateRequest', (_message.Message,), dict( - DESCRIPTOR = _BATTERYSTATEREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.BatteryStateRequest) - )) -_sym_db.RegisterMessage(BatteryStateRequest) - -BatteryStateResponse = _reflection.GeneratedProtocolMessageType('BatteryStateResponse', (_message.Message,), dict( - DESCRIPTOR = _BATTERYSTATERESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.BatteryStateResponse) - )) -_sym_db.RegisterMessage(BatteryStateResponse) - -CubeBattery = _reflection.GeneratedProtocolMessageType('CubeBattery', (_message.Message,), dict( - DESCRIPTOR = _CUBEBATTERY, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.CubeBattery) - )) -_sym_db.RegisterMessage(CubeBattery) - -VersionStateRequest = _reflection.GeneratedProtocolMessageType('VersionStateRequest', (_message.Message,), dict( - DESCRIPTOR = _VERSIONSTATEREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.VersionStateRequest) - )) -_sym_db.RegisterMessage(VersionStateRequest) - -VersionStateResponse = _reflection.GeneratedProtocolMessageType('VersionStateResponse', (_message.Message,), dict( - DESCRIPTOR = _VERSIONSTATERESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.VersionStateResponse) - )) -_sym_db.RegisterMessage(VersionStateResponse) - -NetworkStateRequest = _reflection.GeneratedProtocolMessageType('NetworkStateRequest', (_message.Message,), dict( - DESCRIPTOR = _NETWORKSTATEREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.NetworkStateRequest) - )) -_sym_db.RegisterMessage(NetworkStateRequest) - -NetworkStateResponse = _reflection.GeneratedProtocolMessageType('NetworkStateResponse', (_message.Message,), dict( - DESCRIPTOR = _NETWORKSTATERESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.NetworkStateResponse) - )) -_sym_db.RegisterMessage(NetworkStateResponse) - -SayTextRequest = _reflection.GeneratedProtocolMessageType('SayTextRequest', (_message.Message,), dict( - DESCRIPTOR = _SAYTEXTREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SayTextRequest) - )) -_sym_db.RegisterMessage(SayTextRequest) - -SayTextResponse = _reflection.GeneratedProtocolMessageType('SayTextResponse', (_message.Message,), dict( - DESCRIPTOR = _SAYTEXTRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SayTextResponse) - )) -_sym_db.RegisterMessage(SayTextResponse) - -StimulationInfo = _reflection.GeneratedProtocolMessageType('StimulationInfo', (_message.Message,), dict( - DESCRIPTOR = _STIMULATIONINFO, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.StimulationInfo) - )) -_sym_db.RegisterMessage(StimulationInfo) - -AudioSendModeRequest = _reflection.GeneratedProtocolMessageType('AudioSendModeRequest', (_message.Message,), dict( - DESCRIPTOR = _AUDIOSENDMODEREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.AudioSendModeRequest) - )) -_sym_db.RegisterMessage(AudioSendModeRequest) - -AudioSendModeChanged = _reflection.GeneratedProtocolMessageType('AudioSendModeChanged', (_message.Message,), dict( - DESCRIPTOR = _AUDIOSENDMODECHANGED, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.AudioSendModeChanged) - )) -_sym_db.RegisterMessage(AudioSendModeChanged) - -AudioChunk = _reflection.GeneratedProtocolMessageType('AudioChunk', (_message.Message,), dict( - DESCRIPTOR = _AUDIOCHUNK, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.AudioChunk) - )) -_sym_db.RegisterMessage(AudioChunk) - -AudioFeedRequest = _reflection.GeneratedProtocolMessageType('AudioFeedRequest', (_message.Message,), dict( - DESCRIPTOR = _AUDIOFEEDREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.AudioFeedRequest) - )) -_sym_db.RegisterMessage(AudioFeedRequest) - -AudioFeedResponse = _reflection.GeneratedProtocolMessageType('AudioFeedResponse', (_message.Message,), dict( - DESCRIPTOR = _AUDIOFEEDRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.AudioFeedResponse) - )) -_sym_db.RegisterMessage(AudioFeedResponse) - -EnableMarkerDetectionRequest = _reflection.GeneratedProtocolMessageType('EnableMarkerDetectionRequest', (_message.Message,), dict( - DESCRIPTOR = _ENABLEMARKERDETECTIONREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EnableMarkerDetectionRequest) - )) -_sym_db.RegisterMessage(EnableMarkerDetectionRequest) - -EnableMarkerDetectionResponse = _reflection.GeneratedProtocolMessageType('EnableMarkerDetectionResponse', (_message.Message,), dict( - DESCRIPTOR = _ENABLEMARKERDETECTIONRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EnableMarkerDetectionResponse) - )) -_sym_db.RegisterMessage(EnableMarkerDetectionResponse) - -EnableFaceDetectionRequest = _reflection.GeneratedProtocolMessageType('EnableFaceDetectionRequest', (_message.Message,), dict( - DESCRIPTOR = _ENABLEFACEDETECTIONREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EnableFaceDetectionRequest) - )) -_sym_db.RegisterMessage(EnableFaceDetectionRequest) - -EnableFaceDetectionResponse = _reflection.GeneratedProtocolMessageType('EnableFaceDetectionResponse', (_message.Message,), dict( - DESCRIPTOR = _ENABLEFACEDETECTIONRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EnableFaceDetectionResponse) - )) -_sym_db.RegisterMessage(EnableFaceDetectionResponse) - -EnableMotionDetectionRequest = _reflection.GeneratedProtocolMessageType('EnableMotionDetectionRequest', (_message.Message,), dict( - DESCRIPTOR = _ENABLEMOTIONDETECTIONREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EnableMotionDetectionRequest) - )) -_sym_db.RegisterMessage(EnableMotionDetectionRequest) - -EnableMotionDetectionResponse = _reflection.GeneratedProtocolMessageType('EnableMotionDetectionResponse', (_message.Message,), dict( - DESCRIPTOR = _ENABLEMOTIONDETECTIONRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EnableMotionDetectionResponse) - )) -_sym_db.RegisterMessage(EnableMotionDetectionResponse) - -EnableMirrorModeRequest = _reflection.GeneratedProtocolMessageType('EnableMirrorModeRequest', (_message.Message,), dict( - DESCRIPTOR = _ENABLEMIRRORMODEREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EnableMirrorModeRequest) - )) -_sym_db.RegisterMessage(EnableMirrorModeRequest) - -EnableMirrorModeResponse = _reflection.GeneratedProtocolMessageType('EnableMirrorModeResponse', (_message.Message,), dict( - DESCRIPTOR = _ENABLEMIRRORMODERESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EnableMirrorModeResponse) - )) -_sym_db.RegisterMessage(EnableMirrorModeResponse) - -MirrorModeDisabled = _reflection.GeneratedProtocolMessageType('MirrorModeDisabled', (_message.Message,), dict( - DESCRIPTOR = _MIRRORMODEDISABLED, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.MirrorModeDisabled) - )) -_sym_db.RegisterMessage(MirrorModeDisabled) - -EnableImageStreamingRequest = _reflection.GeneratedProtocolMessageType('EnableImageStreamingRequest', (_message.Message,), dict( - DESCRIPTOR = _ENABLEIMAGESTREAMINGREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EnableImageStreamingRequest) - )) -_sym_db.RegisterMessage(EnableImageStreamingRequest) - -EnableImageStreamingResponse = _reflection.GeneratedProtocolMessageType('EnableImageStreamingResponse', (_message.Message,), dict( - DESCRIPTOR = _ENABLEIMAGESTREAMINGRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EnableImageStreamingResponse) - )) -_sym_db.RegisterMessage(EnableImageStreamingResponse) - -VisionModesAutoDisabled = _reflection.GeneratedProtocolMessageType('VisionModesAutoDisabled', (_message.Message,), dict( - DESCRIPTOR = _VISIONMODESAUTODISABLED, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.VisionModesAutoDisabled) - )) -_sym_db.RegisterMessage(VisionModesAutoDisabled) - -ImageChunk = _reflection.GeneratedProtocolMessageType('ImageChunk', (_message.Message,), dict( - DESCRIPTOR = _IMAGECHUNK, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ImageChunk) - )) -_sym_db.RegisterMessage(ImageChunk) - -CameraFeedRequest = _reflection.GeneratedProtocolMessageType('CameraFeedRequest', (_message.Message,), dict( - DESCRIPTOR = _CAMERAFEEDREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.CameraFeedRequest) - )) -_sym_db.RegisterMessage(CameraFeedRequest) - -CameraFeedResponse = _reflection.GeneratedProtocolMessageType('CameraFeedResponse', (_message.Message,), dict( - DESCRIPTOR = _CAMERAFEEDRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.CameraFeedResponse) - )) -_sym_db.RegisterMessage(CameraFeedResponse) - -SetEyeColorRequest = _reflection.GeneratedProtocolMessageType('SetEyeColorRequest', (_message.Message,), dict( - DESCRIPTOR = _SETEYECOLORREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SetEyeColorRequest) - )) -_sym_db.RegisterMessage(SetEyeColorRequest) - -SetEyeColorResponse = _reflection.GeneratedProtocolMessageType('SetEyeColorResponse', (_message.Message,), dict( - DESCRIPTOR = _SETEYECOLORRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SetEyeColorResponse) - )) -_sym_db.RegisterMessage(SetEyeColorResponse) - -SDKInitializationRequest = _reflection.GeneratedProtocolMessageType('SDKInitializationRequest', (_message.Message,), dict( - DESCRIPTOR = _SDKINITIALIZATIONREQUEST, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SDKInitializationRequest) - )) -_sym_db.RegisterMessage(SDKInitializationRequest) - -SDKInitializationResponse = _reflection.GeneratedProtocolMessageType('SDKInitializationResponse', (_message.Message,), dict( - DESCRIPTOR = _SDKINITIALIZATIONRESPONSE, - __module__ = 'anki_vector.messaging.messages_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.SDKInitializationResponse) - )) -_sym_db.RegisterMessage(SDKInitializationResponse) - - -_FACIALEXPRESSION.has_options = True -_FACIALEXPRESSION._options = _descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\020\001')) -_AUDIOFEEDRESPONSE.has_options = True -_AUDIOFEEDRESPONSE._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\200\246\035\001')) -_CAMERAFEEDRESPONSE.has_options = True -_CAMERAFEEDRESPONSE._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\200\246\035\001')) -# @@protoc_insertion_point(module_scope) diff --git a/anki_vector/messaging/messages_pb2_grpc.py b/anki_vector/messaging/messages_pb2_grpc.py deleted file mode 100644 index a894352..0000000 --- a/anki_vector/messaging/messages_pb2_grpc.py +++ /dev/null @@ -1,3 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - diff --git a/anki_vector/messaging/nav_map.proto b/anki_vector/messaging/nav_map.proto deleted file mode 100644 index 21c97a6..0000000 --- a/anki_vector/messaging/nav_map.proto +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2018 Anki, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License in the file LICENSE.txt or at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// External interface for robot <-> app and robot <-> sdk communication -// about the robot's navigational memory map. - -syntax = "proto3"; - -package Anki.Vector.external_interface; - -// Every tile in the nav map will be tagged with a content key referring to -// the different environmental elements that Vector can identify. -enum NavNodeContentType -{ - NAV_NODE_UNKNOWN = 0; - NAV_NODE_CLEAR_OF_OBSTACLE = 1; - NAV_NODE_CLEAR_OF_CLIFF = 2; - NAV_NODE_OBSTACLE_CUBE = 3; - NAV_NODE_OBSTACLE_PROXIMITY = 4; - NAV_NODE_OBSTACLE_PROXIMITY_EXPLORED = 5; - NAV_NODE_OBSTACLE_UNRECOGNIZED = 6; - NAV_NODE_CLIFF = 7; - NAV_NODE_INTERESTING_EDGE = 8; - NAV_NODE_NON_INTERESTING_EDGE = 9; -} - -// An individual sample of vector's nav map. This quad's size will vary and -// depends on the resolution the map requires to effectively identify -// boundaries in the environment. -message NavMapQuadInfo -{ - NavNodeContentType content = 1; - uint32 depth = 2; - uint32 color_rgba = 3; -} - -// General information about the nav map as a whole. -message NavMapInfo -{ - int32 root_depth = 1; - float root_size_mm = 2; - float root_center_x = 3; - float root_center_y = 4; - float root_center_z = 5; -} - -// Requests nav map data from the robot at a specified maximum update frequency. -// Responses in the nav map stream may be sent less frequently if the robot does -// not consider there to be relevant new information. -message NavMapFeedRequest -{ - float frequency = 1; -} - -// A full nav map sent from the robot. It contains an origin_id that -// which can be compared against the robot's current origin_id, general -// info about the map, and a collection of quads representing the map's -// content. -message NavMapFeedResponse -{ - uint32 origin_id = 1; - NavMapInfo map_info = 2; - repeated NavMapQuadInfo quad_infos = 3; -} diff --git a/anki_vector/messaging/nav_map_pb2.py b/anki_vector/messaging/nav_map_pb2.py deleted file mode 100644 index b5b2feb..0000000 --- a/anki_vector/messaging/nav_map_pb2.py +++ /dev/null @@ -1,312 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: anki_vector/messaging/nav_map.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='anki_vector/messaging/nav_map.proto', - package='Anki.Vector.external_interface', - syntax='proto3', - serialized_pb=_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') -) - -_NAVNODECONTENTTYPE = _descriptor.EnumDescriptor( - name='NavNodeContentType', - full_name='Anki.Vector.external_interface.NavNodeContentType', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='NAV_NODE_UNKNOWN', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NAV_NODE_CLEAR_OF_OBSTACLE', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NAV_NODE_CLEAR_OF_CLIFF', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NAV_NODE_OBSTACLE_CUBE', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NAV_NODE_OBSTACLE_PROXIMITY', index=4, number=4, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NAV_NODE_OBSTACLE_PROXIMITY_EXPLORED', index=5, number=5, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NAV_NODE_OBSTACLE_UNRECOGNIZED', index=6, number=6, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NAV_NODE_CLIFF', index=7, number=7, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NAV_NODE_INTERESTING_EDGE', index=8, number=8, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NAV_NODE_NON_INTERESTING_EDGE', index=9, number=9, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=531, - serialized_end=859, -) -_sym_db.RegisterEnumDescriptor(_NAVNODECONTENTTYPE) - -NavNodeContentType = enum_type_wrapper.EnumTypeWrapper(_NAVNODECONTENTTYPE) -NAV_NODE_UNKNOWN = 0 -NAV_NODE_CLEAR_OF_OBSTACLE = 1 -NAV_NODE_CLEAR_OF_CLIFF = 2 -NAV_NODE_OBSTACLE_CUBE = 3 -NAV_NODE_OBSTACLE_PROXIMITY = 4 -NAV_NODE_OBSTACLE_PROXIMITY_EXPLORED = 5 -NAV_NODE_OBSTACLE_UNRECOGNIZED = 6 -NAV_NODE_CLIFF = 7 -NAV_NODE_INTERESTING_EDGE = 8 -NAV_NODE_NON_INTERESTING_EDGE = 9 - - - -_NAVMAPQUADINFO = _descriptor.Descriptor( - name='NavMapQuadInfo', - full_name='Anki.Vector.external_interface.NavMapQuadInfo', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='content', full_name='Anki.Vector.external_interface.NavMapQuadInfo.content', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='depth', full_name='Anki.Vector.external_interface.NavMapQuadInfo.depth', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='color_rgba', full_name='Anki.Vector.external_interface.NavMapQuadInfo.color_rgba', index=2, - number=3, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=71, - serialized_end=191, -) - - -_NAVMAPINFO = _descriptor.Descriptor( - name='NavMapInfo', - full_name='Anki.Vector.external_interface.NavMapInfo', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='root_depth', full_name='Anki.Vector.external_interface.NavMapInfo.root_depth', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='root_size_mm', full_name='Anki.Vector.external_interface.NavMapInfo.root_size_mm', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='root_center_x', full_name='Anki.Vector.external_interface.NavMapInfo.root_center_x', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='root_center_y', full_name='Anki.Vector.external_interface.NavMapInfo.root_center_y', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='root_center_z', full_name='Anki.Vector.external_interface.NavMapInfo.root_center_z', index=4, - number=5, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=193, - serialized_end=316, -) - - -_NAVMAPFEEDREQUEST = _descriptor.Descriptor( - name='NavMapFeedRequest', - full_name='Anki.Vector.external_interface.NavMapFeedRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='frequency', full_name='Anki.Vector.external_interface.NavMapFeedRequest.frequency', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=318, - serialized_end=356, -) - - -_NAVMAPFEEDRESPONSE = _descriptor.Descriptor( - name='NavMapFeedResponse', - full_name='Anki.Vector.external_interface.NavMapFeedResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='origin_id', full_name='Anki.Vector.external_interface.NavMapFeedResponse.origin_id', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='map_info', full_name='Anki.Vector.external_interface.NavMapFeedResponse.map_info', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='quad_infos', full_name='Anki.Vector.external_interface.NavMapFeedResponse.quad_infos', index=2, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=359, - serialized_end=528, -) - -_NAVMAPQUADINFO.fields_by_name['content'].enum_type = _NAVNODECONTENTTYPE -_NAVMAPFEEDRESPONSE.fields_by_name['map_info'].message_type = _NAVMAPINFO -_NAVMAPFEEDRESPONSE.fields_by_name['quad_infos'].message_type = _NAVMAPQUADINFO -DESCRIPTOR.message_types_by_name['NavMapQuadInfo'] = _NAVMAPQUADINFO -DESCRIPTOR.message_types_by_name['NavMapInfo'] = _NAVMAPINFO -DESCRIPTOR.message_types_by_name['NavMapFeedRequest'] = _NAVMAPFEEDREQUEST -DESCRIPTOR.message_types_by_name['NavMapFeedResponse'] = _NAVMAPFEEDRESPONSE -DESCRIPTOR.enum_types_by_name['NavNodeContentType'] = _NAVNODECONTENTTYPE -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -NavMapQuadInfo = _reflection.GeneratedProtocolMessageType('NavMapQuadInfo', (_message.Message,), dict( - DESCRIPTOR = _NAVMAPQUADINFO, - __module__ = 'anki_vector.messaging.nav_map_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.NavMapQuadInfo) - )) -_sym_db.RegisterMessage(NavMapQuadInfo) - -NavMapInfo = _reflection.GeneratedProtocolMessageType('NavMapInfo', (_message.Message,), dict( - DESCRIPTOR = _NAVMAPINFO, - __module__ = 'anki_vector.messaging.nav_map_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.NavMapInfo) - )) -_sym_db.RegisterMessage(NavMapInfo) - -NavMapFeedRequest = _reflection.GeneratedProtocolMessageType('NavMapFeedRequest', (_message.Message,), dict( - DESCRIPTOR = _NAVMAPFEEDREQUEST, - __module__ = 'anki_vector.messaging.nav_map_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.NavMapFeedRequest) - )) -_sym_db.RegisterMessage(NavMapFeedRequest) - -NavMapFeedResponse = _reflection.GeneratedProtocolMessageType('NavMapFeedResponse', (_message.Message,), dict( - DESCRIPTOR = _NAVMAPFEEDRESPONSE, - __module__ = 'anki_vector.messaging.nav_map_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.NavMapFeedResponse) - )) -_sym_db.RegisterMessage(NavMapFeedResponse) - - -# @@protoc_insertion_point(module_scope) diff --git a/anki_vector/messaging/nav_map_pb2_grpc.py b/anki_vector/messaging/nav_map_pb2_grpc.py deleted file mode 100644 index a894352..0000000 --- a/anki_vector/messaging/nav_map_pb2_grpc.py +++ /dev/null @@ -1,3 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - diff --git a/anki_vector/messaging/protocol.py b/anki_vector/messaging/protocol.py deleted file mode 100644 index 2d60fa0..0000000 --- a/anki_vector/messaging/protocol.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# pylint: skip-file - -""" -Protobuf messages exposed to the Vector Python SDK -""" -import sys -import inspect - -from .alexa_pb2 import * -from .behavior_pb2 import * -from .cube_pb2 import * -from .messages_pb2 import * -from .nav_map_pb2 import * -from .response_status_pb2 import * -from .settings_pb2 import * -from .shared_pb2 import * -from .external_interface_pb2 import * - -__all__ = [obj.__name__ for _, obj in inspect.getmembers(sys.modules[__name__]) if inspect.isclass(obj)] diff --git a/anki_vector/messaging/response_status.proto b/anki_vector/messaging/response_status.proto deleted file mode 100644 index 3ac0fc3..0000000 --- a/anki_vector/messaging/response_status.proto +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2018 Anki, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License in the file LICENSE.txt or at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Response status - -syntax = "proto3"; - -package Anki.Vector.external_interface; - -message ResponseStatus { - enum StatusCode { - UNKNOWN = 0; - RESPONSE_RECEIVED = 1; // The message has completed as expected - REQUEST_PROCESSING = 2; // The message has been sent to the robot - OK = 3; - FORBIDDEN = 100; // The user was not authorizied - NOT_FOUND = 101; // The requested attribute was not found - ERROR_UPDATE_IN_PROGRESS = 102; // Currently updating values from another call - } - StatusCode code = 1; -} diff --git a/anki_vector/messaging/response_status_pb2.py b/anki_vector/messaging/response_status_pb2.py deleted file mode 100644 index dcb49e5..0000000 --- a/anki_vector/messaging/response_status_pb2.py +++ /dev/null @@ -1,114 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: anki_vector/messaging/response_status.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='anki_vector/messaging/response_status.proto', - package='Anki.Vector.external_interface', - syntax='proto3', - serialized_pb=_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') -) - - - -_RESPONSESTATUS_STATUSCODE = _descriptor.EnumDescriptor( - name='StatusCode', - full_name='Anki.Vector.external_interface.ResponseStatus.StatusCode', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='UNKNOWN', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='RESPONSE_RECEIVED', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='REQUEST_PROCESSING', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='OK', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='FORBIDDEN', index=4, number=100, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NOT_FOUND', index=5, number=101, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ERROR_UPDATE_IN_PROGRESS', index=6, number=102, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=172, - serialized_end=312, -) -_sym_db.RegisterEnumDescriptor(_RESPONSESTATUS_STATUSCODE) - - -_RESPONSESTATUS = _descriptor.Descriptor( - name='ResponseStatus', - full_name='Anki.Vector.external_interface.ResponseStatus', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='code', full_name='Anki.Vector.external_interface.ResponseStatus.code', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _RESPONSESTATUS_STATUSCODE, - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=80, - serialized_end=312, -) - -_RESPONSESTATUS.fields_by_name['code'].enum_type = _RESPONSESTATUS_STATUSCODE -_RESPONSESTATUS_STATUSCODE.containing_type = _RESPONSESTATUS -DESCRIPTOR.message_types_by_name['ResponseStatus'] = _RESPONSESTATUS -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -ResponseStatus = _reflection.GeneratedProtocolMessageType('ResponseStatus', (_message.Message,), dict( - DESCRIPTOR = _RESPONSESTATUS, - __module__ = 'anki_vector.messaging.response_status_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ResponseStatus) - )) -_sym_db.RegisterMessage(ResponseStatus) - - -# @@protoc_insertion_point(module_scope) diff --git a/anki_vector/messaging/response_status_pb2_grpc.py b/anki_vector/messaging/response_status_pb2_grpc.py deleted file mode 100644 index a894352..0000000 --- a/anki_vector/messaging/response_status_pb2_grpc.py +++ /dev/null @@ -1,3 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - diff --git a/anki_vector/messaging/settings.proto b/anki_vector/messaging/settings.proto deleted file mode 100644 index d3d35cf..0000000 --- a/anki_vector/messaging/settings.proto +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2018 Anki, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License in the file LICENSE.txt or at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Settings definition - -syntax = "proto3"; - -package Anki.Vector.external_interface; - - -enum ApiVersion { - INVALID = 0; - LATEST = 1; -} - -enum Volume { - MUTE = 0; - LOW = 1; - MEDIUM_LOW = 2; - MEDIUM = 3; - MEDIUM_HIGH = 4; - HIGH = 5; -} - diff --git a/anki_vector/messaging/settings_pb2.py b/anki_vector/messaging/settings_pb2.py deleted file mode 100644 index f5dff10..0000000 --- a/anki_vector/messaging/settings_pb2.py +++ /dev/null @@ -1,103 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: anki_vector/messaging/settings.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='anki_vector/messaging/settings.proto', - package='Anki.Vector.external_interface', - syntax='proto3', - serialized_pb=_b('\n$anki_vector/messaging/settings.proto\x12\x1e\x41nki.Vector.external_interface*%\n\nApiVersion\x12\x0b\n\x07INVALID\x10\x00\x12\n\n\x06LATEST\x10\x01*R\n\x06Volume\x12\x08\n\x04MUTE\x10\x00\x12\x07\n\x03LOW\x10\x01\x12\x0e\n\nMEDIUM_LOW\x10\x02\x12\n\n\x06MEDIUM\x10\x03\x12\x0f\n\x0bMEDIUM_HIGH\x10\x04\x12\x08\n\x04HIGH\x10\x05\x62\x06proto3') -) - -_APIVERSION = _descriptor.EnumDescriptor( - name='ApiVersion', - full_name='Anki.Vector.external_interface.ApiVersion', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='INVALID', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='LATEST', index=1, number=1, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=72, - serialized_end=109, -) -_sym_db.RegisterEnumDescriptor(_APIVERSION) - -ApiVersion = enum_type_wrapper.EnumTypeWrapper(_APIVERSION) -_VOLUME = _descriptor.EnumDescriptor( - name='Volume', - full_name='Anki.Vector.external_interface.Volume', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='MUTE', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='LOW', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MEDIUM_LOW', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MEDIUM', index=3, number=3, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MEDIUM_HIGH', index=4, number=4, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='HIGH', index=5, number=5, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=111, - serialized_end=193, -) -_sym_db.RegisterEnumDescriptor(_VOLUME) - -Volume = enum_type_wrapper.EnumTypeWrapper(_VOLUME) -INVALID = 0 -LATEST = 1 -MUTE = 0 -LOW = 1 -MEDIUM_LOW = 2 -MEDIUM = 3 -MEDIUM_HIGH = 4 -HIGH = 5 - - -DESCRIPTOR.enum_types_by_name['ApiVersion'] = _APIVERSION -DESCRIPTOR.enum_types_by_name['Volume'] = _VOLUME -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - - -# @@protoc_insertion_point(module_scope) diff --git a/anki_vector/messaging/settings_pb2_grpc.py b/anki_vector/messaging/settings_pb2_grpc.py deleted file mode 100644 index a894352..0000000 --- a/anki_vector/messaging/settings_pb2_grpc.py +++ /dev/null @@ -1,3 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - diff --git a/anki_vector/messaging/shared.proto b/anki_vector/messaging/shared.proto deleted file mode 100644 index f8e130a..0000000 --- a/anki_vector/messaging/shared.proto +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2018 Anki, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License in the file LICENSE.txt or at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// External interface for robot <-> app and robot <-> sdk communication - -syntax = "proto3"; - -package Anki.Vector.external_interface; - -import "anki_vector/messaging/behavior.proto"; -import "anki_vector/messaging/cube.proto"; -import "anki_vector/messaging/messages.proto"; -import "anki_vector/messaging/settings.proto"; -import "anki_vector/messaging/extensions.proto"; -import "anki_vector/messaging/response_status.proto"; - -message ProtocolVersionRequest { - int64 client_version = 1; - int64 min_host_version = 2; -} - -message ProtocolVersionResponse { - enum Result { - UNSUPPORTED = 0; - SUCCESS = 1; - } - Result result = 1; - int64 host_version = 2; -} - -message ConnectionResponse { - ResponseStatus status = 1; - bool is_primary = 2; -} - -// Messages originating from the engine -message Event { - oneof event_type { - TimeStampedStatus time_stamped_status = 1; - WakeWord wake_word = 3; - RobotObservedFace robot_observed_face = 5; - RobotChangedObservedFaceID robot_changed_observed_face_id = 6; - ObjectEvent object_event = 7; - StimulationInfo stimulation_info = 8; - PhotoTaken photo_taken = 9; - RobotState robot_state = 10; - CubeBattery cube_battery = 11; - KeepAlivePing keep_alive = 12; - ConnectionResponse connection_response = 13; - MirrorModeDisabled mirror_mode_disabled = 16; - VisionModesAutoDisabled vision_modes_auto_disabled = 17; - } -} - -message FilterList { - repeated string list = 1; -} - -message EventRequest { - oneof list_type { - FilterList white_list = 1; - FilterList black_list = 2; - } - string connection_id = 3; -} - -message EventResponse { - option (streamed) = true; - ResponseStatus status = 1; - Event event = 2; -} - -message UserAuthenticationRequest { - bytes user_session_id = 1; - bytes client_name = 2; -} - -message UserAuthenticationResponse { - ResponseStatus status = 1; - enum Code { - UNAUTHORIZED = 0; - AUTHORIZED = 1; - } - Code code = 2; - bytes client_token_guid = 3; -} - diff --git a/anki_vector/messaging/shared_pb2.py b/anki_vector/messaging/shared_pb2.py deleted file mode 100644 index 0310af8..0000000 --- a/anki_vector/messaging/shared_pb2.py +++ /dev/null @@ -1,657 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: anki_vector/messaging/shared.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from anki_vector.messaging import behavior_pb2 as anki__vector_dot_messaging_dot_behavior__pb2 -from anki_vector.messaging import cube_pb2 as anki__vector_dot_messaging_dot_cube__pb2 -from anki_vector.messaging import messages_pb2 as anki__vector_dot_messaging_dot_messages__pb2 -from anki_vector.messaging import settings_pb2 as anki__vector_dot_messaging_dot_settings__pb2 -from anki_vector.messaging import extensions_pb2 as anki__vector_dot_messaging_dot_extensions__pb2 -from anki_vector.messaging import response_status_pb2 as anki__vector_dot_messaging_dot_response__status__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='anki_vector/messaging/shared.proto', - package='Anki.Vector.external_interface', - syntax='proto3', - serialized_pb=_b('\n\"anki_vector/messaging/shared.proto\x12\x1e\x41nki.Vector.external_interface\x1a$anki_vector/messaging/behavior.proto\x1a anki_vector/messaging/cube.proto\x1a$anki_vector/messaging/messages.proto\x1a$anki_vector/messaging/settings.proto\x1a&anki_vector/messaging/extensions.proto\x1a+anki_vector/messaging/response_status.proto\"J\n\x16ProtocolVersionRequest\x12\x16\n\x0e\x63lient_version\x18\x01 \x01(\x03\x12\x18\n\x10min_host_version\x18\x02 \x01(\x03\"\xa7\x01\n\x17ProtocolVersionResponse\x12N\n\x06result\x18\x01 \x01(\x0e\x32>.Anki.Vector.external_interface.ProtocolVersionResponse.Result\x12\x14\n\x0chost_version\x18\x02 \x01(\x03\"&\n\x06Result\x12\x0f\n\x0bUNSUPPORTED\x10\x00\x12\x0b\n\x07SUCCESS\x10\x01\"h\n\x12\x43onnectionResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12\x12\n\nis_primary\x18\x02 \x01(\x08\"\x86\x08\n\x05\x45vent\x12P\n\x13time_stamped_status\x18\x01 \x01(\x0b\x32\x31.Anki.Vector.external_interface.TimeStampedStatusH\x00\x12=\n\twake_word\x18\x03 \x01(\x0b\x32(.Anki.Vector.external_interface.WakeWordH\x00\x12P\n\x13robot_observed_face\x18\x05 \x01(\x0b\x32\x31.Anki.Vector.external_interface.RobotObservedFaceH\x00\x12\x64\n\x1erobot_changed_observed_face_id\x18\x06 \x01(\x0b\x32:.Anki.Vector.external_interface.RobotChangedObservedFaceIDH\x00\x12\x43\n\x0cobject_event\x18\x07 \x01(\x0b\x32+.Anki.Vector.external_interface.ObjectEventH\x00\x12K\n\x10stimulation_info\x18\x08 \x01(\x0b\x32/.Anki.Vector.external_interface.StimulationInfoH\x00\x12\x41\n\x0bphoto_taken\x18\t \x01(\x0b\x32*.Anki.Vector.external_interface.PhotoTakenH\x00\x12\x41\n\x0brobot_state\x18\n \x01(\x0b\x32*.Anki.Vector.external_interface.RobotStateH\x00\x12\x43\n\x0c\x63ube_battery\x18\x0b \x01(\x0b\x32+.Anki.Vector.external_interface.CubeBatteryH\x00\x12\x43\n\nkeep_alive\x18\x0c \x01(\x0b\x32-.Anki.Vector.external_interface.KeepAlivePingH\x00\x12Q\n\x13\x63onnection_response\x18\r \x01(\x0b\x32\x32.Anki.Vector.external_interface.ConnectionResponseH\x00\x12R\n\x14mirror_mode_disabled\x18\x10 \x01(\x0b\x32\x32.Anki.Vector.external_interface.MirrorModeDisabledH\x00\x12]\n\x1avision_modes_auto_disabled\x18\x11 \x01(\x0b\x32\x37.Anki.Vector.external_interface.VisionModesAutoDisabledH\x00\x42\x0c\n\nevent_type\"\x1a\n\nFilterList\x12\x0c\n\x04list\x18\x01 \x03(\t\"\xb6\x01\n\x0c\x45ventRequest\x12@\n\nwhite_list\x18\x01 \x01(\x0b\x32*.Anki.Vector.external_interface.FilterListH\x00\x12@\n\nblack_list\x18\x02 \x01(\x0b\x32*.Anki.Vector.external_interface.FilterListH\x00\x12\x15\n\rconnection_id\x18\x03 \x01(\tB\x0b\n\tlist_type\"\x8b\x01\n\rEventResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12\x34\n\x05\x65vent\x18\x02 \x01(\x0b\x32%.Anki.Vector.external_interface.Event:\x04\x80\xa6\x1d\x01\"I\n\x19UserAuthenticationRequest\x12\x17\n\x0fuser_session_id\x18\x01 \x01(\x0c\x12\x13\n\x0b\x63lient_name\x18\x02 \x01(\x0c\"\xf0\x01\n\x1aUserAuthenticationResponse\x12>\n\x06status\x18\x01 \x01(\x0b\x32..Anki.Vector.external_interface.ResponseStatus\x12M\n\x04\x63ode\x18\x02 \x01(\x0e\x32?.Anki.Vector.external_interface.UserAuthenticationResponse.Code\x12\x19\n\x11\x63lient_token_guid\x18\x03 \x01(\x0c\"(\n\x04\x43ode\x12\x10\n\x0cUNAUTHORIZED\x10\x00\x12\x0e\n\nAUTHORIZED\x10\x01\x62\x06proto3') - , - dependencies=[anki__vector_dot_messaging_dot_behavior__pb2.DESCRIPTOR,anki__vector_dot_messaging_dot_cube__pb2.DESCRIPTOR,anki__vector_dot_messaging_dot_messages__pb2.DESCRIPTOR,anki__vector_dot_messaging_dot_settings__pb2.DESCRIPTOR,anki__vector_dot_messaging_dot_extensions__pb2.DESCRIPTOR,anki__vector_dot_messaging_dot_response__status__pb2.DESCRIPTOR,]) - - - -_PROTOCOLVERSIONRESPONSE_RESULT = _descriptor.EnumDescriptor( - name='Result', - full_name='Anki.Vector.external_interface.ProtocolVersionResponse.Result', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='UNSUPPORTED', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='SUCCESS', index=1, number=1, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=509, - serialized_end=547, -) -_sym_db.RegisterEnumDescriptor(_PROTOCOLVERSIONRESPONSE_RESULT) - -_USERAUTHENTICATIONRESPONSE_CODE = _descriptor.EnumDescriptor( - name='Code', - full_name='Anki.Vector.external_interface.UserAuthenticationResponse.Code', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='UNAUTHORIZED', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='AUTHORIZED', index=1, number=1, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=2319, - serialized_end=2359, -) -_sym_db.RegisterEnumDescriptor(_USERAUTHENTICATIONRESPONSE_CODE) - - -_PROTOCOLVERSIONREQUEST = _descriptor.Descriptor( - name='ProtocolVersionRequest', - full_name='Anki.Vector.external_interface.ProtocolVersionRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='client_version', full_name='Anki.Vector.external_interface.ProtocolVersionRequest.client_version', index=0, - number=1, type=3, cpp_type=2, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='min_host_version', full_name='Anki.Vector.external_interface.ProtocolVersionRequest.min_host_version', index=1, - number=2, type=3, cpp_type=2, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=303, - serialized_end=377, -) - - -_PROTOCOLVERSIONRESPONSE = _descriptor.Descriptor( - name='ProtocolVersionResponse', - full_name='Anki.Vector.external_interface.ProtocolVersionResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='result', full_name='Anki.Vector.external_interface.ProtocolVersionResponse.result', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='host_version', full_name='Anki.Vector.external_interface.ProtocolVersionResponse.host_version', index=1, - number=2, type=3, cpp_type=2, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _PROTOCOLVERSIONRESPONSE_RESULT, - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=380, - serialized_end=547, -) - - -_CONNECTIONRESPONSE = _descriptor.Descriptor( - name='ConnectionResponse', - full_name='Anki.Vector.external_interface.ConnectionResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.ConnectionResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='is_primary', full_name='Anki.Vector.external_interface.ConnectionResponse.is_primary', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=549, - serialized_end=653, -) - - -_EVENT = _descriptor.Descriptor( - name='Event', - full_name='Anki.Vector.external_interface.Event', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='time_stamped_status', full_name='Anki.Vector.external_interface.Event.time_stamped_status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='wake_word', full_name='Anki.Vector.external_interface.Event.wake_word', index=1, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='robot_observed_face', full_name='Anki.Vector.external_interface.Event.robot_observed_face', index=2, - number=5, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='robot_changed_observed_face_id', full_name='Anki.Vector.external_interface.Event.robot_changed_observed_face_id', index=3, - number=6, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='object_event', full_name='Anki.Vector.external_interface.Event.object_event', index=4, - number=7, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='stimulation_info', full_name='Anki.Vector.external_interface.Event.stimulation_info', index=5, - number=8, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='photo_taken', full_name='Anki.Vector.external_interface.Event.photo_taken', index=6, - number=9, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='robot_state', full_name='Anki.Vector.external_interface.Event.robot_state', index=7, - number=10, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='cube_battery', full_name='Anki.Vector.external_interface.Event.cube_battery', index=8, - number=11, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='keep_alive', full_name='Anki.Vector.external_interface.Event.keep_alive', index=9, - number=12, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='connection_response', full_name='Anki.Vector.external_interface.Event.connection_response', index=10, - number=13, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='mirror_mode_disabled', full_name='Anki.Vector.external_interface.Event.mirror_mode_disabled', index=11, - number=16, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='vision_modes_auto_disabled', full_name='Anki.Vector.external_interface.Event.vision_modes_auto_disabled', index=12, - number=17, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='event_type', full_name='Anki.Vector.external_interface.Event.event_type', - index=0, containing_type=None, fields=[]), - ], - serialized_start=656, - serialized_end=1686, -) - - -_FILTERLIST = _descriptor.Descriptor( - name='FilterList', - full_name='Anki.Vector.external_interface.FilterList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='list', full_name='Anki.Vector.external_interface.FilterList.list', index=0, - number=1, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1688, - serialized_end=1714, -) - - -_EVENTREQUEST = _descriptor.Descriptor( - name='EventRequest', - full_name='Anki.Vector.external_interface.EventRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='white_list', full_name='Anki.Vector.external_interface.EventRequest.white_list', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='black_list', full_name='Anki.Vector.external_interface.EventRequest.black_list', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='connection_id', full_name='Anki.Vector.external_interface.EventRequest.connection_id', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='list_type', full_name='Anki.Vector.external_interface.EventRequest.list_type', - index=0, containing_type=None, fields=[]), - ], - serialized_start=1717, - serialized_end=1899, -) - - -_EVENTRESPONSE = _descriptor.Descriptor( - name='EventResponse', - full_name='Anki.Vector.external_interface.EventResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.EventResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='event', full_name='Anki.Vector.external_interface.EventResponse.event', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\200\246\035\001')), - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1902, - serialized_end=2041, -) - - -_USERAUTHENTICATIONREQUEST = _descriptor.Descriptor( - name='UserAuthenticationRequest', - full_name='Anki.Vector.external_interface.UserAuthenticationRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='user_session_id', full_name='Anki.Vector.external_interface.UserAuthenticationRequest.user_session_id', index=0, - number=1, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='client_name', full_name='Anki.Vector.external_interface.UserAuthenticationRequest.client_name', index=1, - number=2, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2043, - serialized_end=2116, -) - - -_USERAUTHENTICATIONRESPONSE = _descriptor.Descriptor( - name='UserAuthenticationResponse', - full_name='Anki.Vector.external_interface.UserAuthenticationResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='Anki.Vector.external_interface.UserAuthenticationResponse.status', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='code', full_name='Anki.Vector.external_interface.UserAuthenticationResponse.code', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='client_token_guid', full_name='Anki.Vector.external_interface.UserAuthenticationResponse.client_token_guid', index=2, - number=3, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _USERAUTHENTICATIONRESPONSE_CODE, - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2119, - serialized_end=2359, -) - -_PROTOCOLVERSIONRESPONSE.fields_by_name['result'].enum_type = _PROTOCOLVERSIONRESPONSE_RESULT -_PROTOCOLVERSIONRESPONSE_RESULT.containing_type = _PROTOCOLVERSIONRESPONSE -_CONNECTIONRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_EVENT.fields_by_name['time_stamped_status'].message_type = anki__vector_dot_messaging_dot_messages__pb2._TIMESTAMPEDSTATUS -_EVENT.fields_by_name['wake_word'].message_type = anki__vector_dot_messaging_dot_messages__pb2._WAKEWORD -_EVENT.fields_by_name['robot_observed_face'].message_type = anki__vector_dot_messaging_dot_messages__pb2._ROBOTOBSERVEDFACE -_EVENT.fields_by_name['robot_changed_observed_face_id'].message_type = anki__vector_dot_messaging_dot_messages__pb2._ROBOTCHANGEDOBSERVEDFACEID -_EVENT.fields_by_name['object_event'].message_type = anki__vector_dot_messaging_dot_cube__pb2._OBJECTEVENT -_EVENT.fields_by_name['stimulation_info'].message_type = anki__vector_dot_messaging_dot_messages__pb2._STIMULATIONINFO -_EVENT.fields_by_name['photo_taken'].message_type = anki__vector_dot_messaging_dot_messages__pb2._PHOTOTAKEN -_EVENT.fields_by_name['robot_state'].message_type = anki__vector_dot_messaging_dot_messages__pb2._ROBOTSTATE -_EVENT.fields_by_name['cube_battery'].message_type = anki__vector_dot_messaging_dot_messages__pb2._CUBEBATTERY -_EVENT.fields_by_name['keep_alive'].message_type = anki__vector_dot_messaging_dot_messages__pb2._KEEPALIVEPING -_EVENT.fields_by_name['connection_response'].message_type = _CONNECTIONRESPONSE -_EVENT.fields_by_name['mirror_mode_disabled'].message_type = anki__vector_dot_messaging_dot_messages__pb2._MIRRORMODEDISABLED -_EVENT.fields_by_name['vision_modes_auto_disabled'].message_type = anki__vector_dot_messaging_dot_messages__pb2._VISIONMODESAUTODISABLED -_EVENT.oneofs_by_name['event_type'].fields.append( - _EVENT.fields_by_name['time_stamped_status']) -_EVENT.fields_by_name['time_stamped_status'].containing_oneof = _EVENT.oneofs_by_name['event_type'] -_EVENT.oneofs_by_name['event_type'].fields.append( - _EVENT.fields_by_name['wake_word']) -_EVENT.fields_by_name['wake_word'].containing_oneof = _EVENT.oneofs_by_name['event_type'] -_EVENT.oneofs_by_name['event_type'].fields.append( - _EVENT.fields_by_name['robot_observed_face']) -_EVENT.fields_by_name['robot_observed_face'].containing_oneof = _EVENT.oneofs_by_name['event_type'] -_EVENT.oneofs_by_name['event_type'].fields.append( - _EVENT.fields_by_name['robot_changed_observed_face_id']) -_EVENT.fields_by_name['robot_changed_observed_face_id'].containing_oneof = _EVENT.oneofs_by_name['event_type'] -_EVENT.oneofs_by_name['event_type'].fields.append( - _EVENT.fields_by_name['object_event']) -_EVENT.fields_by_name['object_event'].containing_oneof = _EVENT.oneofs_by_name['event_type'] -_EVENT.oneofs_by_name['event_type'].fields.append( - _EVENT.fields_by_name['stimulation_info']) -_EVENT.fields_by_name['stimulation_info'].containing_oneof = _EVENT.oneofs_by_name['event_type'] -_EVENT.oneofs_by_name['event_type'].fields.append( - _EVENT.fields_by_name['photo_taken']) -_EVENT.fields_by_name['photo_taken'].containing_oneof = _EVENT.oneofs_by_name['event_type'] -_EVENT.oneofs_by_name['event_type'].fields.append( - _EVENT.fields_by_name['robot_state']) -_EVENT.fields_by_name['robot_state'].containing_oneof = _EVENT.oneofs_by_name['event_type'] -_EVENT.oneofs_by_name['event_type'].fields.append( - _EVENT.fields_by_name['cube_battery']) -_EVENT.fields_by_name['cube_battery'].containing_oneof = _EVENT.oneofs_by_name['event_type'] -_EVENT.oneofs_by_name['event_type'].fields.append( - _EVENT.fields_by_name['keep_alive']) -_EVENT.fields_by_name['keep_alive'].containing_oneof = _EVENT.oneofs_by_name['event_type'] -_EVENT.oneofs_by_name['event_type'].fields.append( - _EVENT.fields_by_name['connection_response']) -_EVENT.fields_by_name['connection_response'].containing_oneof = _EVENT.oneofs_by_name['event_type'] -_EVENT.oneofs_by_name['event_type'].fields.append( - _EVENT.fields_by_name['mirror_mode_disabled']) -_EVENT.fields_by_name['mirror_mode_disabled'].containing_oneof = _EVENT.oneofs_by_name['event_type'] -_EVENT.oneofs_by_name['event_type'].fields.append( - _EVENT.fields_by_name['vision_modes_auto_disabled']) -_EVENT.fields_by_name['vision_modes_auto_disabled'].containing_oneof = _EVENT.oneofs_by_name['event_type'] -_EVENTREQUEST.fields_by_name['white_list'].message_type = _FILTERLIST -_EVENTREQUEST.fields_by_name['black_list'].message_type = _FILTERLIST -_EVENTREQUEST.oneofs_by_name['list_type'].fields.append( - _EVENTREQUEST.fields_by_name['white_list']) -_EVENTREQUEST.fields_by_name['white_list'].containing_oneof = _EVENTREQUEST.oneofs_by_name['list_type'] -_EVENTREQUEST.oneofs_by_name['list_type'].fields.append( - _EVENTREQUEST.fields_by_name['black_list']) -_EVENTREQUEST.fields_by_name['black_list'].containing_oneof = _EVENTREQUEST.oneofs_by_name['list_type'] -_EVENTRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_EVENTRESPONSE.fields_by_name['event'].message_type = _EVENT -_USERAUTHENTICATIONRESPONSE.fields_by_name['status'].message_type = anki__vector_dot_messaging_dot_response__status__pb2._RESPONSESTATUS -_USERAUTHENTICATIONRESPONSE.fields_by_name['code'].enum_type = _USERAUTHENTICATIONRESPONSE_CODE -_USERAUTHENTICATIONRESPONSE_CODE.containing_type = _USERAUTHENTICATIONRESPONSE -DESCRIPTOR.message_types_by_name['ProtocolVersionRequest'] = _PROTOCOLVERSIONREQUEST -DESCRIPTOR.message_types_by_name['ProtocolVersionResponse'] = _PROTOCOLVERSIONRESPONSE -DESCRIPTOR.message_types_by_name['ConnectionResponse'] = _CONNECTIONRESPONSE -DESCRIPTOR.message_types_by_name['Event'] = _EVENT -DESCRIPTOR.message_types_by_name['FilterList'] = _FILTERLIST -DESCRIPTOR.message_types_by_name['EventRequest'] = _EVENTREQUEST -DESCRIPTOR.message_types_by_name['EventResponse'] = _EVENTRESPONSE -DESCRIPTOR.message_types_by_name['UserAuthenticationRequest'] = _USERAUTHENTICATIONREQUEST -DESCRIPTOR.message_types_by_name['UserAuthenticationResponse'] = _USERAUTHENTICATIONRESPONSE -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -ProtocolVersionRequest = _reflection.GeneratedProtocolMessageType('ProtocolVersionRequest', (_message.Message,), dict( - DESCRIPTOR = _PROTOCOLVERSIONREQUEST, - __module__ = 'anki_vector.messaging.shared_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ProtocolVersionRequest) - )) -_sym_db.RegisterMessage(ProtocolVersionRequest) - -ProtocolVersionResponse = _reflection.GeneratedProtocolMessageType('ProtocolVersionResponse', (_message.Message,), dict( - DESCRIPTOR = _PROTOCOLVERSIONRESPONSE, - __module__ = 'anki_vector.messaging.shared_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ProtocolVersionResponse) - )) -_sym_db.RegisterMessage(ProtocolVersionResponse) - -ConnectionResponse = _reflection.GeneratedProtocolMessageType('ConnectionResponse', (_message.Message,), dict( - DESCRIPTOR = _CONNECTIONRESPONSE, - __module__ = 'anki_vector.messaging.shared_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.ConnectionResponse) - )) -_sym_db.RegisterMessage(ConnectionResponse) - -Event = _reflection.GeneratedProtocolMessageType('Event', (_message.Message,), dict( - DESCRIPTOR = _EVENT, - __module__ = 'anki_vector.messaging.shared_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.Event) - )) -_sym_db.RegisterMessage(Event) - -FilterList = _reflection.GeneratedProtocolMessageType('FilterList', (_message.Message,), dict( - DESCRIPTOR = _FILTERLIST, - __module__ = 'anki_vector.messaging.shared_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.FilterList) - )) -_sym_db.RegisterMessage(FilterList) - -EventRequest = _reflection.GeneratedProtocolMessageType('EventRequest', (_message.Message,), dict( - DESCRIPTOR = _EVENTREQUEST, - __module__ = 'anki_vector.messaging.shared_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EventRequest) - )) -_sym_db.RegisterMessage(EventRequest) - -EventResponse = _reflection.GeneratedProtocolMessageType('EventResponse', (_message.Message,), dict( - DESCRIPTOR = _EVENTRESPONSE, - __module__ = 'anki_vector.messaging.shared_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.EventResponse) - )) -_sym_db.RegisterMessage(EventResponse) - -UserAuthenticationRequest = _reflection.GeneratedProtocolMessageType('UserAuthenticationRequest', (_message.Message,), dict( - DESCRIPTOR = _USERAUTHENTICATIONREQUEST, - __module__ = 'anki_vector.messaging.shared_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.UserAuthenticationRequest) - )) -_sym_db.RegisterMessage(UserAuthenticationRequest) - -UserAuthenticationResponse = _reflection.GeneratedProtocolMessageType('UserAuthenticationResponse', (_message.Message,), dict( - DESCRIPTOR = _USERAUTHENTICATIONRESPONSE, - __module__ = 'anki_vector.messaging.shared_pb2' - # @@protoc_insertion_point(class_scope:Anki.Vector.external_interface.UserAuthenticationResponse) - )) -_sym_db.RegisterMessage(UserAuthenticationResponse) - - -_EVENTRESPONSE.has_options = True -_EVENTRESPONSE._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\200\246\035\001')) -# @@protoc_insertion_point(module_scope) diff --git a/anki_vector/messaging/shared_pb2_grpc.py b/anki_vector/messaging/shared_pb2_grpc.py deleted file mode 100644 index a894352..0000000 --- a/anki_vector/messaging/shared_pb2_grpc.py +++ /dev/null @@ -1,3 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - diff --git a/anki_vector/motors.py b/anki_vector/motors.py deleted file mode 100644 index 0816b6a..0000000 --- a/anki_vector/motors.py +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Control the motors of Vector. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['MotorComponent'] - -from . import connection, util -from .messaging import protocol - - -class MotorComponent(util.Component): - """Controls the low-level motor functions.""" - @connection.on_connection_thread() - async def set_wheel_motors(self, - left_wheel_speed: float, - right_wheel_speed: float, - left_wheel_accel: float = 0.0, - right_wheel_accel: float = 0.0): - """Tell Vector to move his wheels / treads at a given speed. - - The wheels will continue to move at that speed until commanded to drive - at a new speed. - - To unlock the wheel track, call `set_wheel_motors(0, 0)`. - - .. testcode:: - - import anki_vector - import time - - with anki_vector.Robot() as robot: - robot.motors.set_wheel_motors(25, 50) - time.sleep(3.0) - - :param left_wheel_speed: Speed of the left tread (in millimeters per second). - :param right_wheel_speed: Speed of the right tread (in millimeters per second). - :param left_wheel_accel: Acceleration of left tread (in millimeters per second squared) - ``None`` value defaults this to the same as l_wheel_speed. - :param right_wheel_accel: Acceleration of right tread (in millimeters per second squared) - ``None`` value defaults this to the same as r_wheel_speed. - """ - motors = protocol.DriveWheelsRequest(left_wheel_mmps=left_wheel_speed, - right_wheel_mmps=right_wheel_speed, - left_wheel_mmps2=left_wheel_accel, - right_wheel_mmps2=right_wheel_accel) - return await self.grpc_interface.DriveWheels(motors) - - @connection.on_connection_thread() - async def set_head_motor(self, - speed: float): - """Tell Vector's head motor to move with a certain speed. - - Positive speed for up, negative speed for down. Measured in radians per second. - - To unlock the head track, call `set_head_motor(0)`. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.motors.set_head_motor(-5.0) - - :param speed: Motor speed for Vector's head, measured in radians per second. - """ - set_head_request = protocol.MoveHeadRequest(speed_rad_per_sec=speed) - return await self.grpc_interface.MoveHead(set_head_request) - - @connection.on_connection_thread() - async def set_lift_motor(self, - speed: float): - """Tell Vector's lift motor to move with a certain speed. - - Positive speed for up, negative speed for down. Measured in radians per second. - - To unlock the lift track, call `set_lift_motor(0)`. - - .. testcode:: - - import anki_vector - import time - - with anki_vector.Robot() as robot: - robot.motors.set_lift_motor(-5.0) - time.sleep(3.0) - robot.motors.set_lift_motor(5.0) - time.sleep(3.0) - - :param speed: Motor speed for Vector's lift, measured in radians per second. - """ - set_lift_request = protocol.MoveLiftRequest(speed_rad_per_sec=speed) - return await self.grpc_interface.MoveLift(set_lift_request) diff --git a/anki_vector/nav_map.py b/anki_vector/nav_map.py deleted file mode 100755 index 3db4c34..0000000 --- a/anki_vector/nav_map.py +++ /dev/null @@ -1,405 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""A 2D navigation memory map of the world around Vector. - -Vector builds a memory map of the navigable world around him as he drives -around. This is mostly based on where objects are seen (the cubes, charger, and -any custom objects), and also includes where Vector detects cliffs/drops, and -probabilities of occupancy, but instead encodes what type of content is there. - -To use the map you must first call :meth:`anki_vector.nav_map.NavMapComponent.init_nav_map_feed` -with a positive frequency so that the data is streamed to the SDK. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['EvtNavMapUpdate', - 'NavMapComponent', 'NavMapGrid', 'NavMapGridNode', - 'NavNodeContentTypes'] - -import asyncio -from concurrent.futures import CancelledError -from enum import Enum -from logging import Logger -from typing import List - -from . import util -from .events import Events -from .messaging import protocol - - -class EvtNavMapUpdate(): # pylint: disable=too-few-public-methods - """Dispatched when a new nav map is received. - - :param nav_map: The current state of the robot's nav map. - """ - - def __init__(self, nav_map): - self.nav_map = nav_map - - -class NavNodeContentTypes(Enum): # pylint: disable=too-few-public-methods - """The content types for a :class:`NavMapGridNode`. - """ - - #: The contents of the node is unknown. - Unknown = protocol.NavNodeContentType.Value("NAV_NODE_UNKNOWN") - - #: The node is clear of obstacles, because Vector has seen objects on the - #: other side, but it might contain a cliff. The node will be marked as - #: either :attr:`Cliff` or :attr:`ClearOfCliff` once Vector has driven there. - ClearOfObstacle = protocol.NavNodeContentType.Value("NAV_NODE_CLEAR_OF_OBSTACLE") - - #: The node is clear of any cliffs (a sharp drop) or obstacles. - ClearOfCliff = protocol.NavNodeContentType.Value("NAV_NODE_CLEAR_OF_CLIFF") - - #: The node contains a :class:`~anki_vector.objects.LightCube`. - ObstacleCube = protocol.NavNodeContentType.Value("NAV_NODE_OBSTACLE_CUBE") - - #: The node contains a proximity detected obstacle which has not been explored. - ObstacleProximity = protocol.NavNodeContentType.Value("NAV_NODE_OBSTACLE_PROXIMITY") - - #: The node contains a proximity detected obstacle which has been explored. - ObstacleProximityExplored = protocol.NavNodeContentType.Value("NAV_NODE_OBSTACLE_PROXIMITY_EXPLORED") - - #: The node contains an unrecognized obstacle. - ObstacleUnrecognized = protocol.NavNodeContentType.Value("NAV_NODE_OBSTACLE_UNRECOGNIZED") - - #: The node contains a cliff (a sharp drop). - Cliff = protocol.NavNodeContentType.Value("NAV_NODE_CLIFF") - - #: The node contains a visible edge (based on the camera feed). - InterestingEdge = protocol.NavNodeContentType.Value("NAV_NODE_INTERESTING_EDGE") - - # This entry is undocumented and not currently used - NonInterestingEdge = protocol.NavNodeContentType.Value("NAV_NODE_NON_INTERESTING_EDGE") - - -class NavMapGridNode: - """A node in a :class:`NavMapGrid`. - - Leaf nodes contain content, all other nodes are split into 4 equally sized - children. - - Child node indices are stored in the following X,Y orientation: - - +---+----+---+ - | ^ | 2 | 0 | - +---+----+---+ - | Y | 3 | 1 | - +---+----+---+ - | | X->| | - +---+----+---+ - """ - - def __init__(self, depth: int, size: float, center: util.Vector3, parent: 'NavMapGridNode', logger: Logger): - #: The depth of this node (i.e. how far down the quad-tree it is). - self.depth = depth - - #: The size (width or length) of this square node. - self.size = size - - #: The center of this node. - self.center = center - - #: The parent of this node. Is ``None`` for the root node. - self.parent = parent - - #: ``None`` for leaf nodes, a list of 4 child nodes otherwise. - self.children: List[NavMapGridNode] = None - - #: The content type in this node. Only leaf nodes have content, - #: this is ``None`` for all other nodes. - self.content: protocol.NavNodeContentType = None - - self._next_child = 0 # Used when building to track which branch to follow - - self._logger = logger - - def __repr__(self): - return '<%s center: %s size: %s content: %s>' % ( - self.__class__.__name__, self.center, self.size, self.content) - - def contains_point(self, x: float, y: float) -> bool: - """Test if the node contains the given x,y coordinates. - - :param x: x coordinate for the point. - :param y: y coordinate for the point. - - Returns: - True if the node contains the point, False otherwise. - """ - half_size = self.size * 0.5 - dist_x = abs(self.center.x - x) - dist_y = abs(self.center.y - y) - return (dist_x <= half_size) and (dist_y <= half_size) - - def _get_node(self, x: float, y: float, assumed_in_bounds: bool) -> 'NavMapGridNode': - if not assumed_in_bounds and not self.contains_point(x, y): - # point is out of bounds - return None - - if self.children is None: - return self - - x_offset = 2 if x < self.center.x else 0 - y_offset = 1 if y < self.center.y else 0 - child_node = self.children[x_offset + y_offset] - # child node is by definition in bounds / on boundary - return child_node._get_node(x, y, True) # pylint: disable=protected-access - - def get_node(self, x: float, y: float) -> 'NavMapGridNode': - """Get the node at the given x,y coordinates. - - :param x: x coordinate for the point. - :param y: y coordinate for the point. - - Returns: - The smallest node that includes the point. - Will be ``None`` if the point is outside of the map. - """ - return self._get_node(x, y, assumed_in_bounds=False) - - def get_content(self, x: float, y: float) -> protocol.NavNodeContentType: - """Get the node's content at the given x,y coordinates. - - :param x: x coordinate for the point. - :param y: y coordinate for the point. - - Returns: - The content included at that point. Will be :attr:`NavNodeContentTypes.Unknown` - if the point is outside of the map. - """ - node = self.get_node(x, y) - if node: - return node.content - - return NavNodeContentTypes.Unknown - - def add_child(self, content: protocol.NavNodeContentType, depth: int) -> bool: - """Add a child node to the quad tree. - - The quad-tree is serialized to a flat list of nodes, we deserialize - back to a quad-tree structure here, with the depth of each node - indicating where it is placed. - - :param content: The content to store in the leaf node. - :param depth: The depth that this leaf node is located at. - - Returns: - True if parent should use the next child for future add_child - calls. - """ - if depth > self.depth: - self._logger.error("NavMapGridNode depth %s > %s", depth, self.depth) - if self._next_child > 3: - self._logger.error("NavMapGridNode _next_child %s (>3) at depth %s", self._next_child, self.depth) - - if self.depth == depth: - if self.content is not None: - self._logger.error("NavMapGridNode: Clobbering %s at depth %s with %s", - self.content, self.depth, content) - self.content = content - # This node won't be further subdivided, and is now full - return True - - if self.children is None: - # Create 4 child nodes for quad-tree structure - next_depth = self.depth - 1 - next_size = self.size * 0.5 - offset = next_size * 0.5 - center1 = util.Vector3(self.center.x + offset, self.center.y + offset, self.center.z) - center2 = util.Vector3(self.center.x + offset, self.center.y - offset, self.center.z) - center3 = util.Vector3(self.center.x - offset, self.center.y + offset, self.center.z) - center4 = util.Vector3(self.center.x - offset, self.center.y - offset, self.center.z) - self.children = [NavMapGridNode(next_depth, next_size, center1, self, self._logger), - NavMapGridNode(next_depth, next_size, center2, self, self._logger), - NavMapGridNode(next_depth, next_size, center3, self, self._logger), - NavMapGridNode(next_depth, next_size, center4, self, self._logger)] - if self.children[self._next_child].add_child(content, depth): - # Child node is now full, start using the next child - self._next_child += 1 - - if self._next_child > 3: - # All children are now full - parent should start using the next child - return True - - # Empty children remain - parent can keep using this child - return False - - -class NavMapGrid: - """A navigation memory map, stored as a quad-tree.""" - - def __init__(self, msg: protocol.NavMapFeedResponse, logger: Logger): - #: The origin ID for the map. Only maps and :class:`~anki_vector.util.Pose` - #: objects of the same origin ID are in the same coordinate frame and - #: can therefore be compared. - self.origin_id = msg.origin_id - root_center = util.Vector3(msg.map_info.root_center_x, msg.map_info.root_center_y, msg.map_info.root_center_z) - self._root_node = NavMapGridNode(msg.map_info.root_depth, msg.map_info.root_size_mm, root_center, None, logger) - for quad in msg.quad_infos: - self.add_quad(quad.content, quad.depth) - - self._logger = logger - - def __repr__(self): - return '<%s center: %s size: %s>' % ( - self.__class__.__name__, self.center, self.size) - - @property - def root_node(self) -> NavMapGridNode: - """The root node for the grid, contains all other nodes.""" - return self._root_node - - @property - def size(self) -> float: - """The size (width or length) of the square grid.""" - return self._root_node.size - - @property - def center(self) -> util.Vector3: - """The center of this map.""" - return self._root_node.center - - def contains_point(self, x: float, y: float) -> bool: - """Test if the map contains the given x,y coordinates. - - :param x: x coordinate for the point. - :param y: y coordinate for the point. - - Returns: - True if the map contains the point, False otherwise. - """ - return self._root_node.contains_point(x, y) - - def get_node(self, x: float, y: float) -> NavMapGridNode: - """Get the node at the given x,y coordinates. - - :param x: x coordinate for the point. - :param y: y coordinate for the point. - - Returns: - The smallest node that includes the point. - Will be ``None`` if the point is outside of the map. - """ - return self._root_node.get_node(x, y) - - def get_content(self, x: float, y: float) -> protocol.NavNodeContentType: - """Get the map's content at the given x,y coordinates. - - :param x: x coordinate for the point. - :param y: y coordinate for the point. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_nav_map_feed=True) as robot: - # Make sure Vector drives around so the nav map will update - robot.behavior.drive_off_charger() - robot.motors.set_wheel_motors(-100, 100) - latest_nav_map = robot.nav_map.latest_nav_map - content = latest_nav_map.get_content(0.0, 100.0) - print(f"Sampling point at 0.0, 100.0 and found content: {content}") - - Returns: - The content included at that point. Will be :attr:`NavNodeContentTypes.Unknown` - if the point is outside of the map. - """ - return self._root_node.get_content(x, y) - - def add_quad(self, content: protocol.NavNodeContentType, depth: int): - """Adds a new quad to the nav map. - - :param content: What content this node contains. - :param depth: How deep in the navMap this node is. - """ - self._root_node.add_child(content, depth) - - -class NavMapComponent(util.Component): - """Represents Vector's navigation memory map. - - The NavMapComponent object subscribes for nav memory map updates from the robot to store and dispatch. - - The :class:`anki_vector.robot.Robot` or :class:`anki_vector.robot.AsyncRobot` instance hosts this component. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_nav_map_feed=True) as robot: - # Make sure Vector drives around so the nav map will update - robot.behavior.drive_off_charger() - robot.motors.set_wheel_motors(-100, 100) - latest_nav_map = robot.nav_map.latest_nav_map - - :param robot: A reference to the owner Robot object. - """ - - def __init__(self, robot): - super().__init__(robot) - - self._latest_nav_map: NavMapGrid = None - self._nav_map_feed_task: asyncio.Task = None - - @property - @util.block_while_none() - def latest_nav_map(self) -> NavMapGrid: - """:class:`NavMapGrid`: The most recently processed image received from the robot. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_nav_map_feed=True) as robot: - # Make sure Vector drives around so the nav map will update - robot.behavior.drive_off_charger() - robot.motors.set_wheel_motors(-100, 100) - latest_nav_map = robot.nav_map.latest_nav_map - """ - if not self._nav_map_feed_task or self._nav_map_feed_task.done(): - raise Exception("Nav map not initialized") - return self._latest_nav_map - - def init_nav_map_feed(self, frequency: float = 0.5) -> None: - """Begin nav map feed task. - - :param frequency: How frequently to send nav map updates. - """ - if not self._nav_map_feed_task or self._nav_map_feed_task.done(): - self._nav_map_feed_task = self.conn.loop.create_task(self._request_and_handle_nav_maps(frequency)) - - def close_nav_map_feed(self) -> None: - """Cancel nav map feed task.""" - if self._nav_map_feed_task: - self._nav_map_feed_task.cancel() - future = self.conn.run_coroutine(self._nav_map_feed_task) - future.result() - self._nav_map_feed_task = None - - async def _request_and_handle_nav_maps(self, frequency: float) -> None: - """Queries and listens for nav map feed events from the robot. - Received events are parsed by a helper function. - - :param frequency: How frequently to send nav map updates. - """ - try: - req = protocol.NavMapFeedRequest(frequency=frequency) - async for evt in self.grpc_interface.NavMapFeed(req): - self._latest_nav_map = NavMapGrid(evt, self.logger) - await self._robot.events.dispatch_event(evt, Events.nav_map_update) - except CancelledError: - self.logger.debug('Nav Map feed task was cancelled. This is expected during disconnection.') diff --git a/anki_vector/objects.py b/anki_vector/objects.py deleted file mode 100644 index 4888df0..0000000 --- a/anki_vector/objects.py +++ /dev/null @@ -1,1658 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Object and Light Cube recognition. - -Vector can recognize and track a number of different types of objects. - -These objects may be visible (currently observed by the robot's camera) -and tappable (in the case of the Light Cube that ships with the robot). - -The Light Cube is known as a :class:`LightCube` by the SDK. The cube -has controllable lights, and sensors that can determine when it's being -moved or tapped. - -Objects can generate events which can be subscribed to from the anki_vector.events -class, such as object_appeared (of type EvtObjectAppeared), and -object_disappeared (of type EvtObjectDisappeared), which are broadcast -based on both robot originating events and local state. - -All observable objects have a marker of a known size attached to them, which allows Vector -to recognize the object and its position and rotation ("pose"). You can attach -markers to your own objects for Vector to recognize by printing them out from the -online documentation. They will be detected as :class:`CustomObject` instances. - -Vector connects to his Light Cubes with BLE. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['LIGHT_CUBE_1_TYPE', 'OBJECT_VISIBILITY_TIMEOUT', - 'EvtObjectAppeared', 'EvtObjectDisappeared', 'EvtObjectFinishedMove', 'EvtObjectObserved', - 'Charger', 'CustomObjectArchetype', 'CustomObject', 'CustomObjectMarkers', 'CustomObjectTypes', - 'FixedCustomObject', 'LightCube', 'ObservableObject'] - -# TODO Curious why events like the following aren't listed? At least some do seem to be supported in other parts of anki_vector. -# EvtObjectTapped, EvtObjectConnectChanged, EvtObjectConnected, EvtObjectLocated, EvtObjectMoving, EvtObjectMovingStarted - - -import collections -import math -import time - -from . import connection, lights, util -from .events import Events - -from .messaging import protocol - -#: Length of time in seconds to go without receiving an observed event before -#: assuming that Vector can no longer see an object. -OBJECT_VISIBILITY_TIMEOUT = 0.8 - - -class EvtObjectObserved(): # pylint: disable=too-few-public-methods - """Triggered whenever an object is visually identified by the robot. - - A stream of these events are produced while an object is visible to the robot. - Each event has an updated image_box field. - - See EvtObjectAppeared if you only want to know when an object first - becomes visible. - - :param obj: The object that was observed - :param image_rect: An :class:`anki_vector.util.ImageRect`: defining where the object is within Vector's camera view - :param pose: The :class:`anki_vector.util.Pose`: defining the position and rotation of the object - """ - - def __init__(self, obj, image_rect: util.ImageRect, pose: util.Pose): - self.obj = obj - self.image_rect = image_rect - self.pose = pose - - -class EvtObjectAppeared(): # pylint: disable=too-few-public-methods - """Triggered whenever an object is first visually identified by a robot. - - This differs from EvtObjectObserved in that it's only triggered when - an object initially becomes visible. If it disappears for more than - OBJECT_VISIBILITY_TIMEOUT seconds and then is seen again, a - EvtObjectDisappeared will be dispatched, followed by another - EvtObjectAppeared event. - - For continuous tracking information about a visible object, see - EvtObjectObserved. - - :param obj: The object that is starting to be observed - :param image_rect: An :class:`anki_vector.util.ImageRect`: defining where the object is within Vector's camera view - :param pose: The :class:`anki_vector.util.Pose`: defining the position and rotation of the object - """ - - def __init__(self, obj, image_rect: util.ImageRect, pose: util.Pose): - self.obj = obj - self.image_rect = image_rect - self.pose = pose - - -class EvtObjectDisappeared(): # pylint: disable=too-few-public-methods - """Triggered whenever an object that was previously being observed is no longer visible. - - :param obj: The object that is no longer being observed - """ - - def __init__(self, obj): - self.obj = obj - - -class EvtObjectFinishedMove(): # pylint: disable=too-few-public-methods - """Triggered when an active object stops moving. - - :param obj: The object that moved - :param move_duration: The duration of the move - """ - - def __init__(self, obj, move_duration: float): - self.obj = obj - self.move_duration = move_duration - - -class ObservableObject(util.Component): - """Represents any object Vector can see in the world.""" - - visibility_timeout = OBJECT_VISIBILITY_TIMEOUT - - def __init__(self, robot, **kw): - super().__init__(robot, **kw) - - self._pose: util.Pose = None - - #: The time the last event was received. - #: ``None`` if no events have yet been received. - self._last_event_time: float = None - - #: The time the element was last observed by the robot. - #: ``None`` if the element has not yet been observed. - self._last_observed_time: float = None - - #: The robot's timestamp of the last observed event. - #: ``None`` if the element has not yet been observed. - #: In milliseconds relative to robot epoch. - self._last_observed_robot_timestamp: int = None - - #: The ImageRect defining where the - #: object was last visible within Vector's camera view. - #: ``None`` if the element has not yet been observed. - self._last_observed_image_rect: util.ImageRect = None - - self._is_visible: bool = False - self._observed_timeout_handler: callable = None - - def __repr__(self): - extra = self._repr_values() - if extra: - extra = ' ' + extra - if self.pose: - extra += ' pose=%s' % self.pose - - return '<%s%s is_visible=%s>' % (self.__class__.__name__, - extra, self.is_visible) - #### Properties #### - - @property - def pose(self) -> util.Pose: - """The pose of this object in the world. - - Is ``None`` for elements that don't have pose information. - - .. testcode:: - - import anki_vector - import time - - # First, place a cube directly in front of Vector so he can observe it. - - with anki_vector.Robot() as robot: - connectionResult = robot.world.connect_cube() - connected_cube = robot.world.connected_light_cube - - for _ in range(16): - connected_cube = robot.world.connected_light_cube - if connected_cube: - print(connected_cube) - print("last observed timestamp: " + str(connected_cube.last_observed_time) + ", robot timestamp: " + str(connected_cube.last_observed_robot_timestamp)) - print(robot.world.connected_light_cube.pose) - time.sleep(0.5) - """ - return self._pose - - @property - def last_event_time(self) -> float: - """Time this object last received an event from Vector.""" - return self._last_event_time - - @property - def last_observed_time(self) -> float: - """Time this object was last seen.""" - return self._last_observed_time - - @property - def last_observed_robot_timestamp(self) -> int: - """Time this object was last seen according to Vector's time.""" - return self._last_observed_robot_timestamp - - @property - def time_since_last_seen(self) -> float: - """Time since this object was last seen. math.inf if never seen. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_face_detection=True) as robot: - for face in robot.world.visible_faces: - print(f"time_since_last_seen: {face.time_since_last_seen}") - """ - if self._last_observed_time is None: - return math.inf - return time.time() - self._last_observed_time - - @property - def last_observed_image_rect(self) -> util.ImageRect: - """The location in 2d camera space where this object was last seen.""" - return self._last_observed_image_rect - - @property - def is_visible(self) -> bool: - """True if the element has been observed recently, False otherwise. - - "recently" is defined as :attr:`visibility_timeout` seconds. - """ - return self._is_visible - - #### Private Methods #### - - def _repr_values(self): # pylint: disable=no-self-use - return '' - - def _reset_observed_timeout_handler(self): - if self._observed_timeout_handler is not None: - self._observed_timeout_handler.cancel() - self._observed_timeout_handler = self.conn.loop.call_later(self.visibility_timeout, self._observed_timeout) - - def _observed_timeout(self): - # Triggered when the element is no longer considered "visible". - # i.e. visibility_timeout seconds after the last observed event. - self._is_visible = False - self.conn.run_soon(self._robot.events.dispatch_event(EvtObjectDisappeared(self), Events.object_disappeared)) - - def _on_observed(self, pose: util.Pose, image_rect: util.ImageRect, robot_timestamp: int): - # Called from subclasses on their corresponding observed messages. - newly_visible = self._is_visible is False - self._is_visible = True - - now = time.time() - self._last_observed_time = now - self._last_observed_robot_timestamp = robot_timestamp - self._last_event_time = now - self._last_observed_image_rect = image_rect - self._pose = pose - self._reset_observed_timeout_handler() - self.conn.run_soon(self._robot.events.dispatch_event(EvtObjectObserved(self, image_rect, pose), Events.object_observed)) - - if newly_visible: - self.conn.run_soon(self._robot.events.dispatch_event(EvtObjectAppeared(self, image_rect, pose), Events.object_appeared)) - - -#: LIGHT_CUBE_1_TYPE's markers look like 2 concentric circles with lines and gaps. -LIGHT_CUBE_1_TYPE = protocol.ObjectType.Value("BLOCK_LIGHTCUBE1") - - -class LightCube(ObservableObject): - """Represents Vector's Cube. - - The LightCube object has four LEDs that Vector can actively manipulate and communicate with. - - As Vector drives around, he uses the position of objects that he recognizes, including his cube, - to localize himself, taking note of the :class:`anki_vector.util.Pose` of the objects. - - You can subscribe to cube events including :class:`anki_vector.events.Events.object_tapped`, - :class:`anki_vector.events.Events.object_appeared`, and :class:`anki_vector.events.Events.object_disappeared`. - - Vector supports 1 LightCube. - - See parent class :class:`ObservableObject` for additional properties - and methods. - """ - - #: Length of time in seconds to go without receiving an observed event before - #: assuming that Vector can no longer see an object. Can be overridden in subclasses. - visibility_timeout = OBJECT_VISIBILITY_TIMEOUT - - def __init__(self, robot, **kw): - super().__init__(robot, **kw) - - #: The time the object was last tapped. - #: ``None`` if the cube wasn't tapped yet. - self._last_tapped_time: float = None - - #: The robot's timestamp of the last tapped event. - #: ``None`` if the cube wasn't tapped yet. - #: In milliseconds relative to robot epoch. - self._last_tapped_robot_timestamp: int = None - - #: The time the object was last moved. - #: ``None`` if the cube wasn't moved yet. - self._last_moved_time: float = None - - #: The robot's timestamp of the last move event. - #: ``None`` if the cube wasn't moved yet. - #: In milliseconds relative to robot epoch. - self._last_moved_robot_timestamp: int = None - - #: The time the object started moving when last moved. - self._last_moved_start_time: float = None - - #: The robot's timestamp of when the object started moving when last moved. - #: ``None`` if the cube wasn't moved yet. - #: In milliseconds relative to robot epoch. - self._last_moved_start_robot_timestamp: int = None - - #: The time the last up axis event was received. - #: ``None`` if no events have yet been received. - self._last_up_axis_changed_time: float = None - - #: The robot's timestamp of the last up axis event. - #: ``None`` if the there has not been an up axis event. - #: In milliseconds relative to robot epoch. - self._last_up_axis_changed_robot_timestamp: int = None - - # The object's up_axis value from the last time it changed. - self._up_axis: protocol.UpAxis = None - - #: True if the cube's accelerometer indicates that the cube is moving. - self._is_moving: bool = False - - #: True if the cube is currently connected to the robot via radio. - self._is_connected: bool = False - - #: angular distance from the current reported up axis - #: ``None`` if the object has not yet been observed. - self._top_face_orientation_rad: float = None - - self._object_id: str = None - - #: unique identification of the physical cube - self._factory_id: str = None - - #: Subscribe to relevant events - self.robot.events.subscribe( - self._on_object_connection_state_changed, - Events.object_connection_state) - - self.robot.events.subscribe( - self._on_object_moved, - Events.object_moved) - - self.robot.events.subscribe( - self._on_object_stopped_moving, - Events.object_stopped_moving) - - self.robot.events.subscribe( - self._on_object_up_axis_changed, - Events.object_up_axis_changed) - - self.robot.events.subscribe( - self._on_object_tapped, - Events.object_tapped) - - self.robot.events.subscribe( - self._on_object_observed, - Events.robot_observed_object) - - self.robot.events.subscribe( - self._on_object_connection_lost, - Events.cube_connection_lost) - - #### Public Methods #### - - def teardown(self): - """All faces will be torn down by the world when no longer needed.""" - self.robot.events.unsubscribe( - self._on_object_connection_state_changed, - Events.object_connection_state) - - self.robot.events.unsubscribe( - self._on_object_moved, - Events.object_moved) - - self.robot.events.unsubscribe( - self._on_object_stopped_moving, - Events.object_stopped_moving) - - self.robot.events.unsubscribe( - self._on_object_up_axis_changed, - Events.object_up_axis_changed) - - self.robot.events.unsubscribe( - self._on_object_tapped, - Events.object_tapped) - - self.robot.events.unsubscribe( - self._on_object_observed, - Events.robot_observed_object) - - self.robot.events.unsubscribe( - self._on_object_connection_lost, - Events.cube_connection_lost) - - @connection.on_connection_thread() - async def set_light_corners(self, - light1: lights.Light, - light2: lights.Light, - light3: lights.Light, - light4: lights.Light, - color_profile: lights.ColorProfile = lights.WHITE_BALANCED_CUBE_PROFILE): - """Set the light for each corner. - - .. testcode:: - - import anki_vector - - import time - - with anki_vector.Robot() as robot: - robot.world.connect_cube() - - if robot.world.connected_light_cube: - cube = robot.world.connected_light_cube - - cube.set_light_corners(anki_vector.lights.blue_light, - anki_vector.lights.green_light, - anki_vector.lights.red_light, - anki_vector.lights.white_light) - time.sleep(3) - - cube.set_lights_off() - - :param light1: The settings for the first light. - :param light2: The settings for the second light. - :param light3: The settings for the third light. - :param light4: The settings for the fourth light. - :param color_profile: The profile to be used for the cube lights - """ - params = lights.package_request_params((light1, light2, light3, light4), color_profile) - req = protocol.SetCubeLightsRequest( - object_id=self._object_id, - on_color=params['on_color'], - off_color=params['off_color'], - on_period_ms=params['on_period_ms'], - off_period_ms=params['off_period_ms'], - transition_on_period_ms=params['transition_on_period_ms'], - transition_off_period_ms=params['transition_off_period_ms'], - offset=[0, 0, 0, 0], - relative_to_x=0.0, - relative_to_y=0.0, - rotate=False, - make_relative=protocol.SetCubeLightsRequest.OFF) # pylint: disable=no-member - return await self.grpc_interface.SetCubeLights(req) - - def set_lights(self, light: lights.Light, color_profile: lights.ColorProfile = lights.WHITE_BALANCED_CUBE_PROFILE): - """Set all lights on the cube - - .. testcode:: - - import anki_vector - - import time - - with anki_vector.Robot() as robot: - robot.world.connect_cube() - - if robot.world.connected_light_cube: - cube = robot.world.connected_light_cube - - # Set cube lights to yellow - cube.set_lights(anki_vector.lights.yellow_light) - time.sleep(3) - - cube.set_lights_off() - - :param light: The settings for the lights - :param color_profile: The profile to be used for the cube lights - """ - return self.set_light_corners(light, light, light, light, color_profile) - - def set_lights_off(self, color_profile: lights.ColorProfile = lights.WHITE_BALANCED_CUBE_PROFILE): - """Set all lights off on the cube - - .. testcode:: - - import anki_vector - - import time - - with anki_vector.Robot() as robot: - robot.world.connect_cube() - - if robot.world.connected_light_cube: - cube = robot.world.connected_light_cube - - # Set cube lights to yellow - cube.set_lights(anki_vector.lights.yellow_light) - time.sleep(3) - - # Turn off cube lights - cube.set_lights_off() - - :param color_profile: The profile to be used for the cube lights - """ - - return self.set_light_corners(lights.off_light, lights.off_light, lights.off_light, lights.off_light, color_profile) - - #### Private Methods #### - - def _repr_values(self): - return 'object_id=%s' % self.object_id - - #### Properties #### - - @property - def last_tapped_time(self) -> float: - """The time the object was last tapped in SDK time. - - .. testcode:: - - import time - import anki_vector - - with anki_vector.Robot() as robot: - print("disconnecting from any connected cube...") - robot.world.disconnect_cube() - - time.sleep(2) - - print("connect to a cube...") - connectionResult = robot.world.connect_cube() - - print("For the next 8 seconds, please tap and move the cube. Cube properties will be logged to console.") - for _ in range(16): - connected_cube = robot.world.connected_light_cube - if connected_cube: - print(f'last_tapped_time: {connected_cube.last_tapped_time}') - time.sleep(0.5) - """ - return self._last_tapped_time - - @property - def last_tapped_robot_timestamp(self) -> float: - """The time the object was last tapped in robot time. - - .. testcode:: - - import time - import anki_vector - - with anki_vector.Robot() as robot: - print("disconnecting from any connected cube...") - robot.world.disconnect_cube() - - time.sleep(2) - - print("connect to a cube...") - connectionResult = robot.world.connect_cube() - - print("For the next 8 seconds, please tap and move the cube. Cube properties will be logged to console.") - for _ in range(16): - connected_cube = robot.world.connected_light_cube - if connected_cube: - print(f'last_tapped_robot_timestamp: {connected_cube.last_tapped_robot_timestamp}') - time.sleep(0.5) - """ - return self._last_tapped_robot_timestamp - - @property - def last_moved_time(self) -> float: - """The time the object was last moved in SDK time. - - .. testcode:: - - import time - import anki_vector - - with anki_vector.Robot() as robot: - print("disconnecting from any connected cube...") - robot.world.disconnect_cube() - - time.sleep(2) - - print("connect to a cube...") - connectionResult = robot.world.connect_cube() - - print("For the next 8 seconds, please tap and move the cube. Cube properties will be logged to console.") - for _ in range(16): - connected_cube = robot.world.connected_light_cube - if connected_cube: - print(f'last_moved_time: {connected_cube.last_moved_time}') - time.sleep(0.5) - """ - return self._last_moved_time - - @property - def last_moved_robot_timestamp(self) -> float: - """The time the object was last moved in robot time. - - .. testcode:: - - import time - import anki_vector - - with anki_vector.Robot() as robot: - print("disconnecting from any connected cube...") - robot.world.disconnect_cube() - - time.sleep(2) - - print("connect to a cube...") - connectionResult = robot.world.connect_cube() - - print("For the next 8 seconds, please tap and move the cube. Cube properties will be logged to console.") - for _ in range(16): - connected_cube = robot.world.connected_light_cube - if connected_cube: - print(f'last_moved_robot_timestamp: {connected_cube.last_moved_robot_timestamp}') - time.sleep(0.5) - """ - return self._last_moved_robot_timestamp - - @property - def last_moved_start_time(self) -> float: - """The time the object most recently started moving in SDK time. - - .. testcode:: - - import time - import anki_vector - - with anki_vector.Robot() as robot: - print("disconnecting from any connected cube...") - robot.world.disconnect_cube() - - time.sleep(2) - - print("connect to a cube...") - connectionResult = robot.world.connect_cube() - - print("For the next 8 seconds, please tap and move the cube. Cube properties will be logged to console.") - for _ in range(16): - connected_cube = robot.world.connected_light_cube - if connected_cube: - print(f'last_moved_start_time: {connected_cube.last_moved_start_time}') - time.sleep(0.5) - """ - return self._last_moved_start_time - - @property - def last_moved_start_robot_timestamp(self) -> float: - """The time the object more recently started moving in robot time. - - .. testcode:: - - import time - import anki_vector - - with anki_vector.Robot() as robot: - print("disconnecting from any connected cube...") - robot.world.disconnect_cube() - - time.sleep(2) - - print("connect to a cube...") - connectionResult = robot.world.connect_cube() - - print("For the next 8 seconds, please tap and move the cube. Cube properties will be logged to console.") - for _ in range(16): - connected_cube = robot.world.connected_light_cube - if connected_cube: - print(f'last_moved_start_robot_timestamp: {connected_cube.last_moved_start_robot_timestamp}') - time.sleep(0.5) - """ - return self._last_moved_start_robot_timestamp - - @property - def last_up_axis_changed_time(self) -> float: - """The time the object's orientation last changed in SDK time. - - .. testcode:: - - import time - import anki_vector - - with anki_vector.Robot() as robot: - print("disconnecting from any connected cube...") - robot.world.disconnect_cube() - - time.sleep(2) - - print("connect to a cube...") - connectionResult = robot.world.connect_cube() - - print("For the next 8 seconds, please tap and move the cube. Cube properties will be logged to console.") - for _ in range(16): - connected_cube = robot.world.connected_light_cube - if connected_cube: - print(f'last_up_axis_changed_time: {connected_cube.last_up_axis_changed_time}') - time.sleep(0.5) - """ - return self._last_up_axis_changed_time - - @property - def last_up_axis_changed_robot_timestamp(self) -> float: - """Time the object's orientation last changed in robot time. - - .. testcode:: - - import time - import anki_vector - - with anki_vector.Robot() as robot: - print("disconnecting from any connected cube...") - robot.world.disconnect_cube() - - time.sleep(2) - - print("connect to a cube...") - connectionResult = robot.world.connect_cube() - - print("For the next 8 seconds, please tap and move the cube. Cube properties will be logged to console.") - for _ in range(16): - connected_cube = robot.world.connected_light_cube - if connected_cube: - print(f'last_up_axis_changed_robot_timestamp: {connected_cube.last_up_axis_changed_robot_timestamp}') - time.sleep(0.5) - """ - return self._last_up_axis_changed_robot_timestamp - - @property - def up_axis(self) -> protocol.UpAxis: - """The object's up_axis value from the last time it changed. - - .. testcode:: - - import time - import anki_vector - - with anki_vector.Robot() as robot: - print("disconnecting from any connected cube...") - robot.world.disconnect_cube() - - time.sleep(2) - - print("connect to a cube...") - connectionResult = robot.world.connect_cube() - - print("For the next 8 seconds, please tap and move the cube. Cube properties will be logged to console.") - for _ in range(16): - connected_cube = robot.world.connected_light_cube - if connected_cube: - print(f'up_axis: {connected_cube.up_axis}') - time.sleep(0.5) - """ - return self._up_axis - - @property - def is_moving(self) -> bool: - """True if the cube's accelerometer indicates that the cube is moving. - - .. testcode:: - - import time - import anki_vector - - with anki_vector.Robot() as robot: - print("disconnecting from any connected cube...") - robot.world.disconnect_cube() - - time.sleep(2) - - print("connect to a cube...") - connectionResult = robot.world.connect_cube() - - print("For the next 8 seconds, please tap and move the cube. Cube properties will be logged to console.") - for _ in range(16): - connected_cube = robot.world.connected_light_cube - if connected_cube: - print(f'is_moving: {connected_cube.is_moving}') - time.sleep(0.5) - """ - return self._is_moving - - @property - def is_connected(self) -> bool: - """True if the cube is currently connected to the robot. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.world.connect_cube() - if robot.world.connected_light_cube: - cube = robot.world.connected_light_cube - print(f"{cube.is_connected}") - """ - return self._is_connected - - @property - def top_face_orientation_rad(self) -> float: - """Angular distance from the current reported up axis. - - .. testcode:: - - import time - import anki_vector - - with anki_vector.Robot() as robot: - print("disconnecting from any connected cube...") - robot.world.disconnect_cube() - - time.sleep(2) - - print("connect to a cube...") - connectionResult = robot.world.connect_cube() - - print("For the next 8 seconds, please tap and move the cube. Cube properties will be logged to console.") - for _ in range(16): - connected_cube = robot.world.connected_light_cube - if connected_cube: - print(f'top_face_orientation_rad: {connected_cube.top_face_orientation_rad}') - time.sleep(0.5) - """ - return self._top_face_orientation_rad - - @property - def factory_id(self) -> str: - """The unique hardware id of the physical cube. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.world.connect_cube() - if robot.world.connected_light_cube: - cube = robot.world.connected_light_cube - print(f"{cube.factory_id}") - """ - return self._factory_id - - @factory_id.setter - def factory_id(self, value: str): - self._factory_id = value - - @property - def descriptive_name(self) -> str: - """A descriptive name for this ObservableObject instance. - - Note: Sub-classes should override this to add any other relevant info - for that object type. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.world.connect_cube() - if robot.world.connected_light_cube: - cube = robot.world.connected_light_cube - print(f"{cube.descriptive_name}") - """ - return "{0} id={1} factory_id={2} is_connected={3}".format(self.__class__.__name__, self._object_id, self._factory_id, self._is_connected) - - @property - def object_id(self) -> int: - """The internal ID assigned to the object. - - This value can only be assigned once as it is static on the robot. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.world.connect_cube() - if robot.world.connected_light_cube: - cube = robot.world.connected_light_cube - print(f"{cube.object_id}") - """ - return self._object_id - - @object_id.setter - def object_id(self, value: str): - if self._object_id is not None: - # We cannot currently rely on robot ensuring that object ID remains static - # E.g. in the case of a cube disconnecting and reconnecting it's removed - # and then re-added to blockworld which results in a new ID. - self.logger.warning("Changing object_id for %s from %s to %s", self.__class__, self._object_id, value) - else: - self.logger.debug("Setting object_id for %s to %s", self.__class__, value) - self._object_id = value - - #### Private Event Handlers #### - - def _on_object_connection_state_changed(self, _, msg): - if msg.object_type == LIGHT_CUBE_1_TYPE: - self._object_id = msg.object_id - - if self._factory_id != msg.factory_id: - self.logger.debug('Factory id changed from {0} to {1}'.format(self._factory_id, msg.factory_id)) - self._factory_id = msg.factory_id - - if self._is_connected != msg.connected: - if msg.connected: - self.logger.debug('Object connected: %s', self) - else: - self.logger.debug('Object disconnected: %s', self) - self._is_connected = msg.connected - - def _on_object_moved(self, _, msg): - if msg.object_id == self._object_id: - now = time.time() - started_moving = not self._is_moving - self._is_moving = True - self._last_event_time = now - self._last_moved_time = now - self._last_moved_robot_timestamp = msg.timestamp - - if started_moving: - self._last_moved_start_time = now - self._last_moved_start_robot_timestamp = msg.timestamp - else: - self.logger.warning('An object not currently tracked by the world moved with id {0}'.format(msg.object_id)) - - async def _on_object_stopped_moving(self, _, msg): - if msg.object_id == self._object_id: - now = time.time() - self._last_event_time = now - move_duration = 0.0 - - # _is_moving might already be false. - # This happens for very short movements that are immediately - # considered stopped (no acceleration info is present) - if self._is_moving: - self._is_moving = False - move_duration = now - self._last_moved_start_time - await self._robot.events.dispatch_event(EvtObjectFinishedMove(self, move_duration), Events.object_finished_move) - else: - self.logger.warning('An object not currently tracked by the world stopped moving with id {0}'.format(msg.object_id)) - - def _on_object_up_axis_changed(self, _, msg): - if msg.object_id == self._object_id: - - now = time.time() - self._up_axis = msg.up_axis - self._last_event_time = now - self._last_up_axis_changed_time = now - self._last_up_axis_changed_robot_timestamp = msg.timestamp - else: - self.logger.warning('Up Axis changed on an object not currently tracked by the world with id {0}'.format(msg.object_id)) - - def _on_object_tapped(self, _, msg): - if msg.object_id == self._object_id: - - now = time.time() - self._last_event_time = now - self._last_tapped_time = now - self._last_tapped_robot_timestamp = msg.timestamp - else: - self.logger.warning('Tapped an object not currently tracked by the world with id {0}'.format(msg.object_id)) - - def _on_object_observed(self, _, msg): - if msg.object_id == self._object_id: - - pose = util.Pose(x=msg.pose.x, y=msg.pose.y, z=msg.pose.z, - q0=msg.pose.q0, q1=msg.pose.q1, - q2=msg.pose.q2, q3=msg.pose.q3, - origin_id=msg.pose.origin_id) - image_rect = util.ImageRect(msg.img_rect.x_top_left, - msg.img_rect.y_top_left, - msg.img_rect.width, - msg.img_rect.height) - self._top_face_orientation_rad = msg.top_face_orientation_rad - - self._on_observed(pose, image_rect, msg.timestamp) - - def _on_object_connection_lost(self, _, msg): - if msg.object_id == self._object_id: - self._is_connected = False - - -class Charger(ObservableObject): - """Vector's charger object, which the robot can observe and drive toward. - We get an :class:`anki_vector.objects.EvtObjectObserved` message when the - robot sees the charger. - - See parent class :class:`ObservableObject` for additional properties - and methods. - - .. testcode:: - - import anki_vector - - # Position Vector so he can see his charger - with anki_vector.Robot() as robot: - if robot.world.charger: - print('Robot is aware of charger: {0}'.format(robot.world.charger)) - """ - - def __init__(self, robot, object_id: int, **kw): - super().__init__(robot, **kw) - - self._object_id = object_id - - self.robot.events.subscribe( - self._on_object_observed, - Events.robot_observed_object) - - #### Public Methods #### - - def teardown(self): - """All objects will be torn down by the world when the world closes.""" - - self.robot.events.unsubscribe( - self._on_object_observed, - Events.robot_observed_object) - - #### Properties #### - @property - def object_id(self) -> int: - """The internal ID assigned to the object. - - .. testcode:: - - import anki_vector - - # Position Vector so he can see his charger - with anki_vector.Robot() as robot: - if robot.world.charger: - charger_object_id = robot.world.charger.object_id - print(f"charger_object_id: {charger_object_id}") - - This value can only be assigned once as it is static on the robot. - """ - return self._object_id - - @object_id.setter - def object_id(self, value: str): - if self._object_id is not None: - # We cannot currently rely on robot ensuring that object ID remains static - # E.g. in the case of a cube disconnecting and reconnecting it's removed - # and then re-added to blockworld which results in a new ID. - self.logger.warning("Changing object_id for %s from %s to %s", self.__class__, self._object_id, value) - else: - self.logger.debug("Setting object_id for %s to %s", self.__class__, value) - self._object_id = value - - #### Private Methods #### - - def _on_object_observed(self, _, msg): - if msg.object_id == self._object_id: - - pose = util.Pose(x=msg.pose.x, y=msg.pose.y, z=msg.pose.z, - q0=msg.pose.q0, q1=msg.pose.q1, - q2=msg.pose.q2, q3=msg.pose.q3, - origin_id=msg.pose.origin_id) - image_rect = util.ImageRect(msg.img_rect.x_top_left, - msg.img_rect.y_top_left, - msg.img_rect.width, - msg.img_rect.height) - - self._on_observed(pose, image_rect, msg.timestamp) - - -class CustomObjectArchetype(): - """An object archetype defined by the SDK. It is bound to a specific objectType e.g ``CustomType00``. - - This defined object is given a size in the x,y and z axis. The dimensions - of the markers on the object are also defined. - - When the robot observes custom objects, they will be linked to these archetypes. - These can be created using the methods - :meth:`~anki_vector.world.World.define_custom_box`, - :meth:`~anki_vector.world.World.define_custom_cube`, or - :meth:`~anki_vector.world.World.define_custom_wall`. - """ - - def __init__(self, - custom_type: protocol.CustomType, - x_size_mm: float, - y_size_mm: float, - z_size_mm: float, - marker_width_mm: float, - marker_height_mm: float, - is_unique: bool): - - self._custom_type = custom_type - self._x_size_mm = x_size_mm - self._y_size_mm = y_size_mm - self._z_size_mm = z_size_mm - self._marker_width_mm = marker_width_mm - self._marker_height_mm = marker_height_mm - self._is_unique = is_unique - - #### Properties #### - - @property - def custom_type(self) -> protocol.CustomType: - """id of this archetype on the robot - - .. testcode:: - - import anki_vector - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - for obj in robot.world.custom_object_archetypes: - print('custom object archetype defined with type: {0}'.format(obj.custom_type)) - """ - return self._custom_type - - @property - def x_size_mm(self) -> float: - """Size of this object in its X axis, in millimeters. - - .. testcode:: - - import anki_vector - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - for obj in robot.world.custom_object_archetypes: - print('custom object archetype defined with dimensions: {0}mm x {1}mm x {2}mm'.format(obj.x_size_mm, obj.y_size_mm, obj.z_size_mm)) - """ - return self._x_size_mm - - @property - def y_size_mm(self) -> float: - """Size of this object in its Y axis, in millimeters. - - .. testcode:: - - import anki_vector - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - for obj in robot.world.custom_object_archetypes: - print('custom object archetype defined with dimensions: {0}mm x {1}mm x {2}mm'.format(obj.x_size_mm, obj.y_size_mm, obj.z_size_mm)) - """ - return self._y_size_mm - - @property - def z_size_mm(self) -> float: - """Size of this object in its Z axis, in millimeters. - - .. testcode:: - - import anki_vector - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - for obj in robot.world.custom_object_archetypes: - print('custom object archetype defined with dimensions: {0}mm x {1}mm x {2}mm'.format(obj.x_size_mm, obj.y_size_mm, obj.z_size_mm)) - """ - return self._z_size_mm - - @property - def marker_width_mm(self) -> float: - """Width in millimeters of the marker on this object. - - .. testcode:: - - import anki_vector - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - for obj in robot.world.custom_object_archetypes: - print('custom object archetype defined with marker size: {0}mm x {1}mm'.format(obj.marker_width_mm, obj.marker_height_mm)) - """ - return self._marker_width_mm - - @property - def marker_height_mm(self) -> float: - """Height in millimeters of the marker on this object. - - .. testcode:: - - import anki_vector - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - for obj in robot.world.custom_object_archetypes: - print('custom object archetype defined with marker size: {0}mm x {1}mm'.format(obj.marker_width_mm, obj.marker_height_mm)) - """ - return self._marker_height_mm - - @property - def is_unique(self) -> bool: - """True if there should only be one of this object type in the world.""" - return self._is_unique - - #### Private Methods #### - - def __repr__(self): - return ('custom_type={self.custom_type} ' - 'x_size_mm={self.x_size_mm:.1f} ' - 'y_size_mm={self.y_size_mm:.1f} ' - 'z_size_mm={self.z_size_mm:.1f} ' - 'marker_width_mm={self.marker_width_mm:.1f} ' - 'marker_height_mm={self.marker_height_mm:.1f} ' - 'is_unique={self.is_unique}'.format(self=self)) - - -class CustomObject(ObservableObject): - """An object defined by the SDK observed by the robot. The object will - reference a :class:`CustomObjectArchetype`, with additional instance data. - - These objects are created automatically by the engine when Vector observes - an object with custom markers. For Vector to see one of these you must first - define an archetype with custom markers, via one of the following methods: - :meth:`~anki_vector.world.World.define_custom_box`. - :meth:`~anki_vector.world.World.define_custom_cube`, or - :meth:`~anki_vector.world.World.define_custom_wall` - """ - - def __init__(self, - robot, - archetype: CustomObjectArchetype, - object_id: int, **kw): - super().__init__(robot, **kw) - - self._object_id = object_id - self._archetype = archetype - - self.robot.events.subscribe( - self._on_object_observed, - Events.robot_observed_object) - - #### Public Methods #### - - def teardown(self): - """All objects will be torn down by the world when no longer needed.""" - - self.robot.events.unsubscribe( - self._on_object_observed, - Events.robot_observed_object) - - #### Properties #### - - @property - def object_id(self) -> int: - """The internal ID assigned to the object. - - This value can only be assigned once as it is static on the robot. - - .. testcode:: - - import anki_vector - from anki_vector.objects import CustomObjectMarkers, CustomObjectTypes - - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - robot.world.define_custom_cube(custom_object_type=CustomObjectTypes.CustomType00, - marker=CustomObjectMarkers.Circles2, - size_mm=20.0, - marker_width_mm=50.0, marker_height_mm=50.0) - - # have the robot observe a custom object in the real world with the Circles2 marker - - for obj in robot.world.visible_custom_objects: - print('custom object seen with id: {0}'.format(obj.object_id)) - """ - return self._object_id - - @object_id.setter - def object_id(self, value: str): - if self._object_id is not None: - # We cannot currently rely on robot ensuring that object ID remains static - # E.g. in the case of a cube disconnecting and reconnecting it's removed - # and then re-added to robot's internal world model which results in a new ID. - self.logger.warning("Changing object_id for %s from %s to %s", self.__class__, self._object_id, value) - else: - self.logger.debug("Setting object_id for %s to %s", self.__class__, value) - self._object_id = value - - @property - def archetype(self) -> CustomObjectArchetype: - """Archetype defining this custom object's properties. - - .. testcode:: - - import anki_vector - from anki_vector.objects import CustomObjectMarkers, CustomObjectTypes - - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - robot.world.define_custom_cube(custom_object_type=CustomObjectTypes.CustomType00, - marker=CustomObjectMarkers.Circles2, - size_mm=20.0, - marker_width_mm=50.0, marker_height_mm=50.0) - - # have the robot observe a custom object in the real world with the Circles2 marker - - for obj in robot.world.visible_custom_objects: - print('custom object seen with archetype: {0}'.format(obj.archetype)) - """ - return self._archetype - - @property - def descriptive_name(self) -> str: - """A descriptive name for this CustomObject instance. - - .. testcode:: - - import anki_vector - from anki_vector.objects import CustomObjectMarkers, CustomObjectTypes - - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - robot.world.define_custom_cube(custom_object_type=CustomObjectTypes.CustomType00, - marker=CustomObjectMarkers.Circles2, - size_mm=20.0, - marker_width_mm=50.0, marker_height_mm=50.0) - - # have the robot observe a custom object in the real world with the Circles2 marker - - for obj in robot.world.visible_custom_objects: - print('custom object seen with name: {0}'.format(obj.descriptive_name)) - """ - # Specialization of ObservableObject's method to include the object type. - return "%s id=%d" % (self.archetype.object_type.name, self.object_id) - - #### Private Methods #### - - def _repr_values(self): - return ('object_type={archetype.custom_type} ' - 'x_size_mm={archetype.x_size_mm:.1f} ' - 'y_size_mm={archetype.y_size_mm:.1f} ' - 'z_size_mm={archetype.z_size_mm:.1f} ' - 'is_unique={archetype.is_unique}'.format(archetype=self._archetype)) - - def _on_object_observed(self, _, msg): - if msg.object_id == self._object_id: - - pose = util.Pose(x=msg.pose.x, y=msg.pose.y, z=msg.pose.z, - q0=msg.pose.q0, q1=msg.pose.q1, - q2=msg.pose.q2, q3=msg.pose.q3, - origin_id=msg.pose.origin_id) - image_rect = util.ImageRect(msg.img_rect.x_top_left, - msg.img_rect.y_top_left, - msg.img_rect.width, - msg.img_rect.height) - - self._on_observed(pose, image_rect, msg.timestamp) - - -class _CustomObjectType(collections.namedtuple('_CustomObjectType', 'name id')): - # Tuple mapping between Proto CustomObjectType name and ID - # All instances will be members of CustomObjectType - - # Keep _CustomObjectType as lightweight as a normal namedtuple - __slots__ = () - - def __str__(self): - return 'CustomObjectTypes.%s' % self.name - - -class CustomObjectTypes(): # pylint: disable=too-few-public-methods - """Defines all available custom object types. - - For use with world.define_custom methods such as - :meth:`anki_vector.world.World.define_custom_box`, - :meth:`anki_vector.world.World.define_custom_cube`, and - :meth:`anki_vector.world.World.define_custom_wall` - - .. testcode:: - - import anki_vector - from anki_vector.objects import CustomObjectMarkers, CustomObjectTypes - - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - robot.world.define_custom_cube(custom_object_type=CustomObjectTypes.CustomType00, - marker=CustomObjectMarkers.Circles2, - size_mm=20.0, - marker_width_mm=50.0, marker_height_mm=50.0) - """ - - #: CustomType00 - the first custom object type - CustomType00 = _CustomObjectType("CustomType00", protocol.CustomType.Value("CUSTOM_TYPE_00")) - - #: - CustomType01 = _CustomObjectType("CustomType01", protocol.CustomType.Value("CUSTOM_TYPE_01")) - - #: - CustomType02 = _CustomObjectType("CustomType02", protocol.CustomType.Value("CUSTOM_TYPE_02")) - - #: - CustomType03 = _CustomObjectType("CustomType03", protocol.CustomType.Value("CUSTOM_TYPE_03")) - - #: - CustomType04 = _CustomObjectType("CustomType04", protocol.CustomType.Value("CUSTOM_TYPE_04")) - - #: - CustomType05 = _CustomObjectType("CustomType05", protocol.CustomType.Value("CUSTOM_TYPE_05")) - - #: - CustomType06 = _CustomObjectType("CustomType06", protocol.CustomType.Value("CUSTOM_TYPE_06")) - - #: - CustomType07 = _CustomObjectType("CustomType07", protocol.CustomType.Value("CUSTOM_TYPE_07")) - - #: - CustomType08 = _CustomObjectType("CustomType08", protocol.CustomType.Value("CUSTOM_TYPE_08")) - - #: - CustomType09 = _CustomObjectType("CustomType09", protocol.CustomType.Value("CUSTOM_TYPE_09")) - - #: - CustomType10 = _CustomObjectType("CustomType10", protocol.CustomType.Value("CUSTOM_TYPE_10")) - - #: - CustomType11 = _CustomObjectType("CustomType11", protocol.CustomType.Value("CUSTOM_TYPE_11")) - - #: - CustomType12 = _CustomObjectType("CustomType12", protocol.CustomType.Value("CUSTOM_TYPE_12")) - - #: - CustomType13 = _CustomObjectType("CustomType13", protocol.CustomType.Value("CUSTOM_TYPE_13")) - - #: - CustomType14 = _CustomObjectType("CustomType14", protocol.CustomType.Value("CUSTOM_TYPE_14")) - - #: - CustomType15 = _CustomObjectType("CustomType15", protocol.CustomType.Value("CUSTOM_TYPE_15")) - - #: - CustomType16 = _CustomObjectType("CustomType16", protocol.CustomType.Value("CUSTOM_TYPE_16")) - - #: - CustomType17 = _CustomObjectType("CustomType17", protocol.CustomType.Value("CUSTOM_TYPE_17")) - - #: - CustomType18 = _CustomObjectType("CustomType18", protocol.CustomType.Value("CUSTOM_TYPE_18")) - - #: CustomType19 - the last custom object type - CustomType19 = _CustomObjectType("CustomType19", protocol.CustomType.Value("CUSTOM_TYPE_19")) - - -class _CustomObjectMarker(collections.namedtuple('_CustomObjectMarker', 'name id')): - # Tuple mapping between Proto CustomObjectMarker name and ID - # All instances will be members of CustomObjectMarker - - # Keep _CustomObjectMarker as lightweight as a normal namedtuple - __slots__ = () - - def __str__(self): - return 'CustomObjectMarkers.%s' % self.name - - -class CustomObjectMarkers(): # pylint: disable=too-few-public-methods - """Defines all available custom object markers. - - For use with world.define_custom methods such as - :meth:`anki_vector.world.World.define_custom_box`, - :meth:`anki_vector.world.World.define_custom_cube`, and - :meth:`anki_vector.world.World.define_custom_wall` - - .. testcode:: - - import anki_vector - from anki_vector.objects import CustomObjectMarkers, CustomObjectTypes - - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - robot.world.define_custom_cube(custom_object_type=CustomObjectTypes.CustomType00, - marker=CustomObjectMarkers.Circles2, - size_mm=20.0, - marker_width_mm=50.0, marker_height_mm=50.0) - """ - - #: .. image:: ../images/custom_markers/SDK_2Circles.png - Circles2 = _CustomObjectMarker("Circles2", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_CIRCLES_2")) - - #: .. image:: ../images/custom_markers/SDK_3Circles.png - Circles3 = _CustomObjectMarker("Circles3", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_CIRCLES_3")) - - #: .. image:: ../images/custom_markers/SDK_4Circles.png - Circles4 = _CustomObjectMarker("Circles4", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_CIRCLES_4")) - - #: .. image:: ../images/custom_markers/SDK_5Circles.png - Circles5 = _CustomObjectMarker("Circles5", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_CIRCLES_5")) - - #: .. image:: ../images/custom_markers/SDK_2Diamonds.png - Diamonds2 = _CustomObjectMarker("Diamonds2", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_DIAMONDS_2")) - - #: .. image:: ../images/custom_markers/SDK_3Diamonds.png - Diamonds3 = _CustomObjectMarker("Diamonds3", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_DIAMONDS_3")) - - #: .. image:: ../images/custom_markers/SDK_4Diamonds.png - Diamonds4 = _CustomObjectMarker("Diamonds4", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_DIAMONDS_4")) - - #: .. image:: ../images/custom_markers/SDK_5Diamonds.png - Diamonds5 = _CustomObjectMarker("Diamonds5", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_DIAMONDS_5")) - - #: .. image:: ../images/custom_markers/SDK_2Hexagons.png - Hexagons2 = _CustomObjectMarker("Hexagons2", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_HEXAGONS_2")) - - #: .. image:: ../images/custom_markers/SDK_3Hexagons.png - Hexagons3 = _CustomObjectMarker("Hexagons3", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_HEXAGONS_3")) - - #: .. image:: ../images/custom_markers/SDK_4Hexagons.png - Hexagons4 = _CustomObjectMarker("Hexagons4", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_HEXAGONS_4")) - - #: .. image:: ../images/custom_markers/SDK_5Hexagons.png - Hexagons5 = _CustomObjectMarker("Hexagons5", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_HEXAGONS_5")) - - #: .. image:: ../images/custom_markers/SDK_2Triangles.png - Triangles2 = _CustomObjectMarker("Triangles2", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_TRIANGLES_2")) - - #: .. image:: ../images/custom_markers/SDK_3Triangles.png - Triangles3 = _CustomObjectMarker("Triangles3", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_TRIANGLES_3")) - - #: .. image:: ../images/custom_markers/SDK_4Triangles.png - Triangles4 = _CustomObjectMarker("Triangles4", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_TRIANGLES_4")) - - #: .. image:: ../images/custom_markers/SDK_5Triangles.png - Triangles5 = _CustomObjectMarker("Triangles5", protocol.CustomObjectMarker.Value("CUSTOM_MARKER_TRIANGLES_5")) - - -class FixedCustomObject(util.Component): - """A fixed object defined by the SDK. It is given a pose and x,y,z sizes. - - This object cannot be observed by the robot so its pose never changes. - The position is static in Vector's world view; once instantiated, these - objects never move. This could be used to make Vector aware of objects and - know to plot a path around them even when they don't have any markers. - - To create these use :meth:`~anki_vector.world.World.create_custom_fixed_object` - - .. testcode:: - - import anki_vector - from anki_vector.util import degrees, Pose - import time - - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - robot.world.create_custom_fixed_object(Pose(100, 0, 0, angle_z=degrees(0)), - 10, 100, 100, relative_to_robot=True) - """ - - def __init__(self, - robot, - pose: util.Pose, - x_size_mm: float, - y_size_mm: float, - z_size_mm: float, - object_id: int, **kw): - super().__init__(robot, **kw) - self._pose = pose - self._x_size_mm = x_size_mm - self._y_size_mm = y_size_mm - self._z_size_mm = z_size_mm - self._object_id = object_id - - def __repr__(self): - return ('<%s pose=%s object_id=%d x_size_mm=%.1f y_size_mm=%.1f z_size_mm=%.1f=>' % - (self.__class__.__name__, self.pose, self.object_id, - self.x_size_mm, self.y_size_mm, self.z_size_mm)) - - #### Public Methods #### - - def teardown(self): - pass - - #### Properties #### - @property - def object_id(self) -> int: - """The internal ID assigned to the object. - - This value can only be assigned once as it is static in the engine. - - .. testcode:: - - import anki_vector - from anki_vector.util import degrees, Pose - import time - - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - obj = robot.world.create_custom_fixed_object(Pose(100, 0, 0, angle_z=degrees(0)), - 10, 100, 100, relative_to_robot=True) - print('fixed custom object id: {0}'.format(obj.object_id)) - """ - return self._object_id - - @object_id.setter - def object_id(self, value: int): - if self._object_id is not None: - raise ValueError("Cannot change object ID once set (from %s to %s)" % (self._object_id, value)) - self.logger.debug("Updated object_id for %s from %s to %s", self.__class__, self._object_id, value) - self._object_id = value - - @property - def pose(self) -> util.Pose: - """The pose of the object in the world. - - .. testcode:: - - import anki_vector - from anki_vector.util import degrees, Pose - import time - - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - obj = robot.world.create_custom_fixed_object(Pose(100, 0, 0, angle_z=degrees(0)), - 10, 100, 100, relative_to_robot=True) - print('fixed custom object id: {0}'.format(obj.pose)) - """ - return self._pose - - @property - def x_size_mm(self) -> float: - """The length of the object in its X axis, in millimeters. - - .. testcode:: - - import anki_vector - from anki_vector.util import degrees, Pose - import time - - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - obj = robot.world.create_custom_fixed_object(Pose(100, 0, 0, angle_z=degrees(0)), - 10, 100, 100, relative_to_robot=True) - print('fixed custom object size: {0}mm x {1}mm x {2}mm'.format(obj.x_size_mm, obj.y_size_mm, obj.z_size_mm)) - """ - return self._x_size_mm - - @property - def y_size_mm(self) -> float: - """The length of the object in its Y axis, in millimeters. - - .. testcode:: - - import anki_vector - from anki_vector.util import degrees, Pose - import time - - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - obj = robot.world.create_custom_fixed_object(Pose(100, 0, 0, angle_z=degrees(0)), - 10, 100, 100, relative_to_robot=True) - print('fixed custom object size: {0}mm x {1}mm x {2}mm'.format(obj.x_size_mm, obj.y_size_mm, obj.z_size_mm)) - """ - return self._y_size_mm - - @property - def z_size_mm(self) -> float: - """The length of the object in its Z axis, in millimeters. - - .. testcode:: - - import anki_vector - from anki_vector.util import degrees, Pose - import time - - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - obj = robot.world.create_custom_fixed_object(Pose(100, 0, 0, angle_z=degrees(0)), - 10, 100, 100, relative_to_robot=True) - print('fixed custom object size: {0}mm x {1}mm x {2}mm'.format(obj.x_size_mm, obj.y_size_mm, obj.z_size_mm)) - """ - return self._z_size_mm diff --git a/anki_vector/opengl/__init__.py b/anki_vector/opengl/__init__.py deleted file mode 100644 index 0db3dc8..0000000 --- a/anki_vector/opengl/__init__.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""This module provides 3D classes for running the OpenGL Viewer. - -It should be launched in a separate process to allow Vector to run freely while -the viewer is rendering. - -It uses PyOpenGL, a Python OpenGL 3D graphics library which is available on most -platforms. It also depends on the Pillow library for image processing. - -Warning: - This package requires Python to have the PyOpenGL package installed, along - with an implementation of GLUT (OpenGL Utility Toolkit). - - To install the Python packages on Mac and Linux do ``python3 -m pip install --user "anki_vector[3dviewer]"`` - - To install the Python packages on Windows do ``py -3 -m pip install --user "anki_vector[3dviewer]"`` - - On Windows and Linux you must also install freeglut (macOS / OSX has one - preinstalled). - - On Linux: ``sudo apt-get install freeglut3`` - - On Windows: Go to http://freeglut.sourceforge.net/ to get a ``freeglut.dll`` - file. It's included in any of the `Windows binaries` downloads. Place the DLL - next to your Python script, or install it somewhere in your PATH to allow any - script to use it." -""" - -import multiprocessing as mp - -from . import opengl_viewer - - -def main(close_event: mp.Event, - input_intent_queue: mp.Queue, - nav_map_queue: mp.Queue, - world_frame_queue: mp.Queue, - extra_render_function_queue: mp.Queue, - user_data_queue: mp.Queue): - """Run the 3D Viewer window. This is intended to run on a background process. - - .. code-block:: python - - import multiprocessing as mp - - from anki_vector import opengl - - ctx = mp.get_context('spawn') - close_event = ctx.Event() - input_intent_queue = ctx.Queue(maxsize=10) - nav_map_queue = ctx.Queue(maxsize=10) - world_frame_queue = ctx.Queue(maxsize=10) - extra_render_function_queue = ctx.Queue(maxsize=1) - user_data_queue = ctx.Queue() - process = ctx.Process(target=opengl.main, - args=(close_event, - input_intent_queue, - nav_map_queue, - world_frame_queue, - extra_render_function_queue, - user_data_queue), - daemon=True) - process.start() - - :param close_event: Used to notify each process when done rendering. - :type close_event: multiprocessing.Event - :param input_intent_queue: Sends key commands from the 3D viewer process to the main process. - :type input_intent_queue: multiprocessing.Queue - :param nav_map_queue: Updates the 3D viewer process with the latest navigation map. - :type nav_map_queue: multiprocessing.Queue - :param world_frame_queue: Provides the 3D viewer with details about the world. - :type world_frame_queue: multiprocessing.Queue - :param extra_render_function_queue: Functions to be executed in the 3D viewer process. - :type extra_render_function_queue: multiprocessing.Queue - :param user_data_queue: A queue that may be used outside the SDK to pass information to the viewer process. - May be used by ``extra_render_function_queue`` functions. - """ - viewer = opengl_viewer.OpenGLViewer(close_event, - input_intent_queue, - nav_map_queue, - world_frame_queue, - extra_render_function_queue, - user_data_queue) - viewer.run() - - -__all__ = ['main'] diff --git a/anki_vector/opengl/assets/LICENSE.txt b/anki_vector/opengl/assets/LICENSE.txt deleted file mode 100644 index 26ecd40..0000000 --- a/anki_vector/opengl/assets/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -Anki, Inc. Image and 3D Model License Agreement Version 1.1 (last updated November 15, 2018) - -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. - -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. - -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. - -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. - -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. - -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. - -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. - -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. - -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. - -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. diff --git a/anki_vector/opengl/assets/cube.jpg b/anki_vector/opengl/assets/cube.jpg deleted file mode 100644 index 244708b..0000000 Binary files a/anki_vector/opengl/assets/cube.jpg and /dev/null differ diff --git a/anki_vector/opengl/assets/cube.mtl b/anki_vector/opengl/assets/cube.mtl deleted file mode 100644 index 67c14e0..0000000 --- a/anki_vector/opengl/assets/cube.mtl +++ /dev/null @@ -1,9 +0,0 @@ -newmtl cube_mtl -map_Kd cube.jpg -illum 4 -Kd 0.15 0.15 0.15 -Ka 0.15 0.15 0.15 -Tf 1.00 1.00 1.00 -Ni 1.00 -Ks 0.99 0.99 0.99 -Ns 10 diff --git a/anki_vector/opengl/assets/cube.obj b/anki_vector/opengl/assets/cube.obj deleted file mode 100644 index 0ff91a9..0000000 --- a/anki_vector/opengl/assets/cube.obj +++ /dev/null @@ -1,1000 +0,0 @@ -# This file uses centimeters as units for non-parametric coordinates. - -mtllib cube.mtl -g default -v 2.056166 -2.056165 -2.083990 -v 2.056166 2.056165 -2.083990 -v 2.056166 -2.056165 2.083990 -v 2.056166 2.056165 2.083990 -v -2.056166 -2.056165 2.083990 -v -2.056166 2.056165 2.083990 -v -2.056166 -2.056165 -2.083990 -v -2.056166 2.056165 -2.083990 -v -1.152302 2.056165 2.083990 -v -1.152302 -2.056165 2.083990 -v -1.152302 -2.056165 -2.083990 -v -1.152302 2.056165 -2.083990 -v 1.152302 2.056165 2.083990 -v 1.152302 -2.056165 2.083990 -v 1.152302 -2.056165 -2.083990 -v 1.152302 2.056165 -2.083990 -v -2.056166 1.161861 2.083990 -v -2.056166 1.161861 -2.083990 -v -1.152302 1.161861 -2.083990 -v 1.152302 1.161861 -2.083990 -v 2.056166 1.161861 -2.083990 -v 2.056166 1.161861 2.083990 -v 1.152302 1.161861 2.083990 -v -1.152302 1.161861 2.083990 -v -2.056166 -1.161861 2.083990 -v -2.056166 -1.161861 -2.083990 -v -1.152302 -1.161861 -2.083990 -v 1.152302 -1.161861 -2.083990 -v 2.056166 -1.161861 -2.083990 -v 2.056166 -1.161861 2.083990 -v 1.152302 -1.161861 2.083990 -v -1.152302 -1.161861 2.083990 -v -1.152302 2.056165 0.834948 -v 1.152302 2.056165 0.834948 -v 2.056166 2.056165 0.834948 -v 2.056166 1.161861 0.834948 -v 2.056166 -1.161861 0.834948 -v 2.056166 -2.056165 0.834948 -v 1.152302 -2.056165 0.834948 -v -1.152302 -2.056165 0.834948 -v -2.056166 -2.056165 0.834948 -v -2.056166 -1.161861 0.834948 -v -2.056166 1.161861 0.834948 -v -2.056166 2.056165 0.834948 -v -1.152302 2.056165 -0.834948 -v 1.152302 2.056165 -0.834948 -v 2.056166 2.056165 -0.834948 -v 2.056166 1.161861 -0.834948 -v 2.056166 -1.161861 -0.834948 -v 2.056166 -2.056165 -0.834948 -v 1.152302 -2.056165 -0.834948 -v -1.152302 -2.056165 -0.834948 -v -2.056166 -2.056165 -0.834948 -v -2.056166 -1.161861 -0.834948 -v -2.056166 1.161861 -0.834948 -v -2.056166 2.056165 -0.834948 -v -1.152302 2.056165 1.188201 -v 1.152302 2.056165 1.188201 -v 2.056166 2.056165 1.188201 -v 2.056166 1.161861 1.188201 -v 2.056166 -1.161861 1.188201 -v 2.056166 -2.056165 1.188201 -v 1.152302 -2.056165 1.188201 -v -1.152302 -2.056165 1.188201 -v -2.056166 -2.056165 1.188201 -v -2.056166 -1.161861 1.188201 -v -2.056166 1.161861 1.188201 -v -2.056166 2.056165 1.188201 -v -1.152302 2.056165 -1.188200 -v 1.152302 2.056165 -1.188200 -v 2.056166 2.056165 -1.188200 -v 2.056166 1.161861 -1.188200 -v 2.056166 -1.161861 -1.188200 -v 2.056166 -2.056165 -1.188200 -v 1.152302 -2.056165 -1.188200 -v -1.152302 -2.056165 -1.188200 -v -2.056166 -2.056165 -1.188200 -v -2.056166 -1.161861 -1.188200 -v -2.056166 1.161861 -1.188200 -v -2.056166 2.056165 -1.188200 -v -1.152302 -1.148280 -1.184925 -v 1.152302 -1.148280 -1.184925 -v 1.152302 -1.752164 -1.188200 -v -1.152302 -1.752164 -1.188200 -v -1.152302 -1.161861 -1.779988 -v 1.152302 -1.161861 -1.779988 -v 1.152302 1.185458 -1.192178 -v 1.152302 1.752164 -1.188200 -v -1.152302 1.185458 -1.192178 -v -1.152302 1.752164 -1.188200 -v -1.152302 1.161861 -1.779988 -v 1.152302 1.161861 -1.779988 -v -1.752164 -1.161861 -1.188200 -v -1.752164 1.161861 -1.188200 -v -1.169887 1.161861 -1.191440 -v -1.169887 -1.161861 -1.191440 -v -1.152302 -1.161861 -1.779988 -v -1.152302 1.161861 -1.779988 -v 1.152302 -1.161861 -1.779988 -v 1.135147 -1.161861 -1.187053 -v 1.152302 1.161861 -1.779988 -v 1.135147 1.161861 -1.187053 -v 1.752164 -1.161861 -1.188200 -v 1.752164 1.161861 -1.188200 -v 1.152302 1.752164 -0.834948 -v 1.098395 1.098396 -0.834948 -v 1.152302 1.752164 0.834948 -v 1.098395 1.098396 0.834948 -v 1.752164 1.161861 -0.834948 -v 1.752164 1.161861 0.834948 -v 1.752164 -1.161861 -0.834948 -v 1.098395 -1.098396 -0.834948 -v 1.752164 -1.161861 0.834948 -v 1.098395 -1.098396 0.834948 -v 1.152302 -1.752164 -0.834948 -v 1.152302 -1.752164 0.834948 -v -1.152302 -1.752164 -0.834948 -v -1.098396 -1.098396 -0.834948 -v -1.152302 -1.752164 0.834948 -v -1.098396 -1.098396 0.834948 -v -1.752165 -1.161861 0.834948 -v -1.752165 -1.161861 -0.834948 -v -1.752165 1.161861 0.834948 -v -1.098396 1.098396 0.834948 -v -1.098396 1.098396 -0.834948 -v -1.752165 1.161861 -0.834948 -v -1.152302 1.752164 0.834948 -v -1.152302 1.752164 -0.834948 -vt 0.130571 0.888886 -vt 0.149113 0.900420 -vt 0.109401 0.884117 -vt 0.141131 0.914957 -vt 0.066228 0.901712 -vt 0.141581 0.920096 -vt 0.057036 0.852973 -vt 0.150772 0.940296 -vt 0.084612 0.946709 -vt 0.159964 0.932921 -vt 0.109231 0.879903 -vt 0.124162 0.935804 -vt 0.046027 0.907270 -vt 0.055219 0.918279 -vt 1.023864 0.075692 -vt 1.023864 0.122645 -vt 0.785215 0.121233 -vt 0.785215 0.100216 -vt 0.129360 0.907270 -vt 0.690722 0.580315 -vt 0.159964 0.945498 -vt 0.872807 0.784904 -vt 0.169068 0.934435 -vt 0.128683 0.902984 -vt 0.026068 0.884117 -vt 0.079521 0.930930 -vt 0.502314 0.784904 -vt 0.084612 0.863376 -vt 0.862723 0.637649 -vt 0.116710 0.884456 -vt 1.023864 0.119798 -vt 0.807557 0.514524 -vt 0.807557 0.571858 -vt 0.805389 0.637649 -vt 0.687561 0.784904 -vt 0.076631 0.932921 -vt 1.023864 0.132289 -vt 0.785215 0.194345 -vt 0.064998 0.859204 -vt 0.135773 0.956863 -vt 0.750224 0.514524 -vt 0.750224 0.571858 -vt 0.748056 0.637649 -vt 0.131177 0.907270 -vt 0.748056 0.694982 -vt 0.159535 0.947197 -vt 0.275829 0.264245 -vt 0.785215 0.193792 -vt 0.872807 0.908402 -vt 0.811058 0.908402 -vt 0.749310 0.908402 -vt 0.687561 0.908402 -vt 0.625812 0.908402 -vt 0.564063 0.908402 -vt 0.502314 0.908402 -vt 0.440566 0.908402 -vt 0.378817 0.908402 -vt 0.692890 0.399856 -vt 0.750224 0.399856 -vt 0.807557 0.399856 -vt 0.864891 0.399856 -vt 0.934556 0.908402 -vt 0.872807 0.846653 -vt 0.811058 0.846653 -vt 0.749310 0.846653 -vt 0.687561 0.846653 -vt 0.625812 0.846653 -vt 0.564063 0.846653 -vt 0.502314 0.846653 -vt 0.440566 0.846653 -vt 0.378817 0.846653 -vt 0.692890 0.457190 -vt 0.750224 0.457190 -vt 0.807557 0.457190 -vt 0.864891 0.457190 -vt 0.934556 0.846653 -vt 0.872807 0.939277 -vt 0.128683 0.861317 -vt 0.141131 0.873290 -vt 1.023864 0.180216 -vt 0.159535 0.905530 -vt 0.109401 0.842450 -vt 1.023864 0.180218 -vt 0.138552 0.876612 -vt 0.055219 0.876612 -vt 0.066228 0.943378 -vt 0.785215 0.180219 -vt 0.058247 0.961762 -vt 0.141581 0.961762 -vt 0.124162 0.894137 -vt 0.872807 0.815779 -vt 0.811058 0.815779 -vt 0.749310 0.815779 -vt 0.687561 0.815779 -vt 0.625812 0.815779 -vt 0.564063 0.815779 -vt 0.502314 0.815779 -vt 0.440566 0.815779 -vt 0.378817 0.815779 -vt 0.692890 0.485857 -vt 0.750224 0.485857 -vt 0.807557 0.485857 -vt 0.864891 0.485857 -vt 0.934556 0.815779 -vt 0.502314 0.784904 -vt 0.502314 0.815779 -vt 0.440566 0.815779 -vt 0.440566 0.784904 -vt 0.690722 0.580315 -vt 0.750224 0.571858 -vt 0.748056 0.637649 -vt 0.690722 0.637649 -vt 0.811058 0.815779 -vt 0.811058 0.784904 -vt 0.872807 0.784904 -vt 0.872807 0.815779 -vt 0.805389 0.637649 -vt 0.807557 0.571858 -vt 0.862723 0.580315 -vt 0.862723 0.637649 -vt 0.750224 0.485857 -vt 0.807557 0.485857 -vt 0.807557 0.514524 -vt 0.750224 0.514524 -vt 0.748056 0.694982 -vt 0.805389 0.694982 -vt 0.625812 0.815779 -vt 0.625812 0.784904 -vt 0.687561 0.784904 -vt 0.687561 0.815779 -vt 0.749310 0.846653 -vt 0.811058 0.846653 -vt 0.811058 0.908402 -vt 0.749310 0.908402 -vt 0.687561 0.908402 -vt 0.687561 0.846653 -vt 0.564063 0.846653 -vt 0.625812 0.846653 -vt 0.625812 0.908402 -vt 0.564063 0.908402 -vt 0.502314 0.846653 -vt 0.502314 0.908402 -vt 0.378817 0.846653 -vt 0.440566 0.846653 -vt 0.440566 0.908402 -vt 0.378817 0.908402 -vt 0.692890 0.399856 -vt 0.750224 0.399856 -vt 0.750224 0.457190 -vt 0.692890 0.457190 -vt 0.807557 0.399856 -vt 0.864891 0.399856 -vt 0.864891 0.457190 -vt 0.807557 0.457190 -vt 0.934556 0.908402 -vt 0.872807 0.908402 -vt 0.872807 0.846653 -vt 0.934556 0.846653 -vt 0.026068 0.842450 -vt 0.502314 0.939277 -vt 0.269071 0.452125 -vt 0.076201 0.905530 -vt 0.564063 0.939277 -vt 0.564063 0.939277 -vt 0.785215 0.180216 -vt 0.050546 0.257397 -vt 0.625812 0.939277 -vt 0.079521 0.847597 -vt 0.076201 0.947197 -vt 0.162855 0.847597 -vt 0.785256 0.123955 -vt 0.785215 0.132289 -vt 0.785175 0.182936 -vt 0.162855 0.930930 -vt 1.023864 0.192231 -vt 1.023864 0.121233 -vt 1.023864 0.100216 -vt 0.275829 0.487548 -vt 0.499132 0.264245 -vt 0.499132 0.487548 -vt 0.052259 0.452125 -vt 0.052259 0.484354 -vt 0.269071 0.484354 -vt 0.269071 0.299771 -vt 0.052259 0.299771 -vt 0.049198 0.711204 -vt 0.279927 0.711204 -vt 0.279927 0.676906 -vt 0.049198 0.676906 -vt 0.785215 0.180218 -vt 0.785215 0.192231 -vt 0.138552 0.918279 -vt 0.052440 0.873530 -vt 0.149561 0.943378 -vt 1.023864 0.180219 -vt 0.135773 0.873530 -vt 0.785215 0.119798 -vt 0.785215 0.082647 -vt 0.058247 0.920096 -vt 1.023864 0.082647 -vt 1.023864 0.193792 -vt 1.023864 0.180218 -vt 0.785215 0.180218 -vt 0.785215 0.075692 -vt 0.785215 0.122645 -vt 0.148331 0.859204 -vt 0.040829 0.935804 -vt 0.085734 0.934435 -vt 1.023864 0.194345 -vt 0.057798 0.873290 -vt 1.023864 0.123955 -vt 0.085734 0.851102 -vt 1.023864 0.182936 -vt 0.378817 0.939277 -vt 0.692890 0.371190 -vt 0.750224 0.371190 -vt 0.440566 0.939277 -vt 0.149561 0.901712 -vt 0.052440 0.956863 -vt 0.864891 0.371190 -vt 0.934556 0.939277 -vt 0.040829 0.894137 -vt 0.807557 0.371190 -vt 0.064998 0.942538 -vt 0.148331 0.942538 -vt 0.045350 0.861317 -vt 0.749310 0.939277 -vt 0.687561 0.939277 -vt 0.057798 0.914957 -vt 0.811058 0.939277 -vt 0.169068 0.851102 -vt 0.045350 0.902984 -vt 0.033377 0.926123 -vt 0.149113 0.942087 -vt 0.065780 0.942087 -vt 0.116710 0.926123 -vt 0.065780 0.900420 -vt 0.805389 0.694982 -vt 0.076631 0.849588 -vt 0.033377 0.884456 -vt 0.159964 0.849588 -vt 0.811058 0.784904 -vt 0.047844 0.948936 -vt 0.130571 0.930552 -vt 0.047238 0.930552 -vt 0.047238 0.888886 -vt 0.690722 0.637649 -vt 0.131177 0.948936 -vt 0.167945 0.946709 -vt 0.625812 0.784904 -vt 0.167945 0.863376 -vt 0.047844 0.907270 -vt 0.046027 0.948936 -vt 0.066228 0.889438 -vt 0.149561 0.889438 -vt 0.149561 0.931104 -vt 0.140369 0.852973 -vt 0.129360 0.948936 -vt 0.066228 0.931104 -vt 0.057036 0.936306 -vt 0.440566 0.784904 -vt 0.140369 0.936306 -vt 0.150772 0.898630 -vt 0.109231 0.921569 -vt 0.025898 0.921569 -vt 0.067439 0.898630 -vt 0.159964 0.862165 -vt 0.076631 0.862165 -vt 0.067439 0.940296 -vt 0.076631 0.945498 -vt 0.025898 0.879903 -vt 0.862723 0.580315 -vt 0.748056 0.580315 -vt 0.274602 0.485008 -vt 0.274602 0.711170 -vt 0.748056 0.637649 -vt 0.805389 0.637649 -vt 0.500763 0.711170 -vt 0.500763 0.485008 -vt 0.805389 0.580315 -vt 0.279927 0.514773 -vt 0.049198 0.514773 -vt 0.279927 0.480475 -vt 0.049198 0.480475 -vt 0.277612 0.267438 -vt 0.277612 0.234246 -vt 0.500900 0.234246 -vt 0.500900 0.267438 -vt 0.277612 0.077342 -vt 0.500900 0.077342 -vt 0.277612 0.044150 -vt 0.500900 0.044150 -vt 0.269071 0.267542 -vt 0.052259 0.267542 -vt 0.050546 0.224188 -vt 0.273946 0.224188 -vt 0.273946 0.257397 -vt 0.050546 0.067206 -vt 0.273946 0.067206 -vt 0.050546 0.033997 -vt 0.273946 0.033997 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 0.005424 -0.999985 -vn 0.000000 0.005424 -0.999985 -vn 0.000000 0.005424 -0.999985 -vn 0.000000 0.005424 -0.999985 -vn 0.000000 -0.999740 0.022817 -vn 0.000000 -0.999740 0.022817 -vn 0.000000 -0.999740 0.022817 -vn 0.000000 -0.999740 0.022817 -vn 0.000000 0.007019 -0.999975 -vn 0.000000 0.007019 -0.999975 -vn 0.000000 0.007019 -0.999975 -vn 0.000000 0.007019 -0.999975 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.999195 -0.040112 -vn 0.000000 0.999195 -0.040112 -vn 0.000000 0.999195 -0.040112 -vn 0.000000 0.999195 -0.040112 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn -0.005563 0.000000 -0.999985 -vn -0.005563 0.000000 -0.999985 -vn -0.005563 0.000000 -0.999985 -vn -0.005563 0.000000 -0.999985 -vn -0.999554 0.000000 -0.029865 -vn -0.999554 0.000000 -0.029865 -vn -0.999554 0.000000 -0.029865 -vn -0.999554 0.000000 -0.029865 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.999582 0.000000 0.028920 -vn 0.999582 0.000000 0.028920 -vn 0.999582 0.000000 0.028920 -vn 0.999582 0.000000 0.028920 -vn -0.001861 0.000000 -0.999998 -vn -0.001861 0.000000 -0.999998 -vn -0.001861 0.000000 -0.999998 -vn -0.001861 0.000000 -0.999998 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.996618 -0.082176 0.000000 -vn 0.996618 -0.082176 0.000000 -vn 0.996618 -0.082176 0.000000 -vn 0.996618 -0.082176 0.000000 -vn -0.096622 0.995321 0.000000 -vn -0.096622 0.995321 0.000000 -vn -0.096622 0.995321 0.000000 -vn -0.096622 0.995321 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn -0.096622 -0.995321 0.000000 -vn -0.096622 -0.995321 0.000000 -vn -0.096622 -0.995321 0.000000 -vn -0.096622 -0.995321 0.000000 -vn 0.996618 0.082176 0.000000 -vn 0.996618 0.082176 0.000000 -vn 0.996618 0.082176 0.000000 -vn 0.996618 0.082176 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -0.996618 0.082175 0.000000 -vn -0.996618 0.082175 0.000000 -vn -0.996618 0.082175 0.000000 -vn -0.996618 0.082175 0.000000 -vn 0.096622 -0.995321 0.000000 -vn 0.096622 -0.995321 0.000000 -vn 0.096622 -0.995321 0.000000 -vn 0.096622 -0.995321 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.096622 0.995321 0.000000 -vn 0.096622 0.995321 0.000000 -vn 0.096622 0.995321 0.000000 -vn 0.096622 0.995321 0.000000 -vn -0.996618 -0.082175 0.000000 -vn -0.996618 -0.082175 0.000000 -vn -0.996618 -0.082175 0.000000 -vn -0.996618 -0.082175 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn -1.000000 -0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 -0.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -1.000000 -0.000000 0.000000 -vn -1.000000 -0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 -0.000000 0.000000 -vn -1.000000 -0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 1.000000 -0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 -0.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 1.000000 -0.000000 0.000000 -vn 1.000000 -0.000000 0.000000 -vn -1.000000 -0.000000 0.000000 -vn -1.000000 -0.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn -0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn -0.000000 0.000000 1.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn -0.000000 0.000000 1.000000 -vn -0.000000 0.000000 1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn -0.000000 0.000000 1.000000 -vn -0.000000 0.000000 1.000000 -vn -0.000000 0.000000 1.000000 -vn -0.000000 0.000000 1.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn -0.000000 0.000000 -1.000000 -vn -0.000000 0.000000 -1.000000 -vn -0.000000 0.000000 -1.000000 -vn -0.000000 0.000000 -1.000000 -vn -0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn -0.000000 0.000000 1.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -0.000000 0.000000 1.000000 -vn -0.000000 0.000000 1.000000 -s 1 -g coz_block_geo -usemtl cube_mtl -f 1/252/1 29/44/2 73/248/3 74/243/4 -s 2 -f 3/168/5 30/170/6 31/174/7 14/26/8 -s 3 -f 77/254/9 78/255/10 26/256/11 7/259/12 -s off -f 15/28/13 28/251/14 29/249/15 1/9/16 -s 4 -f 2/240/17 16/30/18 70/236/19 71/233/20 -s 5 -f 15/246/21 1/1/22 74/244/23 75/245/24 -s 2 -f 10/193/25 32/196/26 25/40/27 5/219/28 -s 5 -f 7/13/29 11/19/30 76/258/31 77/253/32 -s off -f 7/7/33 26/257/34 27/262/35 11/260/36 -s 4 -f 80/264/37 69/265/38 12/271/39 8/11/40 -s 2 -f 14/177/8 31/175/7 32/191/26 10/18/25 -s off -f 81/108/41 82/105/42 83/106/43 84/107/44 -f 81/109/45 85/110/46 86/111/47 82/112/48 -f 88/113/49 87/114/50 89/115/51 90/116/52 -s 3 -f 79/266/53 80/263/54 8/8/55 18/269/56 -s off -f 19/270/57 18/268/58 8/267/59 12/21/60 -f 92/117/61 91/118/62 89/119/63 87/120/64 -f 21/36/65 20/239/66 16/241/67 2/10/68 -s 1 -f 72/235/69 21/237/70 2/2/71 71/234/72 -s 2 -f 23/208/73 22/212/74 4/231/75 13/23/76 -f 24/209/77 23/38/73 13/204/76 9/15/78 -f 17/224/79 24/39/77 9/206/78 6/225/80 -s off -f 93/121/81 94/122/82 95/123/83 96/124/84 -f 97/110/85 96/124/86 95/123/87 98/118/88 -f 28/275/89 27/274/90 19/279/91 20/278/92 -f 100/125/93 99/111/94 101/117/95 102/126/96 -f 103/127/97 100/128/98 102/129/99 104/130/100 -s 2 -f 31/173/7 30/171/6 22/211/74 23/213/73 -f 32/178/26 31/47/7 23/179/73 24/180/77 -f 25/198/27 32/48/26 24/201/77 17/200/79 -s 4 -f 58/285/101 34/286/102 33/287/103 57/288/104 -f 35/51/105 34/50/102 58/230/101 59/227/106 -s 1 -f 60/228/107 36/52/108 35/51/109 59/227/110 -f 61/166/111 37/295/112 36/296/108 60/297/107 -f 38/54/113 37/53/112 61/167/111 62/163/114 -s 5 -f 39/55/115 38/54/116 62/164/117 63/160/118 -f 40/161/119 39/181/115 63/182/118 64/183/120 -f 41/57/121 40/56/119 64/217/120 65/214/122 -s 3 -f 65/215/123 66/216/124 42/59/125 41/58/126 -f 66/186/124 67/187/127 43/188/128 42/189/125 -f 67/223/127 68/220/129 44/61/130 43/60/128 -s 4 -f 68/221/131 57/77/104 33/49/103 44/62/132 -f 34/286/102 46/289/133 45/290/134 33/287/103 -s off -f 106/131/135 105/132/136 107/133/137 108/134/138 -f 110/135/139 109/136/140 106/131/141 108/134/142 -s 1 -f 37/295/112 49/298/143 48/299/144 36/296/108 -s off -f 112/137/145 111/138/146 113/139/147 114/140/148 -f 115/141/149 112/137/150 114/140/151 116/142/152 -s 5 -f 52/184/153 51/185/154 39/181/115 40/161/119 -s off -f 118/143/155 117/144/156 119/145/157 120/146/158 -f 120/147/159 121/148/160 122/149/161 118/150/162 -s 3 -f 42/189/125 43/188/128 55/281/163 54/282/164 -s off -f 123/151/165 124/152/166 125/153/167 126/154/168 -f 124/155/169 127/156/170 128/157/171 125/158/172 -s 4 -f 13/205/173 58/203/101 57/202/104 9/16/174 -f 59/226/106 58/78/101 13/24/173 4/232/175 -s 1 -f 22/229/176 60/210/107 59/79/110 4/4/177 -f 30/172/178 61/165/111 60/80/107 22/37/176 -f 62/162/114 61/81/111 30/46/178 3/169/179 -s 5 -f 63/159/118 62/82/117 3/3/180 14/25/181 -f 64/190/120 63/83/118 14/176/181 10/17/182 -f 65/85/122 64/84/120 10/192/182 5/14/183 -s 3 -f 5/5/184 25/218/185 66/194/124 65/86/123 -f 25/197/185 17/31/186 67/195/127 66/87/124 -f 17/199/186 6/6/187 68/89/129 67/88/127 -s 4 -f 9/207/174 57/222/104 68/90/131 6/12/188 -f 46/289/133 70/291/19 69/292/38 45/290/134 -f 71/93/20 70/92/19 46/64/133 47/65/189 -s 1 -f 48/66/144 72/94/69 71/93/72 47/65/190 -f 49/298/143 73/300/3 72/301/69 48/299/144 -f 74/96/4 73/95/3 49/67/143 50/68/191 -s 5 -f 75/97/24 74/96/23 50/68/192 51/69/154 -f 76/293/31 75/294/24 51/185/154 52/184/153 -f 77/99/32 76/98/31 52/70/153 53/71/193 -s 3 -f 53/72/194 54/73/164 78/101/10 77/100/9 -f 54/282/164 55/281/163 79/283/53 78/284/10 -f 55/74/163 56/75/195 80/103/54 79/102/53 -s 4 -f 56/76/196 45/63/134 69/91/38 80/104/37 -s 14 -f 15/27/197 75/97/198 83/106/199 82/105/200 -s off -f 75/97/201 76/98/202 84/107/203 83/106/204 -s 15 -f 76/98/205 11/261/206 81/108/207 84/107/208 -f 11/20/206 27/273/209 85/110/210 81/109/207 -s off -f 27/273/211 28/276/212 86/111/213 85/110/214 -s 14 -f 28/276/215 15/247/197 82/112/200 86/111/216 -s 16 -f 70/92/217 16/242/218 87/114/219 88/113/220 -s 17 -f 12/22/221 69/91/222 90/116/223 89/115/224 -s off -f 69/91/225 70/92/226 88/113/227 90/116/228 -f 20/277/229 19/280/230 91/118/231 92/117/232 -s 17 -f 19/280/233 12/272/221 89/119/224 91/118/234 -s 16 -f 16/29/218 20/277/235 92/117/236 87/120/219 -s off -f 78/101/237 79/102/238 94/122/239 93/121/240 -s 18 -f 79/102/241 18/32/242 95/123/243 94/122/244 -s 19 -f 26/41/245 78/101/246 93/121/247 96/124/248 -f 27/42/249 26/41/245 96/124/248 97/110/250 -s 18 -f 18/32/242 19/33/251 98/118/252 95/123/243 -s off -f 19/33/253 27/42/254 97/110/255 98/118/256 -s 20 -f 29/45/257 28/43/258 99/111/259 100/125/260 -s off -f 28/43/261 20/34/262 101/117/263 99/111/264 -s 21 -f 20/34/265 21/238/266 102/126/267 101/117/268 -s 20 -f 73/95/269 29/250/257 100/128/260 103/127/270 -s 21 -f 21/35/266 72/94/271 104/130/272 102/129/267 -s off -f 72/94/273 73/95/274 103/127/275 104/130/276 -s 22 -f 47/65/277 46/64/278 105/132/279 106/131/280 -s off -f 46/64/281 34/50/282 107/133/283 105/132/284 -s 23 -f 34/50/285 35/51/286 108/134/287 107/133/288 -s off -f 36/52/289 48/66/290 109/136/291 110/135/292 -s 22 -f 48/66/293 47/65/277 106/131/280 109/136/294 -s 23 -f 35/51/286 36/52/295 110/135/296 108/134/287 -s 24 -f 50/68/297 49/67/298 111/138/299 112/137/300 -s off -f 49/67/301 37/53/302 113/139/303 111/138/304 -s 25 -f 37/53/305 38/54/306 114/140/307 113/139/308 -s 24 -f 51/69/309 50/68/297 112/137/300 115/141/310 -s 25 -f 38/54/306 39/55/311 116/142/312 114/140/307 -s off -f 39/55/313 51/69/314 115/141/315 116/142/316 -s 26 -f 53/71/317 52/70/318 117/144/319 118/143/320 -s off -f 52/70/321 40/56/322 119/145/323 117/144/324 -s 27 -f 40/56/325 41/57/326 120/146/327 119/145/328 -f 41/58/326 42/59/329 121/148/330 120/147/327 -s off -f 42/59/331 54/73/332 122/149/333 121/148/334 -s 26 -f 54/73/335 53/72/317 118/150/320 122/149/336 -s 28 -f 43/60/337 44/61/338 124/152/339 123/151/340 -s 29 -f 56/75/341 55/74/342 126/154/343 125/153/344 -s off -f 55/74/345 43/60/346 123/151/347 126/154/348 -s 28 -f 44/62/338 33/49/349 127/156/350 124/155/339 -s off -f 33/49/351 45/63/352 128/157/353 127/156/354 -s 29 -f 45/63/355 56/76/341 125/158/344 128/157/356 diff --git a/anki_vector/opengl/assets/vector.mtl b/anki_vector/opengl/assets/vector.mtl deleted file mode 100644 index 9bd40b8..0000000 --- a/anki_vector/opengl/assets/vector.mtl +++ /dev/null @@ -1,67 +0,0 @@ -# rim around the screen -newmtl ScreenOp_matSG -illum 4 -Kd 0.00 0.00 0.00 0.2 -Ka 0.00 0.00 0.00 0.2 -Tf 1.00 1.00 1.00 -Ni 1.00 -Ks 0.08 0.08 0.08 0.2 -Ns 10 - -# glass screen -newmtl anisotropic1SG -illum 4 -Kd 0.00 0.00 0.00 0.2 -Ka 0.00 0.00 0.00 0.2 -Tf 0.09 0.09 0.09 -Ni 1.00 -Ks 0.1 0.1 0.1 0.2 -Ns 10 - -# head, arms+fork, wheels (but not treads) -newmtl blinn2SG -illum 4 -Kd 0.15 0.15 0.15 -Ka 0.00 0.00 0.00 -Tf 1.00 1.00 1.00 -Ni 1.00 -Ks 0.50 0.50 0.50 -Ns 10 - -# Treads -newmtl blinn3SG -illum 4 -Kd 0.10 0.10 0.10 -Ka 0.00 0.00 0.00 -Tf 1.00 1.00 1.00 -Ni 1.00 -Ks 0.5 0.5 0.5 -Ns 10 - -# Body and wheel-spacers -newmtl blinn4SG -illum 4 -Kd 0.15 0.15 0.15 -Ka 0.00 0.00 0.00 -Tf 1.00 1.00 1.00 -Ni 1.00 -Ks 0.50 0.50 0.50 -Ns 10 - -# Eyelids -newmtl lambert2SG -illum 4 -Kd 0.00 0.00 0.00 -Ka 0.00 0.00 0.00 -Tf 1.00 1.00 1.00 -Ni 1.00 -Ks 0.50 0.50 0.50 -Ns 10 - -# eyes -newmtl shadingMap1SG -illum 4 -Kd 0.00 0.60 1.00 -Ka 0.00 0.60 1.00 -Tf 1.00 1.00 1.00 -Ni 0.00 diff --git a/anki_vector/opengl/assets/vector.obj b/anki_vector/opengl/assets/vector.obj deleted file mode 100644 index f3daead..0000000 --- a/anki_vector/opengl/assets/vector.obj +++ /dev/null @@ -1,13220 +0,0 @@ -# This file uses millimeters as units for non-parametric coordinates. - -mtllib vector.mtl -g default -v 0.626701 0.539736 4.911171 -v 0.626701 0.580759 4.916572 -v 0.626701 0.618987 4.932406 -v 0.626701 0.651814 4.957595 -v 0.626701 0.677003 4.990423 -v 0.626701 0.692837 5.028650 -v 0.626701 0.698238 5.069674 -v 0.626701 0.539736 5.069674 -v 0.626701 0.539736 5.545547 -v 0.626701 0.580759 5.540147 -v 0.626701 0.618987 5.524312 -v 0.626701 0.651814 5.499124 -v 0.626701 0.677003 5.466297 -v 0.626701 0.692837 5.428069 -v 0.626701 0.698238 5.387045 -v 0.626701 0.539736 5.387045 -v 0.626701 0.222362 5.545547 -v 0.626701 0.181338 5.540147 -v 0.626701 0.143110 5.524312 -v 0.626701 0.110284 5.499124 -v 0.626701 0.085094 5.466297 -v 0.626701 0.069260 5.428069 -v 0.626701 0.063859 5.387045 -v 0.626701 0.222362 5.387045 -v 0.626701 0.222362 4.911171 -v 0.626701 0.181338 4.916572 -v 0.626701 0.143110 4.932406 -v 0.626701 0.110284 4.957595 -v 0.626701 0.085094 4.990423 -v 0.626701 0.069260 5.028650 -v 0.626701 0.063859 5.069674 -v 0.626701 0.222362 5.069674 -v 0.626701 0.381049 4.911171 -v 0.626701 0.381049 5.069674 -v 0.626701 0.381049 5.387045 -v 0.626701 0.381049 5.545547 -v 0.626701 0.063859 5.228359 -v 0.626701 0.222362 5.228359 -v 0.626701 0.381049 5.228359 -v 0.626701 0.539736 5.228359 -v 0.626701 0.698238 5.228359 -vt 0.343750 0.843750 -vt 0.349074 0.884190 -vt 0.364684 0.921875 -vt 0.389515 0.954235 -vt 0.421875 0.979066 -vt 0.459560 0.994676 -vt 0.500000 1.000000 -vt 0.500000 0.837500 -vt 0.500000 1.000000 -vt 0.500000 0.837500 -vt 0.459560 0.994676 -vt 0.421875 0.979066 -vt 0.389515 0.954235 -vt 0.364684 0.921875 -vt 0.349074 0.884190 -vt 0.343750 0.843750 -vt 0.500000 1.000000 -vt 0.459560 0.994676 -vt 0.500000 0.837500 -vt 0.421875 0.979066 -vt 0.389515 0.954235 -vt 0.364684 0.921875 -vt 0.349074 0.884190 -vt 0.343750 0.843750 -vt 0.500000 1.000000 -vt 0.500000 0.837500 -vt 0.459560 0.994676 -vt 0.421875 0.979066 -vt 0.389515 0.954235 -vt 0.364684 0.921875 -vt 0.349074 0.884190 -vt 0.343750 0.843750 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.500000 1.000000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 1.000000 0.500000 -vt 0.500000 0.000000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.000000 0.500000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 -0.000002 0.000000 -vn 1.000000 -0.000005 0.000000 -vn 1.000000 -0.000005 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 -0.000003 0.000000 -vn 1.000000 -0.000000 0.000000 -vn 1.000000 -0.000000 0.000000 -vn 1.000000 -0.000002 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 0.000002 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000002 0.000000 -vn 1.000000 0.000005 0.000000 -vn 1.000000 0.000005 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000003 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000002 0.000000 -vn 1.000000 0.000002 0.000000 -vn 1.000000 -0.000002 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -s 1 -g eye_L_geo -usemtl shadingMap1SG -f 1/7/1 2/6/2 8/8/3 -f 2/6/2 3/5/4 8/8/3 -f 3/5/4 4/4/5 8/8/3 -f 4/4/5 5/3/6 8/8/3 -f 5/3/6 6/2/7 8/8/3 -f 6/2/7 7/1/8 8/8/3 -s 2 -f 9/9/9 16/10/10 10/11/11 -f 10/11/11 16/10/10 11/12/12 -f 11/12/12 16/10/10 12/13/13 -f 12/13/13 16/10/10 13/14/14 -f 13/14/14 16/10/10 14/15/15 -f 14/15/15 16/10/10 15/16/16 -s 3 -f 17/17/17 18/18/18 24/19/19 -f 18/18/18 19/20/20 24/19/19 -f 19/20/20 20/21/21 24/19/19 -f 20/21/21 21/22/22 24/19/19 -f 21/22/22 22/23/23 24/19/19 -f 22/23/23 23/24/24 24/19/19 -s 4 -f 25/25/25 32/26/26 26/27/27 -f 26/27/27 32/26/26 27/28/28 -f 27/28/28 32/26/26 28/29/29 -f 28/29/29 32/26/26 29/30/30 -f 29/30/30 32/26/26 30/31/31 -f 30/31/31 32/26/26 31/32/32 -s 5 -f 17/33/33 24/34/34 35/56/35 36/58/36 -s 6 -f 15/37/37 16/38/38 40/63/39 41/65/40 -s 7 -f 24/41/41 23/42/42 37/59/43 38/61/44 -s 8 -f 35/57/45 24/46/46 38/60/47 39/62/48 -s 9 -f 34/55/49 32/50/50 25/51/51 33/53/52 -f 8/49/53 34/55/49 33/53/52 1/52/54 -s 8 -f 16/45/55 35/57/45 39/62/48 40/64/56 -s 5 -f 36/58/36 35/56/35 16/35/57 9/36/58 -s 7 -f 38/61/44 37/59/43 31/43/59 32/44/60 -s 8 -f 39/62/48 38/60/47 32/47/61 34/54/62 -f 40/64/56 39/62/48 34/54/62 8/48/63 -s 6 -f 41/65/40 40/63/39 8/39/64 7/40/65 -g default -v 0.626701 -0.212377 4.911171 -v 0.626701 -0.171354 4.916572 -v 0.626701 -0.133126 4.932406 -v 0.626701 -0.100299 4.957595 -v 0.626701 -0.075110 4.990423 -v 0.626701 -0.059276 5.028650 -v 0.626701 -0.053874 5.069674 -v 0.626701 -0.212377 5.069674 -v 0.626701 -0.212377 5.545547 -v 0.626701 -0.171354 5.540147 -v 0.626701 -0.133126 5.524312 -v 0.626701 -0.100299 5.499124 -v 0.626701 -0.075110 5.466297 -v 0.626701 -0.059276 5.428069 -v 0.626701 -0.053874 5.387045 -v 0.626701 -0.212377 5.387045 -v 0.626701 -0.529751 5.545547 -v 0.626701 -0.570775 5.540147 -v 0.626701 -0.609003 5.524312 -v 0.626701 -0.641829 5.499124 -v 0.626701 -0.667018 5.466297 -v 0.626701 -0.682853 5.428069 -v 0.626701 -0.688254 5.387045 -v 0.626701 -0.529751 5.387045 -v 0.626701 -0.529751 4.911171 -v 0.626701 -0.570775 4.916572 -v 0.626701 -0.609003 4.932406 -v 0.626701 -0.641829 4.957595 -v 0.626701 -0.667018 4.990423 -v 0.626701 -0.682853 5.028650 -v 0.626701 -0.688254 5.069674 -v 0.626701 -0.529751 5.069674 -v 0.626701 -0.371064 4.911171 -v 0.626701 -0.371064 5.069674 -v 0.626701 -0.371064 5.387045 -v 0.626701 -0.371064 5.545547 -v 0.626701 -0.688254 5.228359 -v 0.626701 -0.529751 5.228359 -v 0.626701 -0.371064 5.228359 -v 0.626701 -0.212377 5.228359 -v 0.626701 -0.053874 5.228359 -vt 0.750145 0.000000 -vt 0.814812 0.008514 -vt 0.750146 0.249856 -vt 0.875073 0.033474 -vt 0.926818 0.073181 -vt 0.966526 0.124928 -vt 0.991486 0.185189 -vt 1.000000 0.249856 -vt 0.750145 1.000000 -vt 0.750145 0.750145 -vt 0.814812 0.991487 -vt 0.875073 0.966527 -vt 0.926818 0.926820 -vt 0.966526 0.875073 -vt 0.991486 0.814812 -vt 1.000000 0.750145 -vt 0.249855 1.000000 -vt 0.185188 0.991487 -vt 0.249855 0.750145 -vt 0.124927 0.966527 -vt 0.073182 0.926820 -vt 0.033474 0.875073 -vt 0.008514 0.814812 -vt 0.000000 0.750145 -vt 0.249855 0.000000 -vt 0.249855 0.249856 -vt 0.185188 0.008514 -vt 0.124927 0.033474 -vt 0.073182 0.073181 -vt 0.033474 0.124928 -vt 0.008514 0.185189 -vt 0.000000 0.249856 -vt 0.500000 0.750145 -vt 0.500000 1.000000 -vt 0.750145 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.249855 0.500000 -vt 0.500001 0.500000 -vt 0.500001 0.249856 -vt 0.500000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 -0.000002 0.000000 -vn 1.000000 -0.000005 0.000000 -vn 1.000000 -0.000005 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 -0.000003 0.000000 -vn 1.000000 -0.000000 0.000000 -vn 1.000000 -0.000000 0.000000 -vn 1.000000 -0.000002 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 0.000002 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000002 0.000000 -vn 1.000000 0.000005 0.000000 -vn 1.000000 0.000005 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000003 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000002 0.000000 -vn 1.000000 0.000002 0.000000 -vn 1.000000 -0.000002 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -s 1 -g eye_R_geo -usemtl shadingMap1SG -f 42/66/66 43/67/67 49/68/68 -f 43/67/67 44/69/69 49/68/68 -f 44/69/69 45/70/70 49/68/68 -f 45/70/70 46/71/71 49/68/68 -f 46/71/71 47/72/72 49/68/68 -f 47/72/72 48/73/73 49/68/68 -s 2 -f 50/74/74 57/75/75 51/76/76 -f 51/76/76 57/75/75 52/77/77 -f 52/77/77 57/75/75 53/78/78 -f 53/78/78 57/75/75 54/79/79 -f 54/79/79 57/75/75 55/80/80 -f 55/80/80 57/75/75 56/81/81 -s 3 -f 58/82/82 59/83/83 65/84/84 -f 59/83/83 60/85/85 65/84/84 -f 60/85/85 61/86/86 65/84/84 -f 61/86/86 62/87/87 65/84/84 -f 62/87/87 63/88/88 65/84/84 -f 63/88/88 64/89/89 65/84/84 -s 4 -f 66/90/90 73/91/91 67/92/92 -f 67/92/92 73/91/91 68/93/93 -f 68/93/93 73/91/91 69/94/94 -f 69/94/94 73/91/91 70/95/95 -f 70/95/95 73/91/91 71/96/96 -f 71/96/96 73/91/91 72/97/97 -s 5 -f 58/82/98 65/84/99 76/98/100 77/99/101 -s 6 -f 56/81/102 57/75/103 81/100/104 82/101/105 -s 7 -f 65/84/106 64/89/107 78/102/108 79/103/109 -s 8 -f 76/98/110 65/84/111 79/103/112 80/104/113 -s 9 -f 75/105/114 73/91/115 66/90/116 74/106/117 -f 49/68/118 75/105/114 74/106/117 42/66/119 -s 8 -f 57/75/120 76/98/110 80/104/113 81/100/121 -s 5 -f 77/99/101 76/98/100 57/75/122 50/74/123 -s 7 -f 79/103/109 78/102/108 72/97/124 73/91/125 -s 8 -f 80/104/113 79/103/112 73/91/126 75/105/127 -f 81/100/121 80/104/113 75/105/127 49/68/128 -s 6 -f 82/101/105 81/100/104 49/68/129 48/73/130 -g default -v 0.661209 -1.087000 4.640860 -v 0.661210 1.087000 4.640860 -v 0.661209 -1.087000 5.797500 -v 0.661210 1.087000 5.815860 -v 0.661209 -1.087000 4.404531 -v 0.661210 0.979863 4.404531 -v 0.661209 -1.087000 6.026443 -v 0.661210 0.979863 6.052188 -v 0.661209 -1.253955 4.640860 -v 0.661209 -1.253955 5.797500 -v 0.661210 1.253955 4.640860 -v 0.661210 1.253955 5.815860 -v 0.661209 -1.189870 4.478348 -v 0.661210 1.141597 4.478348 -v 0.661209 -1.189870 5.978371 -v 0.661210 1.141597 5.978371 -v 0.066067 -1.087000 4.640860 -v 0.066068 1.087000 4.640860 -v 0.066068 -1.087000 5.797500 -v 0.066068 1.087000 5.815859 -v 0.066067 -1.087000 4.404531 -v 0.066068 0.979863 4.404531 -v 0.066068 -1.087000 6.026443 -v 0.066068 0.979863 6.052188 -v 0.066067 -1.253955 4.640860 -v 0.066068 -1.253955 5.797500 -v 0.066068 1.253955 4.640860 -v 0.066068 1.253955 5.815859 -v 0.066067 -1.189870 4.478348 -v 0.066068 1.141597 4.478348 -v 0.066068 -1.189870 5.978371 -v 0.066068 1.141597 5.978371 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vn 1.000000 -0.000000 0.000000 -vn 1.000000 -0.000000 0.000000 -vn 1.000000 -0.000000 0.000000 -vn 1.000000 -0.000000 0.000000 -vn 1.000000 -0.000000 -0.000000 -vn 1.000000 -0.000000 -0.000000 -vn 1.000000 -0.000000 -0.000000 -vn 1.000000 -0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 -0.000000 -vn 1.000000 0.000001 0.000000 -vn 1.000000 0.000001 0.000000 -vn 1.000000 0.000001 0.000000 -vn 1.000000 0.000001 0.000000 -vn 1.000000 0.000001 0.000000 -vn 1.000000 0.000001 0.000000 -vn 1.000000 0.000001 0.000000 -vn 1.000000 0.000001 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000001 0.008445 -0.999964 -vn 0.000001 0.008445 -0.999964 -vn 0.000001 0.008445 -0.999964 -vn 0.000001 0.008445 -0.999964 -vn 0.000000 -0.000000 -1.000000 -vn 0.000000 -0.000000 -1.000000 -vn 0.000000 -0.000000 -1.000000 -vn 0.000000 -0.000000 -1.000000 -vn 0.000000 -0.012455 0.999922 -vn 0.000000 -0.012455 0.999922 -vn 0.000000 -0.012455 0.999923 -vn 0.000000 -0.012455 0.999923 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -0.583007 -0.812467 -vn 0.000000 -0.583007 -0.812467 -vn 0.000000 -0.583007 -0.812467 -vn 0.000000 -0.583007 -0.812467 -vn 0.000000 -0.930281 -0.366847 -vn 0.000000 -0.930281 -0.366847 -vn 0.000000 -0.930281 -0.366847 -vn 0.000000 -0.930281 -0.366847 -vn 0.000000 0.415209 -0.909726 -vn 0.000000 0.415209 -0.909726 -vn 0.000000 0.415209 -0.909726 -vn 0.000000 0.415209 -0.909726 -vn 0.000000 0.822549 -0.568695 -vn 0.000000 0.822549 -0.568695 -vn 0.000000 0.822549 -0.568695 -vn 0.000000 0.822549 -0.568695 -vn 0.000000 -0.423361 0.905961 -vn 0.000000 -0.423361 0.905961 -vn 0.000000 -0.423361 0.905961 -vn 0.000000 -0.423361 0.905961 -vn 0.000000 -0.942584 0.333968 -vn 0.000000 -0.942584 0.333968 -vn 0.000000 -0.942584 0.333968 -vn 0.000000 -0.942584 0.333968 -vn 0.000000 0.415209 0.909726 -vn 0.000000 0.415209 0.909726 -vn 0.000000 0.415209 0.909726 -vn 0.000000 0.415209 0.909726 -vn -0.000001 0.822548 0.568696 -vn -0.000001 0.822548 0.568696 -vn -0.000001 0.822548 0.568696 -vn -0.000001 0.822548 0.568696 -s off -g screenEdge_geo -usemtl lambert2SG -f 84/107/131 83/108/132 87/109/133 88/110/134 -f 85/111/135 86/112/136 90/113/137 89/114/138 -f 83/115/139 85/116/140 92/117/141 91/118/142 -f 86/119/143 84/120/144 93/121/145 94/122/146 -f 87/123/147 83/124/148 91/125/149 95/126/150 -f 84/127/151 88/128/152 96/129/153 93/130/154 -f 85/131/155 89/132/156 97/133/157 92/134/158 -f 90/135/159 86/136/160 94/137/161 98/138/162 -f 83/139/163 84/140/164 100/141/165 99/142/166 -f 85/143/167 83/144/168 99/145/169 101/146/170 -f 84/147/171 86/148/172 102/149/173 100/150/174 -f 86/151/175 85/152/176 101/153/177 102/154/178 -f 88/155/179 87/156/180 103/157/181 104/158/182 -f 89/159/183 90/160/184 106/161/185 105/162/186 -f 91/163/187 92/164/188 108/165/189 107/166/190 -f 94/167/191 93/168/192 109/169/193 110/170/194 -f 87/171/195 95/172/196 111/173/197 103/174/198 -f 95/175/199 91/176/200 107/177/201 111/178/202 -f 96/179/203 88/180/204 104/181/205 112/182/206 -f 93/183/207 96/184/208 112/185/209 109/186/210 -f 97/187/211 89/188/212 105/189/213 113/190/214 -f 92/191/215 97/192/216 113/193/217 108/194/218 -f 90/195/219 98/196/220 114/197/221 106/198/222 -f 98/199/223 94/200/224 110/201/225 114/202/226 -g default -v 0.629725 -0.680588 5.556550 -v 0.629725 -0.648576 5.556550 -v 0.629725 -0.597651 5.556550 -v 0.629725 -0.531285 5.556550 -v 0.629725 -0.454001 5.556550 -v 0.629725 -0.371064 5.556550 -v 0.629725 -0.288127 5.556550 -v 0.629725 -0.210842 5.556550 -v 0.629725 -0.144476 5.556550 -v 0.629725 -0.093552 5.556550 -v 0.629725 -0.061539 5.556550 -v 0.629725 -0.050620 5.556550 -v 0.629725 -0.691507 5.556550 -v 0.629725 -0.680588 5.668884 -v 0.629725 -0.648576 5.668884 -v 0.629725 -0.597651 5.668884 -v 0.629725 -0.531285 5.668884 -v 0.629725 -0.454001 5.668884 -v 0.629725 -0.371064 5.668884 -v 0.629725 -0.288127 5.668884 -v 0.629725 -0.210842 5.668884 -v 0.629725 -0.144476 5.668884 -v 0.629725 -0.093552 5.668884 -v 0.629725 -0.061539 5.668884 -v 0.629725 -0.050620 5.668884 -v 0.629725 -0.691507 5.668884 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -s off -g eyeLid_R_top_geo -usemtl lambert2SG -f 116/204/227 129/227/228 128/228/229 115/203/230 -f 117/206/231 130/229/232 129/230/233 116/205/234 -f 118/208/235 131/231/236 130/232/237 117/207/238 -f 119/210/239 132/233/240 131/234/241 118/209/242 -f 120/212/243 133/235/244 132/236/245 119/211/246 -f 121/214/247 134/237/248 133/238/249 120/213/250 -f 122/216/251 135/239/252 134/240/253 121/215/254 -f 123/218/255 136/241/256 135/242/257 122/217/258 -f 124/220/259 137/243/260 136/244/261 123/219/262 -f 125/222/263 138/245/264 137/246/265 124/221/266 -f 126/224/267 139/247/268 138/248/269 125/223/270 -f 115/226/271 128/249/272 140/250/273 127/225/274 -g default -v 0.629725 0.069547 5.556550 -v 0.629725 0.101560 5.556550 -v 0.629725 0.152484 5.556550 -v 0.629725 0.218850 5.556550 -v 0.629725 0.296135 5.556550 -v 0.629725 0.379072 5.556550 -v 0.629725 0.462009 5.556550 -v 0.629725 0.539294 5.556550 -v 0.629725 0.605660 5.556550 -v 0.629725 0.656584 5.556550 -v 0.629725 0.688596 5.556550 -v 0.629725 0.699515 5.556550 -v 0.629725 0.058628 5.556550 -v 0.629725 0.069547 5.668884 -v 0.629725 0.101560 5.668884 -v 0.629725 0.152484 5.668884 -v 0.629725 0.218850 5.668884 -v 0.629725 0.296135 5.668884 -v 0.629725 0.379072 5.668884 -v 0.629725 0.462009 5.668884 -v 0.629725 0.539294 5.668884 -v 0.629725 0.605660 5.668884 -v 0.629725 0.656584 5.668884 -v 0.629725 0.688596 5.668884 -v 0.629725 0.699515 5.668884 -v 0.629725 0.058628 5.668884 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -vn 1.000000 0.000000 0.000002 -s off -g eyeLid_L_top_geo -usemtl lambert2SG -f 142/252/275 155/275/276 154/276/277 141/251/278 -f 143/254/279 156/277/280 155/278/281 142/253/282 -f 144/256/283 157/279/284 156/280/285 143/255/286 -f 145/258/287 158/281/288 157/282/289 144/257/290 -f 146/260/291 159/283/292 158/284/293 145/259/294 -f 147/262/295 160/285/296 159/286/297 146/261/298 -f 148/264/299 161/287/300 160/288/301 147/263/302 -f 149/266/303 162/289/304 161/290/305 148/265/306 -f 150/268/307 163/291/308 162/292/309 149/267/310 -f 151/270/311 164/293/312 163/294/313 150/269/314 -f 152/272/315 165/295/316 164/296/317 151/271/318 -f 141/274/319 154/297/320 166/298/321 153/273/322 -g default -v 0.629725 0.690372 4.887191 -v 0.629725 0.658359 4.887191 -v 0.629725 0.607435 4.887191 -v 0.629725 0.541069 4.887191 -v 0.629725 0.463784 4.887191 -v 0.629725 0.380847 4.887191 -v 0.629725 0.297910 4.887191 -v 0.629725 0.220625 4.887191 -v 0.629725 0.154259 4.887191 -v 0.629725 0.103335 4.887191 -v 0.629725 0.071323 4.887191 -v 0.629725 0.060404 4.887191 -v 0.629725 0.701291 4.887191 -v 0.629725 0.690372 4.774857 -v 0.629725 0.658359 4.774857 -v 0.629725 0.607435 4.774857 -v 0.629725 0.541069 4.774857 -v 0.629725 0.463784 4.774857 -v 0.629725 0.380847 4.774857 -v 0.629725 0.297910 4.774857 -v 0.629725 0.220625 4.774857 -v 0.629725 0.154259 4.774857 -v 0.629725 0.103335 4.774857 -v 0.629725 0.071323 4.774857 -v 0.629725 0.060404 4.774857 -v 0.629725 0.701291 4.774857 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -s off -g eyeLid_L_btm_geo -usemtl lambert2SG -f 168/300/323 181/323/324 180/324/325 167/299/326 -f 169/302/327 182/325/328 181/326/329 168/301/330 -f 170/304/331 183/327/332 182/328/333 169/303/334 -f 171/306/335 184/329/336 183/330/337 170/305/338 -f 172/308/339 185/331/340 184/332/341 171/307/342 -f 173/310/343 186/333/344 185/334/345 172/309/346 -f 174/312/347 187/335/348 186/336/349 173/311/350 -f 175/314/351 188/337/352 187/338/353 174/313/354 -f 176/316/355 189/339/356 188/340/357 175/315/358 -f 177/318/359 190/341/360 189/342/361 176/317/362 -f 178/320/363 191/343/364 190/344/365 177/319/366 -f 167/322/367 180/345/368 192/346/369 179/321/370 -g default -v 0.629725 -0.061539 4.887191 -v 0.629725 -0.093552 4.887191 -v 0.629725 -0.144476 4.887191 -v 0.629725 -0.210842 4.887191 -v 0.629725 -0.288127 4.887191 -v 0.629725 -0.371064 4.887191 -v 0.629725 -0.454001 4.887191 -v 0.629725 -0.531285 4.887191 -v 0.629725 -0.597651 4.887191 -v 0.629725 -0.648576 4.887191 -v 0.629725 -0.680588 4.887191 -v 0.629725 -0.691507 4.887191 -v 0.629725 -0.050620 4.887191 -v 0.629725 -0.061539 4.774857 -v 0.629725 -0.093552 4.774857 -v 0.629725 -0.144476 4.774857 -v 0.629725 -0.210842 4.774857 -v 0.629725 -0.288127 4.774857 -v 0.629725 -0.371064 4.774857 -v 0.629725 -0.454001 4.774857 -v 0.629725 -0.531285 4.774857 -v 0.629725 -0.597651 4.774857 -v 0.629725 -0.648576 4.774857 -v 0.629725 -0.680588 4.774857 -v 0.629725 -0.691507 4.774857 -v 0.629725 -0.050620 4.774857 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -vn 1.000000 0.000000 -0.000002 -s off -g eyeLid_R_btm_geo -usemtl lambert2SG -f 194/348/371 207/371/372 206/372/373 193/347/374 -f 195/350/375 208/373/376 207/374/377 194/349/378 -f 196/352/379 209/375/380 208/376/381 195/351/382 -f 197/354/383 210/377/384 209/378/385 196/353/386 -f 198/356/387 211/379/388 210/380/389 197/355/390 -f 199/358/391 212/381/392 211/382/393 198/357/394 -f 200/360/395 213/383/396 212/384/397 199/359/398 -f 201/362/399 214/385/400 213/386/401 200/361/402 -f 202/364/403 215/387/404 214/388/405 201/363/406 -f 203/366/407 216/389/408 215/390/409 202/365/410 -f 204/368/411 217/391/412 216/392/413 203/367/414 -f 193/370/415 206/393/416 218/394/417 205/369/418 -g default -v 0.294744 1.617529 0.093327 -v 0.951768 1.617529 0.269376 -v 1.432745 1.617529 0.750351 -v 1.608791 1.617529 1.407370 -v 1.478268 1.617529 1.990349 -v 0.917296 1.617529 2.553165 -v 0.294744 1.617529 2.726990 -v 0.294744 2.784919 0.093327 -v 0.951768 2.784919 0.269376 -v 1.432745 2.784919 0.750351 -v 1.608791 2.784919 1.407370 -v 1.478268 2.784919 1.990349 -v 0.917296 2.784919 2.553165 -v 0.294744 2.784919 2.726990 -v -4.444170 1.617529 1.975439 -v -5.223321 1.617529 1.499233 -v -5.343847 1.617529 1.121490 -v -5.282925 1.617529 0.628455 -v -4.894008 1.617529 0.267533 -v -4.444170 1.617529 0.135424 -v -4.444170 2.784919 1.975439 -v -5.223321 2.784919 1.499233 -v -5.343847 2.784919 1.121490 -v -5.282925 2.784919 0.628455 -v -4.894008 2.784919 0.267533 -v -4.444170 2.784919 0.135424 -v -4.894008 2.784919 1.828536 -v -4.894008 1.617529 1.828536 -v -3.917632 2.784919 2.058953 -v -3.917632 1.617529 2.058953 -v -3.391076 2.784919 2.142448 -v -3.391076 1.617529 2.142448 -v -2.864538 2.784919 2.225962 -v -2.864538 1.617529 2.225962 -v -2.337991 2.784919 2.309457 -v -2.337991 1.617529 2.309457 -v -1.811444 2.784919 2.392971 -v -1.811444 1.617529 2.392971 -v -1.284896 2.784919 2.476466 -v -1.284896 1.617529 2.476466 -v -0.758350 2.784919 2.559980 -v -0.758350 1.617529 2.559980 -v -0.231803 2.784919 2.643476 -v -0.231803 1.617529 2.643476 -v -3.851815 2.784919 0.130162 -v -3.851815 1.617529 0.130162 -v -3.259441 2.784919 0.124900 -v -3.259441 1.617529 0.124900 -v -2.667077 2.784919 0.119638 -v -2.667077 1.617529 0.119638 -v -2.074713 2.784919 0.114375 -v -2.074713 1.617529 0.114375 -v -1.482349 2.784919 0.109113 -v -1.482349 1.617529 0.109113 -v -0.889985 2.784919 0.103851 -v -0.889985 1.617529 0.103851 -v -0.297620 2.784919 0.098589 -v -0.297620 1.617529 0.098589 -v 0.312742 1.617529 -0.048297 -v 1.021350 1.617529 0.148849 -v 1.021350 2.784919 0.148849 -v 0.312742 2.784919 -0.048297 -v 1.553272 1.617529 0.680764 -v 1.553272 2.784919 0.680764 -v 1.748672 1.617529 1.404471 -v 1.748672 2.784919 1.404471 -v 1.599585 1.617529 2.056938 -v 1.599585 2.784919 2.056938 -v 0.987688 1.617529 2.673410 -v 0.987688 2.784919 2.673410 -v 0.302839 1.617529 2.867529 -v 0.302839 2.784919 2.867529 -v -3.940186 1.617529 2.201262 -v -4.477831 1.617529 2.115074 -v -4.477831 2.784919 2.115074 -v -3.940186 2.784919 2.201262 -v -4.967319 1.617529 1.947952 -v -5.342868 1.617529 1.572073 -v -5.342868 2.784919 1.572073 -v -4.967319 2.784919 1.947952 -v -5.483991 1.617529 1.134556 -v -5.483991 2.784919 1.134556 -v -5.403414 1.617529 0.566817 -v -5.403414 2.784919 0.566817 -v -4.963327 1.617529 0.145605 -v -4.963327 2.784919 0.145605 -v -4.465105 1.617529 -0.005736 -v -4.465105 2.784919 -0.005736 -v -0.298900 1.617529 -0.045487 -v -0.298900 2.784919 -0.045487 -v -3.413649 1.617529 2.284757 -v -3.413649 2.784919 2.284757 -v -2.887111 1.617529 2.368271 -v -2.887111 2.784919 2.368271 -v -2.360555 1.617529 2.451766 -v -2.360555 2.784919 2.451766 -v -1.834012 1.617529 2.535280 -v -1.834012 2.784919 2.535280 -v -1.307464 1.617529 2.618775 -v -1.307464 2.784919 2.618775 -v -0.780916 1.617529 2.702271 -v -0.780916 2.784919 2.702271 -v -0.254376 1.617529 2.785785 -v -0.254376 2.784919 2.785785 -v -3.853095 1.617529 -0.013914 -v -3.853095 2.784919 -0.013914 -v -3.260722 1.617529 -0.019176 -v -3.260722 2.784919 -0.019176 -v -2.668357 1.617529 -0.024438 -v -2.668357 2.784919 -0.024438 -v -2.075993 1.617529 -0.029700 -v -2.075993 2.784919 -0.029700 -v -1.483629 1.617529 -0.034962 -v -1.483629 2.784919 -0.034962 -v -0.891265 1.617529 -0.040225 -v -0.891265 2.784919 -0.040225 -vt 0.479167 0.312500 -vt 0.500000 0.312500 -vt 0.520833 0.312500 -vt 0.541667 0.312500 -vt 0.562500 0.312500 -vt 0.583333 0.312500 -vt 0.604167 0.312500 -vt 0.479167 0.688440 -vt 0.500000 0.688440 -vt 0.520833 0.688440 -vt 0.541667 0.688440 -vt 0.562500 0.688440 -vt 0.583333 0.688440 -vt 0.604167 0.688440 -vt 0.375000 0.312500 -vt 0.395833 0.312500 -vt 0.395833 0.688440 -vt 0.375000 0.688440 -vt 0.416667 0.312500 -vt 0.416667 0.688440 -vt 0.437500 0.312500 -vt 0.437500 0.688440 -vt 0.458333 0.312500 -vt 0.458333 0.688440 -vt 0.479167 0.312500 -vt 0.479167 0.688440 -vt 0.625000 0.312500 -vt 0.625000 0.688440 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.384304 0.688440 -vt 0.384304 0.312500 -vt 0.622685 0.688440 -vt 0.622685 0.312500 -vt 0.620370 0.688440 -vt 0.620370 0.312500 -vt 0.618056 0.688440 -vt 0.618056 0.312500 -vt 0.615741 0.688440 -vt 0.615741 0.312500 -vt 0.613426 0.688440 -vt 0.613426 0.312500 -vt 0.611111 0.688440 -vt 0.611111 0.312500 -vt 0.608796 0.688440 -vt 0.608796 0.312500 -vt 0.606481 0.688440 -vt 0.606481 0.312500 -vt 1.000000 0.875000 -vt 0.000000 0.875000 -vt 1.000000 0.750000 -vt 0.000000 0.750000 -vt 1.000000 0.625000 -vt 0.000000 0.625000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.375000 -vt 0.000000 0.375000 -vt 1.000000 0.250000 -vt 0.000000 0.250000 -vt 1.000000 0.125000 -vt 0.000000 0.125000 -vt 0.479167 0.312500 -vt 0.500000 0.312500 -vt 0.500000 0.688440 -vt 0.479167 0.688440 -vt 0.520833 0.312500 -vt 0.520833 0.688440 -vt 0.541667 0.312500 -vt 0.541667 0.688440 -vt 0.562500 0.312500 -vt 0.562500 0.688440 -vt 0.583333 0.312500 -vt 0.583333 0.688440 -vt 0.604167 0.312500 -vt 0.604167 0.688440 -vt 0.622685 0.312500 -vt 0.625000 0.312500 -vt 0.625000 0.688440 -vt 0.622685 0.688440 -vt 0.384304 0.312500 -vt 0.395833 0.312500 -vt 0.395833 0.688440 -vt 0.384304 0.688440 -vt 0.416667 0.312500 -vt 0.416667 0.688440 -vt 0.437500 0.312500 -vt 0.437500 0.688440 -vt 0.458333 0.312500 -vt 0.458333 0.688440 -vt 0.479167 0.312500 -vt 0.479167 0.688440 -vt 0.000000 0.125000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 0.125000 -vt 0.375000 0.312500 -vt 0.375000 0.688440 -vt 0.620370 0.312500 -vt 0.620370 0.688440 -vt 0.618056 0.312500 -vt 0.618056 0.688440 -vt 0.615741 0.312500 -vt 0.615741 0.688440 -vt 0.613426 0.312500 -vt 0.613426 0.688440 -vt 0.611111 0.312500 -vt 0.611111 0.688440 -vt 0.608796 0.312500 -vt 0.608796 0.688440 -vt 0.606481 0.312500 -vt 0.606481 0.688440 -vt 0.000000 1.000000 -vt 0.000000 0.875000 -vt 1.000000 0.875000 -vt 1.000000 1.000000 -vt 0.000000 0.750000 -vt 1.000000 0.750000 -vt 0.000000 0.625000 -vt 1.000000 0.625000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.375000 -vt 1.000000 0.375000 -vt 0.000000 0.250000 -vt 1.000000 0.250000 -vt 0.479167 0.312500 -vt 0.500000 0.312500 -vt 0.500000 0.688440 -vt 0.479167 0.688440 -vt 0.520833 0.312500 -vt 0.520833 0.688440 -vt 0.541667 0.312500 -vt 0.541667 0.688440 -vt 0.562500 0.312500 -vt 0.562500 0.688440 -vt 0.583333 0.312500 -vt 0.583333 0.688440 -vt 0.604167 0.312500 -vt 0.604167 0.688440 -vt 0.622685 0.312500 -vt 0.625000 0.312500 -vt 0.625000 0.688440 -vt 0.622685 0.688440 -vt 0.384304 0.312500 -vt 0.395833 0.312500 -vt 0.395833 0.688440 -vt 0.384304 0.688440 -vt 0.416667 0.312500 -vt 0.416667 0.688440 -vt 0.437500 0.312500 -vt 0.437500 0.688440 -vt 0.458333 0.312500 -vt 0.458333 0.688440 -vt 0.479167 0.312500 -vt 0.479167 0.688440 -vt 0.000000 0.125000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 0.125000 -vt 0.375000 0.312500 -vt 0.375000 0.688440 -vt 0.620370 0.312500 -vt 0.620370 0.688440 -vt 0.618056 0.312500 -vt 0.618056 0.688440 -vt 0.615741 0.312500 -vt 0.615741 0.688440 -vt 0.613426 0.312500 -vt 0.613426 0.688440 -vt 0.611111 0.312500 -vt 0.611111 0.688440 -vt 0.608796 0.312500 -vt 0.608796 0.688440 -vt 0.606481 0.312500 -vt 0.606481 0.688440 -vt 0.000000 1.000000 -vt 0.000000 0.875000 -vt 1.000000 0.875000 -vt 1.000000 1.000000 -vt 0.000000 0.750000 -vt 1.000000 0.750000 -vt 0.000000 0.625000 -vt 1.000000 0.625000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.375000 -vt 1.000000 0.375000 -vt 0.000000 0.250000 -vt 1.000000 0.250000 -vn 0.145627 0.000000 -0.989340 -vn 0.145627 0.000000 -0.989340 -vn 0.506678 0.000000 -0.862135 -vn 0.506678 0.000000 -0.862135 -vn 0.865312 0.000000 -0.501234 -vn 0.865312 0.000000 -0.501234 -vn 0.999434 0.000000 -0.033634 -vn 0.999434 0.000000 -0.033634 -vn 0.857606 0.000000 0.514307 -vn 0.857606 0.000000 0.514307 -vn 0.530057 0.000000 0.847962 -vn 0.530057 0.000000 0.847962 -vn 0.090106 0.000000 0.995932 -vn 0.090106 0.000000 0.995932 -vn -0.157460 0.000000 0.987525 -vn -0.157460 0.000000 0.987525 -vn -0.239444 0.000000 0.970910 -vn -0.239444 0.000000 0.970910 -vn -0.531655 0.000000 0.846961 -vn -0.531655 0.000000 0.846961 -vn -0.844104 0.000000 0.536179 -vn -0.844104 0.000000 0.536179 -vn -0.998191 0.000000 0.060120 -vn -0.998191 0.000000 0.060120 -vn -0.884858 0.000000 -0.465861 -vn -0.884858 0.000000 -0.465861 -vn -0.520881 0.000000 -0.853629 -vn -0.520881 0.000000 -0.853629 -vn -0.142220 0.000000 -0.989835 -vn -0.142220 0.000000 -0.989835 -vn -0.006704 0.000000 -0.999978 -vn -0.006704 0.000000 -0.999978 -vn -0.156634 0.000000 0.987657 -vn -0.156634 0.000000 0.987657 -vn -0.156632 0.000000 0.987657 -vn -0.156632 0.000000 0.987657 -vn -0.156631 0.000000 0.987657 -vn -0.156631 0.000000 0.987657 -vn -0.156632 0.000000 0.987657 -vn -0.156632 0.000000 0.987657 -vn -0.156614 0.000000 0.987660 -vn -0.156614 0.000000 0.987660 -vn -0.156633 0.000000 0.987657 -vn -0.156633 0.000000 0.987657 -vn -0.150744 0.000000 0.988573 -vn -0.150744 0.000000 0.988573 -vn -0.011159 0.000000 -0.999938 -vn -0.011159 0.000000 -0.999938 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.258818 0.000000 0.965926 -vn -0.258818 0.000000 0.965926 -vn -0.258818 0.000000 0.965926 -vn -0.258818 0.000000 0.965926 -vn -0.707105 0.000000 0.707109 -vn -0.707105 0.000000 0.707109 -vn -0.707105 0.000000 0.707109 -vn -0.707105 0.000000 0.707109 -vn -0.965927 0.000000 0.258817 -vn -0.965927 0.000000 0.258817 -vn -0.965927 0.000000 0.258817 -vn -0.965927 0.000000 0.258817 -vn -0.975841 0.000000 -0.218482 -vn -0.975841 0.000000 -0.218482 -vn -0.975841 0.000000 -0.218482 -vn -0.975841 0.000000 -0.218482 -vn -0.708267 0.000000 -0.705945 -vn -0.708267 0.000000 -0.705945 -vn -0.708267 0.000000 -0.705945 -vn -0.708267 0.000000 -0.705945 -vn -0.268927 0.000000 -0.963161 -vn -0.268927 0.000000 -0.963161 -vn -0.268927 0.000000 -0.963161 -vn -0.268927 0.000000 -0.963161 -vn 0.156632 0.000000 -0.987657 -vn 0.156652 0.000000 -0.987654 -vn 0.156652 0.000000 -0.987654 -vn 0.156632 0.000000 -0.987657 -vn 0.521496 0.000000 -0.853254 -vn 0.707096 0.000000 -0.707117 -vn 0.707096 0.000000 -0.707117 -vn 0.521496 0.000000 -0.853254 -vn 0.952681 0.000000 -0.303972 -vn 0.952681 0.000000 -0.303972 -vn 0.952681 0.000000 -0.303972 -vn 0.952681 0.000000 -0.303972 -vn 0.992452 0.000000 0.122633 -vn 0.992452 0.000000 0.122633 -vn 0.992452 0.000000 0.122633 -vn 0.992452 0.000000 0.122633 -vn 0.680233 0.000000 0.732996 -vn 0.680233 0.000000 0.732996 -vn 0.680233 0.000000 0.732996 -vn 0.680233 0.000000 0.732996 -vn 0.281780 0.000000 0.959479 -vn 0.281780 0.000000 0.959479 -vn 0.281780 0.000000 0.959479 -vn 0.281780 0.000000 0.959479 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.310434 0.000000 -0.950595 -vn 0.310434 0.000000 -0.950595 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156633 0.000000 -0.987657 -vn 0.156633 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156649 0.000000 -0.987654 -vn 0.156649 0.000000 -0.987654 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008884 0.000000 0.999961 -vn 0.008884 0.000000 0.999961 -vn 0.008884 0.000000 0.999961 -vn 0.008884 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 0.000001 -vn 0.000000 1.000000 0.000001 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 0.000001 -vn 0.000000 1.000000 0.000001 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000001 -vn 0.000000 1.000000 0.000001 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000001 -vn 0.000000 1.000000 0.000001 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000001 -vn 0.000000 1.000000 0.000001 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000001 -vn 0.000000 1.000000 0.000001 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000001 -vn 0.000000 1.000000 0.000001 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -s 1 -g tracks_L_geo -usemtl blinn3SG -f 277/523/419 280/526/420 279/525/421 278/524/422 -f 278/524/422 279/525/421 282/528/423 281/527/424 -f 281/527/424 282/528/423 284/530/425 283/529/426 -f 283/529/426 284/530/425 286/532/427 285/531/428 -f 285/531/428 286/532/427 288/534/429 287/533/430 -f 287/533/430 288/534/429 290/536/431 289/535/432 -f 291/537/433 294/540/434 293/539/435 292/538/436 -f 295/541/437 298/544/438 297/543/439 296/542/440 -f 296/542/440 297/543/439 300/546/441 299/545/442 -f 299/545/442 300/546/441 302/548/443 301/547/444 -f 301/547/444 302/548/443 304/550/445 303/549/446 -f 303/549/446 304/550/445 306/552/447 305/551/448 -f 307/553/449 308/556/450 280/555/420 277/554/419 -f 292/557/436 293/558/435 298/544/438 295/541/437 -f 309/559/451 310/560/452 294/540/434 291/537/433 -f 311/561/453 312/562/454 310/560/452 309/559/451 -f 313/563/455 314/564/456 312/562/454 311/561/453 -f 315/565/457 316/566/458 314/564/456 313/563/455 -f 317/567/459 318/568/460 316/566/458 315/565/457 -f 319/569/461 320/570/462 318/568/460 317/567/459 -f 321/571/463 322/572/464 320/570/462 319/569/461 -f 289/535/432 290/536/431 322/572/464 321/571/463 -f 305/573/448 306/576/447 324/575/465 323/574/466 -f 323/574/466 324/575/465 326/578/467 325/577/468 -f 325/577/468 326/578/467 328/580/469 327/579/470 -f 327/579/470 328/580/469 330/582/471 329/581/472 -f 329/581/472 330/582/471 332/584/473 331/583/474 -f 331/583/474 332/584/473 334/586/475 333/585/476 -f 333/585/476 334/586/475 308/556/450 307/553/449 -s off -f 219/459/477 220/460/478 227/461/479 226/462/480 -f 220/460/481 221/463/482 228/464/483 227/461/484 -f 221/463/485 222/465/486 229/466/487 228/464/488 -f 222/465/489 223/467/490 230/468/491 229/466/492 -f 223/467/493 224/469/494 231/470/495 230/468/496 -f 224/469/497 225/471/498 232/472/499 231/470/500 -s 3 -f 248/473/501 233/474/502 239/475/503 247/476/504 -s 4 -f 246/477/505 234/478/506 240/479/507 245/480/508 -s off -f 234/478/509 235/481/510 241/482/511 240/479/512 -f 235/481/513 236/483/514 242/484/515 241/482/516 -f 236/483/517 237/485/518 243/486/519 242/484/520 -f 237/485/521 238/487/522 244/488/523 243/486/524 -s 5 -f 276/489/525 219/490/526 226/491/527 275/492/528 -s 4 -f 233/493/529 246/477/505 245/480/508 239/494/530 -s 3 -f 250/495/531 248/473/501 247/476/504 249/496/532 -f 252/497/533 250/495/531 249/496/532 251/498/534 -f 254/499/535 252/497/533 251/498/534 253/500/536 -f 256/501/537 254/499/535 253/500/536 255/502/538 -f 258/503/539 256/501/537 255/502/538 257/504/540 -f 260/505/541 258/503/539 257/504/540 259/506/542 -f 262/507/543 260/505/541 259/506/542 261/508/544 -f 225/471/545 262/507/543 261/508/544 232/472/546 -s 5 -f 238/509/547 264/510/548 263/511/549 244/512/550 -f 264/510/548 266/513/551 265/514/552 263/511/549 -f 266/513/551 268/515/553 267/516/554 265/514/552 -f 268/515/553 270/517/555 269/518/556 267/516/554 -f 270/517/555 272/519/557 271/520/558 269/518/556 -f 272/519/557 274/521/559 273/522/560 271/520/558 -f 274/521/559 276/489/525 275/492/528 273/522/560 -s 7 -f 219/395/561 277/523/562 278/524/563 220/396/564 -s 8 -f 227/403/565 279/525/566 280/526/567 226/402/568 -s 7 -f 220/396/564 278/524/563 281/527/569 221/397/570 -s 8 -f 228/404/571 282/528/572 279/525/566 227/403/565 -s 7 -f 221/397/570 281/527/569 283/529/573 222/398/574 -s 8 -f 229/405/575 284/530/576 282/528/572 228/404/571 -s 7 -f 222/398/574 283/529/573 285/531/577 223/399/578 -s 8 -f 230/406/579 286/532/580 284/530/576 229/405/575 -s 7 -f 223/399/578 285/531/577 287/533/581 224/400/582 -s 8 -f 231/407/583 288/534/584 286/532/580 230/406/579 -s 7 -f 224/400/582 287/533/581 289/535/585 225/401/586 -s 8 -f 232/408/587 290/536/588 288/534/584 231/407/583 -s 7 -f 248/430/589 291/537/590 292/538/591 233/421/592 -s 8 -f 239/422/593 293/539/594 294/540/595 247/429/596 -s 7 -f 246/428/597 295/541/598 296/542/599 234/410/600 -s 8 -f 240/411/601 297/543/602 298/544/603 245/427/604 -s 7 -f 234/410/600 296/542/599 299/545/605 235/413/606 -s 8 -f 241/414/607 300/546/608 297/543/602 240/411/601 -s 7 -f 235/413/606 299/545/605 301/547/609 236/415/610 -s 8 -f 242/416/611 302/548/612 300/546/608 241/414/607 -s 7 -f 236/415/610 301/547/609 303/549/613 237/417/614 -s 8 -f 243/418/615 304/550/616 302/548/612 242/416/611 -s 7 -f 237/417/614 303/549/613 305/551/617 238/419/618 -s 8 -f 244/420/619 306/552/620 304/550/616 243/418/615 -s 7 -f 276/458/621 307/553/622 277/554/562 219/423/561 -s 8 -f 226/424/568 280/555/567 308/556/623 275/457/624 -s 7 -f 233/409/592 292/557/591 295/541/598 246/428/597 -s 8 -f 245/427/604 298/544/603 293/558/594 239/412/593 -s 7 -f 250/432/625 309/559/626 291/537/590 248/430/589 -s 8 -f 247/429/596 294/540/595 310/560/627 249/431/628 -s 7 -f 252/434/629 311/561/630 309/559/626 250/432/625 -s 8 -f 249/431/628 310/560/627 312/562/631 251/433/632 -s 7 -f 254/436/633 313/563/634 311/561/630 252/434/629 -s 8 -f 251/433/632 312/562/631 314/564/635 253/435/636 -s 7 -f 256/438/637 315/565/638 313/563/634 254/436/633 -s 8 -f 253/435/636 314/564/635 316/566/639 255/437/640 -s 7 -f 258/440/641 317/567/642 315/565/638 256/438/637 -s 8 -f 255/437/640 316/566/639 318/568/643 257/439/644 -s 7 -f 260/442/645 319/569/646 317/567/642 258/440/641 -s 8 -f 257/439/644 318/568/643 320/570/647 259/441/648 -s 7 -f 262/444/649 321/571/650 319/569/646 260/442/645 -s 8 -f 259/441/648 320/570/647 322/572/651 261/443/652 -s 7 -f 225/401/586 289/535/585 321/571/650 262/444/649 -s 8 -f 261/443/652 322/572/651 290/536/588 232/408/587 -s 7 -f 238/426/618 305/573/617 323/574/653 264/446/654 -s 8 -f 263/445/655 324/575/656 306/576/620 244/425/619 -s 7 -f 264/446/654 323/574/653 325/577/657 266/448/658 -s 8 -f 265/447/659 326/578/660 324/575/656 263/445/655 -s 7 -f 266/448/658 325/577/657 327/579/661 268/450/662 -s 8 -f 267/449/663 328/580/664 326/578/660 265/447/659 -s 7 -f 268/450/662 327/579/661 329/581/665 270/452/666 -s 8 -f 269/451/667 330/582/668 328/580/664 267/449/663 -s 7 -f 270/452/666 329/581/665 331/583/669 272/454/670 -s 8 -f 271/453/671 332/584/672 330/582/668 269/451/667 -s 7 -f 272/454/670 331/583/669 333/585/673 274/456/674 -s 8 -f 273/455/675 334/586/676 332/584/672 271/453/671 -s 7 -f 274/456/674 333/585/673 307/553/622 276/458/621 -s 8 -f 275/457/624 308/556/623 334/586/676 273/455/675 -g default -v 0.294744 -1.617529 0.093327 -v 0.951768 -1.617529 0.269376 -v 1.432745 -1.617529 0.750351 -v 1.608791 -1.617529 1.407370 -v 1.478268 -1.617529 1.990349 -v 0.917296 -1.617529 2.553165 -v 0.294744 -1.617529 2.726990 -v 0.294744 -2.784919 0.093327 -v 0.951768 -2.784919 0.269376 -v 1.432745 -2.784919 0.750351 -v 1.608791 -2.784919 1.407370 -v 1.478268 -2.784919 1.990349 -v 0.917296 -2.784919 2.553165 -v 0.294744 -2.784919 2.726990 -v -4.444170 -1.617529 1.975439 -v -5.223321 -1.617529 1.499233 -v -5.343847 -1.617529 1.121490 -v -5.282925 -1.617529 0.628455 -v -4.894008 -1.617529 0.267533 -v -4.444170 -1.617529 0.135424 -v -4.444170 -2.784919 1.975439 -v -5.223321 -2.784919 1.499233 -v -5.343847 -2.784919 1.121490 -v -5.282925 -2.784919 0.628455 -v -4.894008 -2.784919 0.267533 -v -4.444170 -2.784919 0.135424 -v -4.894008 -2.784919 1.828536 -v -4.894008 -1.617529 1.828536 -v -3.917632 -2.784919 2.058953 -v -3.917632 -1.617529 2.058953 -v -3.391076 -2.784919 2.142448 -v -3.391076 -1.617529 2.142448 -v -2.864538 -2.784919 2.225962 -v -2.864538 -1.617529 2.225962 -v -2.337991 -2.784919 2.309457 -v -2.337991 -1.617529 2.309457 -v -1.811444 -2.784919 2.392971 -v -1.811444 -1.617529 2.392971 -v -1.284896 -2.784919 2.476466 -v -1.284896 -1.617529 2.476466 -v -0.758350 -2.784919 2.559980 -v -0.758350 -1.617529 2.559980 -v -0.231803 -2.784919 2.643476 -v -0.231803 -1.617529 2.643476 -v -3.851815 -2.784919 0.130162 -v -3.851815 -1.617529 0.130162 -v -3.259441 -2.784919 0.124900 -v -3.259441 -1.617529 0.124900 -v -2.667077 -2.784919 0.119638 -v -2.667077 -1.617529 0.119638 -v -2.074713 -2.784919 0.114375 -v -2.074713 -1.617529 0.114375 -v -1.482349 -2.784919 0.109113 -v -1.482349 -1.617529 0.109113 -v -0.889985 -2.784919 0.103851 -v -0.889985 -1.617529 0.103851 -v -0.297620 -2.784919 0.098589 -v -0.297620 -1.617529 0.098589 -v 0.312742 -1.617529 -0.048297 -v 1.021350 -1.617529 0.148849 -v 1.021350 -2.784919 0.148849 -v 0.312742 -2.784919 -0.048297 -v 1.553272 -1.617529 0.680764 -v 1.553272 -2.784919 0.680764 -v 1.748672 -1.617529 1.404471 -v 1.748672 -2.784919 1.404471 -v 1.599585 -1.617529 2.056938 -v 1.599585 -2.784919 2.056938 -v 0.987688 -1.617529 2.673410 -v 0.987688 -2.784919 2.673410 -v 0.302839 -1.617529 2.867529 -v 0.302839 -2.784919 2.867529 -v -3.940186 -1.617529 2.201262 -v -4.477831 -1.617529 2.115074 -v -4.477831 -2.784919 2.115074 -v -3.940186 -2.784919 2.201262 -v -4.967319 -1.617529 1.947952 -v -5.342868 -1.617529 1.572073 -v -5.342868 -2.784919 1.572073 -v -4.967319 -2.784919 1.947952 -v -5.483991 -1.617529 1.134556 -v -5.483991 -2.784919 1.134556 -v -5.403414 -1.617529 0.566817 -v -5.403414 -2.784919 0.566817 -v -4.963327 -1.617529 0.145605 -v -4.963327 -2.784919 0.145605 -v -4.465105 -1.617529 -0.005736 -v -4.465105 -2.784919 -0.005736 -v -0.298900 -1.617529 -0.045487 -v -0.298900 -2.784919 -0.045487 -v -3.413649 -1.617529 2.284757 -v -3.413649 -2.784919 2.284757 -v -2.887111 -1.617529 2.368271 -v -2.887111 -2.784919 2.368271 -v -2.360555 -1.617529 2.451766 -v -2.360555 -2.784919 2.451766 -v -1.834012 -1.617529 2.535280 -v -1.834012 -2.784919 2.535280 -v -1.307464 -1.617529 2.618775 -v -1.307464 -2.784919 2.618775 -v -0.780916 -1.617529 2.702271 -v -0.780916 -2.784919 2.702271 -v -0.254376 -1.617529 2.785785 -v -0.254376 -2.784919 2.785785 -v -3.853095 -1.617529 -0.013914 -v -3.853095 -2.784919 -0.013914 -v -3.260722 -1.617529 -0.019176 -v -3.260722 -2.784919 -0.019176 -v -2.668357 -1.617529 -0.024438 -v -2.668357 -2.784919 -0.024438 -v -2.075993 -1.617529 -0.029700 -v -2.075993 -2.784919 -0.029700 -v -1.483629 -1.617529 -0.034962 -v -1.483629 -2.784919 -0.034962 -v -0.891265 -1.617529 -0.040225 -v -0.891265 -2.784919 -0.040225 -vt 0.479167 0.312500 -vt 0.500000 0.312500 -vt 0.520833 0.312500 -vt 0.541667 0.312500 -vt 0.562500 0.312500 -vt 0.583333 0.312500 -vt 0.604167 0.312500 -vt 0.479167 0.688440 -vt 0.500000 0.688440 -vt 0.520833 0.688440 -vt 0.541667 0.688440 -vt 0.562500 0.688440 -vt 0.583333 0.688440 -vt 0.604167 0.688440 -vt 0.375000 0.312500 -vt 0.395833 0.312500 -vt 0.395833 0.688440 -vt 0.375000 0.688440 -vt 0.416667 0.312500 -vt 0.416667 0.688440 -vt 0.437500 0.312500 -vt 0.437500 0.688440 -vt 0.458333 0.312500 -vt 0.458333 0.688440 -vt 0.479167 0.312500 -vt 0.479167 0.688440 -vt 0.625000 0.312500 -vt 0.625000 0.688440 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.384304 0.688440 -vt 0.384304 0.312500 -vt 0.622685 0.688440 -vt 0.622685 0.312500 -vt 0.620370 0.688440 -vt 0.620370 0.312500 -vt 0.618056 0.688440 -vt 0.618056 0.312500 -vt 0.615741 0.688440 -vt 0.615741 0.312500 -vt 0.613426 0.688440 -vt 0.613426 0.312500 -vt 0.611111 0.688440 -vt 0.611111 0.312500 -vt 0.608796 0.688440 -vt 0.608796 0.312500 -vt 0.606481 0.688440 -vt 0.606481 0.312500 -vt 1.000000 0.875000 -vt 0.000000 0.875000 -vt 1.000000 0.750000 -vt 0.000000 0.750000 -vt 1.000000 0.625000 -vt 0.000000 0.625000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.375000 -vt 0.000000 0.375000 -vt 1.000000 0.250000 -vt 0.000000 0.250000 -vt 1.000000 0.125000 -vt 0.000000 0.125000 -vt 0.479167 0.312500 -vt 0.500000 0.312500 -vt 0.500000 0.688440 -vt 0.479167 0.688440 -vt 0.520833 0.312500 -vt 0.520833 0.688440 -vt 0.541667 0.312500 -vt 0.541667 0.688440 -vt 0.562500 0.312500 -vt 0.562500 0.688440 -vt 0.583333 0.312500 -vt 0.583333 0.688440 -vt 0.604167 0.312500 -vt 0.604167 0.688440 -vt 0.622685 0.312500 -vt 0.625000 0.312500 -vt 0.625000 0.688440 -vt 0.622685 0.688440 -vt 0.384304 0.312500 -vt 0.395833 0.312500 -vt 0.395833 0.688440 -vt 0.384304 0.688440 -vt 0.416667 0.312500 -vt 0.416667 0.688440 -vt 0.437500 0.312500 -vt 0.437500 0.688440 -vt 0.458333 0.312500 -vt 0.458333 0.688440 -vt 0.479167 0.312500 -vt 0.479167 0.688440 -vt 0.000000 0.125000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 0.125000 -vt 0.375000 0.312500 -vt 0.375000 0.688440 -vt 0.620370 0.312500 -vt 0.620370 0.688440 -vt 0.618056 0.312500 -vt 0.618056 0.688440 -vt 0.615741 0.312500 -vt 0.615741 0.688440 -vt 0.613426 0.312500 -vt 0.613426 0.688440 -vt 0.611111 0.312500 -vt 0.611111 0.688440 -vt 0.608796 0.312500 -vt 0.608796 0.688440 -vt 0.606481 0.312500 -vt 0.606481 0.688440 -vt 0.000000 1.000000 -vt 0.000000 0.875000 -vt 1.000000 0.875000 -vt 1.000000 1.000000 -vt 0.000000 0.750000 -vt 1.000000 0.750000 -vt 0.000000 0.625000 -vt 1.000000 0.625000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.375000 -vt 1.000000 0.375000 -vt 0.000000 0.250000 -vt 1.000000 0.250000 -vt 0.479167 0.312500 -vt 0.500000 0.312500 -vt 0.500000 0.688440 -vt 0.479167 0.688440 -vt 0.520833 0.312500 -vt 0.520833 0.688440 -vt 0.541667 0.312500 -vt 0.541667 0.688440 -vt 0.562500 0.312500 -vt 0.562500 0.688440 -vt 0.583333 0.312500 -vt 0.583333 0.688440 -vt 0.604167 0.312500 -vt 0.604167 0.688440 -vt 0.622685 0.312500 -vt 0.625000 0.312500 -vt 0.625000 0.688440 -vt 0.622685 0.688440 -vt 0.384304 0.312500 -vt 0.395833 0.312500 -vt 0.395833 0.688440 -vt 0.384304 0.688440 -vt 0.416667 0.312500 -vt 0.416667 0.688440 -vt 0.437500 0.312500 -vt 0.437500 0.688440 -vt 0.458333 0.312500 -vt 0.458333 0.688440 -vt 0.479167 0.312500 -vt 0.479167 0.688440 -vt 0.000000 0.125000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 0.125000 -vt 0.375000 0.312500 -vt 0.375000 0.688440 -vt 0.620370 0.312500 -vt 0.620370 0.688440 -vt 0.618056 0.312500 -vt 0.618056 0.688440 -vt 0.615741 0.312500 -vt 0.615741 0.688440 -vt 0.613426 0.312500 -vt 0.613426 0.688440 -vt 0.611111 0.312500 -vt 0.611111 0.688440 -vt 0.608796 0.312500 -vt 0.608796 0.688440 -vt 0.606481 0.312500 -vt 0.606481 0.688440 -vt 0.000000 1.000000 -vt 0.000000 0.875000 -vt 1.000000 0.875000 -vt 1.000000 1.000000 -vt 0.000000 0.750000 -vt 1.000000 0.750000 -vt 0.000000 0.625000 -vt 1.000000 0.625000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.375000 -vt 1.000000 0.375000 -vt 0.000000 0.250000 -vt 1.000000 0.250000 -vn 0.145627 0.000000 -0.989340 -vn 0.506678 0.000000 -0.862135 -vn 0.506678 0.000000 -0.862135 -vn 0.145627 0.000000 -0.989340 -vn 0.865312 0.000000 -0.501234 -vn 0.865312 0.000000 -0.501234 -vn 0.999434 0.000000 -0.033634 -vn 0.999434 0.000000 -0.033634 -vn 0.857606 0.000000 0.514307 -vn 0.857606 0.000000 0.514307 -vn 0.530057 0.000000 0.847962 -vn 0.530057 0.000000 0.847962 -vn 0.090106 0.000000 0.995932 -vn 0.090106 0.000000 0.995932 -vn -0.157460 0.000000 0.987525 -vn -0.239444 0.000000 0.970910 -vn -0.239444 0.000000 0.970910 -vn -0.157460 0.000000 0.987525 -vn -0.531655 0.000000 0.846961 -vn -0.844104 0.000000 0.536179 -vn -0.844104 0.000000 0.536179 -vn -0.531655 0.000000 0.846961 -vn -0.998191 0.000000 0.060120 -vn -0.998191 0.000000 0.060120 -vn -0.884858 0.000000 -0.465861 -vn -0.884858 0.000000 -0.465861 -vn -0.520881 0.000000 -0.853629 -vn -0.520881 0.000000 -0.853629 -vn -0.142220 0.000000 -0.989835 -vn -0.142220 0.000000 -0.989835 -vn -0.006704 0.000000 -0.999978 -vn -0.006704 0.000000 -0.999978 -vn -0.156634 0.000000 0.987657 -vn -0.156634 0.000000 0.987657 -vn -0.156632 0.000000 0.987657 -vn -0.156632 0.000000 0.987657 -vn -0.156631 0.000000 0.987657 -vn -0.156631 0.000000 0.987657 -vn -0.156632 0.000000 0.987657 -vn -0.156632 0.000000 0.987657 -vn -0.156614 0.000000 0.987660 -vn -0.156614 0.000000 0.987660 -vn -0.156633 0.000000 0.987657 -vn -0.156633 0.000000 0.987657 -vn -0.150744 0.000000 0.988573 -vn -0.150744 0.000000 0.988573 -vn -0.011159 0.000000 -0.999938 -vn -0.011159 0.000000 -0.999938 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.008883 0.000000 -0.999961 -vn -0.258818 0.000000 0.965926 -vn -0.258818 0.000000 0.965926 -vn -0.258818 0.000000 0.965926 -vn -0.258818 0.000000 0.965926 -vn -0.707105 0.000000 0.707109 -vn -0.707105 0.000000 0.707109 -vn -0.707105 0.000000 0.707109 -vn -0.707105 0.000000 0.707109 -vn -0.965927 0.000000 0.258817 -vn -0.965927 0.000000 0.258817 -vn -0.965927 0.000000 0.258817 -vn -0.965927 0.000000 0.258817 -vn -0.975841 0.000000 -0.218482 -vn -0.975841 0.000000 -0.218482 -vn -0.975841 0.000000 -0.218482 -vn -0.975841 0.000000 -0.218482 -vn -0.708267 0.000000 -0.705945 -vn -0.708267 0.000000 -0.705945 -vn -0.708267 0.000000 -0.705945 -vn -0.708267 0.000000 -0.705945 -vn -0.268927 0.000000 -0.963161 -vn -0.268927 0.000000 -0.963161 -vn -0.268927 0.000000 -0.963161 -vn -0.268927 0.000000 -0.963161 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156652 0.000000 -0.987654 -vn 0.156652 0.000000 -0.987654 -vn 0.521496 0.000000 -0.853254 -vn 0.521496 0.000000 -0.853254 -vn 0.707096 0.000000 -0.707117 -vn 0.707096 0.000000 -0.707117 -vn 0.952681 0.000000 -0.303972 -vn 0.952681 0.000000 -0.303972 -vn 0.952681 0.000000 -0.303972 -vn 0.952681 0.000000 -0.303972 -vn 0.992452 0.000000 0.122633 -vn 0.992452 0.000000 0.122633 -vn 0.992452 0.000000 0.122633 -vn 0.992452 0.000000 0.122633 -vn 0.680233 0.000000 0.732996 -vn 0.680233 0.000000 0.732996 -vn 0.680233 0.000000 0.732996 -vn 0.680233 0.000000 0.732996 -vn 0.281780 0.000000 0.959479 -vn 0.281780 0.000000 0.959479 -vn 0.281780 0.000000 0.959479 -vn 0.281780 0.000000 0.959479 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.310434 0.000000 -0.950595 -vn 0.310434 0.000000 -0.950595 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156633 0.000000 -0.987657 -vn 0.156633 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156632 0.000000 -0.987657 -vn 0.156649 0.000000 -0.987654 -vn 0.156649 0.000000 -0.987654 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008884 0.000000 0.999961 -vn 0.008884 0.000000 0.999961 -vn 0.008884 0.000000 0.999961 -vn 0.008884 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.008883 0.000000 0.999961 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000002 -vn 0.000000 -1.000000 -0.000002 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -s 1 -g tracks_R_geo -usemtl blinn3SG -f 393/715/677 394/716/678 395/717/679 396/718/680 -f 394/716/678 397/719/681 398/720/682 395/717/679 -f 397/719/681 399/721/683 400/722/684 398/720/682 -f 399/721/683 401/723/685 402/724/686 400/722/684 -f 401/723/685 403/725/687 404/726/688 402/724/686 -f 403/725/687 405/727/689 406/728/690 404/726/688 -f 407/729/691 408/730/692 409/731/693 410/732/694 -f 411/733/695 412/734/696 413/735/697 414/736/698 -f 412/734/696 415/737/699 416/738/700 413/735/697 -f 415/737/699 417/739/701 418/740/702 416/738/700 -f 417/739/701 419/741/703 420/742/704 418/740/702 -f 419/741/703 421/743/705 422/744/706 420/742/704 -f 423/745/707 393/746/677 396/747/680 424/748/708 -f 408/749/692 411/733/695 414/736/698 409/750/693 -f 425/751/709 407/729/691 410/732/694 426/752/710 -f 427/753/711 425/751/709 426/752/710 428/754/712 -f 429/755/713 427/753/711 428/754/712 430/756/714 -f 431/757/715 429/755/713 430/756/714 432/758/716 -f 433/759/717 431/757/715 432/758/716 434/760/718 -f 435/761/719 433/759/717 434/760/718 436/762/720 -f 437/763/721 435/761/719 436/762/720 438/764/722 -f 405/727/689 437/763/721 438/764/722 406/728/690 -f 421/765/705 439/766/723 440/767/724 422/768/706 -f 439/766/723 441/769/725 442/770/726 440/767/724 -f 441/769/725 443/771/727 444/772/728 442/770/726 -f 443/771/727 445/773/729 446/774/730 444/772/728 -f 445/773/729 447/775/731 448/776/732 446/774/730 -f 447/775/731 449/777/733 450/778/734 448/776/732 -f 449/777/733 423/745/707 424/748/708 450/778/734 -s off -f 335/651/735 342/654/736 343/653/737 336/652/738 -f 336/652/739 343/653/740 344/656/741 337/655/742 -f 337/655/743 344/656/744 345/658/745 338/657/746 -f 338/657/747 345/658/748 346/660/749 339/659/750 -f 339/659/751 346/660/752 347/662/753 340/661/754 -f 340/661/755 347/662/756 348/664/757 341/663/758 -s 4 -f 364/665/759 363/668/760 355/667/761 349/666/762 -s 5 -f 362/669/763 361/672/764 356/671/765 350/670/766 -s off -f 350/670/767 356/671/768 357/674/769 351/673/770 -f 351/673/771 357/674/772 358/676/773 352/675/774 -f 352/675/775 358/676/776 359/678/777 353/677/778 -f 353/677/779 359/678/780 360/680/781 354/679/782 -s 6 -f 392/681/783 391/684/784 342/683/785 335/682/786 -s 5 -f 349/685/787 355/686/788 361/672/764 362/669/763 -s 4 -f 366/687/789 365/688/790 363/668/760 364/665/759 -f 368/689/791 367/690/792 365/688/790 366/687/789 -f 370/691/793 369/692/794 367/690/792 368/689/791 -f 372/693/795 371/694/796 369/692/794 370/691/793 -f 374/695/797 373/696/798 371/694/796 372/693/795 -f 376/697/799 375/698/800 373/696/798 374/695/797 -f 378/699/801 377/700/802 375/698/800 376/697/799 -f 341/663/803 348/664/804 377/700/802 378/699/801 -s 6 -f 354/701/805 360/704/806 379/703/807 380/702/808 -f 380/702/808 379/703/807 381/706/809 382/705/810 -f 382/705/810 381/706/809 383/708/811 384/707/812 -f 384/707/812 383/708/811 385/710/813 386/709/814 -f 386/709/814 385/710/813 387/712/815 388/711/816 -f 388/711/816 387/712/815 389/714/817 390/713/818 -f 390/713/818 389/714/817 391/684/784 392/681/783 -s 8 -f 335/587/819 336/588/820 394/716/821 393/715/822 -s 9 -f 343/595/823 342/594/824 396/718/825 395/717/826 -s 8 -f 336/588/820 337/589/827 397/719/828 394/716/821 -s 9 -f 344/596/829 343/595/823 395/717/826 398/720/830 -s 8 -f 337/589/827 338/590/831 399/721/832 397/719/828 -s 9 -f 345/597/833 344/596/829 398/720/830 400/722/834 -s 8 -f 338/590/831 339/591/835 401/723/836 399/721/832 -s 9 -f 346/598/837 345/597/833 400/722/834 402/724/838 -s 8 -f 339/591/835 340/592/839 403/725/840 401/723/836 -s 9 -f 347/599/841 346/598/837 402/724/838 404/726/842 -s 8 -f 340/592/839 341/593/843 405/727/844 403/725/840 -s 9 -f 348/600/845 347/599/841 404/726/842 406/728/846 -s 8 -f 364/622/847 349/613/848 408/730/849 407/729/850 -s 9 -f 355/614/851 363/621/852 410/732/853 409/731/854 -s 8 -f 362/620/855 350/602/856 412/734/857 411/733/858 -s 9 -f 356/603/859 361/619/860 414/736/861 413/735/862 -s 8 -f 350/602/856 351/605/863 415/737/864 412/734/857 -s 9 -f 357/606/865 356/603/859 413/735/862 416/738/866 -s 8 -f 351/605/863 352/607/867 417/739/868 415/737/864 -s 9 -f 358/608/869 357/606/865 416/738/866 418/740/870 -s 8 -f 352/607/867 353/609/871 419/741/872 417/739/868 -s 9 -f 359/610/873 358/608/869 418/740/870 420/742/874 -s 8 -f 353/609/871 354/611/875 421/743/876 419/741/872 -s 9 -f 360/612/877 359/610/873 420/742/874 422/744/878 -s 8 -f 392/650/879 335/615/819 393/746/822 423/745/880 -s 9 -f 342/616/824 391/649/881 424/748/882 396/747/825 -s 8 -f 349/601/848 362/620/855 411/733/858 408/749/849 -s 9 -f 361/619/860 355/604/851 409/750/854 414/736/861 -s 8 -f 366/624/883 364/622/847 407/729/850 425/751/884 -s 9 -f 363/621/852 365/623/885 426/752/886 410/732/853 -s 8 -f 368/626/887 366/624/883 425/751/884 427/753/888 -s 9 -f 365/623/885 367/625/889 428/754/890 426/752/886 -s 8 -f 370/628/891 368/626/887 427/753/888 429/755/892 -s 9 -f 367/625/889 369/627/893 430/756/894 428/754/890 -s 8 -f 372/630/895 370/628/891 429/755/892 431/757/896 -s 9 -f 369/627/893 371/629/897 432/758/898 430/756/894 -s 8 -f 374/632/899 372/630/895 431/757/896 433/759/900 -s 9 -f 371/629/897 373/631/901 434/760/902 432/758/898 -s 8 -f 376/634/903 374/632/899 433/759/900 435/761/904 -s 9 -f 373/631/901 375/633/905 436/762/906 434/760/902 -s 8 -f 378/636/907 376/634/903 435/761/904 437/763/908 -s 9 -f 375/633/905 377/635/909 438/764/910 436/762/906 -s 8 -f 341/593/843 378/636/907 437/763/908 405/727/844 -s 9 -f 377/635/909 348/600/845 406/728/846 438/764/910 -s 8 -f 354/618/875 380/638/911 439/766/912 421/765/876 -s 9 -f 379/637/913 360/617/877 422/768/878 440/767/914 -s 8 -f 380/638/911 382/640/915 441/769/916 439/766/912 -s 9 -f 381/639/917 379/637/913 440/767/914 442/770/918 -s 8 -f 382/640/915 384/642/919 443/771/920 441/769/916 -s 9 -f 383/641/921 381/639/917 442/770/918 444/772/922 -s 8 -f 384/642/919 386/644/923 445/773/924 443/771/920 -s 9 -f 385/643/925 383/641/921 444/772/922 446/774/926 -s 8 -f 386/644/923 388/646/927 447/775/928 445/773/924 -s 9 -f 387/645/929 385/643/925 446/774/926 448/776/930 -s 8 -f 388/646/927 390/648/931 449/777/932 447/775/928 -s 9 -f 389/647/933 387/645/929 448/776/930 450/778/934 -s 8 -f 390/648/931 392/650/879 423/745/880 449/777/932 -s 9 -f 391/649/881 389/647/933 450/778/934 424/748/882 -g default -v -0.292415 -1.947312 3.146179 -v 0.340746 -1.947312 3.944062 -v 0.496262 0.000000 3.674693 -v -0.023602 0.000000 2.752161 -v -0.292415 -1.947312 6.253839 -v 0.340746 -1.947312 5.455937 -v 0.565167 0.000000 5.724967 -v -0.023602 -0.000000 6.647462 -v -2.602183 -1.947312 5.455937 -v -1.804295 -1.947312 6.253839 -v -2.073856 0.000000 6.647462 -v -2.996380 0.000000 5.724967 -v -1.804295 -1.947312 3.146179 -v -2.602183 -1.947312 3.944062 -v -2.996380 0.000000 3.674693 -v -2.073856 0.000000 2.752161 -v -2.373526 -1.947312 3.394631 -v -2.687928 -1.947312 4.700018 -v -1.048356 -1.947312 3.073622 -v 0.147333 -1.947312 3.414399 -v 0.362688 -1.947312 4.700018 -v 0.127546 -1.947312 5.965795 -v -1.048356 -1.947312 6.332985 -v -2.274584 -1.947312 5.965795 -v 0.496262 -1.344734 3.701766 -v -0.050665 -1.134867 2.803594 -v 0.315321 0.000000 3.059653 -v -0.050665 -1.134867 6.596028 -v 0.565167 -1.344734 5.697895 -v 0.494925 0.000000 6.339989 -v -2.944946 -1.344734 5.697895 -v -2.046784 -1.134867 6.596028 -v -2.688888 0.000000 6.339989 -v -2.046784 -1.134867 2.803594 -v -2.944946 -1.344734 3.701766 -v -2.688888 0.000000 3.059653 -v 0.565167 0.000000 4.699830 -v -1.048728 0.000000 6.749953 -v -3.098871 0.000000 4.699830 -v -1.048728 0.000000 2.649669 -v 0.272002 -1.254753 3.102972 -v 0.451634 -1.241415 6.296688 -v -2.645577 -1.241415 6.296688 -v -2.645577 -1.254753 3.102972 -v 0.565167 -1.381248 4.699830 -v -1.048728 -1.095359 6.695808 -v -3.044745 -1.381248 4.699830 -v -1.048728 -1.095359 2.703814 -v 0.230395 -1.840604 6.069340 -v -0.224819 -1.838608 6.373538 -v -1.048728 -1.836123 6.460027 -v -1.872635 -1.838608 6.373538 -v -2.381010 -1.842505 6.068775 -v -2.722455 -1.838608 5.523713 -v -2.815062 -1.835803 4.699830 -v -2.722455 -1.838608 3.875910 -v -2.473890 -1.837158 3.292856 -v -1.872635 -1.838608 3.026104 -v -1.048728 -1.836424 2.945809 -v -0.224819 -1.838608 3.026104 -v 0.249080 -1.839079 3.311607 -v 0.460266 -1.838608 3.875910 -v 0.488186 -1.835219 4.699830 -v 0.460266 -1.838608 5.523713 -v -2.211261 -1.947312 3.554091 -v -2.412045 -1.947312 4.036575 -v -1.047553 -1.947312 4.700395 -v -2.487332 -1.947312 4.700395 -v -1.711382 -1.947312 3.335931 -v -1.047553 -1.947312 3.272222 -v -0.383728 -1.947312 3.335931 -v -0.009322 -1.947312 3.571487 -v 0.152219 -1.947312 4.036575 -v 0.162112 -1.947312 4.700395 -v 0.152219 -1.947312 5.364253 -v -0.026698 -1.947312 5.811983 -v -0.383728 -1.947312 6.064897 -v -1.047553 -1.947312 6.134404 -v -1.711382 -1.947312 6.064897 -v -2.124368 -1.947312 5.811983 -v -2.412045 -1.947312 5.364253 -v -2.412045 1.947312 4.036575 -v -2.211261 1.947312 3.554091 -v -1.047553 1.947312 4.700395 -v -2.487332 1.947312 4.700395 -v -1.711382 1.947312 3.335931 -v -1.047553 1.947312 3.272222 -v -0.383728 1.947312 3.335931 -v -0.009322 1.947312 3.571487 -v 0.152219 1.947312 4.036575 -v 0.162112 1.947312 4.700395 -v 0.152219 1.947312 5.364253 -v -0.026698 1.947312 5.811983 -v -0.383728 1.947312 6.064897 -v -1.047553 1.947312 6.134404 -v -1.711382 1.947312 6.064897 -v -2.124368 1.947312 5.811983 -v -2.412045 1.947312 5.364253 -v 0.340746 1.947312 3.944062 -v 0.147333 1.947312 3.414399 -v 0.249080 1.839079 3.311607 -v 0.460266 1.838608 3.875910 -v -0.292415 1.947312 3.146179 -v -0.224819 1.838608 3.026104 -v 0.272002 1.254753 3.102972 -v -0.050665 1.134867 2.803594 -v 0.496262 1.344734 3.701766 -v -0.292415 1.947312 6.253839 -v 0.127546 1.947312 5.965795 -v 0.230395 1.840604 6.069340 -v -0.224819 1.838608 6.373538 -v 0.340746 1.947312 5.455937 -v 0.460266 1.838608 5.523713 -v 0.451634 1.241415 6.296688 -v 0.565167 1.344734 5.697895 -v -0.050665 1.134867 6.596028 -v -2.602183 1.947312 5.455937 -v -2.274584 1.947312 5.965795 -v -2.381010 1.842505 6.068775 -v -2.722455 1.838608 5.523713 -v -1.804295 1.947312 6.253839 -v -1.872635 1.838608 6.373538 -v -2.645577 1.241415 6.296688 -v -2.046784 1.134867 6.596028 -v -2.944946 1.344734 5.697895 -v -1.804295 1.947312 3.146179 -v -2.373526 1.947312 3.394631 -v -2.473890 1.837158 3.292856 -v -1.872635 1.838608 3.026104 -v -2.602183 1.947312 3.944062 -v -2.722455 1.838608 3.875910 -v -2.645577 1.254753 3.102972 -v -2.944946 1.344734 3.701766 -v -2.046784 1.134867 2.803594 -v 0.488186 1.835219 4.699830 -v 0.362688 1.947312 4.700018 -v 0.565167 1.381248 4.699830 -v -1.048728 1.836123 6.460027 -v -1.048356 1.947312 6.332985 -v -1.048728 1.095359 6.695808 -v -2.815062 1.835803 4.699830 -v -2.687928 1.947312 4.700018 -v -3.044745 1.381248 4.699830 -v -1.048728 1.836424 2.945809 -v -1.048356 1.947312 3.073622 -v -1.048728 1.095359 2.703814 -vt 0.125000 0.049995 -vt 0.149998 0.024998 -vt 0.250000 0.125000 -vt 0.125000 0.125000 -vt 0.174995 0.000000 -vt 0.250000 0.000000 -vt 0.325005 0.000000 -vt 0.343752 0.049998 -vt 0.381945 0.074998 -vt 0.359375 0.125000 -vt 0.375000 0.200005 -vt 0.350003 0.225002 -vt 0.325005 0.250000 -vt 0.250000 0.250000 -vt 0.174995 0.250000 -vt 0.149998 0.225002 -vt 0.125000 0.200005 -vt 0.425001 0.024997 -vt 0.434375 0.062497 -vt 0.412503 0.000000 -vt 0.500000 0.000000 -vt 0.500000 0.024997 -vt 0.500000 0.062497 -vt 0.375000 0.299995 -vt 0.375000 0.250000 -vt 0.437500 0.250000 -vt 0.437500 0.306247 -vt 0.437500 0.193752 -vt 0.500000 0.193752 -vt 0.500000 0.250000 -vt 0.500000 0.306247 -vt 0.375000 0.549995 -vt 0.375000 0.500000 -vt 0.437500 0.500000 -vt 0.437500 0.556247 -vt 0.375000 0.450005 -vt 0.437500 0.443752 -vt 0.500000 0.443752 -vt 0.500000 0.500000 -vt 0.500000 0.556247 -vt 0.375000 0.799995 -vt 0.375000 0.750000 -vt 0.437500 0.750000 -vt 0.437500 0.806248 -vt 0.375000 0.700005 -vt 0.437500 0.693753 -vt 0.500000 0.693752 -vt 0.500000 0.750000 -vt 0.500000 0.806247 -vt 0.437500 0.125000 -vt 0.500000 0.125000 -vt 0.437500 0.375000 -vt 0.375000 0.375000 -vt 0.500000 0.375000 -vt 0.437500 0.625000 -vt 0.375000 0.625000 -vt 0.500000 0.625000 -vt 0.437500 0.875000 -vt 0.375000 0.875000 -vt 0.500000 0.875000 -vt 0.500000 0.950005 -vt 0.437500 0.950005 -vt 0.375000 0.950005 -vt 0.382829 0.250000 -vt 0.382974 0.300793 -vt 0.383157 0.375000 -vt 0.382974 0.449207 -vt 0.382688 0.500000 -vt 0.382974 0.550793 -vt 0.383180 0.625000 -vt 0.382974 0.699207 -vt 0.383080 0.750000 -vt 0.382974 0.800793 -vt 0.383134 0.875000 -vt 0.336169 0.000000 -vt 0.382974 0.950005 -vt 0.354074 0.046822 -vt 0.388635 0.073403 -vt 0.369655 0.125000 -vt 0.382974 0.199207 -vt 0.125000 0.049995 -vt 0.149998 0.024998 -vt 0.125000 0.125000 -vt 0.174995 0.000000 -vt 0.250000 0.000000 -vt 0.325005 0.000000 -vt 0.343752 0.049998 -vt 0.381945 0.074998 -vt 0.359375 0.125000 -vt 0.375000 0.200005 -vt 0.350003 0.225002 -vt 0.325005 0.250000 -vt 0.250000 0.250000 -vt 0.174995 0.250000 -vt 0.149998 0.225002 -vt 0.125000 0.200005 -vt 0.125000 0.049995 -vt 0.149998 0.024998 -vt 0.250000 0.125000 -vt 0.125000 0.125000 -vt 0.174995 0.000000 -vt 0.250000 0.000000 -vt 0.325005 0.000000 -vt 0.343752 0.049998 -vt 0.381945 0.074998 -vt 0.359375 0.125000 -vt 0.375000 0.200005 -vt 0.350003 0.225002 -vt 0.325005 0.250000 -vt 0.250000 0.250000 -vt 0.174995 0.250000 -vt 0.149998 0.225002 -vt 0.125000 0.200005 -vt 0.381945 0.074998 -vt 0.343752 0.049998 -vt 0.354074 0.046822 -vt 0.388635 0.073403 -vt 0.325005 0.000000 -vt 0.336169 0.000000 -vt 0.425001 0.024997 -vt 0.412503 0.000000 -vt 0.500000 0.000000 -vt 0.500000 0.024997 -vt 0.434375 0.062497 -vt 0.500000 0.062497 -vt 0.375000 0.299995 -vt 0.375000 0.250000 -vt 0.382829 0.250000 -vt 0.382974 0.300793 -vt 0.375000 0.200005 -vt 0.382974 0.199207 -vt 0.437500 0.250000 -vt 0.437500 0.193752 -vt 0.500000 0.193752 -vt 0.500000 0.250000 -vt 0.437500 0.306247 -vt 0.500000 0.306247 -vt 0.375000 0.549995 -vt 0.375000 0.500000 -vt 0.382688 0.500000 -vt 0.382974 0.550793 -vt 0.375000 0.450005 -vt 0.382974 0.449207 -vt 0.437500 0.500000 -vt 0.437500 0.443752 -vt 0.500000 0.443752 -vt 0.500000 0.500000 -vt 0.437500 0.556247 -vt 0.500000 0.556247 -vt 0.375000 0.799995 -vt 0.375000 0.750000 -vt 0.383080 0.750000 -vt 0.382974 0.800793 -vt 0.375000 0.700005 -vt 0.382974 0.699207 -vt 0.437500 0.750000 -vt 0.437500 0.693753 -vt 0.500000 0.693752 -vt 0.500000 0.750000 -vt 0.437500 0.806248 -vt 0.500000 0.806247 -vt 0.369655 0.125000 -vt 0.359375 0.125000 -vt 0.500000 0.125000 -vt 0.437500 0.125000 -vt 0.383157 0.375000 -vt 0.375000 0.375000 -vt 0.500000 0.375000 -vt 0.437500 0.375000 -vt 0.383180 0.625000 -vt 0.375000 0.625000 -vt 0.500000 0.625000 -vt 0.437500 0.625000 -vt 0.383134 0.875000 -vt 0.375000 0.875000 -vt 0.500000 0.875000 -vt 0.437500 0.875000 -vt 0.500000 0.950005 -vt 0.437500 0.950005 -vt 0.382974 0.950005 -vt 0.375000 0.950005 -vt 0.125000 0.049995 -vt 0.149998 0.024998 -vt 0.125000 0.125000 -vt 0.174995 0.000000 -vt 0.250000 0.000000 -vt 0.350003 0.225002 -vt 0.325005 0.250000 -vt 0.250000 0.250000 -vt 0.174995 0.250000 -vt 0.149998 0.225002 -vt 0.125000 0.200005 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.369150 -0.927872 -0.052747 -vn 0.288204 -0.931150 -0.223380 -vn 0.745175 -0.375681 -0.550980 -vn 0.944586 -0.287342 -0.158719 -vn 0.093652 -0.928730 -0.358734 -vn 0.218017 -0.406729 -0.887153 -vn 0.832705 -0.121154 -0.540300 -vn 0.289760 -0.148840 -0.945455 -vn 0.295795 0.000000 -0.955251 -vn 0.865366 0.000000 -0.501140 -vn 0.983650 -0.047100 -0.173823 -vn 0.986348 0.000000 -0.164677 -vn 0.102438 -0.927886 0.358516 -vn 0.281454 -0.934302 0.218778 -vn 0.663836 -0.490699 0.564390 -vn 0.217141 -0.420056 0.881137 -vn 0.369832 -0.927268 0.058302 -vn 0.919008 -0.373425 0.126403 -vn 0.818540 -0.160309 0.551628 -vn 0.992732 -0.085094 0.085098 -vn 0.998414 -0.000000 0.056304 -vn 0.841401 -0.000000 0.540412 -vn 0.261404 -0.156882 0.952395 -vn 0.262154 -0.000000 0.965026 -vn -0.348905 -0.931447 0.103307 -vn -0.239836 -0.940353 0.241277 -vn -0.557100 -0.532787 0.637006 -vn -0.806110 -0.537863 0.246758 -vn -0.095914 -0.930037 0.354728 -vn -0.207238 -0.423510 0.881869 -vn -0.697405 -0.186405 0.692011 -vn -0.246384 -0.158616 0.956105 -vn -0.247041 0.000000 0.969005 -vn -0.714317 -0.000000 0.699822 -vn -0.952390 -0.168175 0.254304 -vn -0.970620 -0.000000 0.240616 -vn -0.078121 -0.932843 -0.351711 -vn -0.260646 -0.929952 -0.259330 -vn -0.578787 -0.490664 -0.651349 -vn -0.187762 -0.413080 -0.891129 -vn -0.350656 -0.933247 -0.078044 -vn -0.830529 -0.514539 -0.213241 -vn -0.694840 -0.169758 -0.698842 -vn -0.957677 -0.153172 -0.243707 -vn -0.970553 0.000000 -0.240890 -vn -0.714291 0.000000 -0.699849 -vn -0.240500 -0.151827 -0.958701 -vn -0.247362 0.000000 -0.968923 -vn 0.952213 -0.305089 -0.014557 -vn 0.351994 -0.936002 0.000007 -vn 0.999420 0.000000 -0.034044 -vn 0.998740 -0.040128 -0.030123 -vn -0.000015 -0.386106 0.922455 -vn 0.000049 -0.933185 0.359396 -vn 0.000000 -0.000000 1.000000 -vn -0.000000 -0.145694 0.989330 -vn -0.857214 -0.514960 -0.000011 -vn -0.359155 -0.933278 0.000027 -vn -1.000000 0.000000 0.000000 -vn -0.988961 -0.148177 0.000000 -vn -0.000014 -0.389360 -0.921086 -vn 0.000045 -0.934128 -0.356938 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 -0.146987 -0.989138 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.369150 0.927872 -0.052747 -vn 0.944586 0.287342 -0.158719 -vn 0.745175 0.375681 -0.550980 -vn 0.288204 0.931150 -0.223380 -vn 0.218017 0.406729 -0.887153 -vn 0.093652 0.928730 -0.358734 -vn 0.832705 0.121154 -0.540301 -vn 0.289760 0.148840 -0.945455 -vn 0.983650 0.047100 -0.173823 -vn 0.102438 0.927886 0.358517 -vn 0.217141 0.420056 0.881137 -vn 0.663836 0.490699 0.564390 -vn 0.281454 0.934302 0.218778 -vn 0.919008 0.373425 0.126402 -vn 0.369832 0.927268 0.058302 -vn 0.818540 0.160309 0.551628 -vn 0.992732 0.085094 0.085098 -vn 0.261404 0.156882 0.952395 -vn -0.348905 0.931447 0.103307 -vn -0.806110 0.537863 0.246758 -vn -0.557100 0.532788 0.637006 -vn -0.239836 0.940353 0.241277 -vn -0.207237 0.423510 0.881869 -vn -0.095914 0.930037 0.354728 -vn -0.697405 0.186405 0.692011 -vn -0.246384 0.158616 0.956105 -vn -0.952390 0.168175 0.254304 -vn -0.078121 0.932843 -0.351711 -vn -0.187763 0.413080 -0.891129 -vn -0.578787 0.490664 -0.651349 -vn -0.260646 0.929952 -0.259330 -vn -0.830528 0.514539 -0.213241 -vn -0.350656 0.933247 -0.078044 -vn -0.694840 0.169758 -0.698842 -vn -0.957677 0.153172 -0.243707 -vn -0.240500 0.151827 -0.958701 -vn 0.351994 0.936002 0.000007 -vn 0.952213 0.305089 -0.014557 -vn 0.998740 0.040128 -0.030123 -vn 0.000049 0.933185 0.359396 -vn -0.000015 0.386106 0.922455 -vn 0.000000 0.145694 0.989330 -vn -0.359155 0.933278 0.000027 -vn -0.857214 0.514960 -0.000011 -vn -0.988961 0.148177 0.000000 -vn 0.000045 0.934128 -0.356938 -vn -0.000014 0.389360 -0.921086 -vn 0.000000 0.146987 -0.989138 -s 1 -g head_geo -usemtl blinn2SG -f 516/859/935 515/860/936 517/781/937 518/861/938 -f 519/862/939 520/863/940 517/781/937 515/860/936 -f 521/864/941 522/865/942 517/781/937 520/863/940 -f 523/866/943 524/867/944 517/781/937 522/865/942 -f 525/868/945 526/869/946 517/781/937 524/867/944 -f 527/870/947 528/871/948 517/781/937 526/869/946 -f 529/872/949 530/873/950 517/781/937 528/871/948 -f 531/874/951 518/861/938 517/781/937 530/873/950 -f 452/787/952 470/786/953 511/855/954 512/856/955 -f 470/786/953 451/785/956 510/853/957 511/855/954 -f 491/796/958 476/798/959 454/799/960 477/800/961 -f 475/797/962 491/796/958 477/800/961 453/801/963 -f 455/802/964 472/803/965 499/842/966 500/843/967 -f 472/803/965 456/789/968 514/858/969 499/842/966 -f 492/804/970 479/806/971 457/807/972 480/808/973 -f 478/805/974 492/804/970 480/808/973 458/809/975 -f 459/810/976 474/811/977 503/846/978 504/847/979 -f 474/811/977 460/814/980 502/845/981 503/846/978 -f 493/812/982 482/815/983 461/816/984 483/817/985 -f 481/813/986 493/812/982 483/817/985 462/818/987 -f 463/819/988 467/820/989 507/850/990 508/851/991 -f 467/820/989 464/823/992 506/849/993 507/850/990 -f 494/821/994 485/824/995 465/825/996 486/826/997 -f 484/822/998 494/821/994 486/826/997 466/827/999 -f 452/787/952 512/856/955 513/857/1000 471/788/1001 -f 475/797/962 453/801/963 487/829/1002 495/828/1003 -f 495/828/1003 487/829/1002 457/807/972 479/806/971 -f 471/788/1001 513/857/1000 514/858/969 456/789/968 -f 455/802/964 500/843/967 501/844/1004 473/831/1005 -f 478/805/974 458/809/975 488/832/1006 496/830/1007 -f 496/830/1007 488/832/1006 461/816/984 482/815/983 -f 473/831/1005 501/844/1004 502/845/981 460/814/980 -f 459/810/976 504/847/979 505/848/1008 468/834/1009 -f 481/813/986 462/818/987 489/835/1010 497/833/1011 -f 497/833/1011 489/835/1010 465/825/996 485/824/995 -f 468/834/1009 505/848/1008 506/849/993 464/823/992 -f 463/819/988 508/851/991 509/852/1012 469/837/1013 -f 484/822/998 466/827/999 490/838/1014 498/836/1015 -f 498/836/1015 490/838/1014 454/839/960 476/840/959 -f 469/837/1013 509/852/1012 510/854/957 451/841/956 -f 500/843/967 499/842/966 492/804/970 478/805/974 -f 501/844/1004 500/843/967 478/805/974 496/830/1007 -f 502/845/981 501/844/1004 496/830/1007 482/815/983 -f 503/846/978 502/845/981 482/815/983 493/812/982 -f 504/847/979 503/846/978 493/812/982 481/813/986 -f 505/848/1008 504/847/979 481/813/986 497/833/1011 -f 506/849/993 505/848/1008 497/833/1011 485/824/995 -f 507/850/990 506/849/993 485/824/995 494/821/994 -f 508/851/991 507/850/990 494/821/994 484/822/998 -f 509/852/1012 508/851/991 484/822/998 498/836/1015 -f 510/854/957 509/852/1012 498/836/1015 476/840/959 -f 511/855/954 510/853/957 476/798/959 491/796/958 -f 512/856/955 511/855/954 491/796/958 475/797/962 -f 513/857/1000 512/856/955 475/797/962 495/828/1003 -f 514/858/969 513/857/1000 495/828/1003 479/806/971 -f 499/842/966 514/858/969 479/806/971 492/804/970 -f 464/779/992 467/780/989 515/860/936 516/859/935 -f 468/782/1009 464/779/992 516/859/935 518/861/938 -f 463/783/988 469/784/1013 520/863/940 519/862/939 -f 467/780/989 463/783/988 519/862/939 515/860/936 -f 451/785/956 470/786/953 522/865/942 521/864/941 -f 469/784/1013 451/785/956 521/864/941 520/863/940 -f 452/787/952 471/788/1001 524/867/944 523/866/943 -f 470/786/953 452/787/952 523/866/943 522/865/942 -f 456/789/968 472/790/965 526/869/946 525/868/945 -f 471/788/1001 456/789/968 525/868/945 524/867/944 -f 455/791/964 473/792/1005 528/871/948 527/870/947 -f 472/790/965 455/791/964 527/870/947 526/869/946 -f 460/793/980 474/794/977 530/873/950 529/872/949 -f 473/792/1005 460/793/980 529/872/949 528/871/948 -f 459/795/976 468/782/1009 518/861/938 531/874/951 -f 474/794/977 459/795/976 531/874/951 530/873/950 -f 532/875/1016 535/878/1017 534/877/1018 533/876/1019 -f 536/879/1020 533/876/1019 534/877/1018 537/880/1021 -f 538/881/1022 537/880/1021 534/877/1018 539/882/1023 -f 540/883/1024 539/882/1023 534/877/1018 541/884/1025 -f 542/885/1026 541/884/1025 534/877/1018 543/886/1027 -f 544/887/1028 543/886/1027 534/877/1018 545/888/1029 -f 546/889/1030 545/888/1029 534/877/1018 547/890/1031 -f 548/891/1032 547/890/1031 534/877/1018 535/878/1017 -f 549/892/1033 552/895/1034 551/894/1035 550/893/1036 -f 550/893/1036 551/894/1035 554/897/1037 553/896/1038 -f 555/898/1039 477/901/961 454/900/960 556/899/1040 -f 557/902/1041 453/903/963 477/901/961 555/898/1039 -f 558/904/1042 561/907/1043 560/906/1044 559/905/1045 -f 559/905/1045 560/906/1044 563/909/1046 562/908/1047 -f 564/910/1048 480/913/973 457/912/972 565/911/1049 -f 566/914/1050 458/915/975 480/913/973 564/910/1048 -f 567/916/1051 570/919/1052 569/918/1053 568/917/1054 -f 568/917/1054 569/918/1053 572/921/1055 571/920/1056 -f 573/922/1057 483/925/985 461/924/984 574/923/1058 -f 575/926/1059 462/927/987 483/925/985 573/922/1057 -f 576/928/1060 579/931/1061 578/930/1062 577/929/1063 -f 577/929/1063 578/930/1062 581/933/1064 580/932/1065 -f 582/934/1066 486/937/997 465/936/996 583/935/1067 -f 584/938/1068 466/939/999 486/937/997 582/934/1066 -f 549/892/1033 586/941/1069 585/940/1070 552/895/1034 -f 557/902/1041 587/943/1071 487/942/1002 453/903/963 -f 587/943/1071 565/911/1049 457/912/972 487/942/1002 -f 586/941/1069 562/908/1047 563/909/1046 585/940/1070 -f 558/904/1042 589/945/1072 588/944/1073 561/907/1043 -f 566/914/1050 590/947/1074 488/946/1006 458/915/975 -f 590/947/1074 574/923/1058 461/924/984 488/946/1006 -f 589/945/1072 571/920/1056 572/921/1055 588/944/1073 -f 567/916/1051 592/949/1075 591/948/1076 570/919/1052 -f 575/926/1059 593/951/1077 489/950/1010 462/927/987 -f 593/951/1077 583/935/1067 465/936/996 489/950/1010 -f 592/949/1075 580/932/1065 581/933/1064 591/948/1076 -f 576/928/1060 595/953/1078 594/952/1079 579/931/1061 -f 584/938/1068 596/955/1080 490/954/1014 466/939/999 -f 596/955/1080 556/957/1040 454/956/960 490/954/1014 -f 595/953/1078 553/959/1038 554/958/1037 594/952/1079 -f 561/907/1043 566/914/1050 564/910/1048 560/906/1044 -f 588/944/1073 590/947/1074 566/914/1050 561/907/1043 -f 572/921/1055 574/923/1058 590/947/1074 588/944/1073 -f 569/918/1053 573/922/1057 574/923/1058 572/921/1055 -f 570/919/1052 575/926/1059 573/922/1057 569/918/1053 -f 591/948/1076 593/951/1077 575/926/1059 570/919/1052 -f 581/933/1064 583/935/1067 593/951/1077 591/948/1076 -f 578/930/1062 582/934/1066 583/935/1067 581/933/1064 -f 579/931/1061 584/938/1068 582/934/1066 578/930/1062 -f 594/952/1079 596/955/1080 584/938/1068 579/931/1061 -f 554/958/1037 556/957/1040 596/955/1080 594/952/1079 -f 551/894/1035 555/898/1039 556/899/1040 554/897/1037 -f 552/895/1034 557/902/1041 555/898/1039 551/894/1035 -f 585/940/1070 587/943/1071 557/902/1041 552/895/1034 -f 563/909/1046 565/911/1049 587/943/1071 585/940/1070 -f 560/906/1044 564/910/1048 565/911/1049 563/909/1046 -f 580/960/1065 532/875/1016 533/876/1019 577/961/1063 -f 592/962/1075 535/878/1017 532/875/1016 580/960/1065 -f 576/963/1060 536/879/1020 537/880/1021 595/964/1078 -f 577/961/1063 533/876/1019 536/879/1020 576/963/1060 -f 553/896/1038 538/881/1022 539/882/1023 550/893/1036 -f 595/964/1078 537/880/1021 538/881/1022 553/896/1038 -f 549/892/1033 540/883/1024 541/884/1025 586/941/1069 -f 550/893/1036 539/882/1023 540/883/1024 549/892/1033 -f 562/908/1047 542/885/1026 543/886/1027 559/965/1045 -f 586/941/1069 541/884/1025 542/885/1026 562/908/1047 -f 558/966/1042 544/887/1028 545/888/1029 589/967/1072 -f 559/965/1045 543/886/1027 544/887/1028 558/966/1042 -f 571/968/1056 546/889/1030 547/890/1031 568/969/1054 -f 589/967/1072 545/888/1029 546/889/1030 571/968/1056 -f 567/970/1051 548/891/1032 535/878/1017 592/962/1075 -f 568/969/1054 547/890/1031 548/891/1032 567/970/1051 -g default -v -3.937325 -2.740168 4.115081 -v -4.079747 -2.740168 4.257522 -v -4.131877 -2.740168 4.452075 -v -4.079747 -2.740168 4.646626 -v -3.937325 -2.740168 4.789030 -v -3.742772 -2.740168 4.841179 -v -3.548220 -2.740168 4.789030 -v -3.405798 -2.740168 4.646626 -v -3.353668 -2.740168 4.452075 -v -3.405798 -2.740168 4.257522 -v -3.548220 -2.740168 4.115081 -v -3.742772 -2.740168 4.062970 -v -3.937325 -1.802424 4.115081 -v -4.079747 -1.802424 4.257522 -v -4.131877 -1.802424 4.452075 -v -4.079747 -1.802424 4.646626 -v -3.937325 -1.802424 4.789030 -v -3.742772 -1.802424 4.841179 -v -3.548220 -1.802424 4.789030 -v -3.405798 -1.802424 4.646626 -v -3.353668 -1.802424 4.452075 -v -3.405798 -1.802424 4.257522 -v -3.548220 -1.802424 4.115081 -v -3.742772 -1.802424 4.062970 -v -3.906242 -2.803350 4.168925 -v -4.025922 -2.803350 4.288586 -v -3.742772 -2.803350 4.452075 -v -4.069712 -2.803350 4.452075 -v -4.025922 -2.803350 4.615525 -v -3.906242 -2.803350 4.735224 -v -3.742772 -2.803350 4.779014 -v -3.579302 -2.803350 4.735224 -v -3.459623 -2.803350 4.615525 -v -3.415833 -2.803350 4.452075 -v -3.459623 -2.803350 4.288586 -v -3.579302 -2.803350 4.168925 -v -3.742772 -2.803350 4.125097 -v -3.405798 -2.086929 4.646626 -v -3.548220 -2.086929 4.789030 -v -3.742772 -2.086929 4.841179 -v -3.937325 -2.086929 4.789030 -v -4.079747 -2.086929 4.646626 -v -4.131877 -2.086929 4.452075 -v -4.079747 -2.086929 4.257522 -v -3.937325 -2.086929 4.115081 -v -3.742772 -2.086929 4.062970 -v -3.548220 -2.086929 4.115081 -v -3.405798 -2.086929 4.257522 -v -3.353668 -2.086929 4.452075 -v -3.405798 -2.562936 4.646626 -v -3.548220 -2.562936 4.789030 -v -3.742772 -2.562936 4.841179 -v -3.937325 -2.562936 4.789030 -v -4.079747 -2.562936 4.646626 -v -4.131877 -2.562936 4.452075 -v -4.079747 -2.562936 4.257522 -v -3.937325 -2.562936 4.115081 -v -3.742772 -2.562936 4.062970 -v -3.548220 -2.562936 4.115081 -v -3.405798 -2.562936 4.257522 -v -3.353668 -2.562936 4.452075 -v -2.692145 -2.086929 4.562322 -v -2.692145 -2.086929 4.704763 -v -2.692145 -2.086929 4.030814 -v -2.692145 -2.086929 4.173217 -v -2.692145 -2.086929 4.367770 -v -2.692145 -2.562936 4.704763 -v -2.692145 -2.562936 4.562322 -v -2.692145 -2.562936 4.030814 -v -2.692145 -2.562936 4.173217 -v -2.692145 -2.562936 4.367770 -v 0.819625 -2.086929 4.989644 -v 0.819625 -2.086929 5.132047 -v 0.819625 -2.086929 4.458099 -v 0.819625 -2.086929 4.600540 -v 0.819625 -2.086929 4.795092 -v 0.819625 -2.562936 5.132047 -v 0.819625 -2.562936 4.989644 -v 0.819625 -2.562936 4.458099 -v 0.819625 -2.562936 4.600540 -v 0.819625 -2.562936 4.795092 -v 1.216317 -2.086929 4.877251 -v 1.259166 -2.086929 5.013064 -v 1.056386 -2.086929 4.370330 -v 1.099235 -2.086929 4.506182 -v 1.157785 -2.086929 4.691697 -v 1.259166 -2.504857 5.013064 -v 1.216317 -2.504857 4.877251 -v 1.056386 -2.504857 4.370330 -v 1.099235 -2.504857 4.506182 -v 1.157785 -2.504857 4.691697 -v 2.581139 -1.733218 3.366467 -v 2.623988 -1.733218 3.502281 -v 2.421189 -1.733218 2.859584 -v 2.464038 -1.733218 2.995398 -v 2.522589 -1.733218 3.180933 -v 2.623988 -2.019982 3.502281 -v 2.581139 -2.019982 3.366467 -v 2.421189 -2.019982 2.859584 -v 2.464038 -2.019982 2.995398 -v 2.522589 -2.019982 3.180933 -v 2.029242 -2.127575 3.977385 -v 2.072072 -2.127575 4.113199 -v 2.072072 -1.764262 4.113199 -v 2.029242 -1.764262 3.977385 -v 1.970692 -1.764262 3.791869 -v 1.912160 -1.764262 3.606316 -v 1.869311 -1.764262 3.470502 -v 1.869311 -2.127575 3.470502 -v 1.912160 -2.127575 3.606316 -v 1.970692 -2.127575 3.791869 -vt 0.635316 0.078125 -vt 0.578125 0.020934 -vt 0.500000 0.000000 -vt 0.421875 0.020934 -vt 0.364684 0.078125 -vt 0.343750 0.156250 -vt 0.364684 0.234375 -vt 0.421875 0.291566 -vt 0.500000 0.312500 -vt 0.578125 0.291566 -vt 0.635316 0.234375 -vt 0.656250 0.156250 -vt 0.375000 0.312500 -vt 0.395833 0.312500 -vt 0.416667 0.312500 -vt 0.437500 0.312500 -vt 0.458333 0.312500 -vt 0.479167 0.312500 -vt 0.500000 0.312500 -vt 0.520833 0.312500 -vt 0.541667 0.312500 -vt 0.562500 0.312500 -vt 0.583333 0.312500 -vt 0.604167 0.312500 -vt 0.625000 0.312500 -vt 0.375000 0.688440 -vt 0.395833 0.688440 -vt 0.416667 0.688440 -vt 0.437500 0.688440 -vt 0.458333 0.688440 -vt 0.479167 0.688440 -vt 0.500000 0.688440 -vt 0.520833 0.688440 -vt 0.541667 0.688440 -vt 0.562500 0.688440 -vt 0.583333 0.688440 -vt 0.604167 0.688440 -vt 0.625000 0.688440 -vt 0.500000 0.150000 -vt 0.578125 0.020934 -vt 0.635316 0.078125 -vt 0.500000 0.000000 -vt 0.421875 0.020934 -vt 0.364684 0.078125 -vt 0.343750 0.156250 -vt 0.364684 0.234375 -vt 0.421875 0.291566 -vt 0.500000 0.312500 -vt 0.578125 0.291566 -vt 0.635316 0.234375 -vt 0.656250 0.156250 -vt 0.520833 0.558498 -vt 0.500000 0.558498 -vt 0.479167 0.558498 -vt 0.458333 0.558498 -vt 0.437500 0.558498 -vt 0.416667 0.558498 -vt 0.395833 0.558498 -vt 0.625000 0.558498 -vt 0.375000 0.558498 -vt 0.604167 0.558498 -vt 0.583333 0.558498 -vt 0.562500 0.558498 -vt 0.541667 0.558498 -vt 0.520833 0.430310 -vt 0.500000 0.430310 -vt 0.479167 0.430310 -vt 0.458333 0.430310 -vt 0.437500 0.430310 -vt 0.416667 0.430310 -vt 0.395833 0.430310 -vt 0.625000 0.430310 -vt 0.375000 0.430310 -vt 0.604167 0.430310 -vt 0.583333 0.430310 -vt 0.562500 0.430310 -vt 0.541667 0.430310 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vn -0.488213 -0.215869 -0.845605 -vn -0.845616 -0.215890 -0.488186 -vn -0.866037 0.000000 -0.499979 -vn -0.500001 0.000000 -0.866025 -vn -0.976418 -0.215891 -0.000000 -vn -1.000000 0.000000 0.000000 -vn -0.845587 -0.215895 0.488234 -vn -0.866013 0.000000 0.500022 -vn -0.488219 -0.215887 0.845598 -vn -0.500000 0.000000 0.866025 -vn 0.000000 -0.215855 0.976425 -vn -0.000000 0.000000 1.000000 -vn 0.488218 -0.215887 0.845598 -vn 0.174271 -0.081123 0.981350 -vn 0.845586 -0.215896 0.488234 -vn 0.217027 -0.968089 0.125309 -vn 0.976417 -0.215891 -0.000000 -vn 0.215967 -0.976401 0.000000 -vn 0.845616 -0.215890 -0.488186 -vn 0.199491 -0.973108 -0.115171 -vn 0.488213 -0.215869 -0.845606 -vn 0.033994 -0.117459 -0.992496 -vn -0.000000 -0.215876 -0.976421 -vn 0.000000 0.000000 -1.000000 -vn -0.296183 -0.939699 -0.171000 -vn -0.170990 -0.939712 -0.296147 -vn 0.000000 -1.000000 0.000000 -vn -0.341978 -0.939708 0.000001 -vn -0.296169 -0.939708 0.170978 -vn -0.170999 -0.939699 0.296185 -vn 0.000000 -0.939702 0.341994 -vn 0.170999 -0.939699 0.296185 -vn 0.296169 -0.939708 0.170978 -vn 0.341978 -0.939708 0.000001 -vn 0.296183 -0.939699 -0.171000 -vn 0.170990 -0.939712 -0.296147 -vn -0.000000 -0.939695 -0.342013 -vn 0.197270 0.075896 0.977407 -vn 0.332320 0.923443 0.191876 -vn 0.866013 0.000000 0.500022 -vn 0.500001 0.000000 0.866025 -vn -0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn -0.500000 0.000000 0.866025 -vn -0.500001 0.000000 0.866025 -vn -0.866013 0.000000 0.500022 -vn -0.866013 0.000000 0.500022 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -0.866037 0.000000 -0.499979 -vn -0.866037 0.000000 -0.499979 -vn -0.500001 0.000000 -0.866025 -vn -0.500001 0.000000 -0.866025 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.066632 0.110243 -0.991669 -vn 0.500001 0.000000 -0.866025 -vn 0.307626 0.934786 -0.177598 -vn 0.866037 0.000000 -0.499979 -vn 0.334599 0.942361 0.000000 -vn 1.000000 0.000000 0.000000 -vn -0.074734 0.298010 0.951633 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.075503 0.264515 -0.961421 -vn 0.000000 1.000000 0.000000 -vn -0.074734 -0.298010 0.951633 -vn 0.000000 -1.000000 0.000000 -vn 0.075503 -0.264515 -0.961421 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn -0.077316 0.263555 0.961541 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.087390 0.311498 -0.946220 -vn 0.000000 1.000000 0.000000 -vn -0.076710 -0.265845 0.960959 -vn 0.014300 -0.999895 -0.002202 -vn 0.096240 -0.313314 -0.944761 -vn 0.015146 -0.999883 -0.002333 -vn 0.014685 -0.999890 -0.002262 -vn 0.587020 0.216157 0.780182 -vn -0.205416 0.976527 0.064802 -vn -0.225446 0.971656 0.071129 -vn -0.702219 0.324273 -0.633826 -vn -0.215345 0.974171 0.067947 -vn 0.621687 -0.259265 0.739112 -vn 0.274712 -0.958162 -0.080366 -vn -0.479744 -0.442211 -0.757823 -vn 0.296644 -0.950985 -0.087346 -vn 0.285657 -0.954657 -0.083849 -vn 0.629835 0.382153 0.676215 -vn -0.194106 0.979067 0.061240 -vn -0.182364 0.981546 0.057533 -vn -0.730614 0.323904 -0.601074 -vn -0.188301 0.980313 0.059415 -vn 0.759049 -0.295389 0.580165 -vn 0.258127 -0.962672 -0.081439 -vn -0.668761 -0.288778 -0.685103 -vn 0.249404 -0.965198 -0.078684 -vn 0.253810 -0.963933 -0.080086 -vn 0.142853 -0.988717 -0.045077 -vn 0.711653 -0.409577 0.570787 -vn 0.645476 0.463960 0.606714 -vn -0.041649 0.999046 0.013143 -vn -0.041650 0.999046 0.013143 -vn -0.041652 0.999046 0.013142 -vn -0.725245 0.247163 -0.642597 -vn -0.701661 -0.230015 -0.674362 -vn 0.142862 -0.988716 -0.045074 -vn 0.142856 -0.988717 -0.045077 -s 1 -g uprArm_geo -usemtl blinn2SG -f 597/983/1081 598/984/1082 652/1041/1083 653/1043/1084 -f 598/984/1082 599/985/1085 651/1040/1086 652/1041/1083 -f 599/985/1085 600/986/1087 650/1039/1088 651/1040/1086 -f 600/986/1087 601/987/1089 649/1038/1090 650/1039/1088 -f 601/987/1089 602/988/1091 648/1037/1092 649/1038/1090 -f 602/988/1091 603/989/1093 647/1036/1094 648/1037/1092 -f 603/989/1093 604/990/1095 646/1035/1096 647/1036/1094 -f 604/990/1095 605/991/1097 657/1047/1098 646/1035/1096 -f 605/991/1097 606/992/1099 656/1046/1100 657/1047/1098 -f 606/992/1099 607/993/1101 655/1045/1102 656/1046/1100 -f 607/993/1101 608/994/1103 654/1044/1104 655/1045/1102 -f 608/994/1103 597/995/1081 653/1042/1084 654/1044/1104 -f 622/1010/1105 621/1011/1106 623/1009/1107 -f 624/1012/1108 622/1010/1105 623/1009/1107 -f 625/1013/1109 624/1012/1108 623/1009/1107 -f 626/1014/1110 625/1013/1109 623/1009/1107 -f 627/1015/1111 626/1014/1110 623/1009/1107 -f 628/1016/1112 627/1015/1111 623/1009/1107 -f 629/1017/1113 628/1016/1112 623/1009/1107 -f 630/1018/1114 629/1017/1113 623/1009/1107 -f 631/1019/1115 630/1018/1114 623/1009/1107 -f 632/1020/1116 631/1019/1115 623/1009/1107 -f 633/1021/1117 632/1020/1116 623/1009/1107 -f 621/1011/1106 633/1021/1117 623/1009/1107 -f 598/972/1082 597/971/1081 621/1011/1106 622/1010/1105 -f 599/973/1085 598/972/1082 622/1010/1105 624/1012/1108 -f 600/974/1087 599/973/1085 624/1012/1108 625/1013/1109 -f 601/975/1089 600/974/1087 625/1013/1109 626/1014/1110 -f 602/976/1091 601/975/1089 626/1014/1110 627/1015/1111 -f 603/977/1093 602/976/1091 627/1015/1111 628/1016/1112 -f 604/978/1095 603/977/1093 628/1016/1112 629/1017/1113 -f 605/979/1097 604/978/1095 629/1017/1113 630/1018/1114 -f 606/980/1099 605/979/1097 630/1018/1114 631/1019/1115 -f 607/981/1101 606/980/1099 631/1019/1115 632/1020/1116 -f 608/982/1103 607/981/1101 632/1020/1116 633/1021/1117 -f 597/971/1081 608/982/1103 633/1021/1117 621/1011/1106 -f 635/1023/1118 634/1022/1119 616/1003/1120 615/1002/1121 -f 636/1024/1122 635/1023/1118 615/1002/1121 614/1001/1123 -f 637/1025/1124 636/1024/1122 614/1001/1123 613/1000/1125 -f 638/1026/1126 637/1025/1124 613/1000/1125 612/999/1127 -f 639/1027/1128 638/1026/1126 612/999/1127 611/998/1129 -f 640/1028/1130 639/1027/1128 611/998/1129 610/997/1131 -f 641/1030/1132 640/1028/1130 610/997/1131 609/996/1133 -f 642/1031/1134 641/1029/1132 609/1008/1133 620/1007/1135 -f 643/1032/1136 642/1031/1134 620/1007/1135 619/1006/1137 -f 644/1033/1138 643/1032/1136 619/1006/1137 618/1005/1139 -f 645/1034/1140 644/1033/1138 618/1005/1139 617/1004/1141 -f 634/1022/1119 645/1034/1140 617/1004/1141 616/1003/1120 -f 648/1037/1092 647/1036/1094 635/1023/1118 636/1024/1122 -f 649/1038/1090 648/1037/1092 636/1024/1122 637/1025/1124 -f 650/1039/1088 649/1038/1090 637/1025/1124 638/1026/1126 -f 651/1040/1086 650/1039/1088 638/1026/1126 639/1027/1128 -f 652/1041/1083 651/1040/1086 639/1027/1128 640/1028/1130 -f 653/1043/1084 652/1041/1083 640/1028/1130 641/1030/1132 -f 654/1044/1104 653/1042/1084 641/1029/1132 642/1031/1134 -f 655/1045/1102 654/1044/1104 642/1031/1134 643/1032/1136 -f 634/1048/1119 635/1049/1118 659/1050/1142 658/1051/1143 -f 643/1052/1136 644/1053/1138 661/1054/1144 660/1055/1145 -f 644/1056/1138 645/1057/1140 662/1058/1146 661/1059/1144 -f 645/1060/1140 634/1061/1119 658/1062/1143 662/1063/1146 -f 635/1064/1118 647/1065/1094 663/1066/1147 659/1067/1142 -f 647/1068/1094 646/1069/1096 664/1070/1148 663/1071/1147 -f 655/1072/1102 643/1073/1136 660/1074/1145 665/1075/1149 -f 656/1076/1100 655/1077/1102 665/1078/1149 666/1079/1150 -f 657/1080/1098 656/1081/1100 666/1082/1150 667/1083/1151 -f 646/1084/1096 657/1085/1098 667/1086/1151 664/1087/1148 -f 658/1088/1143 659/1089/1142 669/1090/1152 668/1091/1153 -f 660/1092/1145 661/1093/1144 671/1094/1154 670/1095/1155 -f 661/1096/1144 662/1097/1146 672/1098/1156 671/1099/1154 -f 662/1100/1146 658/1101/1143 668/1102/1153 672/1103/1156 -f 659/1104/1142 663/1105/1147 673/1106/1157 669/1107/1152 -f 663/1108/1147 664/1109/1148 674/1110/1158 673/1111/1157 -f 665/1112/1149 660/1113/1145 670/1114/1155 675/1115/1159 -f 666/1116/1150 665/1117/1149 675/1118/1159 676/1119/1160 -f 667/1120/1151 666/1121/1150 676/1122/1160 677/1123/1161 -f 664/1124/1148 667/1125/1151 677/1126/1161 674/1127/1158 -f 668/1128/1153 669/1129/1152 679/1130/1162 678/1131/1163 -f 670/1132/1155 671/1133/1154 681/1134/1164 680/1135/1165 -f 671/1136/1154 672/1137/1156 682/1138/1166 681/1139/1164 -f 672/1140/1156 668/1141/1153 678/1142/1163 682/1143/1166 -f 669/1144/1152 673/1145/1157 683/1146/1167 679/1147/1162 -f 673/1148/1157 674/1149/1158 684/1150/1168 683/1151/1167 -f 675/1152/1159 670/1153/1155 680/1154/1165 685/1155/1169 -f 676/1156/1160 675/1157/1159 685/1158/1169 686/1159/1170 -f 677/1160/1161 676/1161/1160 686/1162/1170 687/1163/1171 -f 674/1164/1158 677/1165/1161 687/1166/1171 684/1167/1168 -f 678/1168/1163 679/1169/1162 700/1212/1172 701/1215/1173 -f 680/1172/1165 681/1173/1164 703/1218/1174 704/1221/1175 -f 681/1176/1164 682/1177/1166 702/1216/1176 703/1219/1174 -f 682/1180/1166 678/1181/1163 701/1214/1173 702/1217/1176 -f 679/1184/1162 683/1185/1167 699/1210/1177 700/1213/1172 -f 683/1188/1167 684/1189/1168 698/1208/1178 699/1211/1177 -f 685/1192/1169 680/1193/1165 704/1220/1175 705/1223/1179 -f 686/1196/1170 685/1197/1169 705/1222/1179 706/1225/1180 -f 687/1200/1171 686/1201/1170 706/1224/1180 707/1227/1181 -f 684/1204/1168 687/1205/1171 707/1226/1181 698/1209/1178 -f 699/1211/1177 698/1208/1178 694/1190/1182 693/1191/1183 -f 700/1213/1172 699/1210/1177 693/1186/1183 689/1187/1184 -f 701/1215/1173 700/1212/1172 689/1170/1184 688/1171/1185 -f 702/1217/1176 701/1214/1173 688/1182/1185 692/1183/1186 -f 703/1219/1174 702/1216/1176 692/1178/1186 691/1179/1187 -f 704/1221/1175 703/1218/1174 691/1174/1187 690/1175/1188 -f 705/1223/1179 704/1220/1175 690/1194/1188 695/1195/1189 -f 706/1225/1180 705/1222/1179 695/1198/1189 696/1199/1190 -f 707/1227/1181 706/1224/1180 696/1202/1190 697/1203/1191 -f 698/1209/1178 707/1226/1181 697/1206/1191 694/1207/1182 -g default -v -4.013798 -2.834903 2.779402 -v -4.212209 -2.834903 2.977814 -v -4.284823 -2.834903 3.248840 -v -4.212209 -2.834903 3.519865 -v -4.013798 -2.834903 3.718257 -v -3.742772 -2.834903 3.790890 -v -3.471747 -2.834903 3.718257 -v -3.273335 -2.834903 3.519865 -v -3.200722 -2.834903 3.248840 -v -3.273335 -2.834903 2.977814 -v -3.471747 -2.834903 2.779402 -v -3.742772 -2.834903 2.706789 -v -4.013798 -2.025686 2.779402 -v -4.212209 -2.025686 2.977814 -v -4.284823 -2.025686 3.248840 -v -4.212209 -2.025686 3.519865 -v -4.013798 -2.025686 3.718257 -v -3.742772 -2.025686 3.790890 -v -3.471747 -2.025686 3.718257 -v -3.273335 -2.025686 3.519865 -v -3.200722 -2.025686 3.248840 -v -3.273335 -2.025686 2.977814 -v -3.471747 -2.025686 2.779402 -v -3.742772 -2.025686 2.706789 -v -3.970516 -2.922916 2.854388 -v -4.137224 -2.922916 3.021096 -v -3.742772 -2.922916 3.248840 -v -4.198240 -2.922916 3.248840 -v -4.137224 -2.922916 3.476564 -v -3.970516 -2.922916 3.643291 -v -3.742772 -2.922916 3.704288 -v -3.515029 -2.922916 3.643291 -v -3.348321 -2.922916 3.476564 -v -3.287305 -2.922916 3.248840 -v -3.348321 -2.922916 3.021096 -v -3.515029 -2.922916 2.854388 -v -3.742772 -2.922916 2.793372 -v -3.273335 -2.113700 3.519865 -v -3.471747 -2.113700 3.718257 -v -3.742772 -2.113700 3.790890 -v -4.013798 -2.113700 3.718257 -v -4.212209 -2.113700 3.519865 -v -4.284823 -2.113700 3.248840 -v -4.212209 -2.113700 2.977814 -v -4.013798 -2.113700 2.779402 -v -3.742772 -2.113700 2.706789 -v -3.471747 -2.113700 2.779402 -v -3.273335 -2.113700 2.977814 -v -3.200722 -2.113700 3.248840 -v -3.273335 -2.489513 3.519865 -v -3.471747 -2.489513 3.718257 -v -3.742772 -2.489513 3.790890 -v -4.013798 -2.489513 3.718257 -v -4.212209 -2.489513 3.519865 -v -4.284823 -2.489513 3.248840 -v -4.212209 -2.489513 2.977814 -v -4.013798 -2.489513 2.779402 -v -3.742772 -2.489513 2.706789 -v -3.471747 -2.489513 2.779402 -v -3.273335 -2.489513 2.977814 -v -3.200722 -2.489513 3.248840 -v 0.727752 -2.489513 3.103179 -v 0.874636 -2.489513 3.342256 -v 0.727752 -2.113700 3.103179 -v 0.874636 -2.113700 3.342256 -v 0.882317 -2.489513 3.622733 -v 0.882317 -2.113700 3.622733 -v 0.748725 -2.489513 3.869472 -v 0.748725 -2.113700 3.869472 -v 1.248698 -2.298199 2.891871 -v 1.342510 -2.298199 3.130948 -v 1.248698 -2.055319 2.891871 -v 1.342510 -2.055319 3.130948 -v 1.347424 -2.298199 3.411425 -v 1.347424 -2.055319 3.411425 -v 1.262084 -2.298199 3.658164 -v 1.262084 -2.055319 3.658164 -v 2.382670 -2.165209 1.821288 -v 2.476501 -2.165209 2.060364 -v 2.382670 -1.922329 1.821288 -v 2.476501 -1.922329 2.060364 -v 2.481397 -2.165209 2.340841 -v 2.481397 -1.922329 2.340841 -v 2.396075 -2.165209 2.587580 -v 2.396075 -1.922329 2.587580 -v 1.948721 -2.218130 2.558625 -v 1.953635 -2.218130 2.839101 -v 1.868295 -2.218130 3.085840 -v 1.868295 -1.975250 3.085840 -v 1.953635 -1.975250 2.839101 -v 1.948721 -1.975250 2.558625 -v 1.854909 -1.975250 2.319548 -v 1.854909 -2.218130 2.319548 -vt 0.635316 0.078125 -vt 0.578125 0.020934 -vt 0.500000 0.000000 -vt 0.421875 0.020934 -vt 0.364684 0.078125 -vt 0.343750 0.156250 -vt 0.364684 0.234375 -vt 0.421875 0.291566 -vt 0.500000 0.312500 -vt 0.578125 0.291566 -vt 0.635316 0.234375 -vt 0.656250 0.156250 -vt 0.375000 0.312500 -vt 0.395833 0.312500 -vt 0.416667 0.312500 -vt 0.437500 0.312500 -vt 0.458333 0.312500 -vt 0.479167 0.312500 -vt 0.500000 0.312500 -vt 0.520833 0.312500 -vt 0.541667 0.312500 -vt 0.562500 0.312500 -vt 0.583333 0.312500 -vt 0.604167 0.312500 -vt 0.625000 0.312500 -vt 0.375000 0.688440 -vt 0.395833 0.688440 -vt 0.416667 0.688440 -vt 0.437500 0.688440 -vt 0.458333 0.688440 -vt 0.479167 0.688440 -vt 0.500000 0.688440 -vt 0.520833 0.688440 -vt 0.541667 0.688440 -vt 0.562500 0.688440 -vt 0.583333 0.688440 -vt 0.604167 0.688440 -vt 0.625000 0.688440 -vt 0.500000 0.150000 -vt 0.578125 0.020934 -vt 0.635316 0.078125 -vt 0.500000 0.000000 -vt 0.421875 0.020934 -vt 0.364684 0.078125 -vt 0.343750 0.156250 -vt 0.364684 0.234375 -vt 0.421875 0.291566 -vt 0.500000 0.312500 -vt 0.578125 0.291566 -vt 0.635316 0.234375 -vt 0.656250 0.156250 -vt 0.520833 0.558498 -vt 0.500000 0.558498 -vt 0.479167 0.558498 -vt 0.458333 0.558498 -vt 0.437500 0.558498 -vt 0.416667 0.558498 -vt 0.395833 0.558498 -vt 0.625000 0.558498 -vt 0.375000 0.558498 -vt 0.604167 0.558498 -vt 0.583333 0.558498 -vt 0.562500 0.558498 -vt 0.541667 0.558498 -vt 0.520833 0.430310 -vt 0.500000 0.430310 -vt 0.479167 0.430310 -vt 0.458333 0.430310 -vt 0.437500 0.430310 -vt 0.416667 0.430310 -vt 0.395833 0.430310 -vt 0.625000 0.430310 -vt 0.375000 0.430310 -vt 0.604167 0.430310 -vt 0.583333 0.430310 -vt 0.562500 0.430310 -vt 0.541667 0.430310 -vt 0.562500 0.430310 -vt 0.583333 0.430310 -vt 0.583333 0.558498 -vt 0.562500 0.558498 -vt 0.541667 0.430310 -vt 0.541667 0.558498 -vt 0.520833 0.430310 -vt 0.520833 0.558498 -vt 0.562500 0.430310 -vt 0.583333 0.430310 -vt 0.583333 0.558498 -vt 0.562500 0.558498 -vt 0.541667 0.430310 -vt 0.541667 0.558498 -vt 0.520833 0.430310 -vt 0.520833 0.558498 -vt 0.562500 0.430310 -vt 0.583333 0.430310 -vt 0.583333 0.558498 -vt 0.562500 0.558498 -vt 0.541667 0.430310 -vt 0.541667 0.558498 -vt 0.520833 0.430310 -vt 0.520833 0.558498 -vt 0.562500 0.430310 -vt 0.541667 0.430310 -vt 0.520833 0.430310 -vt 0.520833 0.558498 -vt 0.541667 0.558498 -vt 0.562500 0.558498 -vt 0.583333 0.558498 -vt 0.583333 0.430310 -vn -0.493012 -0.166503 -0.853942 -vn -0.853942 -0.166503 -0.493012 -vn -0.866029 0.000000 -0.499994 -vn -0.499994 0.000000 -0.866029 -vn -0.986040 -0.166511 0.000000 -vn -1.000000 0.000000 -0.000000 -vn -0.853932 -0.166504 0.493029 -vn -0.866020 0.000000 0.500010 -vn -0.493014 -0.166508 0.853940 -vn -0.499995 0.000000 0.866029 -vn 0.000000 -0.166505 0.986041 -vn 0.000000 0.000000 1.000000 -vn 0.493014 -0.166508 0.853940 -vn 0.499994 0.000000 0.866029 -vn 0.853932 -0.166504 0.493028 -vn 0.054274 -0.497545 0.865739 -vn 0.986040 -0.166511 0.000000 -vn 0.072483 -0.997370 0.000000 -vn 0.853942 -0.166503 -0.493011 -vn 0.073471 -0.996395 -0.042418 -vn 0.493011 -0.166503 -0.853942 -vn 0.127835 -0.202875 -0.970824 -vn 0.000000 -0.166511 -0.986040 -vn 0.000000 0.000000 -1.000000 -vn -0.296167 -0.939706 -0.170991 -vn -0.170990 -0.939706 -0.296167 -vn 0.000000 -1.000000 -0.000000 -vn -0.341975 -0.939709 0.000001 -vn -0.296162 -0.939709 0.170983 -vn -0.170994 -0.939701 0.296180 -vn 0.000000 -0.939714 0.341963 -vn 0.170993 -0.939701 0.296180 -vn 0.296162 -0.939709 0.170983 -vn 0.341975 -0.939709 0.000000 -vn 0.296167 -0.939706 -0.170991 -vn 0.170990 -0.939706 -0.296167 -vn 0.000000 -0.939711 -0.341970 -vn 0.499995 0.000000 0.866029 -vn -0.008264 0.514230 0.857612 -vn 0.866020 0.000000 0.500010 -vn 0.499995 0.000000 0.866028 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn -0.499995 0.000000 0.866028 -vn -0.499995 0.000000 0.866028 -vn -0.866020 0.000000 0.500010 -vn -0.866020 0.000000 0.500010 -vn -1.000000 0.000000 -0.000000 -vn -1.000000 0.000000 0.000000 -vn -0.866029 0.000000 -0.499994 -vn -0.866029 0.000000 -0.499994 -vn -0.499994 0.000000 -0.866029 -vn -0.499994 0.000000 -0.866029 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.097509 0.217208 -0.971243 -vn 0.499994 0.000000 -0.866029 -vn 0.018786 0.999765 -0.010846 -vn 0.866029 0.000000 -0.499994 -vn 0.018516 0.999829 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.051015 -0.607768 -0.792474 -vn 0.056906 -0.998296 -0.012933 -vn 0.018047 0.604438 -0.796448 -vn -0.017522 0.999839 0.003966 -vn 0.054141 -0.998422 0.014916 -vn -0.016719 0.999849 -0.004694 -vn -0.026389 -0.651800 0.757932 -vn -0.030983 0.643675 0.764672 -vn -0.254216 -0.705409 -0.661643 -vn 0.202818 -0.978120 -0.046326 -vn -0.452051 0.714996 -0.533321 -vn -0.113042 0.993367 0.021057 -vn 0.276129 -0.960166 0.042833 -vn -0.151368 0.988044 -0.029259 -vn 0.577145 -0.348256 0.738662 -vn 0.469969 0.450037 0.759339 -vn -0.446163 -0.700713 -0.556723 -vn 0.096697 -0.995119 -0.019712 -vn -0.539287 0.685689 -0.488877 -vn -0.096697 0.995119 0.019712 -vn 0.133363 -0.990913 0.017470 -vn -0.133363 0.990913 -0.017470 -vn 0.649166 -0.426321 0.629947 -vn 0.559101 0.501699 0.660079 -vn 0.079796 -0.996583 -0.021326 -vn 0.103579 -0.994613 0.004074 -vn 0.586920 -0.585187 0.559537 -vn 0.445835 0.708174 0.547467 -vn -0.103579 0.994613 -0.004075 -vn -0.079797 0.996583 0.021326 -vn -0.577760 0.605166 -0.547693 -vn -0.524232 -0.586358 -0.617547 -s 1 -g lwrArm_R_geo -usemtl blinn2SG -f 708/1240/1192 709/1241/1193 763/1298/1194 764/1300/1195 -f 709/1241/1193 710/1242/1196 762/1297/1197 763/1298/1194 -f 710/1242/1196 711/1243/1198 761/1296/1199 762/1297/1197 -f 711/1243/1198 712/1244/1200 760/1295/1201 761/1296/1199 -f 712/1244/1200 713/1245/1202 759/1294/1203 760/1295/1201 -f 713/1245/1202 714/1246/1204 758/1293/1205 759/1294/1203 -f 714/1246/1204 715/1247/1206 757/1292/1207 758/1293/1205 -f 715/1247/1206 716/1248/1208 768/1304/1209 757/1292/1207 -f 716/1248/1208 717/1249/1210 767/1303/1211 768/1304/1209 -f 717/1249/1210 718/1250/1212 766/1302/1213 767/1303/1211 -f 718/1250/1212 719/1251/1214 765/1301/1215 766/1302/1213 -f 719/1251/1214 708/1252/1192 764/1299/1195 765/1301/1215 -f 733/1267/1216 732/1268/1217 734/1266/1218 -f 735/1269/1219 733/1267/1216 734/1266/1218 -f 736/1270/1220 735/1269/1219 734/1266/1218 -f 737/1271/1221 736/1270/1220 734/1266/1218 -f 738/1272/1222 737/1271/1221 734/1266/1218 -f 739/1273/1223 738/1272/1222 734/1266/1218 -f 740/1274/1224 739/1273/1223 734/1266/1218 -f 741/1275/1225 740/1274/1224 734/1266/1218 -f 742/1276/1226 741/1275/1225 734/1266/1218 -f 743/1277/1227 742/1276/1226 734/1266/1218 -f 744/1278/1228 743/1277/1227 734/1266/1218 -f 732/1268/1217 744/1278/1228 734/1266/1218 -f 709/1229/1193 708/1228/1192 732/1268/1217 733/1267/1216 -f 710/1230/1196 709/1229/1193 733/1267/1216 735/1269/1219 -f 711/1231/1198 710/1230/1196 735/1269/1219 736/1270/1220 -f 712/1232/1200 711/1231/1198 736/1270/1220 737/1271/1221 -f 713/1233/1202 712/1232/1200 737/1271/1221 738/1272/1222 -f 714/1234/1204 713/1233/1202 738/1272/1222 739/1273/1223 -f 715/1235/1206 714/1234/1204 739/1273/1223 740/1274/1224 -f 716/1236/1208 715/1235/1206 740/1274/1224 741/1275/1225 -f 717/1237/1210 716/1236/1208 741/1275/1225 742/1276/1226 -f 718/1238/1212 717/1237/1210 742/1276/1226 743/1277/1227 -f 719/1239/1214 718/1238/1212 743/1277/1227 744/1278/1228 -f 708/1228/1192 719/1239/1214 744/1278/1228 732/1268/1217 -f 746/1280/1229 745/1279/1230 727/1260/1231 726/1259/1232 -f 747/1281/1233 746/1280/1229 726/1259/1232 725/1258/1234 -f 748/1282/1235 747/1281/1233 725/1258/1234 724/1257/1236 -f 749/1283/1237 748/1282/1235 724/1257/1236 723/1256/1238 -f 750/1284/1239 749/1283/1237 723/1256/1238 722/1255/1240 -f 751/1285/1241 750/1284/1239 722/1255/1240 721/1254/1242 -f 752/1287/1243 751/1285/1241 721/1254/1242 720/1253/1244 -f 753/1288/1245 752/1286/1243 720/1265/1244 731/1264/1246 -f 754/1289/1247 753/1288/1245 731/1264/1246 730/1263/1248 -f 755/1290/1249 754/1289/1247 730/1263/1248 729/1262/1250 -f 756/1291/1251 755/1290/1249 729/1262/1250 728/1261/1252 -f 745/1279/1230 756/1291/1251 728/1261/1252 727/1260/1231 -f 758/1293/1205 757/1292/1207 745/1279/1230 746/1280/1229 -f 759/1294/1203 758/1293/1205 746/1280/1229 747/1281/1233 -f 760/1295/1201 759/1294/1203 747/1281/1233 748/1282/1235 -f 761/1296/1199 760/1295/1201 748/1282/1235 749/1283/1237 -f 762/1297/1197 761/1296/1199 749/1283/1237 750/1284/1239 -f 763/1298/1194 762/1297/1197 750/1284/1239 751/1285/1241 -f 764/1300/1195 763/1298/1194 751/1285/1241 752/1287/1243 -f 765/1301/1215 764/1299/1195 752/1286/1243 753/1288/1245 -f 766/1302/1213 765/1301/1215 753/1288/1245 754/1289/1247 -f 767/1303/1211 766/1302/1213 769/1306/1253 770/1305/1254 -f 766/1302/1213 754/1289/1247 771/1307/1255 769/1306/1253 -f 754/1289/1247 755/1290/1249 772/1308/1256 771/1307/1255 -f 768/1304/1209 767/1303/1211 770/1305/1254 773/1309/1257 -f 755/1290/1249 756/1291/1251 774/1310/1258 772/1308/1256 -f 757/1292/1207 768/1304/1209 773/1309/1257 775/1311/1259 -f 756/1291/1251 745/1279/1230 776/1312/1260 774/1310/1258 -f 745/1279/1230 757/1292/1207 775/1311/1259 776/1312/1260 -f 770/1305/1254 769/1306/1253 777/1314/1261 778/1313/1262 -f 769/1306/1253 771/1307/1255 779/1315/1263 777/1314/1261 -f 771/1307/1255 772/1308/1256 780/1316/1264 779/1315/1263 -f 773/1309/1257 770/1305/1254 778/1313/1262 781/1317/1265 -f 772/1308/1256 774/1310/1258 782/1318/1266 780/1316/1264 -f 775/1311/1259 773/1309/1257 781/1317/1265 783/1319/1267 -f 774/1310/1258 776/1312/1260 784/1320/1268 782/1318/1266 -f 776/1312/1260 775/1311/1259 783/1319/1267 784/1320/1268 -f 778/1313/1262 777/1314/1261 800/1336/1269 793/1329/1270 -f 777/1314/1261 779/1315/1263 799/1335/1271 800/1336/1269 -f 779/1315/1263 780/1316/1264 798/1334/1272 799/1335/1271 -f 781/1317/1265 778/1313/1262 793/1329/1270 794/1330/1273 -f 780/1316/1264 782/1318/1266 797/1333/1274 798/1334/1272 -f 783/1319/1267 781/1317/1265 794/1330/1273 795/1331/1275 -f 782/1318/1266 784/1320/1268 796/1332/1276 797/1333/1274 -f 784/1320/1268 783/1319/1267 795/1331/1275 796/1332/1276 -f 794/1330/1273 793/1329/1270 786/1321/1277 789/1325/1278 -f 795/1331/1275 794/1330/1273 789/1325/1278 791/1327/1279 -f 796/1332/1276 795/1331/1275 791/1327/1279 792/1328/1280 -f 797/1333/1274 796/1332/1276 792/1328/1280 790/1326/1281 -f 798/1334/1272 797/1333/1274 790/1326/1281 788/1324/1282 -f 799/1335/1271 798/1334/1272 788/1324/1282 787/1323/1283 -f 800/1336/1269 799/1335/1271 787/1323/1283 785/1322/1284 -f 793/1329/1270 800/1336/1269 785/1322/1284 786/1321/1277 -g default -v -0.615337 -2.784912 0.346995 -v -0.615337 -1.617536 0.346995 -v -0.891418 -2.784912 2.387670 -v -0.891418 -1.617536 2.387670 -v -3.706954 -2.784912 1.940161 -v -3.706954 -1.617536 1.940161 -v -3.749398 -2.784912 0.346995 -v -3.749398 -1.617536 0.346995 -v -1.162735 -2.784912 1.334254 -v -3.380559 -2.784912 1.222088 -v -3.380559 -1.617536 1.222088 -v -1.286063 -1.617536 1.334254 -v -0.942665 -2.784912 0.779819 -v -3.447443 -2.784912 0.659830 -v -3.447443 -1.617536 0.659830 -v -0.942665 -1.617536 0.779819 -v -1.148753 -2.784912 1.867356 -v -3.516576 -2.784912 1.678854 -v -3.516576 -1.617536 1.678854 -v -1.148753 -1.617536 1.867356 -vt 0.375000 0.000000 -vt 0.625000 0.000000 -vt 0.375000 0.250000 -vt 0.625000 0.250000 -vt 0.375000 0.500000 -vt 0.625000 0.500000 -vt 0.375000 0.750000 -vt 0.625000 0.750000 -vt 0.375000 1.000000 -vt 0.625000 1.000000 -vt 0.875000 0.000000 -vt 0.875000 0.250000 -vt 0.125000 0.000000 -vt 0.125000 0.250000 -vt 0.375000 0.153497 -vt 0.125000 0.153497 -vt 0.375000 0.596503 -vt 0.625000 0.596503 -vt 0.875000 0.153497 -vt 0.625000 0.153497 -vt 0.375000 0.067294 -vt 0.125000 0.054873 -vt 0.375000 0.695127 -vt 0.625000 0.695127 -vt 0.875000 0.054873 -vt 0.625000 0.067294 -vt 0.375000 0.202335 -vt 0.125000 0.224042 -vt 0.375000 0.525958 -vt 0.625000 0.525958 -vt 0.875000 0.224042 -vt 0.625000 0.202335 -vn 0.797597 0.000000 0.603191 -vn 0.797597 0.000000 0.603191 -vn 0.850803 0.025239 0.524879 -vn 0.850803 0.025239 0.524879 -vn -0.156973 0.000000 0.987603 -vn -0.156973 0.000000 0.987603 -vn -0.156973 0.000000 0.987603 -vn -0.156973 0.000000 0.987603 -vn -0.921493 0.000000 0.388396 -vn -0.921493 0.000000 0.388396 -vn -0.719508 0.000000 0.694484 -vn -0.719508 0.000000 0.694484 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn -0.910367 0.000000 -0.413801 -vn -0.910367 0.000000 -0.413801 -vn -0.997707 0.000000 -0.067687 -vn -0.997707 0.000000 -0.067687 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.980530 0.051794 0.189414 -vn 0.981744 0.051858 0.183002 -vn 0.953189 0.025480 -0.301300 -vn 0.953189 0.025480 -0.301300 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn -0.808241 0.000000 -0.588852 -vn -0.808241 0.000000 -0.588852 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.896363 0.000000 -0.443321 -vn 0.896363 0.000000 -0.443321 -s 1 -g trackBase_R_geo -usemtl blinn4SG -f 801/1337/1285 802/1338/1286 816/1362/1287 813/1357/1288 -s off -f 805/1341/1289 803/1339/1290 804/1340/1291 806/1342/1292 -s 2 -f 814/1359/1293 815/1360/1294 808/1344/1295 807/1343/1296 -s off -f 802/1346/1297 801/1345/1298 807/1343/1299 808/1344/1300 -s 3 -f 816/1362/1301 802/1338/1302 808/1347/1303 815/1361/1304 -s 4 -f 801/1337/1305 813/1357/1306 814/1358/1307 807/1349/1308 -f 809/1351/1309 817/1363/1310 818/1364/1311 810/1352/1312 -s 2 -f 818/1365/1313 819/1366/1314 811/1354/1315 810/1353/1316 -s 3 -f 820/1368/1317 812/1356/1318 811/1355/1319 819/1367/1320 -s 1 -f 809/1351/1321 812/1356/1322 820/1368/1323 817/1363/1324 -s 4 -f 813/1357/1306 809/1351/1309 810/1352/1312 814/1358/1307 -s 2 -f 810/1353/1316 811/1354/1315 815/1360/1294 814/1359/1293 -s 3 -f 812/1356/1318 816/1362/1301 815/1361/1304 811/1355/1319 -s 1 -f 813/1357/1288 816/1362/1287 812/1356/1322 809/1351/1321 -s 4 -f 817/1363/1310 803/1339/1325 805/1350/1326 818/1364/1311 -s 2 -f 805/1341/1327 806/1342/1328 819/1366/1314 818/1365/1313 -s 3 -f 804/1340/1329 820/1368/1317 819/1367/1320 806/1348/1330 -s 1 -f 817/1363/1324 820/1368/1323 804/1340/1331 803/1339/1332 -g default -v 0.317213 -1.531502 0.493733 -v 0.640943 0.000000 0.360719 -v 0.512114 -1.582651 2.673993 -v 0.766233 0.000000 2.833397 -v -5.031329 -1.543880 1.632459 -v -5.218313 0.000000 1.768875 -v -5.031329 -1.543880 0.410350 -v -5.074479 0.000000 0.357996 -v 1.508484 0.000000 1.617661 -v 0.998909 -1.557555 1.570087 -v -5.209013 -1.561558 0.888702 -v -5.298325 0.000000 0.879015 -v -5.135477 -1.343096 1.801219 -v -5.298325 -1.309736 0.879015 -v -5.074479 -1.309736 0.357996 -v 0.640943 -1.319272 0.360719 -v 1.508484 -1.376485 1.617661 -v 0.766233 -1.376485 2.833397 -v -1.517298 0.000000 2.916308 -v -1.822397 -1.349206 2.836729 -v -1.831104 -1.628317 2.586864 -v -2.310552 -1.651040 1.249529 -v -2.488923 -1.571094 0.355996 -v -2.505801 -1.309736 0.241028 -v -2.505801 0.000000 0.241028 -v -2.772646 -1.335886 3.006675 -v -5.541149 -1.301885 2.446796 -v -2.552330 0.000000 3.099866 -v -5.606175 0.000000 2.430454 -v -3.062687 -1.298459 4.194453 -v -5.779792 -1.391198 3.600593 -v -3.020496 0.000000 4.296568 -v -5.862854 0.000000 3.673263 -v -3.355870 -1.309708 5.512304 -v -5.599058 -1.299833 4.910385 -v -3.102730 0.000000 6.227181 -v -5.606363 0.000000 5.628500 -v -5.609601 -0.551718 5.534180 -v -5.863419 -0.550113 3.659971 -v -5.606175 -0.536836 2.430454 -v -5.218313 -0.534619 1.768875 -v -5.298325 -0.534619 0.879015 -v -5.074479 -0.534619 0.357996 -v -2.505801 -0.534619 0.241028 -v 0.640943 -0.534619 0.360719 -v 1.508484 -0.534619 1.617661 -v 0.766233 -0.534619 2.833397 -v -1.517298 -0.534619 2.916308 -v -2.552330 -0.534619 3.099866 -v -3.026521 -0.534619 4.281959 -v -3.138896 -0.536229 6.125066 -v -4.926239 0.000000 6.168819 -v -4.932829 -0.546470 6.053413 -v -5.047180 -1.425980 5.185401 -v -5.259354 -1.508072 3.709372 -v -4.950526 -1.418365 2.562691 -v -4.306869 -1.425151 2.115036 -v -4.251933 -1.561558 1.915156 -v -4.421202 -1.584301 0.981911 -v -4.361559 -1.561558 0.358552 -v -4.346536 -1.309736 0.278356 -v -4.346536 -0.534619 0.278356 -v -4.346536 0.000000 0.278356 -v -3.268045 -2.057654 3.115699 -v -4.613081 -2.074786 2.851640 -v -3.331697 -2.075444 4.123591 -v -4.909559 -2.142900 3.785958 -v -3.589864 -2.077647 5.219289 -v -4.720354 -2.134748 4.972249 -v -4.918181 -2.020942 5.076660 -v -3.392036 -1.943848 5.410189 -v -3.068711 -1.931008 4.179844 -v -2.978250 -1.931008 3.047735 -v -4.849239 -1.943848 2.686889 -v -5.172526 -2.020942 3.729704 -v -4.918181 -1.633287 5.076660 -v -3.392036 -1.556183 5.410189 -v -3.068711 -1.543334 4.179844 -v -2.978250 -1.543334 3.047735 -v -4.849239 -1.556183 2.686889 -v -5.172526 -1.633287 3.729704 -v 0.317204 1.531502 0.493733 -v 0.640943 1.319272 0.360719 -v 1.508484 1.376485 1.617661 -v 0.998909 1.557555 1.570087 -v 0.512114 1.582651 2.673993 -v 0.766233 1.376485 2.833397 -v -1.822397 1.349206 2.836729 -v -1.831104 1.628317 2.586864 -v -5.209013 1.561558 0.888702 -v -5.298325 1.309736 0.879015 -v -5.074479 1.309736 0.357996 -v -5.031329 1.543880 0.410350 -v -2.488923 1.571094 0.355996 -v -2.505801 1.309736 0.241028 -v -2.310552 1.651040 1.249529 -v -5.031329 1.543880 1.632459 -v -5.135477 1.343096 1.801219 -v -5.218313 0.534619 1.768875 -v -5.298325 0.534619 0.879015 -v -5.074479 0.534619 0.357996 -v -2.505801 0.534619 0.241028 -v 0.640943 0.534619 0.360719 -v 1.508484 0.534619 1.617661 -v 0.766233 0.534619 2.833397 -v -1.517298 0.534619 2.916308 -v -5.047180 1.425980 5.185401 -v -3.355870 1.309708 5.512304 -v -3.138896 0.536229 6.125066 -v -4.932829 0.546470 6.053413 -v -4.306869 1.425151 2.115036 -v -4.251933 1.561558 1.915156 -v -4.421202 1.584301 0.981911 -v -4.361559 1.561558 0.358552 -v -4.346536 1.309736 0.278356 -v -4.346536 0.534619 0.278356 -v -2.772646 1.335886 3.006675 -v -4.950526 1.418365 2.562691 -v -2.552330 0.534619 3.099866 -v -5.541149 1.301885 2.446796 -v -5.606175 0.536836 2.430454 -v -4.613081 2.074786 2.851640 -v -3.268045 2.057654 3.115699 -v -3.331697 2.075444 4.123591 -v -4.909559 2.142900 3.785958 -v -3.026521 0.534619 4.281959 -v -3.062687 1.298459 4.194453 -v -5.779792 1.391198 3.600593 -v -5.863419 0.550113 3.659971 -v -3.589864 2.077647 5.219289 -v -4.720354 2.134748 4.972249 -v -5.599058 1.299843 4.910385 -v -5.609601 0.551718 5.534180 -v -5.862854 -0.000000 3.673263 -v -5.606363 -0.000000 5.628500 -v -5.606175 -0.000000 2.430454 -v -5.218313 -0.000000 1.768875 -v -5.298325 -0.000000 0.879015 -v -5.074479 -0.000000 0.357996 -v -2.505801 -0.000000 0.241028 -v -4.346536 0.000000 0.278356 -v 0.640943 -0.000000 0.360719 -v 1.508484 0.000000 1.617661 -v 0.766233 -0.000000 2.833397 -v -1.517298 -0.000000 2.916308 -v -2.552330 0.000000 3.099866 -v -3.020496 -0.000000 4.296568 -v -3.102730 -0.000000 6.227181 -v -4.926239 -0.000000 6.168819 -v -5.259354 1.508072 3.709372 -v -2.978250 1.543334 3.047735 -v -4.849239 1.556183 2.686889 -v -3.068711 1.543334 4.179844 -v -5.172526 1.633287 3.729704 -v -3.392036 1.556183 5.410189 -v -4.918181 1.633287 5.076660 -v -3.392036 1.943848 5.410189 -v -4.918181 2.020942 5.076660 -v -3.068711 1.931008 4.179844 -v -2.978250 1.931008 3.047735 -v -4.849239 1.943848 2.686889 -v -5.172526 2.020942 3.729704 -v 1.351754 -1.386021 2.324914 -v -2.062391 -1.660585 1.975683 -v -5.074479 -1.493360 1.719888 -v -5.154642 -1.561558 1.337467 -v -5.241130 -1.309736 1.324345 -v -5.218313 -0.940757 1.768875 -v -5.241130 -0.534619 1.324345 -v -5.298325 -0.940757 0.879015 -v -5.074479 -0.940757 0.357996 -v -5.241130 -0.534619 0.556010 -v 0.640943 -0.940757 0.360719 -v -2.505801 -0.940757 0.241028 -v -0.864602 -0.534619 0.207745 -v 1.508484 -0.940757 1.617661 -v 1.351754 -0.534619 0.896816 -v 0.766233 -0.940757 2.833397 -v 1.351754 -0.534619 2.324914 -v -1.517298 -0.940757 2.916308 -v -0.363409 -0.534619 2.957933 -v -4.131011 -1.343435 5.549994 -v -4.952521 -0.988152 5.707157 -v -3.247393 -0.947177 5.818685 -v -3.986349 -0.541043 6.250262 -v -3.187543 -1.561558 2.247273 -v -3.216988 -1.425151 2.460163 -v -4.221227 -1.493360 2.057333 -v -3.576008 -1.584301 1.096771 -v -4.344088 -1.584301 1.488634 -v -3.626086 -1.561558 0.357549 -v -4.406743 -1.584301 0.599146 -v -4.346536 -1.493360 0.278356 -v -3.623582 -1.309736 0.263695 -v -3.623582 -0.534619 0.263695 -v -4.346536 -0.940757 0.278356 -v -4.563830 -1.402418 2.288108 -v -2.506874 -1.287003 2.837294 -v -3.784642 -1.413874 2.680921 -v -2.175547 -0.534619 2.926230 -v -2.552330 -0.940757 3.099866 -v -5.378450 -0.534619 2.089470 -v -5.309433 -1.287003 2.105153 -v -5.606175 -0.949605 2.430454 -v -3.913735 -2.070625 2.867322 -v -4.883692 -2.109163 3.141171 -v -3.150662 -2.070625 3.491098 -v -4.120637 -2.121249 3.954755 -v -2.861827 -1.298459 3.549385 -v -2.861827 -0.534619 3.549385 -v -3.044613 -0.940757 4.238206 -v -5.785892 -0.543472 2.936114 -v -5.709231 -1.346542 2.954451 -v -5.865001 -1.002724 3.620097 -v -4.918181 -2.154139 4.507161 -v -3.392036 -2.077045 4.840652 -v -4.155109 -2.115582 5.243424 -v -3.113574 -1.298459 4.954589 -v -2.968912 -0.534619 5.304761 -v -5.784386 -0.552325 4.655513 -v -5.718908 -1.406080 4.357641 -v -5.619278 -1.009144 5.251256 -v -5.782240 0.000000 4.708679 -v -5.785892 0.000000 2.936114 -v -5.378450 0.000000 2.089470 -v -5.241130 0.000000 1.324345 -v -5.241130 0.000000 0.556010 -v -3.623582 0.000000 0.263695 -v -0.864602 0.000000 0.207745 -v 1.351754 0.000000 0.896816 -v 1.351754 0.000000 2.324914 -v -0.363409 0.000000 2.957933 -v -2.175547 0.000000 2.926230 -v -2.861827 0.000000 3.549385 -v -2.944814 0.000000 5.363123 -v -3.962232 0.000000 6.366986 -v -5.399837 -0.549897 5.907433 -v -5.397653 0.000000 6.018923 -v -5.430487 -1.393937 5.048533 -v -5.519837 -1.509353 3.648336 -v -5.250920 -1.521515 4.430537 -v -5.346031 -1.417696 2.495820 -v -5.249225 -1.467699 3.064510 -v -4.877969 -1.425151 1.958194 -v -4.826196 -1.561558 1.764357 -v -4.941075 -1.584301 0.917779 -v -4.826196 -1.561558 0.359187 -v -4.803228 -1.309736 0.287616 -v -4.803228 -0.534619 0.287616 -v -4.803228 0.000000 0.287616 -v -4.849239 -1.461110 2.686889 -v -2.978250 -1.448261 3.047735 -v -3.879264 -1.543334 2.717708 -v -3.068711 -1.448261 4.179844 -v -2.861827 -1.543334 3.549385 -v -5.172526 -1.538204 3.729704 -v -5.172526 -1.594730 3.082847 -v -3.392036 -1.461110 5.410189 -v -3.137691 -1.543334 4.896227 -v -4.918181 -1.538204 5.076660 -v -4.155109 -1.594730 5.433270 -v -5.172526 -1.646127 4.451547 -v -4.155109 -1.982404 5.433270 -v -3.392036 -2.040785 5.410189 -v -4.918181 -2.117879 5.076660 -v -3.137691 -1.931008 4.896227 -v -3.068711 -2.027946 4.179844 -v -2.861827 -1.931008 3.549385 -v -2.978250 -2.027946 3.047735 -v -3.879264 -1.931008 2.717708 -v -4.849239 -2.040785 2.686889 -v -5.172526 -1.982404 3.082847 -v -5.172526 -2.117879 3.729704 -v -5.172526 -2.033801 4.451547 -v -3.392036 -1.749710 5.410189 -v -4.918181 -1.826804 5.076660 -v -3.068711 -1.736851 4.179844 -v -2.978250 -1.736851 3.047735 -v -4.849239 -1.749710 2.686889 -v -5.172526 -1.826804 3.729704 -v 0.843026 1.533093 0.870515 -v 0.640943 1.531502 0.360719 -v 1.508484 1.533093 1.617661 -v 1.351754 1.347878 0.896816 -v -0.380706 1.523244 2.760143 -v 0.766233 1.533093 2.833397 -v -1.754009 1.531502 2.790585 -v -0.363409 1.347878 2.957933 -v -5.154642 1.561558 0.560482 -v -5.298325 1.493360 0.879015 -v -5.074479 1.493360 0.357996 -v -5.241130 1.309736 0.556010 -v -0.819251 1.599701 0.353716 -v -2.505801 1.493360 0.241028 -v -0.864602 1.309736 0.207745 -v -2.438289 1.622443 0.700899 -v -0.529849 1.851297 1.427335 -v 0.905662 1.557555 2.285359 -v 1.351754 1.386021 2.324914 -v -2.062391 1.660585 1.975683 -v -5.154642 1.561558 1.337467 -v -5.074479 1.493360 1.719888 -v -5.241130 1.309736 1.324345 -v -5.218313 0.940757 1.768875 -v -5.298325 0.940757 0.879015 -v -5.241130 0.534619 1.324345 -v -5.074479 0.940757 0.357996 -v -5.241130 0.534619 0.556010 -v 0.640943 0.940757 0.360719 -v -0.864602 0.534619 0.207745 -v -2.505801 0.940757 0.241028 -v 1.508484 0.940757 1.617661 -v 1.351754 0.534619 0.896816 -v 0.766233 0.940757 2.833397 -v 1.351754 0.534619 2.324914 -v -1.517298 0.940757 2.916308 -v -0.363409 0.534619 2.957933 -v -4.952521 0.988152 5.707157 -v -4.131011 1.343435 5.549994 -v -3.986349 0.541043 6.250262 -v -3.247393 0.947177 5.818685 -v -3.187543 1.561558 2.247273 -v -4.221227 1.493360 2.057333 -v -3.216988 1.425151 2.460163 -v -4.344088 1.584301 1.488634 -v -3.576008 1.584301 1.096771 -v -4.406743 1.584301 0.599146 -v -3.626086 1.561558 0.357549 -v -4.346536 1.493360 0.278356 -v -3.623582 1.309736 0.263695 -v -3.623582 0.534619 0.263695 -v -4.346536 0.940757 0.278356 -v -4.563830 1.402418 2.288108 -v -3.784642 1.413874 2.680921 -v -2.506874 1.287003 2.837294 -v -2.552330 0.940757 3.099866 -v -2.175547 0.534619 2.926230 -v -5.378450 0.534619 2.089470 -v -5.606175 0.949605 2.430454 -v -5.309433 1.287003 2.105153 -v -4.883692 2.109163 3.141171 -v -3.913735 2.070625 2.867322 -v -4.120637 2.121249 3.954755 -v -3.150662 2.070625 3.491098 -v -2.861827 1.298459 3.549385 -v -3.044613 0.940757 4.238206 -v -2.861827 0.534619 3.549385 -v -5.785892 0.543472 2.936114 -v -5.865001 1.002724 3.620097 -v -5.709231 1.346542 2.954451 -v -4.918181 2.154139 4.507161 -v -4.155109 2.115582 5.243424 -v -3.392036 2.077045 4.840652 -v -3.113574 1.298459 4.954589 -v -2.968912 0.534619 5.304761 -v -5.784386 0.552325 4.655513 -v -5.619278 1.009144 5.251256 -v -5.718908 1.406080 4.357641 -v -5.782240 -0.000000 4.708679 -v -5.785892 -0.000000 2.936114 -v -5.378450 -0.000000 2.089470 -v -5.241130 -0.000000 1.324345 -v -5.241130 -0.000000 0.556010 -v -3.623582 0.000000 0.263695 -v -0.864602 -0.000000 0.207745 -v 1.351754 0.000000 0.896816 -v 1.351754 0.000000 2.324914 -v -0.363409 -0.000000 2.957933 -v -2.175547 0.000000 2.926230 -v -2.861827 -0.000000 3.549385 -v -2.944814 -0.000000 5.363123 -v -3.962232 -0.000000 6.366986 -v -5.399837 0.549897 5.907433 -v -5.397653 -0.000000 6.018923 -v -5.430487 1.393937 5.048533 -v -5.519837 1.509353 3.648336 -v -5.250920 1.521515 4.430537 -v -5.346031 1.417696 2.495820 -v -5.249225 1.467699 3.064510 -v -4.877969 1.425151 1.958194 -v -4.826196 1.561558 1.764357 -v -4.941075 1.584301 0.917779 -v -4.826196 1.561558 0.359187 -v -4.803228 1.309736 0.287616 -v -4.803228 0.534619 0.287616 -v -4.803228 0.000000 0.287616 -v -4.849239 1.461110 2.686889 -v -3.879264 1.543334 2.717708 -v -2.978250 1.448261 3.047735 -v -2.861827 1.543334 3.549385 -v -3.068711 1.448261 4.179844 -v -5.172526 1.538204 3.729704 -v -5.172526 1.594730 3.082847 -v -3.137691 1.543334 4.896227 -v -3.392036 1.461110 5.410189 -v -4.155109 1.594730 5.433270 -v -4.918181 1.538204 5.076660 -v -5.172526 1.646127 4.451547 -v -3.392036 2.040785 5.410189 -v -4.155109 1.982404 5.433270 -v -4.918181 2.117879 5.076660 -v -3.068711 2.027946 4.179844 -v -3.137691 1.931008 4.896227 -v -2.978250 2.027946 3.047735 -v -2.861827 1.931008 3.549385 -v -4.849239 2.040785 2.686889 -v -3.879264 1.931008 2.717708 -v -5.172526 2.117879 3.729704 -v -5.172526 1.982404 3.082847 -v -5.172526 2.033801 4.451547 -v -3.392036 1.749710 5.410189 -v -4.918181 1.826804 5.076660 -v -3.068711 1.736851 4.179844 -v -2.978250 1.736851 3.047735 -v -4.849239 1.749710 2.686889 -v -5.172526 1.826804 3.729704 -v 0.640943 -1.531502 0.360719 -v 0.843026 -1.557555 0.870515 -v 1.351754 -1.347878 0.896816 -v 1.508484 -1.533093 1.617661 -v 0.766233 -1.533093 2.833397 -v -0.380706 -1.523244 2.760143 -v -0.363409 -1.347878 2.957933 -v -1.754009 -1.531502 2.790585 -v -5.298325 -1.493360 0.879015 -v -5.154642 -1.561558 0.560482 -v -5.241130 -1.309736 0.556010 -v -5.074479 -1.493360 0.357996 -v -2.505801 -1.493360 0.241028 -v -0.819251 -1.599701 0.353716 -v -0.864602 -1.309736 0.207745 -v -2.438289 -1.622443 0.700899 -v -0.529849 -1.851297 1.427335 -v 0.905662 -1.557555 2.285359 -v 1.351754 -1.533093 0.896816 -v -0.363409 -1.523244 2.957933 -v -5.241130 -1.493360 0.556010 -v -0.864602 -1.493360 0.207745 -v -0.683200 -1.736870 0.791623 -v 1.351754 -1.533093 2.324914 -v -0.432601 -1.889439 2.166715 -v -5.241130 -1.493360 1.324345 -v -5.241130 -0.940757 1.324345 -v -5.241130 -0.940757 0.556010 -v -0.864602 -0.940757 0.207745 -v 1.351754 -0.940757 0.896816 -v 1.351754 -0.940757 2.324914 -v -0.363409 -0.940757 2.957933 -v -4.058680 -0.966455 5.900128 -v -3.122385 -1.493360 2.423376 -v -3.383037 -1.584301 1.718947 -v -3.633636 -1.584301 0.639106 -v -3.623582 -1.493360 0.263695 -v -3.623582 -0.940757 0.263695 -v -3.500815 -1.402418 2.570542 -v -2.175547 -0.940757 2.926230 -v -5.378450 -0.940757 2.089470 -v -4.017186 -2.101971 3.316125 -v -2.861827 -0.940757 3.549385 -v -5.785892 -0.976169 2.936114 -v -4.155109 -2.127669 4.673887 -v -3.041243 -0.940757 5.129675 -v -5.790824 -1.011572 4.496090 -v -5.406276 -1.001867 5.572925 -v -5.485987 -1.524630 4.367506 -v -5.479209 -1.463529 3.009480 -v -5.102267 -1.402418 2.152162 -v -4.803228 -1.493360 1.893525 -v -4.895138 -1.584301 1.376852 -v -4.895138 -1.584301 0.573900 -v -4.803228 -1.493360 0.287616 -v -4.803228 -0.940757 0.287616 -v -3.879264 -1.448261 2.717708 -v -2.861827 -1.448261 3.549385 -v -5.172526 -1.499657 3.082847 -v -3.137691 -1.448261 4.896227 -v -4.155109 -1.499657 5.433270 -v -5.172526 -1.551053 4.451547 -v -4.155109 -2.079342 5.433270 -v -3.137691 -2.027946 4.896227 -v -2.861827 -2.027946 3.549385 -v -3.879264 -2.027946 2.717708 -v -5.172526 -2.079342 3.082847 -v -5.172526 -2.130738 4.451547 -v -4.155109 -1.788247 5.433270 -v -3.137691 -1.736851 4.896227 -v -2.861827 -1.736851 3.549385 -v -3.879264 -1.736851 2.717708 -v -5.172526 -1.788247 3.082847 -v -5.172526 -1.839643 4.451547 -v 1.351754 1.533093 0.896816 -v -0.363409 1.523244 2.957933 -v -5.241130 1.493360 0.556010 -v -0.864602 1.493360 0.207745 -v -0.683200 1.736870 0.791623 -v 1.351754 1.533093 2.324914 -v -0.432601 1.889439 2.166715 -v -5.241130 1.493360 1.324345 -v -5.241130 0.940757 1.324345 -v -5.241130 0.940757 0.556010 -v -0.864602 0.940757 0.207745 -v 1.351754 0.940757 0.896816 -v 1.351754 0.940757 2.324914 -v -0.363409 0.940757 2.957933 -v -4.058680 0.966455 5.900128 -v -3.122385 1.493360 2.423376 -v -3.383037 1.584301 1.718947 -v -3.633636 1.584301 0.639106 -v -3.623582 1.493360 0.263695 -v -3.623582 0.940757 0.263695 -v -3.500815 1.402418 2.570542 -v -2.175547 0.940757 2.926230 -v -5.378450 0.940757 2.089470 -v -4.017186 2.101971 3.316125 -v -2.861827 0.940757 3.549385 -v -5.785892 0.976169 2.936114 -v -4.155109 2.127669 4.673887 -v -3.041243 0.940757 5.129675 -v -5.790824 1.011572 4.496090 -v -5.406276 1.001867 5.572925 -v -5.485987 1.524630 4.367506 -v -5.479209 1.463529 3.009480 -v -5.102267 1.402418 2.152162 -v -4.803228 1.493360 1.893525 -v -4.895138 1.584301 1.376852 -v -4.895138 1.584301 0.573900 -v -4.803228 1.493360 0.287616 -v -4.803228 0.940757 0.287616 -v -3.879264 1.448261 2.717708 -v -2.861827 1.448261 3.549385 -v -5.172526 1.499657 3.082847 -v -3.137691 1.448261 4.896227 -v -4.155109 1.499657 5.433270 -v -5.172526 1.551053 4.451547 -v -4.155109 2.079342 5.433270 -v -3.137691 2.027946 4.896227 -v -2.861827 2.027946 3.549385 -v -3.879264 2.027946 2.717708 -v -5.172526 2.079342 3.082847 -v -5.172526 2.130738 4.451547 -v -4.155109 1.788247 5.433270 -v -3.137691 1.736851 4.896227 -v -2.861827 1.736851 3.549385 -v -3.879264 1.736851 2.717708 -v -5.172526 1.788247 3.082847 -v -5.172526 1.839643 4.451547 -vt 0.375000 0.000000 -vt 0.437500 0.000000 -vt 0.437500 0.063691 -vt 0.371334 0.063691 -vt 0.495451 0.000000 -vt 0.495451 0.063691 -vt 0.495451 0.126786 -vt 0.437500 0.126786 -vt 0.371334 0.126786 -vt 0.375000 0.250000 -vt 0.437500 0.253964 -vt 0.437500 0.327165 -vt 0.375000 0.327165 -vt 0.495451 0.253964 -vt 0.495451 0.327165 -vt 0.497089 0.397537 -vt 0.437500 0.393717 -vt 0.375000 0.404329 -vt 0.375000 0.622618 -vt 0.437500 0.623214 -vt 0.437500 0.686309 -vt 0.375000 0.686309 -vt 0.495451 0.623214 -vt 0.495451 0.686309 -vt 0.495451 0.737358 -vt 0.437500 0.737358 -vt 0.375000 0.750000 -vt 0.375000 0.845671 -vt 0.437500 0.856283 -vt 0.437500 0.922835 -vt 0.375000 0.922835 -vt 0.495451 0.856283 -vt 0.495451 0.922835 -vt 0.495451 1.000000 -vt 0.437500 1.000000 -vt 0.375000 1.000000 -vt 0.220671 0.000000 -vt 0.297835 0.000000 -vt 0.297835 0.063691 -vt 0.231283 0.063691 -vt 0.297835 0.126786 -vt 0.231283 0.126786 -vt 0.437500 0.188691 -vt 0.371334 0.188691 -vt 0.495451 0.188691 -vt 0.297835 0.188691 -vt 0.231283 0.188691 -vt 0.297835 0.250000 -vt 0.220671 0.250000 -vt 0.375000 0.500000 -vt 0.437500 0.512047 -vt 0.437500 0.561309 -vt 0.375000 0.561309 -vt 0.497089 0.507710 -vt 0.495451 0.561309 -vt 0.544305 0.515327 -vt 0.544305 0.561309 -vt 0.582083 0.515327 -vt 0.582083 0.561309 -vt 0.582083 0.623214 -vt 0.544305 0.623214 -vt 0.544305 0.686309 -vt 0.544305 0.737358 -vt 0.582083 0.686309 -vt 0.582083 0.737358 -vt 0.544305 0.922835 -vt 0.544305 1.000000 -vt 0.544305 0.856283 -vt 0.582083 0.856283 -vt 0.582083 0.922835 -vt 0.582083 1.000000 -vt 0.544305 0.063691 -vt 0.544305 0.126786 -vt 0.544305 0.000000 -vt 0.582083 0.000000 -vt 0.582083 0.063691 -vt 0.582083 0.126786 -vt 0.544305 0.188691 -vt 0.544305 0.253964 -vt 0.582083 0.188691 -vt 0.582083 0.253964 -vt 0.544305 0.327165 -vt 0.544305 0.385038 -vt 0.582083 0.327165 -vt 0.582083 0.385038 -vt 0.507089 0.470303 -vt 0.511076 0.439044 -vt 0.544305 0.439044 -vt 0.544305 0.468360 -vt 0.511076 0.413008 -vt 0.544305 0.413008 -vt 0.582083 0.413008 -vt 0.582083 0.439044 -vt 0.582083 0.468360 -vt 0.437500 0.439044 -vt 0.375000 0.439044 -vt 0.484375 0.439044 -vt 0.484375 0.468360 -vt 0.437500 0.468360 -vt 0.375000 0.473758 -vt 0.156640 0.126786 -vt 0.185956 0.126786 -vt 0.185956 0.188691 -vt 0.156640 0.188691 -vt 0.185956 0.250000 -vt 0.151242 0.250000 -vt 0.151242 0.000000 -vt 0.185956 0.000000 -vt 0.185956 0.063691 -vt 0.156640 0.063691 -vt 0.375000 0.776242 -vt 0.437500 0.781640 -vt 0.437500 0.810956 -vt 0.375000 0.810956 -vt 0.495451 0.781640 -vt 0.495451 0.810956 -vt 0.544305 0.810956 -vt 0.582083 0.810956 -vt 0.544305 0.781640 -vt 0.582083 0.781640 -vt 0.500000 0.439044 -vt 0.500000 0.468360 -vt 0.511076 0.413008 -vt 0.507089 0.409883 -vt 0.500000 0.439044 -vt 0.500000 0.470303 -vt 0.544305 0.404329 -vt 0.582083 0.404329 -vt 0.582083 0.404329 -vt 0.544305 0.404329 -vt 0.544305 0.500000 -vt 0.582083 0.500000 -vt 0.511076 0.496720 -vt 0.511076 0.496720 -vt 0.544305 0.500000 -vt 0.582083 0.500000 -vt 0.500000 0.458329 -vt 0.500000 0.439044 -vt 0.500000 0.439044 -vt 0.500000 0.465079 -vt 0.500000 0.419758 -vt 0.500000 0.413008 -vt 0.500000 0.413008 -vt 0.500000 0.439044 -vt 0.500000 0.465079 -vt 0.544305 0.404329 -vt 0.511076 0.404329 -vt 0.582083 0.404329 -vt 0.582083 0.404329 -vt 0.544305 0.404329 -vt 0.511076 0.404329 -vt 0.544305 0.500000 -vt 0.582083 0.500000 -vt 0.511076 0.496720 -vt 0.511076 0.496720 -vt 0.544305 0.500000 -vt 0.582083 0.500000 -vt 0.500000 0.439044 -vt 0.500000 0.465079 -vt 0.500000 0.413008 -vt 0.500000 0.419758 -vt 0.500000 0.439044 -vt 0.500000 0.458329 -vt 0.544305 0.404329 -vt 0.511076 0.404329 -vt 0.582083 0.404329 -vt 0.544305 0.500000 -vt 0.582083 0.500000 -vt 0.511076 0.496720 -vt 0.519691 0.494168 -vt 0.544305 0.496720 -vt 0.582083 0.496720 -vt 0.625000 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.561309 -vt 0.625000 0.622618 -vt 0.625000 0.686309 -vt 0.625000 0.750000 -vt 0.625000 0.845671 -vt 0.625000 0.810956 -vt 0.625000 0.776242 -vt 0.625000 0.922835 -vt 0.625000 1.000000 -vt 0.625000 0.000000 -vt 0.625000 0.063691 -vt 0.625000 0.127382 -vt 0.625000 0.188691 -vt 0.625000 0.250000 -vt 0.625000 0.327165 -vt 0.625000 0.404329 -vt 0.625000 0.404329 -vt 0.625000 0.404329 -vt 0.625000 0.404329 -vt 0.625000 0.404329 -vt 0.625000 0.404329 -vt 0.625000 0.404329 -vt 0.625000 0.439044 -vt 0.625000 0.473758 -vt 0.582083 0.486879 -vt 0.625000 0.486879 -vt 0.511076 0.486879 -vt 0.544305 0.486879 -vt 0.500000 0.486879 -vt 0.500000 0.486879 -vt 0.500000 0.477038 -vt 0.500000 0.477038 -vt 0.500000 0.486879 -vt 0.500000 0.486879 -vt 0.500000 0.477038 -vt 0.484375 0.486879 -vt 0.500000 0.486879 -vt 0.437500 0.486879 -vt 0.375000 0.486879 -vt 0.125000 0.127382 -vt 0.138121 0.126786 -vt 0.138121 0.188691 -vt 0.125000 0.188691 -vt 0.138121 0.250000 -vt 0.125000 0.250000 -vt 0.125000 0.000000 -vt 0.138121 0.000000 -vt 0.138121 0.063691 -vt 0.125000 0.063691 -vt 0.437500 0.763121 -vt 0.375000 0.763121 -vt 0.495451 0.763121 -vt 0.544305 0.763121 -vt 0.582083 0.763121 -vt 0.625000 0.763121 -vt 0.500000 0.439044 -vt 0.500000 0.465079 -vt 0.500000 0.413008 -vt 0.500000 0.413008 -vt 0.500000 0.439044 -vt 0.500000 0.465079 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.404329 -vt 0.500000 0.413008 -vt 0.500000 0.413008 -vt 0.500000 0.404329 -vt 0.500000 0.439044 -vt 0.500000 0.465079 -vt 0.500000 0.465079 -vt 0.500000 0.439044 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.413008 -vt 0.500000 0.439044 -vt 0.500000 0.439044 -vt 0.500000 0.413008 -vt 0.500000 0.465079 -vt 0.500000 0.465079 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.413008 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.413008 -vt 0.500000 0.465079 -vt 0.500000 0.439044 -vt 0.500000 0.439044 -vt 0.500000 0.465079 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.439044 -vt 0.500000 0.413008 -vt 0.500000 0.465079 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.413008 -vt 0.500000 0.439044 -vt 0.500000 0.465079 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.375000 0.000000 -vt 0.371334 0.063691 -vt 0.437500 0.063691 -vt 0.437500 0.000000 -vt 0.371334 0.126786 -vt 0.437500 0.126786 -vt 0.495451 0.126786 -vt 0.495451 0.063691 -vt 0.495451 0.000000 -vt 0.375000 0.250000 -vt 0.375000 0.327165 -vt 0.437500 0.327165 -vt 0.437500 0.253964 -vt 0.375000 0.404329 -vt 0.437500 0.393717 -vt 0.497089 0.397537 -vt 0.495451 0.327165 -vt 0.495451 0.253964 -vt 0.375000 0.622618 -vt 0.375000 0.686309 -vt 0.437500 0.686309 -vt 0.437500 0.623214 -vt 0.375000 0.750000 -vt 0.437500 0.737358 -vt 0.495451 0.737358 -vt 0.495451 0.686309 -vt 0.495451 0.623214 -vt 0.375000 0.845671 -vt 0.375000 0.922835 -vt 0.437500 0.922835 -vt 0.437500 0.856283 -vt 0.375000 1.000000 -vt 0.437500 1.000000 -vt 0.495451 1.000000 -vt 0.495451 0.922835 -vt 0.495451 0.856283 -vt 0.220671 0.000000 -vt 0.231283 0.063691 -vt 0.297835 0.063691 -vt 0.297835 0.000000 -vt 0.231283 0.126786 -vt 0.297835 0.126786 -vt 0.371334 0.188691 -vt 0.437500 0.188691 -vt 0.495451 0.188691 -vt 0.231283 0.188691 -vt 0.297835 0.188691 -vt 0.220671 0.250000 -vt 0.297835 0.250000 -vt 0.375000 0.500000 -vt 0.375000 0.561309 -vt 0.437500 0.561309 -vt 0.437500 0.512047 -vt 0.495451 0.561309 -vt 0.497089 0.507710 -vt 0.544305 0.561309 -vt 0.544305 0.515327 -vt 0.544305 0.623214 -vt 0.582083 0.623214 -vt 0.582083 0.561309 -vt 0.582083 0.515327 -vt 0.544305 0.737358 -vt 0.544305 0.686309 -vt 0.582083 0.737358 -vt 0.582083 0.686309 -vt 0.544305 1.000000 -vt 0.544305 0.922835 -vt 0.582083 1.000000 -vt 0.582083 0.922835 -vt 0.582083 0.856283 -vt 0.544305 0.856283 -vt 0.544305 0.126786 -vt 0.544305 0.063691 -vt 0.582083 0.126786 -vt 0.582083 0.063691 -vt 0.582083 0.000000 -vt 0.544305 0.000000 -vt 0.544305 0.253964 -vt 0.544305 0.188691 -vt 0.582083 0.253964 -vt 0.582083 0.188691 -vt 0.544305 0.385038 -vt 0.544305 0.327165 -vt 0.582083 0.385038 -vt 0.582083 0.327165 -vt 0.507089 0.470303 -vt 0.544305 0.468360 -vt 0.544305 0.439044 -vt 0.511076 0.439044 -vt 0.582083 0.468360 -vt 0.582083 0.439044 -vt 0.582083 0.413008 -vt 0.544305 0.413008 -vt 0.511076 0.413008 -vt 0.375000 0.439044 -vt 0.437500 0.439044 -vt 0.375000 0.473758 -vt 0.437500 0.468360 -vt 0.484375 0.468360 -vt 0.484375 0.439044 -vt 0.156640 0.126786 -vt 0.156640 0.188691 -vt 0.185956 0.188691 -vt 0.185956 0.126786 -vt 0.151242 0.250000 -vt 0.185956 0.250000 -vt 0.151242 0.000000 -vt 0.156640 0.063691 -vt 0.185956 0.063691 -vt 0.185956 0.000000 -vt 0.375000 0.776242 -vt 0.375000 0.810956 -vt 0.437500 0.810956 -vt 0.437500 0.781640 -vt 0.495451 0.810956 -vt 0.495451 0.781640 -vt 0.582083 0.810956 -vt 0.544305 0.810956 -vt 0.582083 0.781640 -vt 0.544305 0.781640 -vt 0.500000 0.468360 -vt 0.500000 0.439044 -vt 0.500000 0.470303 -vt 0.500000 0.439044 -vt 0.507089 0.409883 -vt 0.511076 0.413008 -vt 0.544305 0.404329 -vt 0.544305 0.404329 -vt 0.582083 0.404329 -vt 0.582083 0.404329 -vt 0.582083 0.500000 -vt 0.544305 0.500000 -vt 0.582083 0.500000 -vt 0.544305 0.500000 -vt 0.511076 0.496720 -vt 0.511076 0.496720 -vt 0.500000 0.458329 -vt 0.500000 0.465079 -vt 0.500000 0.439044 -vt 0.500000 0.439044 -vt 0.500000 0.465079 -vt 0.500000 0.439044 -vt 0.500000 0.413008 -vt 0.500000 0.413008 -vt 0.500000 0.419758 -vt 0.511076 0.404329 -vt 0.544305 0.404329 -vt 0.511076 0.404329 -vt 0.544305 0.404329 -vt 0.582083 0.404329 -vt 0.582083 0.404329 -vt 0.582083 0.500000 -vt 0.544305 0.500000 -vt 0.582083 0.500000 -vt 0.544305 0.500000 -vt 0.511076 0.496720 -vt 0.511076 0.496720 -vt 0.500000 0.465079 -vt 0.500000 0.439044 -vt 0.500000 0.458329 -vt 0.500000 0.439044 -vt 0.500000 0.419758 -vt 0.500000 0.413008 -vt 0.511076 0.404329 -vt 0.544305 0.404329 -vt 0.582083 0.404329 -vt 0.582083 0.500000 -vt 0.544305 0.500000 -vt 0.582083 0.496720 -vt 0.544305 0.496720 -vt 0.519691 0.494168 -vt 0.511076 0.496720 -vt 0.625000 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.622618 -vt 0.625000 0.561309 -vt 0.625000 0.750000 -vt 0.625000 0.686309 -vt 0.625000 0.845671 -vt 0.625000 0.810956 -vt 0.625000 0.776242 -vt 0.625000 1.000000 -vt 0.625000 0.922835 -vt 0.625000 0.127382 -vt 0.625000 0.063691 -vt 0.625000 0.000000 -vt 0.625000 0.250000 -vt 0.625000 0.188691 -vt 0.625000 0.404329 -vt 0.625000 0.327165 -vt 0.625000 0.404329 -vt 0.625000 0.404329 -vt 0.625000 0.404329 -vt 0.625000 0.404329 -vt 0.625000 0.404329 -vt 0.625000 0.404329 -vt 0.625000 0.473758 -vt 0.625000 0.439044 -vt 0.582083 0.486879 -vt 0.625000 0.486879 -vt 0.544305 0.486879 -vt 0.511076 0.486879 -vt 0.500000 0.486879 -vt 0.500000 0.486879 -vt 0.500000 0.477038 -vt 0.500000 0.477038 -vt 0.500000 0.486879 -vt 0.500000 0.486879 -vt 0.500000 0.477038 -vt 0.500000 0.486879 -vt 0.484375 0.486879 -vt 0.375000 0.486879 -vt 0.437500 0.486879 -vt 0.125000 0.127382 -vt 0.125000 0.188691 -vt 0.138121 0.188691 -vt 0.138121 0.126786 -vt 0.125000 0.250000 -vt 0.138121 0.250000 -vt 0.125000 0.000000 -vt 0.125000 0.063691 -vt 0.138121 0.063691 -vt 0.138121 0.000000 -vt 0.375000 0.763121 -vt 0.437500 0.763121 -vt 0.495451 0.763121 -vt 0.582083 0.763121 -vt 0.544305 0.763121 -vt 0.625000 0.763121 -vt 0.500000 0.465079 -vt 0.500000 0.439044 -vt 0.500000 0.465079 -vt 0.500000 0.439044 -vt 0.500000 0.413008 -vt 0.500000 0.413008 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.413008 -vt 0.500000 0.413008 -vt 0.500000 0.439044 -vt 0.500000 0.439044 -vt 0.500000 0.465079 -vt 0.500000 0.465079 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.413008 -vt 0.500000 0.413008 -vt 0.500000 0.439044 -vt 0.500000 0.439044 -vt 0.500000 0.465079 -vt 0.500000 0.465079 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.413008 -vt 0.500000 0.413008 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.465079 -vt 0.500000 0.465079 -vt 0.500000 0.439044 -vt 0.500000 0.439044 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.413008 -vt 0.500000 0.439044 -vt 0.500000 0.465079 -vt 0.500000 0.404329 -vt 0.500000 0.404329 -vt 0.500000 0.413008 -vt 0.500000 0.404329 -vt 0.500000 0.465079 -vt 0.500000 0.439044 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vt 0.500000 0.473758 -vn 0.085668 -0.959476 -0.268453 -vn 0.237671 -0.590689 -0.771103 -vn 0.428335 -0.851721 -0.301829 -vn 0.115624 -0.987136 -0.110427 -vn 0.302120 0.000000 -0.953270 -vn 0.824926 0.000000 -0.565241 -vn 0.999999 0.000000 0.001599 -vn 0.396028 -0.918225 -0.004941 -vn 0.149934 -0.987495 -0.048723 -vn 0.078432 -0.956844 0.279819 -vn 0.253032 -0.710203 0.656952 -vn -0.008180 -0.663171 0.748423 -vn -0.000647 -0.952219 0.305417 -vn 0.348943 0.000000 0.937144 -vn 0.010148 -0.053063 0.998540 -vn -0.084081 -0.243554 0.966236 -vn -0.102127 -0.712402 0.694301 -vn -0.079449 -0.953396 0.291074 -vn -0.270142 -0.962820 0.000763 -vn -0.950249 -0.311488 -0.001624 -vn -0.886057 -0.290529 -0.361241 -vn -0.254341 -0.959978 -0.117272 -vn -1.000000 0.000000 0.000000 -vn -0.918792 0.000000 -0.394742 -vn -0.522566 0.000000 -0.852599 -vn -0.513619 -0.216278 -0.830313 -vn -0.209017 -0.913432 -0.349219 -vn -0.023808 -0.952843 -0.302527 -vn -0.018633 -0.406711 -0.913367 -vn 0.030609 -0.440480 -0.897241 -vn 0.015159 -0.953383 -0.301381 -vn -0.020275 0.000000 -0.999794 -vn 0.039077 0.000000 -0.999236 -vn 0.027942 -0.986213 -0.163102 -vn -0.049095 -0.991821 -0.117814 -vn 0.035542 -0.997592 -0.059563 -vn -0.079454 -0.996246 -0.034362 -vn 0.394772 -0.889911 0.228506 -vn 0.154277 -0.986454 0.055740 -vn 0.853477 0.000000 0.521131 -vn 0.029024 -0.990960 0.130981 -vn -0.092849 -0.992533 0.079098 -vn -0.272744 -0.942196 0.194623 -vn -0.728062 -0.551187 0.407577 -vn -0.908860 -0.369104 0.194256 -vn -0.263163 -0.961625 0.077609 -vn -0.916248 -0.400528 -0.008150 -vn -0.985529 -0.072412 0.153261 -vn -0.986384 -0.075320 -0.146194 -vn -0.993629 -0.025497 0.109777 -vn -0.984273 0.000000 -0.176652 -vn -0.995982 0.000000 0.089554 -vn -1.000000 0.000000 -0.000000 -vn -1.000000 0.000000 0.000000 -vn -0.918792 0.000000 -0.394742 -vn -0.522566 0.000000 -0.852599 -vn -0.918792 0.000000 -0.394742 -vn -0.522566 0.000000 -0.852599 -vn 0.038195 0.000000 -0.999270 -vn 0.299884 0.000000 -0.953976 -vn -0.020275 0.000000 -0.999794 -vn -0.020275 0.000000 -0.999794 -vn 0.038009 0.000000 -0.999277 -vn 0.296885 0.000000 -0.954913 -vn 0.826662 0.000000 -0.562698 -vn 0.999997 0.000000 0.002501 -vn 0.823003 0.000000 -0.568037 -vn 1.000000 0.000000 -0.000000 -vn 0.853500 0.000000 0.521093 -vn 0.349456 0.000000 0.936953 -vn 0.853500 0.000000 0.521093 -vn 0.346244 0.000000 0.938145 -vn 0.027350 -0.020422 0.999417 -vn -0.036396 -0.054991 0.997823 -vn 0.036285 0.000000 0.999342 -vn -0.017493 0.000000 0.999847 -vn -0.214000 -0.781708 0.585778 -vn -0.084362 -0.685032 0.723612 -vn -0.048808 -0.654888 0.754148 -vn -0.184484 -0.663356 0.725206 -vn 0.452190 -0.620738 0.640475 -vn 0.498851 -0.603148 0.622382 -vn 0.613223 -0.357249 0.704508 -vn -0.032637 -0.409223 0.911851 -vn -0.209848 -0.407611 0.888716 -vn -0.189093 -0.746250 0.638244 -vn -0.080328 -0.983333 0.163107 -vn -0.105419 -0.855710 0.506604 -vn -0.077054 -0.962553 0.259912 -vn -0.163965 -0.836266 0.523235 -vn -0.042853 -0.988052 0.148046 -vn 0.000000 -1.000000 -0.000000 -vn -0.028600 -0.999585 -0.003471 -vn -0.041544 -0.998635 0.031653 -vn -0.005978 -0.999709 0.023377 -vn -0.000261 -0.967301 -0.253630 -vn -0.010304 -0.968353 -0.249372 -vn -0.018918 -0.998656 -0.048249 -vn 0.000863 -0.999440 -0.033437 -vn -0.016708 -0.319725 -0.947363 -vn -0.017408 -0.361435 -0.932235 -vn -0.020274 0.000000 -0.999794 -vn -0.020275 0.000000 -0.999794 -vn -0.020275 0.000000 -0.999794 -vn -0.020275 0.000000 -0.999794 -vn -0.020274 0.000000 -0.999794 -vn -0.020274 0.000000 -0.999794 -vn 0.023604 -0.997107 0.072260 -vn -0.004033 -0.999959 0.008139 -vn 0.107920 -0.800798 0.589131 -vn 0.510420 -0.837864 0.193535 -vn 0.074196 -0.979694 -0.186265 -vn -0.005954 -0.994817 -0.101504 -vn 0.128666 -0.149890 0.980295 -vn 0.174620 0.000000 0.984636 -vn 0.672238 0.000000 0.740335 -vn 0.703779 -0.213098 0.677705 -vn -0.856408 -0.091417 -0.508142 -vn -0.862594 0.000000 -0.505897 -vn -0.741387 -0.499930 -0.447678 -vn -0.778662 -0.488024 -0.394358 -vn -0.898089 -0.088025 -0.430915 -vn -0.901613 0.000000 -0.432544 -vn 0.006371 -0.990514 -0.137263 -vn 0.037645 -0.991796 -0.122161 -vn 0.034456 -0.998626 -0.039487 -vn -0.010145 -0.997613 -0.068309 -vn 0.067745 -0.993255 -0.094102 -vn 0.077784 -0.996873 -0.013922 -vn 0.081192 -0.996694 0.003140 -vn 0.041932 -0.999012 -0.014714 -vn -0.000750 -0.999595 -0.028455 -vn 0.930621 -0.087688 0.355325 -vn 0.936194 -0.208031 0.283310 -vn 0.926870 -0.011419 0.375209 -vn 0.997040 -0.041935 0.064445 -vn 0.990314 -0.082425 0.111732 -vn 0.983308 -0.087172 0.159709 -vn -0.973543 -0.090813 -0.209684 -vn -0.978951 0.002312 -0.204085 -vn -0.829899 -0.519544 -0.203326 -vn -0.851029 -0.524409 -0.027293 -vn -0.995425 -0.095381 -0.005536 -vn -0.999995 -0.001534 0.002744 -vn 0.046857 -0.998886 0.005533 -vn -0.002563 -0.999982 0.005462 -vn 0.096268 -0.995221 0.016381 -vn 0.081317 -0.994520 0.065716 -vn 0.034488 -0.996780 0.072389 -vn -0.004938 -0.998098 0.061443 -vn 0.963640 -0.239836 0.117803 -vn 0.955318 -0.247611 0.161422 -vn 0.988847 -0.128369 0.075522 -vn -0.982754 -0.121219 0.139646 -vn -0.989780 -0.028197 0.139786 -vn -0.843037 -0.524004 0.121283 -vn -0.804521 -0.520309 0.286398 -vn -0.915705 -0.251606 0.313336 -vn -0.945100 -0.105575 0.309258 -vn -0.990700 -0.011623 0.135566 -vn -0.999995 -0.000611 0.003209 -vn -0.952611 -0.045038 0.300838 -vn -0.979215 0.001047 -0.202821 -vn -0.901303 0.000000 -0.433189 -vn -0.862643 0.000000 -0.505814 -vn -0.984273 0.000000 -0.176652 -vn -0.995982 0.000000 0.089554 -vn -1.000000 0.000000 -0.000000 -vn -0.918792 0.000000 -0.394742 -vn -0.522566 0.000000 -0.852599 -vn -0.020275 0.000000 -0.999794 -vn -0.020275 0.000000 -0.999794 -vn -0.020274 0.000000 -0.999795 -vn 0.038009 0.000000 -0.999277 -vn 0.296885 0.000000 -0.954913 -vn 0.823003 0.000000 -0.568037 -vn 1.000000 0.000000 0.000000 -vn 0.853500 0.000000 0.521093 -vn 0.346244 0.000000 0.938145 -vn 0.036285 0.000000 0.999342 -vn -0.017493 0.000000 0.999847 -vn 0.174620 0.000000 0.984636 -vn 0.672238 0.000000 0.740335 -vn 0.929695 -0.004985 0.368297 -vn 0.998548 -0.017614 0.050903 -vn 0.996772 -0.053236 0.060091 -vn 0.655549 -0.180052 0.733373 -vn -0.029985 -0.205126 0.978276 -vn -0.228924 -0.196980 0.953306 -vn -0.551052 -0.330186 0.766368 -vn -0.583129 -0.157090 0.797047 -vn -0.333767 -0.851548 0.404308 -vn -0.457109 -0.606162 0.650861 -vn -0.233719 -0.971427 -0.041301 -vn -0.248692 -0.964673 0.086937 -vn -0.078969 -0.996090 -0.039613 -vn -0.151288 -0.982582 0.107907 -vn -0.189174 -0.968985 -0.159000 -vn -0.216352 -0.969643 -0.113952 -vn -0.049814 -0.994187 -0.095454 -vn -0.183103 -0.961234 0.206163 -vn -0.146686 -0.985655 -0.083476 -vn -0.212120 -0.814551 0.539919 -vn -0.072849 -0.983471 0.165766 -vn -0.031086 -0.999517 0.000212 -vn -0.032675 -0.999056 0.028611 -vn -0.035715 -0.957857 -0.285016 -vn -0.028057 -0.998696 -0.042656 -vn -0.095991 -0.274003 -0.956926 -vn -0.108756 0.000000 -0.994069 -vn -0.108756 0.000000 -0.994069 -vn -0.108756 0.000000 -0.994069 -vn -0.108756 0.000000 -0.994069 -vn 0.156137 -0.550636 -0.820013 -vn -0.153967 -0.688835 -0.708379 -vn 0.567205 -0.567753 -0.596603 -vn 0.632886 0.000000 -0.774245 -vn 0.189600 0.000000 -0.981861 -vn -0.267666 0.000000 -0.963512 -vn 0.968849 -0.204346 0.139906 -vn 0.979325 -0.047448 0.196651 -vn 0.979662 0.000000 0.200657 -vn 0.996823 0.000000 0.079651 -vn -0.679167 -0.681272 -0.273130 -vn -0.836309 -0.547920 -0.019265 -vn -0.953620 0.000000 -0.301014 -vn -1.000000 0.000000 0.000000 -vn 0.965444 -0.141132 0.219090 -vn 0.468008 -0.406155 0.784861 -vn 0.470905 0.000000 0.882184 -vn 0.967273 0.000000 0.253736 -vn -0.163238 -0.478153 0.862974 -vn -0.490663 -0.576235 0.653608 -vn -0.692420 0.000000 0.721495 -vn -0.211081 0.000000 0.977469 -vn -0.777435 -0.597079 0.197714 -vn -0.982630 0.000000 0.185576 -vn 0.462823 0.000000 0.886451 -vn -0.215875 0.000000 0.976421 -vn -0.098549 -0.765505 0.635838 -vn 0.328367 -0.775801 0.538802 -vn -0.696291 0.000000 0.717760 -vn -0.424480 -0.778986 0.461517 -vn 0.979662 0.000000 0.200657 -vn 0.967053 0.000000 0.254576 -vn 0.507766 -0.852500 0.124167 -vn 0.442141 -0.892828 0.085841 -vn 0.632886 0.000000 -0.774245 -vn 0.996823 0.000000 0.079651 -vn 0.487131 -0.872465 0.038837 -vn 0.431359 -0.756068 -0.492230 -vn -0.275654 0.000000 -0.961257 -vn 0.189154 0.000000 -0.981947 -vn 0.140821 -0.697493 -0.702619 -vn -0.180674 -0.732644 -0.656193 -vn -1.000000 0.000000 0.000000 -vn -0.956630 0.000000 -0.291306 -vn -0.436671 -0.879401 -0.189666 -vn -0.408224 -0.912160 -0.036288 -vn -0.982640 0.000000 0.185525 -vn -0.466253 -0.881234 0.077683 -vn -0.213491 0.000000 0.976945 -vn 0.466827 0.000000 0.884349 -vn -0.694362 0.000000 0.719626 -vn 0.967162 0.000000 0.254159 -vn 0.979662 0.000000 0.200657 -vn 0.996823 0.000000 0.079651 -vn 0.632886 0.000000 -0.774245 -vn 0.189376 0.000000 -0.981905 -vn -0.271698 0.000000 -0.962383 -vn -0.955146 0.000000 -0.296137 -vn -1.000000 0.000000 0.000000 -vn -0.982635 0.000000 0.185551 -vn 0.088281 0.964432 -0.249152 -vn 0.114329 0.987183 -0.111354 -vn 0.412228 0.858586 -0.304792 -vn 0.232420 0.605022 -0.761531 -vn 0.149106 0.987172 -0.057090 -vn 0.387470 0.921825 -0.010259 -vn 0.999999 0.000000 0.001599 -vn 0.824926 0.000000 -0.565241 -vn 0.302120 0.000000 -0.953270 -vn 0.078432 0.956844 0.279819 -vn -0.000647 0.952219 0.305417 -vn -0.008180 0.663171 0.748423 -vn 0.253032 0.710203 0.656952 -vn -0.079449 0.953396 0.291074 -vn -0.102127 0.712402 0.694301 -vn -0.084081 0.243554 0.966236 -vn 0.010148 0.053063 0.998540 -vn 0.348942 0.000000 0.937144 -vn -0.270142 0.962820 0.000763 -vn -0.254341 0.959978 -0.117272 -vn -0.886058 0.290529 -0.361241 -vn -0.950249 0.311487 -0.001624 -vn -0.209017 0.913432 -0.349219 -vn -0.513619 0.216278 -0.830313 -vn -0.522566 0.000000 -0.852599 -vn -0.918792 0.000000 -0.394742 -vn -1.000000 0.000000 0.000000 -vn -0.023808 0.952843 -0.302527 -vn 0.016826 0.954930 -0.296353 -vn 0.030609 0.440480 -0.897241 -vn -0.018633 0.406711 -0.913367 -vn 0.039077 0.000000 -0.999236 -vn -0.020275 0.000000 -0.999794 -vn -0.049095 0.991821 -0.117814 -vn 0.031793 0.985982 -0.163795 -vn -0.079454 0.996246 -0.034362 -vn 0.038142 0.997144 -0.065190 -vn 0.154277 0.986454 0.055740 -vn 0.394772 0.889910 0.228506 -vn 0.853477 0.000000 0.521131 -vn -0.092849 0.992533 0.079098 -vn 0.029024 0.990960 0.130981 -vn -0.272744 0.942195 0.194624 -vn -0.263163 0.961625 0.077609 -vn -0.908860 0.369104 0.194256 -vn -0.728062 0.551187 0.407577 -vn -0.985529 0.072412 0.153261 -vn -0.916248 0.400528 -0.008150 -vn -0.993629 0.025497 0.109777 -vn -0.986384 0.075320 -0.146194 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 -0.000000 -vn -0.995982 0.000000 0.089554 -vn -0.984273 0.000000 -0.176652 -vn -0.522566 0.000000 -0.852599 -vn -0.918792 0.000000 -0.394742 -vn -0.522566 0.000000 -0.852599 -vn -0.918792 0.000000 -0.394742 -vn 0.299884 0.000000 -0.953976 -vn 0.038195 0.000000 -0.999270 -vn 0.296885 0.000000 -0.954913 -vn 0.038009 0.000000 -0.999277 -vn -0.020275 0.000000 -0.999794 -vn -0.020275 0.000000 -0.999794 -vn 0.999997 0.000000 0.002501 -vn 0.826662 0.000000 -0.562698 -vn 1.000000 0.000000 -0.000000 -vn 0.823003 0.000000 -0.568037 -vn 0.349456 0.000000 0.936953 -vn 0.853500 0.000000 0.521093 -vn 0.346244 0.000000 0.938145 -vn 0.853500 0.000000 0.521093 -vn -0.036396 0.054991 0.997823 -vn 0.027350 0.020422 0.999417 -vn -0.017493 0.000000 0.999847 -vn 0.036285 0.000000 0.999342 -vn -0.214000 0.781708 0.585778 -vn -0.184484 0.663356 0.725206 -vn -0.048808 0.654888 0.754148 -vn -0.084362 0.685032 0.723612 -vn -0.209848 0.407611 0.888716 -vn -0.032637 0.409223 0.911851 -vn 0.613223 0.357249 0.704508 -vn 0.498851 0.603148 0.622382 -vn 0.452190 0.620738 0.640475 -vn -0.080328 0.983333 0.163107 -vn -0.189093 0.746250 0.638243 -vn -0.042853 0.988052 0.148046 -vn -0.163965 0.836266 0.523235 -vn -0.077054 0.962553 0.259912 -vn -0.105419 0.855710 0.506604 -vn 0.000000 1.000000 -0.000000 -vn -0.005978 0.999709 0.023377 -vn -0.041544 0.998635 0.031653 -vn -0.028600 0.999585 -0.003471 -vn -0.000261 0.967301 -0.253631 -vn 0.000863 0.999440 -0.033437 -vn -0.018918 0.998656 -0.048248 -vn -0.010304 0.968353 -0.249372 -vn -0.017408 0.361435 -0.932235 -vn -0.016708 0.319725 -0.947363 -vn -0.020275 0.000000 -0.999794 -vn -0.020274 0.000000 -0.999794 -vn -0.020275 0.000000 -0.999794 -vn -0.020275 0.000000 -0.999794 -vn -0.020274 0.000000 -0.999794 -vn -0.020274 0.000000 -0.999794 -vn -0.004033 0.999959 0.008139 -vn 0.023604 0.997107 0.072260 -vn -0.005954 0.994817 -0.101504 -vn 0.074196 0.979694 -0.186265 -vn 0.510420 0.837864 0.193535 -vn 0.107920 0.800798 0.589131 -vn 0.128666 0.149890 0.980295 -vn 0.703779 0.213098 0.677705 -vn 0.672238 0.000000 0.740335 -vn 0.174620 0.000000 0.984636 -vn -0.862594 0.000000 -0.505897 -vn -0.856408 0.091416 -0.508142 -vn -0.901613 0.000000 -0.432544 -vn -0.898089 0.088025 -0.430915 -vn -0.778662 0.488024 -0.394358 -vn -0.741387 0.499930 -0.447678 -vn 0.006371 0.990514 -0.137263 -vn -0.010145 0.997613 -0.068309 -vn 0.034456 0.998626 -0.039487 -vn 0.037645 0.991796 -0.122161 -vn -0.000750 0.999595 -0.028455 -vn 0.041932 0.999012 -0.014715 -vn 0.081192 0.996694 0.003140 -vn 0.077784 0.996873 -0.013922 -vn 0.067745 0.993255 -0.094101 -vn 0.936194 0.208031 0.283310 -vn 0.930621 0.087688 0.355325 -vn 0.983308 0.087172 0.159709 -vn 0.990314 0.082425 0.111732 -vn 0.997040 0.041935 0.064445 -vn 0.926870 0.011419 0.375209 -vn -0.978951 -0.002312 -0.204085 -vn -0.973543 0.090813 -0.209684 -vn -0.999995 0.001534 0.002744 -vn -0.995426 0.095381 -0.005536 -vn -0.851029 0.524409 -0.027293 -vn -0.829899 0.519544 -0.203326 -vn -0.002563 0.999982 0.005462 -vn 0.046857 0.998886 0.005533 -vn -0.004938 0.998098 0.061443 -vn 0.034488 0.996780 0.072389 -vn 0.081317 0.994520 0.065716 -vn 0.096268 0.995221 0.016381 -vn 0.955318 0.247611 0.161422 -vn 0.963640 0.239836 0.117803 -vn 0.988847 0.128369 0.075522 -vn -0.989780 0.028197 0.139786 -vn -0.982754 0.121218 0.139646 -vn -0.945100 0.105575 0.309258 -vn -0.915705 0.251606 0.313337 -vn -0.804520 0.520311 0.286397 -vn -0.843037 0.524003 0.121282 -vn -0.999995 0.000611 0.003209 -vn -0.990700 0.011623 0.135566 -vn -0.952611 0.045038 0.300838 -vn -0.901303 0.000000 -0.433189 -vn -0.979215 -0.001047 -0.202821 -vn -0.984273 0.000000 -0.176652 -vn -0.862643 0.000000 -0.505814 -vn -1.000000 0.000000 -0.000000 -vn -0.995982 0.000000 0.089554 -vn -0.522566 0.000000 -0.852599 -vn -0.918792 0.000000 -0.394742 -vn -0.020275 0.000000 -0.999794 -vn -0.020275 0.000000 -0.999794 -vn -0.020274 0.000000 -0.999795 -vn 0.296885 0.000000 -0.954913 -vn 0.038009 0.000000 -0.999277 -vn 1.000000 0.000000 0.000000 -vn 0.823003 0.000000 -0.568037 -vn 0.346244 0.000000 0.938145 -vn 0.853500 0.000000 0.521093 -vn -0.017493 0.000000 0.999847 -vn 0.036285 0.000000 0.999342 -vn 0.672238 0.000000 0.740335 -vn 0.174620 0.000000 0.984636 -vn 0.998548 0.017614 0.050903 -vn 0.929695 0.004985 0.368297 -vn 0.655549 0.180052 0.733373 -vn 0.996772 0.053236 0.060091 -vn -0.228924 0.196980 0.953306 -vn -0.029985 0.205126 0.978276 -vn -0.551051 0.330186 0.766368 -vn -0.583129 0.157090 0.797047 -vn -0.457108 0.606162 0.650861 -vn -0.333764 0.851549 0.404309 -vn -0.248688 0.964674 0.086935 -vn -0.233719 0.971427 -0.041301 -vn -0.151288 0.982582 0.107907 -vn -0.078969 0.996090 -0.039613 -vn -0.216352 0.969643 -0.113952 -vn -0.189174 0.968985 -0.159000 -vn -0.049814 0.994187 -0.095454 -vn -0.146686 0.985655 -0.083476 -vn -0.183103 0.961234 0.206163 -vn -0.072849 0.983471 0.165766 -vn -0.212120 0.814551 0.539919 -vn -0.032675 0.999056 0.028611 -vn -0.031085 0.999517 0.000212 -vn -0.028057 0.998696 -0.042655 -vn -0.035715 0.957857 -0.285016 -vn -0.095991 0.274003 -0.956927 -vn -0.108756 0.000000 -0.994069 -vn -0.108756 0.000000 -0.994069 -vn -0.108756 0.000000 -0.994069 -vn -0.108756 0.000000 -0.994069 -vn -0.153967 0.688835 -0.708379 -vn 0.156137 0.550636 -0.820013 -vn -0.267666 0.000000 -0.963512 -vn 0.189600 0.000000 -0.981861 -vn 0.632886 0.000000 -0.774245 -vn 0.567205 0.567753 -0.596603 -vn 0.968849 0.204346 0.139906 -vn 0.996823 0.000000 0.079651 -vn 0.979662 0.000000 0.200657 -vn 0.979325 0.047448 0.196651 -vn -0.836309 0.547920 -0.019265 -vn -0.679168 0.681272 -0.273131 -vn -1.000000 0.000000 0.000000 -vn -0.953620 0.000000 -0.301014 -vn 0.965444 0.141132 0.219090 -vn 0.967274 0.000000 0.253736 -vn 0.470905 0.000000 0.882184 -vn 0.468008 0.406155 0.784861 -vn -0.163238 0.478152 0.862974 -vn -0.211081 0.000000 0.977469 -vn -0.692420 0.000000 0.721495 -vn -0.490663 0.576235 0.653608 -vn -0.777435 0.597079 0.197715 -vn -0.982630 0.000000 0.185576 -vn 0.462823 0.000000 0.886451 -vn 0.328367 0.775801 0.538802 -vn -0.098548 0.765505 0.635838 -vn -0.215875 0.000000 0.976421 -vn -0.424480 0.778986 0.461517 -vn -0.696291 0.000000 0.717760 -vn 0.979662 0.000000 0.200657 -vn 0.442141 0.892828 0.085841 -vn 0.507766 0.852500 0.124167 -vn 0.967053 0.000000 0.254576 -vn 0.632886 0.000000 -0.774245 -vn 0.431359 0.756068 -0.492230 -vn 0.487131 0.872465 0.038837 -vn 0.996823 0.000000 0.079651 -vn -0.275654 0.000000 -0.961257 -vn -0.180674 0.732644 -0.656193 -vn 0.140821 0.697493 -0.702619 -vn 0.189154 0.000000 -0.981947 -vn -1.000000 0.000000 0.000000 -vn -0.408224 0.912160 -0.036288 -vn -0.436671 0.879401 -0.189666 -vn -0.956630 0.000000 -0.291306 -vn -0.466253 0.881234 0.077683 -vn -0.982640 0.000000 0.185525 -vn 0.466827 0.000000 0.884349 -vn -0.213491 0.000000 0.976945 -vn -0.694362 0.000000 0.719626 -vn 0.979662 0.000000 0.200657 -vn 0.967162 0.000000 0.254159 -vn 0.632886 0.000000 -0.774245 -vn 0.996823 0.000000 0.079651 -vn -0.271698 0.000000 -0.962383 -vn 0.189376 0.000000 -0.981905 -vn -1.000000 0.000000 0.000000 -vn -0.955146 0.000000 -0.296137 -vn -0.982635 0.000000 0.185551 -s 1 -g body_geo -usemtl blinn4SG -f 821/1369/1333 1237/1370/1334 1255/1371/1335 1238/1372/1336 -f 1237/1370/1334 836/1373/1337 1239/1374/1338 1255/1371/1335 -f 1255/1371/1335 1239/1374/1338 837/1375/1339 1240/1376/1340 -f 1238/1372/1336 1255/1371/1335 1240/1376/1340 830/1377/1341 -f 823/1378/1342 1241/1379/1343 1256/1380/1344 1242/1381/1345 -f 1241/1379/1343 838/1382/1346 1243/1383/1347 1256/1380/1344 -f 1256/1380/1344 1243/1383/1347 840/1384/1348 1244/1385/1349 -f 1242/1381/1345 1256/1380/1344 1244/1385/1349 841/1386/1350 -f 831/1387/1351 1245/1388/1352 1257/1389/1353 1246/1390/1354 -f 1245/1388/1352 834/1391/1355 1247/1392/1356 1257/1389/1353 -f 1257/1389/1353 1247/1392/1356 835/1393/1357 1248/1394/1358 -f 1246/1390/1354 1257/1389/1353 1248/1394/1358 827/1395/1359 -f 843/1396/1360 1249/1397/1361 1258/1398/1362 1250/1399/1363 -f 1249/1397/1361 844/1400/1364 1251/1401/1365 1258/1398/1362 -f 1258/1398/1362 1251/1401/1365 836/1402/1337 1237/1403/1334 -f 1250/1399/1363 1258/1398/1362 1237/1403/1334 821/1404/1333 -f 843/1405/1360 1250/1406/1363 1259/1407/1366 1252/1408/1367 -f 1250/1406/1363 821/1369/1333 1238/1372/1336 1259/1407/1366 -f 1259/1407/1366 1238/1372/1336 830/1377/1341 1253/1409/1368 -f 1252/1408/1367 1259/1407/1366 1253/1409/1368 842/1410/1369 -f 830/1377/1341 1240/1376/1340 1260/1411/1370 1254/1412/1371 -f 1240/1376/1340 837/1375/1339 983/1413/1372 1260/1411/1370 -f 1260/1411/1370 983/1413/1372 838/1382/1346 1241/1379/1343 -f 1254/1412/1371 1260/1411/1370 1241/1379/1343 823/1378/1342 -f 842/1410/1369 1253/1409/1368 1261/1414/1373 984/1415/1374 -f 1253/1409/1368 830/1377/1341 1254/1412/1371 1261/1414/1373 -f 1261/1414/1373 1254/1412/1371 823/1378/1342 1242/1416/1345 -f 984/1415/1374 1261/1414/1373 1242/1416/1345 841/1417/1350 -f 825/1418/1375 985/1419/1376 1262/1420/1377 986/1421/1378 -f 985/1419/1376 833/1422/1379 987/1423/1380 1262/1420/1377 -f 1262/1420/1377 987/1423/1380 834/1391/1355 1245/1388/1352 -f 986/1421/1378 1262/1420/1377 1245/1388/1352 831/1387/1351 -f 833/1422/1379 988/1424/1381 1263/1425/1382 987/1423/1380 -f 988/1424/1381 861/1426/1383 989/1427/1384 1263/1425/1382 -f 1263/1425/1382 989/1427/1384 862/1428/1385 990/1429/1386 -f 987/1423/1380 1263/1425/1382 990/1429/1386 834/1391/1355 -f 835/1393/1357 1247/1392/1356 1264/1430/1387 991/1431/1388 -f 1247/1392/1356 834/1391/1355 990/1429/1386 1264/1430/1387 -f 1264/1430/1387 990/1429/1386 862/1428/1385 992/1432/1389 -f 991/1431/1388 1264/1430/1387 992/1432/1389 863/1433/1390 -f 836/1402/1337 1251/1401/1365 1265/1434/1391 993/1435/1392 -f 1251/1401/1365 844/1400/1364 994/1436/1393 1265/1434/1391 -f 1265/1434/1391 994/1436/1393 864/1437/1394 995/1438/1395 -f 993/1435/1392 1265/1434/1391 995/1438/1395 865/1439/1396 -f 837/1375/1339 1239/1374/1338 1266/1440/1397 996/1441/1398 -f 1239/1374/1338 836/1373/1337 993/1442/1392 1266/1440/1397 -f 1266/1440/1397 993/1442/1392 865/1443/1396 997/1444/1399 -f 996/1441/1398 1266/1440/1397 997/1444/1399 866/1445/1400 -f 838/1382/1346 983/1413/1372 1267/1446/1401 998/1447/1402 -f 983/1413/1372 837/1375/1339 996/1441/1398 1267/1446/1401 -f 1267/1446/1401 996/1441/1398 866/1445/1400 999/1448/1403 -f 998/1447/1402 1267/1446/1401 999/1448/1403 867/1449/1404 -f 840/1384/1348 1243/1383/1347 1268/1450/1405 1000/1451/1406 -f 1243/1383/1347 838/1382/1346 998/1447/1402 1268/1450/1405 -f 1268/1450/1405 998/1447/1402 867/1449/1404 1001/1452/1407 -f 1000/1451/1406 1268/1450/1405 1001/1452/1407 868/1453/1408 -f 874/1454/1409 1002/1455/1410 1269/1456/1411 1003/1457/1412 -f 1002/1455/1410 854/1458/1413 1004/1459/1414 1269/1456/1411 -f 1269/1456/1411 1004/1459/1414 871/1460/1415 1005/1461/1416 -f 1003/1457/1412 1269/1456/1411 1005/1461/1416 873/1462/1417 -f 841/1386/1350 1244/1385/1349 1270/1463/1418 1006/1464/1419 -f 1244/1385/1349 840/1384/1348 1007/1465/1420 1270/1463/1418 -f 1270/1463/1418 1007/1465/1420 877/1466/1421 1008/1467/1422 -f 1006/1464/1419 1270/1463/1418 1008/1467/1422 878/1468/1423 -f 879/1469/1424 1009/1470/1425 1271/1471/1426 1010/1472/1427 -f 1009/1470/1425 842/1410/1369 984/1415/1374 1271/1471/1426 -f 1271/1471/1426 984/1415/1374 841/1417/1350 1006/1473/1419 -f 1010/1472/1427 1271/1471/1426 1006/1473/1419 878/1474/1423 -f 880/1475/1428 1011/1476/1429 1272/1477/1430 1012/1478/1431 -f 1011/1476/1429 843/1405/1360 1252/1408/1367 1272/1477/1430 -f 1272/1477/1430 1252/1408/1367 842/1410/1369 1009/1470/1425 -f 1012/1478/1431 1272/1477/1430 1009/1470/1425 879/1469/1424 -f 880/1479/1428 1013/1480/1432 1273/1481/1433 1011/1482/1429 -f 1013/1480/1432 881/1483/1434 1014/1484/1435 1273/1481/1433 -f 1273/1481/1433 1014/1484/1435 844/1400/1364 1249/1397/1361 -f 1011/1482/1429 1273/1481/1433 1249/1397/1361 843/1396/1360 -f 864/1437/1394 994/1436/1393 1274/1485/1436 1015/1486/1437 -f 994/1436/1393 844/1400/1364 1014/1484/1435 1274/1485/1436 -f 1274/1485/1436 1014/1484/1435 881/1483/1434 1016/1487/1438 -f 1015/1486/1437 1274/1485/1436 1016/1487/1438 882/1488/1439 -f 877/1466/1421 1007/1465/1420 1275/1489/1440 1017/1490/1441 -f 1007/1465/1420 840/1384/1348 1018/1491/1442 1275/1489/1440 -f 1275/1489/1440 1018/1491/1442 846/1492/1443 1019/1493/1444 -f 1017/1490/1441 1275/1489/1440 1019/1493/1444 876/1494/1445 -f 840/1384/1348 1000/1451/1406 1276/1495/1446 1018/1491/1442 -f 1000/1451/1406 868/1453/1408 1020/1496/1447 1276/1495/1446 -f 1276/1495/1446 1020/1496/1447 869/1497/1448 1021/1498/1449 -f 1018/1491/1442 1276/1495/1446 1021/1498/1449 846/1492/1443 -f 861/1426/1383 988/1424/1381 1277/1499/1450 1022/1500/1451 -f 988/1424/1381 833/1422/1379 1023/1501/1452 1277/1499/1450 -f 1277/1499/1450 1023/1501/1452 847/1502/1453 1024/1503/1454 -f 1022/1500/1451 1277/1499/1450 1024/1503/1454 860/1504/1455 -f 885/1505/1456 1025/1506/1457 1278/1507/1458 1026/1508/1459 -f 1025/1506/1457 884/1509/1460 1027/1510/1461 1278/1507/1458 -f 1278/1507/1458 1027/1510/1461 886/1511/1462 1028/1512/1463 -f 1026/1508/1459 1278/1507/1458 1028/1512/1463 887/1513/1464 -f 846/1492/1443 1021/1498/1449 1279/1514/1465 1029/1515/1466 -f 1021/1498/1449 869/1497/1448 1030/1516/1467 1279/1514/1465 -f 1279/1514/1465 1030/1516/1467 870/1517/1468 1031/1518/1469 -f 1029/1515/1466 1279/1514/1465 1031/1518/1469 850/1519/1470 -f 860/1504/1455 1024/1503/1454 1280/1520/1471 1032/1521/1472 -f 1024/1503/1454 847/1502/1453 1033/1522/1473 1280/1520/1471 -f 1280/1520/1471 1033/1522/1473 851/1523/1474 1034/1524/1475 -f 1032/1521/1472 1280/1520/1471 1034/1524/1475 859/1525/1476 -f 887/1513/1464 1028/1512/1463 1281/1526/1477 1035/1527/1478 -f 1028/1512/1463 886/1511/1462 1036/1528/1479 1281/1526/1477 -f 1281/1526/1477 1036/1528/1479 888/1529/1480 1037/1530/1481 -f 1035/1527/1478 1281/1526/1477 1037/1530/1481 889/1531/1482 -f 850/1519/1470 1031/1518/1469 1282/1532/1483 1038/1533/1484 -f 1031/1518/1469 870/1517/1468 1039/1534/1485 1282/1532/1483 -f 1282/1532/1483 1039/1534/1485 871/1460/1415 1004/1459/1414 -f 1038/1533/1484 1282/1532/1483 1004/1459/1414 854/1458/1413 -f 859/1525/1476 1034/1524/1475 1283/1535/1486 1040/1536/1487 -f 1034/1524/1475 851/1523/1474 1041/1537/1488 1283/1535/1486 -f 1283/1535/1486 1041/1537/1488 855/1538/1489 1042/1539/1490 -f 1040/1536/1487 1283/1535/1486 1042/1539/1490 858/1540/1491 -f 1043/1542/1492 853/1541/1493 859/1525/1476 1040/1536/1487 -f 1043/1542/1492 1040/1536/1487 858/1540/1491 857/1543/1494 -f 1044/1545/1495 849/1544/1496 860/1504/1455 1032/1521/1472 -f 1044/1545/1495 1032/1521/1472 859/1525/1476 853/1541/1493 -f 1045/1547/1497 826/1546/1498 861/1426/1383 1022/1500/1451 -f 1045/1547/1497 1022/1500/1451 860/1504/1455 849/1544/1496 -f 862/1428/1385 989/1427/1384 1046/1548/1499 832/1549/1500 -f 989/1427/1384 861/1426/1383 826/1546/1498 1046/1548/1499 -f 863/1433/1390 992/1432/1389 1047/1550/1501 828/1551/1502 -f 992/1432/1389 862/1428/1385 832/1549/1500 1047/1550/1501 -f 1048/1553/1503 845/1552/1504 864/1437/1394 1015/1486/1437 -f 1048/1553/1503 1015/1486/1437 882/1488/1439 883/1554/1505 -f 865/1439/1396 995/1438/1395 1049/1555/1506 822/1556/1507 -f 995/1438/1395 864/1437/1394 845/1552/1504 1049/1555/1506 -f 866/1445/1400 997/1444/1399 1050/1558/1508 829/1559/1509 -f 997/1444/1399 865/1443/1396 822/1557/1507 1050/1558/1508 -f 867/1449/1404 999/1448/1403 1051/1560/1510 824/1561/1511 -f 999/1448/1403 866/1445/1400 829/1559/1509 1051/1560/1510 -f 868/1453/1408 1001/1452/1407 1052/1562/1512 839/1563/1513 -f 1001/1452/1407 867/1449/1404 824/1561/1511 1052/1562/1512 -f 869/1497/1448 1020/1496/1447 1053/1564/1514 848/1565/1515 -f 1020/1496/1447 868/1453/1408 839/1563/1513 1053/1564/1514 -f 870/1517/1468 1030/1516/1467 1054/1566/1516 852/1567/1517 -f 1030/1516/1467 869/1497/1448 848/1565/1515 1054/1566/1516 -f 871/1460/1415 1039/1534/1485 1055/1568/1518 856/1569/1519 -f 1039/1534/1485 870/1517/1468 852/1567/1517 1055/1568/1518 -f 873/1462/1417 1005/1461/1416 1056/1570/1520 872/1571/1521 -f 1005/1461/1416 871/1460/1415 856/1569/1519 1056/1570/1520 -f 857/1543/1494 858/1540/1491 1057/1572/1522 1058/1573/1523 -f 1057/1572/1522 873/1462/1417 872/1571/1521 1058/1573/1523 -f 855/1538/1489 1059/1574/1524 1284/1575/1525 1042/1539/1490 -f 1059/1574/1524 874/1454/1409 1003/1457/1412 1284/1575/1525 -f 1284/1575/1525 1003/1457/1412 873/1462/1417 1057/1572/1522 -f 1042/1539/1490 1284/1575/1525 1057/1572/1522 858/1540/1491 -f 851/1523/1474 1060/1576/1526 1285/1577/1527 1041/1537/1488 -f 1060/1576/1526 875/1578/1528 1061/1579/1529 1285/1577/1527 -f 1285/1577/1527 1061/1579/1529 874/1454/1409 1059/1574/1524 -f 1041/1537/1488 1285/1577/1527 1059/1574/1524 855/1538/1489 -f 847/1502/1453 1062/1580/1530 1286/1581/1531 1033/1522/1473 -f 1062/1580/1530 876/1494/1445 1063/1582/1532 1286/1581/1531 -f 1286/1581/1531 1063/1582/1532 875/1578/1528 1060/1576/1526 -f 1033/1522/1473 1286/1581/1531 1060/1576/1526 851/1523/1474 -f 833/1422/1379 1064/1583/1533 1287/1584/1534 1023/1501/1452 -f 1064/1583/1533 877/1466/1421 1017/1490/1441 1287/1584/1534 -f 1287/1584/1534 1017/1490/1441 876/1494/1445 1062/1580/1530 -f 1023/1501/1452 1287/1584/1534 1062/1580/1530 847/1502/1453 -f 878/1468/1423 1008/1467/1422 1288/1585/1535 1065/1586/1536 -f 1008/1467/1422 877/1466/1421 1064/1583/1533 1288/1585/1535 -f 1288/1585/1535 1064/1583/1533 833/1422/1379 985/1419/1376 -f 1065/1586/1536 1288/1585/1535 985/1419/1376 825/1418/1375 -f 831/1587/1351 1066/1588/1537 1289/1589/1538 986/1590/1378 -f 1066/1588/1537 879/1469/1424 1010/1472/1427 1289/1589/1538 -f 1289/1589/1538 1010/1472/1427 878/1474/1423 1065/1591/1536 -f 986/1590/1378 1289/1589/1538 1065/1591/1536 825/1592/1375 -f 827/1593/1359 1067/1594/1539 1290/1595/1540 1246/1596/1354 -f 1067/1594/1539 880/1475/1428 1012/1478/1431 1290/1595/1540 -f 1290/1595/1540 1012/1478/1431 879/1469/1424 1066/1588/1537 -f 1246/1596/1354 1290/1595/1540 1066/1588/1537 831/1587/1351 -f 827/1395/1359 1248/1394/1358 1291/1597/1541 1067/1598/1539 -f 1248/1394/1358 835/1393/1357 1068/1599/1542 1291/1597/1541 -f 1291/1597/1541 1068/1599/1542 881/1483/1434 1013/1480/1432 -f 1067/1598/1539 1291/1597/1541 1013/1480/1432 880/1479/1428 -f 882/1488/1439 1016/1487/1438 1292/1600/1543 1069/1601/1544 -f 1016/1487/1438 881/1483/1434 1068/1599/1542 1292/1600/1543 -f 1292/1600/1543 1068/1599/1542 835/1393/1357 991/1431/1388 -f 1069/1601/1544 1292/1600/1543 991/1431/1388 863/1433/1390 -f 1070/1602/1545 883/1554/1505 882/1488/1439 1069/1601/1544 -f 1070/1602/1545 1069/1601/1544 863/1433/1390 828/1551/1502 -f 876/1494/1445 1019/1493/1444 1293/1603/1546 1071/1604/1547 -f 1019/1493/1444 846/1492/1443 1072/1605/1548 1293/1603/1546 -f 1293/1603/1546 1072/1605/1548 899/1606/1549 1073/1607/1550 -f 1071/1604/1547 1293/1603/1546 1073/1607/1550 900/1608/1551 -f 846/1492/1443 1029/1515/1466 1294/1609/1552 1072/1605/1548 -f 1029/1515/1466 850/1519/1470 1074/1610/1553 1294/1609/1552 -f 1294/1609/1552 1074/1610/1553 898/1611/1554 1075/1612/1555 -f 1072/1605/1548 1294/1609/1552 1075/1612/1555 899/1606/1549 -f 875/1578/1528 1063/1582/1532 1295/1613/1556 1076/1614/1557 -f 1063/1582/1532 876/1494/1445 1071/1604/1547 1295/1613/1556 -f 1295/1613/1556 1071/1604/1547 900/1608/1551 1077/1615/1558 -f 1076/1614/1557 1295/1613/1556 1077/1615/1558 901/1616/1559 -f 850/1519/1470 1038/1533/1484 1296/1617/1560 1074/1610/1553 -f 1038/1533/1484 854/1458/1413 1078/1618/1561 1296/1617/1560 -f 1296/1617/1560 1078/1618/1561 897/1619/1562 1079/1620/1563 -f 1074/1610/1553 1296/1617/1560 1079/1620/1563 898/1611/1554 -f 854/1458/1413 1002/1455/1410 1297/1621/1564 1078/1618/1561 -f 1002/1455/1410 874/1454/1409 1080/1622/1565 1297/1621/1564 -f 1297/1621/1564 1080/1622/1565 896/1623/1566 1081/1624/1567 -f 1078/1618/1561 1297/1621/1564 1081/1624/1567 897/1619/1562 -f 874/1454/1409 1061/1579/1529 1298/1625/1568 1080/1622/1565 -f 1061/1579/1529 875/1578/1528 1076/1614/1557 1298/1625/1568 -f 1298/1625/1568 1076/1614/1557 901/1616/1559 1082/1626/1569 -f 1080/1622/1565 1298/1625/1568 1082/1626/1569 896/1623/1566 -f 891/1627/1570 1083/1628/1571 1299/1629/1572 1084/1630/1573 -f 1083/1628/1571 890/1631/1574 1085/1632/1575 1299/1629/1572 -f 1299/1629/1572 1085/1632/1575 889/1531/1482 1037/1530/1481 -f 1084/1630/1573 1299/1629/1572 1037/1530/1481 888/1529/1480 -f 892/1633/1576 1086/1634/1577 1300/1635/1578 1087/1636/1579 -f 1086/1634/1577 891/1627/1570 1084/1630/1573 1300/1635/1578 -f 1300/1635/1578 1084/1630/1573 888/1529/1480 1036/1528/1479 -f 1087/1636/1579 1300/1635/1578 1036/1528/1479 886/1511/1462 -f 893/1637/1580 1088/1638/1581 1301/1639/1582 1089/1640/1583 -f 1088/1638/1581 892/1633/1576 1087/1636/1579 1301/1639/1582 -f 1301/1639/1582 1087/1636/1579 886/1511/1462 1027/1510/1461 -f 1089/1640/1583 1301/1639/1582 1027/1510/1461 884/1509/1460 -f 894/1641/1584 1090/1642/1585 1302/1643/1586 1091/1644/1587 -f 1090/1642/1585 893/1637/1580 1089/1640/1583 1302/1643/1586 -f 1302/1643/1586 1089/1640/1583 884/1509/1460 1025/1506/1457 -f 1091/1644/1587 1302/1643/1586 1025/1506/1457 885/1505/1456 -f 895/1645/1588 1092/1646/1589 1303/1647/1590 1093/1648/1591 -f 1092/1646/1589 894/1641/1584 1091/1644/1587 1303/1647/1590 -f 1303/1647/1590 1091/1644/1587 885/1505/1456 1026/1508/1459 -f 1093/1648/1591 1303/1647/1590 1026/1508/1459 887/1513/1464 -f 890/1631/1574 1094/1649/1592 1304/1650/1593 1085/1632/1575 -f 1094/1649/1592 895/1645/1588 1093/1648/1591 1304/1650/1593 -f 1304/1650/1593 1093/1648/1591 887/1513/1464 1035/1527/1478 -f 1085/1632/1575 1304/1650/1593 1035/1527/1478 889/1531/1482 -f 897/1619/1562 1081/1624/1567 1305/1651/1594 1095/1652/1595 -f 1081/1624/1567 896/1623/1566 1096/1653/1596 1305/1651/1594 -f 1305/1651/1594 1096/1653/1596 890/1631/1574 1083/1628/1571 -f 1095/1652/1595 1305/1651/1594 1083/1628/1571 891/1627/1570 -f 898/1611/1554 1079/1620/1563 1306/1654/1597 1097/1655/1598 -f 1079/1620/1563 897/1619/1562 1095/1652/1595 1306/1654/1597 -f 1306/1654/1597 1095/1652/1595 891/1627/1570 1086/1634/1577 -f 1097/1655/1598 1306/1654/1597 1086/1634/1577 892/1633/1576 -f 899/1606/1549 1075/1612/1555 1307/1656/1599 1098/1657/1600 -f 1075/1612/1555 898/1611/1554 1097/1655/1598 1307/1656/1599 -f 1307/1656/1599 1097/1655/1598 892/1633/1576 1088/1638/1581 -f 1098/1657/1600 1307/1656/1599 1088/1638/1581 893/1637/1580 -f 900/1608/1551 1073/1607/1550 1308/1658/1601 1099/1659/1602 -f 1073/1607/1550 899/1606/1549 1098/1657/1600 1308/1658/1601 -f 1308/1658/1601 1098/1657/1600 893/1637/1580 1090/1642/1585 -f 1099/1659/1602 1308/1658/1601 1090/1642/1585 894/1641/1584 -f 901/1616/1559 1077/1615/1558 1309/1660/1603 1100/1661/1604 -f 1077/1615/1558 900/1608/1551 1099/1659/1602 1309/1660/1603 -f 1309/1660/1603 1099/1659/1602 894/1641/1584 1092/1646/1589 -f 1100/1661/1604 1309/1660/1603 1092/1646/1589 895/1645/1588 -f 896/1623/1566 1082/1626/1569 1310/1662/1605 1096/1653/1596 -f 1082/1626/1569 901/1616/1559 1100/1661/1604 1310/1662/1605 -f 1310/1662/1605 1100/1661/1604 895/1645/1588 1094/1649/1592 -f 1096/1653/1596 1310/1662/1605 1094/1649/1592 890/1631/1574 -s 15 -f 902/1663/1606 1101/1664/1607 1311/1665/1608 1102/1666/1609 -f 1101/1664/1607 905/1667/1610 1103/1668/1611 1311/1665/1608 -f 1311/1665/1608 1103/1668/1611 904/1669/1612 1104/1670/1613 -f 1102/1666/1609 1311/1665/1608 1104/1670/1613 903/1671/1614 -f 906/1672/1615 1105/1673/1616 1312/1674/1617 1106/1675/1618 -f 1105/1673/1616 909/1676/1619 1107/1677/1620 1312/1674/1617 -f 1312/1674/1617 1107/1677/1620 908/1678/1621 1108/1679/1622 -f 1106/1675/1618 1312/1674/1617 1108/1679/1622 907/1680/1623 -f 910/1681/1624 1109/1682/1625 1313/1683/1626 1110/1684/1627 -f 1109/1682/1625 913/1685/1628 1111/1686/1629 1313/1683/1626 -f 1313/1683/1626 1111/1686/1629 912/1687/1630 1112/1688/1631 -f 1110/1684/1627 1313/1683/1626 1112/1688/1631 911/1689/1632 -f 914/1690/1633 1113/1691/1634 1314/1692/1635 1114/1693/1636 -f 1113/1691/1634 902/1694/1606 1102/1695/1609 1314/1692/1635 -f 1314/1692/1635 1102/1695/1609 903/1696/1614 1115/1697/1637 -f 1114/1693/1636 1314/1692/1635 1115/1697/1637 915/1698/1638 -f 914/1699/1633 1116/1700/1639 1315/1701/1640 1113/1702/1634 -f 1116/1700/1639 916/1703/1641 1117/1704/1642 1315/1701/1640 -f 1315/1701/1640 1117/1704/1642 905/1667/1610 1101/1664/1607 -f 1113/1702/1634 1315/1701/1640 1101/1664/1607 902/1663/1606 -f 905/1667/1610 1118/1705/1643 1316/1706/1644 1103/1668/1611 -f 1118/1705/1643 906/1672/1615 1106/1675/1618 1316/1706/1644 -f 1316/1706/1644 1106/1675/1618 907/1680/1623 1119/1707/1645 -f 1103/1668/1611 1316/1706/1644 1119/1707/1645 904/1669/1612 -f 916/1703/1641 1120/1708/1646 1317/1709/1647 1117/1704/1642 -f 1120/1708/1646 909/1710/1619 1105/1711/1616 1317/1709/1647 -f 1317/1709/1647 1105/1711/1616 906/1672/1615 1118/1705/1643 -f 1117/1704/1642 1317/1709/1647 1118/1705/1643 905/1667/1610 -f 917/1712/1648 1121/1713/1649 1318/1714/1650 1122/1715/1651 -f 1121/1713/1649 910/1681/1624 1110/1684/1627 1318/1714/1650 -f 1318/1714/1650 1110/1684/1627 911/1689/1632 1123/1716/1652 -f 1122/1715/1651 1318/1714/1650 1123/1716/1652 918/1717/1653 -f 918/1717/1653 1123/1716/1652 1319/1718/1654 1124/1719/1655 -f 1123/1716/1652 911/1689/1632 1125/1720/1656 1319/1718/1654 -f 1319/1718/1654 1125/1720/1656 920/1721/1657 1126/1722/1658 -f 1124/1719/1655 1319/1718/1654 1126/1722/1658 919/1723/1659 -f 912/1687/1630 1127/1724/1660 1320/1725/1661 1112/1688/1631 -f 1127/1724/1660 921/1726/1662 1128/1727/1663 1320/1725/1661 -f 1320/1725/1661 1128/1727/1663 920/1721/1657 1125/1720/1656 -f 1112/1688/1631 1320/1725/1661 1125/1720/1656 911/1689/1632 -f 903/1696/1614 1129/1728/1664 1321/1729/1665 1115/1697/1637 -f 1129/1728/1664 923/1730/1666 1130/1731/1667 1321/1729/1665 -f 1321/1729/1665 1130/1731/1667 922/1732/1668 1131/1733/1669 -f 1115/1697/1637 1321/1729/1665 1131/1733/1669 915/1698/1638 -f 904/1669/1612 1132/1734/1670 1322/1735/1671 1104/1670/1613 -f 1132/1734/1670 924/1736/1672 1133/1737/1673 1322/1735/1671 -f 1322/1735/1671 1133/1737/1673 923/1738/1666 1129/1739/1664 -f 1104/1670/1613 1322/1735/1671 1129/1739/1664 903/1671/1614 -f 907/1680/1623 1134/1740/1674 1323/1741/1675 1119/1707/1645 -f 1134/1740/1674 925/1742/1676 1135/1743/1677 1323/1741/1675 -f 1323/1741/1675 1135/1743/1677 924/1736/1672 1132/1734/1670 -f 1119/1707/1645 1323/1741/1675 1132/1734/1670 904/1669/1612 -f 908/1678/1621 1136/1744/1678 1324/1745/1679 1108/1679/1622 -f 1136/1744/1678 926/1746/1680 1137/1747/1681 1324/1745/1679 -f 1324/1745/1679 1137/1747/1681 925/1742/1676 1134/1740/1674 -f 1108/1679/1622 1324/1745/1679 1134/1740/1674 907/1680/1623 -f 927/1748/1682 1138/1749/1683 1325/1750/1684 1139/1751/1685 -f 1138/1749/1683 930/1752/1686 1140/1753/1687 1325/1750/1684 -f 1325/1750/1684 1140/1753/1687 929/1754/1688 1141/1755/1689 -f 1139/1751/1685 1325/1750/1684 1141/1755/1689 928/1756/1690 -f 909/1676/1619 1142/1757/1691 1326/1758/1692 1107/1677/1620 -f 1142/1757/1691 932/1759/1693 1143/1760/1694 1326/1758/1692 -f 1326/1758/1692 1143/1760/1694 931/1761/1695 1144/1762/1696 -f 1107/1677/1620 1326/1758/1692 1144/1762/1696 908/1678/1621 -f 933/1763/1697 1145/1764/1698 1327/1765/1699 1146/1766/1700 -f 1145/1764/1698 932/1767/1693 1142/1768/1691 1327/1765/1699 -f 1327/1765/1699 1142/1768/1691 909/1710/1619 1120/1708/1646 -f 1146/1766/1700 1327/1765/1699 1120/1708/1646 916/1703/1641 -f 934/1769/1701 1147/1770/1702 1328/1771/1703 1148/1772/1704 -f 1147/1770/1702 933/1763/1697 1146/1766/1700 1328/1771/1703 -f 1328/1771/1703 1146/1766/1700 916/1703/1641 1116/1700/1639 -f 1148/1772/1704 1328/1771/1703 1116/1700/1639 914/1699/1633 -f 934/1773/1701 1148/1774/1704 1329/1775/1705 1149/1776/1706 -f 1148/1774/1704 914/1690/1633 1114/1693/1636 1329/1775/1705 -f 1329/1775/1705 1114/1693/1636 915/1698/1638 1150/1777/1707 -f 1149/1776/1706 1329/1775/1705 1150/1777/1707 935/1778/1708 -f 922/1732/1668 1151/1779/1709 1330/1780/1710 1131/1733/1669 -f 1151/1779/1709 936/1781/1711 1152/1782/1712 1330/1780/1710 -f 1330/1780/1710 1152/1782/1712 935/1778/1708 1150/1777/1707 -f 1131/1733/1669 1330/1780/1710 1150/1777/1707 915/1698/1638 -f 931/1761/1695 1153/1783/1713 1331/1784/1714 1144/1762/1696 -f 1153/1783/1713 938/1785/1715 1154/1786/1716 1331/1784/1714 -f 1331/1784/1714 1154/1786/1716 937/1787/1717 1155/1788/1718 -f 1144/1762/1696 1331/1784/1714 1155/1788/1718 908/1678/1621 -f 908/1678/1621 1155/1788/1718 1332/1789/1719 1136/1744/1678 -f 1155/1788/1718 937/1787/1717 1156/1790/1720 1332/1789/1719 -f 1332/1789/1719 1156/1790/1720 939/1791/1721 1157/1792/1722 -f 1136/1744/1678 1332/1789/1719 1157/1792/1722 926/1746/1680 -f 919/1723/1659 1158/1793/1723 1333/1794/1724 1124/1719/1655 -f 1158/1793/1723 941/1795/1725 1159/1796/1726 1333/1794/1724 -f 1333/1794/1724 1159/1796/1726 940/1797/1727 1160/1798/1728 -f 1124/1719/1655 1333/1794/1724 1160/1798/1728 918/1717/1653 -f 942/1799/1729 1161/1800/1730 1334/1801/1731 1162/1802/1732 -f 1161/1800/1730 945/1803/1733 1163/1804/1734 1334/1801/1731 -f 1334/1801/1731 1163/1804/1734 944/1805/1735 1164/1806/1736 -f 1162/1802/1732 1334/1801/1731 1164/1806/1736 943/1807/1737 -f 937/1787/1717 1165/1808/1738 1335/1809/1739 1156/1790/1720 -f 1165/1808/1738 947/1810/1740 1166/1811/1741 1335/1809/1739 -f 1335/1809/1739 1166/1811/1741 946/1812/1742 1167/1813/1743 -f 1156/1790/1720 1335/1809/1739 1167/1813/1743 939/1791/1721 -f 941/1795/1725 1168/1814/1744 1336/1815/1745 1159/1796/1726 -f 1168/1814/1744 949/1816/1746 1169/1817/1747 1336/1815/1745 -f 1336/1815/1745 1169/1817/1747 948/1818/1748 1170/1819/1749 -f 1159/1796/1726 1336/1815/1745 1170/1819/1749 940/1797/1727 -f 945/1803/1733 1171/1820/1750 1337/1821/1751 1163/1804/1734 -f 1171/1820/1750 951/1822/1752 1172/1823/1753 1337/1821/1751 -f 1337/1821/1751 1172/1823/1753 950/1824/1754 1173/1825/1755 -f 1163/1804/1734 1337/1821/1751 1173/1825/1755 944/1805/1735 -f 947/1810/1740 1174/1826/1756 1338/1827/1757 1166/1811/1741 -f 1174/1826/1756 928/1756/1690 1141/1755/1689 1338/1827/1757 -f 1338/1827/1757 1141/1755/1689 929/1754/1688 1175/1828/1758 -f 1166/1811/1741 1338/1827/1757 1175/1828/1758 946/1812/1742 -f 949/1816/1746 1176/1829/1759 1339/1830/1760 1169/1817/1747 -f 1176/1829/1759 953/1831/1761 1177/1832/1762 1339/1830/1760 -f 1339/1830/1760 1177/1832/1762 952/1833/1763 1178/1834/1764 -f 1169/1817/1747 1339/1830/1760 1178/1834/1764 948/1818/1748 -f 954/1835/1765 1179/1836/1766 1176/1829/1759 949/1816/1746 -f 1179/1836/1766 955/1837/1767 953/1831/1761 1176/1829/1759 -f 956/1838/1768 1180/1839/1769 1168/1814/1744 941/1795/1725 -f 1180/1839/1769 954/1835/1765 949/1816/1746 1168/1814/1744 -f 957/1840/1770 1181/1841/1771 1158/1793/1723 919/1723/1659 -f 1181/1841/1771 956/1838/1768 941/1795/1725 1158/1793/1723 -f 1126/1722/1658 920/1721/1657 958/1842/1772 1182/1843/1773 -f 1126/1722/1658 1182/1843/1773 957/1840/1770 919/1723/1659 -f 1128/1727/1663 921/1726/1662 959/1844/1774 1183/1845/1775 -f 1128/1727/1663 1183/1845/1775 958/1842/1772 920/1721/1657 -f 960/1846/1776 1184/1847/1777 1151/1779/1709 922/1732/1668 -f 1184/1847/1777 961/1848/1778 936/1781/1711 1151/1779/1709 -f 1130/1731/1667 923/1730/1666 962/1849/1779 1185/1850/1780 -f 1130/1731/1667 1185/1850/1780 960/1846/1776 922/1732/1668 -f 1133/1737/1673 924/1736/1672 963/1851/1781 1186/1852/1782 -f 1133/1737/1673 1186/1852/1782 962/1853/1779 923/1738/1666 -f 1135/1743/1677 925/1742/1676 964/1854/1783 1187/1855/1784 -f 1135/1743/1677 1187/1855/1784 963/1851/1781 924/1736/1672 -f 1137/1747/1681 926/1746/1680 965/1856/1785 1188/1857/1786 -f 1137/1747/1681 1188/1857/1786 964/1854/1783 925/1742/1676 -f 1157/1792/1722 939/1791/1721 966/1858/1787 1189/1859/1788 -f 1157/1792/1722 1189/1859/1788 965/1856/1785 926/1746/1680 -f 1167/1813/1743 946/1812/1742 967/1860/1789 1190/1861/1790 -f 1167/1813/1743 1190/1861/1790 966/1858/1787 939/1791/1721 -f 1175/1828/1758 929/1754/1688 968/1862/1791 1191/1863/1792 -f 1175/1828/1758 1191/1863/1792 967/1860/1789 946/1812/1742 -f 1140/1753/1687 930/1752/1686 969/1864/1793 1192/1865/1794 -f 1140/1753/1687 1192/1865/1794 968/1862/1791 929/1754/1688 -f 1193/1866/1795 953/1831/1761 955/1837/1767 1194/1867/1796 -f 1193/1866/1795 1194/1867/1796 969/1864/1793 930/1752/1686 -f 952/1833/1763 1177/1832/1762 1340/1868/1797 1195/1869/1798 -f 1177/1832/1762 953/1831/1761 1193/1866/1795 1340/1868/1797 -f 1340/1868/1797 1193/1866/1795 930/1752/1686 1138/1749/1683 -f 1195/1869/1798 1340/1868/1797 1138/1749/1683 927/1748/1682 -f 948/1818/1748 1178/1834/1764 1341/1870/1799 1196/1871/1800 -f 1178/1834/1764 952/1833/1763 1195/1869/1798 1341/1870/1799 -f 1341/1870/1799 1195/1869/1798 927/1748/1682 1197/1872/1801 -f 1196/1871/1800 1341/1870/1799 1197/1872/1801 970/1873/1802 -f 940/1797/1727 1170/1819/1749 1342/1874/1803 1198/1875/1804 -f 1170/1819/1749 948/1818/1748 1196/1871/1800 1342/1874/1803 -f 1342/1874/1803 1196/1871/1800 970/1873/1802 1199/1876/1805 -f 1198/1875/1804 1342/1874/1803 1199/1876/1805 938/1785/1715 -f 918/1717/1653 1160/1798/1728 1343/1877/1806 1200/1878/1807 -f 1160/1798/1728 940/1797/1727 1198/1875/1804 1343/1877/1806 -f 1343/1877/1806 1198/1875/1804 938/1785/1715 1153/1783/1713 -f 1200/1878/1807 1343/1877/1806 1153/1783/1713 931/1761/1695 -f 932/1759/1693 1201/1879/1808 1344/1880/1809 1143/1760/1694 -f 1201/1879/1808 917/1712/1648 1122/1715/1651 1344/1880/1809 -f 1344/1880/1809 1122/1715/1651 918/1717/1653 1200/1878/1807 -f 1143/1760/1694 1344/1880/1809 1200/1878/1807 931/1761/1695 -f 910/1881/1624 1121/1882/1649 1345/1883/1810 1202/1884/1811 -f 1121/1882/1649 917/1885/1648 1201/1886/1808 1345/1883/1810 -f 1345/1883/1810 1201/1886/1808 932/1767/1693 1145/1764/1698 -f 1202/1884/1811 1345/1883/1810 1145/1764/1698 933/1763/1697 -f 913/1887/1628 1109/1888/1625 1346/1889/1812 1203/1890/1813 -f 1109/1888/1625 910/1881/1624 1202/1884/1811 1346/1889/1812 -f 1346/1889/1812 1202/1884/1811 933/1763/1697 1147/1770/1702 -f 1203/1890/1813 1346/1889/1812 1147/1770/1702 934/1769/1701 -f 913/1685/1628 1203/1891/1813 1347/1892/1814 1111/1686/1629 -f 1203/1891/1813 934/1773/1701 1149/1776/1706 1347/1892/1814 -f 1347/1892/1814 1149/1776/1706 935/1778/1708 1204/1893/1815 -f 1111/1686/1629 1347/1892/1814 1204/1893/1815 912/1687/1630 -f 936/1781/1711 1205/1894/1816 1348/1895/1817 1152/1782/1712 -f 1205/1894/1816 921/1726/1662 1127/1724/1660 1348/1895/1817 -f 1348/1895/1817 1127/1724/1660 912/1687/1630 1204/1893/1815 -f 1152/1782/1712 1348/1895/1817 1204/1893/1815 935/1778/1708 -f 936/1781/1711 961/1848/1778 1206/1896/1818 1205/1894/1816 -f 1206/1896/1818 959/1844/1774 921/1726/1662 1205/1894/1816 -f 938/1785/1715 1207/1897/1819 1349/1898/1820 1154/1786/1716 -f 1207/1897/1819 972/1899/1821 1208/1900/1822 1349/1898/1820 -f 1349/1898/1820 1208/1900/1822 971/1901/1823 1209/1902/1824 -f 1154/1786/1716 1349/1898/1820 1209/1902/1824 937/1787/1717 -f 937/1787/1717 1209/1902/1824 1350/1903/1825 1165/1808/1738 -f 1209/1902/1824 971/1901/1823 1210/1904/1826 1350/1903/1825 -f 1350/1903/1825 1210/1904/1826 973/1905/1827 1211/1906/1828 -f 1165/1808/1738 1350/1903/1825 1211/1906/1828 947/1810/1740 -f 970/1873/1802 1212/1907/1829 1351/1908/1830 1199/1876/1805 -f 1212/1907/1829 974/1909/1831 1213/1910/1832 1351/1908/1830 -f 1351/1908/1830 1213/1910/1832 972/1899/1821 1207/1897/1819 -f 1199/1876/1805 1351/1908/1830 1207/1897/1819 938/1785/1715 -f 947/1810/1740 1211/1906/1828 1352/1911/1833 1174/1826/1756 -f 1211/1906/1828 973/1905/1827 1214/1912/1834 1352/1911/1833 -f 1352/1911/1833 1214/1912/1834 975/1913/1835 1215/1914/1836 -f 1174/1826/1756 1352/1911/1833 1215/1914/1836 928/1756/1690 -f 928/1756/1690 1215/1914/1836 1353/1915/1837 1139/1751/1685 -f 1215/1914/1836 975/1913/1835 1216/1916/1838 1353/1915/1837 -f 1353/1915/1837 1216/1916/1838 976/1917/1839 1217/1918/1840 -f 1139/1751/1685 1353/1915/1837 1217/1918/1840 927/1748/1682 -f 927/1748/1682 1217/1918/1840 1354/1919/1841 1197/1872/1801 -f 1217/1918/1840 976/1917/1839 1218/1920/1842 1354/1919/1841 -f 1354/1919/1841 1218/1920/1842 974/1909/1831 1212/1907/1829 -f 1197/1872/1801 1354/1919/1841 1212/1907/1829 970/1873/1802 -f 977/1921/1843 1219/1922/1844 1355/1923/1845 1220/1924/1846 -f 1219/1922/1844 950/1824/1754 1172/1823/1753 1355/1923/1845 -f 1355/1923/1845 1172/1823/1753 951/1822/1752 1221/1925/1847 -f 1220/1924/1846 1355/1923/1845 1221/1925/1847 978/1926/1848 -f 979/1927/1849 1222/1928/1850 1356/1929/1851 1223/1930/1852 -f 1222/1928/1850 944/1805/1735 1173/1825/1755 1356/1929/1851 -f 1356/1929/1851 1173/1825/1755 950/1824/1754 1219/1922/1844 -f 1223/1930/1852 1356/1929/1851 1219/1922/1844 977/1921/1843 -f 980/1931/1853 1224/1932/1854 1357/1933/1855 1225/1934/1856 -f 1224/1932/1854 943/1807/1737 1164/1806/1736 1357/1933/1855 -f 1357/1933/1855 1164/1806/1736 944/1805/1735 1222/1928/1850 -f 1225/1934/1856 1357/1933/1855 1222/1928/1850 979/1927/1849 -f 981/1935/1857 1226/1936/1858 1358/1937/1859 1227/1938/1860 -f 1226/1936/1858 942/1799/1729 1162/1802/1732 1358/1937/1859 -f 1358/1937/1859 1162/1802/1732 943/1807/1737 1224/1932/1854 -f 1227/1938/1860 1358/1937/1859 1224/1932/1854 980/1931/1853 -f 982/1939/1861 1228/1940/1862 1359/1941/1863 1229/1942/1864 -f 1228/1940/1862 945/1803/1733 1161/1800/1730 1359/1941/1863 -f 1359/1941/1863 1161/1800/1730 942/1799/1729 1226/1936/1858 -f 1229/1942/1864 1359/1941/1863 1226/1936/1858 981/1935/1857 -f 978/1926/1848 1221/1925/1847 1360/1943/1865 1230/1944/1866 -f 1221/1925/1847 951/1822/1752 1171/1820/1750 1360/1943/1865 -f 1360/1943/1865 1171/1820/1750 945/1803/1733 1228/1940/1862 -f 1230/1944/1866 1360/1943/1865 1228/1940/1862 982/1939/1861 -f 975/1913/1835 1231/1945/1867 1361/1946/1868 1216/1916/1838 -f 1231/1945/1867 977/1921/1843 1220/1924/1846 1361/1946/1868 -f 1361/1946/1868 1220/1924/1846 978/1926/1848 1232/1947/1869 -f 1216/1916/1838 1361/1946/1868 1232/1947/1869 976/1917/1839 -f 973/1905/1827 1233/1948/1870 1362/1949/1871 1214/1912/1834 -f 1233/1948/1870 979/1927/1849 1223/1930/1852 1362/1949/1871 -f 1362/1949/1871 1223/1930/1852 977/1921/1843 1231/1945/1867 -f 1214/1912/1834 1362/1949/1871 1231/1945/1867 975/1913/1835 -f 971/1901/1823 1234/1950/1872 1363/1951/1873 1210/1904/1826 -f 1234/1950/1872 980/1931/1853 1225/1934/1856 1363/1951/1873 -f 1363/1951/1873 1225/1934/1856 979/1927/1849 1233/1948/1870 -f 1210/1904/1826 1363/1951/1873 1233/1948/1870 973/1905/1827 -f 972/1899/1821 1235/1952/1874 1364/1953/1875 1208/1900/1822 -f 1235/1952/1874 981/1935/1857 1227/1938/1860 1364/1953/1875 -f 1364/1953/1875 1227/1938/1860 980/1931/1853 1234/1950/1872 -f 1208/1900/1822 1364/1953/1875 1234/1950/1872 971/1901/1823 -f 974/1909/1831 1236/1954/1876 1365/1955/1877 1213/1910/1832 -f 1236/1954/1876 982/1939/1861 1229/1942/1864 1365/1955/1877 -f 1365/1955/1877 1229/1942/1864 981/1935/1857 1235/1952/1874 -f 1213/1910/1832 1365/1955/1877 1235/1952/1874 972/1899/1821 -f 976/1917/1839 1232/1947/1869 1366/1956/1878 1218/1920/1842 -f 1232/1947/1869 978/1926/1848 1230/1944/1866 1366/1956/1878 -f 1366/1956/1878 1230/1944/1866 982/1939/1861 1236/1954/1876 -f 1218/1920/1842 1366/1956/1878 1236/1954/1876 974/1909/1831 -g default -v 0.731122 -1.025815 3.962625 -v 0.854774 0.000000 3.815101 -v 0.721313 -1.025890 5.797148 -v 0.757460 0.000000 5.944634 -v 0.798596 -1.157449 4.879924 -v 0.920271 0.000000 4.879924 -v 0.742455 -0.602220 5.914624 -v 0.879982 -0.649286 4.879924 -v 0.795169 -0.602220 3.845186 -v 0.761658 -1.128306 5.418849 -v 0.827363 -0.632342 5.430258 -v 0.861401 0.000000 5.441102 -v 0.776908 -1.130866 4.441946 -v 0.869816 -0.633698 4.430763 -v 0.915244 0.000000 4.420069 -v 0.827363 0.632417 5.430258 -v 0.742455 0.602145 5.914624 -v 0.869816 0.633698 4.430763 -v 0.879982 0.649286 4.879924 -v 0.761658 1.128306 5.418849 -v 0.721313 1.025890 5.797148 -v 0.798596 1.157449 4.879924 -v 0.776908 1.131017 4.441946 -v 0.731122 1.025815 3.962625 -v 0.795169 0.602220 3.845186 -v 0.679481 -1.115955 3.883742 -v 0.749779 -0.620820 3.718785 -v 0.675659 -1.116483 5.875842 -v 0.690984 -0.621423 6.040573 -v 0.726133 -1.264760 4.422743 -v 0.751191 -1.289761 4.880037 -v 0.716136 -1.257530 5.437939 -v 0.703127 0.000000 6.075101 -v 0.813939 0.000000 3.684069 -v 0.690984 0.621423 6.040573 -v 0.675659 1.116407 5.875842 -v 0.716136 1.257530 5.437939 -v 0.726133 1.264760 4.422743 -v 0.751191 1.289761 4.880037 -v 0.679481 1.116031 3.883742 -v 0.749779 0.620820 3.718785 -v 0.501797 -1.339463 3.683956 -v 0.586516 -0.743644 3.485262 -v 0.497599 -1.340141 6.075704 -v 0.515842 -0.744472 6.274059 -v 0.555980 -1.517561 4.312345 -v 0.588267 -1.548587 4.880150 -v 0.546378 -1.510030 5.548488 -v 0.530281 0.000000 6.315477 -v 0.663554 0.000000 3.443618 -v 0.515842 0.744397 6.274059 -v 0.497599 1.340141 6.075704 -v 0.546378 1.510030 5.548488 -v 0.555980 1.517561 4.312345 -v 0.588267 1.548662 4.880150 -v 0.501797 1.339463 3.683956 -v 0.586516 0.743569 3.485262 -v 0.638006 0.379240 3.451337 -v 0.534254 1.081315 3.551870 -v 0.679142 0.674890 3.614863 -v 0.530639 1.472378 4.004984 -v 0.601314 1.214832 3.795220 -v 0.574806 1.539550 5.222339 -v 0.572829 1.539249 4.538036 -v 0.680140 1.404301 4.880075 -v 0.652032 1.376287 4.374133 -v 0.516764 1.462814 5.844138 -v 0.642562 1.369133 5.486624 -v 0.501948 1.082143 6.207602 -v 0.597530 1.215510 5.964439 -v 0.525989 0.379616 6.307570 -v 0.615038 0.675492 6.144420 -v 0.572829 -1.539249 4.538036 -v 0.516764 -1.462814 5.844138 -v 0.638006 -0.379315 3.451337 -v 0.748292 0.000000 3.577361 -v 0.525989 -0.379541 6.307570 -v 0.627614 0.000000 6.181583 -v 0.574806 -1.539475 5.222339 -v 0.642562 -1.369058 5.486624 -v 0.680140 -1.404301 4.880075 -v 0.530639 -1.472378 4.004984 -v 0.652032 -1.376287 4.374133 -v 0.501948 -1.082143 6.207602 -v 0.615038 -0.675492 6.144420 -v 0.597530 -1.215510 5.964439 -v 0.534254 -1.081315 3.551870 -v 0.679142 -0.674815 3.614863 -v 0.601314 -1.214832 3.795220 -v 0.792421 0.316736 3.690771 -v 0.707175 0.902464 3.773946 -v 0.779431 0.600714 3.762764 -v 0.706742 1.227634 4.164708 -v 0.712277 1.073860 3.922675 -v 0.739763 1.281854 5.165784 -v 0.738295 1.281703 4.594327 -v 0.781633 1.242319 4.879961 -v 0.757309 1.216564 4.440440 -v 0.692660 1.218597 5.684264 -v 0.746635 1.211519 5.420205 -v 0.680083 0.902840 5.985449 -v 0.707796 1.074161 5.837059 -v 0.699531 0.317112 6.068437 -v 0.723215 0.601090 5.996858 -v 0.738295 -1.281779 4.594327 -v 0.692660 -1.218597 5.684264 -v 0.792421 -0.316661 3.690771 -v 0.842367 0.000000 3.729591 -v 0.699531 -0.317037 6.068437 -v 0.735471 0.000000 6.030784 -v 0.739763 -1.281929 5.165784 -v 0.746635 -1.211443 5.420205 -v 0.781633 -1.242319 4.879961 -v 0.706742 -1.227634 4.164708 -v 0.757309 -1.216564 4.440440 -v 0.680083 -0.902840 5.985449 -v 0.723215 -0.601015 5.996858 -v 0.707796 -1.074161 5.837059 -v 0.707175 -0.902464 3.773946 -v 0.779431 -0.600714 3.762764 -v 0.712277 -1.073860 3.922675 -v 0.834931 0.308377 3.821276 -v 0.780861 0.617582 4.145693 -v 0.753318 0.870609 3.891499 -v 0.753827 1.096677 4.194679 -v 0.786020 1.150069 5.156258 -v 0.861194 0.644466 5.156107 -v 0.821658 0.920010 4.437728 -v 0.787959 1.150144 4.603590 -v 0.837849 0.941849 4.879924 -v 0.735960 1.093439 5.655648 -v 0.728053 0.870685 5.868274 -v 0.793419 0.917751 5.423104 -v 0.878344 0.644391 4.603740 -v 0.909069 0.331496 4.879924 -v 0.902537 0.323438 4.423571 -v 0.782876 0.615624 5.704710 -v 0.753055 0.308377 5.938421 -v 0.851686 0.322911 5.437562 -v 0.780861 -0.617582 4.145693 -v 0.921683 0.000000 4.599335 -v 0.902537 -0.323438 4.423571 -v 0.821658 -0.920010 4.437728 -v 0.787959 -1.150069 4.603590 -v 0.851686 -0.322836 5.437562 -v 0.807275 -0.000000 5.725607 -v 0.793419 -0.917751 5.423104 -v 0.861194 -0.644391 5.156107 -v 0.735960 -1.093514 5.655648 -v 0.878344 -0.644391 4.603740 -v 0.834931 -0.308302 3.821276 -v 0.782876 -0.615624 5.704710 -v 0.909069 -0.331571 4.879924 -v 0.753055 -0.308302 5.938421 -v 0.837849 -0.941849 4.879924 -v 0.899411 0.000000 5.160513 -v 0.786020 -1.150069 5.156258 -v 0.753827 -1.096602 4.194679 -v 0.728053 -0.870685 5.868274 -v 0.753318 -0.870609 3.891499 -v 0.725323 0.343771 3.584665 -v 0.630796 0.981459 3.674920 -v 0.628329 1.336601 4.094109 -v 0.668129 1.395716 5.190372 -v 0.666340 1.395490 4.569852 -v 0.615151 1.327414 5.755089 -v 0.601653 0.982137 6.084439 -v 0.624093 0.344298 6.174467 -v 0.666340 -1.395490 4.569852 -v 0.615151 -1.327489 5.755089 -v 0.725323 -0.343771 3.584628 -v 0.624093 -0.344298 6.174467 -v 0.668129 -1.395716 5.190372 -v 0.628329 -1.336677 4.094109 -v 0.601653 -0.982137 6.084439 -v 0.630796 -0.981384 3.674920 -v 0.821056 0.307097 3.735879 -v 0.737749 0.870459 3.816908 -v 0.735734 1.178459 4.194642 -v 0.769980 1.234713 5.157350 -v 0.769001 1.234788 4.602611 -v 0.722688 1.172585 5.655196 -v 0.711599 0.870760 5.942713 -v 0.731743 0.307323 6.023931 -v 0.769001 -1.234863 4.602611 -v 0.722688 -1.172510 5.655196 -v 0.821056 -0.307021 3.735879 -v 0.731743 -0.307323 6.023931 -v 0.769980 -1.234788 5.157350 -v 0.735734 -1.178459 4.194642 -v 0.711599 -0.870835 5.942713 -v 0.737749 -0.870459 3.816908 -v 0.744639 0.315908 4.096292 -v 0.777152 0.894180 4.172690 -v 0.888624 0.328935 5.158743 -v 0.822242 0.935372 5.155581 -v 0.831598 0.935448 4.604267 -v 0.758966 0.891394 5.677675 -v 0.909785 0.328935 4.601104 -v 0.800121 0.314853 5.720562 -v 0.744639 -0.315832 4.096292 -v 0.777152 -0.894180 4.172690 -v 0.888624 -0.328935 5.158743 -v 0.822242 -0.935372 5.155581 -v 0.831598 -0.935448 4.604267 -v 0.758966 -0.891469 5.677675 -v 0.909785 -0.328860 4.601104 -v 0.800121 -0.314853 5.720562 -v 0.702336 0.000000 3.881426 -v 0.702336 -0.179981 4.060917 -v 0.702336 -0.147336 3.912622 -v 0.702336 0.147260 3.912622 -v 0.702336 0.179905 4.060917 -v 0.702336 0.154527 4.200403 -v 0.702336 0.000000 4.226082 -v 0.702336 -0.154565 4.200403 -v 0.479055 -0.177496 4.060823 -v 0.479055 -0.145340 3.914542 -v 0.479055 0.000000 3.883780 -v 0.479055 0.145265 3.914542 -v 0.479055 0.177420 4.060823 -v 0.479055 0.152419 4.198407 -v 0.479055 0.000000 4.223747 -v 0.479055 -0.152494 4.198407 -v 0.479055 0.000000 4.056418 -vt 0.375000 0.000000 -vt 0.625000 0.000000 -vt 0.375000 0.250000 -vt 0.625000 0.250000 -vt 0.375000 0.125000 -vt 0.625000 0.125000 -vt 0.500000 0.250000 -vt 0.500000 0.125000 -vt 0.500000 0.000000 -vt 0.375000 0.187500 -vt 0.500000 0.187500 -vt 0.625000 0.187500 -vt 0.375000 0.062500 -vt 0.500000 0.062500 -vt 0.625000 0.062500 -vt 0.500000 0.187500 -vt 0.625000 0.187500 -vt 0.625000 0.250000 -vt 0.500000 0.250000 -vt 0.500000 0.062500 -vt 0.625000 0.062500 -vt 0.625000 0.125000 -vt 0.500000 0.125000 -vt 0.375000 0.187500 -vt 0.375000 0.250000 -vt 0.375000 0.125000 -vt 0.375000 0.062500 -vt 0.375000 0.000000 -vt 0.500000 0.000000 -vt 0.625000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.500000 1.000000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 0.500000 1.000000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 0.000000 -vt 0.562500 0.000000 -vt 0.500000 0.031250 -vt 0.500000 0.000000 -vt 0.437500 0.000000 -vt 0.375000 0.031250 -vt 0.500000 0.000000 -vt 0.375000 0.156250 -vt 0.500000 0.000000 -vt 0.500000 0.156250 -vt 0.437500 0.062500 -vt 0.375000 0.093750 -vt 0.500000 0.000000 -vt 0.437500 0.125000 -vt 0.375000 0.218750 -vt 0.500000 0.000000 -vt 0.437500 0.250000 -vt 0.500000 0.000000 -vt 0.437500 0.187500 -vt 0.500000 0.093750 -vt 0.562500 0.125000 -vt 0.562500 0.062500 -vt 0.500000 0.218750 -vt 0.562500 0.250000 -vt 0.500000 0.000000 -vt 0.562500 0.187500 -vt 0.500000 0.031250 -vt 0.625000 0.093750 -vt 0.625000 0.093750 -vt 0.562500 0.062500 -vt 0.437500 0.062500 -vt 0.500000 0.000000 -vt 0.375000 0.093750 -vt 0.562500 0.187500 -vt 0.625000 0.218750 -vt 0.625000 0.218750 -vt 0.437500 0.187500 -vt 0.500000 0.156250 -vt 0.500000 0.000000 -vt 0.375000 0.218750 -vt 0.500000 0.093750 -vt 0.562500 0.000000 -vt 0.500000 0.000000 -vt 0.500000 0.218750 -vt 0.562500 0.125000 -vt 0.500000 0.000000 -vt 0.562500 0.250000 -vt 0.437500 0.125000 -vt 0.625000 0.156250 -vt 0.625000 0.156250 -vt 0.500000 0.000000 -vt 0.375000 0.156250 -vt 0.500000 0.000000 -vt 0.375000 0.031250 -vt 0.500000 0.000000 -vt 0.437500 0.250000 -vt 0.437500 0.000000 -vt 0.500000 0.000000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.562500 0.031250 -vt 0.437500 0.031250 -vt 0.562500 0.156250 -vt 0.437500 0.156250 -vt 0.437500 0.093750 -vt 0.437500 0.218750 -vt 0.562500 0.093750 -vt 0.562500 0.218750 -vt 0.562500 0.031250 -vt 0.437500 0.031250 -vt 0.562500 0.156250 -vt 0.437500 0.156250 -vt 0.437500 0.093750 -vt 0.437500 0.218750 -vt 0.562500 0.093750 -vt 0.562500 0.218750 -vt 0.562500 0.031250 -vt 0.562500 0.000000 -vt 0.625000 0.000000 -vt 0.625000 0.000000 -vt 0.562500 0.000000 -vt 0.562500 0.031250 -vt 0.562500 0.062500 -vt 0.625000 0.062500 -vt 0.562500 0.062500 -vt 0.625000 0.062500 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 0.500000 1.000000 -vn 0.984688 -0.097551 0.144479 -vn 0.986498 -0.053849 0.154668 -vn 0.980330 -0.045644 0.192014 -vn 0.980639 -0.083754 0.177008 -vn 0.971122 -0.088581 -0.221530 -vn 0.952023 -0.013453 -0.305731 -vn 0.997650 -0.066438 -0.016758 -vn 0.991688 -0.125591 -0.027943 -vn 0.980258 -0.156820 0.120423 -vn 0.982607 -0.131327 0.131290 -vn 0.980458 -0.114971 0.159635 -vn 0.978906 -0.143603 0.145332 -vn 0.984153 -0.172029 -0.042997 -vn 0.976909 -0.150906 -0.151247 -vn 0.982505 -0.186097 0.007200 -vn 0.986957 -0.160005 0.017700 -vn 0.985359 -0.146269 0.087591 -vn 0.982020 -0.171220 0.079497 -vn 0.992666 -0.117325 0.029127 -vn 0.997366 -0.062646 0.036563 -vn 0.993048 -0.059079 0.101806 -vn 0.989442 -0.108328 0.096283 -vn 0.982456 -0.121713 -0.141300 -vn 0.988177 -0.050148 -0.144883 -vn 0.984685 0.097562 0.144488 -vn 0.980636 0.083764 0.177022 -vn 0.980329 0.045640 0.192020 -vn 0.986498 0.053848 0.154669 -vn 0.971121 0.088587 -0.221531 -vn 0.991688 0.125594 -0.027938 -vn 0.997649 0.066448 -0.016754 -vn 0.952027 0.013437 -0.305718 -vn 0.980262 0.156793 0.120429 -vn 0.978914 0.143548 0.145334 -vn 0.980455 0.114980 0.159651 -vn 0.982602 0.131349 0.131306 -vn 0.976916 0.150873 -0.151237 -vn 0.984158 0.172006 -0.042983 -vn 0.982501 0.186120 0.007214 -vn 0.982019 0.171230 0.079496 -vn 0.985358 0.146284 0.087585 -vn 0.986958 0.160005 0.017697 -vn 0.992667 0.117319 0.029125 -vn 0.989443 0.108330 0.096268 -vn 0.993050 0.059075 0.101797 -vn 0.997366 0.062637 0.036566 -vn 0.988175 0.050153 -0.144895 -vn 0.982457 0.121697 -0.141306 -vn 0.997712 -0.059744 0.031654 -vn 0.988664 -0.126809 -0.080394 -vn 0.920965 -0.228466 -0.315637 -vn 0.933244 -0.176975 -0.312628 -vn 0.975850 -0.130997 0.174804 -vn 0.976640 -0.102262 0.188988 -vn 0.921200 -0.142587 0.362021 -vn 0.918658 -0.252969 0.303436 -vn 0.973261 -0.181539 -0.140735 -vn 0.973416 -0.181649 -0.139520 -vn 0.929966 -0.329528 -0.163017 -vn 0.912550 -0.316171 -0.259399 -vn 0.940731 -0.329923 0.078587 -vn 0.940285 -0.340388 -0.000386 -vn 0.976216 -0.072216 0.204418 -vn 0.975012 -0.037913 0.218895 -vn 0.923159 -0.039378 0.382396 -vn 0.924049 -0.083057 0.373142 -vn 0.851568 -0.000000 0.524244 -vn 0.983039 0.045779 0.177589 -vn 0.945280 -0.110558 -0.306956 -vn 0.953232 -0.000000 -0.302240 -vn 0.933692 -0.309664 0.179799 -vn 0.939778 -0.317527 0.126470 -vn 0.973925 -0.194248 -0.117208 -vn 0.978379 -0.199145 -0.055825 -vn 0.934557 -0.349057 -0.069007 -vn 0.935134 -0.333986 -0.118232 -vn 0.974410 0.000000 0.224778 -vn 0.975012 0.037919 0.218891 -vn 0.923160 0.039362 0.382396 -vn 0.923007 -0.000000 0.384783 -vn 0.976217 0.072217 0.204413 -vn 0.976642 0.102267 0.188978 -vn 0.921211 0.142574 0.361998 -vn 0.924055 0.083088 0.373121 -vn 0.975860 0.130968 0.174770 -vn 0.933687 0.309658 0.179834 -vn 0.918638 0.252990 0.303482 -vn 0.978375 0.199173 -0.055790 -vn 0.934482 0.349260 -0.068996 -vn 0.940230 0.340540 -0.000374 -vn 0.940717 0.329967 0.078575 -vn 0.939767 0.317582 0.126411 -vn 0.973923 0.194261 -0.117207 -vn 0.973411 0.181645 -0.139558 -vn 0.929916 0.329653 -0.163047 -vn 0.935029 0.334288 -0.118204 -vn 0.973260 0.181534 -0.140753 -vn 0.988664 0.126805 -0.080398 -vn 0.920976 0.228450 -0.315617 -vn 0.912579 0.316108 -0.259373 -vn 0.997712 0.059752 0.031645 -vn 0.983047 -0.045797 0.177544 -vn 0.945281 0.110556 -0.306956 -vn 0.933241 0.177001 -0.312622 -vn 0.853971 -0.190864 -0.484050 -vn 0.858327 -0.263946 -0.440009 -vn 0.853197 -0.269027 -0.446855 -vn 0.848369 -0.193907 -0.492616 -vn 0.861909 -0.330693 0.384389 -vn 0.842122 -0.189144 0.505031 -vn 0.836113 -0.194902 0.512765 -vn 0.856777 -0.337669 0.389760 -vn 0.864087 -0.386757 -0.322136 -vn 0.860525 -0.469112 -0.198570 -vn 0.853564 -0.478515 -0.206037 -vn 0.859762 -0.391292 -0.328175 -vn 0.848013 -0.529970 -0.002299 -vn 0.849503 -0.521247 0.081528 -vn 0.846957 -0.525221 0.082505 -vn 0.846311 -0.532683 -0.002566 -vn 0.826558 -0.103732 0.553211 -vn 0.817848 -0.046160 0.573580 -vn 0.814010 -0.046974 0.578949 -vn 0.820782 -0.106543 0.561219 -vn 0.851554 0.000007 -0.524267 -vn 0.851720 -0.113138 -0.511638 -vn 0.847716 -0.114871 -0.517863 -vn 0.847991 0.000015 -0.530011 -vn 0.853078 -0.503091 0.138413 -vn 0.861187 -0.457259 0.221970 -vn 0.855296 -0.465529 0.227490 -vn 0.848329 -0.510522 0.140375 -vn 0.853594 -0.504837 -0.128518 -vn 0.847878 -0.524922 -0.074566 -vn 0.845849 -0.528024 -0.075702 -vn 0.846775 -0.515806 -0.130063 -vn 0.814715 0.000000 0.579861 -vn 0.817846 0.046172 0.573582 -vn 0.814008 0.046967 0.578952 -vn 0.811699 0.000000 0.584076 -vn 0.826551 0.103735 0.553219 -vn 0.842136 0.189161 0.505000 -vn 0.836115 0.194897 0.512764 -vn 0.820777 0.106556 0.561223 -vn 0.861895 0.330696 0.384418 -vn 0.861123 0.457329 0.222076 -vn 0.855308 0.465481 0.227543 -vn 0.856798 0.337673 0.389711 -vn 0.848074 0.529873 -0.002300 -vn 0.847929 0.524839 -0.074567 -vn 0.845902 0.527936 -0.075720 -vn 0.846401 0.532540 -0.002582 -vn 0.853074 0.503109 0.138372 -vn 0.849549 0.521177 0.081497 -vn 0.847044 0.525084 0.082482 -vn 0.848361 0.510460 0.140410 -vn 0.853596 0.504843 -0.128485 -vn 0.860480 0.469200 -0.198559 -vn 0.853551 0.478539 -0.206037 -vn 0.846784 0.515786 -0.130087 -vn 0.864063 0.386844 -0.322098 -vn 0.858370 0.263917 -0.439943 -vn 0.853170 0.269042 -0.446897 -vn 0.859750 0.391335 -0.328157 -vn 0.853972 0.190849 -0.484053 -vn 0.851687 0.113148 -0.511691 -vn 0.847697 0.114872 -0.517895 -vn 0.848350 0.193893 -0.492653 -vn 0.844067 0.123367 -0.521854 -vn 0.844715 0.000018 -0.535216 -vn 0.845481 0.203249 -0.493813 -vn 0.852715 0.282911 -0.439134 -vn 0.859291 0.392542 -0.327916 -vn 0.853990 0.471331 -0.220338 -vn 0.845582 0.516631 -0.134472 -vn 0.844135 0.528981 0.087265 -vn 0.843630 0.536919 -0.002672 -vn 0.845850 0.512965 0.146303 -vn 0.843554 0.531071 -0.079884 -vn 0.854375 0.459722 0.242280 -vn 0.855757 0.342176 0.388066 -vn 0.836422 0.209766 0.506356 -vn 0.818235 0.115255 0.563211 -vn 0.810256 0.050886 0.583863 -vn 0.808242 0.000000 0.588850 -vn 0.843520 -0.531129 -0.079854 -vn 0.843533 -0.537071 -0.002649 -vn 0.845538 -0.516714 -0.134434 -vn 0.854353 -0.459759 0.242288 -vn 0.855734 -0.342186 0.388109 -vn 0.845842 -0.513000 0.146228 -vn 0.844076 -0.123389 -0.521834 -vn 0.845544 -0.203290 -0.493688 -vn 0.810253 -0.050874 0.583868 -vn 0.818248 -0.115259 0.563192 -vn 0.844078 -0.529069 0.087276 -vn 0.853943 -0.471398 -0.220376 -vn 0.859280 -0.392534 -0.327955 -vn 0.836430 -0.209772 0.506340 -vn 0.852764 -0.282895 -0.439049 -vn 0.984535 -0.146383 -0.096240 -vn 0.994636 0.000000 0.103440 -vn 0.987365 0.000000 0.158462 -vn 0.999249 -0.000000 0.038757 -vn 0.999917 0.000000 -0.012879 -vn 0.902617 0.000000 -0.430445 -vn 0.980205 0.000000 0.197987 -vn 0.984531 0.146419 -0.096232 -vn 0.725306 0.253888 0.639900 -vn 0.887794 0.459846 -0.019052 -vn 0.505015 -0.000001 0.863110 -vn 0.725433 -0.253755 0.639809 -vn 0.887953 -0.459540 -0.019061 -vn 0.803203 -0.183757 -0.566656 -vn 0.713283 -0.000000 -0.700876 -vn 0.803157 0.183791 -0.566710 -vn 0.010677 0.976593 0.214830 -vn 0.010677 0.976593 0.214830 -vn 0.010677 0.976593 0.214830 -vn 0.010677 0.976593 0.214830 -vn 0.010289 0.207094 0.978267 -vn 0.010289 0.207094 0.978267 -vn 0.010289 0.207094 0.978267 -vn 0.010289 0.207094 0.978267 -vn 0.010289 -0.207196 0.978245 -vn 0.010289 -0.207196 0.978245 -vn 0.010289 -0.207196 0.978245 -vn 0.010289 -0.207196 0.978245 -vn 0.010677 -0.976593 0.214830 -vn 0.010677 -0.976593 0.214830 -vn 0.010677 -0.976593 0.214830 -vn 0.010677 -0.976593 0.214830 -vn 0.010957 -0.983809 -0.178886 -vn 0.010957 -0.983809 -0.178886 -vn 0.010957 -0.983809 -0.178886 -vn 0.010957 -0.983809 -0.178886 -vn 0.010339 -0.163957 -0.986413 -vn 0.010339 -0.163957 -0.986413 -vn 0.010339 -0.163957 -0.986413 -vn 0.010339 -0.163957 -0.986413 -vn 0.010874 0.983786 -0.179016 -vn 0.010874 0.983786 -0.179016 -vn 0.010874 0.983786 -0.179016 -vn 0.010874 0.983786 -0.179016 -vn 0.010327 0.163898 -0.986423 -vn 0.010327 0.163899 -0.986423 -vn 0.010327 0.163898 -0.986423 -vn 0.010327 0.163898 -0.986423 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 -0.000001 0.000000 -s 1 -g front_Screen_geo -usemtl anisotropic1SG -f 1377/1967/1879 1511/2260/1880 1574/2332/1881 1518/2270/1882 -f 1380/1970/1883 1508/2256/1884 1573/2331/1885 1516/2267/1886 -f 1376/1966/1887 1513/2263/1888 1572/2330/1889 1515/2266/1890 -f 1380/1970/1883 1516/2267/1886 1571/2329/1891 1509/2257/1892 -f 1371/1961/1893 1521/2274/1894 1570/2328/1895 1523/2278/1896 -f 1374/1964/1897 1519/2271/1898 1569/2327/1899 1514/2264/1900 -f 1380/1970/1883 1509/2257/1892 1568/2326/1901 1506/2253/1902 -f 1382/1972/1903 1503/2249/1904 1566/2324/1905 1505/2252/1906 -f 1384/1976/1907 1500/2246/1908 1565/2323/1909 1502/2248/1910 -f 1386/1980/1911 1497/2241/1912 1564/2322/1913 1499/2245/1914 -f 1384/1976/1907 1494/2237/1915 1563/2321/1916 1500/2246/1908 -f 1388/1982/1917 1492/2234/1918 1562/2320/1919 1496/2240/1920 -f 1385/1979/1921 1493/2236/1922 1561/2319/1923 1501/2247/1924 -f 1384/1976/1907 1489/2229/1925 1560/2318/1926 1494/2237/1915 -f 1375/1987/1927 1526/2284/1928 1558/2316/1929 1486/2224/1930 -f 1369/1991/1931 1525/2281/1932 1557/2315/1933 1484/2220/1934 -f 1367/1995/1935 1524/2279/1936 1556/2314/1937 1487/2226/1938 -f 1371/1999/1893 1523/2277/1896 1555/2313/1939 1479/2210/1940 -f 1373/2003/1941 1520/2272/1942 1554/2312/1943 1483/2218/1944 -f 1368/2007/1945 1517/2269/1946 1553/2311/1947 1474/2200/1948 -f 1376/2011/1887 1515/2265/1890 1552/2310/1949 1478/2208/1950 -f 1379/2015/1951 1510/2258/1952 1551/2309/1953 1481/2214/1954 -f 1370/2019/1955 1504/2251/1956 1550/2308/1957 1476/2204/1958 -f 1383/2023/1959 1498/2244/1960 1549/2307/1961 1470/2192/1962 -f 1387/2027/1963 1497/2242/1912 1548/2306/1964 1468/2188/1965 -f 1388/2031/1917 1495/2239/1966 1547/2305/1967 1463/2178/1968 -f 1386/2035/1911 1492/2235/1918 1546/2304/1969 1466/2184/1970 -f 1389/2039/1971 1491/2233/1972 1545/2303/1973 1464/2180/1974 -f 1390/2043/1975 1490/2230/1976 1544/2302/1977 1460/2172/1978 -f 1391/2047/1979 1488/2227/1980 1543/2301/1981 1458/2168/1982 -usemtl ScreenOp_matSG -f 1393/2051/1983 1485/2222/1984 1542/2300/1985 1454/2160/1986 -f 1394/2055/1987 1482/2215/1988 1541/2299/1989 1452/2157/1990 -f 1392/2059/1991 1480/2211/1992 1540/2298/1993 1455/2162/1994 -f 1397/2063/1995 1477/2205/1996 1539/2297/1997 1447/2149/1998 -f 1395/2067/1999 1475/2201/2000 1538/2296/2001 1451/2155/2002 -f 1400/2071/2003 1473/2198/2004 1537/2295/2005 1442/2141/2006 -f 1398/2075/2007 1472/2195/2008 1536/2294/2009 1446/2147/2010 -f 1396/2079/2011 1471/2193/2012 1535/2293/2013 1449/2152/2014 -f 1399/2083/2015 1469/2190/2016 1534/2292/2017 1444/2144/2018 -f 1401/2087/2019 1467/2186/2020 1533/2291/2021 1438/2136/2022 -f 1402/2091/2023 1465/2182/2024 1532/2290/2025 1436/2133/2026 -f 1405/2095/2027 1462/2176/2028 1531/2289/2029 1431/2125/2030 -f 1403/2099/2031 1461/2174/2032 1530/2288/2033 1434/2130/2034 -f 1404/2103/2035 1459/2170/2036 1529/2287/2037 1432/2127/2038 -f 1406/2107/2039 1457/2165/2040 1528/2286/2041 1428/2121/2042 -f 1407/2111/2043 1456/2163/2044 1527/2285/2045 1426/2118/2046 -f 1424/2115/2047 1527/2285/2045 1442/2140/2006 1416/2113/2048 -f 1442/2140/2006 1527/2285/2045 1456/2163/2044 1400/2112/2003 -f 1426/2118/2046 1527/2285/2045 1424/2115/2047 1423/2114/2049 -f 1425/2116/2050 1528/2286/2041 1426/2117/2046 1423/2109/2049 -f 1426/2117/2046 1528/2286/2041 1457/2165/2040 1407/2108/2043 -f 1428/2121/2042 1528/2286/2041 1425/2116/2050 1422/2110/2051 -f 1427/2119/2052 1529/2287/2037 1428/2120/2042 1422/2105/2051 -f 1428/2120/2042 1529/2287/2037 1459/2170/2036 1406/2104/2039 -f 1432/2127/2038 1529/2287/2037 1427/2119/2052 1420/2106/2053 -f 1429/2122/2054 1530/2288/2033 1431/2124/2030 1421/2101/2055 -f 1431/2124/2030 1530/2288/2033 1461/2174/2032 1405/2100/2027 -f 1434/2130/2034 1530/2288/2033 1429/2122/2054 1419/2102/2056 -f 1430/2123/2057 1531/2289/2029 1432/2126/2038 1420/2097/2053 -f 1432/2126/2038 1531/2289/2029 1462/2176/2028 1404/2096/2035 -f 1431/2125/2030 1531/2289/2029 1430/2123/2057 1421/2098/2055 -f 1433/2128/2058 1532/2290/2025 1434/2129/2034 1419/2093/2056 -f 1434/2129/2034 1532/2290/2025 1465/2182/2024 1403/2092/2031 -f 1436/2133/2026 1532/2290/2025 1433/2128/2058 1418/2094/2059 -f 1435/2131/2060 1533/2291/2021 1436/2132/2026 1418/2089/2059 -f 1436/2132/2026 1533/2291/2021 1467/2186/2020 1402/2088/2023 -f 1438/2136/2022 1533/2291/2021 1435/2131/2060 1417/2090/2061 -f 1437/2134/2062 1534/2292/2017 1438/2135/2022 1417/2085/2061 -f 1438/2135/2022 1534/2292/2017 1469/2190/2016 1401/2084/2019 -f 1444/2144/2018 1534/2292/2017 1437/2134/2062 1415/2086/2063 -f 1439/2137/2064 1535/2293/2013 1447/2148/1998 1413/2081/2065 -f 1447/2148/1998 1535/2293/2013 1471/2193/2012 1397/2080/1995 -f 1449/2152/2014 1535/2293/2013 1439/2137/2064 1412/2082/2066 -f 1440/2138/2067 1536/2294/2009 1452/2156/1990 1410/2077/2068 -f 1452/2156/1990 1536/2294/2009 1472/2195/2008 1394/2076/1987 -f 1446/2147/2010 1536/2294/2009 1440/2138/2067 1414/2078/2069 -f 1441/2139/2070 1537/2295/2005 1454/2159/1986 1409/2073/2071 -f 1454/2159/1986 1537/2295/2005 1473/2198/2004 1393/2072/1983 -f 1442/2141/2006 1537/2295/2005 1441/2139/2070 1416/2074/2048 -f 1443/2142/2072 1538/2296/2001 1444/2143/2018 1415/2069/2063 -f 1444/2143/2018 1538/2296/2001 1475/2201/2000 1399/2068/2015 -f 1451/2155/2002 1538/2296/2001 1443/2142/2072 1411/2070/2073 -f 1445/2145/2074 1539/2297/1997 1446/2146/2010 1414/2065/2069 -f 1446/2146/2010 1539/2297/1997 1477/2205/1996 1398/2064/2007 -f 1447/2149/1998 1539/2297/1997 1445/2145/2074 1413/2066/2065 -f 1448/2150/2075 1540/2298/1993 1449/2151/2014 1412/2061/2066 -f 1449/2151/2014 1540/2298/1993 1480/2211/1992 1396/2060/2011 -f 1455/2162/1994 1540/2298/1993 1448/2150/2075 1408/2062/2076 -f 1450/2153/2077 1541/2299/1989 1451/2154/2002 1411/2057/2073 -f 1451/2154/2002 1541/2299/1989 1482/2215/1988 1395/2056/1999 -f 1452/2157/1990 1541/2299/1989 1450/2153/2077 1410/2058/2068 -f 1453/2158/2078 1542/2300/1985 1455/2161/1994 1408/2053/2076 -f 1455/2161/1994 1542/2300/1985 1485/2222/1984 1392/2052/1991 -f 1454/2160/1986 1542/2300/1985 1453/2158/2078 1409/2054/2071 -usemtl anisotropic1SG -f 1456/2164/2044 1543/2301/1981 1474/2199/1948 1400/2049/2003 -f 1474/2199/1948 1543/2301/1981 1488/2227/1980 1368/2048/1945 -f 1458/2168/1982 1543/2301/1981 1456/2164/2044 1407/2050/2043 -f 1457/2166/2040 1544/2302/1977 1458/2167/1982 1407/2045/2043 -f 1458/2167/1982 1544/2302/1977 1490/2230/1976 1391/2044/1979 -f 1460/2172/1978 1544/2302/1977 1457/2166/2040 1406/2046/2039 -f 1459/2169/2036 1545/2303/1973 1460/2171/1978 1406/2041/2039 -f 1460/2171/1978 1545/2303/1973 1491/2233/1972 1390/2040/1975 -f 1464/2180/1974 1545/2303/1973 1459/2169/2036 1404/2042/2035 -f 1461/2173/2032 1546/2304/1969 1463/2177/1968 1405/2037/2027 -f 1463/2177/1968 1546/2304/1969 1492/2235/1918 1388/2036/1917 -f 1466/2184/1970 1546/2304/1969 1461/2173/2032 1403/2038/2031 -f 1462/2175/2028 1547/2305/1967 1464/2179/1974 1404/2033/2035 -f 1464/2179/1974 1547/2305/1967 1495/2239/1966 1389/2032/1971 -f 1463/2178/1968 1547/2305/1967 1462/2175/2028 1405/2034/2027 -f 1465/2181/2024 1548/2306/1964 1466/2183/1970 1403/2029/2031 -f 1466/2183/1970 1548/2306/1964 1497/2242/1912 1386/2028/1911 -f 1468/2188/1965 1548/2306/1964 1465/2181/2024 1402/2030/2023 -f 1467/2185/2020 1549/2307/1961 1468/2187/1965 1402/2025/2023 -f 1468/2187/1965 1549/2307/1961 1498/2244/1960 1387/2024/1963 -f 1470/2192/1962 1549/2307/1961 1467/2185/2020 1401/2026/2019 -f 1469/2189/2016 1550/2308/1957 1470/2191/1962 1401/2021/2019 -f 1470/2191/1962 1550/2308/1957 1504/2251/1956 1383/2020/1959 -f 1476/2204/1958 1550/2308/1957 1469/2189/2016 1399/2022/2015 -f 1471/2194/2012 1551/2309/1953 1479/2209/1940 1397/2017/1995 -f 1479/2209/1940 1551/2309/1953 1510/2258/1952 1371/2016/1893 -f 1481/2214/1954 1551/2309/1953 1471/2194/2012 1396/2018/2011 -f 1472/2196/2008 1552/2310/1949 1484/2219/1934 1394/2013/1987 -f 1484/2219/1934 1552/2310/1949 1515/2265/1890 1369/2012/1931 -f 1478/2208/1950 1552/2310/1949 1472/2196/2008 1398/2014/2007 -f 1473/2197/2004 1553/2311/1947 1486/2223/1930 1393/2009/1983 -f 1486/2223/1930 1553/2311/1947 1517/2269/1946 1375/2008/1927 -f 1474/2200/1948 1553/2311/1947 1473/2197/2004 1400/2010/2003 -f 1475/2202/2000 1554/2312/1943 1476/2203/1958 1399/2005/2015 -f 1476/2203/1958 1554/2312/1943 1520/2272/1942 1370/2004/1955 -f 1483/2218/1944 1554/2312/1943 1475/2202/2000 1395/2006/1999 -f 1477/2206/1996 1555/2313/1939 1478/2207/1950 1398/2001/2007 -f 1478/2207/1950 1555/2313/1939 1523/2277/1896 1376/2000/1887 -f 1479/2210/1940 1555/2313/1939 1477/2206/1996 1397/2002/1995 -f 1480/2212/1992 1556/2314/1937 1481/2213/1954 1396/1997/2011 -f 1481/2213/1954 1556/2314/1937 1524/2279/1936 1379/1996/1951 -f 1487/2226/1938 1556/2314/1937 1480/2212/1992 1392/1998/1991 -f 1482/2216/1988 1557/2315/1933 1483/2217/1944 1395/1993/1999 -f 1483/2217/1944 1557/2315/1933 1525/2281/1932 1373/1992/1941 -f 1484/2220/1934 1557/2315/1933 1482/2216/1988 1394/1994/1987 -f 1485/2221/1984 1558/2316/1929 1487/2225/1938 1392/1989/1991 -f 1487/2225/1938 1558/2316/1929 1526/2284/1928 1367/1988/1935 -f 1486/2224/1930 1558/2316/1929 1485/2221/1984 1393/1990/1983 -f 1502/2248/1910 1559/2317/2079 1489/2229/1925 1384/1976/1907 -f 1489/2229/1925 1559/2317/2079 1488/2228/1980 1391/1985/1979 -f 1491/2232/1972 1560/2318/1926 1490/2231/1976 1390/1984/1975 -f 1490/2231/1976 1560/2318/1926 1489/2229/1925 1391/1985/1979 -f 1494/2237/1915 1560/2318/1926 1491/2232/1972 1389/1983/1971 -f 1522/2276/2080 1561/2319/1923 1505/2252/1906 1378/1973/2081 -f 1505/2252/1906 1561/2319/1923 1493/2236/1922 1382/1972/1903 -f 1501/2247/1924 1561/2319/1923 1522/2276/2080 1372/1978/2082 -f 1493/2236/1922 1562/2320/1919 1499/2245/1914 1382/1972/1903 -f 1499/2245/1914 1562/2320/1919 1492/2234/1918 1386/1980/1911 -f 1496/2240/1920 1562/2320/1919 1493/2236/1922 1385/1979/1921 -f 1496/2240/1920 1563/2321/1916 1495/2238/1966 1388/1982/1917 -f 1495/2238/1966 1563/2321/1916 1494/2237/1915 1389/1983/1971 -f 1500/2246/1908 1563/2321/1916 1496/2240/1920 1385/1979/1921 -f 1503/2249/1904 1564/2322/1913 1498/2243/1960 1383/1975/1959 -f 1498/2243/1960 1564/2322/1913 1497/2241/1912 1387/1981/1963 -f 1499/2245/1914 1564/2322/1913 1503/2249/1904 1382/1972/1903 -f 1507/2255/2083 1565/2323/1909 1501/2247/1924 1372/1978/2082 -f 1501/2247/1924 1565/2323/1909 1500/2246/1908 1385/1979/1921 -f 1502/2248/1910 1565/2323/1909 1507/2255/2083 1381/1977/2084 -f 1512/2262/2085 1566/2324/1905 1504/2250/1956 1370/1974/1955 -f 1504/2250/1956 1566/2324/1905 1503/2249/1904 1383/1975/1959 -f 1505/2252/1906 1566/2324/1905 1512/2262/2085 1378/1973/2081 -f 1506/2253/1902 1567/2325/2086 1508/2256/1884 1380/1970/1883 -f 1517/2268/1946 1567/2325/2086 1506/2253/1902 1375/1965/1927 -f 1526/2283/1928 1568/2326/1901 1524/2280/1936 1367/1957/1935 -f 1524/2280/1936 1568/2326/1901 1509/2257/1892 1379/1969/1951 -f 1506/2253/1902 1568/2326/1901 1526/2283/1928 1375/1965/1927 -f 1511/2260/1880 1569/2327/1899 1522/2275/2080 1378/1968/2081 -f 1522/2275/2080 1569/2327/1899 1519/2271/1898 1372/1962/2082 -f 1514/2264/1900 1569/2327/1899 1511/2260/1880 1377/1967/1879 -f 1513/2263/1888 1570/2328/1895 1514/2264/1900 1377/1967/1879 -f 1514/2264/1900 1570/2328/1895 1521/2274/1894 1374/1964/1897 -f 1523/2278/1896 1570/2328/1895 1513/2263/1888 1376/1966/1887 -f 1510/2259/1952 1571/2329/1891 1521/2274/1894 1371/1961/1893 -f 1521/2274/1894 1571/2329/1891 1516/2267/1886 1374/1964/1897 -f 1509/2257/1892 1571/2329/1891 1510/2259/1952 1379/1969/1951 -f 1525/2282/1932 1572/2330/1889 1518/2270/1882 1373/1963/1941 -f 1518/2270/1882 1572/2330/1889 1513/2263/1888 1377/1967/1879 -f 1515/2266/1890 1572/2330/1889 1525/2282/1932 1369/1959/1931 -f 1519/2271/1898 1573/2331/1885 1507/2254/2083 1372/1962/2082 -f 1507/2254/2083 1573/2331/1885 1508/2256/1884 1381/1971/2084 -f 1516/2267/1886 1573/2331/1885 1519/2271/1898 1374/1964/1897 -f 1520/2273/1942 1574/2332/1881 1512/2261/2085 1370/1960/1955 -f 1512/2261/2085 1574/2332/1881 1511/2260/1880 1378/1968/2081 -f 1518/2270/1882 1574/2332/1881 1520/2273/1942 1373/1963/1941 -f 1567/2325/2086 1517/2268/1946 1577/2334/2087 1576/2333/2088 -f 1517/2268/1946 1368/1958/1945 1575/2335/2089 1577/2334/2087 -f 1368/1986/1945 1488/2228/1980 1578/2337/2090 1575/2336/2089 -f 1488/2228/1980 1559/2317/2079 1579/2338/2091 1578/2337/2090 -f 1559/2317/2079 1502/2248/1910 1580/2339/2092 1579/2338/2091 -f 1502/2248/1910 1381/1977/2084 1581/2340/2093 1580/2339/2092 -f 1508/2256/1884 1567/2325/2086 1576/2333/2088 1582/2341/2094 -f 1381/1971/2084 1508/2256/1884 1582/2341/2094 1581/2342/2093 -s off -f 1576/2343/2095 1577/2344/2096 1584/2345/2097 1583/2346/2098 -f 1577/2347/2099 1575/2348/2100 1585/2349/2101 1584/2350/2102 -f 1575/2351/2103 1578/2352/2104 1586/2353/2105 1585/2354/2106 -f 1578/2355/2107 1579/2356/2108 1587/2357/2109 1586/2358/2110 -f 1579/2359/2111 1580/2360/2112 1588/2361/2113 1587/2362/2114 -f 1580/2363/2115 1581/2364/2116 1589/2365/2117 1588/2366/2118 -f 1582/2367/2119 1576/2368/2120 1583/2369/2121 1590/2370/2122 -f 1581/2371/2123 1582/2372/2124 1590/2373/2125 1589/2374/2126 -f 1591/2376/2127 1583/2375/2128 1584/2377/2129 1585/2378/2130 -f 1591/2380/2131 1585/2379/2132 1586/2381/2133 1587/2382/2134 -f 1591/2384/2135 1587/2383/2136 1588/2385/2137 1589/2386/2138 -f 1591/2390/2139 1589/2389/2140 1590/2387/2141 1583/2388/2142 -g default -v -0.362284 1.617529 2.545371 -v -0.843255 1.617529 2.064394 -v -1.019304 1.617529 1.407370 -v -0.843255 1.617529 0.750351 -v -0.362284 1.617529 0.269376 -v 0.294744 1.617529 0.093327 -v 0.951768 1.617529 0.269376 -v 1.432745 1.617529 0.750351 -v 1.608791 1.617529 1.407370 -v 1.432745 1.617529 2.064394 -v 0.951768 1.617529 2.545371 -v 0.294744 1.617529 2.721417 -v -0.362284 2.784919 2.545371 -v -0.843255 2.784919 2.064394 -v -1.019304 2.784919 1.407370 -v -0.843255 2.784919 0.750351 -v -0.362284 2.784919 0.269376 -v 0.294744 2.784919 0.093327 -v 0.951768 2.784919 0.269376 -v 1.432745 2.784919 0.750351 -v 1.608791 2.784919 1.407370 -v 1.432745 2.784919 2.064394 -v 0.951768 2.784919 2.545371 -v 0.294744 2.784919 2.721417 -v 0.294744 1.617529 1.407370 -v -0.342702 2.784919 2.511453 -v -0.809337 2.784919 2.044811 -v -0.980139 2.784919 1.407370 -v -0.809337 2.784919 0.769933 -v -0.342702 2.784919 0.303293 -v 0.294744 2.784919 0.132492 -v 0.932185 2.784919 0.303293 -v 1.398827 2.784919 0.769933 -v 1.569626 2.784919 1.407370 -v 1.398827 2.784919 2.044811 -v 0.932185 2.784919 2.511453 -v 0.294744 2.784919 2.682252 -v -0.109886 2.784919 2.108206 -v -0.337770 2.784919 1.882901 -v 0.294744 2.784919 1.407371 -v -0.512943 2.784919 1.361995 -v -0.406091 2.784919 1.002747 -v -0.109886 2.784919 0.706539 -v 0.230375 2.784919 0.601543 -v 0.750016 2.784919 0.754042 -v 0.995579 2.784919 1.002747 -v 1.103997 2.784919 1.407371 -v 1.055995 2.784919 1.734248 -v 0.645042 2.784919 2.151772 -v 0.294744 2.784919 2.216624 -v -0.809337 2.559730 2.044811 -v -0.980139 2.559730 1.407370 -v -0.512943 2.559730 1.361995 -v -0.337770 2.559730 1.882901 -v 0.294744 2.559730 0.132492 -v 0.932185 2.559730 0.303293 -v 0.750016 2.559730 0.754042 -v 0.230375 2.559730 0.601543 -v 1.398827 2.559730 2.044811 -v 0.932185 2.559730 2.511453 -v 0.645042 2.559730 2.151772 -v 1.055995 2.559730 1.734248 -vt 0.635316 0.078125 -vt 0.578125 0.020934 -vt 0.500000 0.000000 -vt 0.421875 0.020934 -vt 0.364684 0.078125 -vt 0.343750 0.156250 -vt 0.364684 0.234375 -vt 0.421875 0.291566 -vt 0.500000 0.312500 -vt 0.578125 0.291566 -vt 0.635316 0.234375 -vt 0.656250 0.156250 -vt 0.375000 0.312500 -vt 0.395833 0.312500 -vt 0.416667 0.312500 -vt 0.437500 0.312500 -vt 0.458333 0.312500 -vt 0.479167 0.312500 -vt 0.500000 0.312500 -vt 0.520833 0.312500 -vt 0.541667 0.312500 -vt 0.562500 0.312500 -vt 0.583333 0.312500 -vt 0.604167 0.312500 -vt 0.625000 0.312500 -vt 0.375000 0.688440 -vt 0.395833 0.688440 -vt 0.416667 0.688440 -vt 0.437500 0.688440 -vt 0.458333 0.688440 -vt 0.479167 0.688440 -vt 0.500000 0.688440 -vt 0.520833 0.688440 -vt 0.541667 0.688440 -vt 0.562500 0.688440 -vt 0.583333 0.688440 -vt 0.604167 0.688440 -vt 0.625000 0.688440 -vt 0.635316 0.765625 -vt 0.578125 0.708434 -vt 0.500000 0.687500 -vt 0.421875 0.708434 -vt 0.364684 0.765625 -vt 0.343750 0.843750 -vt 0.364684 0.921875 -vt 0.421875 0.979066 -vt 0.500000 1.000000 -vt 0.578125 0.979066 -vt 0.635316 0.921875 -vt 0.656250 0.843750 -vt 0.500000 0.150000 -vt 0.500000 0.837500 -vt 0.635316 0.921875 -vt 0.578125 0.979066 -vt 0.500000 1.000000 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.343750 0.843750 -vt 0.364684 0.765625 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.578125 0.708434 -vt 0.635316 0.765625 -vt 0.656250 0.843750 -vt 0.635316 0.921875 -vt 0.578125 0.979066 -vt 0.500000 1.000000 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.343750 0.843750 -vt 0.364684 0.765625 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.578125 0.708434 -vt 0.635316 0.765625 -vt 0.656250 0.843750 -vt 0.578125 0.979066 -vt 0.500000 1.000000 -vt 0.500000 1.000000 -vt 0.578125 0.979066 -vt 0.343750 0.843750 -vt 0.364684 0.765625 -vt 0.364684 0.765625 -vt 0.343750 0.843750 -vt 0.578125 0.708434 -vt 0.635316 0.765625 -vt 0.635316 0.765625 -vt 0.578125 0.708434 -vn -0.707112 0.000000 0.707102 -vn -0.707112 0.000000 0.707102 -vn -0.707112 0.000000 0.707102 -vn -0.707112 0.000000 0.707102 -vn -0.965926 0.000000 0.258820 -vn -0.965926 0.000000 0.258820 -vn -0.965926 0.000000 0.258820 -vn -0.965926 0.000000 0.258820 -vn -0.965925 0.000000 -0.258821 -vn -0.965925 0.000000 -0.258821 -vn -0.965925 0.000000 -0.258821 -vn -0.965925 0.000000 -0.258821 -vn -0.707110 0.000000 -0.707103 -vn -0.707110 0.000000 -0.707103 -vn -0.707110 0.000000 -0.707103 -vn -0.707110 0.000000 -0.707103 -vn -0.258817 0.000000 -0.965927 -vn -0.258817 0.000000 -0.965927 -vn -0.258817 0.000000 -0.965927 -vn -0.258817 0.000000 -0.965927 -vn 0.258818 0.000000 -0.965926 -vn 0.258818 0.000000 -0.965926 -vn 0.258818 0.000000 -0.965926 -vn 0.258818 0.000000 -0.965926 -vn 0.707105 0.000000 -0.707109 -vn 0.707105 0.000000 -0.707109 -vn 0.707105 0.000000 -0.707109 -vn 0.707105 0.000000 -0.707109 -vn 0.965927 0.000000 -0.258817 -vn 0.965927 0.000000 -0.258817 -vn 0.965927 0.000000 -0.258817 -vn 0.965927 0.000000 -0.258817 -vn 0.965927 0.000000 0.258815 -vn 0.965927 0.000000 0.258815 -vn 0.965927 0.000000 0.258815 -vn 0.965927 0.000000 0.258815 -vn 0.707107 0.000000 0.707107 -vn 0.707107 0.000000 0.707107 -vn 0.707107 0.000000 0.707107 -vn 0.707107 0.000000 0.707107 -vn 0.258815 0.000000 0.965927 -vn 0.258815 0.000000 0.965927 -vn 0.258815 0.000000 0.965927 -vn 0.258815 0.000000 0.965927 -vn -0.258813 0.000000 0.965927 -vn -0.258813 0.000000 0.965927 -vn -0.258813 0.000000 0.965927 -vn -0.258813 0.000000 0.965927 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000005 -vn 0.000000 1.000000 -0.000005 -vn 0.000000 1.000000 -0.000005 -vn 0.000000 1.000000 -0.000005 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000005 -vn 0.000000 1.000000 0.000005 -vn 0.000000 1.000000 0.000005 -vn 0.000000 1.000000 0.000005 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000005 -vn 0.000000 1.000000 -0.000005 -vn 0.000000 1.000000 -0.000005 -vn 0.000000 1.000000 -0.000005 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000005 -vn 0.000000 1.000000 0.000005 -vn 0.000000 1.000000 0.000005 -vn 0.000000 1.000000 0.000005 -vn 0.000000 1.000000 0.000001 -vn 0.000000 1.000000 0.000001 -vn 0.000000 1.000000 0.000001 -vn 0.000000 1.000000 0.000001 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000001 -vn 0.000000 1.000000 0.000001 -vn 0.000000 1.000000 0.000001 -vn 0.000000 1.000000 0.000001 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.965926 0.000000 -0.258820 -vn 0.965926 0.000000 -0.258820 -vn 0.965926 0.000000 -0.258820 -vn 0.965926 0.000000 -0.258820 -vn 0.096666 0.000000 0.995317 -vn 0.096666 0.000000 0.995317 -vn 0.096666 0.000000 0.995317 -vn 0.096666 0.000000 0.995317 -vn -0.947841 0.000000 0.318745 -vn -0.947841 0.000000 0.318745 -vn -0.947841 0.000000 0.318745 -vn -0.947841 0.000000 0.318745 -vn -0.324738 0.000000 -0.945804 -vn -0.324738 0.000000 -0.945804 -vn -0.324738 0.000000 -0.945804 -vn -0.324738 0.000000 -0.945804 -vn -0.258818 0.000000 0.965926 -vn -0.258818 0.000000 0.965926 -vn -0.258818 0.000000 0.965926 -vn -0.258818 0.000000 0.965926 -vn -0.927145 0.000000 -0.374704 -vn -0.927145 0.000000 -0.374704 -vn -0.927145 0.000000 -0.374704 -vn -0.927145 0.000000 -0.374704 -vn 0.281594 0.000000 -0.959534 -vn 0.281594 0.000000 -0.959534 -vn 0.281594 0.000000 -0.959534 -vn 0.281594 0.000000 -0.959534 -vn 0.990715 0.000000 0.135957 -vn 0.990715 0.000000 0.135957 -vn 0.990715 0.000000 0.135957 -vn 0.990715 0.000000 0.135957 -vn -0.707107 0.000000 -0.707107 -vn -0.707107 0.000000 -0.707107 -vn -0.707107 0.000000 -0.707107 -vn -0.707107 0.000000 -0.707107 -vn 0.781506 0.000000 -0.623898 -vn 0.781506 0.000000 -0.623898 -vn 0.781506 0.000000 -0.623898 -vn 0.781506 0.000000 -0.623898 -vn 0.712693 0.000000 0.701476 -vn 0.712693 0.000000 0.701476 -vn 0.712693 0.000000 0.701476 -vn 0.712693 0.000000 0.701476 -vn -0.671367 0.000000 0.741125 -vn -0.671367 0.000000 0.741125 -vn -0.671367 0.000000 0.741125 -vn -0.671367 0.000000 0.741125 -s off -g wheel_FL_geo -usemtl blinn2SG -f 1592/2403/2143 1604/2416/2144 1605/2417/2145 1593/2404/2146 -f 1593/2404/2147 1605/2417/2148 1606/2418/2149 1594/2405/2150 -f 1594/2405/2151 1606/2418/2152 1607/2419/2153 1595/2406/2154 -f 1595/2406/2155 1607/2419/2156 1608/2420/2157 1596/2407/2158 -f 1596/2407/2159 1608/2420/2160 1609/2421/2161 1597/2408/2162 -f 1597/2408/2163 1609/2421/2164 1610/2422/2165 1598/2409/2166 -f 1598/2409/2167 1610/2422/2168 1611/2423/2169 1599/2410/2170 -f 1599/2410/2171 1611/2423/2172 1612/2424/2173 1600/2411/2174 -f 1600/2411/2175 1612/2424/2176 1613/2425/2177 1601/2412/2178 -f 1601/2412/2179 1613/2425/2180 1614/2426/2181 1602/2413/2182 -f 1602/2413/2183 1614/2426/2184 1615/2427/2185 1603/2414/2186 -f 1603/2414/2187 1615/2427/2188 1604/2428/2189 1592/2415/2190 -s 1 -f 1593/2392/2191 1616/2441/2192 1592/2391/2193 -f 1594/2393/2194 1616/2441/2192 1593/2392/2191 -f 1595/2394/2195 1616/2441/2192 1594/2393/2194 -f 1596/2395/2196 1616/2441/2192 1595/2394/2195 -f 1597/2396/2197 1616/2441/2192 1596/2395/2196 -f 1598/2397/2198 1616/2441/2192 1597/2396/2197 -f 1599/2398/2199 1616/2441/2192 1598/2397/2198 -f 1600/2399/2200 1616/2441/2192 1599/2398/2199 -f 1601/2400/2201 1616/2441/2192 1600/2399/2200 -f 1602/2401/2202 1616/2441/2192 1601/2400/2201 -f 1603/2402/2203 1616/2441/2192 1602/2401/2202 -f 1592/2391/2193 1616/2441/2192 1603/2402/2203 -s 2 -f 1629/2455/2204 1631/2442/2205 1630/2456/2206 -f 1630/2456/2206 1631/2442/2205 1632/2457/2207 -f 1632/2457/2207 1631/2442/2205 1633/2458/2208 -f 1633/2458/2208 1631/2442/2205 1634/2459/2209 -f 1634/2459/2209 1631/2442/2205 1635/2460/2210 -f 1635/2460/2210 1631/2442/2205 1636/2461/2211 -f 1636/2461/2211 1631/2442/2205 1637/2462/2212 -f 1637/2462/2212 1631/2442/2205 1638/2463/2213 -f 1638/2463/2213 1631/2442/2205 1639/2464/2214 -f 1639/2464/2214 1631/2442/2205 1640/2465/2215 -f 1640/2465/2215 1631/2442/2205 1641/2466/2216 -f 1641/2466/2216 1631/2442/2205 1629/2455/2204 -s off -f 1604/2439/2217 1617/2443/2218 1618/2444/2219 1605/2438/2220 -f 1605/2438/2221 1618/2444/2222 1619/2445/2223 1606/2437/2224 -f 1606/2437/2225 1619/2445/2226 1620/2446/2227 1607/2436/2228 -f 1607/2436/2229 1620/2446/2230 1621/2447/2231 1608/2435/2232 -f 1608/2435/2233 1621/2447/2234 1622/2448/2235 1609/2434/2236 -f 1609/2434/2237 1622/2448/2238 1623/2449/2239 1610/2433/2240 -f 1610/2433/2241 1623/2449/2242 1624/2450/2243 1611/2432/2244 -f 1611/2432/2245 1624/2450/2246 1625/2451/2247 1612/2431/2248 -f 1612/2431/2249 1625/2451/2250 1626/2452/2251 1613/2430/2252 -f 1613/2430/2253 1626/2452/2254 1627/2453/2255 1614/2429/2256 -f 1614/2429/2257 1627/2453/2258 1628/2454/2259 1615/2440/2260 -f 1615/2440/2261 1628/2454/2262 1617/2443/2263 1604/2439/2264 -f 1617/2443/2265 1629/2455/2266 1630/2456/2267 1618/2444/2268 -f 1642/2467/2269 1645/2470/2270 1644/2469/2271 1643/2468/2272 -f 1619/2445/2273 1632/2457/2274 1633/2458/2275 1620/2446/2276 -f 1620/2446/2277 1633/2458/2278 1634/2459/2279 1621/2447/2280 -f 1621/2447/2281 1634/2459/2282 1635/2460/2283 1622/2448/2284 -f 1646/2471/2285 1649/2474/2286 1648/2473/2287 1647/2472/2288 -f 1623/2449/2289 1636/2461/2290 1637/2462/2291 1624/2450/2292 -f 1624/2450/2293 1637/2462/2294 1638/2463/2295 1625/2451/2296 -f 1625/2451/2297 1638/2463/2298 1639/2464/2299 1626/2452/2300 -f 1650/2475/2301 1653/2478/2302 1652/2477/2303 1651/2476/2304 -f 1627/2453/2305 1640/2465/2306 1641/2466/2307 1628/2454/2308 -f 1628/2454/2309 1641/2466/2310 1629/2455/2311 1617/2443/2312 -f 1618/2444/2313 1642/2467/2314 1643/2468/2315 1619/2445/2316 -f 1619/2445/2317 1643/2468/2318 1644/2469/2319 1632/2457/2320 -f 1632/2457/2321 1644/2469/2322 1645/2470/2323 1630/2456/2324 -f 1630/2456/2325 1645/2470/2326 1642/2467/2327 1618/2444/2328 -f 1622/2448/2329 1646/2471/2330 1647/2472/2331 1623/2449/2332 -f 1623/2449/2333 1647/2472/2334 1648/2473/2335 1636/2461/2336 -f 1636/2461/2337 1648/2473/2338 1649/2474/2339 1635/2460/2340 -f 1635/2460/2341 1649/2474/2342 1646/2471/2343 1622/2448/2344 -f 1626/2452/2345 1650/2475/2346 1651/2476/2347 1627/2453/2348 -f 1627/2453/2349 1651/2476/2350 1652/2477/2351 1640/2465/2352 -f 1640/2465/2353 1652/2477/2354 1653/2478/2355 1639/2464/2356 -f 1639/2464/2357 1653/2478/2358 1650/2475/2359 1626/2452/2360 -g default -v 0.661209 -1.087000 4.640859 -v 0.661209 1.087000 4.640859 -v 0.661209 1.087000 4.659219 -v 0.661209 -1.087000 4.659219 -v 0.661209 -1.087000 4.677578 -v 0.661209 1.087000 4.677578 -v 0.661209 1.087000 4.695937 -v 0.661209 -1.087000 4.695937 -v 0.661209 -1.087000 4.714297 -v 0.661209 1.087000 4.714297 -v 0.661209 1.087000 4.732656 -v 0.661209 -1.087000 4.732656 -v 0.661209 -1.087000 4.751016 -v 0.661209 1.087000 4.751016 -v 0.661209 1.087000 4.769375 -v 0.661209 -1.087000 4.769375 -v 0.661209 -1.087000 4.787734 -v 0.661209 1.087000 4.787734 -v 0.661209 1.087000 4.806094 -v 0.661209 -1.087000 4.806094 -v 0.661209 -1.087000 4.824453 -v 0.661209 1.087000 4.824453 -v 0.661209 1.087000 4.842813 -v 0.661209 -1.087000 4.842813 -v 0.661209 -1.087000 4.861172 -v 0.661209 1.087000 4.861172 -v 0.661209 1.087000 4.879531 -v 0.661209 -1.087000 4.879531 -v 0.661209 -1.087000 4.897891 -v 0.661209 1.087000 4.897891 -v 0.661209 1.087000 4.916250 -v 0.661209 -1.087000 4.916250 -v 0.661209 -1.087000 4.934609 -v 0.661209 1.087000 4.934609 -v 0.661209 1.087000 4.952969 -v 0.661209 -1.087000 4.952969 -v 0.661209 -1.087000 4.971328 -v 0.661209 1.087000 4.971328 -v 0.661209 1.087000 4.989687 -v 0.661209 -1.087000 4.989687 -v 0.661209 -1.087000 5.008047 -v 0.661209 1.087000 5.008047 -v 0.661209 1.087000 5.026406 -v 0.661209 -1.087000 5.026406 -v 0.661209 -1.087000 5.044765 -v 0.661209 1.087000 5.044765 -v 0.661209 1.087000 5.063125 -v 0.661209 -1.087000 5.063125 -v 0.661209 -1.087000 5.081484 -v 0.661209 1.087000 5.081484 -v 0.661209 1.087000 5.099844 -v 0.661209 -1.087000 5.099844 -v 0.661209 -1.087000 5.118203 -v 0.661209 1.087000 5.118203 -v 0.661209 1.087000 5.136562 -v 0.661209 -1.087000 5.136562 -v 0.661209 -1.087000 5.154922 -v 0.661209 1.087000 5.154922 -v 0.661209 1.087000 5.173281 -v 0.661209 -1.087000 5.173281 -v 0.661209 -1.087000 5.191640 -v 0.661209 1.087000 5.191640 -v 0.661209 1.087000 5.210000 -v 0.661209 -1.087000 5.210000 -v 0.661209 -1.087000 5.228359 -v 0.661209 1.087000 5.228359 -v 0.661209 1.087000 5.246718 -v 0.661209 -1.087000 5.246718 -v 0.661209 -1.087000 5.265078 -v 0.661209 1.087000 5.265078 -v 0.661209 1.087000 5.283437 -v 0.661209 -1.087000 5.283437 -v 0.661209 -1.087000 5.301797 -v 0.661209 1.087000 5.301797 -v 0.661209 1.087000 5.320156 -v 0.661209 -1.087000 5.320156 -v 0.661209 -1.087000 5.338515 -v 0.661209 1.087000 5.338515 -v 0.661209 1.087000 5.356875 -v 0.661209 -1.087000 5.356875 -v 0.661209 -1.087000 5.375234 -v 0.661209 1.087000 5.375234 -v 0.661209 1.087000 5.393594 -v 0.661209 -1.087000 5.393594 -v 0.661209 -1.087000 5.411953 -v 0.661209 1.087000 5.411953 -v 0.661209 1.087000 5.430312 -v 0.661209 -1.087000 5.430312 -v 0.661209 -1.087000 5.448672 -v 0.661209 1.087000 5.448672 -v 0.661209 1.087000 5.467031 -v 0.661209 -1.087000 5.467031 -v 0.661209 -1.087000 5.485391 -v 0.661209 1.087000 5.485391 -v 0.661209 1.087000 5.503750 -v 0.661209 -1.087000 5.503750 -v 0.661209 -1.087000 5.522109 -v 0.661209 1.087000 5.522109 -v 0.661209 1.087000 5.540469 -v 0.661209 -1.087000 5.540469 -v 0.661209 -1.087000 5.558828 -v 0.661209 1.087000 5.558828 -v 0.661209 1.087000 5.577188 -v 0.661209 -1.087000 5.577188 -v 0.661209 -1.087000 5.595547 -v 0.661209 1.087000 5.595547 -v 0.661209 1.087000 5.613906 -v 0.661209 -1.087000 5.613906 -v 0.661209 -1.087000 5.632266 -v 0.661209 1.087000 5.632266 -v 0.661209 1.087000 5.650625 -v 0.661209 -1.087000 5.650625 -v 0.661209 -1.087000 5.668984 -v 0.661209 1.087000 5.668984 -v 0.661209 1.087000 5.687344 -v 0.661209 -1.087000 5.687344 -v 0.661209 -1.087000 5.705703 -v 0.661209 1.087000 5.705703 -v 0.661209 1.087000 5.724062 -v 0.661209 -1.087000 5.724062 -v 0.661209 -1.087000 5.742422 -v 0.661209 1.087000 5.742422 -v 0.661209 1.087000 5.760781 -v 0.661209 -1.087000 5.760781 -v 0.661209 -1.087000 5.779140 -v 0.661209 1.087000 5.779140 -v 0.661209 1.087000 5.797500 -v 0.661209 -1.087000 5.797500 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 0.008445 -vt 0.000000 0.008445 -vt 0.000000 0.016890 -vt 1.000000 0.016890 -vt 1.000000 0.025335 -vt 0.000000 0.025335 -vt 0.000000 0.033780 -vt 1.000000 0.033780 -vt 1.000000 0.042225 -vt 0.000000 0.042225 -vt 0.000000 0.050670 -vt 1.000000 0.050670 -vt 1.000000 0.059115 -vt 0.000000 0.059115 -vt 0.000000 0.067560 -vt 1.000000 0.067560 -vt 1.000000 0.076005 -vt 0.000000 0.076005 -vt 0.000000 0.084450 -vt 1.000000 0.084450 -vt 1.000000 0.092895 -vt 0.000000 0.092895 -vt 0.000000 0.101340 -vt 1.000000 0.101340 -vt 1.000000 0.109785 -vt 0.000000 0.109785 -vt 0.000000 0.118230 -vt 1.000000 0.118230 -vt 1.000000 0.126675 -vt 0.000000 0.126675 -vt 0.000000 0.135120 -vt 1.000000 0.135120 -vt 1.000000 0.143565 -vt 0.000000 0.143565 -vt 0.000000 0.152010 -vt 1.000000 0.152010 -vt 1.000000 0.160455 -vt 0.000000 0.160455 -vt 0.000000 0.168899 -vt 1.000000 0.168899 -vt 1.000000 0.177344 -vt 0.000000 0.177344 -vt 0.000000 0.185789 -vt 1.000000 0.185789 -vt 1.000000 0.194234 -vt 0.000000 0.194234 -vt 0.000000 0.202679 -vt 1.000000 0.202679 -vt 1.000000 0.211124 -vt 0.000000 0.211124 -vt 0.000000 0.219569 -vt 1.000000 0.219569 -vt 1.000000 0.228014 -vt 0.000000 0.228014 -vt 0.000000 0.236459 -vt 1.000000 0.236459 -vt 1.000000 0.244904 -vt 0.000000 0.244904 -vt 0.000000 0.253349 -vt 1.000000 0.253349 -vt 1.000000 0.261794 -vt 0.000000 0.261794 -vt 0.000000 0.270239 -vt 1.000000 0.270239 -vt 1.000000 0.278684 -vt 0.000000 0.278684 -vt 0.000000 0.287129 -vt 1.000000 0.287129 -vt 1.000000 0.295574 -vt 0.000000 0.295574 -vt 0.000000 0.304019 -vt 1.000000 0.304019 -vt 1.000000 0.312464 -vt 0.000000 0.312464 -vt 0.000000 0.320909 -vt 1.000000 0.320909 -vt 1.000000 0.329354 -vt 0.000000 0.329354 -vt 0.000000 0.337799 -vt 1.000000 0.337799 -vt 1.000000 0.346244 -vt 0.000000 0.346244 -vt 0.000000 0.354689 -vt 1.000000 0.354689 -vt 1.000000 0.363134 -vt 0.000000 0.363134 -vt 0.000000 0.371579 -vt 1.000000 0.371579 -vt 1.000000 0.380024 -vt 0.000000 0.380024 -vt 0.000000 0.388469 -vt 1.000000 0.388469 -vt 1.000000 0.396914 -vt 0.000000 0.396914 -vt 0.000000 0.405359 -vt 1.000000 0.405359 -vt 1.000000 0.413804 -vt 0.000000 0.413804 -vt 0.000000 0.422249 -vt 1.000000 0.422249 -vt 1.000000 0.430694 -vt 0.000000 0.430694 -vt 0.000000 0.439139 -vt 1.000000 0.439139 -vt 1.000000 0.447584 -vt 0.000000 0.447584 -vt 0.000000 0.456029 -vt 1.000000 0.456029 -vt 1.000000 0.464474 -vt 0.000000 0.464474 -vt 0.000000 0.472919 -vt 1.000000 0.472919 -vt 1.000000 0.481364 -vt 0.000000 0.481364 -vt 0.000000 0.489808 -vt 1.000000 0.489808 -vt 1.000000 0.498253 -vt 0.000000 0.498253 -vt 0.000000 0.506698 -vt 1.000000 0.506698 -vt 1.000000 0.515143 -vt 0.000000 0.515143 -vt 0.000000 0.523588 -vt 1.000000 0.523588 -vt 1.000000 0.532033 -vt 0.000000 0.532033 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -s off -g overscan_1_geo -usemtl lambert2SG -f 1654/2479/2361 1655/2480/2362 1656/2481/2363 1657/2482/2364 -f 1658/2483/2365 1659/2484/2366 1660/2485/2367 1661/2486/2368 -f 1662/2487/2369 1663/2488/2370 1664/2489/2371 1665/2490/2372 -f 1666/2491/2373 1667/2492/2374 1668/2493/2375 1669/2494/2376 -f 1670/2495/2377 1671/2496/2378 1672/2497/2379 1673/2498/2380 -f 1674/2499/2381 1675/2500/2382 1676/2501/2383 1677/2502/2384 -f 1678/2503/2385 1679/2504/2386 1680/2505/2387 1681/2506/2388 -f 1682/2507/2389 1683/2508/2390 1684/2509/2391 1685/2510/2392 -f 1686/2511/2393 1687/2512/2394 1688/2513/2395 1689/2514/2396 -f 1690/2515/2397 1691/2516/2398 1692/2517/2399 1693/2518/2400 -f 1694/2519/2401 1695/2520/2402 1696/2521/2403 1697/2522/2404 -f 1698/2523/2405 1699/2524/2406 1700/2525/2407 1701/2526/2408 -f 1702/2527/2409 1703/2528/2410 1704/2529/2411 1705/2530/2412 -f 1706/2531/2413 1707/2532/2414 1708/2533/2415 1709/2534/2416 -f 1710/2535/2417 1711/2536/2418 1712/2537/2419 1713/2538/2420 -f 1714/2539/2421 1715/2540/2422 1716/2541/2423 1717/2542/2424 -f 1718/2543/2425 1719/2544/2426 1720/2545/2427 1721/2546/2428 -f 1722/2547/2429 1723/2548/2430 1724/2549/2431 1725/2550/2432 -f 1726/2551/2433 1727/2552/2434 1728/2553/2435 1729/2554/2436 -f 1730/2555/2437 1731/2556/2438 1732/2557/2439 1733/2558/2440 -f 1734/2559/2441 1735/2560/2442 1736/2561/2443 1737/2562/2444 -f 1738/2563/2445 1739/2564/2446 1740/2565/2447 1741/2566/2448 -f 1742/2567/2449 1743/2568/2450 1744/2569/2451 1745/2570/2452 -f 1746/2571/2453 1747/2572/2454 1748/2573/2455 1749/2574/2456 -f 1750/2575/2457 1751/2576/2458 1752/2577/2459 1753/2578/2460 -f 1754/2579/2461 1755/2580/2462 1756/2581/2463 1757/2582/2464 -f 1758/2583/2465 1759/2584/2466 1760/2585/2467 1761/2586/2468 -f 1762/2587/2469 1763/2588/2470 1764/2589/2471 1765/2590/2472 -f 1766/2591/2473 1767/2592/2474 1768/2593/2475 1769/2594/2476 -f 1770/2595/2477 1771/2596/2478 1772/2597/2479 1773/2598/2480 -f 1774/2599/2481 1775/2600/2482 1776/2601/2483 1777/2602/2484 -f 1778/2603/2485 1779/2604/2486 1780/2605/2487 1781/2606/2488 -g default -v 0.616473 -1.025815 3.962625 -v 0.686349 0.000000 3.815101 -v 0.610931 -1.025890 5.797148 -v 0.631357 0.000000 5.944634 -v 0.607510 -1.157449 4.879924 -v 0.622460 0.000000 4.879924 -v 0.622878 -0.602220 5.914624 -v 0.621902 -0.649286 4.879924 -v 0.652666 -0.602220 3.845186 -v 0.586636 -1.128306 5.418849 -v 0.621172 -0.632342 5.430258 -v 0.621644 0.000000 5.441102 -v 0.642347 -1.130866 4.441946 -v 0.621761 -0.633698 4.430763 -v 0.622391 0.000000 4.420069 -v 0.621172 0.632417 5.430258 -v 0.622878 0.602145 5.914624 -v 0.621761 0.633698 4.430763 -v 0.621902 0.649286 4.879924 -v 0.600953 1.128306 5.418849 -v 0.610931 1.025890 5.797148 -v 0.621826 1.157449 4.879924 -v 0.642347 1.131017 4.441946 -v 0.616473 1.025815 3.962625 -v 0.652666 0.602220 3.845186 -v 0.587291 -1.115955 3.883742 -v 0.627016 -0.620820 3.718785 -v 0.585132 -1.116483 5.875842 -v 0.593791 -0.621423 6.040573 -v 0.613654 -1.264760 4.422743 -v 0.627814 -1.289761 4.880037 -v 0.608005 -1.257530 5.437939 -v 0.600654 0.000000 6.075101 -v 0.663273 0.000000 3.684069 -v 0.593791 0.621423 6.040573 -v 0.585132 1.116407 5.875842 -v 0.608005 1.257530 5.437939 -v 0.613654 1.264760 4.422743 -v 0.627814 1.289761 4.880037 -v 0.587291 1.116031 3.883742 -v 0.627016 0.620820 3.718785 -v 0.587100 0.674890 3.614863 -v 0.543119 1.214832 3.795220 -v 0.587664 1.404301 4.880075 -v 0.571780 1.376287 4.374133 -v 0.566429 1.369133 5.486624 -v 0.540981 1.215510 5.964439 -v 0.550875 0.675492 6.144420 -v 0.626176 0.000000 3.577361 -v 0.557981 0.000000 6.181583 -v 0.566429 -1.369058 5.486624 -v 0.587664 -1.404301 4.880075 -v 0.571780 -1.376287 4.374133 -v 0.550875 -0.675492 6.144420 -v 0.540981 -1.215510 5.964439 -v 0.587100 -0.674815 3.614863 -v 0.543119 -1.214832 3.795220 -v 0.651113 0.316736 3.690771 -v 0.602941 0.902464 3.773946 -v 0.643772 0.600714 3.762764 -v 0.602696 1.227634 4.164708 -v 0.605824 1.073860 3.922675 -v 0.621356 1.281854 5.165784 -v 0.620527 1.281703 4.594327 -v 0.645017 1.242319 4.879961 -v 0.631272 1.216564 4.440440 -v 0.594738 1.218597 5.684264 -v 0.625240 1.211519 5.420205 -v 0.587632 0.902840 5.985449 -v 0.603292 1.074161 5.837059 -v 0.598622 0.317112 6.068437 -v 0.612005 0.601090 5.996858 -v 0.620527 -1.281779 4.594327 -v 0.594738 -1.218597 5.684264 -v 0.651113 -0.316661 3.690771 -v 0.679338 0.000000 3.729591 -v 0.598622 -0.317037 6.068437 -v 0.618931 0.000000 6.030784 -v 0.621356 -1.281929 5.165784 -v 0.625240 -1.211443 5.420205 -v 0.645017 -1.242319 4.879961 -v 0.602696 -1.227634 4.164708 -v 0.631272 -1.216564 4.440440 -v 0.587632 -0.902840 5.985449 -v 0.612005 -0.601015 5.996858 -v 0.603292 -1.074161 5.837059 -v 0.602941 -0.902464 3.773946 -v 0.643772 -0.600714 3.762764 -v 0.605824 -1.073860 3.922675 -v 0.675135 0.308377 3.821276 -v 0.620527 0.617582 4.145693 -v 0.629016 0.870609 3.891499 -v 0.629303 1.096677 4.194679 -v 0.614720 1.150069 5.156258 -v 0.621641 0.644466 5.156107 -v 0.621093 0.920010 4.437728 -v 0.615816 1.150144 4.603590 -v 0.588541 0.941849 4.879924 -v 0.619207 1.093439 5.655648 -v 0.614739 0.870685 5.868274 -v 0.587925 0.917751 5.423104 -v 0.621879 0.644391 4.603740 -v 0.622305 0.331496 4.879924 -v 0.622214 0.323438 4.423571 -v 0.620555 0.615624 5.704710 -v 0.628868 0.308377 5.938421 -v 0.621509 0.322911 5.437562 -v 0.620527 -0.617582 4.145693 -v 0.622480 0.000000 4.599335 -v 0.622214 -0.323438 4.423571 -v 0.621093 -0.920010 4.437728 -v 0.601499 -1.150069 4.603590 -v 0.621509 -0.322836 5.437562 -v 0.620893 0.000000 5.725607 -v 0.573608 -0.917751 5.423104 -v 0.621641 -0.644391 5.156107 -v 0.619207 -1.093514 5.655648 -v 0.621879 -0.644391 4.603740 -v 0.675135 -0.308302 3.821276 -v 0.620555 -0.615624 5.704710 -v 0.622305 -0.331571 4.879924 -v 0.628868 -0.308302 5.938421 -v 0.574224 -0.941849 4.879924 -v 0.622171 0.000000 5.160513 -v 0.600403 -1.150069 5.156258 -v 0.629303 -1.096602 4.194679 -v 0.614739 -0.870685 5.868274 -v 0.629016 -0.870609 3.891499 -v 0.613197 0.343771 3.584665 -v 0.559780 0.981459 3.674920 -v 0.558386 1.336601 4.094109 -v 0.580876 1.395716 5.190372 -v 0.579865 1.395490 4.569852 -v 0.550939 1.327414 5.755089 -v 0.543311 0.982137 6.084439 -v 0.555992 0.344298 6.174467 -v 0.579865 -1.395490 4.569852 -v 0.550939 -1.327489 5.755089 -v 0.613197 -0.343771 3.584628 -v 0.555992 -0.344298 6.174467 -v 0.580876 -1.395716 5.190372 -v 0.558386 -1.336677 4.094109 -v 0.543311 -0.982137 6.084439 -v 0.559780 -0.981384 3.674920 -v 0.667295 0.307097 3.735879 -v 0.620218 0.870459 3.816908 -v 0.619080 1.178459 4.194642 -v 0.638432 1.234713 5.157350 -v 0.637878 1.234788 4.602611 -v 0.611707 1.172585 5.655196 -v 0.605441 0.870760 5.942713 -v 0.616825 0.307323 6.023931 -v 0.637878 -1.234863 4.602611 -v 0.611707 -1.172510 5.655196 -v 0.667295 -0.307021 3.735879 -v 0.616825 -0.307323 6.023931 -v 0.638432 -1.234788 5.157350 -v 0.619080 -1.178459 4.194642 -v 0.605441 -0.870835 5.942713 -v 0.620218 -0.870459 3.816908 -v 0.620025 0.315908 4.096292 -v 0.620475 0.894180 4.172690 -v 0.622021 0.328935 5.158743 -v 0.588324 0.935372 5.155581 -v 0.588454 0.935448 4.604267 -v 0.620223 0.891394 5.677675 -v 0.622315 0.328935 4.601104 -v 0.620794 0.314853 5.720562 -v 0.620025 -0.315832 4.096292 -v 0.620475 -0.894180 4.172690 -v 0.622021 -0.328935 5.158743 -v 0.574008 -0.935372 5.155581 -v 0.574138 -0.935448 4.604267 -v 0.620223 -0.891469 5.677675 -v 0.622315 -0.328860 4.601104 -v 0.620794 -0.314853 5.720562 -v 0.620025 0.000000 4.056418 -vt 0.375000 0.000000 -vt 0.625000 0.000000 -vt 0.375000 0.250000 -vt 0.625000 0.250000 -vt 0.375000 0.125000 -vt 0.625000 0.125000 -vt 0.500000 0.250000 -vt 0.500000 0.125000 -vt 0.500000 0.000000 -vt 0.375000 0.187500 -vt 0.500000 0.187500 -vt 0.625000 0.187500 -vt 0.375000 0.062500 -vt 0.500000 0.062500 -vt 0.625000 0.062500 -vt 0.500000 0.187500 -vt 0.625000 0.187500 -vt 0.625000 0.250000 -vt 0.500000 0.250000 -vt 0.500000 0.062500 -vt 0.625000 0.062500 -vt 0.625000 0.125000 -vt 0.500000 0.125000 -vt 0.375000 0.187500 -vt 0.375000 0.250000 -vt 0.375000 0.125000 -vt 0.375000 0.062500 -vt 0.375000 0.000000 -vt 0.500000 0.000000 -vt 0.625000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 0.000000 -vt 0.500000 1.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 1.000000 -vt 0.500000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.500000 0.000000 -vt 0.562500 0.000000 -vt 0.500000 0.031250 -vt 0.500000 0.000000 -vt 0.437500 0.000000 -vt 0.375000 0.031250 -vt 0.500000 0.000000 -vt 0.375000 0.156250 -vt 0.500000 0.000000 -vt 0.500000 0.156250 -vt 0.437500 0.062500 -vt 0.375000 0.093750 -vt 0.500000 0.000000 -vt 0.437500 0.125000 -vt 0.375000 0.218750 -vt 0.500000 0.000000 -vt 0.437500 0.250000 -vt 0.500000 0.000000 -vt 0.437500 0.187500 -vt 0.500000 0.093750 -vt 0.562500 0.125000 -vt 0.562500 0.062500 -vt 0.500000 0.218750 -vt 0.562500 0.250000 -vt 0.500000 0.000000 -vt 0.562500 0.187500 -vt 0.500000 0.031250 -vt 0.625000 0.093750 -vt 0.625000 0.093750 -vt 0.562500 0.062500 -vt 0.437500 0.062500 -vt 0.500000 0.000000 -vt 0.375000 0.093750 -vt 0.562500 0.187500 -vt 0.625000 0.218750 -vt 0.625000 0.218750 -vt 0.437500 0.187500 -vt 0.500000 0.156250 -vt 0.500000 0.000000 -vt 0.375000 0.218750 -vt 0.500000 0.093750 -vt 0.562500 0.000000 -vt 0.500000 0.000000 -vt 0.500000 0.218750 -vt 0.562500 0.125000 -vt 0.500000 0.000000 -vt 0.562500 0.250000 -vt 0.437500 0.125000 -vt 0.625000 0.156250 -vt 0.625000 0.156250 -vt 0.500000 0.000000 -vt 0.375000 0.156250 -vt 0.500000 0.000000 -vt 0.375000 0.031250 -vt 0.500000 0.000000 -vt 0.437500 0.250000 -vt 0.437500 0.000000 -vt 0.500000 0.000000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.500000 0.500000 -vt 0.562500 0.031250 -vt 0.437500 0.031250 -vt 0.562500 0.156250 -vt 0.437500 0.156250 -vt 0.437500 0.093750 -vt 0.437500 0.218750 -vt 0.562500 0.093750 -vt 0.562500 0.218750 -vt 0.562500 0.031250 -vt 0.437500 0.031250 -vt 0.562500 0.156250 -vt 0.437500 0.156250 -vt 0.437500 0.093750 -vt 0.437500 0.218750 -vt 0.562500 0.093750 -vt 0.562500 0.218750 -vt 0.500000 1.000000 -vt 0.500000 1.000000 -vt 0.500000 1.000000 -vt 0.500000 1.000000 -vn 0.998187 -0.058081 -0.015779 -vn 0.999997 -0.000757 0.002175 -vn 0.999912 -0.003060 -0.012915 -vn 0.999447 -0.025231 -0.021639 -vn 0.999706 -0.014768 0.019260 -vn 0.999991 -0.000719 -0.004169 -vn 1.000000 -0.000923 -0.000233 -vn 0.997694 -0.063715 0.023390 -vn 0.988841 0.140140 -0.050542 -vn 0.997760 -0.046454 -0.048142 -vn 0.997789 -0.031963 -0.058273 -vn 0.996324 0.034619 -0.078360 -vn 0.997421 -0.020686 0.068731 -vn 0.997435 0.016310 0.069691 -vn 0.975070 0.221897 0.000872 -vn 0.999472 -0.032494 0.000682 -vn 0.998960 -0.044372 0.010506 -vn 0.977785 0.209172 0.013587 -vn 0.996837 -0.079467 0.000411 -vn 1.000000 -0.000871 0.000509 -vn 0.999999 -0.000826 0.001422 -vn 0.996840 -0.079318 0.004292 -vn 0.999927 0.000424 0.012110 -vn 0.998763 -0.013262 0.047930 -vn 0.999110 0.040880 -0.010376 -vn 0.999689 0.019461 -0.015582 -vn 0.999912 0.003060 -0.012916 -vn 0.999997 0.000757 0.002175 -vn 0.999866 0.010668 0.012451 -vn 0.998859 0.044931 0.016185 -vn 1.000000 0.000923 -0.000233 -vn 0.999991 0.000719 -0.004169 -vn 0.994301 -0.103741 -0.024574 -vn 0.999017 -0.018861 -0.040117 -vn 0.999096 0.023114 -0.035670 -vn 0.999224 0.025139 -0.030329 -vn 0.998689 -0.022061 0.046186 -vn 0.998886 -0.002155 0.047140 -vn 0.984471 -0.175545 0.000872 -vn 0.986565 -0.162540 0.016458 -vn 0.999824 0.016178 0.009466 -vn 0.999989 0.004618 0.000672 -vn 0.998437 0.055891 0.000406 -vn 0.998438 0.055761 0.003398 -vn 0.999999 0.000826 0.001422 -vn 1.000000 0.000871 0.000509 -vn 0.998763 0.013264 0.047926 -vn 0.999927 -0.000424 0.012107 -vn 0.997007 -0.041422 0.065275 -vn 0.998712 -0.049227 0.012266 -vn 0.972617 -0.136372 -0.188202 -vn 0.977133 -0.104744 -0.185040 -vn 0.996203 -0.048395 0.072377 -vn 0.998283 -0.031593 0.049322 -vn 0.972611 -0.084955 0.216359 -vn 0.971664 -0.151159 0.181714 -vn 0.997273 -0.057642 -0.046082 -vn 0.999292 -0.009510 -0.036397 -vn 0.975916 -0.195553 -0.096685 -vn 0.969445 -0.189718 -0.155508 -vn 0.988456 0.148947 0.027752 -vn 0.989786 0.142563 -0.000264 -vn 0.999320 -0.020352 0.030763 -vn 0.999824 -0.010049 0.015870 -vn 0.973335 -0.023420 0.228192 -vn 0.973657 -0.049382 0.222608 -vn 0.988343 -0.000000 0.152242 -vn 0.992115 -0.022164 0.123358 -vn 0.981396 -0.064937 -0.180681 -vn 0.984111 0.000000 -0.177555 -vn 0.995620 -0.076763 0.053379 -vn 0.996395 0.082182 0.021069 -vn 0.995186 0.056593 0.080009 -vn 0.979936 0.183909 0.076830 -vn 0.997374 0.072370 0.002919 -vn 0.991538 -0.127629 -0.023747 -vn 0.999947 0.000000 0.010290 -vn 0.999824 0.010051 0.015871 -vn 0.973335 0.023409 0.228192 -vn 0.973275 0.000000 0.229642 -vn 0.999320 0.020351 0.030761 -vn 0.998283 0.031595 0.049321 -vn 0.972615 0.084946 0.216344 -vn 0.973659 0.049401 0.222595 -vn 0.996203 0.048387 0.072377 -vn 0.991507 0.109733 0.069804 -vn 0.971656 0.151174 0.181743 -vn 0.987970 -0.146709 0.048913 -vn 0.999848 0.013845 -0.010637 -vn 0.999285 -0.037814 -0.000268 -vn 0.998438 -0.044473 0.033824 -vn 0.999286 0.000920 0.037770 -vn 0.997723 -0.047811 0.047560 -vn 0.999292 0.009504 -0.036392 -vn 0.975897 0.195634 -0.096706 -vn 0.988049 0.149391 -0.037971 -vn 0.997274 0.057636 -0.046078 -vn 0.998712 0.049226 0.012265 -vn 0.972621 0.136361 -0.188188 -vn 0.969456 0.189676 -0.155490 -vn 0.997007 0.041428 0.065271 -vn 0.992114 0.022164 0.123366 -vn 0.981396 0.064936 -0.180681 -vn 0.977132 0.104760 -0.185037 -vn 0.945516 -0.119497 -0.302853 -vn 0.947398 -0.164730 -0.274411 -vn 0.946814 -0.175468 -0.269730 -vn 0.945275 -0.125763 -0.301062 -vn 0.948912 -0.205547 0.239411 -vn 0.940289 -0.119109 0.318857 -vn 0.940479 -0.131484 0.313388 -vn 0.947944 -0.210891 0.238597 -vn 0.949862 -0.240275 -0.200075 -vn 0.948314 -0.292250 -0.123655 -vn 0.946138 -0.293414 -0.136863 -vn 0.948447 -0.244135 -0.202106 -vn 0.942940 -0.332961 -0.001454 -vn 0.943584 -0.327149 0.051204 -vn 0.944339 -0.324451 0.054374 -vn 0.943859 -0.330344 -0.001562 -vn 0.933281 -0.066045 0.353022 -vn 0.929243 -0.029560 0.368284 -vn 0.930206 -0.032306 0.365614 -vn 0.933685 -0.072414 0.350697 -vn 0.944481 0.000005 -0.328565 -vn 0.944553 -0.071024 -0.320585 -vn 0.945016 -0.076662 -0.317911 -vn 0.944832 0.000005 -0.327555 -vn 0.945132 -0.314985 0.086664 -vn 0.948616 -0.284634 0.138245 -vn 0.947811 -0.281428 0.149841 -vn 0.944894 -0.314694 0.090236 -vn 0.945353 -0.315975 -0.080419 -vn 0.942868 -0.329853 -0.046873 -vn 0.943646 -0.327272 -0.049240 -vn 0.943310 -0.321438 -0.082734 -vn 0.927777 -0.000000 0.373136 -vn 0.929242 0.029569 0.368286 -vn 0.930202 0.032300 0.365625 -vn 0.928621 0.000000 0.371031 -vn 0.933278 0.066047 0.353029 -vn 0.940295 0.119118 0.318834 -vn 0.940489 0.131484 0.313356 -vn 0.933683 0.072418 0.350701 -vn 0.948906 0.205549 0.239432 -vn 0.948588 0.284690 0.138317 -vn 0.947811 0.281409 0.149877 -vn 0.947951 0.210898 0.238560 -vn 0.942966 0.332885 -0.001454 -vn 0.942891 0.329789 -0.046872 -vn 0.943678 0.327184 -0.049229 -vn 0.943895 0.330243 -0.001563 -vn 0.945130 0.314997 0.086639 -vn 0.943605 0.327093 0.051184 -vn 0.944386 0.324317 0.054342 -vn 0.944924 0.314603 0.090239 -vn 0.945354 0.315978 -0.080398 -vn 0.948294 0.292315 -0.123652 -vn 0.946091 0.293557 -0.136877 -vn 0.943300 0.321463 -0.082746 -vn 0.949852 0.240334 -0.200053 -vn 0.947416 0.164706 -0.274362 -vn 0.946825 0.175470 -0.269692 -vn 0.948421 0.244209 -0.202139 -vn 0.945517 0.119488 -0.302854 -vn 0.944539 0.071032 -0.320626 -vn 0.944996 0.076647 -0.317974 -vn 0.945286 0.125760 -0.301029 -vn 0.996684 0.005139 0.081204 -vn 0.999999 -0.000000 0.001443 -vn 0.999998 -0.000000 0.002227 -vn 1.000000 0.000000 0.000538 -vn 1.000000 -0.000000 -0.000179 -vn 0.999990 0.000000 -0.004528 -vn 0.999857 0.000000 -0.016939 -vn 0.996685 -0.005139 0.081200 -vn 0.973442 0.000598 0.228933 -vn 0.999978 -0.000724 -0.006601 -vn 0.973442 -0.000598 0.228933 -vn 0.999978 0.000724 -0.006601 -s 1 -g backScreen_mat -usemtl lambert2SG -f 1792/2617/2489 1894/2862/2490 1957/2934/2491 1901/2872/2492 -f 1795/2620/2493 1891/2858/2494 1956/2933/2495 1899/2869/2496 -f 1791/2616/2497 1896/2865/2498 1955/2932/2499 1898/2868/2500 -f 1795/2620/2493 1899/2869/2496 1954/2931/2501 1892/2859/2502 -f 1786/2611/2503 1904/2876/2504 1953/2930/2505 1906/2880/2506 -f 1789/2614/2507 1902/2873/2508 1952/2929/2509 1897/2866/2510 -f 1795/2620/2493 1892/2859/2502 1951/2928/2511 1889/2855/2512 -f 1797/2622/2513 1886/2851/2514 1949/2926/2515 1888/2854/2516 -f 1799/2626/2517 1883/2848/2518 1948/2925/2519 1885/2850/2520 -f 1801/2630/2521 1880/2843/2522 1947/2924/2523 1882/2847/2524 -f 1799/2626/2517 1877/2839/2525 1946/2923/2526 1883/2848/2518 -f 1803/2632/2527 1875/2836/2528 1945/2922/2529 1879/2842/2530 -f 1800/2629/2531 1876/2838/2532 1944/2921/2533 1884/2849/2534 -f 1799/2626/2517 1872/2831/2535 1943/2920/2536 1877/2839/2525 -f 1790/2637/2537 1909/2886/2538 1941/2918/2539 1869/2826/2540 -f 1784/2641/2541 1908/2883/2542 1940/2917/2543 1867/2822/2544 -f 1782/2645/2545 1907/2881/2546 1939/2916/2547 1870/2828/2548 -f 1786/2649/2503 1906/2879/2506 1938/2915/2549 1862/2812/2550 -f 1788/2653/2551 1903/2874/2552 1937/2914/2553 1866/2820/2554 -f 1783/2657/2555 1900/2871/2556 1936/2913/2557 1857/2802/2558 -f 1791/2661/2497 1898/2867/2500 1935/2912/2559 1861/2810/2560 -f 1794/2665/2561 1893/2860/2562 1934/2911/2563 1864/2816/2564 -f 1785/2669/2565 1887/2853/2566 1933/2910/2567 1859/2806/2568 -f 1798/2673/2569 1881/2846/2570 1932/2909/2571 1853/2794/2572 -f 1802/2677/2573 1880/2844/2522 1931/2908/2574 1851/2790/2575 -f 1803/2681/2527 1878/2841/2576 1930/2907/2577 1846/2780/2578 -f 1801/2685/2521 1875/2837/2528 1929/2906/2579 1849/2786/2580 -f 1804/2689/2581 1874/2835/2582 1928/2905/2583 1847/2782/2584 -f 1805/2693/2585 1873/2832/2586 1927/2904/2587 1843/2774/2588 -f 1806/2697/2589 1871/2829/2590 1926/2903/2591 1841/2770/2592 -f 1808/2701/2593 1868/2824/2594 1925/2902/2595 1837/2762/2596 -f 1809/2703/2597 1865/2817/2598 1924/2901/2599 1836/2760/2600 -f 1807/2705/2601 1863/2813/2602 1923/2900/2603 1838/2764/2604 -f 1812/2707/2605 1860/2807/2606 1922/2899/2607 1833/2754/2608 -f 1810/2709/2609 1858/2803/2610 1921/2898/2611 1835/2758/2612 -f 1815/2711/2613 1856/2800/2614 1920/2897/2615 1830/2748/2616 -f 1813/2713/2617 1855/2797/2618 1919/2896/2619 1832/2752/2620 -f 1811/2715/2621 1854/2795/2622 1918/2895/2623 1834/2756/2624 -f 1814/2717/2625 1852/2792/2626 1917/2894/2627 1831/2750/2628 -f 1816/2719/2629 1850/2788/2630 1916/2893/2631 1829/2746/2632 -f 1817/2721/2633 1848/2784/2634 1915/2892/2635 1828/2744/2636 -f 1820/2723/2637 1845/2778/2638 1914/2891/2639 1825/2738/2640 -f 1818/2725/2641 1844/2776/2642 1913/2890/2643 1827/2742/2644 -f 1819/2727/2645 1842/2772/2646 1912/2889/2647 1826/2740/2648 -f 1821/2729/2649 1840/2767/2650 1911/2888/2651 1824/2736/2652 -f 1822/2731/2653 1839/2765/2654 1910/2887/2655 1823/2734/2656 -f 1830/2747/2616 1910/2887/2655 1839/2765/2654 1815/2732/2613 -f 1823/2733/2656 1911/2888/2651 1840/2767/2650 1822/2730/2653 -f 1824/2735/2652 1912/2889/2647 1842/2772/2646 1821/2728/2649 -f 1825/2737/2640 1913/2890/2643 1844/2776/2642 1820/2726/2637 -f 1826/2739/2648 1914/2891/2639 1845/2778/2638 1819/2724/2645 -f 1827/2741/2644 1915/2892/2635 1848/2784/2634 1818/2722/2641 -f 1828/2743/2636 1916/2893/2631 1850/2788/2630 1817/2720/2633 -f 1829/2745/2632 1917/2894/2627 1852/2792/2626 1816/2718/2629 -f 1833/2753/2608 1918/2895/2623 1854/2795/2622 1812/2716/2605 -f 1836/2759/2600 1919/2896/2619 1855/2797/2618 1809/2714/2597 -f 1837/2761/2596 1920/2897/2615 1856/2800/2614 1808/2712/2593 -f 1831/2749/2628 1921/2898/2611 1858/2803/2610 1814/2710/2625 -f 1832/2751/2620 1922/2899/2607 1860/2807/2606 1813/2708/2617 -f 1834/2755/2624 1923/2900/2603 1863/2813/2602 1811/2706/2621 -f 1835/2757/2612 1924/2901/2599 1865/2817/2598 1810/2704/2609 -f 1838/2763/2604 1925/2902/2595 1868/2824/2594 1807/2702/2601 -f 1839/2766/2654 1926/2903/2591 1857/2801/2558 1815/2699/2613 -f 1857/2801/2558 1926/2903/2591 1871/2829/2590 1783/2698/2555 -f 1841/2770/2592 1926/2903/2591 1839/2766/2654 1822/2700/2653 -f 1840/2768/2650 1927/2904/2587 1841/2769/2592 1822/2695/2653 -f 1841/2769/2592 1927/2904/2587 1873/2832/2586 1806/2694/2589 -f 1843/2774/2588 1927/2904/2587 1840/2768/2650 1821/2696/2649 -f 1842/2771/2646 1928/2905/2583 1843/2773/2588 1821/2691/2649 -f 1843/2773/2588 1928/2905/2583 1874/2835/2582 1805/2690/2585 -f 1847/2782/2584 1928/2905/2583 1842/2771/2646 1819/2692/2645 -f 1844/2775/2642 1929/2906/2579 1846/2779/2578 1820/2687/2637 -f 1846/2779/2578 1929/2906/2579 1875/2837/2528 1803/2686/2527 -f 1849/2786/2580 1929/2906/2579 1844/2775/2642 1818/2688/2641 -f 1845/2777/2638 1930/2907/2577 1847/2781/2584 1819/2683/2645 -f 1847/2781/2584 1930/2907/2577 1878/2841/2576 1804/2682/2581 -f 1846/2780/2578 1930/2907/2577 1845/2777/2638 1820/2684/2637 -f 1848/2783/2634 1931/2908/2574 1849/2785/2580 1818/2679/2641 -f 1849/2785/2580 1931/2908/2574 1880/2844/2522 1801/2678/2521 -f 1851/2790/2575 1931/2908/2574 1848/2783/2634 1817/2680/2633 -f 1850/2787/2630 1932/2909/2571 1851/2789/2575 1817/2675/2633 -f 1851/2789/2575 1932/2909/2571 1881/2846/2570 1802/2674/2573 -f 1853/2794/2572 1932/2909/2571 1850/2787/2630 1816/2676/2629 -f 1852/2791/2626 1933/2910/2567 1853/2793/2572 1816/2671/2629 -f 1853/2793/2572 1933/2910/2567 1887/2853/2566 1798/2670/2569 -f 1859/2806/2568 1933/2910/2567 1852/2791/2626 1814/2672/2625 -f 1854/2796/2622 1934/2911/2563 1862/2811/2550 1812/2667/2605 -f 1862/2811/2550 1934/2911/2563 1893/2860/2562 1786/2666/2503 -f 1864/2816/2564 1934/2911/2563 1854/2796/2622 1811/2668/2621 -f 1855/2798/2618 1935/2912/2559 1867/2821/2544 1809/2663/2597 -f 1867/2821/2544 1935/2912/2559 1898/2867/2500 1784/2662/2541 -f 1861/2810/2560 1935/2912/2559 1855/2798/2618 1813/2664/2617 -f 1856/2799/2614 1936/2913/2557 1869/2825/2540 1808/2659/2593 -f 1869/2825/2540 1936/2913/2557 1900/2871/2556 1790/2658/2537 -f 1857/2802/2558 1936/2913/2557 1856/2799/2614 1815/2660/2613 -f 1858/2804/2610 1937/2914/2553 1859/2805/2568 1814/2655/2625 -f 1859/2805/2568 1937/2914/2553 1903/2874/2552 1785/2654/2565 -f 1866/2820/2554 1937/2914/2553 1858/2804/2610 1810/2656/2609 -f 1860/2808/2606 1938/2915/2549 1861/2809/2560 1813/2651/2617 -f 1861/2809/2560 1938/2915/2549 1906/2879/2506 1791/2650/2497 -f 1862/2812/2550 1938/2915/2549 1860/2808/2606 1812/2652/2605 -f 1863/2814/2602 1939/2916/2547 1864/2815/2564 1811/2647/2621 -f 1864/2815/2564 1939/2916/2547 1907/2881/2546 1794/2646/2561 -f 1870/2828/2548 1939/2916/2547 1863/2814/2602 1807/2648/2601 -f 1865/2818/2598 1940/2917/2543 1866/2819/2554 1810/2643/2609 -f 1866/2819/2554 1940/2917/2543 1908/2883/2542 1788/2642/2551 -f 1867/2822/2544 1940/2917/2543 1865/2818/2598 1809/2644/2597 -f 1868/2823/2594 1941/2918/2539 1870/2827/2548 1807/2639/2601 -f 1870/2827/2548 1941/2918/2539 1909/2886/2538 1782/2638/2545 -f 1869/2826/2540 1941/2918/2539 1868/2823/2594 1808/2640/2593 -f 1885/2850/2520 1942/2919/2657 1872/2831/2535 1799/2626/2517 -f 1872/2831/2535 1942/2919/2657 1871/2830/2590 1806/2635/2589 -f 1874/2834/2582 1943/2920/2536 1873/2833/2586 1805/2634/2585 -f 1873/2833/2586 1943/2920/2536 1872/2831/2535 1806/2635/2589 -f 1877/2839/2525 1943/2920/2536 1874/2834/2582 1804/2633/2581 -f 1905/2878/2658 1944/2921/2533 1888/2854/2516 1793/2623/2659 -f 1888/2854/2516 1944/2921/2533 1876/2838/2532 1797/2622/2513 -f 1884/2849/2534 1944/2921/2533 1905/2878/2658 1787/2628/2660 -f 1876/2838/2532 1945/2922/2529 1882/2847/2524 1797/2622/2513 -f 1882/2847/2524 1945/2922/2529 1875/2836/2528 1801/2630/2521 -f 1879/2842/2530 1945/2922/2529 1876/2838/2532 1800/2629/2531 -f 1879/2842/2530 1946/2923/2526 1878/2840/2576 1803/2632/2527 -f 1878/2840/2576 1946/2923/2526 1877/2839/2525 1804/2633/2581 -f 1883/2848/2518 1946/2923/2526 1879/2842/2530 1800/2629/2531 -f 1886/2851/2514 1947/2924/2523 1881/2845/2570 1798/2625/2569 -f 1881/2845/2570 1947/2924/2523 1880/2843/2522 1802/2631/2573 -f 1882/2847/2524 1947/2924/2523 1886/2851/2514 1797/2622/2513 -f 1890/2857/2661 1948/2925/2519 1884/2849/2534 1787/2628/2660 -f 1884/2849/2534 1948/2925/2519 1883/2848/2518 1800/2629/2531 -f 1885/2850/2520 1948/2925/2519 1890/2857/2661 1796/2627/2662 -f 1895/2864/2663 1949/2926/2515 1887/2852/2566 1785/2624/2565 -f 1887/2852/2566 1949/2926/2515 1886/2851/2514 1798/2625/2569 -f 1888/2854/2516 1949/2926/2515 1895/2864/2663 1793/2623/2659 -f 1889/2855/2512 1950/2927/2664 1891/2858/2494 1795/2620/2493 -f 1900/2870/2556 1950/2927/2664 1889/2855/2512 1790/2615/2537 -f 1909/2885/2538 1951/2928/2511 1907/2882/2546 1782/2607/2545 -f 1907/2882/2546 1951/2928/2511 1892/2859/2502 1794/2619/2561 -f 1889/2855/2512 1951/2928/2511 1909/2885/2538 1790/2615/2537 -f 1894/2862/2490 1952/2929/2509 1905/2877/2658 1793/2618/2659 -f 1905/2877/2658 1952/2929/2509 1902/2873/2508 1787/2612/2660 -f 1897/2866/2510 1952/2929/2509 1894/2862/2490 1792/2617/2489 -f 1896/2865/2498 1953/2930/2505 1897/2866/2510 1792/2617/2489 -f 1897/2866/2510 1953/2930/2505 1904/2876/2504 1789/2614/2507 -f 1906/2880/2506 1953/2930/2505 1896/2865/2498 1791/2616/2497 -f 1893/2861/2562 1954/2931/2501 1904/2876/2504 1786/2611/2503 -f 1904/2876/2504 1954/2931/2501 1899/2869/2496 1789/2614/2507 -f 1892/2859/2502 1954/2931/2501 1893/2861/2562 1794/2619/2561 -f 1908/2884/2542 1955/2932/2499 1901/2872/2492 1788/2613/2551 -f 1901/2872/2492 1955/2932/2499 1896/2865/2498 1792/2617/2489 -f 1898/2868/2500 1955/2932/2499 1908/2884/2542 1784/2609/2541 -f 1902/2873/2508 1956/2933/2495 1890/2856/2661 1787/2612/2660 -f 1890/2856/2661 1956/2933/2495 1891/2858/2494 1796/2621/2662 -f 1899/2869/2496 1956/2933/2495 1902/2873/2508 1789/2614/2507 -f 1903/2875/2552 1957/2934/2491 1895/2863/2663 1785/2610/2565 -f 1895/2863/2663 1957/2934/2491 1894/2862/2490 1793/2618/2659 -f 1901/2872/2492 1957/2934/2491 1903/2875/2552 1788/2613/2551 -f 1942/2919/2657 1958/2936/2665 1783/2636/2555 1871/2830/2590 -f 1796/2621/2662 1891/2858/2494 1950/2927/2664 1958/2938/2666 -f 1783/2608/2555 1958/2935/2667 1950/2927/2664 1900/2870/2556 -f 1796/2627/2662 1958/2937/2668 1942/2919/2657 1885/2850/2520 -g default -v -3.984048 2.834903 2.766335 -v -4.192110 2.834903 2.954602 -v -4.278152 2.834903 3.221668 -v -4.219148 2.834903 3.495978 -v -4.030880 2.834903 3.704021 -v -3.763815 2.834903 3.790082 -v -3.489504 2.834903 3.731060 -v -3.281443 2.834903 3.542811 -v -3.195401 2.834903 3.275745 -v -3.254404 2.834903 3.001435 -v -3.442672 2.834903 2.793373 -v -3.709738 2.834903 2.707331 -v -3.984048 2.025686 2.766335 -v -4.192110 2.025686 2.954602 -v -4.278152 2.025686 3.221668 -v -4.219148 2.025686 3.495978 -v -4.030880 2.025686 3.704021 -v -3.763815 2.025686 3.790082 -v -3.489504 2.025686 3.731060 -v -3.281443 2.025686 3.542811 -v -3.195401 2.025686 3.275745 -v -3.254404 2.025686 3.001435 -v -3.442672 2.025686 2.793373 -v -3.709738 2.025686 2.707331 -v -3.944560 2.922916 2.843386 -v -4.119376 2.922916 3.001571 -v -3.736776 2.922916 3.248706 -v -4.191677 2.922916 3.225987 -v -4.142096 2.922916 3.456471 -v -3.983912 2.922916 3.631306 -v -3.759495 2.922916 3.703589 -v -3.528992 2.922916 3.654027 -v -3.354175 2.922916 3.495824 -v -3.281876 2.922916 3.271426 -v -3.331456 2.922916 3.040923 -v -3.489640 2.922916 2.866107 -v -3.714057 2.922916 2.793806 -v -3.281443 2.113700 3.542811 -v -3.489504 2.113700 3.731060 -v -3.763815 2.113700 3.790082 -v -4.030880 2.113700 3.704021 -v -4.219148 2.113700 3.495978 -v -4.278152 2.113700 3.221668 -v -4.192110 2.113700 2.954602 -v -3.984048 2.113700 2.766335 -v -3.709738 2.113700 2.707331 -v -3.442672 2.113700 2.793373 -v -3.254404 2.113700 3.001435 -v -3.195401 2.113700 3.275745 -v -3.281443 2.489513 3.542811 -v -3.489504 2.489513 3.731060 -v -3.763815 2.489513 3.790082 -v -4.030880 2.489513 3.704021 -v -4.219148 2.489513 3.495978 -v -4.278152 2.489513 3.221668 -v -4.192110 2.489513 2.954602 -v -3.984048 2.489513 2.766335 -v -3.709738 2.489513 2.707331 -v -3.442672 2.489513 2.793373 -v -3.254404 2.489513 3.001435 -v -3.195401 2.489513 3.275745 -v 0.735449 2.489513 3.326228 -v 0.870224 2.489513 3.572334 -v 0.735449 2.113700 3.326228 -v 0.870224 2.113700 3.572334 -v 0.863905 2.489513 3.852844 -v 0.863905 2.113700 3.852844 -v 0.718171 2.489513 4.092612 -v 0.718171 2.113700 4.092612 -v 1.266287 2.298199 3.141169 -v 1.348056 2.298199 3.384628 -v 1.266287 2.055319 3.141169 -v 1.348056 2.055319 3.384628 -v 1.338973 2.298199 3.664999 -v 1.338973 2.055319 3.664999 -v 1.241431 2.298199 3.907175 -v 1.241431 2.055319 3.907175 -v 2.452250 2.165209 2.128483 -v 2.534039 2.165209 2.371942 -v 2.452250 1.922329 2.128483 -v 2.534039 1.922329 2.371942 -v 2.524937 2.165209 2.652313 -v 2.524937 1.922329 2.652313 -v 2.427414 2.165209 2.894490 -v 2.427414 1.922329 2.894490 -v 1.982061 2.218130 2.843256 -v 1.972978 2.218130 3.123627 -v 1.875436 2.218130 3.365802 -v 1.875436 1.975250 3.365802 -v 1.972978 1.975250 3.123627 -v 1.982061 1.975250 2.843256 -v 1.900292 1.975250 2.599797 -v 1.900292 2.218130 2.599797 -vt 0.635316 0.078125 -vt 0.578125 0.020934 -vt 0.500000 0.000000 -vt 0.421875 0.020934 -vt 0.364684 0.078125 -vt 0.343750 0.156250 -vt 0.364684 0.234375 -vt 0.421875 0.291566 -vt 0.500000 0.312500 -vt 0.578125 0.291566 -vt 0.635316 0.234375 -vt 0.656250 0.156250 -vt 0.375000 0.312500 -vt 0.395833 0.312500 -vt 0.416667 0.312500 -vt 0.437500 0.312500 -vt 0.458333 0.312500 -vt 0.479167 0.312500 -vt 0.500000 0.312500 -vt 0.520833 0.312500 -vt 0.541667 0.312500 -vt 0.562500 0.312500 -vt 0.583333 0.312500 -vt 0.604167 0.312500 -vt 0.625000 0.312500 -vt 0.375000 0.688440 -vt 0.395833 0.688440 -vt 0.416667 0.688440 -vt 0.437500 0.688440 -vt 0.458333 0.688440 -vt 0.479167 0.688440 -vt 0.500000 0.688440 -vt 0.520833 0.688440 -vt 0.541667 0.688440 -vt 0.562500 0.688440 -vt 0.583333 0.688440 -vt 0.604167 0.688440 -vt 0.625000 0.688440 -vt 0.500000 0.150000 -vt 0.578125 0.020934 -vt 0.635316 0.078125 -vt 0.500000 0.000000 -vt 0.421875 0.020934 -vt 0.364684 0.078125 -vt 0.343750 0.156250 -vt 0.364684 0.234375 -vt 0.421875 0.291566 -vt 0.500000 0.312500 -vt 0.578125 0.291566 -vt 0.635316 0.234375 -vt 0.656250 0.156250 -vt 0.520833 0.558498 -vt 0.500000 0.558498 -vt 0.479167 0.558498 -vt 0.458333 0.558498 -vt 0.437500 0.558498 -vt 0.416667 0.558498 -vt 0.395833 0.558498 -vt 0.625000 0.558498 -vt 0.375000 0.558498 -vt 0.604167 0.558498 -vt 0.583333 0.558498 -vt 0.562500 0.558498 -vt 0.541667 0.558498 -vt 0.520833 0.430310 -vt 0.500000 0.430310 -vt 0.479167 0.430310 -vt 0.458333 0.430310 -vt 0.437500 0.430310 -vt 0.416667 0.430310 -vt 0.395833 0.430310 -vt 0.625000 0.430310 -vt 0.375000 0.430310 -vt 0.604167 0.430310 -vt 0.583333 0.430310 -vt 0.562500 0.430310 -vt 0.541667 0.430310 -vt 0.562500 0.430310 -vt 0.583333 0.430310 -vt 0.583333 0.558498 -vt 0.562500 0.558498 -vt 0.541667 0.430310 -vt 0.541667 0.558498 -vt 0.520833 0.430310 -vt 0.520833 0.558498 -vt 0.562500 0.430310 -vt 0.583333 0.430310 -vt 0.583333 0.558498 -vt 0.562500 0.558498 -vt 0.541667 0.430310 -vt 0.541667 0.558498 -vt 0.520833 0.430310 -vt 0.520833 0.558498 -vt 0.562500 0.430310 -vt 0.583333 0.430310 -vt 0.583333 0.558498 -vt 0.562500 0.558498 -vt 0.541667 0.430310 -vt 0.541667 0.558498 -vt 0.520833 0.430310 -vt 0.520833 0.558498 -vt 0.562500 0.430310 -vt 0.541667 0.430310 -vt 0.520833 0.430310 -vt 0.520833 0.558498 -vt 0.541667 0.558498 -vt 0.562500 0.558498 -vt 0.583333 0.558498 -vt 0.583333 0.430310 -vn -0.449802 0.166503 -0.877471 -vn -0.456172 0.000000 -0.889891 -vn -0.840010 0.000000 -0.542571 -vn -0.828286 0.166503 -0.534994 -vn -0.998755 0.000000 -0.049882 -vn -0.984812 0.166511 -0.049186 -vn -0.889884 0.000000 0.456188 -vn -0.877462 0.166504 0.449819 -vn -0.542571 0.000000 0.840010 -vn -0.534996 0.166508 0.828284 -vn -0.049882 0.000000 0.998755 -vn -0.049186 0.166505 0.984813 -vn 0.456172 0.000000 0.889892 -vn 0.449803 0.166508 0.877469 -vn 0.011022 0.497546 0.867368 -vn 0.828276 0.166504 0.535010 -vn 0.072393 0.997370 0.003616 -vn 0.984812 0.166511 0.049186 -vn 0.075496 0.996395 -0.038700 -vn 0.877471 0.166503 -0.449802 -vn 0.176103 0.202875 -0.963239 -vn 0.534994 0.166503 -0.828286 -vn 0.049882 0.000000 -0.998755 -vn 0.049186 0.166511 -0.984812 -vn -0.287269 0.939706 -0.185551 -vn 0.000000 1.000000 -0.000000 -vn -0.156004 0.939706 -0.304328 -vn -0.341549 0.939709 -0.017057 -vn -0.304322 0.939709 0.155996 -vn -0.185555 0.939702 0.287281 -vn -0.017058 0.939713 0.341538 -vn 0.156006 0.939701 0.304341 -vn 0.287265 0.939709 0.185543 -vn 0.341549 0.939709 0.017059 -vn 0.304328 0.939706 -0.156004 -vn 0.185551 0.939706 -0.287269 -vn 0.017058 0.939711 -0.341544 -vn 0.456172 0.000000 0.889892 -vn 0.456172 0.000000 0.889892 -vn 0.840001 0.000000 0.542585 -vn -0.051033 -0.514231 0.856132 -vn -0.049882 0.000000 0.998755 -vn -0.049882 0.000000 0.998755 -vn -0.542571 0.000000 0.840010 -vn -0.542571 0.000000 0.840010 -vn -0.889884 0.000000 0.456188 -vn -0.889884 0.000000 0.456188 -vn -0.998755 0.000000 -0.049882 -vn -0.998755 0.000000 -0.049882 -vn -0.840010 0.000000 -0.542571 -vn -0.840010 0.000000 -0.542571 -vn -0.456172 0.000000 -0.889891 -vn -0.456172 0.000000 -0.889892 -vn 0.049882 0.000000 -0.998755 -vn 0.049882 0.000000 -0.998755 -vn 0.145836 -0.217208 -0.965170 -vn 0.542571 0.000000 -0.840010 -vn 0.019303 -0.999765 -0.009895 -vn 0.889891 0.000000 -0.456173 -vn 0.018493 -0.999829 0.000923 -vn 0.998755 0.000000 0.049883 -vn 0.057480 0.998296 -0.010078 -vn 0.090482 0.607768 -0.788943 -vn 0.057753 -0.604438 -0.794556 -vn -0.017698 -0.999839 0.003087 -vn 0.053330 0.998422 0.017598 -vn -0.016464 -0.999849 -0.005522 -vn -0.064164 0.651800 0.755672 -vn -0.069088 -0.643676 0.762174 -vn 0.204876 0.978120 -0.036152 -vn -0.220895 0.705409 -0.673501 -vn -0.424885 -0.714995 -0.555207 -vn -0.113952 -0.993367 0.015392 -vn 0.273649 0.960166 0.056554 -vn -0.149720 -0.988044 -0.036773 -vn 0.539581 0.348256 0.766532 -vn 0.431507 -0.450037 0.781837 -vn 0.097560 0.995119 -0.014864 -vn -0.417837 0.700713 -0.578286 -vn -0.514229 -0.685689 -0.515170 -vn -0.097560 -0.995119 0.014864 -vn 0.132326 0.990913 0.024101 -vn -0.132326 -0.990913 -0.024101 -vn 0.616935 0.426321 0.661545 -vn 0.525479 -0.501699 0.687146 -vn 0.103247 0.994613 0.009236 -vn 0.080761 0.996583 -0.017319 -vn 0.558278 0.585187 0.588117 -vn 0.417971 -0.708175 0.569024 -vn -0.103247 -0.994613 -0.009236 -vn -0.080761 -0.996583 0.017319 -vn -0.549721 -0.605166 -0.575831 -vn -0.492775 0.586358 -0.642929 -s 1 -g lwrArm_L_geo -usemtl blinn2SG -f 1959/2951/2669 2015/3011/2670 2014/3009/2671 1960/2952/2672 -f 1960/2952/2672 2014/3009/2671 2013/3008/2673 1961/2953/2674 -f 1961/2953/2674 2013/3008/2673 2012/3007/2675 1962/2954/2676 -f 1962/2954/2676 2012/3007/2675 2011/3006/2677 1963/2955/2678 -f 1963/2955/2678 2011/3006/2677 2010/3005/2679 1964/2956/2680 -f 1964/2956/2680 2010/3005/2679 2009/3004/2681 1965/2957/2682 -f 1965/2957/2682 2009/3004/2681 2008/3003/2683 1966/2958/2684 -f 1966/2958/2684 2008/3003/2683 2019/3015/2685 1967/2959/2686 -f 1967/2959/2686 2019/3015/2685 2018/3014/2687 1968/2960/2688 -f 1968/2960/2688 2018/3014/2687 2017/3013/2689 1969/2961/2690 -f 1969/2961/2690 2017/3013/2689 2016/3012/2691 1970/2962/2692 -f 1970/2962/2692 2016/3012/2691 2015/3010/2670 1959/2963/2669 -f 1984/2978/2693 1985/2977/2694 1983/2979/2695 -f 1986/2980/2696 1985/2977/2694 1984/2978/2693 -f 1987/2981/2697 1985/2977/2694 1986/2980/2696 -f 1988/2982/2698 1985/2977/2694 1987/2981/2697 -f 1989/2983/2699 1985/2977/2694 1988/2982/2698 -f 1990/2984/2700 1985/2977/2694 1989/2983/2699 -f 1991/2985/2701 1985/2977/2694 1990/2984/2700 -f 1992/2986/2702 1985/2977/2694 1991/2985/2701 -f 1993/2987/2703 1985/2977/2694 1992/2986/2702 -f 1994/2988/2704 1985/2977/2694 1993/2987/2703 -f 1995/2989/2705 1985/2977/2694 1994/2988/2704 -f 1983/2979/2695 1985/2977/2694 1995/2989/2705 -f 1960/2940/2672 1984/2978/2693 1983/2979/2695 1959/2939/2669 -f 1961/2941/2674 1986/2980/2696 1984/2978/2693 1960/2940/2672 -f 1962/2942/2676 1987/2981/2697 1986/2980/2696 1961/2941/2674 -f 1963/2943/2678 1988/2982/2698 1987/2981/2697 1962/2942/2676 -f 1964/2944/2680 1989/2983/2699 1988/2982/2698 1963/2943/2678 -f 1965/2945/2682 1990/2984/2700 1989/2983/2699 1964/2944/2680 -f 1966/2946/2684 1991/2985/2701 1990/2984/2700 1965/2945/2682 -f 1967/2947/2686 1992/2986/2702 1991/2985/2701 1966/2946/2684 -f 1968/2948/2688 1993/2987/2703 1992/2986/2702 1967/2947/2686 -f 1969/2949/2690 1994/2988/2704 1993/2987/2703 1968/2948/2688 -f 1970/2950/2692 1995/2989/2705 1994/2988/2704 1969/2949/2690 -f 1959/2939/2669 1983/2979/2695 1995/2989/2705 1970/2950/2692 -f 1997/2991/2706 1977/2970/2707 1978/2971/2708 1996/2990/2709 -f 1998/2992/2710 1976/2969/2711 1977/2970/2707 1997/2991/2706 -f 1999/2993/2712 1975/2968/2713 1976/2969/2711 1998/2992/2710 -f 2000/2994/2714 1974/2967/2715 1975/2968/2713 1999/2993/2712 -f 2001/2995/2716 1973/2966/2717 1974/2967/2715 2000/2994/2714 -f 2002/2996/2718 1972/2965/2719 1973/2966/2717 2001/2995/2716 -f 2003/2998/2720 1971/2964/2721 1972/2965/2719 2002/2996/2718 -f 2004/2999/2722 1982/2975/2723 1971/2976/2721 2003/2997/2720 -f 2005/3000/2724 1981/2974/2725 1982/2975/2723 2004/2999/2722 -f 2006/3001/2726 1980/2973/2727 1981/2974/2725 2005/3000/2724 -f 2007/3002/2728 1979/2972/2729 1980/2973/2727 2006/3001/2726 -f 1996/2990/2709 1978/2971/2708 1979/2972/2729 2007/3002/2728 -f 2009/3004/2681 1997/2991/2706 1996/2990/2709 2008/3003/2683 -f 2010/3005/2679 1998/2992/2710 1997/2991/2706 2009/3004/2681 -f 2011/3006/2677 1999/2993/2712 1998/2992/2710 2010/3005/2679 -f 2012/3007/2675 2000/2994/2714 1999/2993/2712 2011/3006/2677 -f 2013/3008/2673 2001/2995/2716 2000/2994/2714 2012/3007/2675 -f 2014/3009/2671 2002/2996/2718 2001/2995/2716 2013/3008/2673 -f 2015/3011/2670 2003/2998/2720 2002/2996/2718 2014/3009/2671 -f 2016/3012/2691 2004/2999/2722 2003/2997/2720 2015/3010/2670 -f 2017/3013/2689 2005/3000/2724 2004/2999/2722 2016/3012/2691 -f 2018/3014/2687 2021/3016/2730 2020/3017/2731 2017/3013/2689 -f 2017/3013/2689 2020/3017/2731 2022/3018/2732 2005/3000/2724 -f 2005/3000/2724 2022/3018/2732 2023/3019/2733 2006/3001/2726 -f 2019/3015/2685 2024/3020/2734 2021/3016/2730 2018/3014/2687 -f 2006/3001/2726 2023/3019/2733 2025/3021/2735 2007/3002/2728 -f 2008/3003/2683 2026/3022/2736 2024/3020/2734 2019/3015/2685 -f 2007/3002/2728 2025/3021/2735 2027/3023/2737 1996/2990/2709 -f 1996/2990/2709 2027/3023/2737 2026/3022/2736 2008/3003/2683 -f 2021/3016/2730 2029/3024/2738 2028/3025/2739 2020/3017/2731 -f 2020/3017/2731 2028/3025/2739 2030/3026/2740 2022/3018/2732 -f 2022/3018/2732 2030/3026/2740 2031/3027/2741 2023/3019/2733 -f 2024/3020/2734 2032/3028/2742 2029/3024/2738 2021/3016/2730 -f 2023/3019/2733 2031/3027/2741 2033/3029/2743 2025/3021/2735 -f 2026/3022/2736 2034/3030/2744 2032/3028/2742 2024/3020/2734 -f 2025/3021/2735 2033/3029/2743 2035/3031/2745 2027/3023/2737 -f 2027/3023/2737 2035/3031/2745 2034/3030/2744 2026/3022/2736 -f 2029/3024/2738 2044/3040/2746 2051/3047/2747 2028/3025/2739 -f 2028/3025/2739 2051/3047/2747 2050/3046/2748 2030/3026/2740 -f 2030/3026/2740 2050/3046/2748 2049/3045/2749 2031/3027/2741 -f 2032/3028/2742 2045/3041/2750 2044/3040/2746 2029/3024/2738 -f 2031/3027/2741 2049/3045/2749 2048/3044/2751 2033/3029/2743 -f 2034/3030/2744 2046/3042/2752 2045/3041/2750 2032/3028/2742 -f 2033/3029/2743 2048/3044/2751 2047/3043/2753 2035/3031/2745 -f 2035/3031/2745 2047/3043/2753 2046/3042/2752 2034/3030/2744 -f 2045/3041/2750 2040/3036/2754 2037/3032/2755 2044/3040/2746 -f 2046/3042/2752 2042/3038/2756 2040/3036/2754 2045/3041/2750 -f 2047/3043/2753 2043/3039/2757 2042/3038/2756 2046/3042/2752 -f 2048/3044/2751 2041/3037/2758 2043/3039/2757 2047/3043/2753 -f 2049/3045/2749 2039/3035/2759 2041/3037/2758 2048/3044/2751 -f 2050/3046/2748 2038/3034/2760 2039/3035/2759 2049/3045/2749 -f 2051/3047/2747 2036/3033/2761 2038/3034/2760 2050/3046/2748 -f 2044/3040/2746 2037/3032/2755 2036/3033/2761 2051/3047/2747 -g default -v 2.351457 0.000000 0.273094 -v 3.153650 0.000000 0.273094 -v 2.351457 0.000000 1.124107 -v 3.153650 0.000000 1.124107 -v 3.153650 2.396303 0.609369 -v 3.153650 1.276799 0.273094 -v 3.153650 2.396303 1.295917 -v 3.153650 1.502001 1.295917 -v 2.351457 2.396303 1.295917 -v 2.351457 1.502001 1.295917 -v 2.351457 2.396303 0.609369 -v 2.351457 1.276799 0.273094 -v 3.153650 2.396303 3.612302 -v 3.153650 1.502001 3.612302 -v 2.351457 1.502001 3.612302 -v 2.351457 2.396303 3.612302 -v 3.153650 1.903183 3.612302 -v 2.351457 1.903183 3.612302 -v 2.351457 1.903183 1.295917 -v 2.351457 1.903183 0.290934 -v 3.153650 1.903183 0.290934 -v 3.153650 1.903183 1.295917 -v 3.153650 1.903183 2.597539 -v 3.153650 2.396303 2.597539 -v 2.351457 2.396303 2.597539 -v 2.351457 1.903183 2.597539 -v 2.351457 1.502001 2.597539 -v 3.153650 1.502001 2.597539 -v 3.153650 1.903183 1.752289 -v 3.153650 2.396303 1.752289 -v 2.351457 2.396303 1.752289 -v 2.351457 1.903183 1.752289 -v 2.351457 1.502001 1.752289 -v 3.153650 1.502001 1.752289 -v 3.889575 1.627074 2.958046 -v 3.889575 1.831190 2.958046 -v 3.889575 1.831190 2.112796 -v 3.889575 1.627074 2.112796 -v 3.001532 0.000000 1.124107 -v 3.001532 1.502001 1.295917 -v 3.001532 1.502001 1.752289 -v 3.001532 1.502001 2.597539 -v 3.001532 1.502001 3.612302 -v 3.001532 1.903183 3.612302 -v 3.001532 2.396303 3.612302 -v 3.001532 2.396303 2.597539 -v 3.001532 2.396303 1.752289 -v 3.001532 2.396303 1.295917 -v 3.001532 2.396303 0.609369 -v 3.001532 1.903183 0.290934 -v 3.001532 1.276799 0.273094 -v 3.001532 0.000000 0.273094 -v 3.153650 2.330825 3.612302 -v 3.001532 2.330825 3.612302 -v 2.351457 2.330825 3.612302 -v 2.351457 2.330825 2.597539 -v 2.351457 2.330825 1.752289 -v 2.351457 2.330825 1.295917 -v 2.351457 2.330825 0.567085 -v 3.001532 2.330825 0.567085 -v 3.153650 2.330825 0.567085 -v 3.153650 2.330825 1.295917 -v 3.153650 2.330825 1.752289 -v 3.153650 2.330825 2.597539 -v 3.153650 1.555844 3.612302 -v 3.001532 1.555844 3.612302 -v 2.351457 1.555844 3.612302 -v 2.351457 1.555844 2.597539 -v 2.351457 1.555844 1.752289 -v 2.351457 1.555844 1.295917 -v 2.351457 1.360878 0.275487 -v 3.001532 1.360878 0.275487 -v 3.153650 1.360878 0.275487 -v 3.153650 1.555844 1.295917 -v 3.153650 1.555844 1.752289 -v 3.889575 1.654467 2.112796 -v 3.889575 1.654467 2.958046 -v 3.153650 1.555844 2.597539 -v 2.744778 1.555844 3.950350 -v 2.744778 1.903183 3.950350 -v 2.351457 1.555844 3.687910 -v 2.351457 1.903183 3.687910 -v 2.744778 2.330825 3.950350 -v 2.351457 2.330825 3.687910 -v 3.153650 -2.396303 0.609369 -v 3.153650 -1.276809 0.273094 -v 3.153650 -2.396303 1.295917 -v 3.153650 -1.502001 1.295917 -v 2.351457 -2.396303 1.295917 -v 2.351457 -1.502001 1.295917 -v 2.351457 -2.396303 0.609369 -v 2.351457 -1.276809 0.273094 -v 3.153650 -2.396303 3.612302 -v 3.153650 -1.502001 3.612302 -v 2.351457 -1.502001 3.612302 -v 2.351457 -2.396303 3.612302 -v 3.153650 -1.903183 3.612302 -v 2.351457 -1.903183 3.612302 -v 2.351457 -1.903183 1.295917 -v 2.351457 -1.903183 0.290934 -v 3.153650 -1.903183 0.290934 -v 3.153650 -1.903183 1.295917 -v 3.153650 -1.903183 2.597539 -v 3.153650 -2.396303 2.597539 -v 2.351457 -2.396303 2.597539 -v 2.351457 -1.903183 2.597539 -v 2.351457 -1.502001 2.597539 -v 3.153650 -1.502001 2.597539 -v 3.153650 -1.903183 1.752289 -v 3.153650 -2.396303 1.752289 -v 2.351457 -2.396303 1.752289 -v 2.351457 -1.903183 1.752289 -v 2.351457 -1.502001 1.752289 -v 3.153650 -1.502001 1.752289 -v 3.889575 -1.627074 2.958046 -v 3.889575 -1.831190 2.958046 -v 3.889575 -1.831190 2.112796 -v 3.889575 -1.627074 2.112796 -v 3.001532 -1.502001 1.295917 -v 3.001532 -1.502001 1.752289 -v 3.001532 -1.502001 2.597539 -v 3.001532 -1.502001 3.612302 -v 3.001532 -1.903183 3.612302 -v 3.001532 -2.396303 3.612302 -v 3.001532 -2.396303 2.597539 -v 3.001532 -2.396303 1.752289 -v 3.001532 -2.396303 1.295917 -v 3.001532 -2.396303 0.609369 -v 3.001532 -1.903183 0.290934 -v 3.001532 -1.276809 0.273094 -v 3.153650 -2.330825 3.612302 -v 3.001532 -2.330825 3.612302 -v 2.351457 -2.330825 3.612302 -v 2.351457 -2.330825 2.597539 -v 2.351457 -2.330825 1.752289 -v 2.351457 -2.330825 1.295917 -v 2.351457 -2.330825 0.567085 -v 3.001532 -2.330825 0.567085 -v 3.153650 -2.330825 0.567085 -v 3.153650 -2.330825 1.295917 -v 3.153650 -2.330825 1.752289 -v 3.153650 -2.330825 2.597539 -v 3.153650 -1.555844 3.612302 -v 3.001532 -1.555844 3.612302 -v 2.351457 -1.555844 3.612302 -v 2.351457 -1.555844 2.597539 -v 2.351457 -1.555844 1.752289 -v 2.351457 -1.555844 1.295917 -v 2.351457 -1.360878 0.275487 -v 3.001532 -1.360878 0.275487 -v 3.153650 -1.360878 0.275487 -v 3.153650 -1.555844 1.295917 -v 3.153650 -1.555844 1.752289 -v 3.889575 -1.654467 2.112796 -v 3.889575 -1.654467 2.958046 -v 3.153650 -1.555844 2.597539 -v 2.744778 -1.555844 3.950350 -v 2.744778 -1.903183 3.950350 -v 2.351457 -1.555844 3.687910 -v 2.351457 -1.903183 3.687910 -v 2.744778 -2.330825 3.950350 -v 2.351457 -2.330825 3.687910 -vt 0.375000 0.000000 -vt 0.625000 0.000000 -vt 0.625000 0.250000 -vt 0.375000 0.250000 -vt 0.375000 0.250000 -vt 0.625000 0.250000 -vt 0.625000 0.500000 -vt 0.375000 0.500000 -vt 0.375000 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.750000 -vt 0.375000 0.750000 -vt 0.625000 1.000000 -vt 0.375000 1.000000 -vt 0.125000 0.000000 -vt 0.125000 0.250000 -vt 0.875000 0.000000 -vt 0.875000 0.000000 -vt 0.625000 0.000000 -vt 0.875000 0.250000 -vt 0.875000 0.250000 -vt 0.625000 0.250000 -vt 0.529128 0.250000 -vt 0.529128 0.500000 -vt 0.529128 0.500000 -vt 0.529128 0.750000 -vt 0.529128 0.000000 -vt 0.529128 1.000000 -vt 0.529128 0.250000 -vt 0.529128 0.250000 -vt 0.375000 0.250000 -vt 0.375000 0.500000 -vt 0.529128 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.250000 -vt 0.529128 0.250000 -vt 0.375000 0.250000 -vt 0.375000 0.500000 -vt 0.529128 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.250000 -vt 0.625000 0.250000 -vt 0.529128 0.250000 -vt 0.529128 0.250000 -vt 0.625000 0.250000 -vt 0.672408 0.250000 -vt 0.625000 0.297408 -vt 0.672408 0.250000 -vt 0.625000 0.297408 -vt 0.625000 0.297408 -vt 0.625000 0.297408 -vt 0.529128 0.297408 -vt 0.375000 0.297408 -vt 0.375000 0.297408 -vt 0.375000 0.297408 -vt 0.327592 0.250000 -vt 0.375000 0.297408 -vt 0.327592 0.000000 -vt 0.375000 0.952592 -vt 0.529128 0.952592 -vt 0.625000 0.952592 -vt 0.672408 0.000000 -vt 0.672408 0.000000 -vt 0.395468 0.250000 -vt 0.395468 0.297408 -vt 0.395468 0.500000 -vt 0.395468 0.500000 -vt 0.395468 0.500000 -vt 0.395468 0.500000 -vt 0.395468 0.750000 -vt 0.395468 0.952592 -vt 0.395468 0.000000 -vt 0.395468 1.000000 -vt 0.395468 0.250000 -vt 0.395468 0.250000 -vt 0.395468 0.250000 -vt 0.612133 0.250000 -vt 0.612133 0.297408 -vt 0.612133 0.500000 -vt 0.612133 0.500000 -vt 0.612133 0.500000 -vt 0.612133 0.500000 -vt 0.612133 0.750000 -vt 0.612133 0.952592 -vt 0.612133 0.000000 -vt 0.612133 1.000000 -vt 0.612133 0.250000 -vt 0.612133 0.250000 -vt 0.612133 0.250000 -vt 0.612133 0.250000 -vt 0.612133 0.250000 -vt 0.529128 0.297408 -vt 0.612133 0.297408 -vt 0.612133 0.500000 -vt 0.529128 0.500000 -vt 0.395468 0.500000 -vt 0.395468 0.297408 -vt 0.375000 0.000000 -vt 0.395468 0.000000 -vt 0.395468 0.250000 -vt 0.375000 0.250000 -vt 0.375000 0.250000 -vt 0.395468 0.250000 -vt 0.395468 0.297408 -vt 0.375000 0.297408 -vt 0.375000 0.500000 -vt 0.395468 0.500000 -vt 0.395468 0.750000 -vt 0.375000 0.750000 -vt 0.375000 0.952592 -vt 0.395468 0.952592 -vt 0.395468 1.000000 -vt 0.375000 1.000000 -vt 0.327592 0.000000 -vt 0.327592 0.250000 -vt 0.625000 0.000000 -vt 0.672408 0.000000 -vt 0.672408 0.000000 -vt 0.625000 0.000000 -vt 0.875000 0.000000 -vt 0.875000 0.250000 -vt 0.875000 0.250000 -vt 0.875000 0.000000 -vt 0.672408 0.250000 -vt 0.625000 0.250000 -vt 0.625000 0.250000 -vt 0.672408 0.250000 -vt 0.395468 0.250000 -vt 0.375000 0.250000 -vt 0.625000 0.297408 -vt 0.625000 0.297408 -vt 0.625000 0.250000 -vt 0.375000 0.500000 -vt 0.395468 0.500000 -vt 0.375000 0.297408 -vt 0.375000 0.297408 -vt 0.529128 0.250000 -vt 0.612133 0.250000 -vt 0.612133 0.297408 -vt 0.529128 0.297408 -vt 0.612133 0.500000 -vt 0.529128 0.500000 -vt 0.529128 0.500000 -vt 0.612133 0.500000 -vt 0.529128 0.750000 -vt 0.612133 0.750000 -vt 0.529128 1.000000 -vt 0.529128 0.952592 -vt 0.612133 0.952592 -vt 0.612133 1.000000 -vt 0.529128 0.250000 -vt 0.529128 0.000000 -vt 0.612133 0.000000 -vt 0.612133 0.250000 -vt 0.612133 0.250000 -vt 0.529128 0.250000 -vt 0.375000 0.250000 -vt 0.395468 0.250000 -vt 0.375000 0.297408 -vt 0.395468 0.500000 -vt 0.375000 0.500000 -vt 0.375000 0.500000 -vt 0.395468 0.500000 -vt 0.612133 0.500000 -vt 0.529128 0.500000 -vt 0.529128 0.500000 -vt 0.612133 0.500000 -vt 0.625000 0.250000 -vt 0.625000 0.297408 -vt 0.625000 0.297408 -vt 0.625000 0.250000 -vt 0.529128 0.250000 -vt 0.612133 0.250000 -vt 0.612133 0.250000 -vt 0.529128 0.250000 -vt 0.529128 0.250000 -vt 0.612133 0.250000 -vt 0.625000 0.250000 -vt 0.625000 0.250000 -vt 0.625000 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.500000 -vt 0.625000 0.500000 -vt 0.529128 0.297408 -vt 0.612133 0.297408 -vt 0.612133 0.500000 -vt 0.529128 0.500000 -vt 0.125000 0.000000 -vt 0.125000 0.250000 -vt 0.395468 0.500000 -vt 0.395468 0.297408 -vt 0.625000 0.750000 -vt 0.625000 0.952592 -vt 0.625000 1.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 -0.000001 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000001 0.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 -0.000001 0.000000 -vn -1.000000 -0.000001 0.000000 -vn 0.000000 0.542491 -0.840062 -vn 0.000000 0.542491 -0.840062 -vn 0.000000 0.542479 -0.840069 -vn 0.000000 0.542479 -0.840070 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 -0.113646 0.993521 -vn 0.000000 -0.113646 0.993521 -vn 0.000000 -0.113646 0.993521 -vn 0.000000 -0.113646 0.993521 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 -0.000000 0.000000 -vn -1.000000 -0.000001 0.000000 -vn -1.000000 -0.000001 0.000000 -vn -1.000000 -0.000000 0.000000 -vn 0.000000 0.287904 -0.957659 -vn 0.000000 0.028470 -0.999595 -vn 0.000000 0.028470 -0.999595 -vn 0.000000 0.287904 -0.957659 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn -0.439921 0.000000 0.898037 -vn -0.439921 0.000000 0.898037 -vn -0.439921 0.000000 0.898036 -vn -0.439921 0.000000 0.898036 -vn 0.097361 0.995249 0.000000 -vn 0.097361 0.995249 0.000000 -vn 0.097361 0.995249 0.000000 -vn 0.097361 0.995249 0.000000 -vn 0.439921 0.000000 -0.898036 -vn 0.439921 0.000000 -0.898036 -vn 0.439921 0.000000 -0.898037 -vn 0.439921 0.000000 -0.898037 -vn 0.167551 -0.985863 0.000000 -vn 0.167551 -0.985863 0.000000 -vn 0.167551 -0.985863 0.000000 -vn 0.167551 -0.985863 0.000000 -vn 0.000000 -0.113646 0.993521 -vn 0.000000 -0.113646 0.993521 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -0.555032 0.000000 0.831829 -vn -0.555032 0.000000 0.831829 -vn -0.555032 0.000000 0.831829 -vn -0.555032 0.000000 0.831829 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 0.542491 -0.840062 -vn 0.000000 0.542479 -0.840070 -vn 0.000000 0.028470 -0.999595 -vn 0.000000 0.287904 -0.957659 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn -0.555032 0.000000 0.831829 -vn -0.555032 0.000000 0.831829 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 -0.000007 0.000000 -vn -1.000000 -0.000007 0.000000 -vn 0.000000 0.028453 -0.999595 -vn 0.000000 0.028453 -0.999595 -vn 0.000000 0.028453 -0.999595 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.439920 0.000000 -0.898037 -vn 0.439920 0.000000 -0.898037 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn -0.439919 0.000000 0.898037 -vn -0.439919 0.000000 0.898037 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.796345 0.000000 0.604842 -vn 0.796345 0.000000 0.604842 -vn 0.796345 0.000000 0.604842 -vn 0.796345 0.000000 0.604842 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.796345 0.000000 0.604842 -vn 0.796345 0.000000 0.604842 -vn 0.796345 0.000000 0.604842 -vn 0.796345 0.000000 0.604842 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000001 0.000000 -vn -1.000000 0.000001 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 -0.542491 -0.840062 -vn 0.000000 -0.542479 -0.840070 -vn 0.000000 -0.542479 -0.840069 -vn 0.000000 -0.542491 -0.840062 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 0.113646 0.993521 -vn 0.000000 0.113646 0.993521 -vn 0.000000 0.113646 0.993521 -vn 0.000000 0.113646 0.993521 -vn 1.000000 -0.000000 0.000000 -vn 1.000000 -0.000000 0.000000 -vn 1.000000 -0.000000 0.000000 -vn 1.000000 -0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 -0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 -0.287904 -0.957659 -vn 0.000000 -0.287904 -0.957659 -vn 0.000000 -0.028470 -0.999595 -vn 0.000000 -0.028470 -0.999595 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn -0.439921 0.000000 0.898037 -vn -0.439921 0.000000 0.898036 -vn -0.439921 0.000000 0.898036 -vn -0.439921 0.000000 0.898037 -vn 0.097361 -0.995249 0.000000 -vn 0.097361 -0.995249 0.000000 -vn 0.097361 -0.995249 0.000000 -vn 0.097361 -0.995249 0.000000 -vn 0.439921 0.000000 -0.898036 -vn 0.439921 0.000000 -0.898037 -vn 0.439921 0.000000 -0.898037 -vn 0.439921 0.000000 -0.898036 -vn 0.167551 0.985863 0.000000 -vn 0.167551 0.985863 0.000000 -vn 0.167551 0.985863 0.000000 -vn 0.167551 0.985863 0.000000 -vn 0.000000 0.113646 0.993521 -vn 0.000000 0.113646 0.993521 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn -0.555032 0.000000 0.831829 -vn -0.555032 0.000000 0.831829 -vn -0.555032 0.000000 0.831829 -vn -0.555032 0.000000 0.831829 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -0.542491 -0.840062 -vn 0.000000 -0.542479 -0.840070 -vn 0.000000 -0.287904 -0.957659 -vn 0.000000 -0.028470 -0.999595 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn -0.555032 0.000000 0.831829 -vn -0.555032 0.000000 0.831829 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000005 0.000000 -vn -1.000000 0.000005 0.000000 -vn 0.000000 -0.028457 -0.999595 -vn 0.000000 -0.028457 -0.999595 -vn 0.000000 -0.028457 -0.999595 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.439919 0.000000 -0.898037 -vn 0.439919 0.000000 -0.898037 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn -0.439919 0.000000 0.898037 -vn -0.439919 0.000000 0.898037 -vn 1.000000 0.000000 0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.796345 0.000000 0.604842 -vn 0.796345 0.000000 0.604842 -vn 0.796345 0.000000 0.604842 -vn 0.796345 0.000000 0.604842 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.796345 0.000000 0.604842 -vn 0.796345 0.000000 0.604842 -vn 0.796345 0.000000 0.604842 -vn 0.796345 0.000000 0.604842 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -s 1 -g fork_geo -usemtl blinn2SG -f 2056/3048/2762 2058/3051/2763 2113/3121/2764 2112/3119/2765 -s 2 -f 2064/3052/2766 2096/3100/2767 2105/3112/2768 2104/3111/2769 -s 3 -f 2060/3056/2770 2062/3059/2771 2110/3117/2772 2109/3116/2773 -s 4 -f 2100/3106/2774 2056/3061/2775 2112/3120/2776 2111/3118/2777 -s 5 -f 2100/3105/2778 2099/3103/2779 2058/3051/2780 2056/3048/2781 -s 6 -f 2057/3049/2782 2053/3066/2783 2103/3110/2784 2102/3109/2785 -s off -f 2063/3064/2786 2052/3065/2787 2054/3068/2788 2061/3067/2789 -s 7 -f 2091/3095/2790 2090/3093/2791 2055/3069/2792 2059/3050/2793 -s off -f 2059/3050/2794 2055/3069/2795 2053/3066/2796 2057/3049/2797 -s 8 -f 2058/3051/2798 2081/3084/2799 2114/3122/2800 2113/3121/2801 -s 9 -f 2059/3050/2802 2085/3088/2803 2092/3096/2804 2091/3094/2805 -s 10 -f 2109/3116/2806 2108/3115/2807 2082/3085/2808 2060/3056/2809 -s 11 -f 2099/3104/2810 2098/3102/2811 2081/3084/2812 2058/3051/2813 -s 2 -f 2068/3070/2814 2095/3099/2815 2117/3125/2816 2116/3124/2817 -s 10 -f 2121/3129/2818 2120/3128/2819 2083/3086/2820 2070/3072/2821 -s 3 -f 2071/3073/2822 2122/3130/2823 2121/3129/2824 2070/3072/2825 -s 4 -f 2072/3075/2826 2124/3133/2827 2123/3131/2828 2101/3107/2829 -s 1 -f 2073/3076/2830 2125/3134/2831 2124/3132/2832 2072/3074/2833 -s 8 -f 2126/3135/2834 2125/3134/2835 2073/3076/2836 2080/3083/2837 -f 2075/3078/2838 2064/3052/2839 2104/3111/2840 2115/3123/2841 -s 11 -f 2097/3101/2842 2096/3100/2843 2064/3052/2844 2075/3078/2845 -s 10 -f 2107/3114/2846 2106/3113/2847 2067/3055/2848 2076/3079/2849 -f 2119/3127/2850 2118/3126/2851 2069/3071/2852 2077/3080/2853 -s 9 -f 2079/3082/2854 2065/3053/2855 2094/3098/2856 2093/3097/2857 -s 8 -f 2068/3070/2858 2116/3124/2859 2129/3138/2860 2074/3077/2861 -f 2081/3084/2799 2075/3078/2838 2115/3123/2841 2114/3122/2800 -s 11 -f 2098/3102/2811 2097/3101/2842 2075/3078/2845 2081/3084/2812 -s 10 -f 2108/3115/2807 2107/3114/2846 2076/3079/2849 2082/3085/2808 -f 2120/3128/2819 2119/3127/2850 2077/3080/2853 2083/3086/2820 -s 9 -f 2085/3088/2803 2079/3082/2854 2093/3097/2857 2092/3096/2804 -s 23 -f 2128/3137/2862 2127/3136/2863 2088/3091/2864 2087/3090/2865 -s 24 -f 2129/3138/2866 2128/3137/2867 2087/3090/2868 2074/3077/2869 -s off -f 2074/3077/2870 2087/3090/2871 2088/3091/2872 2080/3083/2873 -s 25 -f 2080/3083/2874 2088/3091/2875 2127/3136/2876 2126/3135/2877 -s off -f 2085/3088/2878 2089/3092/2879 2086/3089/2880 2079/3082/2881 -s 7 -f 2061/3067/2882 2054/3068/2883 2090/3093/2791 2091/3095/2790 -s 9 -f 2092/3096/2804 2084/3087/2884 2061/3057/2885 2091/3094/2805 -f 2093/3097/2857 2078/3081/2886 2084/3087/2884 2092/3096/2804 -f 2094/3098/2856 2066/3054/2887 2078/3081/2886 2093/3097/2857 -s 26 -f 2131/3139/2888 2133/3142/2889 2132/3141/2890 2130/3140/2891 -s 2 -f 2096/3100/2767 2067/3055/2892 2106/3113/2893 2105/3112/2768 -s 11 -f 2076/3079/2894 2067/3055/2895 2096/3100/2843 2097/3101/2842 -f 2082/3085/2896 2076/3079/2894 2097/3101/2842 2098/3102/2811 -f 2060/3056/2897 2082/3085/2896 2098/3102/2811 2099/3104/2810 -s 5 -f 2062/3062/2898 2060/3063/2899 2099/3103/2779 2100/3105/2778 -s 4 -f 2062/3059/2900 2100/3106/2774 2111/3118/2777 2110/3117/2901 -f 2123/3131/2828 2122/3130/2902 2071/3073/2903 2101/3107/2829 -s 6 -f 2103/3110/2784 2052/3065/2904 2063/3064/2905 2102/3109/2785 -s 2 -f 2104/3111/2769 2105/3112/2768 2095/3099/2815 2068/3070/2814 -s 26 -f 2135/3143/2906 2133/3142/2889 2131/3139/2888 2134/3144/2907 -s 10 -f 2077/3080/2853 2069/3071/2852 2106/3113/2847 2107/3114/2846 -f 2083/3086/2820 2077/3080/2853 2107/3114/2846 2108/3115/2807 -f 2070/3072/2821 2083/3086/2820 2108/3115/2807 2109/3116/2806 -s 3 -f 2110/3117/2772 2071/3073/2822 2070/3072/2825 2109/3116/2773 -s 4 -f 2111/3118/2777 2101/3107/2829 2071/3073/2903 2110/3117/2901 -f 2112/3120/2776 2072/3075/2826 2101/3107/2829 2111/3118/2777 -s 1 -f 2113/3121/2764 2073/3076/2830 2072/3074/2833 2112/3119/2765 -s 8 -f 2114/3122/2800 2080/3083/2837 2073/3076/2836 2113/3121/2801 -f 2115/3123/2841 2074/3077/2861 2080/3083/2837 2114/3122/2800 -f 2104/3111/2840 2068/3070/2858 2074/3077/2861 2115/3123/2841 -s 2 -f 2116/3124/2817 2117/3125/2816 2094/3098/2908 2065/3053/2909 -f 2118/3126/2910 2066/3054/2911 2094/3098/2908 2117/3125/2816 -s 10 -f 2078/3081/2912 2066/3054/2913 2118/3126/2851 2119/3127/2850 -f 2084/3087/2914 2078/3081/2912 2119/3127/2850 2120/3128/2819 -f 2061/3057/2915 2084/3087/2914 2120/3128/2819 2121/3129/2818 -s 3 -f 2122/3130/2823 2063/3058/2916 2061/3057/2917 2121/3129/2824 -s 4 -f 2102/3108/2918 2063/3058/2919 2122/3130/2902 2123/3131/2828 -f 2124/3133/2827 2057/3060/2920 2102/3108/2918 2123/3131/2828 -s 1 -f 2125/3134/2831 2059/3050/2921 2057/3049/2922 2124/3132/2832 -s 8 -f 2085/3088/2923 2059/3050/2924 2125/3134/2835 2126/3135/2834 -s 25 -f 2127/3136/2876 2089/3092/2925 2085/3088/2926 2126/3135/2877 -s 23 -f 2086/3089/2927 2089/3092/2928 2127/3136/2863 2128/3137/2862 -s 24 -f 2079/3082/2929 2086/3089/2930 2128/3137/2867 2129/3138/2866 -s 8 -f 2116/3124/2859 2065/3053/2931 2079/3082/2932 2129/3138/2860 -s off -f 2095/3099/2933 2131/3139/2934 2130/3140/2935 2117/3125/2936 -f 2117/3125/2937 2130/3140/2938 2132/3141/2939 2118/3126/2940 -f 2118/3126/2941 2132/3141/2942 2133/3142/2943 2069/3071/2944 -f 2106/3113/2945 2135/3143/2946 2134/3144/2947 2105/3112/2948 -f 2105/3112/2949 2134/3144/2950 2131/3139/2951 2095/3099/2952 -f 2069/3071/2953 2133/3142/2954 2135/3143/2955 2106/3113/2956 -s 27 -f 2136/3145/2957 2190/3146/2958 2191/3147/2959 2138/3148/2960 -s 28 -f 2144/3149/2961 2182/3150/2962 2183/3151/2963 2175/3152/2964 -s 29 -f 2140/3153/2965 2187/3154/2966 2188/3155/2967 2142/3156/2968 -s 30 -f 2179/3157/2969 2189/3158/2970 2190/3159/2971 2136/3160/2972 -s 31 -f 2179/3161/2973 2136/3145/2974 2138/3148/2975 2178/3162/2976 -s 32 -f 2137/3163/2977 2181/3164/2978 2103/3165/2979 2053/3166/2980 -s off -f 2143/3167/2981 2141/3168/2982 2054/3169/2983 2052/3170/2984 -s 33 -f 2170/3171/2985 2139/3172/2986 2055/3173/2987 2090/3174/2988 -s off -f 2139/3172/2989 2137/3163/2990 2053/3166/2991 2055/3173/2992 -s 34 -f 2138/3148/2993 2191/3147/2994 2192/3175/2995 2161/3176/2996 -s 35 -f 2139/3172/2997 2170/3177/2998 2171/3178/2999 2165/3179/3000 -s 36 -f 2187/3154/3001 2140/3153/3002 2162/3180/3003 2186/3181/3004 -s 37 -f 2178/3182/3005 2138/3148/3006 2161/3176/3007 2177/3183/3008 -s 28 -f 2148/3184/3009 2194/3185/3010 2195/3186/3011 2174/3187/3012 -s 36 -f 2199/3188/3013 2150/3189/3014 2163/3190/3015 2198/3191/3016 -s 29 -f 2151/3192/3017 2150/3189/3018 2199/3188/3019 2200/3193/3020 -s 30 -f 2152/3194/3021 2180/3195/3022 2201/3196/3023 2202/3197/3024 -s 27 -f 2153/3198/3025 2152/3199/3026 2202/3200/3027 2203/3201/3028 -s 34 -f 2204/3202/3029 2160/3203/3030 2153/3198/3031 2203/3201/3032 -f 2155/3204/3033 2193/3205/3034 2182/3150/3035 2144/3149/3036 -s 37 -f 2176/3206/3037 2155/3204/3038 2144/3149/3039 2175/3152/3040 -s 36 -f 2185/3207/3041 2156/3208/3042 2147/3209/3043 2184/3210/3044 -f 2197/3211/3045 2157/3212/3046 2149/3213/3047 2196/3214/3048 -s 35 -f 2159/3215/3049 2172/3216/3050 2173/3217/3051 2145/3218/3052 -s 34 -f 2148/3184/3053 2154/3219/3054 2207/3220/3055 2194/3185/3056 -f 2161/3176/2996 2192/3175/2995 2193/3205/3034 2155/3204/3033 -s 37 -f 2177/3183/3008 2161/3176/3007 2155/3204/3038 2176/3206/3037 -s 36 -f 2186/3181/3004 2162/3180/3003 2156/3208/3042 2185/3207/3041 -f 2198/3191/3016 2163/3190/3015 2157/3212/3046 2197/3211/3045 -s 35 -f 2165/3179/3000 2171/3178/2999 2172/3216/3050 2159/3215/3049 -s 39 -f 2206/3221/3057 2167/3222/3058 2168/3223/3059 2205/3224/3060 -s 40 -f 2207/3220/3061 2154/3219/3062 2167/3222/3063 2206/3221/3064 -s off -f 2154/3219/3065 2160/3203/3066 2168/3223/3067 2167/3222/3068 -s 41 -f 2160/3203/3069 2204/3202/3070 2205/3224/3071 2168/3223/3072 -s off -f 2165/3179/3073 2159/3215/3074 2166/3225/3075 2169/3226/3076 -s 33 -f 2141/3168/3077 2170/3171/2985 2090/3174/2988 2054/3169/3078 -s 35 -f 2171/3178/2999 2170/3177/2998 2141/3227/3079 2164/3228/3080 -f 2172/3216/3050 2171/3178/2999 2164/3228/3080 2158/3229/3081 -f 2173/3217/3051 2172/3216/3050 2158/3229/3081 2146/3230/3082 -s 42 -f 2209/3231/3083 2208/3232/3084 2210/3233/3085 2211/3234/3086 -s 28 -f 2175/3152/2964 2183/3151/2963 2184/3210/3087 2147/3209/3088 -s 37 -f 2156/3208/3089 2176/3206/3037 2175/3152/3040 2147/3209/3090 -f 2162/3180/3091 2177/3183/3008 2176/3206/3037 2156/3208/3089 -f 2140/3153/3092 2178/3182/3005 2177/3183/3008 2162/3180/3091 -s 31 -f 2142/3235/3093 2179/3161/2973 2178/3162/2976 2140/3236/3094 -s 30 -f 2142/3156/3095 2188/3155/3096 2189/3158/2970 2179/3157/2969 -f 2201/3196/3023 2180/3195/3022 2151/3192/3097 2200/3193/3098 -s 32 -f 2103/3165/2979 2181/3164/2978 2143/3167/3099 2052/3170/3100 -s 28 -f 2182/3150/2962 2148/3184/3009 2174/3187/3012 2183/3151/2963 -s 42 -f 2213/3237/3101 2212/3238/3102 2209/3231/3083 2211/3234/3086 -s 36 -f 2157/3212/3046 2185/3207/3041 2184/3210/3044 2149/3213/3047 -f 2163/3190/3015 2186/3181/3004 2185/3207/3041 2157/3212/3046 -f 2150/3189/3014 2187/3154/3001 2186/3181/3004 2163/3190/3015 -s 29 -f 2188/3155/2967 2187/3154/2966 2150/3189/3018 2151/3192/3017 -s 30 -f 2189/3158/2970 2188/3155/3096 2151/3192/3097 2180/3195/3022 -f 2190/3159/2971 2189/3158/2970 2180/3195/3022 2152/3194/3021 -s 27 -f 2191/3147/2959 2190/3146/2958 2152/3199/3026 2153/3198/3025 -s 34 -f 2192/3175/2995 2191/3147/2994 2153/3198/3031 2160/3203/3030 -f 2193/3205/3034 2192/3175/2995 2160/3203/3030 2154/3219/3054 -f 2182/3150/3035 2193/3205/3034 2154/3219/3054 2148/3184/3053 -s 28 -f 2194/3185/3010 2145/3218/3103 2173/3217/3104 2195/3186/3011 -f 2196/3214/3105 2195/3186/3011 2173/3217/3104 2146/3230/3106 -s 36 -f 2158/3229/3107 2197/3211/3045 2196/3214/3048 2146/3230/3108 -f 2164/3228/3109 2198/3191/3016 2197/3211/3045 2158/3229/3107 -f 2141/3227/3110 2199/3188/3013 2198/3191/3016 2164/3228/3109 -s 29 -f 2200/3193/3020 2199/3188/3019 2141/3227/3111 2143/3239/3112 -s 30 -f 2181/3240/3113 2201/3196/3023 2200/3193/3098 2143/3239/3114 -f 2202/3197/3024 2201/3196/3023 2181/3240/3113 2137/3241/3115 -s 27 -f 2203/3201/3028 2202/3200/3027 2137/3163/3116 2139/3172/3117 -s 34 -f 2165/3179/3118 2204/3202/3029 2203/3201/3032 2139/3172/3119 -s 41 -f 2205/3224/3071 2204/3202/3070 2165/3179/3120 2169/3226/3121 -s 39 -f 2166/3225/3122 2206/3221/3057 2205/3224/3060 2169/3226/3123 -s 40 -f 2159/3215/3124 2207/3220/3061 2206/3221/3064 2166/3225/3125 -s 34 -f 2194/3185/3056 2207/3220/3055 2159/3215/3126 2145/3218/3127 -s off -f 2174/3187/3128 2195/3186/3129 2208/3232/3130 2209/3231/3131 -f 2195/3186/3132 2196/3214/3133 2210/3233/3134 2208/3232/3135 -f 2196/3214/3136 2149/3213/3137 2211/3234/3138 2210/3233/3139 -f 2184/3210/3140 2183/3151/3141 2212/3238/3142 2213/3237/3143 -f 2183/3151/3144 2174/3187/3145 2209/3231/3146 2212/3238/3147 -f 2149/3213/3148 2184/3210/3149 2213/3237/3150 2211/3234/3151 -g default -v -0.615337 2.784926 0.346995 -v -0.615337 1.617523 0.346995 -v -0.891418 2.784926 2.387670 -v -0.891418 1.617523 2.387670 -v -3.706954 2.784926 1.940161 -v -3.706954 1.617523 1.940161 -v -3.749398 2.784926 0.346995 -v -3.749398 1.617523 0.346995 -v -1.162735 2.784926 1.334254 -v -3.380559 2.784926 1.222088 -v -3.380559 1.617523 1.222088 -v -1.286063 1.617523 1.334254 -v -0.942665 2.784926 0.779819 -v -3.447443 2.784926 0.659830 -v -3.447443 1.617523 0.659830 -v -0.942665 1.617523 0.779819 -v -1.148753 2.784926 1.867356 -v -3.516576 2.784926 1.678854 -v -3.516576 1.617523 1.678854 -v -1.148753 1.617523 1.867356 -vt 0.375000 0.000000 -vt 0.625000 0.000000 -vt 0.375000 0.250000 -vt 0.625000 0.250000 -vt 0.375000 0.500000 -vt 0.625000 0.500000 -vt 0.375000 0.750000 -vt 0.625000 0.750000 -vt 0.375000 1.000000 -vt 0.625000 1.000000 -vt 0.875000 0.000000 -vt 0.875000 0.250000 -vt 0.125000 0.000000 -vt 0.125000 0.250000 -vt 0.375000 0.153497 -vt 0.125000 0.153497 -vt 0.375000 0.596503 -vt 0.625000 0.596503 -vt 0.875000 0.153497 -vt 0.625000 0.153497 -vt 0.375000 0.067294 -vt 0.125000 0.054873 -vt 0.375000 0.695127 -vt 0.625000 0.695127 -vt 0.875000 0.054873 -vt 0.625000 0.067294 -vt 0.375000 0.202335 -vt 0.125000 0.224042 -vt 0.375000 0.525958 -vt 0.625000 0.525958 -vt 0.875000 0.224042 -vt 0.625000 0.202335 -vn 0.797597 0.000000 0.603191 -vn 0.850803 -0.025238 0.524879 -vn 0.850803 -0.025238 0.524879 -vn 0.797597 0.000000 0.603191 -vn -0.156972 0.000000 0.987603 -vn -0.156972 0.000000 0.987603 -vn -0.156972 0.000000 0.987603 -vn -0.156972 0.000000 0.987603 -vn -0.921493 0.000000 0.388396 -vn -0.719508 0.000000 0.694484 -vn -0.719508 0.000000 0.694484 -vn -0.921493 0.000000 0.388396 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn -0.910368 0.000000 -0.413801 -vn -0.997707 0.000000 -0.067687 -vn -0.997707 0.000000 -0.067687 -vn -0.910368 0.000000 -0.413801 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.980531 -0.051793 0.189414 -vn 0.953189 -0.025480 -0.301300 -vn 0.953189 -0.025480 -0.301300 -vn 0.981744 -0.051857 0.183002 -vn 0.000000 1.000000 -0.000001 -vn 0.000000 1.000000 -0.000001 -vn -0.808241 0.000000 -0.588852 -vn -0.808241 0.000000 -0.588852 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.896363 0.000000 -0.443321 -vn 0.896363 0.000000 -0.443321 -s 1 -g trackBase_L_geo -usemtl blinn4SG -f 2214/3242/3152 2226/3262/3153 2229/3267/3154 2215/3243/3155 -s off -f 2218/3246/3156 2219/3247/3157 2217/3245/3158 2216/3244/3159 -s 2 -f 2227/3264/3160 2220/3248/3161 2221/3249/3162 2228/3265/3163 -s off -f 2215/3251/3164 2221/3249/3165 2220/3248/3166 2214/3250/3167 -s 3 -f 2229/3267/3168 2228/3266/3169 2221/3252/3170 2215/3243/3171 -s 4 -f 2214/3242/3172 2220/3254/3173 2227/3263/3174 2226/3262/3175 -f 2222/3256/3176 2223/3257/3177 2231/3269/3178 2230/3268/3179 -s 2 -f 2231/3270/3180 2223/3258/3181 2224/3259/3182 2232/3271/3183 -s 3 -f 2233/3273/3184 2232/3272/3185 2224/3260/3186 2225/3261/3187 -s 1 -f 2222/3256/3188 2230/3268/3189 2233/3273/3190 2225/3261/3191 -s 4 -f 2226/3262/3175 2227/3263/3174 2223/3257/3177 2222/3256/3176 -s 2 -f 2223/3258/3181 2227/3264/3160 2228/3265/3163 2224/3259/3182 -s 3 -f 2225/3261/3187 2224/3260/3186 2228/3266/3169 2229/3267/3168 -s 1 -f 2226/3262/3153 2222/3256/3188 2225/3261/3191 2229/3267/3154 -s 4 -f 2230/3268/3179 2231/3269/3178 2218/3255/3192 2216/3244/3193 -s 2 -f 2218/3246/3194 2231/3270/3180 2232/3271/3183 2219/3247/3195 -s 3 -f 2217/3245/3196 2219/3253/3197 2232/3272/3185 2233/3273/3184 -s 1 -f 2230/3268/3189 2216/3244/3198 2217/3245/3199 2233/3273/3190 -g default -v -0.362284 -1.617529 2.545371 -v -0.843255 -1.617529 2.064394 -v -1.019304 -1.617529 1.407370 -v -0.843255 -1.617529 0.750351 -v -0.362284 -1.617529 0.269376 -v 0.294744 -1.617529 0.093327 -v 0.951768 -1.617529 0.269376 -v 1.432745 -1.617529 0.750351 -v 1.608791 -1.617529 1.407370 -v 1.432745 -1.617529 2.064394 -v 0.951768 -1.617529 2.545371 -v 0.294744 -1.617529 2.721417 -v -0.362284 -2.784919 2.545371 -v -0.843255 -2.784919 2.064394 -v -1.019304 -2.784919 1.407370 -v -0.843255 -2.784919 0.750351 -v -0.362284 -2.784919 0.269376 -v 0.294744 -2.784919 0.093327 -v 0.951768 -2.784919 0.269376 -v 1.432745 -2.784919 0.750351 -v 1.608791 -2.784919 1.407370 -v 1.432745 -2.784919 2.064394 -v 0.951768 -2.784919 2.545371 -v 0.294744 -2.784919 2.721417 -v 0.294744 -1.617529 1.407370 -v -0.342702 -2.784919 2.511453 -v -0.809337 -2.784919 2.044811 -v -0.980139 -2.784919 1.407370 -v -0.809337 -2.784919 0.769933 -v -0.342702 -2.784919 0.303293 -v 0.294744 -2.784919 0.132492 -v 0.932185 -2.784919 0.303293 -v 1.398827 -2.784919 0.769933 -v 1.569626 -2.784919 1.407370 -v 1.398827 -2.784919 2.044811 -v 0.932185 -2.784919 2.511453 -v 0.294744 -2.784919 2.682252 -v -0.109886 -2.784919 2.108206 -v -0.337770 -2.784919 1.882901 -v 0.294744 -2.784919 1.407371 -v -0.512943 -2.784919 1.361995 -v -0.406091 -2.784919 1.002747 -v -0.109886 -2.784919 0.706539 -v 0.230375 -2.784919 0.601543 -v 0.750016 -2.784919 0.754042 -v 0.995579 -2.784919 1.002747 -v 1.103997 -2.784919 1.407371 -v 1.055995 -2.784919 1.734248 -v 0.645042 -2.784919 2.151772 -v 0.294744 -2.784919 2.216624 -v -0.809337 -2.559730 2.044811 -v -0.980139 -2.559730 1.407370 -v -0.512943 -2.559730 1.361995 -v -0.337770 -2.559730 1.882901 -v 0.294744 -2.559730 0.132492 -v 0.932185 -2.559730 0.303293 -v 0.750016 -2.559730 0.754042 -v 0.230375 -2.559730 0.601543 -v 1.398827 -2.559730 2.044811 -v 0.932185 -2.559730 2.511453 -v 0.645042 -2.559730 2.151772 -v 1.055995 -2.559730 1.734248 -vt 0.635316 0.078125 -vt 0.578125 0.020934 -vt 0.500000 0.000000 -vt 0.421875 0.020934 -vt 0.364684 0.078125 -vt 0.343750 0.156250 -vt 0.364684 0.234375 -vt 0.421875 0.291566 -vt 0.500000 0.312500 -vt 0.578125 0.291566 -vt 0.635316 0.234375 -vt 0.656250 0.156250 -vt 0.375000 0.312500 -vt 0.395833 0.312500 -vt 0.416667 0.312500 -vt 0.437500 0.312500 -vt 0.458333 0.312500 -vt 0.479167 0.312500 -vt 0.500000 0.312500 -vt 0.520833 0.312500 -vt 0.541667 0.312500 -vt 0.562500 0.312500 -vt 0.583333 0.312500 -vt 0.604167 0.312500 -vt 0.625000 0.312500 -vt 0.375000 0.688440 -vt 0.395833 0.688440 -vt 0.416667 0.688440 -vt 0.437500 0.688440 -vt 0.458333 0.688440 -vt 0.479167 0.688440 -vt 0.500000 0.688440 -vt 0.520833 0.688440 -vt 0.541667 0.688440 -vt 0.562500 0.688440 -vt 0.583333 0.688440 -vt 0.604167 0.688440 -vt 0.625000 0.688440 -vt 0.635316 0.765625 -vt 0.578125 0.708434 -vt 0.500000 0.687500 -vt 0.421875 0.708434 -vt 0.364684 0.765625 -vt 0.343750 0.843750 -vt 0.364684 0.921875 -vt 0.421875 0.979066 -vt 0.500000 1.000000 -vt 0.578125 0.979066 -vt 0.635316 0.921875 -vt 0.656250 0.843750 -vt 0.500000 0.150000 -vt 0.500000 0.837500 -vt 0.635316 0.921875 -vt 0.578125 0.979066 -vt 0.500000 1.000000 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.343750 0.843750 -vt 0.364684 0.765625 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.578125 0.708434 -vt 0.635316 0.765625 -vt 0.656250 0.843750 -vt 0.635316 0.921875 -vt 0.578125 0.979066 -vt 0.500000 1.000000 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.343750 0.843750 -vt 0.364684 0.765625 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.578125 0.708434 -vt 0.635316 0.765625 -vt 0.656250 0.843750 -vt 0.578125 0.979066 -vt 0.500000 1.000000 -vt 0.500000 1.000000 -vt 0.578125 0.979066 -vt 0.343750 0.843750 -vt 0.364684 0.765625 -vt 0.364684 0.765625 -vt 0.343750 0.843750 -vt 0.578125 0.708434 -vt 0.635316 0.765625 -vt 0.635316 0.765625 -vt 0.578125 0.708434 -vn -0.707112 0.000000 0.707102 -vn -0.707112 0.000000 0.707102 -vn -0.707112 0.000000 0.707102 -vn -0.707112 0.000000 0.707102 -vn -0.965926 0.000000 0.258820 -vn -0.965926 0.000000 0.258820 -vn -0.965926 0.000000 0.258820 -vn -0.965926 0.000000 0.258820 -vn -0.965925 0.000000 -0.258821 -vn -0.965925 0.000000 -0.258821 -vn -0.965925 0.000000 -0.258821 -vn -0.965925 0.000000 -0.258821 -vn -0.707110 0.000000 -0.707103 -vn -0.707110 0.000000 -0.707103 -vn -0.707110 0.000000 -0.707103 -vn -0.707110 0.000000 -0.707103 -vn -0.258817 0.000000 -0.965927 -vn -0.258817 0.000000 -0.965927 -vn -0.258817 0.000000 -0.965927 -vn -0.258817 0.000000 -0.965927 -vn 0.258818 0.000000 -0.965926 -vn 0.258818 0.000000 -0.965926 -vn 0.258818 0.000000 -0.965926 -vn 0.258818 0.000000 -0.965926 -vn 0.707105 0.000000 -0.707109 -vn 0.707105 0.000000 -0.707109 -vn 0.707105 0.000000 -0.707109 -vn 0.707105 0.000000 -0.707109 -vn 0.965927 0.000000 -0.258817 -vn 0.965927 0.000000 -0.258817 -vn 0.965927 0.000000 -0.258817 -vn 0.965927 0.000000 -0.258817 -vn 0.965927 0.000000 0.258815 -vn 0.965927 0.000000 0.258815 -vn 0.965927 0.000000 0.258815 -vn 0.965927 0.000000 0.258815 -vn 0.707107 0.000000 0.707107 -vn 0.707107 0.000000 0.707107 -vn 0.707107 0.000000 0.707107 -vn 0.707107 0.000000 0.707107 -vn 0.258815 0.000000 0.965927 -vn 0.258815 0.000000 0.965927 -vn 0.258815 0.000000 0.965927 -vn 0.258815 0.000000 0.965927 -vn -0.258813 0.000000 0.965927 -vn -0.258813 0.000000 0.965927 -vn -0.258813 0.000000 0.965927 -vn -0.258813 0.000000 0.965927 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000002 -vn 0.000000 -1.000000 0.000002 -vn 0.000000 -1.000000 0.000002 -vn 0.000000 -1.000000 0.000002 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000003 -vn 0.000000 -1.000000 -0.000003 -vn 0.000000 -1.000000 -0.000003 -vn 0.000000 -1.000000 -0.000003 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000003 -vn 0.000000 -1.000000 0.000003 -vn 0.000000 -1.000000 0.000003 -vn 0.000000 -1.000000 0.000003 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000006 -vn 0.000000 -1.000000 -0.000006 -vn 0.000000 -1.000000 -0.000006 -vn 0.000000 -1.000000 -0.000006 -vn 0.000000 -1.000000 -0.000002 -vn 0.000000 -1.000000 -0.000002 -vn 0.000000 -1.000000 -0.000002 -vn 0.000000 -1.000000 -0.000002 -vn 0.000000 -1.000000 0.000005 -vn 0.000000 -1.000000 0.000005 -vn 0.000000 -1.000000 0.000005 -vn 0.000000 -1.000000 0.000005 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.965926 0.000000 -0.258820 -vn 0.965926 0.000000 -0.258820 -vn 0.965926 0.000000 -0.258820 -vn 0.965926 0.000000 -0.258820 -vn 0.096666 0.000000 0.995317 -vn 0.096666 0.000000 0.995317 -vn 0.096666 0.000000 0.995317 -vn 0.096666 0.000000 0.995317 -vn -0.947841 0.000000 0.318745 -vn -0.947841 0.000000 0.318745 -vn -0.947841 0.000000 0.318745 -vn -0.947841 0.000000 0.318745 -vn -0.324738 0.000000 -0.945804 -vn -0.324738 0.000000 -0.945804 -vn -0.324738 0.000000 -0.945804 -vn -0.324738 0.000000 -0.945804 -vn -0.258818 0.000000 0.965926 -vn -0.258818 0.000000 0.965926 -vn -0.258818 0.000000 0.965926 -vn -0.258818 0.000000 0.965926 -vn -0.927145 0.000000 -0.374704 -vn -0.927145 0.000000 -0.374704 -vn -0.927145 0.000000 -0.374704 -vn -0.927145 0.000000 -0.374704 -vn 0.281594 0.000000 -0.959534 -vn 0.281594 0.000000 -0.959534 -vn 0.281594 0.000000 -0.959534 -vn 0.281594 0.000000 -0.959534 -vn 0.990715 0.000000 0.135957 -vn 0.990715 0.000000 0.135957 -vn 0.990715 0.000000 0.135957 -vn 0.990715 0.000000 0.135957 -vn -0.707107 0.000000 -0.707107 -vn -0.707107 0.000000 -0.707107 -vn -0.707107 0.000000 -0.707107 -vn -0.707107 0.000000 -0.707107 -vn 0.781506 0.000000 -0.623898 -vn 0.781506 0.000000 -0.623898 -vn 0.781506 0.000000 -0.623898 -vn 0.781506 0.000000 -0.623898 -vn 0.712693 0.000000 0.701476 -vn 0.712693 0.000000 0.701476 -vn 0.712693 0.000000 0.701476 -vn 0.712693 0.000000 0.701476 -vn -0.671367 0.000000 0.741125 -vn -0.671367 0.000000 0.741125 -vn -0.671367 0.000000 0.741125 -vn -0.671367 0.000000 0.741125 -s off -g wheel_FR_geo -usemtl blinn2SG -f 2234/3286/3200 2235/3287/3201 2247/3300/3202 2246/3299/3203 -f 2235/3287/3204 2236/3288/3205 2248/3301/3206 2247/3300/3207 -f 2236/3288/3208 2237/3289/3209 2249/3302/3210 2248/3301/3211 -f 2237/3289/3212 2238/3290/3213 2250/3303/3214 2249/3302/3215 -f 2238/3290/3216 2239/3291/3217 2251/3304/3218 2250/3303/3219 -f 2239/3291/3220 2240/3292/3221 2252/3305/3222 2251/3304/3223 -f 2240/3292/3224 2241/3293/3225 2253/3306/3226 2252/3305/3227 -f 2241/3293/3228 2242/3294/3229 2254/3307/3230 2253/3306/3231 -f 2242/3294/3232 2243/3295/3233 2255/3308/3234 2254/3307/3235 -f 2243/3295/3236 2244/3296/3237 2256/3309/3238 2255/3308/3239 -f 2244/3296/3240 2245/3297/3241 2257/3310/3242 2256/3309/3243 -f 2245/3297/3244 2234/3298/3245 2246/3311/3246 2257/3310/3247 -s 1 -f 2235/3275/3248 2234/3274/3249 2258/3324/3250 -f 2236/3276/3251 2235/3275/3248 2258/3324/3250 -f 2237/3277/3252 2236/3276/3251 2258/3324/3250 -f 2238/3278/3253 2237/3277/3252 2258/3324/3250 -f 2239/3279/3254 2238/3278/3253 2258/3324/3250 -f 2240/3280/3255 2239/3279/3254 2258/3324/3250 -f 2241/3281/3256 2240/3280/3255 2258/3324/3250 -f 2242/3282/3257 2241/3281/3256 2258/3324/3250 -f 2243/3283/3258 2242/3282/3257 2258/3324/3250 -f 2244/3284/3259 2243/3283/3258 2258/3324/3250 -f 2245/3285/3260 2244/3284/3259 2258/3324/3250 -f 2234/3274/3249 2245/3285/3260 2258/3324/3250 -s 2 -f 2271/3338/3261 2272/3339/3262 2273/3325/3263 -f 2272/3339/3262 2274/3340/3264 2273/3325/3263 -f 2274/3340/3264 2275/3341/3265 2273/3325/3263 -f 2275/3341/3265 2276/3342/3266 2273/3325/3263 -f 2276/3342/3266 2277/3343/3267 2273/3325/3263 -f 2277/3343/3267 2278/3344/3268 2273/3325/3263 -f 2278/3344/3268 2279/3345/3269 2273/3325/3263 -f 2279/3345/3269 2280/3346/3270 2273/3325/3263 -f 2280/3346/3270 2281/3347/3271 2273/3325/3263 -f 2281/3347/3271 2282/3348/3272 2273/3325/3263 -f 2282/3348/3272 2283/3349/3273 2273/3325/3263 -f 2283/3349/3273 2271/3338/3261 2273/3325/3263 -s off -f 2246/3322/3274 2247/3321/3275 2260/3327/3276 2259/3326/3277 -f 2247/3321/3278 2248/3320/3279 2261/3328/3280 2260/3327/3281 -f 2248/3320/3282 2249/3319/3283 2262/3329/3284 2261/3328/3285 -f 2249/3319/3286 2250/3318/3287 2263/3330/3288 2262/3329/3289 -f 2250/3318/3290 2251/3317/3291 2264/3331/3292 2263/3330/3293 -f 2251/3317/3294 2252/3316/3295 2265/3332/3296 2264/3331/3297 -f 2252/3316/3298 2253/3315/3299 2266/3333/3300 2265/3332/3301 -f 2253/3315/3302 2254/3314/3303 2267/3334/3304 2266/3333/3305 -f 2254/3314/3306 2255/3313/3307 2268/3335/3308 2267/3334/3309 -f 2255/3313/3310 2256/3312/3311 2269/3336/3312 2268/3335/3313 -f 2256/3312/3314 2257/3323/3315 2270/3337/3316 2269/3336/3317 -f 2257/3323/3318 2246/3322/3319 2259/3326/3320 2270/3337/3321 -f 2259/3326/3322 2260/3327/3323 2272/3339/3324 2271/3338/3325 -f 2284/3350/3326 2285/3351/3327 2286/3352/3328 2287/3353/3329 -f 2261/3328/3330 2262/3329/3331 2275/3341/3332 2274/3340/3333 -f 2262/3329/3334 2263/3330/3335 2276/3342/3336 2275/3341/3337 -f 2263/3330/3338 2264/3331/3339 2277/3343/3340 2276/3342/3341 -f 2288/3354/3342 2289/3355/3343 2290/3356/3344 2291/3357/3345 -f 2265/3332/3346 2266/3333/3347 2279/3345/3348 2278/3344/3349 -f 2266/3333/3350 2267/3334/3351 2280/3346/3352 2279/3345/3353 -f 2267/3334/3354 2268/3335/3355 2281/3347/3356 2280/3346/3357 -f 2292/3358/3358 2293/3359/3359 2294/3360/3360 2295/3361/3361 -f 2269/3336/3362 2270/3337/3363 2283/3349/3364 2282/3348/3365 -f 2270/3337/3366 2259/3326/3367 2271/3338/3368 2283/3349/3369 -f 2260/3327/3370 2261/3328/3371 2285/3351/3372 2284/3350/3373 -f 2261/3328/3374 2274/3340/3375 2286/3352/3376 2285/3351/3377 -f 2274/3340/3378 2272/3339/3379 2287/3353/3380 2286/3352/3381 -f 2272/3339/3382 2260/3327/3383 2284/3350/3384 2287/3353/3385 -f 2264/3331/3386 2265/3332/3387 2289/3355/3388 2288/3354/3389 -f 2265/3332/3390 2278/3344/3391 2290/3356/3392 2289/3355/3393 -f 2278/3344/3394 2277/3343/3395 2291/3357/3396 2290/3356/3397 -f 2277/3343/3398 2264/3331/3399 2288/3354/3400 2291/3357/3401 -f 2268/3335/3402 2269/3336/3403 2293/3359/3404 2292/3358/3405 -f 2269/3336/3406 2282/3348/3407 2294/3360/3408 2293/3359/3409 -f 2282/3348/3410 2281/3347/3411 2295/3361/3412 2294/3360/3413 -f 2281/3347/3414 2268/3335/3415 2292/3358/3416 2295/3361/3417 -g default -v -4.894008 -1.617534 1.828536 -v -5.223333 -1.617529 1.499233 -v -5.343847 -1.617529 1.049395 -v -5.223333 -1.617539 0.599561 -v -4.894008 -1.617524 0.270258 -v -4.444169 -1.617539 0.149724 -v -3.994330 -1.617524 0.270258 -v -3.665042 -1.617539 0.599561 -v -3.544491 -1.617529 1.049395 -v -3.665042 -1.617529 1.499233 -v -3.994330 -1.617534 1.828536 -v -4.444169 -1.617529 1.949063 -v -4.894008 -2.784924 1.828536 -v -5.223333 -2.784919 1.499233 -v -5.343847 -2.784919 1.049395 -v -5.223333 -2.784919 0.599561 -v -4.894008 -2.784913 0.270258 -v -4.444169 -2.784919 0.149724 -v -3.994330 -2.784913 0.270258 -v -3.665042 -2.784919 0.599561 -v -3.544491 -2.784919 1.049395 -v -3.665042 -2.784919 1.499233 -v -3.994330 -2.784924 1.828536 -v -4.444169 -2.784919 1.949063 -v -4.444169 -1.617529 1.049395 -v -4.878751 -2.784924 1.802109 -v -5.196906 -2.784919 1.483976 -v -5.313332 -2.784919 1.049394 -v -5.196906 -2.784919 0.614818 -v -4.878751 -2.784914 0.296684 -v -4.444169 -2.784919 0.180239 -v -4.009588 -2.784914 0.296684 -v -3.691468 -2.784919 0.614818 -v -3.575006 -2.784919 1.049394 -v -3.691468 -2.784919 1.483976 -v -4.009588 -2.784924 1.802109 -v -4.444169 -2.784919 1.918548 -v -4.721886 -2.784922 1.530414 -v -5.035003 -2.784919 1.332596 -v -4.444169 -2.784919 1.049394 -v -5.089558 -2.784919 1.049394 -v -5.038586 -2.784919 0.770998 -v -4.721886 -2.784915 0.568377 -v -4.410956 -2.784919 0.405152 -v -4.121475 -2.784915 0.490476 -v -3.924029 -2.784919 0.685260 -v -3.888733 -2.784919 1.049394 -v -3.919789 -2.784919 1.409300 -v -4.121475 -2.784922 1.608316 -v -4.407044 -2.784919 1.693350 -v -4.878751 -2.660097 1.802109 -v -5.196906 -2.660092 1.483976 -v -5.035003 -2.660092 1.332596 -v -4.721886 -2.660096 1.530414 -v -4.444169 -2.660092 1.918548 -v -4.407044 -2.660092 1.693350 -v -5.196906 -2.660092 0.614818 -v -4.878751 -2.660087 0.296684 -v -4.721886 -2.660088 0.568377 -v -5.038586 -2.660092 0.770998 -v -4.444169 -2.660092 0.180239 -v -4.410956 -2.660092 0.405152 -v -3.691468 -2.660092 0.614818 -v -3.575006 -2.660092 1.049394 -v -3.888733 -2.660092 1.049394 -v -3.924029 -2.660092 0.685260 -v -3.691468 -2.660092 1.483976 -v -3.919789 -2.660092 1.409300 -vt 0.635316 0.078125 -vt 0.578125 0.020934 -vt 0.500000 0.000000 -vt 0.421875 0.020934 -vt 0.364684 0.078125 -vt 0.343750 0.156250 -vt 0.364684 0.234375 -vt 0.421875 0.291566 -vt 0.500000 0.312500 -vt 0.578125 0.291566 -vt 0.635316 0.234375 -vt 0.656250 0.156250 -vt 0.375000 0.312500 -vt 0.395833 0.312500 -vt 0.416667 0.312500 -vt 0.437500 0.312500 -vt 0.458333 0.312500 -vt 0.479167 0.312500 -vt 0.500000 0.312500 -vt 0.520833 0.312500 -vt 0.541667 0.312500 -vt 0.562500 0.312500 -vt 0.583333 0.312500 -vt 0.604167 0.312500 -vt 0.625000 0.312500 -vt 0.375000 0.688440 -vt 0.395833 0.688440 -vt 0.416667 0.688440 -vt 0.437500 0.688440 -vt 0.458333 0.688440 -vt 0.479167 0.688440 -vt 0.500000 0.688440 -vt 0.520833 0.688440 -vt 0.541667 0.688440 -vt 0.562500 0.688440 -vt 0.583333 0.688440 -vt 0.604167 0.688440 -vt 0.625000 0.688440 -vt 0.635316 0.765625 -vt 0.578125 0.708434 -vt 0.500000 0.687500 -vt 0.421875 0.708434 -vt 0.364684 0.765625 -vt 0.343750 0.843750 -vt 0.364684 0.921875 -vt 0.421875 0.979066 -vt 0.500000 1.000000 -vt 0.578125 0.979066 -vt 0.635316 0.921875 -vt 0.656250 0.843750 -vt 0.500000 0.150000 -vt 0.500000 0.837500 -vt 0.635316 0.921875 -vt 0.578125 0.979066 -vt 0.500000 1.000000 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.343750 0.843750 -vt 0.364684 0.765625 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.578125 0.708434 -vt 0.635316 0.765625 -vt 0.656250 0.843750 -vt 0.635316 0.921875 -vt 0.578125 0.979066 -vt 0.500000 1.000000 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.343750 0.843750 -vt 0.364684 0.765625 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.578125 0.708434 -vt 0.635316 0.765625 -vt 0.656250 0.843750 -vt 0.635316 0.921875 -vt 0.578125 0.979066 -vt 0.578125 0.979066 -vt 0.635316 0.921875 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.364684 0.921875 -vt 0.421875 0.979066 -vt 0.343750 0.843750 -vt 0.343750 0.843750 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.500000 0.687500 -vt 0.421875 0.708434 -vt 0.578125 0.708434 -vt 0.578125 0.708434 -vt 0.656250 0.843750 -vt 0.656250 0.843750 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.364684 0.921875 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.421875 0.979066 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.421875 0.979066 -vt 0.421875 0.979066 -vt 0.421875 0.979066 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.343750 0.843750 -vt 0.343750 0.843750 -vt 0.364684 0.921875 -vt 0.343750 0.843750 -vt 0.343750 0.843750 -vt 0.343750 0.843750 -vt 0.343750 0.843750 -vt 0.343750 0.843750 -vt 0.364684 0.921875 -vt 0.364684 0.921875 -vt 0.343750 0.843750 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.500000 0.687500 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.421875 0.708434 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.421875 0.708434 -vt 0.421875 0.708434 -vt 0.421875 0.708434 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.578125 0.708434 -vt 0.578125 0.708434 -vt 0.500000 0.687500 -vt 0.578125 0.708434 -vt 0.578125 0.708434 -vt 0.578125 0.708434 -vt 0.578125 0.708434 -vt 0.578125 0.708434 -vt 0.500000 0.687500 -vt 0.500000 0.687500 -vt 0.578125 0.708434 -vt 0.656250 0.843750 -vt 0.635316 0.921875 -vt 0.635316 0.921875 -vt 0.656250 0.843750 -vt 0.635316 0.921875 -vt 0.656250 0.843750 -vt 0.656250 0.843750 -vt 0.635316 0.921875 -vt 0.656250 0.843750 -vt 0.656250 0.843750 -vt 0.656250 0.843750 -vt 0.656250 0.843750 -vn -0.707082 0.000000 0.707132 -vn -0.707082 0.000000 0.707132 -vn -0.707082 0.000000 0.707132 -vn -0.707082 0.000000 0.707132 -vn -0.965937 0.000000 0.258779 -vn -0.965937 0.000000 0.258779 -vn -0.965937 0.000000 0.258779 -vn -0.965937 0.000000 0.258779 -vn -0.965936 0.000000 -0.258781 -vn -0.965936 0.000000 -0.258781 -vn -0.965936 0.000000 -0.258781 -vn -0.965936 0.000000 -0.258781 -vn -0.707082 0.000000 -0.707131 -vn -0.707082 0.000000 -0.707131 -vn -0.707082 0.000000 -0.707131 -vn -0.707082 0.000000 -0.707131 -vn -0.258819 0.000000 -0.965926 -vn -0.258819 0.000000 -0.965926 -vn -0.258819 0.000000 -0.965926 -vn -0.258819 0.000000 -0.965926 -vn 0.258819 0.000000 -0.965926 -vn 0.258819 0.000000 -0.965926 -vn 0.258819 0.000000 -0.965926 -vn 0.258819 0.000000 -0.965926 -vn 0.707122 0.000000 -0.707092 -vn 0.707122 0.000000 -0.707092 -vn 0.707122 0.000000 -0.707092 -vn 0.707122 0.000000 -0.707092 -vn 0.965916 0.000000 -0.258856 -vn 0.965916 0.000000 -0.258856 -vn 0.965916 0.000000 -0.258856 -vn 0.965916 0.000000 -0.258856 -vn 0.965917 0.000000 0.258853 -vn 0.965917 0.000000 0.258853 -vn 0.965917 0.000000 0.258853 -vn 0.965917 0.000000 0.258853 -vn 0.707122 0.000000 0.707092 -vn 0.707122 0.000000 0.707092 -vn 0.707122 0.000000 0.707092 -vn 0.707122 0.000000 0.707092 -vn 0.258805 0.000000 0.965930 -vn 0.258805 0.000000 0.965930 -vn 0.258805 0.000000 0.965930 -vn 0.258805 0.000000 0.965930 -vn -0.258805 0.000000 0.965930 -vn -0.258805 0.000000 0.965930 -vn -0.258805 0.000000 0.965930 -vn -0.258805 0.000000 0.965930 -vn 0.000003 1.000000 0.000004 -vn -0.000003 1.000000 0.000005 -vn -0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000011 -vn -0.000012 1.000000 0.000000 -vn 0.000003 1.000000 0.000005 -vn 0.000000 1.000000 -0.000011 -vn -0.000003 1.000000 0.000005 -vn 0.000012 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000010 -vn -0.000003 1.000000 0.000005 -vn 0.000003 1.000000 0.000005 -vn 0.000000 1.000000 0.000000 -vn 0.000003 -1.000000 -0.000006 -vn -0.000002 -1.000000 -0.000005 -vn 0.000000 -1.000000 -0.000004 -vn 0.000000 -1.000000 0.000000 -vn 0.000002 -1.000000 -0.000005 -vn -0.000003 -1.000000 -0.000006 -vn 0.000002 -1.000000 -0.000000 -vn 0.000003 -1.000000 -0.000005 -vn -0.000004 -1.000000 -0.000006 -vn 0.000000 -1.000000 -0.000001 -vn 0.000004 -1.000000 -0.000006 -vn -0.000003 -1.000000 -0.000005 -vn -0.000002 -1.000000 0.000000 -vn -0.000005 -1.000000 -0.000006 -vn -0.000005 -1.000000 -0.000006 -vn -0.000005 -1.000000 -0.000006 -vn -0.000005 -1.000000 -0.000006 -vn 0.000000 -1.000000 -0.000002 -vn 0.000000 -1.000000 -0.000002 -vn 0.000000 -1.000000 -0.000002 -vn 0.000000 -1.000000 -0.000002 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000005 -1.000000 -0.000008 -vn 0.000005 -1.000000 -0.000008 -vn 0.000005 -1.000000 -0.000008 -vn 0.000005 -1.000000 -0.000008 -vn -0.000012 -1.000000 0.000001 -vn -0.000012 -1.000000 0.000001 -vn -0.000012 -1.000000 0.000001 -vn -0.000012 -1.000000 0.000001 -vn 0.000012 -1.000000 0.000000 -vn 0.000012 -1.000000 0.000000 -vn 0.000012 -1.000000 0.000000 -vn 0.000012 -1.000000 0.000000 -vn -0.000005 -1.000000 -0.000004 -vn -0.000005 -1.000000 -0.000004 -vn -0.000005 -1.000000 -0.000004 -vn -0.000005 -1.000000 -0.000004 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 0.000002 -vn 0.000000 -1.000000 0.000002 -vn 0.000000 -1.000000 0.000002 -vn 0.000000 -1.000000 0.000002 -vn 0.000005 -1.000000 -0.000012 -vn 0.000005 -1.000000 -0.000012 -vn 0.000005 -1.000000 -0.000012 -vn 0.000005 -1.000000 -0.000012 -vn -0.000012 -1.000000 -0.000002 -vn -0.000012 -1.000000 -0.000002 -vn -0.000012 -1.000000 -0.000002 -vn -0.000012 -1.000000 -0.000002 -vn 0.000012 -1.000000 0.000000 -vn 0.000012 -1.000000 0.000000 -vn 0.000012 -1.000000 0.000000 -vn 0.000012 -1.000000 0.000000 -vn -0.000007 -1.000000 -0.000009 -vn -0.000007 -1.000000 -0.000009 -vn -0.000007 -1.000000 -0.000009 -vn -0.000007 -1.000000 -0.000009 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000007 -1.000000 -0.000008 -vn 0.000007 -1.000000 -0.000008 -vn 0.000007 -1.000000 -0.000008 -vn 0.000007 -1.000000 -0.000008 -vn -0.000011 -1.000000 0.000001 -vn -0.000011 -1.000000 0.000001 -vn -0.000011 -1.000000 0.000001 -vn -0.000011 -1.000000 0.000001 -vn 0.000012 -1.000000 -0.000001 -vn 0.000012 -1.000000 -0.000001 -vn 0.000012 -1.000000 -0.000001 -vn 0.000012 -1.000000 -0.000001 -vn -0.000005 -1.000000 -0.000012 -vn -0.000005 -1.000000 -0.000012 -vn -0.000005 -1.000000 -0.000012 -vn -0.000005 -1.000000 -0.000012 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000006 -1.000000 -0.000011 -vn 0.000006 -1.000000 -0.000011 -vn 0.000006 -1.000000 -0.000011 -vn 0.000006 -1.000000 -0.000011 -vn -0.000012 -1.000000 0.000000 -vn -0.000012 -1.000000 0.000000 -vn -0.000012 -1.000000 0.000000 -vn -0.000012 -1.000000 0.000000 -vn 0.000011 -1.000000 0.000001 -vn 0.000011 -1.000000 0.000001 -vn 0.000011 -1.000000 0.000001 -vn 0.000011 -1.000000 0.000001 -vn 0.707082 0.000000 -0.707131 -vn 0.707082 0.000000 -0.707131 -vn 0.707082 0.000000 -0.707131 -vn 0.707082 0.000000 -0.707131 -vn 0.682971 0.000000 0.730445 -vn 0.682971 0.000000 0.730445 -vn 0.682971 0.000000 0.730445 -vn 0.682971 0.000000 0.730445 -vn -0.534109 0.000000 0.845415 -vn -0.534109 0.000000 0.845416 -vn -0.534109 0.000000 0.845415 -vn -0.534109 0.000000 0.845416 -vn 0.258805 0.000000 -0.965930 -vn 0.258805 0.000000 -0.965930 -vn 0.258805 0.000000 -0.965930 -vn 0.258805 0.000000 -0.965930 -vn -0.459615 0.000000 0.888118 -vn -0.459615 0.000000 0.888118 -vn -0.459615 0.000000 0.888118 -vn -0.459615 0.000000 0.888118 -vn -0.986682 0.000000 -0.162660 -vn -0.986682 0.000000 -0.162660 -vn -0.986682 0.000000 -0.162660 -vn -0.986682 0.000000 -0.162660 -vn 0.707082 0.000000 0.707131 -vn 0.707082 0.000000 0.707131 -vn 0.707082 0.000000 0.707131 -vn 0.707082 0.000000 0.707131 -vn -0.538927 0.000000 -0.842353 -vn -0.538927 0.000000 -0.842353 -vn -0.538927 0.000000 -0.842353 -vn -0.538927 0.000000 -0.842353 -vn 0.702281 0.000000 -0.711900 -vn 0.702281 0.000000 -0.711900 -vn 0.702281 0.000000 -0.711900 -vn 0.702281 0.000000 -0.711900 -vn 0.258819 0.000000 0.965926 -vn 0.258819 0.000000 0.965926 -vn 0.258819 0.000000 0.965926 -vn 0.258819 0.000000 0.965926 -vn -0.989272 0.000000 0.146088 -vn -0.989272 0.000000 0.146088 -vn -0.989272 0.000000 0.146088 -vn -0.989272 0.000000 0.146088 -vn -0.464804 0.000000 -0.885414 -vn -0.464804 0.000000 -0.885414 -vn -0.464804 0.000000 -0.885414 -vn -0.464804 0.000000 -0.885414 -vn -0.965916 0.000000 0.258856 -vn -0.965916 0.000000 0.258856 -vn -0.965916 0.000000 0.258856 -vn -0.965916 0.000000 0.258856 -vn 0.995335 0.000000 -0.096479 -vn 0.995335 0.000000 -0.096479 -vn 0.995335 0.000000 -0.096479 -vn 0.995335 0.000000 -0.096479 -vn 0.289890 0.000000 0.957060 -vn 0.289890 0.000000 0.957060 -vn 0.289890 0.000000 0.957060 -vn 0.289890 0.000000 0.957060 -vn -0.965917 0.000000 -0.258853 -vn -0.965917 0.000000 -0.258853 -vn -0.965917 0.000000 -0.258853 -vn -0.965917 0.000000 -0.258853 -vn 0.310861 0.000000 -0.950456 -vn 0.310861 0.000000 -0.950456 -vn 0.310861 0.000000 -0.950456 -vn 0.310861 0.000000 -0.950456 -vn 0.996298 0.000000 0.085968 -vn 0.996298 0.000000 0.085968 -vn 0.996298 0.000000 0.085968 -vn 0.996298 0.000000 0.085968 -s off -g wheel_BR_geo -usemtl blinn2SG -f 2296/3374/3418 2297/3375/3419 2309/3388/3420 2308/3387/3421 -f 2297/3375/3422 2298/3376/3423 2310/3389/3424 2309/3388/3425 -f 2298/3376/3426 2299/3377/3427 2311/3390/3428 2310/3389/3429 -f 2299/3377/3430 2300/3378/3431 2312/3391/3432 2311/3390/3433 -f 2300/3378/3434 2301/3379/3435 2313/3392/3436 2312/3391/3437 -f 2301/3379/3438 2302/3380/3439 2314/3393/3440 2313/3392/3441 -f 2302/3380/3442 2303/3381/3443 2315/3394/3444 2314/3393/3445 -f 2303/3381/3446 2304/3382/3447 2316/3395/3448 2315/3394/3449 -f 2304/3382/3450 2305/3383/3451 2317/3396/3452 2316/3395/3453 -f 2305/3383/3454 2306/3384/3455 2318/3397/3456 2317/3396/3457 -f 2306/3384/3458 2307/3385/3459 2319/3398/3460 2318/3397/3461 -f 2307/3385/3462 2296/3386/3463 2308/3399/3464 2319/3398/3465 -s 1 -f 2297/3363/3466 2296/3362/3467 2320/3412/3468 -f 2298/3364/3469 2297/3363/3466 2320/3412/3468 -f 2299/3365/3470 2298/3364/3469 2320/3412/3468 -f 2300/3366/3471 2299/3365/3470 2320/3412/3468 -f 2301/3367/3472 2300/3366/3471 2320/3412/3468 -f 2302/3368/3473 2301/3367/3472 2320/3412/3468 -f 2303/3369/3474 2302/3368/3473 2320/3412/3468 -f 2304/3370/3475 2303/3369/3474 2320/3412/3468 -f 2305/3371/3476 2304/3370/3475 2320/3412/3468 -f 2306/3372/3477 2305/3371/3476 2320/3412/3468 -f 2307/3373/3478 2306/3372/3477 2320/3412/3468 -f 2296/3362/3467 2307/3373/3478 2320/3412/3468 -s 2 -f 2333/3426/3479 2334/3427/3480 2335/3413/3481 -f 2334/3427/3480 2336/3428/3482 2335/3413/3481 -f 2336/3428/3482 2337/3429/3483 2335/3413/3481 -f 2337/3429/3483 2338/3430/3484 2335/3413/3481 -f 2338/3430/3484 2339/3431/3485 2335/3413/3481 -f 2339/3431/3485 2340/3432/3486 2335/3413/3481 -f 2340/3432/3486 2341/3433/3487 2335/3413/3481 -f 2341/3433/3487 2342/3434/3488 2335/3413/3481 -f 2342/3434/3488 2343/3435/3489 2335/3413/3481 -f 2343/3435/3489 2344/3436/3490 2335/3413/3481 -f 2344/3436/3490 2345/3437/3491 2335/3413/3481 -f 2345/3437/3491 2333/3426/3479 2335/3413/3481 -s off -f 2308/3410/3492 2309/3409/3493 2322/3415/3494 2321/3414/3495 -f 2309/3409/3496 2310/3408/3497 2323/3416/3498 2322/3415/3499 -f 2310/3408/3500 2311/3407/3501 2324/3417/3502 2323/3416/3503 -f 2311/3407/3504 2312/3406/3505 2325/3418/3506 2324/3417/3507 -f 2312/3406/3508 2313/3405/3509 2326/3419/3510 2325/3418/3511 -f 2313/3405/3512 2314/3404/3513 2327/3420/3514 2326/3419/3515 -f 2314/3404/3516 2315/3403/3517 2328/3421/3518 2327/3420/3519 -f 2315/3403/3520 2316/3402/3521 2329/3422/3522 2328/3421/3523 -f 2316/3402/3524 2317/3401/3525 2330/3423/3526 2329/3422/3527 -f 2317/3401/3528 2318/3400/3529 2331/3424/3530 2330/3423/3531 -f 2318/3400/3532 2319/3411/3533 2332/3425/3534 2331/3424/3535 -f 2319/3411/3536 2308/3410/3537 2321/3414/3538 2332/3425/3539 -f 2346/3438/3540 2347/3439/3541 2348/3440/3542 2349/3441/3543 -f 2322/3415/3544 2323/3416/3545 2336/3428/3546 2334/3427/3547 -f 2323/3416/3548 2324/3417/3549 2337/3429/3550 2336/3428/3551 -f 2352/3442/3552 2353/3443/3553 2354/3444/3554 2355/3445/3555 -f 2353/3443/3556 2356/3446/3557 2357/3447/3558 2354/3444/3559 -f 2326/3419/3560 2327/3420/3561 2340/3432/3562 2339/3431/3563 -f 2327/3420/3564 2328/3421/3565 2341/3433/3566 2340/3432/3567 -f 2358/3448/3568 2359/3449/3569 2360/3450/3570 2361/3451/3571 -f 2359/3449/3572 2362/3452/3573 2363/3453/3574 2360/3450/3575 -f 2330/3423/3576 2331/3424/3577 2344/3436/3578 2343/3435/3579 -f 2331/3424/3580 2332/3425/3581 2345/3437/3582 2344/3436/3583 -f 2350/3454/3584 2346/3438/3585 2349/3441/3586 2351/3455/3587 -f 2321/3414/3588 2322/3415/3589 2347/3439/3590 2346/3438/3591 -f 2322/3415/3592 2334/3427/3593 2348/3440/3594 2347/3439/3595 -f 2334/3427/3596 2333/3426/3597 2349/3441/3598 2348/3440/3599 -f 2332/3456/3600 2321/3457/3601 2346/3458/3602 2350/3459/3603 -f 2333/3460/3604 2345/3461/3605 2351/3462/3606 2349/3463/3607 -f 2345/3464/3608 2332/3465/3609 2350/3466/3610 2351/3467/3611 -f 2324/3468/3612 2325/3469/3613 2353/3470/3614 2352/3471/3615 -f 2338/3472/3616 2337/3473/3617 2355/3474/3618 2354/3475/3619 -f 2337/3476/3620 2324/3477/3621 2352/3478/3622 2355/3479/3623 -f 2325/3480/3624 2326/3481/3625 2356/3482/3626 2353/3483/3627 -f 2326/3484/3628 2339/3485/3629 2357/3486/3630 2356/3487/3631 -f 2339/3488/3632 2338/3489/3633 2354/3490/3634 2357/3491/3635 -f 2328/3492/3636 2329/3493/3637 2359/3494/3638 2358/3495/3639 -f 2342/3496/3640 2341/3497/3641 2361/3498/3642 2360/3499/3643 -f 2341/3500/3644 2328/3501/3645 2358/3502/3646 2361/3503/3647 -f 2329/3504/3648 2330/3505/3649 2362/3506/3650 2359/3507/3651 -f 2330/3508/3652 2343/3509/3653 2363/3510/3654 2362/3511/3655 -f 2343/3512/3656 2342/3513/3657 2360/3514/3658 2363/3515/3659 -g default -v -3.914276 2.740168 4.105663 -v -4.063626 2.740168 4.240822 -v -4.125397 2.740168 4.432532 -v -4.083036 2.740168 4.629443 -v -3.947894 2.740168 4.778773 -v -3.756186 2.740168 4.840562 -v -3.559274 2.740168 4.798182 -v -3.409926 2.740168 4.663061 -v -3.348156 2.740168 4.471351 -v -3.390517 2.740168 4.274440 -v -3.525656 2.740168 4.125072 -v -3.717367 2.740168 4.063321 -v -3.914276 1.802424 4.105663 -v -4.063626 1.802424 4.240822 -v -4.125397 1.802424 4.432532 -v -4.083036 1.802424 4.629443 -v -3.947894 1.802424 4.778773 -v -3.756186 1.802424 4.840562 -v -3.559274 1.802424 4.798182 -v -3.409926 1.802424 4.663061 -v -3.348156 1.802424 4.471351 -v -3.390517 1.802424 4.274440 -v -3.525656 1.802424 4.125072 -v -3.717367 1.802424 4.063321 -v -3.885918 2.803350 4.160990 -v -4.011418 2.803350 4.274532 -v -3.736776 2.803350 4.451941 -v -4.063309 2.803350 4.435633 -v -4.027726 2.803350 4.601065 -v -3.914167 2.803350 4.726584 -v -3.753085 2.803350 4.778474 -v -3.587634 2.803350 4.742893 -v -3.462133 2.803350 4.629313 -v -3.410244 2.803350 4.468250 -v -3.445824 2.803350 4.302780 -v -3.559386 2.803350 4.177299 -v -3.720466 2.803350 4.125371 -v -3.409926 2.086929 4.663061 -v -3.559274 2.086929 4.798182 -v -3.756186 2.086929 4.840562 -v -3.947894 2.086929 4.778773 -v -4.083036 2.086929 4.629443 -v -4.125397 2.086929 4.432532 -v -4.063626 2.086929 4.240822 -v -3.914276 2.086929 4.105663 -v -3.717367 2.086929 4.063321 -v -3.525656 2.086929 4.125072 -v -3.390517 2.086929 4.274440 -v -3.348156 2.086929 4.471351 -v -3.409926 2.562936 4.663061 -v -3.559274 2.562936 4.798182 -v -3.756186 2.562936 4.840562 -v -3.947894 2.562936 4.778773 -v -4.083036 2.562936 4.629443 -v -4.125397 2.562936 4.432532 -v -4.063626 2.562936 4.240822 -v -3.914276 2.562936 4.105663 -v -3.717367 2.562936 4.063321 -v -3.525656 2.562936 4.125072 -v -3.390517 2.562936 4.274440 -v -3.348156 2.562936 4.471351 -v -2.692956 2.086929 4.614460 -v -2.700061 2.086929 4.756723 -v -2.666443 2.086929 4.083613 -v -2.673547 2.086929 4.225839 -v -2.683251 2.086929 4.420149 -v -2.700061 2.562936 4.756723 -v -2.692956 2.562936 4.614460 -v -2.666443 2.562936 4.083613 -v -2.673547 2.562936 4.225839 -v -2.683251 2.562936 4.420149 -v 0.793126 2.086929 5.216424 -v 0.786023 2.086929 5.358650 -v 0.819641 2.086929 4.685541 -v 0.812535 2.086929 4.827804 -v 0.802831 2.086929 5.022114 -v 0.786023 2.562936 5.358650 -v 0.793126 2.562936 5.216424 -v 0.819641 2.562936 4.685541 -v 0.812535 2.562936 4.827804 -v 0.802831 2.562936 5.022114 -v 1.194930 2.086929 5.123959 -v 1.230951 2.086929 5.261741 -v 1.060485 2.086929 4.609692 -v 1.096504 2.086929 4.747511 -v 1.145728 2.086929 4.935717 -v 1.230951 2.504857 5.261741 -v 1.194930 2.504857 5.123959 -v 1.060485 2.504857 4.609692 -v 1.096504 2.504857 4.747511 -v 1.145728 2.504857 4.935717 -v 2.633414 1.733218 3.683136 -v 2.669435 1.733218 3.820918 -v 2.498948 1.733218 3.168906 -v 2.534970 1.733218 3.306688 -v 2.584192 1.733218 3.494912 -v 2.669435 2.019982 3.820918 -v 2.633414 2.019982 3.683136 -v 2.498948 2.019982 3.168906 -v 2.534970 2.019982 3.306688 -v 2.584192 2.019982 3.494912 -v 2.051731 2.127575 4.265763 -v 2.087733 2.127575 4.403545 -v 2.087733 1.764262 4.403545 -v 2.051731 1.764262 4.265763 -v 2.002507 1.764262 4.077558 -v 1.953305 1.764262 3.889316 -v 1.917284 1.764262 3.751534 -v 1.917284 2.127575 3.751534 -v 1.953305 2.127575 3.889316 -v 2.002507 2.127575 4.077558 -vt 0.635316 0.078125 -vt 0.578125 0.020934 -vt 0.500000 0.000000 -vt 0.421875 0.020934 -vt 0.364684 0.078125 -vt 0.343750 0.156250 -vt 0.364684 0.234375 -vt 0.421875 0.291566 -vt 0.500000 0.312500 -vt 0.578125 0.291566 -vt 0.635316 0.234375 -vt 0.656250 0.156250 -vt 0.375000 0.312500 -vt 0.395833 0.312500 -vt 0.416667 0.312500 -vt 0.437500 0.312500 -vt 0.458333 0.312500 -vt 0.479167 0.312500 -vt 0.500000 0.312500 -vt 0.520833 0.312500 -vt 0.541667 0.312500 -vt 0.562500 0.312500 -vt 0.583333 0.312500 -vt 0.604167 0.312500 -vt 0.625000 0.312500 -vt 0.375000 0.688440 -vt 0.395833 0.688440 -vt 0.416667 0.688440 -vt 0.437500 0.688440 -vt 0.458333 0.688440 -vt 0.479167 0.688440 -vt 0.500000 0.688440 -vt 0.520833 0.688440 -vt 0.541667 0.688440 -vt 0.562500 0.688440 -vt 0.583333 0.688440 -vt 0.604167 0.688440 -vt 0.625000 0.688440 -vt 0.500000 0.150000 -vt 0.578125 0.020934 -vt 0.635316 0.078125 -vt 0.500000 0.000000 -vt 0.421875 0.020934 -vt 0.364684 0.078125 -vt 0.343750 0.156250 -vt 0.364684 0.234375 -vt 0.421875 0.291566 -vt 0.500000 0.312500 -vt 0.578125 0.291566 -vt 0.635316 0.234375 -vt 0.656250 0.156250 -vt 0.520833 0.558498 -vt 0.500000 0.558498 -vt 0.479167 0.558498 -vt 0.458333 0.558498 -vt 0.437500 0.558498 -vt 0.416667 0.558498 -vt 0.395833 0.558498 -vt 0.625000 0.558498 -vt 0.375000 0.558498 -vt 0.604167 0.558498 -vt 0.583333 0.558498 -vt 0.562500 0.558498 -vt 0.541667 0.558498 -vt 0.520833 0.430310 -vt 0.500000 0.430310 -vt 0.479167 0.430310 -vt 0.458333 0.430310 -vt 0.437500 0.430310 -vt 0.416667 0.430310 -vt 0.395833 0.430310 -vt 0.625000 0.430310 -vt 0.375000 0.430310 -vt 0.604167 0.430310 -vt 0.583333 0.430310 -vt 0.562500 0.430310 -vt 0.541667 0.430310 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vt 1.000000 0.595625 -vt 0.000000 0.595625 -vn -0.445425 0.215869 -0.868906 -vn -0.456179 0.000000 -0.889888 -vn -0.840019 0.000000 -0.542558 -vn -0.820211 0.215891 -0.529760 -vn -0.998755 0.000000 -0.049882 -vn -0.975202 0.215891 -0.048706 -vn -0.889877 0.000000 0.456200 -vn -0.868888 0.215896 0.445446 -vn -0.542577 0.000000 0.840006 -vn -0.529790 0.215887 0.820192 -vn -0.049881 0.000000 0.998755 -vn -0.048705 0.215855 0.975210 -vn 0.125103 0.081123 0.988822 -vn 0.445430 0.215887 0.868899 -vn 0.210507 0.968089 0.135977 -vn 0.820180 0.215896 0.529805 -vn 0.215699 0.976401 0.010773 -vn 0.975202 0.215891 0.048706 -vn 0.204988 0.973108 -0.105076 -vn 0.868915 0.215890 -0.445397 -vn 0.083460 0.117459 -0.989564 -vn 0.529786 0.215869 -0.820200 -vn 0.049881 0.000000 -0.998755 -vn 0.048706 0.215876 -0.975205 -vn -0.287284 0.939700 -0.185560 -vn 0.000000 1.000000 -0.000000 -vn -0.156005 0.939712 -0.304307 -vn -0.341552 0.939708 -0.017057 -vn -0.304329 0.939708 0.155991 -vn -0.185560 0.939699 0.287286 -vn -0.017059 0.939703 0.341567 -vn 0.156011 0.939699 0.304346 -vn 0.287272 0.939708 0.185538 -vn 0.341552 0.939708 0.017059 -vn 0.304344 0.939699 -0.156013 -vn 0.185550 0.939712 -0.287249 -vn 0.017061 0.939695 -0.341587 -vn 0.148270 -0.075896 0.986030 -vn 0.456178 0.000000 0.889888 -vn 0.839993 0.000000 0.542598 -vn 0.322335 -0.923443 0.208214 -vn -0.049881 0.000000 0.998755 -vn -0.049882 0.000000 0.998755 -vn -0.542577 0.000000 0.840006 -vn -0.542577 0.000000 0.840006 -vn -0.889877 0.000000 0.456200 -vn -0.889877 0.000000 0.456200 -vn -0.998755 0.000000 -0.049882 -vn -0.998755 0.000000 -0.049882 -vn -0.840019 0.000000 -0.542558 -vn -0.840019 0.000000 -0.542557 -vn -0.456179 0.000000 -0.889888 -vn -0.456179 0.000000 -0.889888 -vn 0.049881 0.000000 -0.998755 -vn 0.049882 0.000000 -0.998755 -vn 0.116016 -0.110243 -0.987110 -vn 0.542577 0.000000 -0.840006 -vn 0.316102 -0.934786 -0.162032 -vn 0.889899 0.000000 -0.456157 -vn 0.334183 -0.942360 0.016691 -vn 0.998755 0.000000 0.049882 -vn 0.000000 -1.000000 0.000000 -vn -0.122111 -0.298010 0.946720 -vn 0.123367 -0.264515 -0.956458 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000000 -vn -0.122111 0.298010 0.946720 -vn 0.000000 1.000000 0.000000 -vn 0.123367 0.264515 -0.956458 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000001 -vn 0.000000 -1.000000 0.000000 -vn -0.125183 -0.263555 0.956487 -vn 0.134481 -0.311497 -0.940683 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000000 -vn -0.124549 0.265844 0.955936 -vn 0.014392 0.999895 -0.001486 -vn 0.143247 0.313314 -0.938784 -vn 0.015243 0.999883 -0.001574 -vn 0.014779 0.999890 -0.001526 -vn -0.208392 -0.976527 0.054475 -vn 0.547372 -0.216157 0.808493 -vn -0.669729 -0.324272 -0.668065 -vn -0.228714 -0.971656 0.059795 -vn -0.218466 -0.974171 0.057121 -vn 0.584045 0.259264 0.769203 -vn 0.278380 0.958162 -0.066563 -vn -0.441345 0.442210 -0.780810 -vn 0.300632 0.950985 -0.072439 -vn 0.289484 0.954657 -0.069495 -vn -0.196918 -0.979067 0.051482 -vn 0.595319 -0.382154 0.706791 -vn -0.699722 -0.323903 -0.636770 -vn -0.185007 -0.981546 0.048365 -vn -0.191030 -0.980313 0.049947 -vn 0.729163 0.295389 0.617306 -vn 0.261868 0.962672 -0.068461 -vn -0.633754 0.288778 -0.717609 -vn 0.253018 0.965198 -0.066145 -vn 0.257489 0.963933 -0.067325 -vn 0.682294 0.409578 0.605575 -vn 0.144924 0.988717 -0.037895 -vn 0.614408 -0.463962 0.638155 -vn -0.042253 -0.999046 0.011048 -vn -0.042254 -0.999046 0.011049 -vn -0.042256 -0.999046 0.011048 -vn -0.692288 -0.247164 -0.677973 -vn -0.667150 0.230015 -0.708523 -vn 0.144932 0.988716 -0.037891 -vn 0.144926 0.988717 -0.037894 -s 1 -g uprArm_L_geo -usemtl blinn2SG -f 2364/3528/3660 2420/3588/3661 2419/3586/3662 2365/3529/3663 -f 2365/3529/3663 2419/3586/3662 2418/3585/3664 2366/3530/3665 -f 2366/3530/3665 2418/3585/3664 2417/3584/3666 2367/3531/3667 -f 2367/3531/3667 2417/3584/3666 2416/3583/3668 2368/3532/3669 -f 2368/3532/3669 2416/3583/3668 2415/3582/3670 2369/3533/3671 -f 2369/3533/3671 2415/3582/3670 2414/3581/3672 2370/3534/3673 -f 2370/3534/3673 2414/3581/3672 2413/3580/3674 2371/3535/3675 -f 2371/3535/3675 2413/3580/3674 2424/3592/3676 2372/3536/3677 -f 2372/3536/3677 2424/3592/3676 2423/3591/3678 2373/3537/3679 -f 2373/3537/3679 2423/3591/3678 2422/3590/3680 2374/3538/3681 -f 2374/3538/3681 2422/3590/3680 2421/3589/3682 2375/3539/3683 -f 2375/3539/3683 2421/3589/3682 2420/3587/3661 2364/3540/3660 -f 2389/3555/3684 2390/3554/3685 2388/3556/3686 -f 2391/3557/3687 2390/3554/3685 2389/3555/3684 -f 2392/3558/3688 2390/3554/3685 2391/3557/3687 -f 2393/3559/3689 2390/3554/3685 2392/3558/3688 -f 2394/3560/3690 2390/3554/3685 2393/3559/3689 -f 2395/3561/3691 2390/3554/3685 2394/3560/3690 -f 2396/3562/3692 2390/3554/3685 2395/3561/3691 -f 2397/3563/3693 2390/3554/3685 2396/3562/3692 -f 2398/3564/3694 2390/3554/3685 2397/3563/3693 -f 2399/3565/3695 2390/3554/3685 2398/3564/3694 -f 2400/3566/3696 2390/3554/3685 2399/3565/3695 -f 2388/3556/3686 2390/3554/3685 2400/3566/3696 -f 2365/3517/3663 2389/3555/3684 2388/3556/3686 2364/3516/3660 -f 2366/3518/3665 2391/3557/3687 2389/3555/3684 2365/3517/3663 -f 2367/3519/3667 2392/3558/3688 2391/3557/3687 2366/3518/3665 -f 2368/3520/3669 2393/3559/3689 2392/3558/3688 2367/3519/3667 -f 2369/3521/3671 2394/3560/3690 2393/3559/3689 2368/3520/3669 -f 2370/3522/3673 2395/3561/3691 2394/3560/3690 2369/3521/3671 -f 2371/3523/3675 2396/3562/3692 2395/3561/3691 2370/3522/3673 -f 2372/3524/3677 2397/3563/3693 2396/3562/3692 2371/3523/3675 -f 2373/3525/3679 2398/3564/3694 2397/3563/3693 2372/3524/3677 -f 2374/3526/3681 2399/3565/3695 2398/3564/3694 2373/3525/3679 -f 2375/3527/3683 2400/3566/3696 2399/3565/3695 2374/3526/3681 -f 2364/3516/3660 2388/3556/3686 2400/3566/3696 2375/3527/3683 -f 2402/3568/3697 2382/3547/3698 2383/3548/3699 2401/3567/3700 -f 2403/3569/3701 2381/3546/3702 2382/3547/3698 2402/3568/3697 -f 2404/3570/3703 2380/3545/3704 2381/3546/3702 2403/3569/3701 -f 2405/3571/3705 2379/3544/3706 2380/3545/3704 2404/3570/3703 -f 2406/3572/3707 2378/3543/3708 2379/3544/3706 2405/3571/3705 -f 2407/3573/3709 2377/3542/3710 2378/3543/3708 2406/3572/3707 -f 2408/3575/3711 2376/3541/3712 2377/3542/3710 2407/3573/3709 -f 2409/3576/3713 2387/3552/3714 2376/3553/3712 2408/3574/3711 -f 2410/3577/3715 2386/3551/3716 2387/3552/3714 2409/3576/3713 -f 2411/3578/3717 2385/3550/3718 2386/3551/3716 2410/3577/3715 -f 2412/3579/3719 2384/3549/3720 2385/3550/3718 2411/3578/3717 -f 2401/3567/3700 2383/3548/3699 2384/3549/3720 2412/3579/3719 -f 2415/3582/3670 2403/3569/3701 2402/3568/3697 2414/3581/3672 -f 2416/3583/3668 2404/3570/3703 2403/3569/3701 2415/3582/3670 -f 2417/3584/3666 2405/3571/3705 2404/3570/3703 2416/3583/3668 -f 2418/3585/3664 2406/3572/3707 2405/3571/3705 2417/3584/3666 -f 2419/3586/3662 2407/3573/3709 2406/3572/3707 2418/3585/3664 -f 2420/3588/3661 2408/3575/3711 2407/3573/3709 2419/3586/3662 -f 2421/3589/3682 2409/3576/3713 2408/3574/3711 2420/3587/3661 -f 2422/3590/3680 2410/3577/3715 2409/3576/3713 2421/3589/3682 -f 2401/3593/3700 2425/3596/3721 2426/3595/3722 2402/3594/3697 -f 2410/3597/3715 2427/3600/3723 2428/3599/3724 2411/3598/3717 -f 2411/3601/3717 2428/3604/3724 2429/3603/3725 2412/3602/3719 -f 2412/3605/3719 2429/3608/3725 2425/3607/3721 2401/3606/3700 -f 2402/3609/3697 2426/3612/3722 2430/3611/3726 2414/3610/3672 -f 2414/3613/3672 2430/3616/3726 2431/3615/3727 2413/3614/3674 -f 2422/3617/3680 2432/3620/3728 2427/3619/3723 2410/3618/3715 -f 2423/3621/3678 2433/3624/3729 2432/3623/3728 2422/3622/3680 -f 2424/3625/3676 2434/3628/3730 2433/3627/3729 2423/3626/3678 -f 2413/3629/3674 2431/3632/3727 2434/3631/3730 2424/3630/3676 -f 2425/3633/3721 2435/3636/3731 2436/3635/3732 2426/3634/3722 -f 2427/3637/3723 2437/3640/3733 2438/3639/3734 2428/3638/3724 -f 2428/3641/3724 2438/3644/3734 2439/3643/3735 2429/3642/3725 -f 2429/3645/3725 2439/3648/3735 2435/3647/3731 2425/3646/3721 -f 2426/3649/3722 2436/3652/3732 2440/3651/3736 2430/3650/3726 -f 2430/3653/3726 2440/3656/3736 2441/3655/3737 2431/3654/3727 -f 2432/3657/3728 2442/3660/3738 2437/3659/3733 2427/3658/3723 -f 2433/3661/3729 2443/3664/3739 2442/3663/3738 2432/3662/3728 -f 2434/3665/3730 2444/3668/3740 2443/3667/3739 2433/3666/3729 -f 2431/3669/3727 2441/3672/3737 2444/3671/3740 2434/3670/3730 -f 2435/3673/3731 2445/3676/3741 2446/3675/3742 2436/3674/3732 -f 2437/3677/3733 2447/3680/3743 2448/3679/3744 2438/3678/3734 -f 2438/3681/3734 2448/3684/3744 2449/3683/3745 2439/3682/3735 -f 2439/3685/3735 2449/3688/3745 2445/3687/3741 2435/3686/3731 -f 2436/3689/3732 2446/3692/3742 2450/3691/3746 2440/3690/3736 -f 2440/3693/3736 2450/3696/3746 2451/3695/3747 2441/3694/3737 -f 2442/3697/3738 2452/3700/3748 2447/3699/3743 2437/3698/3733 -f 2443/3701/3739 2453/3704/3749 2452/3703/3748 2442/3702/3738 -f 2444/3705/3740 2454/3708/3750 2453/3707/3749 2443/3706/3739 -f 2441/3709/3737 2451/3712/3747 2454/3711/3750 2444/3710/3740 -f 2445/3713/3741 2468/3760/3751 2467/3757/3752 2446/3714/3742 -f 2447/3717/3743 2471/3766/3753 2470/3763/3754 2448/3718/3744 -f 2448/3721/3744 2470/3764/3754 2469/3761/3755 2449/3722/3745 -f 2449/3725/3745 2469/3762/3755 2468/3759/3751 2445/3726/3741 -f 2446/3729/3742 2467/3758/3752 2466/3755/3756 2450/3730/3746 -f 2450/3733/3746 2466/3756/3756 2465/3753/3757 2451/3734/3747 -f 2452/3737/3748 2472/3768/3758 2471/3765/3753 2447/3738/3743 -f 2453/3741/3749 2473/3770/3759 2472/3767/3758 2452/3742/3748 -f 2454/3745/3750 2474/3772/3760 2473/3769/3759 2453/3746/3749 -f 2451/3749/3747 2465/3754/3757 2474/3771/3760 2454/3750/3750 -f 2466/3756/3756 2460/3736/3761 2461/3735/3762 2465/3753/3757 -f 2467/3758/3752 2456/3732/3763 2460/3731/3761 2466/3755/3756 -f 2468/3760/3751 2455/3716/3764 2456/3715/3763 2467/3757/3752 -f 2469/3762/3755 2459/3728/3765 2455/3727/3764 2468/3759/3751 -f 2470/3764/3754 2458/3724/3766 2459/3723/3765 2469/3761/3755 -f 2471/3766/3753 2457/3720/3767 2458/3719/3766 2470/3763/3754 -f 2472/3768/3758 2462/3740/3768 2457/3739/3767 2471/3765/3753 -f 2473/3770/3759 2463/3744/3769 2462/3743/3768 2472/3767/3758 -f 2474/3772/3760 2464/3748/3770 2463/3747/3769 2473/3769/3759 -f 2465/3754/3757 2461/3752/3762 2464/3751/3770 2474/3771/3760 -g default -v -4.894008 1.617534 1.828536 -v -5.223333 1.617529 1.499233 -v -5.343847 1.617529 1.049395 -v -5.223333 1.617539 0.599561 -v -4.894008 1.617524 0.270258 -v -4.444169 1.617539 0.149724 -v -3.994330 1.617524 0.270258 -v -3.665042 1.617539 0.599561 -v -3.544491 1.617529 1.049395 -v -3.665042 1.617529 1.499233 -v -3.994330 1.617534 1.828536 -v -4.444169 1.617529 1.949063 -v -4.894008 2.784924 1.828536 -v -5.223333 2.784919 1.499233 -v -5.343847 2.784919 1.049395 -v -5.223333 2.784919 0.599561 -v -4.894008 2.784913 0.270258 -v -4.444169 2.784919 0.149724 -v -3.994330 2.784913 0.270258 -v -3.665042 2.784919 0.599561 -v -3.544491 2.784919 1.049395 -v -3.665042 2.784919 1.499233 -v -3.994330 2.784924 1.828536 -v -4.444169 2.784919 1.949063 -v -4.444169 1.617529 1.049395 -v -4.878751 2.784924 1.802109 -v -5.196906 2.784919 1.483976 -v -5.313332 2.784919 1.049394 -v -5.196906 2.784919 0.614818 -v -4.878751 2.784914 0.296684 -v -4.444169 2.784919 0.180239 -v -4.009588 2.784914 0.296684 -v -3.691468 2.784919 0.614818 -v -3.575006 2.784919 1.049394 -v -3.691468 2.784919 1.483976 -v -4.009588 2.784924 1.802109 -v -4.444169 2.784919 1.918548 -v -4.721886 2.784922 1.530414 -v -5.035003 2.784919 1.332596 -v -4.444169 2.784919 1.049394 -v -5.089558 2.784919 1.049394 -v -5.038586 2.784919 0.770998 -v -4.721886 2.784915 0.568377 -v -4.410956 2.784919 0.405152 -v -4.121475 2.784915 0.490476 -v -3.924029 2.784919 0.685260 -v -3.888733 2.784919 1.049394 -v -3.919789 2.784919 1.409300 -v -4.121475 2.784922 1.608316 -v -4.407044 2.784919 1.693350 -v -4.878751 2.660097 1.802109 -v -5.196906 2.660092 1.483976 -v -5.035003 2.660092 1.332596 -v -4.721886 2.660095 1.530414 -v -4.444169 2.660092 1.918548 -v -4.407044 2.660092 1.693350 -v -5.196906 2.660092 0.614818 -v -4.878751 2.660087 0.296684 -v -4.721886 2.660088 0.568377 -v -5.038586 2.660092 0.770998 -v -4.444169 2.660092 0.180239 -v -4.410956 2.660092 0.405152 -v -3.691468 2.660092 0.614818 -v -3.575006 2.660092 1.049394 -v -3.888733 2.660092 1.049394 -v -3.924029 2.660092 0.685260 -v -3.691468 2.660092 1.483976 -v -3.919789 2.660092 1.409300 -vt 0.635316 0.078125 -vt 0.578125 0.020934 -vt 0.500000 0.000000 -vt 0.421875 0.020934 -vt 0.364684 0.078125 -vt 0.343750 0.156250 -vt 0.364684 0.234375 -vt 0.421875 0.291566 -vt 0.500000 0.312500 -vt 0.578125 0.291566 -vt 0.635316 0.234375 -vt 0.656250 0.156250 -vt 0.375000 0.312500 -vt 0.395833 0.312500 -vt 0.416667 0.312500 -vt 0.437500 0.312500 -vt 0.458333 0.312500 -vt 0.479167 0.312500 -vt 0.500000 0.312500 -vt 0.520833 0.312500 -vt 0.541667 0.312500 -vt 0.562500 0.312500 -vt 0.583333 0.312500 -vt 0.604167 0.312500 -vt 0.625000 0.312500 -vt 0.375000 0.688440 -vt 0.395833 0.688440 -vt 0.416667 0.688440 -vt 0.437500 0.688440 -vt 0.458333 0.688440 -vt 0.479167 0.688440 -vt 0.500000 0.688440 -vt 0.520833 0.688440 -vt 0.541667 0.688440 -vt 0.562500 0.688440 -vt 0.583333 0.688440 -vt 0.604167 0.688440 -vt 0.625000 0.688440 -vt 0.635316 0.765625 -vt 0.578125 0.708434 -vt 0.500000 0.687500 -vt 0.421875 0.708434 -vt 0.364684 0.765625 -vt 0.343750 0.843750 -vt 0.364684 0.921875 -vt 0.421875 0.979066 -vt 0.500000 1.000000 -vt 0.578125 0.979066 -vt 0.635316 0.921875 -vt 0.656250 0.843750 -vt 0.500000 0.150000 -vt 0.500000 0.837500 -vt 0.635316 0.921875 -vt 0.578125 0.979066 -vt 0.500000 1.000000 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.343750 0.843750 -vt 0.364684 0.765625 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.578125 0.708434 -vt 0.635316 0.765625 -vt 0.656250 0.843750 -vt 0.635316 0.921875 -vt 0.578125 0.979066 -vt 0.500000 1.000000 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.343750 0.843750 -vt 0.364684 0.765625 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.578125 0.708434 -vt 0.635316 0.765625 -vt 0.656250 0.843750 -vt 0.635316 0.921875 -vt 0.578125 0.979066 -vt 0.578125 0.979066 -vt 0.635316 0.921875 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.364684 0.921875 -vt 0.421875 0.979066 -vt 0.343750 0.843750 -vt 0.343750 0.843750 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.500000 0.687500 -vt 0.421875 0.708434 -vt 0.578125 0.708434 -vt 0.578125 0.708434 -vt 0.656250 0.843750 -vt 0.656250 0.843750 -vt 0.421875 0.979066 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.364684 0.921875 -vt 0.364684 0.921875 -vt 0.364684 0.921875 -vt 0.421875 0.979066 -vt 0.421875 0.979066 -vt 0.421875 0.979066 -vt 0.421875 0.979066 -vt 0.421875 0.979066 -vt 0.421875 0.979066 -vt 0.364684 0.921875 -vt 0.364684 0.921875 -vt 0.343750 0.843750 -vt 0.343750 0.843750 -vt 0.343750 0.843750 -vt 0.343750 0.843750 -vt 0.343750 0.843750 -vt 0.343750 0.843750 -vt 0.343750 0.843750 -vt 0.343750 0.843750 -vt 0.364684 0.921875 -vt 0.364684 0.921875 -vt 0.421875 0.708434 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.500000 0.687500 -vt 0.500000 0.687500 -vt 0.500000 0.687500 -vt 0.421875 0.708434 -vt 0.421875 0.708434 -vt 0.421875 0.708434 -vt 0.421875 0.708434 -vt 0.421875 0.708434 -vt 0.421875 0.708434 -vt 0.500000 0.687500 -vt 0.500000 0.687500 -vt 0.578125 0.708434 -vt 0.578125 0.708434 -vt 0.578125 0.708434 -vt 0.578125 0.708434 -vt 0.578125 0.708434 -vt 0.578125 0.708434 -vt 0.578125 0.708434 -vt 0.578125 0.708434 -vt 0.500000 0.687500 -vt 0.500000 0.687500 -vt 0.656250 0.843750 -vt 0.656250 0.843750 -vt 0.635316 0.921875 -vt 0.635316 0.921875 -vt 0.635316 0.921875 -vt 0.635316 0.921875 -vt 0.656250 0.843750 -vt 0.656250 0.843750 -vt 0.656250 0.843750 -vt 0.656250 0.843750 -vt 0.656250 0.843750 -vt 0.656250 0.843750 -vn -0.707082 0.000000 0.707132 -vn -0.707082 0.000000 0.707132 -vn -0.707082 0.000000 0.707132 -vn -0.707082 0.000000 0.707132 -vn -0.965937 0.000000 0.258779 -vn -0.965937 0.000000 0.258779 -vn -0.965937 0.000000 0.258779 -vn -0.965937 0.000000 0.258779 -vn -0.965936 0.000000 -0.258781 -vn -0.965936 0.000000 -0.258781 -vn -0.965936 0.000000 -0.258781 -vn -0.965936 0.000000 -0.258781 -vn -0.707082 0.000000 -0.707131 -vn -0.707082 0.000000 -0.707131 -vn -0.707082 0.000000 -0.707131 -vn -0.707082 0.000000 -0.707131 -vn -0.258819 0.000000 -0.965926 -vn -0.258819 0.000000 -0.965926 -vn -0.258819 0.000000 -0.965926 -vn -0.258819 0.000000 -0.965926 -vn 0.258819 0.000000 -0.965926 -vn 0.258819 0.000000 -0.965926 -vn 0.258819 0.000000 -0.965926 -vn 0.258819 0.000000 -0.965926 -vn 0.707122 0.000000 -0.707092 -vn 0.707122 0.000000 -0.707092 -vn 0.707122 0.000000 -0.707092 -vn 0.707122 0.000000 -0.707092 -vn 0.965916 0.000000 -0.258856 -vn 0.965916 0.000000 -0.258856 -vn 0.965916 0.000000 -0.258856 -vn 0.965916 0.000000 -0.258856 -vn 0.965917 0.000000 0.258853 -vn 0.965917 0.000000 0.258853 -vn 0.965917 0.000000 0.258853 -vn 0.965917 0.000000 0.258853 -vn 0.707122 0.000000 0.707092 -vn 0.707122 0.000000 0.707092 -vn 0.707122 0.000000 0.707092 -vn 0.707122 0.000000 0.707092 -vn 0.258805 0.000000 0.965930 -vn 0.258805 0.000000 0.965930 -vn 0.258805 0.000000 0.965930 -vn 0.258805 0.000000 0.965930 -vn -0.258805 0.000000 0.965930 -vn -0.258805 0.000000 0.965930 -vn -0.258805 0.000000 0.965930 -vn -0.258805 0.000000 0.965930 -vn 0.000003 -1.000000 0.000005 -vn -0.000000 -1.000000 -0.000000 -vn -0.000003 -1.000000 0.000005 -vn 0.000000 -1.000000 -0.000011 -vn -0.000012 -1.000000 0.000000 -vn 0.000003 -1.000000 0.000005 -vn -0.000000 -1.000000 -0.000011 -vn -0.000003 -1.000000 0.000005 -vn 0.000012 -1.000000 0.000000 -vn 0.000000 -1.000000 -0.000010 -vn -0.000003 -1.000000 0.000005 -vn 0.000003 -1.000000 0.000005 -vn 0.000000 -1.000000 0.000000 -vn 0.000003 1.000000 -0.000006 -vn 0.000000 1.000000 -0.000004 -vn -0.000002 1.000000 -0.000005 -vn 0.000000 1.000000 -0.000000 -vn 0.000002 1.000000 -0.000005 -vn -0.000003 1.000000 -0.000006 -vn 0.000002 1.000000 0.000000 -vn 0.000003 1.000000 -0.000005 -vn -0.000004 1.000000 -0.000006 -vn 0.000000 1.000000 -0.000000 -vn 0.000004 1.000000 -0.000006 -vn -0.000003 1.000000 -0.000005 -vn -0.000002 1.000000 0.000000 -vn -0.000005 1.000000 -0.000004 -vn -0.000005 1.000000 -0.000004 -vn -0.000005 1.000000 -0.000004 -vn -0.000005 1.000000 -0.000004 -vn 0.000000 1.000000 -0.000002 -vn 0.000000 1.000000 -0.000002 -vn 0.000000 1.000000 -0.000002 -vn 0.000000 1.000000 -0.000002 -vn 0.000000 1.000000 0.000002 -vn 0.000000 1.000000 0.000002 -vn 0.000000 1.000000 0.000002 -vn 0.000000 1.000000 0.000002 -vn 0.000005 1.000000 -0.000009 -vn 0.000005 1.000000 -0.000009 -vn 0.000005 1.000000 -0.000009 -vn 0.000005 1.000000 -0.000009 -vn -0.000012 1.000000 0.000000 -vn -0.000012 1.000000 0.000000 -vn -0.000012 1.000000 0.000000 -vn -0.000012 1.000000 0.000000 -vn 0.000012 1.000000 0.000000 -vn 0.000012 1.000000 0.000000 -vn 0.000012 1.000000 0.000000 -vn 0.000012 1.000000 0.000000 -vn -0.000005 1.000000 -0.000004 -vn -0.000005 1.000000 -0.000004 -vn -0.000005 1.000000 -0.000004 -vn -0.000005 1.000000 -0.000004 -vn 0.000000 1.000000 -0.000002 -vn 0.000000 1.000000 -0.000002 -vn 0.000000 1.000000 -0.000002 -vn 0.000000 1.000000 -0.000002 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000005 1.000000 -0.000013 -vn 0.000005 1.000000 -0.000013 -vn 0.000005 1.000000 -0.000013 -vn 0.000005 1.000000 -0.000013 -vn -0.000012 1.000000 0.000000 -vn -0.000012 1.000000 0.000000 -vn -0.000012 1.000000 0.000000 -vn -0.000012 1.000000 0.000000 -vn 0.000012 1.000000 0.000000 -vn 0.000012 1.000000 0.000000 -vn 0.000012 1.000000 0.000000 -vn 0.000012 1.000000 0.000000 -vn -0.000007 1.000000 -0.000008 -vn -0.000007 1.000000 -0.000008 -vn -0.000007 1.000000 -0.000008 -vn -0.000007 1.000000 -0.000008 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000007 1.000000 -0.000009 -vn 0.000007 1.000000 -0.000009 -vn 0.000007 1.000000 -0.000009 -vn 0.000007 1.000000 -0.000009 -vn -0.000011 1.000000 0.000001 -vn -0.000011 1.000000 0.000001 -vn -0.000011 1.000000 0.000001 -vn -0.000011 1.000000 0.000001 -vn 0.000012 1.000000 -0.000001 -vn 0.000012 1.000000 -0.000001 -vn 0.000012 1.000000 -0.000001 -vn 0.000012 1.000000 -0.000001 -vn -0.000005 1.000000 -0.000012 -vn -0.000005 1.000000 -0.000012 -vn -0.000005 1.000000 -0.000012 -vn -0.000005 1.000000 -0.000012 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000006 1.000000 -0.000013 -vn 0.000006 1.000000 -0.000013 -vn 0.000006 1.000000 -0.000013 -vn 0.000006 1.000000 -0.000013 -vn -0.000012 1.000000 0.000000 -vn -0.000012 1.000000 0.000000 -vn -0.000012 1.000000 0.000000 -vn -0.000012 1.000000 0.000000 -vn 0.000011 1.000000 0.000002 -vn 0.000011 1.000000 0.000002 -vn 0.000011 1.000000 0.000002 -vn 0.000011 1.000000 0.000002 -vn 0.707082 0.000000 -0.707132 -vn 0.707082 0.000000 -0.707132 -vn 0.707082 0.000000 -0.707132 -vn 0.707082 0.000000 -0.707132 -vn 0.682971 0.000000 0.730446 -vn 0.682971 0.000000 0.730446 -vn 0.682971 0.000000 0.730446 -vn 0.682971 0.000000 0.730446 -vn -0.534109 0.000000 0.845415 -vn -0.534109 0.000000 0.845415 -vn -0.534109 0.000000 0.845415 -vn -0.534109 0.000000 0.845415 -vn 0.258805 0.000000 -0.965930 -vn 0.258805 0.000000 -0.965930 -vn 0.258805 0.000000 -0.965930 -vn 0.258805 0.000000 -0.965930 -vn -0.459615 0.000000 0.888118 -vn -0.459615 0.000000 0.888118 -vn -0.459615 0.000000 0.888118 -vn -0.459615 0.000000 0.888118 -vn -0.986682 0.000000 -0.162660 -vn -0.986682 0.000000 -0.162660 -vn -0.986682 0.000000 -0.162660 -vn -0.986682 0.000000 -0.162660 -vn 0.707082 0.000000 0.707132 -vn 0.707082 0.000000 0.707132 -vn 0.707082 0.000000 0.707132 -vn 0.707082 0.000000 0.707132 -vn -0.538927 0.000000 -0.842353 -vn -0.538927 0.000000 -0.842352 -vn -0.538927 0.000000 -0.842353 -vn -0.538927 0.000000 -0.842352 -vn 0.702281 0.000000 -0.711900 -vn 0.702281 0.000000 -0.711900 -vn 0.702281 0.000000 -0.711900 -vn 0.702281 0.000000 -0.711900 -vn 0.258819 0.000000 0.965926 -vn 0.258819 0.000000 0.965926 -vn 0.258819 0.000000 0.965926 -vn 0.258819 0.000000 0.965926 -vn -0.989272 0.000000 0.146089 -vn -0.989272 0.000000 0.146089 -vn -0.989272 0.000000 0.146089 -vn -0.989272 0.000000 0.146089 -vn -0.464804 0.000000 -0.885414 -vn -0.464804 0.000000 -0.885414 -vn -0.464804 0.000000 -0.885414 -vn -0.464804 0.000000 -0.885414 -vn -0.965916 0.000000 0.258856 -vn -0.965916 0.000000 0.258856 -vn -0.965916 0.000000 0.258856 -vn -0.965916 0.000000 0.258856 -vn 0.995335 0.000000 -0.096480 -vn 0.995335 0.000000 -0.096480 -vn 0.995335 0.000000 -0.096480 -vn 0.995335 0.000000 -0.096480 -vn 0.289890 0.000000 0.957060 -vn 0.289890 0.000000 0.957060 -vn 0.289890 0.000000 0.957060 -vn 0.289890 0.000000 0.957060 -vn -0.965917 0.000000 -0.258853 -vn -0.965917 0.000000 -0.258853 -vn -0.965917 0.000000 -0.258853 -vn -0.965917 0.000000 -0.258853 -vn 0.310860 0.000000 -0.950456 -vn 0.310860 0.000000 -0.950456 -vn 0.310860 0.000000 -0.950456 -vn 0.310860 0.000000 -0.950456 -vn 0.996298 0.000000 0.085968 -vn 0.996298 0.000000 0.085968 -vn 0.996298 0.000000 0.085968 -vn 0.996298 0.000000 0.085968 -s off -g wheel_BL_geo -usemtl blinn2SG -f 2475/3785/3771 2487/3798/3772 2488/3799/3773 2476/3786/3774 -f 2476/3786/3775 2488/3799/3776 2489/3800/3777 2477/3787/3778 -f 2477/3787/3779 2489/3800/3780 2490/3801/3781 2478/3788/3782 -f 2478/3788/3783 2490/3801/3784 2491/3802/3785 2479/3789/3786 -f 2479/3789/3787 2491/3802/3788 2492/3803/3789 2480/3790/3790 -f 2480/3790/3791 2492/3803/3792 2493/3804/3793 2481/3791/3794 -f 2481/3791/3795 2493/3804/3796 2494/3805/3797 2482/3792/3798 -f 2482/3792/3799 2494/3805/3800 2495/3806/3801 2483/3793/3802 -f 2483/3793/3803 2495/3806/3804 2496/3807/3805 2484/3794/3806 -f 2484/3794/3807 2496/3807/3808 2497/3808/3809 2485/3795/3810 -f 2485/3795/3811 2497/3808/3812 2498/3809/3813 2486/3796/3814 -f 2486/3796/3815 2498/3809/3816 2487/3810/3817 2475/3797/3818 -s 1 -f 2476/3774/3819 2499/3823/3820 2475/3773/3821 -f 2477/3775/3822 2499/3823/3820 2476/3774/3819 -f 2478/3776/3823 2499/3823/3820 2477/3775/3822 -f 2479/3777/3824 2499/3823/3820 2478/3776/3823 -f 2480/3778/3825 2499/3823/3820 2479/3777/3824 -f 2481/3779/3826 2499/3823/3820 2480/3778/3825 -f 2482/3780/3827 2499/3823/3820 2481/3779/3826 -f 2483/3781/3828 2499/3823/3820 2482/3780/3827 -f 2484/3782/3829 2499/3823/3820 2483/3781/3828 -f 2485/3783/3830 2499/3823/3820 2484/3782/3829 -f 2486/3784/3831 2499/3823/3820 2485/3783/3830 -f 2475/3773/3821 2499/3823/3820 2486/3784/3831 -s 2 -f 2512/3837/3832 2514/3824/3833 2513/3838/3834 -f 2513/3838/3834 2514/3824/3833 2515/3839/3835 -f 2515/3839/3835 2514/3824/3833 2516/3840/3836 -f 2516/3840/3836 2514/3824/3833 2517/3841/3837 -f 2517/3841/3837 2514/3824/3833 2518/3842/3838 -f 2518/3842/3838 2514/3824/3833 2519/3843/3839 -f 2519/3843/3839 2514/3824/3833 2520/3844/3840 -f 2520/3844/3840 2514/3824/3833 2521/3845/3841 -f 2521/3845/3841 2514/3824/3833 2522/3846/3842 -f 2522/3846/3842 2514/3824/3833 2523/3847/3843 -f 2523/3847/3843 2514/3824/3833 2524/3848/3844 -f 2524/3848/3844 2514/3824/3833 2512/3837/3832 -s off -f 2487/3821/3845 2500/3825/3846 2501/3826/3847 2488/3820/3848 -f 2488/3820/3849 2501/3826/3850 2502/3827/3851 2489/3819/3852 -f 2489/3819/3853 2502/3827/3854 2503/3828/3855 2490/3818/3856 -f 2490/3818/3857 2503/3828/3858 2504/3829/3859 2491/3817/3860 -f 2491/3817/3861 2504/3829/3862 2505/3830/3863 2492/3816/3864 -f 2492/3816/3865 2505/3830/3866 2506/3831/3867 2493/3815/3868 -f 2493/3815/3869 2506/3831/3870 2507/3832/3871 2494/3814/3872 -f 2494/3814/3873 2507/3832/3874 2508/3833/3875 2495/3813/3876 -f 2495/3813/3877 2508/3833/3878 2509/3834/3879 2496/3812/3880 -f 2496/3812/3881 2509/3834/3882 2510/3835/3883 2497/3811/3884 -f 2497/3811/3885 2510/3835/3886 2511/3836/3887 2498/3822/3888 -f 2498/3822/3889 2511/3836/3890 2500/3825/3891 2487/3821/3892 -f 2525/3849/3893 2528/3852/3894 2527/3851/3895 2526/3850/3896 -f 2501/3826/3897 2513/3838/3898 2515/3839/3899 2502/3827/3900 -f 2502/3827/3901 2515/3839/3902 2516/3840/3903 2503/3828/3904 -f 2531/3853/3905 2534/3856/3906 2533/3855/3907 2532/3854/3908 -f 2532/3854/3909 2533/3855/3910 2536/3858/3911 2535/3857/3912 -f 2505/3830/3913 2518/3842/3914 2519/3843/3915 2506/3831/3916 -f 2506/3831/3917 2519/3843/3918 2520/3844/3919 2507/3832/3920 -f 2537/3859/3921 2540/3862/3922 2539/3861/3923 2538/3860/3924 -f 2538/3860/3925 2539/3861/3926 2542/3864/3927 2541/3863/3928 -f 2509/3834/3929 2522/3846/3930 2523/3847/3931 2510/3835/3932 -f 2510/3835/3933 2523/3847/3934 2524/3848/3935 2511/3836/3936 -f 2529/3865/3937 2530/3866/3938 2528/3852/3939 2525/3849/3940 -f 2500/3825/3941 2525/3849/3942 2526/3850/3943 2501/3826/3944 -f 2501/3826/3945 2526/3850/3946 2527/3851/3947 2513/3838/3948 -f 2513/3838/3949 2527/3851/3950 2528/3852/3951 2512/3837/3952 -f 2511/3867/3953 2529/3868/3954 2525/3869/3955 2500/3870/3956 -f 2512/3871/3957 2528/3872/3958 2530/3873/3959 2524/3874/3960 -f 2524/3875/3961 2530/3876/3962 2529/3877/3963 2511/3878/3964 -f 2503/3879/3965 2531/3880/3966 2532/3881/3967 2504/3882/3968 -f 2517/3883/3969 2533/3884/3970 2534/3885/3971 2516/3886/3972 -f 2516/3887/3973 2534/3888/3974 2531/3889/3975 2503/3890/3976 -f 2504/3891/3977 2532/3892/3978 2535/3893/3979 2505/3894/3980 -f 2505/3895/3981 2535/3896/3982 2536/3897/3983 2518/3898/3984 -f 2518/3899/3985 2536/3900/3986 2533/3901/3987 2517/3902/3988 -f 2507/3903/3989 2537/3904/3990 2538/3905/3991 2508/3906/3992 -f 2521/3907/3993 2539/3908/3994 2540/3909/3995 2520/3910/3996 -f 2520/3911/3997 2540/3912/3998 2537/3913/3999 2507/3914/4000 -f 2508/3915/4001 2538/3916/4002 2541/3917/4003 2509/3918/4004 -f 2509/3919/4005 2541/3920/4006 2542/3921/4007 2522/3922/4008 -f 2522/3923/4009 2542/3924/4010 2539/3925/4011 2521/3926/4012 diff --git a/anki_vector/opengl/opengl.py b/anki_vector/opengl/opengl.py deleted file mode 100644 index b950578..0000000 --- a/anki_vector/opengl/opengl.py +++ /dev/null @@ -1,864 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""This module provides 3D support classes for OpenGL, used by opengl_viewer.py. - -It uses PyOpenGL, a Python OpenGL 3D graphics library which is available on most -platforms. It also depends on the Pillow library for image processing. - -Warning: - This package requires Python to have the PyOpenGL package installed, along - with an implementation of GLUT (OpenGL Utility Toolkit). - - To install the Python packages on Mac and Linux do ``python3 -m pip install --user "anki_vector[3dviewer]"`` - - To install the Python packages on Windows do ``py -3 -m pip install --user "anki_vector[3dviewer]"`` - - On Windows and Linux you must also install freeglut (macOS / OSX has one - preinstalled). - - On Linux: ``sudo apt-get install freeglut3`` - - On Windows: Go to http://freeglut.sourceforge.net/ to get a ``freeglut.dll`` - file. It's included in any of the `Windows binaries` downloads. Place the DLL - next to your Python script, or install it somewhere in your PATH to allow any - script to use it." -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['Camera', 'DynamicTexture', 'MaterialLibrary', 'MeshData', 'MeshFace', 'MeshGroup', 'OpenGLWindow', - 'PrecomputedView', 'ResourceManager', - 'raise_opengl_or_pillow_import_error'] - -import math -import sys -from typing import List, Dict - -from pkg_resources import resource_stream - -from anki_vector import util - - -class InvalidOpenGLGlutImplementation(ImportError): - """Raised by OpenGLViewer if no valid GLUT implementation available.""" - - -#: Adds context to exceptions raised from attempts to import OpenGL libraries -def raise_opengl_or_pillow_import_error(opengl_import_exc): - if isinstance(opengl_import_exc, InvalidOpenGLGlutImplementation): - raise NotImplementedError('GLUT (OpenGL Utility Toolkit) is not available:\n%s' - % opengl_import_exc) - else: - raise NotImplementedError('OpenGL is not available; ' - 'make sure the PyOpenGL and Pillow packages are installed:\n' - 'Do `pip3 install --user "anki_vector[3dviewer]"` to install. Error: %s' % opengl_import_exc) - - -try: - from OpenGL.GL import (GL_AMBIENT, GL_AMBIENT_AND_DIFFUSE, GL_CCW, GL_COLOR_BUFFER_BIT, GL_COMPILE, GL_DEPTH_BUFFER_BIT, GL_DEPTH_TEST, GL_DIFFUSE, - GL_FRONT, GL_LIGHT0, GL_LINEAR, GL_MODELVIEW, GL_POLYGON, GL_PROJECTION, GL_POSITION, GL_RGBA, GL_SHININESS, GL_SMOOTH, GL_SPECULAR, - GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER, GL_UNSIGNED_BYTE, - glBegin, glBindTexture, glCallList, glClear, glClearColor, glColor, glDisable, glEnable, - glEnd, glEndList, glFrontFace, glGenLists, glGenTextures, glLoadIdentity, glLightfv, glMaterialfv, glMatrixMode, glNewList, - glNormal3fv, glScalef, glShadeModel, glTexCoord2fv, glTexImage2D, glTexParameteri, - glTexSubImage2D, glVertex3fv, glViewport) - from OpenGL.GLU import gluLookAt, gluPerspective - from OpenGL.GLUT import (glutCreateWindow, glutDisplayFunc, glutIdleFunc, glutInit, glutInitDisplayMode, - glutInitWindowPosition, glutInitWindowSize, glutPostRedisplay, glutReshapeFunc, - glutSetWindow, glutSwapBuffers, glutVisibilityFunc, - GLUT_DEPTH, GLUT_DOUBLE, GLUT_RGB, GLUT_VISIBLE) - from OpenGL.error import NullFunctionError - - from PIL import Image - -except ImportError as import_exc: - raise_opengl_or_pillow_import_error(import_exc) - - -# Check if OpenGL imported correctly and bound to a valid GLUT implementation - - -def _glut_install_instructions(): - if sys.platform.startswith('linux'): - return "Install freeglut: `sudo apt-get install freeglut3`" - if sys.platform.startswith('darwin'): - return "GLUT should already be installed by default on macOS!" - if sys.platform in ('win32', 'cygwin'): - return "Install freeglut: You can download it from http://freeglut.sourceforge.net/ \n"\ - "You just need the `freeglut.dll` file, from any of the 'Windows binaries' downloads. "\ - "Place the DLL next to your Python script, or install it somewhere in your PATH "\ - "to allow any script to use it." - return "(Instructions unknown for platform %s)" % sys.platform - - -def _verify_glut_init(): - # According to the documentation, just checking bool(glutInit) is supposed to be enough - # However on Windows with no GLUT DLL that can still pass, even if calling the method throws a null function error. - if bool(glutInit): - try: - glutInit() - return True - except NullFunctionError as _: - pass - - return False - - -if not _verify_glut_init(): - raise InvalidOpenGLGlutImplementation(_glut_install_instructions()) - - -class ResourceManager(): - """Handles returning file resources by keys. The current implementation delegates to resource_stream - directly. - - :param context_id: Key used for identifying this context - """ - - def __init__(self, context_id: str): - self._context_id = context_id - - @property - def context_id(self) -> str: - """Key used for identifying this context.""" - return self._context_id - - def load(self, *args: str): - """Loads a resource given a groups of key arguments. - - Since the resource_stream path is non_stantard with os.path.join, this resolve is encapsulated inside - the resource manager. The context that these resources are files on disk is similarly encapsulated. - All client classes only need match keys with returned data. - - :param args: string keys for identifying the asset. - """ - resource_path = '/'.join(map(str, args)) # Note: Deliberately not os.path.join, for use with pkg_resources - return resource_stream(self._context_id, resource_path) - - -class DynamicTexture: - """Wrapper around An OpenGL Texture that can be dynamically updated.""" - - def __init__(self): - self._texId = glGenTextures(1) - self._width = None - self._height = None - # Bind an ID for this texture - glBindTexture(GL_TEXTURE_2D, self._texId) - # Use bilinear filtering if the texture has to be scaled - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) - - def bind(self): - """Bind the texture for rendering.""" - glBindTexture(GL_TEXTURE_2D, self._texId) - - def update(self, pil_image: Image.Image): - """Update the texture to contain the provided image. - - :param pil_image: The image to write into the texture. - """ - # Ensure the image is in RGBA format and convert to the raw RGBA bytes. - image_width, image_height = pil_image.size - image = pil_image.convert("RGBA").tobytes("raw", "RGBA") - - # Bind the texture so that it can be modified. - self.bind() - if (self._width == image_width) and (self._height == image_height): - # Same size - just need to update the texels. - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height, - GL_RGBA, GL_UNSIGNED_BYTE, image) - else: - # Different size than the last frame (e.g. the Window is resizing) - # Create a new texture of the correct size. - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width, image_height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, image) - - self._width = image_width - self._height = image_height - - -class MaterialLibrary(): # pylint: disable=too-few-public-methods - """Load a .mtl material asset, and return the contents as a dictionary. - - Supports the subset of MTL required for the Vector 3D Viewer assets. - - :param resource_manager: Manager to load resources from. - :param asset_key: The key of the asset to load. - """ - - def __init__(self, resource_context: ResourceManager, asset_key: str): - self._contents = {} - current_mtl: dict = None - - file_data = resource_context.load('assets', asset_key) - - for line in file_data: - line = line.decode("utf-8") # Convert bytes line to a string - if line.startswith('#'): - # Ignore comments in the file. - continue - - values = line.split() - if not values: - # Ignore empty lines. - continue - - attribute_name = values[0] - if attribute_name == 'newmtl': - # Create a new empty material. - current_mtl = self._contents[values[1]] = {} - elif current_mtl is None: - raise ValueError("mtl file must start with newmtl statement") - elif attribute_name == 'map_Kd': - # Diffuse texture map - load the image into memory. - image_name = values[1] - image_file_data = resource_context.load('assets', image_name) - with Image.open(image_file_data) as image: - image_width, image_height = image.size - image = image.convert("RGBA").tobytes("raw", "RGBA") - - # Bind the image as a texture that can be used for rendering. - texture_id = glGenTextures(1) - current_mtl['texture_Kd'] = texture_id # pylint: disable=unsupported-assignment-operation - - glBindTexture(GL_TEXTURE_2D, texture_id) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width, image_height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, image) - else: - # Store the values for this attribute as a list of float values. - current_mtl[attribute_name] = list(map(float, values[1:])) # pylint: disable=unsupported-assignment-operation - - def get_material_by_name(self, name: str) -> dict: - """Returns a dict of material attributes""" - return self._contents[name] - - -class MeshFace(): - """A face polygon in 3d space - the basic building block of 3D models. - - The actual coordinate data is stored in tables on the host mesh, the face contains - indexes to those table denoting which values should be used in rendering. - - :param position_ids: Worldspace position ids on the host mesh for this face's vertices. - :param normal_ids: Normal direction ids on the host mesh for this face's vertices. - :param tex_ids: Texture coordinate ids on the host mesh for this face's vertices. - :param active_material: Material name used to render this face. - """ - - def __init__(self, position_ids: List[int], normal_ids: List[int], tex_ids: List[int], active_material: str): - self._position_ids = position_ids - self._normal_ids = normal_ids - self._tex_ids = tex_ids - - self._vertex_count = len(position_ids) - - self._material = active_material - - @property - def position_ids(self) -> List[int]: - """Worldspace position ids on the host mesh for this face's vertices.""" - return self._position_ids - - @property - def normal_ids(self) -> List[int]: - """Normal direction ids on the host mesh for this face's vertices.""" - return self._normal_ids - - @property - def tex_ids(self) -> List[int]: - """Texture coordinate ids on the host mesh for this face's vertices.""" - return self._tex_ids - - @property - def material(self) -> str: - """Material name used to render this face.""" - return self._material - - @property - def vertex_count(self) -> int: - """The number of vertices on this face - will be either 3 for a triangle, or 4 for a quad""" - return self._vertex_count - - -class MeshGroup(): - """A colletions of face polygons which can be rendered as a group by name. - - :param name: The name associated with this part of the 3d mesh collection. - """ - - def __init__(self, name: str): - self._name = name - self._faces: List(MeshFace) = [] - - @property - def name(self) -> str: - """The name associated with the mesh group.""" - return self._name - - @property - def faces(self) -> List[MeshFace]: - """All faces associated with the mesh group.""" - return self._faces - - def add_face_by_obj_data(self, source_values: list, active_material: str): - """Adds a new face to the mesh group. - - Face source data is made up of 3 or 4 vertices - - e.g. `f v1 v2 v3` or `f v1 v2 v3 v4` - - where each vertex definition is multiple indexes seperated by - slashes and can follow the following formats: - - position_index - position_index/tex_coord_index - position_index/tex_coord_index/normal_index - position_index//normal_index - - :param source_values: obj data to parse for this face - :param active_material: the material used to render this face - """ - - position_ids: List(int) = [] - normal_ids: List(int) = [] - tex_ids: List(int) = [] - - for vertex in source_values: - vertex_components = vertex.split('/') - - position_ids.append(int(vertex_components[0])) - - # There's only a texture coordinate if there's at least 2 entries and the 2nd entry is non-zero length - if len(vertex_components) >= 2 and vertex_components[1]: - tex_ids.append(int(vertex_components[1])) - else: - # OBJ file indexing starts at 1, so use 0 to indicate no entry - tex_ids.append(0) - - # There's only a normal if there's at least 2 entries and the 2nd entry is non-zero length - if len(vertex_components) >= 3 and vertex_components[2]: - normal_ids.append(int(vertex_components[2])) - else: - # OBJ file indexing starts at 1, so use 0 to indicate no entry - normal_ids.append(0) - - self._faces.append(MeshFace(position_ids, normal_ids, tex_ids, active_material)) - - -class MeshData(): - """The loaded / parsed contents of a 3D Wavefront OBJ file. - - This is the intermediary step between the file on the disk, and a renderable - 3D object. It supports the subset of the OBJ file that was used in the - Vector and Cube assets, and does not attempt to exhaustively support every - possible setting. - - :param resource_manager: The resource manager to load this mesh from. - :param asset_key: The key of the OBJ file to load from the resource manager. - """ - - def __init__(self, resource_manager: ResourceManager, asset_key: str): - - # All worldspace vertex positions in this mesh (coordinates stored as list of 3 floats). - self._vertices: List[List[float]] = [] - # All directional vertex normals in this mesh (coordinates stored as list of 3 floats). - self._normals: List[List[float]] = [] - # All texture coordinates in this mesh (coordinates stored as list of 2 floats). - self._tex_coords: List[List[float]] = [] - - # All supported mesh groups, indexed by group name. - self._groups: Dict[str, MeshGroup] = {} - - # A container that MTL material attribute dicts can be fetched from by string key. - self._material_library: MaterialLibrary = None - - # Resource manager that can be used to load internally referenced assets - self._resource_manager = resource_manager - - self._logger = util.get_class_logger(__name__, self) - - self.load_from_obj_asset(asset_key) - - @property - def vertices(self) -> List[List[float]]: - """All worldspace vertex positions in this mesh.""" - return self._vertices - - @property - def normals(self) -> List[List[float]]: - """All directional vertex normals in this mesh.""" - return self._normals - - @property - def tex_coords(self) -> List[List[float]]: - """All texture coordinates in this mesh.""" - return self._tex_coords - - @property - def groups(self) -> Dict[str, MeshGroup]: - """All supported mesh groups, indexed by group name.""" - return self._groups - - @property - def material_library(self) -> MaterialLibrary: - """A container that MTL material attribute dicts can be fetched from by string key.""" - return self._material_library - - def load_from_obj_asset(self, asset_key: str): # pylint: disable=too-many-branches - """Loads all mesh data from a specified resource. - - :param asset_key: Key for the desired OBJ asset in the resource_manager. - """ - active_group_name: str = None - active_material: str = None - - file_data = self._resource_manager.load('assets', asset_key) - - for data_entry in file_data: - - line = data_entry.decode("utf-8") # Convert bytes to string - if line.startswith('#'): - # ignore comments in the file - continue - - values = line.split() - if not values: - # ignore empty lines - continue - - if values[0] == 'v': - # vertex position - v = list(map(float, values[1:4])) - self._vertices.append(v) - elif values[0] == 'vn': - # vertex normal - v = list(map(float, values[1:4])) - self._normals.append(v) - elif values[0] == 'vt': - # texture coordinate - v = list(map(float, values[1:3])) - self._tex_coords.append(v) - elif values[0] in ('usemtl', 'usemat'): - # material - active_material = values[1] - elif values[0] == 'mtllib': - # material library (a filename) - self._material_library = MaterialLibrary(self._resource_manager, values[1]) - elif values[0] == 'f': - if active_group_name not in self._groups: - self._groups[active_group_name] = MeshGroup(active_group_name) - - group = self._groups[active_group_name] - group.add_face_by_obj_data(values[1:], active_material) - - elif values[0] == 'o': - # object name - ignore - continue - elif values[0] == 'g': - # group name (for a sub-mesh) - active_group_name = values[1] - elif values[0] == 's': - # smooth shading (1..20, and 'off') - ignore - continue - else: - self._logger.warning("LoadedObjFile Ignoring unhandled type '%s' in line %s", - values[0], values) - - -class PrecomputedView(): - """A collection of static 3D object which are pre-computed on the graphics card, so they can - be quickly drawn when needed.""" - - def __init__(self): - self._display_lists = {} - - @staticmethod - def _apply_material(material: dict): - """Utility function to apply a specific MTL material to the current - OpenGL rendering state. - - :param material: A dictionary of MTL attributes defining a material. - """ - def _as_rgba(color): - if len(color) >= 4: - return color - # RGB - add alpha defaulted to 1 - return color + [1.0] - - if 'texture_Kd' in material: - # use diffuse texture map - glBindTexture(GL_TEXTURE_2D, material['texture_Kd']) - else: - # No texture map - glBindTexture(GL_TEXTURE_2D, 0) - - # Diffuse light - mtl_kd_rgba = _as_rgba(material['Kd']) - glColor(mtl_kd_rgba) - - # Ambient light - if 'Ka' in material: - mtl_ka_rgba = _as_rgba(material['Ka']) - glMaterialfv(GL_FRONT, GL_AMBIENT, mtl_ka_rgba) - glMaterialfv(GL_FRONT, GL_DIFFUSE, mtl_kd_rgba) - else: - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mtl_kd_rgba) - - # Specular light - if 'Ks' in material: - mtl_ks_rgba = _as_rgba(material['Ks']) - glMaterialfv(GL_FRONT, GL_SPECULAR, mtl_ks_rgba) - if 'Ns' in material: - specular_exponent = material['Ns'] - glMaterialfv(GL_FRONT, GL_SHININESS, specular_exponent) - - def build_from_mesh_data(self, mesh_data: MeshData): - """Uses a loaded mesh to create 3d geometry to store in the view. - - All groups in the mesh will pre-computed and stored by name. - - :param mesh_data: the source data that 3d geometry will be pre-computed from. - """ - material_library = mesh_data.material_library - - for key in mesh_data.groups: - new_gl_list = glGenLists(1) # pylint: disable=assignment-from-no-return - glNewList(new_gl_list, GL_COMPILE) - - group = mesh_data.groups[key] - - glEnable(GL_TEXTURE_2D) - glFrontFace(GL_CCW) - - for face in group.faces: - self._apply_material(material_library.get_material_by_name(face.material)) - - # Polygon (N verts) with optional normals and tex coords - glBegin(GL_POLYGON) - for i in range(face.vertex_count): - normal_index = face.normal_ids[i] - if normal_index > 0: - glNormal3fv(mesh_data.normals[normal_index - 1]) - tex_coord_index = face.tex_ids[i] - if tex_coord_index > 0: - glTexCoord2fv(mesh_data.tex_coords[tex_coord_index - 1]) - glVertex3fv(mesh_data.vertices[face.position_ids[i] - 1]) - glEnd() - - glDisable(GL_TEXTURE_2D) - glEndList() - - self._display_lists[key] = new_gl_list - - def build_from_render_function(self, name: str, f: callable, *args): - """Uses an externally provided function to create 3d geometry to store in the view. - - :param name: the key this pre-computed geometry can be draw from. - :param f: the function used to create the 3d geometry. - :param args: any parameters the supplied function is expecting. - """ - new_gl_list = glGenLists(1) # pylint: disable=assignment-from-no-return - glNewList(new_gl_list, GL_COMPILE) - f(*args) - glEndList() - - self._display_lists[name] = new_gl_list - - def display_by_key(self, key: str): - """Renders a specific piece of geometry from the view collection. - - :param key: The pre-computed object to render. - """ - try: - glCallList(self._display_lists[key]) - except KeyError: - raise KeyError('No display list with key {0} present on PrerenderedView'.format(key)) - - def display_all(self): - """Renders all pre-computed geometry in the view collection.""" - for display_list in self._display_lists.values(): - glCallList(display_list) - - -class Camera(): - """Class containing the state of a 3d camera, used to transform all object in a scene with - relation to a particular point of view. - - This class is meant to be mutated at run time. - - :param look_at: The initial target of the camera. - :param up: The initial up vector of the camera. - :param distance: The initial distance between the camera and it's target. - :param pitch: The camera's current rotation about its X axis - :param yaw: The camera's current rotation about its up axis - """ - - def __init__(self, look_at: util.Vector3, up: util.Vector3, distance: float, pitch: float, yaw: float): - # Camera position and orientation defined by a look-at positions - # and a pitch/and yaw to rotate around that along with a distance - self._look_at = look_at - self._pitch = pitch - self._yaw = yaw - self._distance = distance - self._pos = util.Vector3(0, 0, 0) - self._up = up - self._update_pos() - - @property - def look_at(self) -> util.Vector3: - """The target position of the camera""" - return self._look_at - - @look_at.setter - def look_at(self, look_at): - self._look_at = look_at - - def move(self, forward_amount: float = 0.0, right_amount: float = 0.0, up_amount: float = 0.0): - """Offsets the camera's position incrementally. - - :param forward_amount: distance to move along the camera's current forward heading. - :param right_amount: distance to move along a right angle to the camera's current forward heading. - :param up_amount: distance to move along the camera's up vector. - """ - self._look_at += self._up * up_amount - - # Move forward/back and left/right - pitch = self._pitch - yaw = self._yaw - camera_offset = util.Vector3(math.cos(yaw), math.sin(yaw), math.sin(pitch)) - - heading = math.atan2(camera_offset.y, camera_offset.x) - half_pi = math.pi * 0.5 - - self._look_at += util.Vector3( - right_amount * math.cos(heading + half_pi), - right_amount * math.sin(heading + half_pi), - 0.0) - - self._look_at += util.Vector3( - forward_amount * math.cos(heading), - forward_amount * math.sin(heading), - 0.0) - - def zoom(self, amount: float): - """Moves the camera closer or further from it's target point. - - :param amount: distance to zoom in or out, automatically minimized at 0.1 - """ - self._distance = max(0.1, self._distance + amount) - - def turn(self, yaw_delta: float, pitch_delta: float): - """Incrementally turns the camera. - - :param yaw_delta: Amount to rotate around the camera's up axis. - :param pitch_delta: Amount to rotate around the camera's X axis. This is automatically capped between +/- pi/2 - """ - # Adjust the Camera pitch and yaw - self._pitch = (self._pitch - pitch_delta) - self._yaw = (self._yaw + yaw_delta) % (2.0 * math.pi) - - # Clamp pitch to slightyly less than pi/2 to avoid lock/errors at full up/down - max_rotation = math.pi * 0.49 - self._pitch = max(-max_rotation, min(max_rotation, self._pitch)) - - def _update_pos(self): - """Calculate camera position based on look-at, distance and angles.""" - cos_pitch = math.cos(self._pitch) - sin_pitch = math.sin(self._pitch) - cos_yaw = math.cos(self._yaw) - sin_yaw = math.sin(self._yaw) - cam_distance = self._distance - cam_look_at = self._look_at - - self._pos = util.Vector3( - cam_look_at.x + (cam_distance * cos_pitch * cos_yaw), - cam_look_at.y + (cam_distance * cos_pitch * sin_yaw), - cam_look_at.z + (cam_distance * sin_pitch)) - - def apply(self): - """Applies the transform this camera represents to the active OpenGL context.""" - self._update_pos() - - gluLookAt(*self._pos.x_y_z, - *self._look_at.x_y_z, - *self._up.x_y_z) - - -class Projector(): # pylint: disable=too-few-public-methods - """Configuration for how 3d objects are projected onto the 2d window. - - :param fov: (Field of View) The viewing angle in degrees between the center of the window, and the top/bottom. - :param near_clip_plane: The minimum distance from the camera at which geometry can be rendered. - :param far_clip_plane: The maximum distance from the camera at which geometry can be rendered. - """ - - def __init__(self, fov: float, near_clip_plane: float, far_clip_plane: float): - self._fov = fov - self._near_clip_plane = near_clip_plane - self._far_clip_plane = far_clip_plane - - def apply(self, window): - """Applies the transform this projection represents to the active OpenGL context.""" - - # Set up the projection matrix - glMatrixMode(GL_PROJECTION) - glLoadIdentity() - fov = self._fov - aspect_ratio = window.width / window.height - near_clip_plane = self._near_clip_plane - far_clip_plane = self._far_clip_plane - gluPerspective(fov, aspect_ratio, near_clip_plane, far_clip_plane) - - # Switch to model matrix for rendering everything - glMatrixMode(GL_MODELVIEW) - glLoadIdentity() - - -class Light(): # pylint: disable=too-few-public-methods - """Configuration for a light in the OpenGL scene that effects the shading of 3d geometry. - - :param ambient_color: Color applied to all geometry in the scene regardless of their relation to the light. - :param diffuse_color: Color applied to geometry in the scene which is facing the light. - :param specular_color: Color applied to geometry that is facing signficantly enough toward the light (depending on it's material's shininess). - :param position: The location of the light (or direction vector in the case of direction lights). - :param is_directional: Flag that sets the light to shine globally from a specified direction rather than an origin point (i.e. Sun light). - """ - - def __init__(self, ambient_color: List[float], diffuse_color: List[float], specular_color: List[float], position: util.Vector3, is_directional: bool = False): - self._ambient_color = ambient_color - self._diffuse_color = diffuse_color - self._specular_color = specular_color - # w coordinate of '1' indicates a positional light in OpenGL, while '0' would indicate a directional light - self._position_coords = [position.x, position.y, position.z, 0 if is_directional else 1] - - def apply(self, index: int): - """Applies this light to the active OpenGL context. - - :param index: the internal OpenGL light index to apply this class's data to. - """ - opengl_index = GL_LIGHT0 + index - glLightfv(opengl_index, GL_AMBIENT, self._ambient_color) - glLightfv(opengl_index, GL_DIFFUSE, self._diffuse_color) - glLightfv(opengl_index, GL_SPECULAR, self._specular_color) - glLightfv(opengl_index, GL_POSITION, self._position_coords) - glEnable(opengl_index) - - -class OpenGLWindow(): - """A Window displaying an OpenGL viewport. - - :param x: The initial x coordinate of the window in pixels. - :param y: The initial y coordinate of the window in pixels. - :param width: The initial height of the window in pixels. - :param height: The initial height of the window in pixels. - :param window_name: The name / title for the window. - """ - - def __init__(self, x: int, y: int, width: int, height: int, window_name: str): - self._pos = (x, y) - #: int: The width of the window - self._width = width - #: int: The height of the window - self._height = height - self._gl_window = None - self._window_name = window_name - - @property - def width(self): - """The horizontal width of the window""" - return self._width - - @property - def height(self): - """The vertical height of the window:""" - return self._height - - def initialize(self, display_function: callable): - """Initialze the OpenGL display parts of the Window. - - Warning: - Must be called on the same thread as OpenGL (usually the main thread), - """ - - glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH) - - glutInitWindowSize(self.width, self.height) - glutInitWindowPosition(*self._pos) - self._gl_window = glutCreateWindow(self._window_name) - - glClearColor(0, 0, 0, 0) - glEnable(GL_DEPTH_TEST) - glShadeModel(GL_SMOOTH) - - glutIdleFunc(self._idle) - glutVisibilityFunc(self._visible) - glutReshapeFunc(self._reshape) - - glutDisplayFunc(display_function) - - def prepare_for_rendering(self, projector: Projector, camera: Camera, lights: List[Light]): - """Selects the window, clears buffers, and sets up the scene transform and lighting state. - - :param projector: The projector configuration to use for this rendering pass. - :param camera: The camera object to use for this rendering pass. - :param lights: The light list to use for this rendering pass. - """ - glutSetWindow(self._gl_window) - - # Clear the screen and the depth buffer - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) - - # Apply our projection so the window is ready to render in perspective - projector.apply(self) - - # Add scene lights - light_count = len(lights) - for i in range(light_count): - lights[i].apply(i) - - # Set scale from mm to cm - glScalef(0.1, 0.1, 0.1) - - # Orient the camera - camera.apply() - - @staticmethod - def display_rendered_content(): - """Swaps buffers once rendering is finished. - """ - glutSwapBuffers() - - def _idle(self): # pylint: disable=no-self-use - """Called from OpenGL when idle.""" - glutPostRedisplay() - - def _visible(self, vis): - """Called from OpenGL when visibility changes (windows are either visible - or completely invisible/hidden).""" - if vis == GLUT_VISIBLE: - glutIdleFunc(self._idle) - else: - glutIdleFunc(None) - - def _reshape(self, width: int, height: int): - """Called from OpenGL whenever this window is resized. - - :param width: the new width of the window in pixels. - :param height: the new height of the window in pixels. - """ - self._width = width - self._height = height - glViewport(0, 0, width, height) diff --git a/anki_vector/opengl/opengl_vector.py b/anki_vector/opengl/opengl_vector.py deleted file mode 100644 index 138fab4..0000000 --- a/anki_vector/opengl/opengl_vector.py +++ /dev/null @@ -1,603 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""This module provides Vector-specific 3D support classes for OpenGL, used by opengl_viewer.py. - -Warning: - This package requires Python to have the PyOpenGL package installed, along - with an implementation of GLUT (OpenGL Utility Toolkit). - - To install the Python packages on Mac and Linux do ``python3 -m pip install --user "anki_vector[3dviewer]"`` - - To install the Python packages on Windows do ``py -3 -m pip install --user "anki_vector[3dviewer]"`` - - On Windows and Linux you must also install freeglut (macOS / OSX has one - preinstalled). - - On Linux: ``sudo apt-get install freeglut3`` - - On Windows: Go to http://freeglut.sourceforge.net/ to get a ``freeglut.dll`` - file. It's included in any of the `Windows binaries` downloads. Place the DLL - next to your Python script, or install it somewhere in your PATH to allow any - script to use it." -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['CubeRenderFrame', 'FaceRenderFrame', 'LightCubeView', 'RobotRenderFrame', 'RobotView', - 'UnitCubeView', 'VectorViewManifest', 'WorldRenderFrame'] - -import math -import time -from typing import List - -from anki_vector.faces import Face -from anki_vector.objects import CustomObject, FixedCustomObject, LightCube, ObservableObject -from anki_vector import nav_map, util -from . import opengl - -try: - from OpenGL.GL import (GL_AMBIENT, GL_BLEND, GL_COMPILE, GL_DIFFUSE, GL_FILL, GL_FRONT, GL_FRONT_AND_BACK, GL_LIGHTING, GL_LINE, GL_LINE_STRIP, - GL_ONE_MINUS_SRC_ALPHA, GL_POLYGON, GL_SHININESS, GL_SPECULAR, GL_SRC_ALPHA, GL_TRIANGLE_STRIP, - glBegin, glBlendFunc, glCallList, glColor, glColor3f, glColor4f, glDisable, glEnable, glEnd, glEndList, glGenLists, - glMaterialfv, glMultMatrixf, glNewList, glNormal3fv, glPolygonMode, glPopMatrix, glPushMatrix, glRotatef, glScalef, - glTranslatef, glVertex3f, glVertex3fv) - -except ImportError as import_exc: - opengl.raise_opengl_or_pillow_import_error(import_exc) - - -#: The object file used to render the robot. -VECTOR_MODEL_FILE = "vector.obj" - -#: The object file used to render the cube. -CUBE_MODEL_FILE = "cube.obj" - -# The following offsets are used in displaying the Vector 3d model. -# These values are tuned to reflect the vector.obj file, and do not -# necessarily reflect the actual measurements of the physical robot. - -#: The length of Vector's lift arm -LIFT_ARM_LENGTH_MM = 66.0 - -#: The height above ground of Vector's lift arm's pivot -LIFT_PIVOT_HEIGHT_MM = 45.0 - -#: Angle of the lift in the object's initial default pose. -LIFT_ANGLE_IN_DEFAULT_POSE = -11.36 - -#: Pivot offset for where the fork rotates around itself -FORK_PIVOT_X = 3.0 -FORK_PIVOT_Z = 3.4 - -#: Offset for the axel that the upper arm rotates around. -UPPER_ARM_PIVOT_X = -3.73 -UPPER_ARM_PIVOT_Z = 4.47 - -#: Offset for the axel that the lower arm rotates around. -LOWER_ARM_PIVOT_X = -3.74 -LOWER_ARM_PIVOT_Z = 3.27 - -#: Offset for the pivot that the head rotates around. -HEAD_PIVOT_X = -1.1 -HEAD_PIVOT_Z = 4.75 - - -_resource_package = __name__ # All resources are in subdirectories from this file's location - - -class UnitCubeView(opengl.PrecomputedView): - """A view containing a cube of unit size at the origin.""" - - def __init__(self): - - self._display_list_name = 'cube' - - super(UnitCubeView, self).__init__() - self.build_from_render_function(self._display_list_name, self._render_cube) - - @staticmethod - def _render_cube(): - """Pre renders a unit-size cube, with normals, centered at the origin. - """ - # build each of the 6 faces - for face_index in range(6): - # calculate normal and vertices for this face - vertex_normal = [0.0, 0.0, 0.0] - vertex_pos_options1 = [-1.0, 1.0, 1.0, -1.0] - vertex_pos_options2 = [1.0, 1.0, -1.0, -1.0] - face_index_even = ((face_index % 2) == 0) - # odd and even faces point in opposite directions - normal_dir = 1.0 if face_index_even else -1.0 - if face_index < 2: - # -X and +X faces (vert positions differ in Y,Z) - vertex_normal[0] = normal_dir - v1i = 1 - v2i = 2 - elif face_index < 4: - # -Y and +Y faces (vert positions differ in X,Z) - vertex_normal[1] = normal_dir - v1i = 0 - v2i = 2 - else: - # -Z and +Z faces (vert positions differ in X,Y) - vertex_normal[2] = normal_dir - v1i = 0 - v2i = 1 - - vertex_pos = list(vertex_normal) - - # Polygon (N verts) with optional normals and tex coords - glBegin(GL_POLYGON) - for vert_index in range(4): - vertex_pos[v1i] = vertex_pos_options1[vert_index] - vertex_pos[v2i] = vertex_pos_options2[vert_index] - glNormal3fv(vertex_normal) - glVertex3fv(vertex_pos) - glEnd() - - def display(self, color: List[float], draw_solid: bool): - """Displays the cube with a specific color. - - :param color: Color to display the cube. - :param draw_solid: Whether to draw solid polygons (False to draw wireframe). - """ - glColor(color) - - if draw_solid: - ambient_color = [color[0] * 0.1, color[1] * 0.1, color[2] * 0.1, 1.0] - else: - ambient_color = color - glMaterialfv(GL_FRONT, GL_AMBIENT, ambient_color) - glMaterialfv(GL_FRONT, GL_DIFFUSE, color) - glMaterialfv(GL_FRONT, GL_SPECULAR, color) - - glMaterialfv(GL_FRONT, GL_SHININESS, 10.0) - - if draw_solid: - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) - else: - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) - - self.display_by_key(self._display_list_name) - - -class LightCubeView(opengl.PrecomputedView): - """A view containing the Vector Light Cube 3D Model. - - :param mesh_data: Source Mesh Data for the light cube. - """ - - def __init__(self, mesh_data: opengl.MeshData): - - super(LightCubeView, self).__init__() - self.build_from_mesh_data(mesh_data) - - def display(self, pose: util.Pose): - """Displays the precomputed view at a specific pose in 3d space. - - :param pose: Where to display the cube. - """ - glPushMatrix() - - # TODO if cube_pose.is_accurate is False, render half-translucent? - # (This would require using a shader, or having duplicate objects) - - cube_matrix = pose.to_matrix() - glMultMatrixf(cube_matrix.in_row_order) - - # Cube is drawn slightly larger than the 10mm to 1 cm scale, as the model looks small otherwise - cube_scale_amt = 10.7 - glScalef(cube_scale_amt, cube_scale_amt, cube_scale_amt) - - self.display_all() - glPopMatrix() - - -class RobotView(opengl.PrecomputedView): - """A view containing the Vector robot 3D Model. - - :param mesh_data: Source Mesh Data for the robot. - """ - - def __init__(self, mesh_data: opengl.MeshData): - - super(RobotView, self).__init__() - self.build_from_mesh_data(mesh_data) - - def _display_vector_body(self): - """Displays the robot's body to the current OpenGL context - """ - - # Render the static body meshes - first the main body: - self.display_by_key("body_geo") - # Render the left treads and wheels - self.display_by_key("trackBase_L_geo") - self.display_by_key("wheel_BL_geo") - self.display_by_key("wheel_FL_geo") - self.display_by_key("tracks_L_geo") - # Render the right treads and wheels - self.display_by_key("trackBase_R_geo") - self.display_by_key("wheel_BR_geo") - self.display_by_key("wheel_FR_geo") - self.display_by_key("tracks_R_geo") - - def _display_vector_lift(self, lift_angle: float): - """Displays the robot's lift to the current OpenGL context - - :param lift_angle: the angle of the lift in radians - """ - - # Render the fork at the front (but not the arms) - glPushMatrix() - # The fork rotates first around upper arm (to get it to the correct position). - glTranslatef(UPPER_ARM_PIVOT_X, 0.0, UPPER_ARM_PIVOT_Z) - glRotatef(lift_angle, 0, 1, 0) - glTranslatef(-UPPER_ARM_PIVOT_X, 0.0, -UPPER_ARM_PIVOT_Z) - # The fork then rotates back around itself as it always hangs vertically. - glTranslatef(FORK_PIVOT_X, 0.0, FORK_PIVOT_Z) - glRotatef(-lift_angle, 0, 1, 0) - glTranslatef(-FORK_PIVOT_X, 0.0, -FORK_PIVOT_Z) - # Render - self.display_by_key("fork_geo") - glPopMatrix() - - # Render the upper arms: - glPushMatrix() - # Rotate the upper arms around the upper arm joint - glTranslatef(UPPER_ARM_PIVOT_X, 0.0, UPPER_ARM_PIVOT_Z) - glRotatef(lift_angle, 0, 1, 0) - glTranslatef(-UPPER_ARM_PIVOT_X, 0.0, -UPPER_ARM_PIVOT_Z) - # Render - self.display_by_key("uprArm_L_geo") - self.display_by_key("uprArm_geo") - glPopMatrix() - - # Render the lower arms: - glPushMatrix() - # Rotate the lower arms around the lower arm joint - glTranslatef(LOWER_ARM_PIVOT_X, 0.0, LOWER_ARM_PIVOT_Z) - glRotatef(lift_angle, 0, 1, 0) - glTranslatef(-LOWER_ARM_PIVOT_X, 0.0, -LOWER_ARM_PIVOT_Z) - # Render - self.display_by_key("lwrArm_L_geo") - self.display_by_key("lwrArm_R_geo") - glPopMatrix() - - def _display_vector_head(self, head_angle: float): - """Displays the robot's head to the current OpenGL context - - :param head_angle: the angle of the lift in radians - """ - - glPushMatrix() - # Rotate the head around the pivot - glTranslatef(HEAD_PIVOT_X, 0.0, HEAD_PIVOT_Z) - glRotatef(-head_angle, 0, 1, 0) - glTranslatef(-HEAD_PIVOT_X, 0.0, -HEAD_PIVOT_Z) - # Render all of the head meshes - self.display_by_key("head_geo") - # Screen - self.display_by_key("backScreen_mat") - self.display_by_key("screenEdge_geo") - self.display_by_key("overscan_1_geo") - # Eyes - self.display_by_key("eye_L_geo") - self.display_by_key("eye_R_geo") - # Eyelids - self.display_by_key("eyeLid_R_top_geo") - self.display_by_key("eyeLid_L_top_geo") - self.display_by_key("eyeLid_L_btm_geo") - self.display_by_key("eyeLid_R_btm_geo") - # Face cover (drawn last as it's translucent): - self.display_by_key("front_Screen_geo") - glPopMatrix() - - def display(self, pose: util.Pose, head_angle: util.Angle, lift_position: util.Distance): - """Displays the precomputed view at a specific pose in 3d space. - - :param pose: Where to display the robot. - """ - if not self._display_lists: - return - - robot_matrix = pose.to_matrix() - head_angle_degrees = head_angle.degrees - - # Get the angle of Vector's lift for rendering - we subtract the angle - # of the lift in the default pose in the object, and apply the inverse - # rotation - sin_angle = (lift_position.distance_mm - LIFT_PIVOT_HEIGHT_MM) / LIFT_ARM_LENGTH_MM - angle_radians = math.asin(sin_angle) - - lift_angle = -(angle_radians - LIFT_ANGLE_IN_DEFAULT_POSE) - - glPushMatrix() - glEnable(GL_LIGHTING) - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_BLEND) - - glMultMatrixf(robot_matrix.in_row_order) - - robot_scale_amt = 10.0 # cm to mm - glScalef(robot_scale_amt, robot_scale_amt, robot_scale_amt) - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) - - self._display_vector_body() - self._display_vector_lift(lift_angle) - self._display_vector_head(head_angle_degrees) - - glDisable(GL_LIGHTING) - glPopMatrix() - - -class NavMapView(opengl.PrecomputedView): - """A view containing a cube of unit size at the origin.""" - - def __init__(self): - self.logger = util.get_class_logger(__name__, self) - super(NavMapView, self).__init__() - - def build_from_nav_map(self, new_nav_map: nav_map.NavMapGrid): - """Reconstructs the display list for the NavMapView based on a :class:`anki_vector.nav_map.NavMapGrid` object. - - :param new_nav_map: nav map source data to be referenced for the new display list. - """ - cen = new_nav_map.center - half_size = new_nav_map.size * 0.5 - - self._display_lists['_navmap'] = glGenLists(1) # pylint: disable=assignment-from-no-return - glNewList(self._display_lists['_navmap'], GL_COMPILE) - - glPushMatrix() - - color_light_gray = (0.65, 0.65, 0.65) - glColor3f(*color_light_gray) - glBegin(GL_LINE_STRIP) - glVertex3f(cen.x + half_size, cen.y + half_size, cen.z) # TL - glVertex3f(cen.x + half_size, cen.y - half_size, cen.z) # TR - glVertex3f(cen.x - half_size, cen.y - half_size, cen.z) # BR - glVertex3f(cen.x - half_size, cen.y + half_size, cen.z) # BL - glVertex3f(cen.x + half_size, cen.y + half_size, - cen.z) # TL (close loop) - glEnd() - - def color_for_content(content): - nct = nav_map.NavNodeContentTypes - colors = {nct.Unknown.value: (0.3, 0.3, 0.3), # dark gray - nct.ClearOfObstacle.value: (0.0, 1.0, 0.0), # green - nct.ClearOfCliff.value: (0.0, 0.5, 0.0), # dark green - nct.ObstacleCube.value: (1.0, 0.0, 0.0), # red - nct.ObstacleProximity.value: (1.0, 0.5, 0.0), # orange - nct.ObstacleProximityExplored.value: (0.5, 1.0, 0.0), # yellow-green - nct.ObstacleUnrecognized.value: (0.5, 0.0, 0.0), # dark red - nct.Cliff.value: (0.0, 0.0, 0.0), # black - nct.InterestingEdge.value: (1.0, 1.0, 0.0), # yellow - nct.NonInterestingEdge.value: (0.5, 0.5, 0.0), # dark-yellow - } - - col = colors.get(content) - if col is None: - col = (1.0, 1.0, 1.0) # white - return col - - fill_z = cen.z - 0.4 - - def _recursive_draw(grid_node: nav_map.NavMapGridNode): - if grid_node.children is not None: - for child in grid_node.children: - _recursive_draw(child) - else: - # leaf node - render as a quad - map_alpha = 0.5 - cen = grid_node.center - half_size = grid_node.size * 0.5 - - # Draw outline - glColor4f(*color_light_gray, 1.0) # fully opaque - glBegin(GL_LINE_STRIP) - glVertex3f(cen.x + half_size, cen.y + half_size, cen.z) - glVertex3f(cen.x + half_size, cen.y - half_size, cen.z) - glVertex3f(cen.x - half_size, cen.y - half_size, cen.z) - glVertex3f(cen.x - half_size, cen.y + half_size, cen.z) - glVertex3f(cen.x + half_size, cen.y + half_size, cen.z) - glEnd() - - # Draw filled contents - glColor4f(*color_for_content(grid_node.content), map_alpha) - glBegin(GL_TRIANGLE_STRIP) - glVertex3f(cen.x + half_size, cen.y - half_size, fill_z) - glVertex3f(cen.x + half_size, cen.y + half_size, fill_z) - glVertex3f(cen.x - half_size, cen.y - half_size, fill_z) - glVertex3f(cen.x - half_size, cen.y + half_size, fill_z) - glEnd() - - _recursive_draw(new_nav_map.root_node) - - glPopMatrix() - glEndList() - - def display(self): - """Displays the precomputed nav map view. - This function will do nothing if no display list has yet been built. - """ - if '_navmap' in self._display_lists: - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_BLEND) - glPushMatrix() - glCallList(self._display_lists['_navmap']) - glPopMatrix() - - -class VectorViewManifest(): - """A collection of Vector-specific source data containing views to display. - """ - - def __init__(self): - self._light_cube_view: LightCubeView = None - self._unit_cube_view: UnitCubeView = None - self._robot_view: RobotView = None - self._nav_map_view: NavMapView = None - - @property - def light_cube_view(self) -> LightCubeView: - """A precomputed view of Vector's light cube.""" - return self._light_cube_view - - @property - def unit_cube_view(self) -> UnitCubeView: - """A precomputed view of a unit cube. - - This is used for representing detected faces. - """ - return self._unit_cube_view - - @property - def robot_view(self) -> RobotView: - """A precomputed view of the robot.""" - return self._robot_view - - @property - def nav_map_view(self) -> NavMapView: - """A precomputable view of the navigation map. This will be updated - as new content comes in. - """ - return self._nav_map_view - - def load_assets(self): - """Loads all assets needed for the view manifest, and precomputes them - into cached views. - """ - resource_context = opengl.ResourceManager(_resource_package) - - # Load 3D objects - robot_mesh_data = opengl.MeshData(resource_context, VECTOR_MODEL_FILE) - self._robot_view = RobotView(robot_mesh_data) - - # Load the cube - cube_mesh_data = opengl.MeshData(resource_context, CUBE_MODEL_FILE) - self._light_cube_view = LightCubeView(cube_mesh_data) - - self._unit_cube_view = UnitCubeView() - - self._nav_map_view = NavMapView() - - -class ObservableObjectRenderFrame(): # pylint: disable=too-few-public-methods - """Minimal copy of an object's state for 1 frame of rendering. - - :param obj: the cube object to be rendered. - """ - - def __init__(self, obj: ObservableObject): - self.pose = obj.pose - self.is_visible = obj.is_visible - self.last_observed_time = obj.last_observed_time - - @property - def time_since_last_seen(self) -> float: - # Equivalent of ObservableObject's method - """time since this obj was last seen (math.inf if never)""" - if self.last_observed_time is None: - return math.inf - return time.time() - self.last_observed_time - - -class CubeRenderFrame(ObservableObjectRenderFrame): # pylint: disable=too-few-public-methods - """Minimal copy of a Cube's state for 1 frame of rendering. - - :param cube: the cube object to be rendered. - """ - - def __init__(self, cube: LightCube): # pylint: disable=useless-super-delegation - super().__init__(cube) - - -class FaceRenderFrame(ObservableObjectRenderFrame): # pylint: disable=too-few-public-methods - """Minimal copy of a Face's state for 1 frame of rendering. - - :param face: The face object to be rendered. - """ - - def __init__(self, face: Face): # pylint: disable=useless-super-delegation - super().__init__(face) - - -class CustomObjectRenderFrame(ObservableObjectRenderFrame): # pylint: disable=too-few-public-methods - """Minimal copy of a CustomObject's state for 1 frame of rendering. - - :param custom_object: The custom object to be rendered. Either :class:`anki_vector.objects.CustomObject` or :class:`anki_vector.objects.FixedCustomObject`. - :param is_fixed: Whether the custom object is permanently defined rather than an observable archetype. - """ - - def __init__(self, custom_object, is_fixed: bool): - if is_fixed: - # Not an observable, so init directly - self.pose = custom_object.pose - self.is_visible = None - self.last_observed_time = None - else: - super().__init__(custom_object) - - self.is_fixed = is_fixed - self.x_size_mm = custom_object.archetype.x_size_mm - self.y_size_mm = custom_object.archetype.y_size_mm - self.z_size_mm = custom_object.archetype.z_size_mm - - -class RobotRenderFrame(): # pylint: disable=too-few-public-methods - """Minimal copy of a Robot's state for 1 frame of rendering. - - :param robot: the robot object to be rendered. - """ - - def __init__(self, robot): - self.pose = robot.pose - if robot.head_angle_rad is None: - self.head_angle = util.radians(0.0) - else: - self.head_angle = util.radians(robot.head_angle_rad) - if robot.lift_height_mm is None: - self.lift_position = util.distance_mm(0.0) - else: - self.lift_position = util.distance_mm(robot.lift_height_mm) - - -class WorldRenderFrame(): # pylint: disable=too-few-public-methods - """Minimal copy of the World's state for 1 frame of rendering. - - :param robot: the robot object to be rendered, which also has handles to the other objects - defined in it's world class. - """ - - def __init__(self, robot): - - self.robot_frame = RobotRenderFrame(robot) - - self.cube_frames: List[CubeRenderFrame] = [] - if robot.world.connected_light_cube is not None: - self.cube_frames.append(CubeRenderFrame(robot.world.connected_light_cube)) - - self.face_frames: List[FaceRenderFrame] = [] - for face in robot.world.visible_faces: - # Ignore faces that have a newer version (with updated id) - # or if they haven't been seen in a while. - if not face.has_updated_face_id and (face.time_since_last_seen < 60): - self.face_frames.append(FaceRenderFrame(face)) - - self.custom_object_frames = [] - for obj in robot.world.all_objects: - is_custom = isinstance(obj, CustomObject) - is_fixed = isinstance(obj, FixedCustomObject) - if is_custom or is_fixed: - self.custom_object_frames.append(CustomObjectRenderFrame(obj, is_fixed)) diff --git a/anki_vector/opengl/opengl_viewer.py b/anki_vector/opengl/opengl_viewer.py deleted file mode 100644 index 43a38ec..0000000 --- a/anki_vector/opengl/opengl_viewer.py +++ /dev/null @@ -1,679 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""This module provides a 3D visualizer for Vector's world state and a 2D camera window. - -It uses PyOpenGL, a Python OpenGL 3D graphics library which is available on most -platforms. It also depends on the Pillow library for image processing. - -Example: - .. testcode:: - - import time - - import anki_vector - - with anki_vector.Robot(show_viewer=True, - show_3d_viewer=True, - enable_camera_feed=True, - enable_face_detection=True, - enable_custom_object_detection=True, - enable_nav_map_feed=True) as robot: - time.sleep(10) - -Warning: - This package requires Python to have the PyOpenGL package installed, along - with an implementation of GLUT (OpenGL Utility Toolkit). - - To install the Python packages on Mac and Linux do ``python3 -m pip install --user "anki_vector[3dviewer]"`` - - To install the Python packages on Windows do ``py -3 -m pip install --user "anki_vector[3dviewer]"`` - - On Windows and Linux you must also install freeglut (macOS / OSX has one - preinstalled). - - On Linux: ``sudo apt-get install freeglut3`` - - On Windows: Go to http://freeglut.sourceforge.net/ to get a ``freeglut.dll`` - file. It's included in any of the `Windows binaries` downloads. Place the DLL - next to your Python script, or install it somewhere in your PATH to allow any - script to use it." -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['OpenGLViewer'] - -import math -import multiprocessing as mp -import sys -from typing import List - -from anki_vector import nav_map, util -from . import opengl, opengl_vector - - -try: - from OpenGL.GL import (GL_FILL, - GL_FRONT_AND_BACK, - GL_LIGHTING, GL_NORMALIZE, - GL_TEXTURE_2D, - glBindTexture, glColor3f, glDisable, glEnable, - glMultMatrixf, glPolygonMode, glPopMatrix, glPushMatrix, - glScalef, glWindowPos2f) - from OpenGL.GLUT import (ctypes, - GLUT_ACTIVE_ALT, GLUT_ACTIVE_CTRL, GLUT_ACTIVE_SHIFT, GLUT_BITMAP_9_BY_15, - GLUT_DOWN, GLUT_LEFT_BUTTON, GLUT_RIGHT_BUTTON, GLUT_VISIBLE, - glutBitmapCharacter, glutCheckLoop, glutGetModifiers, glutIdleFunc, - glutKeyboardFunc, glutKeyboardUpFunc, glutMainLoop, glutMouseFunc, glutMotionFunc, glutPassiveMotionFunc, - glutPostRedisplay, glutSpecialFunc, glutSpecialUpFunc, glutVisibilityFunc) - from OpenGL.error import NullFunctionError - -except ImportError as import_exc: - opengl.raise_opengl_or_pillow_import_error(import_exc) - - -# Constants - - -class _RobotControlIntents(): # pylint: disable=too-few-public-methods - """Input intents for controlling the robot. - - These are sent from the OpenGL process, and consumed by the main process for - issuing movement commands on Vector (to provide a remote-control interface). - """ - - def __init__(self, left_wheel_speed=0.0, right_wheel_speed=0.0, - lift_speed=0.0, head_speed=0.0): - self.left_wheel_speed = left_wheel_speed - self.right_wheel_speed = right_wheel_speed - self.lift_speed = lift_speed - self.head_speed = head_speed - - -def _draw_text(font, input_str, x, y, line_height=16, r=1.0, g=1.0, b=1.0): - """Render text based on window position. The origin is in the bottom-left.""" - glColor3f(r, g, b) - glWindowPos2f(x, y) - input_list = input_str.split('\n') - y = y + (line_height * (len(input_list) - 1)) - for line in input_list: - glWindowPos2f(x, y) - y -= line_height - for ch in line: - glutBitmapCharacter(font, ctypes.c_int(ord(ch))) - - -def _glut_install_instructions(): - if sys.platform.startswith('linux'): - return "Install freeglut: `sudo apt-get install freeglut3`" - if sys.platform.startswith('darwin'): - return "GLUT should already be installed by default on macOS!" - if sys.platform in ('win32', 'cygwin'): - return "Install freeglut: You can download it from http://freeglut.sourceforge.net/ \n"\ - "You just need the `freeglut.dll` file, from any of the 'Windows binaries' downloads. "\ - "Place the DLL next to your Python script, or install it somewhere in your PATH "\ - "to allow any script to use it." - return "(Instructions unknown for platform %s)" % sys.platform - - -class _OpenGLViewController(): - """Controller that registers for keyboard and mouse input through GLUT, and uses them to update - the camera and listen for a shutdown cue. - - :param shutdown_delegate: Function to call when we want to exit the host OpenGLViewer. - :param camera: The camera object for the controller to mutate. - :param input_intent_queue: Sends key commands from the 3D viewer process to the main process. - :type input_intent_queue: multiprocessing.Queue - :param viewer: A reference to the owning OpenGLViewer. - :type viewer: OpenGLViewer - """ - - def __init__(self, shutdown_delegate: callable, camera: opengl.Camera, input_intent_queue: mp.Queue, viewer): - - self._logger = util.get_class_logger(__name__, self) - self._input_intent_queue = input_intent_queue - self._last_robot_control_intents = _RobotControlIntents() - self._is_keyboard_control_enabled = False - - # Keyboard - self._is_key_pressed = {} - self._is_alt_down = False - self._is_ctrl_down = False - self._is_shift_down = False - - # Mouse - self._is_mouse_down = {} - self._mouse_pos = None # type: util.Vector2 - - self._shutdown_delegate = shutdown_delegate - - self._last_robot_position = None - - self._camera = camera - - self._opengl_viewer = viewer - - #### Public Properties #### - - @property - def last_robot_position(self): - return self._last_robot_position - - @last_robot_position.setter - def last_robot_position(self, last_robot_position): - self._last_robot_position = last_robot_position - - #### Public Methods #### - - def initialize(self): - """Sets up the OpenGL window and binds input callbacks to it - """ - - glutKeyboardFunc(self._on_key_down) - glutSpecialFunc(self._on_special_key_down) - - # [Keyboard/Special]Up methods aren't supported on some old GLUT implementations - has_keyboard_up = False - has_special_up = False - try: - if bool(glutKeyboardUpFunc): - glutKeyboardUpFunc(self._on_key_up) - has_keyboard_up = True - if bool(glutSpecialUpFunc): - glutSpecialUpFunc(self._on_special_key_up) - has_special_up = True - except NullFunctionError: - # Methods aren't available on this GLUT version - pass - - if not has_keyboard_up or not has_special_up: - # Warn on old GLUT implementations that don't implement much of the interface. - self._logger.warning("Warning: Old GLUT implementation detected - keyboard remote control of Vector disabled." - "We recommend installing freeglut. %s", _glut_install_instructions()) - self._is_keyboard_control_enabled = False - else: - self._is_keyboard_control_enabled = True - - try: - GLUT_BITMAP_9_BY_15 - except NameError: - self._logger.warning("Warning: GLUT font not detected. Help message will be unavailable.") - - glutMouseFunc(self._on_mouse_button) - glutMotionFunc(self._on_mouse_move) - glutPassiveMotionFunc(self._on_mouse_move) - - glutIdleFunc(self._idle) - glutVisibilityFunc(self._visible) - - #### Private Methods #### - - def _update_modifier_keys(self): - """Updates alt, ctrl, and shift states. - """ - modifiers = glutGetModifiers() - self._is_alt_down = (modifiers & GLUT_ACTIVE_ALT != 0) - self._is_ctrl_down = (modifiers & GLUT_ACTIVE_CTRL != 0) - self._is_shift_down = (modifiers & GLUT_ACTIVE_SHIFT != 0) - - def _key_byte_to_lower(self, key): # pylint: disable=no-self-use - """Convert bytes-object (representing keyboard character) to lowercase equivalent. - """ - if b'A' <= key <= b'Z': - lowercase_key = ord(key) - ord(b'A') + ord(b'a') - lowercase_key = bytes([lowercase_key]) - return lowercase_key - return key - - def _on_key_up(self, key, x, y): # pylint: disable=unused-argument - """Called by GLUT when a standard keyboard key is released. - - :param key: which key was released. - :param x: the x coordinate of the mouse cursor. - :param y: the y coordinate of the mouse cursor. - """ - key = self._key_byte_to_lower(key) - self._update_modifier_keys() - self._is_key_pressed[key] = False - - def _on_key_down(self, key, x, y): # pylint: disable=unused-argument - """Called by GLUT when a standard keyboard key is pressed. - - :param key: which key was released. - :param x: the x coordinate of the mouse cursor. - :param y: the y coordinate of the mouse cursor. - """ - key = self._key_byte_to_lower(key) - self._update_modifier_keys() - self._is_key_pressed[key] = True - - if ord(key) == 9: # Tab - # Set Look-At point to current robot position - if self._last_robot_position is not None: - self._camera.look_at = self._last_robot_position - elif ord(key) == 27: # Escape key - self._shutdown_delegate() - elif ord(key) == 72 or ord(key) == 104: # H key - self._opengl_viewer.show_controls = not self._opengl_viewer.show_controls - - def _on_special_key_up(self, key, x, y): # pylint: disable=unused-argument - """Called by GLUT when a special key is released. - - :param key: which key was released. - :param x: the x coordinate of the mouse cursor. - :param y: the y coordinate of the mouse cursor. - """ - self._update_modifier_keys() - - def _on_special_key_down(self, key, x, y): # pylint: disable=unused-argument - """Called by GLUT when a special key is pressed. - - :param key: which key was pressed. - :param x: the x coordinate of the mouse cursor. - :param y: the y coordinate of the mouse cursor. - """ - self._update_modifier_keys() - - def _on_mouse_button(self, button, state, x, y): - """Called by GLUT when a mouse button is pressed. - - :param button: which button was pressed. - :param state: the current state of the button. - :param x: the x coordinate of the mouse cursor. - :param y: the y coordinate of the mouse cursor. - """ - # Don't update modifier keys- reading modifier keys is unreliable - # from _on_mouse_button (for LMB down/up), only SHIFT key seems to read there - # self._update_modifier_keys() - is_down = (state == GLUT_DOWN) - self._is_mouse_down[button] = is_down - self._mouse_pos = util.Vector2(x, y) - - def _on_mouse_move(self, x, y): - """Handles mouse movement. - - :param x: the x coordinate of the mouse cursor. - :param y: the y coordinate of the mouse cursor. - """ - - # is_active is True if this is not passive (i.e. a mouse button was down) - last_mouse_pos = self._mouse_pos - self._mouse_pos = util.Vector2(x, y) - if last_mouse_pos is None: - # First mouse update - ignore (we need a delta of mouse positions) - return - - left_button = self._is_mouse_down.get(GLUT_LEFT_BUTTON, False) - # For laptop and other 1-button mouse users, treat 'x' key as a right mouse button too - right_button = (self._is_mouse_down.get(GLUT_RIGHT_BUTTON, False) or - self._is_key_pressed.get(b'x', False)) - - MOUSE_SPEED_SCALAR = 1.0 # general scalar for all mouse movement sensitivity - MOUSE_ROTATE_SCALAR = 0.025 # additional scalar for rotation sensitivity - mouse_delta = (self._mouse_pos - last_mouse_pos) * MOUSE_SPEED_SCALAR - - if left_button and right_button: - # Move up/down - self._camera.move(up_amount=-mouse_delta.y) - elif right_button: - # Move forward/back and left/right - self._camera.move(forward_amount=mouse_delta.y, right_amount=mouse_delta.x) - elif left_button: - if self._is_key_pressed.get(b'z', False): - # Zoom in/out - self._camera.zoom(mouse_delta.y) - else: - self._camera.turn(mouse_delta.x * MOUSE_ROTATE_SCALAR, mouse_delta.y * MOUSE_ROTATE_SCALAR) - - def _update_intents_for_robot(self): - # Update driving intents based on current input, and pass to SDK thread - # so that it can pass the input onto the robot. - def get_intent_direction(key1, key2): - # Helper for keyboard inputs that have 1 positive and 1 negative input - pos_key = self._is_key_pressed.get(key1, False) - neg_key = self._is_key_pressed.get(key2, False) - return pos_key - neg_key - - drive_dir = get_intent_direction(b'w', b's') - turn_dir = get_intent_direction(b'd', b'a') - lift_dir = get_intent_direction(b'r', b'f') - head_dir = get_intent_direction(b't', b'g') - if drive_dir < 0: - # It feels more natural to turn the opposite way when reversing - turn_dir = -turn_dir - - # Scale drive speeds with SHIFT (faster) and ALT (slower) - if self._is_shift_down: - speed_scalar = 2.0 - elif self._is_alt_down: - speed_scalar = 0.5 - else: - speed_scalar = 1.0 - - drive_speed = 75.0 * speed_scalar - turn_speed = 100.0 * speed_scalar - - left_wheel_speed = (drive_dir * drive_speed) + (turn_speed * turn_dir) - right_wheel_speed = (drive_dir * drive_speed) - (turn_speed * turn_dir) - lift_speed = 4.0 * lift_dir * speed_scalar - head_speed = head_dir * speed_scalar - - control_intents = _RobotControlIntents(left_wheel_speed, right_wheel_speed, - lift_speed, head_speed) - self._input_intent_queue.put(control_intents, True) - - def _idle(self): - if self._is_keyboard_control_enabled: - self._update_intents_for_robot() - glutPostRedisplay() - - def _visible(self, vis): - # Called from OpenGL when visibility changes (windows are either visible - # or completely invisible/hidden) - if vis == GLUT_VISIBLE: - glutIdleFunc(self._idle) - else: - glutIdleFunc(None) - - -#: A default window resolution provided for OpenGL Vector programs -#: 800x600 is large enough to see detail, while fitting on the smaller -#: end of modern monitors. -default_resolution = [800, 600] - -#: A default projector configurate provided for OpenGL Vector programs -#: A Field of View of 45 degrees is common for 3d applications, -#: and a viewable distance range of 1.0 to 1000.0 will provide a -#: visible space comparable with most physical Vector environments. -default_projector = opengl.Projector( - fov=45.0, - near_clip_plane=1.0, - far_clip_plane=1000.0) - -#: A default camera object provided for OpenGL Vector programs. -#: Starts close to and looking at the charger. -default_camera = opengl.Camera( - look_at=util.Vector3(100.0, -25.0, 0.0), - up=util.Vector3(0.0, 0.0, 1.0), - distance=500.0, - pitch=math.radians(40), - yaw=math.radians(270)) - -#: A default light group provided for OpenGL Vector programs. -#: Contains one light near the origin. -default_lights = [opengl.Light( - ambient_color=[1.0, 1.0, 1.0, 1.0], - diffuse_color=[1.0, 1.0, 1.0, 1.0], - specular_color=[1.0, 1.0, 1.0, 1.0], - position=util.Vector3(0, 32, 20))] - -# Global viewer instance. Stored to make sure multiple viewers are not -# instantiated simultaneously. -opengl_viewer = None # type: OpenGLViewer - - -class OpenGLViewer(): - """OpenGL-based 3D Viewer. - - Handles rendering of a 3D world view including navigation map. - - :param close_event: Used to notify each process when done rendering. - :type close_event: multiprocessing.Event - :param input_intent_queue: Sends key commands from the 3D viewer process to the main process. - :type input_intent_queue: multiprocessing.Queue - :param nav_map_queue: Updates the 3D viewer process with the latest navigation map. - :type nav_map_queue: multiprocessing.Queue - :param world_frame_queue: Provides the 3D viewer with details about the world. - :type world_frame_queue: multiprocessing.Queue - :param extra_render_function_queue: Functions to be executed in the 3D viewer process. - :type extra_render_function_queue: multiprocessing.Queue - :param user_data_queue: A queue that may be used outside the SDK to pass information to the viewer process. - May be used by ``extra_render_function_queue`` functions. - :type user_data_queue: multiprocessing.Queue - :param resolution: Specifies whether to draw controls on the view. - :param projector: Specifies whether to draw controls on the view. - :param camera: Specifies whether to draw controls on the view. - :param lights: Specifies whether to draw controls on the view. - :param show_viewer_controls: Specifies whether to draw controls on the view. - """ - - def __init__(self, - close_event: mp.Event, - input_intent_queue: mp.Queue, - nav_map_queue: mp.Queue, - world_frame_queue: mp.Queue, - extra_render_function_queue: mp.Queue, - user_data_queue: mp.Queue, - resolution: List[int] = None, - projector: opengl.Projector = None, - camera: opengl.Camera = None, - lights: List[opengl.Light] = None, - show_viewer_controls: bool = True): - if resolution is None: - resolution = default_resolution - if projector is None: - projector = default_projector - if camera is None: - camera = default_camera - if lights is None: - lights = default_lights - - self._close_event = close_event - self._input_intent_queue = input_intent_queue - self._nav_map_queue = nav_map_queue - self._world_frame_queue = world_frame_queue - self._extra_render_function_queue = extra_render_function_queue - self._user_data_queue = user_data_queue - - self._logger = util.get_class_logger(__name__, self) - self._extra_render_calls = [] - - self._internal_function_finished = False - - # Controls - self.show_controls = show_viewer_controls - self._instructions = '\n'.join(['W, S: Move forward, backward', - 'A, D: Turn left, right', - 'R, F: Lift up, down', - 'T, G: Head up, down', - '', - 'LMB: Rotate camera', - 'RMB: Move camera', - 'LMB + RMB: Move camera up/down', - 'LMB + Z: Zoom camera', - 'X: same as RMB', - 'TAB: center view on robot', - '', - 'H: Toggle help']) - - self._vector_view_manifest = opengl_vector.VectorViewManifest() - self._main_window = opengl.OpenGLWindow(0, 0, resolution[0], resolution[1], b"Vector 3D Visualizer") - - # Create a 3d projector configuration class. - self._projector = projector - self._camera = camera - self._lights = lights - - self._view_controller = _OpenGLViewController(self.close, self._camera, self._input_intent_queue, self) - - self._latest_world_frame: opengl_vector.WorldRenderFrame = None - - def _render_world_frame(self, world_frame: opengl_vector.WorldRenderFrame): - """Render the world to the current OpenGL context - - :param world_frame: frame to render - """ - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) - glEnable(GL_NORMALIZE) # to re-scale scaled normals - - light_cube_view = self._vector_view_manifest.light_cube_view - unit_cube_view = self._vector_view_manifest.unit_cube_view - robot_view = self._vector_view_manifest.robot_view - nav_map_view = self._vector_view_manifest.nav_map_view - - robot_frame = world_frame.robot_frame - robot_pose = robot_frame.pose - - try: - glDisable(GL_LIGHTING) - nav_map_view.display() - - glEnable(GL_LIGHTING) - # Render the cube - for obj in world_frame.cube_frames: - cube_pose = obj.pose - if cube_pose is not None and cube_pose.is_comparable(robot_pose): - light_cube_view.display(cube_pose) - - # Render the custom objects - for obj in world_frame.custom_object_frames: - obj_pose = obj.pose - if obj_pose is not None and obj_pose.is_comparable(robot_pose): - glPushMatrix() - obj_matrix = obj_pose.to_matrix() - glMultMatrixf(obj_matrix.in_row_order) - - glScalef(obj.x_size_mm * 0.5, - obj.y_size_mm * 0.5, - obj.z_size_mm * 0.5) - - # Only draw solid object for observable custom objects - - if obj.is_fixed: - # fixed objects are drawn as transparent outlined boxes to make - # it clearer that they have no effect on vision. - FIXED_OBJECT_COLOR = [1.0, 0.7, 0.0, 1.0] - unit_cube_view.display(FIXED_OBJECT_COLOR, False) - else: - CUSTOM_OBJECT_COLOR = [1.0, 0.3, 0.3, 1.0] - unit_cube_view.display(CUSTOM_OBJECT_COLOR, True) - - glPopMatrix() - - glBindTexture(GL_TEXTURE_2D, 0) - - for face in world_frame.face_frames: - face_pose = face.pose - if face_pose is not None and face_pose.is_comparable(robot_pose): - glPushMatrix() - face_matrix = face_pose.to_matrix() - glMultMatrixf(face_matrix.in_row_order) - - # Approximate size of a head - glScalef(100, 25, 100) - - FACE_OBJECT_COLOR = [0.5, 0.5, 0.5, 1.0] - draw_solid = face.time_since_last_seen < 30 - unit_cube_view.display(FACE_OBJECT_COLOR, draw_solid) - - glPopMatrix() - except BaseException as e: - self._logger.error('rendering error: {0}'.format(e)) - - glDisable(GL_LIGHTING) - - # Draw the Vector robot to the screen - robot_view.display(robot_frame.pose, robot_frame.head_angle, robot_frame.lift_position) - - if self.show_controls: - self._draw_controls() - - def _draw_controls(self): - try: - GLUT_BITMAP_9_BY_15 - except NameError: - pass - else: - _draw_text(GLUT_BITMAP_9_BY_15, self._instructions, x=10, y=10) - - def _render_3d_view(self, window: opengl.OpenGLWindow): - """Renders 3d objects to an openGL window - - :param window: OpenGL window to render to - """ - window.prepare_for_rendering(self._projector, self._camera, self._lights) - - try: - extra_render_call = self._extra_render_function_queue.get(False) - self._extra_render_calls.append(extra_render_call) - except mp.queues.Empty: - pass - - # Update the latest world frame if there is a new one available - try: - world_frame = self._world_frame_queue.get(False) # type: WorldRenderFrame - if world_frame is not None: - self._view_controller.last_robot_position = world_frame.robot_frame.pose.position - self._latest_world_frame = world_frame - except mp.queues.Empty: - world_frame = self._latest_world_frame - - try: - new_nav_map = self._nav_map_queue.get(False) - if new_nav_map is not None: - new_nav_map = nav_map.NavMapGrid(new_nav_map, self._logger) - self._vector_view_manifest.nav_map_view.build_from_nav_map(new_nav_map) - except mp.queues.Empty: - # no new nav map - queue is empty - pass - - if world_frame is not None: - self._render_world_frame(world_frame) - - for render_call in self._extra_render_calls: - # Protecting the external calls with pushMatrix so internal transform - # state changes will not alter other calls - glPushMatrix() - try: - render_call.invoke(self._user_data_queue) - finally: - glPopMatrix() - - window.display_rendered_content() - - def _on_window_update(self): - """Top level display call. - """ - try: - self._render_3d_view(self._main_window) - - except KeyboardInterrupt: - self._logger.info("_display caught KeyboardInterrupt - exitting") - self._close_event.set() - - def run(self): - """Turns control of the current thread over to the OpenGL viewer - """ - self._main_window.initialize(self._on_window_update) - self._view_controller.initialize() - - self._vector_view_manifest.load_assets() - - # use a non-blocking update loop if possible to make exit conditions - # easier (not supported on all GLUT versions). - if bool(glutCheckLoop): - while not self._close_event.is_set(): - glutCheckLoop() - else: - # This blocks until quit - glutMainLoop() - - if not self._close_event.is_set(): - # Pass the keyboard interrupt on to SDK so that it can close cleanly - raise KeyboardInterrupt - - def close(self): - """Called from the SDK when the program is complete and it's time to exit.""" - if not self._close_event.is_set(): - self._close_event.set() diff --git a/anki_vector/photos.py b/anki_vector/photos.py deleted file mode 100644 index 0686be6..0000000 --- a/anki_vector/photos.py +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Photo related classes, functions, events and values. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ["PhotographComponent"] - -import concurrent -from typing import List - -from . import connection, util -from .messaging import protocol - - -class PhotographComponent(util.Component): - """Access the photos on Vector. - - .. testcode:: - - import anki_vector - import io - from PIL import Image - - with anki_vector.Robot() as robot: - for photo_info in robot.photos.photo_info: - print(f"Opening photo {photo_info.photo_id}") - photo = robot.photos.get_photo(photo_info.photo_id) - image = Image.open(io.BytesIO(photo.image)) - image.show() - - :param anki_vector.Robot robot: A reference to an instance of the Robot class. Used to make rpc calls. - """ - - def __init__(self, robot): - super().__init__(robot) - self._photo_info: List[protocol.PhotoInfo] = [] - - @property - def photo_info(self) -> List[protocol.PhotoInfo]: - """The information about what photos are stored on Vector. - - If the photo info hasn't been loaded yet, accessing this property will request it from the robot. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - for photo_info in robot.photos.photo_info: - print(f"photo_info.photo_id: {photo_info.photo_id}") # the id to use to grab a photo from the robot - print(f"photo_info.timestamp_utc: {photo_info.timestamp_utc}") # utc timestamp of when the photo was taken (according to the robot) - """ - if not self._photo_info: - self.logger.debug("Photo list was empty. Lazy-loading photo list now.") - result = self.load_photo_info() - if isinstance(result, concurrent.futures.Future): - result.result() - return self._photo_info - - @connection.on_connection_thread() - async def load_photo_info(self) -> protocol.PhotosInfoResponse: - """Request the photo information from the robot. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - photo_info = robot.photos.load_photo_info() - print(f"photo_info: {photo_info}") - - :return: UTC timestamp of the photo and additional data. - """ - req = protocol.PhotosInfoRequest() - result = await self.grpc_interface.PhotosInfo(req) - self._photo_info = result.photo_infos - return result - - @connection.on_connection_thread(log_messaging=False) - async def get_photo(self, photo_id: int) -> protocol.PhotoResponse: - """Download a full-resolution photo from the robot's storage. - - .. testcode:: - - import anki_vector - import io - from PIL import Image - - with anki_vector.Robot() as robot: - for photo_info in robot.photos.photo_info: - print(f"Opening photo {photo_info.photo_id}") - photo = robot.photos.get_photo(photo_info.photo_id) - image = Image.open(io.BytesIO(photo.image)) - image.show() - - :param photo_id: The id of the photo to download. It's recommended to get this - value from the photo_info list first. - - :return: A response containing all of the photo bytes which may be rendered using - another library (like :mod:`PIL`) - """ - req = protocol.PhotoRequest(photo_id=photo_id) - return await self.grpc_interface.Photo(req) - - @connection.on_connection_thread(log_messaging=False) - async def get_thumbnail(self, photo_id: int) -> protocol.ThumbnailResponse: - """Download a thumbnail of a given photo from the robot's storage. - - You may use this function to pull all of the images off the robot in a smaller format, and - then determine which one to download as full resolution. - - .. testcode:: - - import anki_vector - from PIL import Image - import io - - with anki_vector.Robot() as robot: - for photo_info in robot.photos.photo_info: - photo = robot.photos.get_thumbnail(photo_info.photo_id) - image = Image.open(io.BytesIO(photo.image)) - image.show() - - :param photo_id: The id of the thumbnail to download. It's recommended to get this - value from the photo_info list first. - - :return: A response containing all of the thumbnail bytes which may be rendered using - another library (like :mod:`PIL`) - """ - req = protocol.ThumbnailRequest(photo_id=photo_id) - return await self.grpc_interface.Thumbnail(req) diff --git a/anki_vector/proximity.py b/anki_vector/proximity.py deleted file mode 100755 index 9f93937..0000000 --- a/anki_vector/proximity.py +++ /dev/null @@ -1,229 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Support for Vector's distance sensor. - -Vector's time-of-flight distance sensor has a usable range of about 30 mm to 1200 mm -(max useful range closer to 300mm for Vector) with a field of view of 25 degrees. - -The distance sensor can be used to detect objects in front of the robot. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ["ProximityComponent", "ProximitySensorData"] - -from . import util -from .events import Events -from .messaging import protocol - - -class ProximitySensorData: - """A distance sample from the time-of-flight sensor with metadata describing reliability of the measurement - - The proximity sensor is located near the bottom of Vector between the two front wheels, facing forward. The - reported distance describes how far in front of this sensor the robot feels an obstacle is. The sensor estimates - based on time-of-flight information within a field of view which the engine resolves to a certain quality value. - - Four additional flags are supplied by the engine to indicate whether this proximity data is considered valid - for the robot's internal pathfinding. Respecting these is optional, but will help python code respect the - behavior of the robot's innate object avoidance. - """ - - def __init__(self, proto_data: protocol.ProxData): - self._distance = util.Distance(distance_mm=proto_data.distance_mm) - self._signal_quality = proto_data.signal_quality - self._is_in_valid_range = proto_data.is_in_valid_range - self._is_valid_signal_quality = proto_data.is_valid_signal_quality - self._is_lift_in_fov = proto_data.is_lift_in_fov - self._is_too_pitched = proto_data.is_too_pitched - - @property - @util.block_while_none() - def distance(self) -> float: - """The distance between the sensor and a detected object - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - distance = robot.proximity.last_sensor_reading.distance - """ - return self._distance - - @property - @util.block_while_none() - def signal_quality(self) -> float: - """The quality of the detected object. - - The proximity sensor detects obstacles within a given field of view, - this value represents the likelihood of the reported distance being - a solid surface. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - signal_quality = robot.proximity.last_sensor_reading.signal_quality - """ - return self._signal_quality - - @property - @util.block_while_none() - def is_in_valid_range(self) -> bool: - """Whether or not the engine considers the detected signal is close enough - to be considered useful. Past a certain threshold, distance readings - become unreliable. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - is_in_valid_range = robot.proximity.last_sensor_reading.is_in_valid_range - """ - return self._is_in_valid_range - - @property - @util.block_while_none() - def is_valid_signal_quality(self) -> bool: - """Whether the engine considers the detected signal to be reliable enough - to be considered an object in proximity. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - is_valid_signal_quality = robot.proximity.last_sensor_reading.is_valid_signal_quality - """ - return self._is_valid_signal_quality - - @property - @util.block_while_none() - def is_lift_in_fov(self) -> bool: - """Whether Vector's lift is blocking the time-of-flight sensor. While - the lift will send clear proximity signals, it's not useful for object - detection. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - is_lift_in_fov = robot.proximity.last_sensor_reading.is_lift_in_fov - """ - return self._is_lift_in_fov - - @property - @util.block_while_none() - def is_too_pitched(self) -> bool: - """Whether the engine considers the robot to be tilted too much up or down - for the time-of-flight data to usefully describe obstacles in the driving - plane. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - is_too_pitched = robot.proximity.last_sensor_reading.is_too_pitched - """ - return self._is_too_pitched - - @property - @util.block_while_none() - def is_valid(self) -> bool: - """Comprehensive judgment of whether the reported distance is useful for - object proximity detection. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - is_valid = robot.proximity.last_sensor_reading.is_valid - """ - return self._is_in_valid_range and self._is_valid_signal_quality and not self._is_lift_in_fov and not self._is_too_pitched - - -class ProximityComponent(util.Component): - """Maintains the most recent proximity sensor data - - This will be updated with every broadcast RobotState, and can be queried at any time. Two sensor readings are made available: - - the most recent data from the robot - - the most recent data which was considered valid by the engine for usage - - An example of how to extract sensor data: - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - proximity_data = robot.proximity.last_sensor_reading - if proximity_data is not None: - print('Proximity distance: {0}, engine considers useful: {1}'.format(proximity_data.distance, proximity_data.is_valid)) - """ - - def __init__(self, robot): - super().__init__(robot) - self._last_valid_sensor_reading = None - self._last_sensor_reading = None - - # Subscribe to a callback that updates the robot's local properties - which includes proximity data. - self._robot.events.subscribe(self._on_robot_state, - Events.robot_state, - on_connection_thread=True) - - def close(self): - """Closing the touch component will unsubscribe from robot state updates.""" - self._robot.events.unsubscribe(self._on_robot_state, - Events.robot_state) - - @property - @util.block_while_none() - def last_sensor_reading(self) -> ProximitySensorData: - """:class:`anki_vector.proximity.ProximitySensorData`: The last reported sensor data. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - last_sensor_reading = robot.proximity.last_sensor_reading - """ - return self._last_sensor_reading - - @property - @util.block_while_none() - def last_valid_sensor_reading(self) -> ProximitySensorData: - """:class:`anki_vector.proximity.ProximitySensorData`: The last reported sensor data - which is considered useful for object detection. - - ..code-block :: - - import anki_vector - - with anki_vector.Robot() as robot: - last_valid_sensor_reading = robot.proximity.last_valid_sensor_reading - """ - return self._last_valid_sensor_reading - - def _on_robot_state(self, _, msg): - self._last_sensor_reading = ProximitySensorData(msg.prox_data) - if self._last_sensor_reading.is_valid: - self._last_valid_sensor_reading = self._last_sensor_reading diff --git a/anki_vector/robot.py b/anki_vector/robot.py deleted file mode 100755 index 12fbeb1..0000000 --- a/anki_vector/robot.py +++ /dev/null @@ -1,907 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -The main robot class for managing Vector. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['AsyncRobot', 'Robot'] - -import concurrent -import configparser -import functools -from pathlib import Path - -from . import (animation, audio, behavior, camera, - connection, events, exceptions, faces, - motors, nav_map, screen, photos, proximity, - status, touch, util, viewer, vision, world) -from .viewer import (ViewerComponent, Viewer3DComponent) -from .messaging import protocol - - -class Robot: - """The Robot object is responsible for managing the state and connections - to a Vector, and is typically the entry-point to running the sdk. - - The majority of the robot will not work until it is properly connected - to Vector. There are two ways to get connected: - - 1. Using :code:`with`: it works just like opening a file, and will close when - the :code:`with` block's indentation ends. - - - .. testcode:: - - import anki_vector - - # Create the robot connection - with anki_vector.Robot() as robot: - # Run your commands - robot.anim.play_animation("anim_turn_left_01") - - 2. Using :func:`connect` and :func:`disconnect` to explicitly open and close the connection: - it allows the robot's connection to continue in the context in which it started. - - .. testcode:: - - import anki_vector - - # Create a Robot object - robot = anki_vector.Robot() - # Connect to the Robot - robot.connect() - # Run your commands - robot.anim.play_animation("anim_turn_left_01") - # Disconnect from Vector - robot.disconnect() - - :param serial: Vector's serial number. The robot's serial number (ex. 00e20100) is located on the underside of Vector, - or accessible from Vector's debug screen. Used to identify which Vector configuration to load. - :param ip: Vector's IP address. (optional) - :param config: A custom :class:`dict` to override values in Vector's configuration. (optional) - Example: :code:`{"cert": "/path/to/file.cert", "name": "Vector-XXXX", "guid": ""}` - where :code:`cert` is the certificate to identify Vector, :code:`name` is the name on Vector's face - when his backpack is double-clicked on the charger, and :code:`guid` is the authorization token - that identifies the SDK user. Note: Never share your authentication credentials with anyone. - :param default_logging: Toggle default logging. - :param behavior_activation_timeout: The time to wait for control of the robot before failing. - :param cache_animation_list: Get the list of animations available at startup. - :param enable_face_detection: Turn on face detection. - :param enable_camera_feed: Turn camera feed on/off. - :param enable_audio_feed: Turn audio feed on/off. - :param enable_custom_object_detection: Turn custom object detection on/off. - :param enable_nav_map_feed: Turn navigation map feed on/off. - :param show_viewer: Render camera feed on/off. - :param show_3d_viewer: Render camera feed on/off. - :param requires_behavior_control: Request control of Vector's behavior system.""" - - def __init__(self, - serial: str = None, - ip: str = None, - config: dict = None, - default_logging: bool = True, - behavior_activation_timeout: int = 10, - cache_animation_list: bool = True, - enable_face_detection: bool = False, - enable_camera_feed: bool = False, - enable_audio_feed: bool = False, - enable_custom_object_detection: bool = False, - enable_nav_map_feed: bool = None, - show_viewer: bool = False, - show_3d_viewer: bool = False, - requires_behavior_control: bool = True): - if default_logging: - util.setup_basic_logging() - self.logger = util.get_class_logger(__name__, self) - self._force_async = False - config = config if config is not None else {} - config = {**self._read_configuration(serial), **config} - - self._name = config["name"] - self._ip = ip if ip is not None else config["ip"] - self._cert_file = config["cert"] - self._guid = config["guid"] - - self._port = "443" - if 'port' in config: - self._port = config["port"] - - if self._name is None or self._ip is None or self._cert_file is None or self._guid is None: - raise ValueError("The Robot object requires a serial and for Vector to be logged in (using the app then running the anki_vector.configure executable submodule).\n" - "You may also provide the values necessary for connection through the config parameter. ex: " - '{"name":"Vector-XXXX", "ip":"XX.XX.XX.XX", "cert":"/path/to/cert_file", "guid":""}') - - #: :class:`anki_vector.connection.Connection`: The active connection to the robot. - self._conn = connection.Connection(self._name, ':'.join([self._ip, self._port]), self._cert_file, self._guid, requires_behavior_control=requires_behavior_control) - self._events = events.EventHandler() - - # placeholders for components before they exist - self._anim: animation.AnimationComponent = None - self._audio: audio.AudioComponent = None - self._behavior: behavior.BehaviorComponent = None - self._camera: camera.CameraComponent = None - self._faces: faces.FaceComponent = None - self._motors: motors.MotorComponent = None - self._nav_map: nav_map.NavMapComponent = None - self._screen: screen.ScreenComponent = None - self._photos: photos.PhotographComponent = None - self._proximity: proximity.ProximityComponent = None - self._touch: touch.TouchComponent = None - self._viewer: viewer.ViewerComponent = None - self._viewer_3d: viewer.Viewer3DComponent = None - self._vision: vision.VisionComponent = None - self._world: world.World = None - - self.behavior_activation_timeout = behavior_activation_timeout - self.enable_face_detection = enable_face_detection - self.enable_custom_object_detection = enable_custom_object_detection - self.cache_animation_list = cache_animation_list - - # Robot state/sensor data - self._pose: util.Pose = None - self._pose_angle_rad: float = None - self._pose_pitch_rad: float = None - self._left_wheel_speed_mmps: float = None - self._right_wheel_speed_mmps: float = None - self._head_angle_rad: float = None - self._lift_height_mm: float = None - self._accel: util.Vector3 = None - self._gyro: util.Vector3 = None - self._carrying_object_id: float = None - self._head_tracking_object_id: float = None - self._localized_to_object_id: float = None - self._last_image_time_stamp: float = None - self._status: status.RobotStatus = status.RobotStatus() - self.pending = [] - - self._enable_camera_feed = enable_camera_feed - self._enable_audio_feed = enable_audio_feed - if enable_nav_map_feed is not None: - self._enable_nav_map_feed = enable_nav_map_feed - else: - self._enable_nav_map_feed = False - self._show_viewer = show_viewer - if show_viewer and not enable_camera_feed: - self.logger.warning("enable_camera_feed should be True for viewer to render correctly.") - self._enable_camera_feed = True - self._show_3d_viewer = show_3d_viewer - if show_3d_viewer and enable_nav_map_feed is None: - self.logger.warning("enable_nav_map_feed should be True for 3d viewer to render correctly.") - self._enable_nav_map_feed = True - - def _read_configuration(self, serial: str) -> dict: - """Open the default conf file, and read it into a :class:`configparser.ConfigParser` - - :param serial: Vector's serial number - """ - home = Path.home() / ".anki_vector" - conf_file = str(home / "sdk_config.ini") - parser = configparser.ConfigParser(strict=False) - parser.read(conf_file) - - sections = parser.sections() - if not sections: - raise Exception('\n\nCould not find the sdk configuration file. Please run `python3 -m anki_vector.configure` to set up your Vector for SDK usage.') - elif serial is None and len(sections) == 1: - serial = sections[0] - self.logger.warning("No serial number provided. Automatically selecting {}".format(serial)) - elif serial is None: - raise Exception('\n\nFound multiple robot serial numbers. Please provide the serial number of the Robot you want to control.\n' - 'Example: ./01_hello_world.py --serial {robot_serial_number}') - - serial = serial.lower() - config = {k.lower(): v for k, v in parser.items()} - try: - dict_entry = config[serial] - except KeyError: - raise Exception('\n\nCould not find matching robot info for given serial number: {}. Please check your serial number is correct.\n' - 'Example: ./01_hello_world.py --serial {{robot_serial_number}}'.format(serial)) - - return dict_entry - - @property - def force_async(self) -> bool: - """A reference to the Robot object instance.""" - return self._force_async - - @property - def conn(self) -> connection.Connection: - """A reference to the Connection instance.""" - return self._conn - - @property - def events(self) -> events.EventHandler: - """A reference to the EventHandler instance.""" - return self._events - - @property - def anim(self) -> animation.AnimationComponent: - """A reference to the AnimationComponent instance.""" - if self._anim is None: - raise exceptions.VectorNotReadyException("AnimationComponent is not yet initialized") - return self._anim - - @property - def audio(self) -> audio.AudioComponent: - """The audio instance used to control Vector's audio feed.""" - - print("\n\nNote: Audio stream is not yet supported and does not yet come from Vector's microphones.\n\n") - - if self._audio is None: - raise exceptions.VectorNotReadyException("AudioComponent is not yet initialized") - return self._audio - - @property - def behavior(self) -> behavior.BehaviorComponent: - """A reference to the BehaviorComponent instance.""" - return self._behavior - - @property - def camera(self) -> camera.CameraComponent: - """The camera instance used to control Vector's camera feed. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot(enable_camera_feed=True) as robot: - image = robot.camera.latest_image - image.show() - """ - if self._camera is None: - raise exceptions.VectorNotReadyException("CameraComponent is not yet initialized") - return self._camera - - @property - def faces(self) -> faces.FaceComponent: - """A reference to the FaceComponent instance.""" - if self._faces is None: - raise exceptions.VectorNotReadyException("FaceComponent is not yet initialized") - return self._faces - - @property - def motors(self) -> motors.MotorComponent: - """A reference to the MotorComponent instance.""" - if self._motors is None: - raise exceptions.VectorNotReadyException("MotorComponent is not yet initialized") - return self._motors - - @property - def nav_map(self) -> nav_map.NavMapComponent: - """A reference to the NavMapComponent instance.""" - if self._nav_map is None: - raise exceptions.VectorNotReadyException("NavMapComponent is not yet initialized") - return self._nav_map - - @property - def screen(self) -> screen.ScreenComponent: - """A reference to the ScreenComponent instance.""" - if self._screen is None: - raise exceptions.VectorNotReadyException("ScreenComponent is not yet initialized") - return self._screen - - @property - def photos(self) -> photos.PhotographComponent: - """A reference to the PhotographComponent instance.""" - if self._photos is None: - raise exceptions.VectorNotReadyException("PhotographyComponent is not yet initialized") - return self._photos - - @property - def proximity(self) -> proximity.ProximityComponent: - """Component containing state related to object proximity detection. - - ..code-block :: - - import anki_vector - with anki_vector.Robot() as robot: - proximity_data = robot.proximity.last_valid_sensor_reading - if proximity_data is not None: - print(proximity_data.distance) - """ - return self._proximity - - @property - def touch(self) -> touch.TouchComponent: - """Component containing state related to object touch detection. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - print('Robot is being touched: {0}'.format(robot.touch.last_sensor_reading.is_being_touched)) - """ - return self._touch - - @property - def viewer(self) -> ViewerComponent: - """The viewer instance used to render Vector's camera feed. - - .. testcode:: - - import time - - import anki_vector - - with anki_vector.Robot(show_viewer=True) as robot: - # Render video for 5 seconds - robot.viewer.show_video() - time.sleep(5) - - # Disable video render and camera feed for 5 seconds - robot.viewer.stop_video() - """ - if self._viewer is None: - raise exceptions.VectorNotReadyException("ViewerComponent is not yet initialized") - return self._viewer - - @property - def viewer_3d(self) -> Viewer3DComponent: - """The 3D viewer instance used to render Vector's navigation map. - - .. testcode:: - - import time - - import anki_vector - - with anki_vector.Robot(show_3d_viewer=True, enable_nav_map_feed=True) as robot: - # Render 3D view of navigation map for 5 seconds - time.sleep(5) - """ - if self._viewer_3d is None: - raise exceptions.VectorNotReadyException("Viewer3DComponent is not yet initialized") - return self._viewer_3d - - @property - def vision(self) -> vision.VisionComponent: - """Component containing functionality related to vision based object detection. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - robot.vision.enable_custom_object_detection() - """ - return self._vision - - @property - def world(self) -> world.World: - """A reference to the World instance, or None if the WorldComponent is not yet initialized.""" - if self._world is None: - raise exceptions.VectorNotReadyException("WorldComponent is not yet initialized") - return self._world - - @property - @util.block_while_none() - def pose(self) -> util.Pose: - """:class:`anki_vector.util.Pose`: The current pose (position and orientation) of Vector. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - current_robot_pose = robot.pose - """ - return self._pose - - @property - @util.block_while_none() - def pose_angle_rad(self) -> float: - """Vector's pose angle (heading in X-Y plane). - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - current_pose_angle_rad = robot.pose_angle_rad - """ - return self._pose_angle_rad - - @property - @util.block_while_none() - def pose_pitch_rad(self) -> float: - """Vector's pose pitch (angle up/down). - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - current_pose_pitch_rad = robot.pose_pitch_rad - """ - return self._pose_pitch_rad - - @property - @util.block_while_none() - def left_wheel_speed_mmps(self) -> float: - """Vector's left wheel speed in mm/sec - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - current_left_wheel_speed_mmps = robot.left_wheel_speed_mmps - """ - return self._left_wheel_speed_mmps - - @property - @util.block_while_none() - def right_wheel_speed_mmps(self) -> float: - """Vector's right wheel speed in mm/sec - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - current_right_wheel_speed_mmps = robot.right_wheel_speed_mmps - """ - return self._right_wheel_speed_mmps - - @property - @util.block_while_none() - def head_angle_rad(self) -> float: - """Vector's head angle (up/down). - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - current_head_angle_rad = robot.head_angle_rad - """ - return self._head_angle_rad - - @property - @util.block_while_none() - def lift_height_mm(self) -> float: - """Height of Vector's lift from the ground. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - current_lift_height_mm = robot.lift_height_mm - """ - return self._lift_height_mm - - @property - @util.block_while_none() - def accel(self) -> util.Vector3: - """:class:`anki_vector.util.Vector3`: The current accelerometer reading (x, y, z) - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - current_accel = robot.accel - """ - return self._accel - - @property - @util.block_while_none() - def gyro(self) -> util.Vector3: - """The current gyroscope reading (x, y, z) - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - current_gyro = robot.gyro - """ - return self._gyro - - @property - @util.block_while_none() - def carrying_object_id(self) -> int: - """The ID of the object currently being carried (-1 if none) - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - current_carrying_object_id = robot.carrying_object_id - """ - return self._carrying_object_id - - @property - @util.block_while_none() - def head_tracking_object_id(self) -> int: - """The ID of the object the head is tracking to (-1 if none) - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - current_head_tracking_object_id = robot.head_tracking_object_id - """ - return self._head_tracking_object_id - - @property - @util.block_while_none() - def localized_to_object_id(self) -> int: - """The ID of the object that the robot is localized to (-1 if none) - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - current_localized_to_object_id = robot.localized_to_object_id - """ - return self._localized_to_object_id - - # TODO Move to photos or somewhere else - @property - @util.block_while_none() - def last_image_time_stamp(self) -> int: - """The robot's timestamp for the last image seen. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - current_last_image_time_stamp = robot.last_image_time_stamp - """ - return self._last_image_time_stamp - - @property - def status(self) -> status.RobotStatus: - """A property that exposes various status properties of the robot. - - This status provides a simple mechanism to, for example, detect if any - of Vector's motors are moving, determine if Vector is being held, or if - he is on the charger. The full list is available in the - :class:`RobotStatus ` class documentation. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - if robot.status.is_being_held: - print("Vector is being held!") - else: - print("Vector is not being held.") - """ - return self._status - - @property - def enable_audio_feed(self) -> bool: - """The audio feed enabled/disabled - - :getter: Returns whether the audio feed is enabled - :setter: Enable/disable the audio feed - - .. code-block:: python - - import asyncio - import time - - import anki_vector - - with anki_vector.Robot(enable_audio_feed=True) as robot: - time.sleep(5) - robot.enable_audio_feed = False - time.sleep(5) - """ - # TODO When audio is ready, convert `.. code-block:: python` to `.. testcode::` - return self._enable_audio_feed - - @enable_audio_feed.setter - def enable_audio_feed(self, enable) -> None: - self._enable_audio_feed = enable - if self.enable_audio_feed: - self.audio.init_audio_feed() - - @property - def enable_camera_feed(self) -> bool: - """The camera feed enabled/disabled - - :getter: Returns whether the camera feed is enabled - :setter: Enable/disable the camera feed - - .. testcode:: - - import asyncio - import time - - import anki_vector - - with anki_vector.Robot(enable_camera_feed=True) as robot: - time.sleep(5) - robot.enable_camera_feed = False - time.sleep(5) - """ - return self._enable_camera_feed - - @enable_camera_feed.setter - def enable_camera_feed(self, enable) -> None: - self._enable_camera_feed = enable - if self.enable_camera_feed: - self.camera.init_camera_feed() - else: - self.camera.close_camera_feed() - - # Unpack streamed data to robot's internal properties - def _unpack_robot_state(self, _, msg): - self._pose = util.Pose(x=msg.pose.x, y=msg.pose.y, z=msg.pose.z, - q0=msg.pose.q0, q1=msg.pose.q1, - q2=msg.pose.q2, q3=msg.pose.q3, - origin_id=msg.pose.origin_id) - self._pose_angle_rad = msg.pose_angle_rad - self._pose_pitch_rad = msg.pose_pitch_rad - self._left_wheel_speed_mmps = msg.left_wheel_speed_mmps - self._right_wheel_speed_mmps = msg.right_wheel_speed_mmps - self._head_angle_rad = msg.head_angle_rad - self._lift_height_mm = msg.lift_height_mm - self._accel = util.Vector3(msg.accel.x, msg.accel.y, msg.accel.z) - self._gyro = util.Vector3(msg.gyro.x, msg.gyro.y, msg.gyro.z) - self._carrying_object_id = msg.carrying_object_id - self._head_tracking_object_id = msg.head_tracking_object_id - self._localized_to_object_id = msg.localized_to_object_id - self._last_image_time_stamp = msg.last_image_time_stamp - self._status.set(msg.status) - - def connect(self, timeout: int = 10) -> None: - """Start the connection to Vector. - - .. testcode:: - - import anki_vector - - robot = anki_vector.Robot() - robot.connect() - robot.anim.play_animation("anim_turn_left_01") - robot.disconnect() - - :param timeout: The time to allow for a connection before a - :class:`anki_vector.exceptions.VectorTimeoutException` is raised. - """ - self.conn.connect(timeout=timeout) - self.events.start(self.conn) - - # Initialize components - self._anim = animation.AnimationComponent(self) - # self._audio = audio.AudioComponent(self) # TODO turn on - self._behavior = behavior.BehaviorComponent(self) - self._camera = camera.CameraComponent(self) - self._faces = faces.FaceComponent(self) - self._motors = motors.MotorComponent(self) - self._nav_map = nav_map.NavMapComponent(self) - self._screen = screen.ScreenComponent(self) - self._photos = photos.PhotographComponent(self) - self._proximity = proximity.ProximityComponent(self) - self._touch = touch.TouchComponent(self) - self._viewer = viewer.ViewerComponent(self) - self._viewer_3d = viewer.Viewer3DComponent(self) - self._vision = vision.VisionComponent(self) - self._world = world.World(self) - - if self.cache_animation_list: - # Load animations so they are ready to play when requested - anim_request = self._anim.load_animation_list() - if isinstance(anim_request, concurrent.futures.Future): - anim_request.result() - - # Start audio feed - if self.enable_audio_feed: - self.audio.init_audio_feed() - - # Start camera feed - if self.enable_camera_feed: - self.camera.init_camera_feed() - - # Start rendering camera feed - if self._show_viewer: - self.viewer.show_video() - - if self._show_3d_viewer: - self.viewer_3d.show() - - if self._enable_nav_map_feed: - self.nav_map.init_nav_map_feed() - - # Enable face detection, to allow Vector to add faces to its world view - if self.conn.requires_behavior_control: - face_detection = self.vision.enable_face_detection(detect_faces=self.enable_face_detection, estimate_expression=False) - if isinstance(face_detection, concurrent.futures.Future): - face_detection.result() - object_detection = self.vision.enable_custom_object_detection(detect_custom_objects=self.enable_custom_object_detection) - if isinstance(object_detection, concurrent.futures.Future): - object_detection.result() - - # Subscribe to a callback that updates the robot's local properties - self.events.subscribe(self._unpack_robot_state, - events.Events.robot_state, - on_connection_thread=True) - - # access the pose to prove it has gotten back from the event stream once. - while not self.pose: - pass - - def disconnect(self) -> None: - """Close the connection with Vector. - - .. testcode:: - - import anki_vector - robot = anki_vector.Robot() - robot.connect() - robot.anim.play_animation("anim_turn_left_01") - robot.disconnect() - """ - if self.conn.requires_behavior_control: - self.vision.close() - - # Stop rendering video - self.viewer.stop_video() - # Stop rendering 3d video - self.viewer_3d.close() - # Shutdown camera feed - self.camera.close_camera_feed() - self._enable_camera_feed = False - # Shutdown audio feed - if self._audio is not None: - self._audio.close_audio_feed() - # Shutdown nav map feed - self.nav_map.close_nav_map_feed() - # Close the world and cleanup its objects - self.world.close() - - self.proximity.close() - self.touch.close() - - self.events.close() - self.conn.close() - - def __enter__(self): - self.connect(self.behavior_activation_timeout) - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self.disconnect() - - @connection.on_connection_thread(requires_control=False) - async def get_battery_state(self) -> protocol.BatteryStateResponse: - """Check the current state of the robot and cube batteries. - - Vector is considered fully-charged above 4.1 volts. At 3.6V, the robot is approaching low charge. - - Battery_level values are as follows: - | Low = 1: 3.6V or less. If on charger, 4V or less. - | Nominal = 2 - | Full = 3: This state can only be achieved when Vector is on the charger. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - battery_state = robot.get_battery_state() - if battery_state: - print("Robot battery voltage: {0}".format(battery_state.battery_volts)) - print("Robot battery Level: {0}".format(battery_state.battery_level)) - print("Robot battery is charging: {0}".format(battery_state.is_charging)) - print("Robot is on charger platform: {0}".format(battery_state.is_on_charger_platform)) - print("Robot's suggested charger time: {0}".format(battery_state.suggested_charger_sec)) - """ - get_battery_state_request = protocol.BatteryStateRequest() - return await self.conn.grpc_interface.BatteryState(get_battery_state_request) - - @connection.on_connection_thread(requires_control=False) - async def get_version_state(self) -> protocol.VersionStateResponse: - """Get the versioning information for Vector, including Vector's os_version and engine_build_id. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - version_state = robot.get_version_state() - """ - get_version_state_request = protocol.VersionStateRequest() - return await self.conn.grpc_interface.VersionState(get_version_state_request) - - @connection.on_connection_thread(requires_control=False) - async def get_network_state(self) -> protocol.NetworkStateResponse: - """Get the network information for Vector. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - network_state = robot.get_network_state() - """ - get_network_state_request = protocol.NetworkStateRequest() - return await self.conn.grpc_interface.NetworkState(get_network_state_request) - - @connection.on_connection_thread() - async def say_text(self, text: str, use_vector_voice: bool = True, duration_scalar: float = 1.0) -> protocol.SayTextResponse: - """Make Vector speak text. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - robot.say_text("Hello World") - - :param text: The words for Vector to say. - :param use_vector_voice: Whether to use Vector's robot voice - (otherwise, he uses a generic human male voice). - :param duration_scalar: Adjust the relative duration of the - generated text to speech audio. - - :return: object that provides the status and utterance state - """ - say_text_request = protocol.SayTextRequest(text=text, - use_vector_voice=use_vector_voice, - duration_scalar=duration_scalar) - return await self.conn.grpc_interface.SayText(say_text_request) - - -class AsyncRobot(Robot): - """The AsyncRobot object is just like the Robot object, but allows multiple commands - to be executed at the same time. To achieve this, all grpc function calls also - return a :class:`concurrent.futures.Future`. - - 1. Using :code:`with`: it works just like opening a file, and will close when - the :code:`with` block's indentation ends. - - .. testcode:: - - import anki_vector - # Create the robot connection - with anki_vector.AsyncRobot() as robot: - # Run your commands - robot.anim.play_animation("anim_turn_left_01").result() - - 2. Using :func:`connect` and :func:`disconnect` to explicitly open and close the connection: - it allows the robot's connection to continue in the context in which it started. - - .. testcode:: - - import anki_vector - # Create a Robot object - robot = anki_vector.AsyncRobot() - # Connect to Vector - robot.connect() - # Run your commands - robot.anim.play_animation("anim_turn_left_01").result() - # Disconnect from Vector - robot.disconnect() - - :param serial: Vector's serial number. Used to identify which Vector configuration to load. - :param ip: Vector's IP Address. (optional) - :param config: A custom :class:`dict` to override values in Vector's configuration. (optional) - Example: :code:`{"cert": "/path/to/file.cert", "name": "Vector-XXXX", "guid": ""}` - where :code:`cert` is the certificate to identify Vector, :code:`name` is the name on Vector's face - when his backpack is double-clicked on the charger, and :code:`guid` is the authorization token - that identifies the SDK user. Note: Never share your authentication credentials with anyone. - :param default_logging: Toggle default logging. - :param behavior_activation_timeout: The time to wait for control of the robot before failing. - :param enable_face_detection: Turn on face detection. - :param enable_camera_feed: Turn camera feed on/off. - :param enable_audio_feed: Turn audio feed on/off. - :param show_viewer: Render camera feed on/off. - :param requires_behavior_control: Request control of Vector's behavior system.""" - - @functools.wraps(Robot.__init__) - def __init__(self, *args, **kwargs): - super(AsyncRobot, self).__init__(*args, **kwargs) - self._force_async = True - - # TODO Should be private? Better method name? If not private, Add docstring and sample code - def add_pending(self, task): - self.pending += [task] - - # TODO Should be private? Better method name? If not private, Add docstring and sample code - def remove_pending(self, task): - self.pending = [x for x in self.pending if x is not task] diff --git a/anki_vector/screen.py b/anki_vector/screen.py deleted file mode 100644 index 0f4f019..0000000 --- a/anki_vector/screen.py +++ /dev/null @@ -1,194 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Vector's LCD Screen that displays his face. - -The screen is 184 x 96 color (RGB565) pixels. The active area is 23.2mm x 12.1mm. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['dimensions', 'convert_image_to_screen_data', - 'convert_pixels_to_screen_data', 'ScreenComponent'] - -import sys - -from . import color, connection, util -from .messaging import protocol - -try: - from PIL import Image -except ImportError: - sys.exit("Cannot import from PIL: Do `pip3 install --user Pillow` to install") - -SCREEN_WIDTH = 184 -SCREEN_HEIGHT = 96 - - -def dimensions(): - """Return the dimension (width, height) of the Screen. - - .. testcode:: - - import anki_vector - - screen_dimensions = anki_vector.screen.SCREEN_WIDTH, anki_vector.screen.SCREEN_HEIGHT - - Returns: - A tuple of ints (width, height) - """ - return SCREEN_WIDTH, SCREEN_HEIGHT - - -def convert_pixels_to_screen_data(pixel_data: list, image_width: int, image_height: int): - """Convert a sequence of pixel data to the correct format to display on Vector's face. - - :param pixel_data: sequence of triplets representing rgb values, should be ints from 0-255 - :param image_width: width of the image defined by the pixel_data - :param image_height: height of the image defined by the pixel_data - - .. testcode:: - - import anki_vector - from anki_vector.screen import convert_pixels_to_screen_data - from PIL import Image - - image_file = Image.open('../examples/face_images/cozmo_image.jpg') - image_data = image_file.getdata() - pixel_bytes = convert_pixels_to_screen_data(image_data, image_file.width, image_file.height) - - Returns: - A :class:`bytes` object representing all of the pixels (16bit color in rgb565 format) - - Raises: - ValueError: Invalid Dimensions - ValueError: Bad image_width - ValueError: Bad image_height - """ - if len(pixel_data) != (image_width * image_height): - raise ValueError('Invalid Dimensions: len(pixel_data) {0} != image_width={1} * image_height={2} (== {3})'. format(len(pixel_data), - image_width, - image_height, - image_width * - image_height)) - - # @TODO: We should decide on a resampling approach and have this function automatically rescale images - # We should either enforce the aspect ratio, or have options to: - # - automatically crop to the proper aspect ratio - # - stretch to fit - # - shrink to fit with margins some default color - if image_width != SCREEN_WIDTH: - raise ValueError('Bad image_width: image_width {0} must be the resolution width: {1}'. format(image_width, SCREEN_WIDTH)) - - if image_height != SCREEN_HEIGHT: - raise ValueError('Bad image_height: image_height {0} must be the resolution height: {1}'. format(image_height, SCREEN_HEIGHT)) - - color_565_data = [] - for color_tuple in pixel_data: - color_object = color.Color(rgb=color_tuple) - color_565_data.extend(color_object.rgb565_bytepair) - - return bytes(color_565_data) - - -def convert_image_to_screen_data(pil_image: Image.Image): - """Convert an image into the correct format to display on Vector's face. - - .. testcode:: - - import anki_vector - - try: - from PIL import Image - except ImportError: - sys.exit("Cannot import from PIL: Do `pip3 install --user Pillow` to install") - - with anki_vector.Robot() as robot: - # Load an image - image_file = Image.open('../examples/face_images/cozmo_image.jpg') - - # Convert the image to the format used by the Screen - screen_data = anki_vector.screen.convert_image_to_screen_data(image_file) - robot.screen.set_screen_with_image_data(screen_data, 4.0) - - :param pil_image: The image to display on Vector's face - - Returns: - A :class:`bytes` object representing all of the pixels (16bit color in rgb565 format) - """ - image_data = pil_image.getdata() - - return convert_pixels_to_screen_data(image_data, pil_image.width, pil_image.height) - - -class ScreenComponent(util.Component): - """Handles messaging to control Vector's screen""" - - @connection.on_connection_thread(log_messaging=False) - async def set_screen_with_image_data(self, image_data: bytes, duration_sec: float, interrupt_running: bool = True): - """ - Display an image on Vector's Screen (his "face"). - - .. testcode:: - - import anki_vector - - try: - from PIL import Image - except ImportError: - sys.exit("Cannot import from PIL: Do `pip3 install --user Pillow` to install") - - with anki_vector.Robot() as robot: - # Load an image - image_file = Image.open('../examples/face_images/cozmo_image.jpg') - - # Convert the image to the format used by the Screen - screen_data = anki_vector.screen.convert_image_to_screen_data(image_file) - robot.screen.set_screen_with_image_data(screen_data, 4.0) - - :param image_data: A :class:`bytes` object representing all of the pixels (16bit color in rgb565 format) - :param duration_sec: The number of seconds the image should remain on Vector's face. - :param interrupt_running: Set to true so any currently-streaming animation will be aborted in favor of this. - """ - if not isinstance(image_data, bytes): - raise ValueError("set_screen_with_image_data expected bytes") - if len(image_data) != 35328: - raise ValueError("set_screen_with_image_data expected 35328 bytes - (2 bytes each for 17664 pixels)") - - # Generate the message - message = protocol.DisplayFaceImageRGBRequest() - # Create byte array at the Screen resolution - message.face_data = image_data - message.duration_ms = int(1000 * duration_sec) - message.interrupt_running = interrupt_running - - return await self.grpc_interface.DisplayFaceImageRGB(message) - - def set_screen_to_color(self, solid_color: color.Color, duration_sec: float, interrupt_running: bool = True): - """ - Set Vector's Screen (his "face"). to a solid color. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.screen.set_screen_to_color(anki_vector.color.Color(rgb=[255, 128, 0]), duration_sec=1.0) - - :param solid_color: Desired color to set Vector's Screen. - :param duration_sec: The number of seconds the color should remain on Vector's face. - :param interrupt_running: Set to true so any currently-streaming animation will be aborted in favor of this. - """ - image_data = bytes(solid_color.rgb565_bytepair * 17664) - return self.set_screen_with_image_data(image_data, duration_sec, interrupt_running) diff --git a/anki_vector/status.py b/anki_vector/status.py deleted file mode 100644 index f3166bb..0000000 --- a/anki_vector/status.py +++ /dev/null @@ -1,314 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -.. _status: - -Robot Status class and exposed properties for Vector's various states. - -The :class:`RobotStatus` class in this module exposes properties -about the robot status like :py:attr:`is_charging `, -:py:attr:`is_being_held `, etc. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['ROBOT_STATUS_NONE', 'ROBOT_STATUS_ARE_MOTORS_MOVING', 'ROBOT_STATUS_IS_CARRYING_BLOCK', - 'ROBOT_STATUS_IS_DOCKING_TO_MARKER', 'ROBOT_STATUS_IS_PICKED_UP', 'ROBOT_STATUS_IS_BUTTON_PRESSED', - 'ROBOT_STATUS_IS_FALLING', 'ROBOT_STATUS_IS_ANIMATING', 'ROBOT_STATUS_IS_PATHING', - 'ROBOT_STATUS_LIFT_IN_POS', 'ROBOT_STATUS_HEAD_IN_POS', 'ROBOT_STATUS_CALM_POWER_MODE', - 'ROBOT_STATUS_IS_ON_CHARGER', 'ROBOT_STATUS_IS_CHARGING', 'ROBOT_STATUS_CLIFF_DETECTED', - 'ROBOT_STATUS_ARE_WHEELS_MOVING', 'ROBOT_STATUS_IS_BEING_HELD', 'ROBOT_STATUS_IS_ROBOT_MOVING', - 'RobotStatus'] - -from . import util -from .messaging import protocol - -ROBOT_STATUS_NONE = protocol.RobotStatus.Value("ROBOT_STATUS_NONE") -ROBOT_STATUS_ARE_MOTORS_MOVING = protocol.RobotStatus.Value("ROBOT_STATUS_IS_MOVING") -ROBOT_STATUS_IS_CARRYING_BLOCK = protocol.RobotStatus.Value("ROBOT_STATUS_IS_CARRYING_BLOCK") -ROBOT_STATUS_IS_DOCKING_TO_MARKER = protocol.RobotStatus.Value("ROBOT_STATUS_IS_PICKING_OR_PLACING") -ROBOT_STATUS_IS_PICKED_UP = protocol.RobotStatus.Value("ROBOT_STATUS_IS_PICKED_UP") -ROBOT_STATUS_IS_BUTTON_PRESSED = protocol.RobotStatus.Value("ROBOT_STATUS_IS_BUTTON_PRESSED") -ROBOT_STATUS_IS_FALLING = protocol.RobotStatus.Value("ROBOT_STATUS_IS_FALLING") -ROBOT_STATUS_IS_ANIMATING = protocol.RobotStatus.Value("ROBOT_STATUS_IS_ANIMATING") -ROBOT_STATUS_IS_PATHING = protocol.RobotStatus.Value("ROBOT_STATUS_IS_PATHING") -ROBOT_STATUS_LIFT_IN_POS = protocol.RobotStatus.Value("ROBOT_STATUS_LIFT_IN_POS") -ROBOT_STATUS_HEAD_IN_POS = protocol.RobotStatus.Value("ROBOT_STATUS_HEAD_IN_POS") -ROBOT_STATUS_CALM_POWER_MODE = protocol.RobotStatus.Value("ROBOT_STATUS_CALM_POWER_MODE") -ROBOT_STATUS_IS_ON_CHARGER = protocol.RobotStatus.Value("ROBOT_STATUS_IS_ON_CHARGER") -ROBOT_STATUS_IS_CHARGING = protocol.RobotStatus.Value("ROBOT_STATUS_IS_CHARGING") -ROBOT_STATUS_CLIFF_DETECTED = protocol.RobotStatus.Value("ROBOT_STATUS_CLIFF_DETECTED") -ROBOT_STATUS_ARE_WHEELS_MOVING = protocol.RobotStatus.Value("ROBOT_STATUS_ARE_WHEELS_MOVING") -ROBOT_STATUS_IS_BEING_HELD = protocol.RobotStatus.Value("ROBOT_STATUS_IS_BEING_HELD") -ROBOT_STATUS_IS_ROBOT_MOVING = protocol.RobotStatus.Value("ROBOT_STATUS_IS_MOTION_DETECTED") - - -class RobotStatus(): - """A class to expose various status properties of the robot.""" - - def __init__(self): - # Default robot status - self._status: int = None - - def set(self, status: int): - self._status = status - - @util.block_while_none() - def __get(self) -> int: - return self._status - - @property - def are_motors_moving(self) -> bool: - """True if Vector is currently moving any of his motors (head, arm or - wheels/treads). - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.are_motors_moving: - print("Vector is moving.") - """ - return (self.__get() & ROBOT_STATUS_ARE_MOTORS_MOVING) != 0 - - @property - def is_carrying_block(self) -> bool: - """True if Vector is currently carrying a block. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.is_carrying_block: - print("Vector is carrying his block.") - """ - return (self.__get() & ROBOT_STATUS_IS_CARRYING_BLOCK) != 0 - - @property - def is_docking_to_marker(self) -> bool: - """True if Vector has seen a marker and is actively heading toward it - (for example his charger or cube). - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.is_docking_to_marker: - print("Vector has found a marker and is docking to it.") - """ - return (self.__get() & ROBOT_STATUS_IS_DOCKING_TO_MARKER) != 0 - - @property - def is_picked_up(self) -> bool: - """True if Vector is currently picked up (in the air). - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.is_picked_up: - print("Vector is picked up.") - """ - return (self.__get() & ROBOT_STATUS_IS_PICKED_UP) != 0 - - @property - def is_button_pressed(self) -> bool: - """True if Vector's button is pressed. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.is_button_pressed: - print("Vector's button was button pressed.") - """ - return (self.__get() & ROBOT_STATUS_IS_BUTTON_PRESSED) != 0 - - @property - def is_falling(self) -> bool: - """True if Vector is currently falling. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.is_falling: - print("Vector is falling.") - """ - return (self.__get() & ROBOT_STATUS_IS_FALLING) != 0 - - @property - def is_animating(self) -> bool: - """True if Vector is currently playing an animation. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.is_animating: - print("Vector is animating.") - """ - return (self.__get() & ROBOT_STATUS_IS_ANIMATING) != 0 - - @property - def is_pathing(self) -> bool: - """True if Vector is currently traversing a path. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.is_pathing: - print("Vector is traversing a path.") - """ - return (self.__get() & ROBOT_STATUS_IS_PATHING) != 0 - - @property - def is_lift_in_pos(self) -> bool: - """True if Vector's arm is in the desired position (False if still - trying to move it there). - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.is_lift_in_pos: - print("Vector's arm is in position.") - """ - return (self.__get() & ROBOT_STATUS_LIFT_IN_POS) != 0 - - @property - def is_head_in_pos(self) -> bool: - """True if Vector's head is in the desired position (False if still - trying to move there). - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.is_head_in_pos: - print("Vector's head is in position.") - """ - return (self.__get() & ROBOT_STATUS_HEAD_IN_POS) != 0 - - @property - def is_in_calm_power_mode(self) -> bool: - """True if Vector is in calm power mode. Calm power mode is generally - when Vector is sleeping or charging. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.is_in_calm_power_mode: - print("Vector is in calm power mode.") - """ - return (self.__get() & ROBOT_STATUS_CALM_POWER_MODE) != 0 - - @property - def is_on_charger(self) -> bool: - """True if Vector is currently on the charger. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.is_on_charger: - print("Vector is on the charger.") - """ - return (self.__get() & ROBOT_STATUS_IS_ON_CHARGER) != 0 - - @property - def is_charging(self) -> bool: - """True if Vector is currently charging. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.is_charging: - print("Vector is currently charging.") - """ - return (self.__get() & ROBOT_STATUS_IS_CHARGING) != 0 - - @property - def is_cliff_detected(self) -> bool: - """True if Vector detected a cliff using any of his four cliff sensors. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.is_cliff_detected: - print("Vector has detected a cliff.") - """ - return (self.__get() & ROBOT_STATUS_CLIFF_DETECTED) != 0 - - @property - def are_wheels_moving(self) -> bool: - """True if Vector's wheels/treads are currently moving. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.are_wheels_moving: - print("Vector's wheels are moving.") - """ - return (self.__get() & ROBOT_STATUS_ARE_WHEELS_MOVING) != 0 - - @property - def is_being_held(self) -> bool: - """True if Vector is being held. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.is_being_held: - print("Vector is being held.") - """ - return (self.__get() & ROBOT_STATUS_IS_BEING_HELD) != 0 - - @property - def is_robot_moving(self) -> bool: - """True if Vector is in motion. This includes any of his motors - (head, arm, wheels/tracks) and if he is being lifted, carried, - or falling. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - if robot.status.is_robot_moving: - print("Vector has is in motion.") - """ - return (self.__get() & ROBOT_STATUS_IS_ROBOT_MOVING) != 0 diff --git a/anki_vector/touch.py b/anki_vector/touch.py deleted file mode 100755 index f0faed6..0000000 --- a/anki_vector/touch.py +++ /dev/null @@ -1,119 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Support for Vector's touch sensor. - -The robot will forward a raw sensor reading representing the capacitance detected -on its back sensor. Accompanied with this value is a true/false flag that takes into -account other aspects of the robot's state to evaluate whether the robot thinks it is -being touched or not. This flag is the same value used internally for petting detection. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ["TouchComponent", "TouchSensorData"] - -from . import util -from .events import Events -from .messaging import protocol - - -class TouchSensorData: - """A touch sample from the capacitive touch sensor, accompanied with the robot's - conclusion on whether this is considered a valid touch. - """ - - def __init__(self, proto_data: protocol.TouchData): - self._raw_touch_value = proto_data.raw_touch_value - self._is_being_touched = proto_data.is_being_touched - - @property - def raw_touch_value(self) -> int: - """The detected sensitivity from the touch sensor. - - This will not map to a constant raw value, as it may be impacted by various - environmental factors such as whether the robot is on its charger, being held, humidity, etc. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - touch_data = robot.touch.last_sensor_reading - if touch_data is not None: - raw_touch_value = touch_data.raw_touch_value - """ - return self._raw_touch_value - - @property - def is_being_touched(self) -> bool: - """The robot's conclusion on whether the current value is considered - a valid touch. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - touch_data = robot.touch.last_sensor_reading - if touch_data is not None: - is_being_touched = touch_data.is_being_touched - """ - return self._is_being_touched - - -class TouchComponent(util.Component): - """Maintains the most recent touch sensor data - - This will be updated with every broadcast RobotState, and can be queried at any time. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - touch_data = robot.touch.last_sensor_reading - if touch_data is not None: - print('Touch sensor value: {0}, is being touched: {1}'.format(touch_data.raw_touch_value, touch_data.is_being_touched)) - """ - - def __init__(self, robot): - super().__init__(robot) - self._last_sensor_reading = None - - # Subscribe to a callback that updates the robot's local properties - which includes touch data. - self._robot.events.subscribe(self._on_robot_state, - Events.robot_state, - on_connection_thread=True) - - def close(self): - """Closing the touch component will unsubscribe from robot state updates.""" - self._robot.events.unsubscribe(self._on_robot_state, - Events.robot_state) - - @property - def last_sensor_reading(self) -> TouchSensorData: - """:class:`anki_vector.touch.TouchSensorData`: The last reported sensor data. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - touch_data = robot.touch.last_sensor_reading - """ - return self._last_sensor_reading - - def _on_robot_state(self, _, msg): - self._last_sensor_reading = TouchSensorData(msg.touch_data) diff --git a/anki_vector/util.py b/anki_vector/util.py deleted file mode 100644 index e8c4817..0000000 --- a/anki_vector/util.py +++ /dev/null @@ -1,1048 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Utility functions and classes for the Vector SDK. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['Angle', - 'BaseOverlay', - 'Component', - 'Distance', - 'ImageRect', - 'Matrix44', - 'Pose', - 'Position', - 'Quaternion', - 'RectangleOverlay', - 'Speed', - 'Vector2', - 'Vector3', - 'angle_z_to_quaternion', - 'block_while_none', - 'degrees', - 'distance_mm', - 'distance_inches', - 'get_class_logger', - 'parse_command_args', - 'radians', - 'setup_basic_logging', - 'speed_mmps'] - -import argparse -from functools import wraps -import logging -import math -import os -import sys -import time -from typing import Callable - -from .messaging import protocol - -try: - from PIL import Image, ImageDraw -except ImportError: - sys.exit("Cannot import from PIL: Do `pip3 install --user Pillow` to install") - -# TODO Move to the robot class - - -def parse_command_args(parser: argparse.ArgumentParser = None): - """ - Parses command line arguments. - - Attempts to read the robot serial number from the command line arguments. If no serial number - is specified, we next attempt to read the robot serial number from environment variable ANKI_ROBOT_SERIAL. - If ANKI_ROBOT_SERIAL is specified, the value will be used as the robot's serial number. - - .. code-block:: python - - import anki_vector - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument("--new_param") - args = anki_vector.util.parse_command_args(parser) - - :param parser: To add new command line arguments, - pass an argparse parser with the new options - already defined. Leave empty to use the defaults. - """ - if parser is None: - parser = argparse.ArgumentParser() - parser.add_argument("-s", "--serial", nargs='?', default=os.environ.get('ANKI_ROBOT_SERIAL', None)) - return parser.parse_args() - - -def block_while_none(interval: float = 0.1, max_iterations: int = 50): - """Use this to denote a property that may need some delay before it appears. - - :param interval: how often to check if the property is no longer None - :param max_iterations: how many times to check the property before raising an error - """ - def blocker(func: Callable): - @wraps(func) - def wrapped(*args, **kwargs): - iterations = 0 - result = func(*args, **kwargs) - while result is None: - time.sleep(interval) - iterations += 1 - if iterations > max_iterations: - raise Exception("Value not ready") - result = func(*args, **kwargs) - return result - return wrapped - return blocker - - -def setup_basic_logging(custom_handler: logging.Handler = None, - general_log_level: str = None, - target: object = None): - """Helper to perform basic setup of the Python logger. - - :param custom_handler: provide an external logger for custom logging locations - :param general_log_level: 'DEBUG', 'INFO', 'WARN', 'ERROR' or an equivalent - constant from the :mod:`logging` module. If None then a - value will be read from the VECTOR_LOG_LEVEL environment variable. - :param target: The stream to send the log data to; defaults to stderr - """ - if general_log_level is None: - general_log_level = os.environ.get('VECTOR_LOG_LEVEL', logging.INFO) - - handler = custom_handler - if handler is None: - handler = logging.StreamHandler(stream=target) - formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s') - handler.setFormatter(formatter) - - vector_logger = logging.getLogger('anki_vector') - if not vector_logger.handlers: - vector_logger.addHandler(handler) - vector_logger.setLevel(general_log_level) - - -def get_class_logger(module: str, obj: object) -> logging.Logger: - """Helper to create logger for a given class (and module). - - .. testcode:: - - import anki_vector - - logger = anki_vector.util.get_class_logger("module_name", "object_name") - - :param module: The name of the module to which the object belongs. - :param obj: the object that owns the logger. - """ - return logging.getLogger(".".join([module, type(obj).__name__])) - - -class Vector2: - """Represents a 2D Vector (type/units aren't specified). - - :param x: X component - :param y: Y component - """ - - __slots__ = ('_x', '_y') - - def __init__(self, x: float, y: float): - self._x = float(x) - self._y = float(y) - - def set_to(self, rhs): - """Copy the x and y components of the given Vector2 instance. - - :param rhs: The right-hand-side of this assignment - the - source Vector2 to copy into this Vector2 instance. - """ - self._x = float(rhs.x) - self._y = float(rhs.y) - - @property - def x(self) -> float: - """The x component.""" - return self._x - - @property - def y(self) -> float: - """The y component.""" - return self._y - - @property - def x_y(self): - """tuple (float, float): The X, Y elements of the Vector2 (x,y)""" - return self._x, self._y - - def __repr__(self): - return "<%s x: %.2f y: %.2f>" % (self.__class__.__name__, self.x, self.y) - - def __add__(self, other): - if not isinstance(other, Vector2): - raise TypeError("Unsupported operand for + expected Vector2") - return Vector2(self.x + other.x, self.y + other.y) - - def __sub__(self, other): - if not isinstance(other, Vector2): - raise TypeError("Unsupported operand for - expected Vector2") - return Vector2(self.x - other.x, self.y - other.y) - - def __mul__(self, other): - if not isinstance(other, (int, float)): - raise TypeError("Unsupported operand for * expected number") - return Vector2(self.x * other, self.y * other) - - def __truediv__(self, other): - if not isinstance(other, (int, float)): - raise TypeError("Unsupported operand for / expected number") - return Vector2(self.x / other, self.y / other) - - -class Vector3: - """Represents a 3D Vector (type/units aren't specified). - - :param x: X component - :param y: Y component - :param z: Z component - """ - - __slots__ = ('_x', '_y', '_z') - - def __init__(self, x: float, y: float, z: float): - self._x = float(x) - self._y = float(y) - self._z = float(z) - - def set_to(self, rhs): - """Copy the x, y and z components of the given Vector3 instance. - - :param rhs: The right-hand-side of this assignment - the - source Vector3 to copy into this Vector3 instance. - """ - self._x = float(rhs.x) - self._y = float(rhs.y) - self._z = float(rhs.z) - - @property - def x(self) -> float: - """The x component.""" - return self._x - - @property - def y(self) -> float: - """The y component.""" - return self._y - - @property - def z(self) -> float: - """The z component.""" - return self._z - - @property - def magnitude_squared(self) -> float: - """float: The magnitude of the Vector3 instance""" - return self._x**2 + self._y**2 + self._z**2 - - @property - def magnitude(self) -> float: - """The magnitude of the Vector3 instance""" - return math.sqrt(self.magnitude_squared) - - @property - def normalized(self): - """A Vector3 instance with the same direction and unit magnitude""" - mag = self.magnitude - if mag == 0: - return Vector3(0, 0, 0) - return Vector3(self._x / mag, self._y / mag, self._z / mag) - - def dot(self, other): - """The dot product of this and another Vector3 instance""" - if not isinstance(other, Vector3): - raise TypeError("Unsupported argument for dot product, expected Vector3") - return self._x * other.x + self._y * other.y + self._z * other.z - - def cross(self, other): - """The cross product of this and another Vector3 instance""" - if not isinstance(other, Vector3): - raise TypeError("Unsupported argument for cross product, expected Vector3") - - return Vector3( - self._y * other.z - self._z * other.y, - self._z * other.x - self._x * other.z, - self._x * other.y - self._y * other.x) - - @property - def x_y_z(self): - """tuple (float, float, float): The X, Y, Z elements of the Vector3 (x,y,z)""" - return self._x, self._y, self._z - - def __repr__(self): - return f"<{self.__class__.__name__} x: {self.x:.2f} y: {self.y:.2f} z: {self.z:.2f}>" - - def __add__(self, other): - if not isinstance(other, Vector3): - raise TypeError("Unsupported operand for +, expected Vector3") - return Vector3(self.x + other.x, self.y + other.y, self.z + other.z) - - def __sub__(self, other): - if not isinstance(other, Vector3): - raise TypeError("Unsupported operand for -, expected Vector3") - return Vector3(self.x - other.x, self.y - other.y, self.z - other.z) - - def __mul__(self, other): - if not isinstance(other, (int, float)): - raise TypeError("Unsupported operand for * expected number") - return Vector3(self.x * other, self.y * other, self.z * other) - - def __truediv__(self, other): - if not isinstance(other, (int, float)): - raise TypeError("Unsupported operand for / expected number") - return Vector3(self.x / other, self.y / other, self.z / other) - - -class Angle: - """Represents an angle. - - Use the :func:`degrees` or :func:`radians` convenience methods to generate - an Angle instance. - - :param radians: The number of radians the angle should represent - (cannot be combined with ``degrees``) - :param degrees: The number of degress the angle should represent - (cannot be combined with ``radians``) - """ - - __slots__ = ('_radians') - - def __init__(self, radians: float = None, degrees: float = None): # pylint: disable=redefined-outer-name - if radians is None and degrees is None: - raise ValueError("Expected either the degrees or radians keyword argument") - if radians and degrees: - raise ValueError("Expected either the degrees or radians keyword argument, not both") - - if degrees is not None: - radians = degrees * math.pi / 180 - self._radians = float(radians) - - @property - def radians(self) -> float: # pylint: disable=redefined-outer-name - """The angle in radians.""" - return self._radians - - @property - def degrees(self) -> float: # pylint: disable=redefined-outer-name - """The angle in degrees.""" - return self._radians / math.pi * 180 - - def __repr__(self): - return f"<{self.__class__.__name__} Radians: {self.radians:.2f} Degrees: {self.degrees:.2f}>" - - def __add__(self, other): - if not isinstance(other, Angle): - raise TypeError("Unsupported type for + expected Angle") - return Angle(radians=(self.radians + other.radians)) - - def __sub__(self, other): - if not isinstance(other, Angle): - raise TypeError("Unsupported type for - expected Angle") - return Angle(radians=(self.radians - other.radians)) - - def __mul__(self, other): - if not isinstance(other, (int, float)): - raise TypeError("Unsupported type for * expected number") - return Angle(radians=(self.radians * other)) - - def __truediv__(self, other): - if not isinstance(other, (int, float)): - raise TypeError("Unsupported type for / expected number") - return radians(self.radians / other) - - def _cmp_int(self, other): - if not isinstance(other, Angle): - raise TypeError("Unsupported type for comparison expected Angle") - return self.radians - other.radians - - def __eq__(self, other): - return self._cmp_int(other) == 0 - - def __ne__(self, other): - return self._cmp_int(other) != 0 - - def __gt__(self, other): - return self._cmp_int(other) > 0 - - def __lt__(self, other): - return self._cmp_int(other) < 0 - - def __ge__(self, other): - return self._cmp_int(other) >= 0 - - def __le__(self, other): - return self._cmp_int(other) <= 0 - - @property - def abs_value(self): - """:class:`anki_vector.util.Angle`: The absolute value of the angle. - - If the Angle is positive then it returns a copy of this Angle, otherwise it returns -Angle. - """ - return Angle(radians=abs(self._radians)) - - -def angle_z_to_quaternion(angle_z: Angle): - """This function converts an angle in the z axis (Euler angle z component) to a quaternion. - - :param angle_z: The z axis angle. - - Returns: - q0, q1, q2, q3 (float, float, float, float): A tuple with all the members - of a quaternion defined by angle_z. - """ - - # Define the quaternion to be converted from a Euler angle (x,y,z) of 0,0,angle_z - # These equations have their original equations above, and simplified implemented - # q0 = cos(x/2)*cos(y/2)*cos(z/2) + sin(x/2)*sin(y/2)*sin(z/2) - q0 = math.cos(angle_z.radians / 2) - # q1 = sin(x/2)*cos(y/2)*cos(z/2) - cos(x/2)*sin(y/2)*sin(z/2) - q1 = 0 - # q2 = cos(x/2)*sin(y/2)*cos(z/2) + sin(x/2)*cos(y/2)*sin(z/2) - q2 = 0 - # q3 = cos(x/2)*cos(y/2)*sin(z/2) - sin(x/2)*sin(y/2)*cos(z/2) - q3 = math.sin(angle_z.radians / 2) - return q0, q1, q2, q3 - - -def degrees(degrees: float) -> Angle: # pylint: disable=redefined-outer-name - """An Angle instance set to the specified number of degrees.""" - return Angle(degrees=degrees) - - -def radians(radians: float) -> Angle: # pylint: disable=redefined-outer-name - """An Angle instance set to the specified number of radians.""" - return Angle(radians=radians) - - -class Matrix44: - """A 4x4 Matrix for representing the rotation and/or position of an object in the world. - - Can be generated from a :class:`Quaternion` for a pure rotation matrix, or - combined with a position for a full translation matrix, as done by - :meth:`Pose.to_matrix`. - """ - __slots__ = ('m00', 'm10', 'm20', 'm30', - 'm01', 'm11', 'm21', 'm31', - 'm02', 'm12', 'm22', 'm32', - 'm03', 'm13', 'm23', 'm33') - - def __init__(self, - m00: float, m10: float, m20: float, m30: float, - m01: float, m11: float, m21: float, m31: float, - m02: float, m12: float, m22: float, m32: float, - m03: float, m13: float, m23: float, m33: float): - self.m00 = float(m00) - self.m10 = float(m10) - self.m20 = float(m20) - self.m30 = float(m30) - - self.m01 = float(m01) - self.m11 = float(m11) - self.m21 = float(m21) - self.m31 = float(m31) - - self.m02 = float(m02) - self.m12 = float(m12) - self.m22 = float(m22) - self.m32 = float(m32) - - self.m03 = float(m03) - self.m13 = float(m13) - self.m23 = float(m23) - self.m33 = float(m33) - - def __repr__(self): - return ("<%s: " - "%.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f " - "%.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f>" % ( - self.__class__.__name__, *self.in_row_order)) - - @property - def tabulated_string(self) -> str: - """A multi-line string formatted with tabs to show the matrix contents.""" - return ("%.1f\t%.1f\t%.1f\t%.1f\n" - "%.1f\t%.1f\t%.1f\t%.1f\n" - "%.1f\t%.1f\t%.1f\t%.1f\n" - "%.1f\t%.1f\t%.1f\t%.1f" % self.in_row_order) - - @property - def in_row_order(self): - """tuple of 16 floats: The contents of the matrix in row order.""" - return self.m00, self.m01, self.m02, self.m03,\ - self.m10, self.m11, self.m12, self.m13,\ - self.m20, self.m21, self.m22, self.m23,\ - self.m30, self.m31, self.m32, self.m33 - - @property - def in_column_order(self): - """tuple of 16 floats: The contents of the matrix in column order.""" - return self.m00, self.m10, self.m20, self.m30,\ - self.m01, self.m11, self.m21, self.m31,\ - self.m02, self.m12, self.m22, self.m32,\ - self.m03, self.m13, self.m23, self.m33 - - @property - def forward_xyz(self): - """tuple of 3 floats: The x,y,z components representing the matrix's forward vector.""" - return self.m00, self.m01, self.m02 - - @property - def left_xyz(self): - """tuple of 3 floats: The x,y,z components representing the matrix's left vector.""" - return self.m10, self.m11, self.m12 - - @property - def up_xyz(self): - """tuple of 3 floats: The x,y,z components representing the matrix's up vector.""" - return self.m20, self.m21, self.m22 - - @property - def pos_xyz(self): - """tuple of 3 floats: The x,y,z components representing the matrix's position vector.""" - return self.m30, self.m31, self.m32 - - def set_forward(self, x: float, y: float, z: float): - """Set the x,y,z components representing the matrix's forward vector. - - :param x: The X component. - :param y: The Y component. - :param z: The Z component. - """ - self.m00 = float(x) - self.m01 = float(y) - self.m02 = float(z) - - def set_left(self, x: float, y: float, z: float): - """Set the x,y,z components representing the matrix's left vector. - - :param x: The X component. - :param y: The Y component. - :param z: The Z component. - """ - self.m10 = float(x) - self.m11 = float(y) - self.m12 = float(z) - - def set_up(self, x: float, y: float, z: float): - """Set the x,y,z components representing the matrix's up vector. - - :param x: The X component. - :param y: The Y component. - :param z: The Z component. - """ - self.m20 = float(x) - self.m21 = float(y) - self.m22 = float(z) - - def set_pos(self, x: float, y: float, z: float): - """Set the x,y,z components representing the matrix's position vector. - - :param x: The X component. - :param y: The Y component. - :param z: The Z component. - """ - self.m30 = float(x) - self.m31 = float(y) - self.m32 = float(z) - - -class Quaternion: - """Represents the rotation of an object in the world.""" - - __slots__ = ('_q0', '_q1', '_q2', '_q3') - - def __init__(self, q0: float = None, q1: float = None, q2: float = None, q3: float = None, angle_z: Angle = None): - is_quaternion = q0 is not None and q1 is not None and q2 is not None and q3 is not None - - if not is_quaternion and angle_z is None: - raise ValueError("Expected either the q0 q1 q2 and q3 or angle_z keyword arguments") - if is_quaternion and angle_z: - raise ValueError("Expected either the q0 q1 q2 and q3 or angle_z keyword argument," - "not both") - if angle_z is not None: - if not isinstance(angle_z, Angle): - raise TypeError("Unsupported type for angle_z expected Angle") - q0, q1, q2, q3 = angle_z_to_quaternion(angle_z) - - self._q0 = float(q0) - self._q1 = float(q1) - self._q2 = float(q2) - self._q3 = float(q3) - - @property - def q0(self) -> float: - """The q0 (w) value of the quaternion.""" - return self._q0 - - @property - def q1(self) -> float: - """The q1 (i) value of the quaternion.""" - return self._q1 - - @property - def q2(self) -> float: - """The q2 (j) value of the quaternion.""" - return self._q2 - - @property - def q3(self) -> float: - """The q3 (k) value of the quaternion.""" - return self._q3 - - @property - def angle_z(self) -> Angle: - """An Angle instance representing the z Euler component of the object's rotation. - - Defined as the rotation in the z axis. - """ - q0, q1, q2, q3 = self.q0_q1_q2_q3 - return Angle(radians=math.atan2(2 * (q1 * q2 + q0 * q3), 1 - 2 * (q2**2 + q3**2))) - - @property - def q0_q1_q2_q3(self): - """tuple of float: Contains all elements of the quaternion (q0,q1,q2,q3)""" - return self._q0, self._q1, self._q2, self._q3 - - def to_matrix(self, pos_x: float = 0.0, pos_y: float = 0.0, pos_z: float = 0.0): - """Convert the Quaternion to a 4x4 matrix representing this rotation. - - A position can also be provided to generate a full translation matrix. - - :param pos_x: The x component for the position. - :param pos_y: The y component for the position. - :param pos_z: The z component for the position. - - Returns: - :class:`anki_vector.util.Matrix44`: A matrix representing this Quaternion's - rotation, with the provided position (which defaults to 0,0,0). - """ - # See https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation - q0q0 = self.q0 * self.q0 - q1q1 = self.q1 * self.q1 - q2q2 = self.q2 * self.q2 - q3q3 = self.q3 * self.q3 - - q0x2 = self.q0 * 2.0 # saves 2 multiplies - q0q1x2 = q0x2 * self.q1 - q0q2x2 = q0x2 * self.q2 - q0q3x2 = q0x2 * self.q3 - q1x2 = self.q1 * 2.0 # saves 1 multiply - q1q2x2 = q1x2 * self.q2 - q1q3x2 = q1x2 * self.q3 - q2q3x2 = 2.0 * self.q2 * self.q3 - - m00 = (q0q0 + q1q1 - q2q2 - q3q3) - m01 = (q1q2x2 + q0q3x2) - m02 = (q1q3x2 - q0q2x2) - - m10 = (q1q2x2 - q0q3x2) - m11 = (q0q0 - q1q1 + q2q2 - q3q3) - m12 = (q0q1x2 + q2q3x2) - - m20 = (q0q2x2 + q1q3x2) - m21 = (q2q3x2 - q0q1x2) - m22 = (q0q0 - q1q1 - q2q2 + q3q3) - - return Matrix44(m00, m10, m20, float(pos_x), - m01, m11, m21, float(pos_y), - m02, m12, m22, float(pos_z), - 0.0, 0.0, 0.0, 1.0) - - def __repr__(self): - return (f"<{self.__class__.__name__} q0: {self.q0:.2f} q1: {self.q1:.2f}" - f" q2: {self.q2:.2f} q3: {self.q3:.2f} {self.angle_z}>") - - -class Position(Vector3): - """Represents the position of an object in the world. - - A position consists of its x, y and z values in millimeters. - - :param x: X position in millimeters - :param y: Y position in millimeters - :param z: Z position in millimeters - """ - __slots__ = () - - -class Pose: - """Represents where an object is in the world. - - Whenever Vector is delocalized (i.e. whenever Vector no longer knows - where he is - e.g. when he's picked up), Vector creates a new pose starting at - (0,0,0) with no rotation, with origin_id incremented to show that these poses - cannot be compared with earlier ones. As Vector drives around, his pose (and the - pose of other objects he observes - e.g. faces, his LightCube, charger, etc.) is relative to this - initial position and orientation. - - The coordinate space is relative to Vector, where Vector's origin is the - point on the ground between Vector's two front wheels. The X axis is Vector's forward direction, - the Y axis is to Vector's left, and the Z axis is up. - - Only poses of the same origin_id can safely be compared or operated on. - - .. testcode:: - - import anki_vector - from anki_vector.util import degrees, Pose - - with anki_vector.Robot() as robot: - pose = Pose(x=50, y=0, z=0, angle_z=anki_vector.util.Angle(degrees=0)) - robot.behavior.go_to_pose(pose) - """ - __slots__ = ('_position', '_rotation', '_origin_id') - - def __init__(self, x: float, y: float, z: float, q0: float = None, q1: float = None, q2: float = None, q3: float = None, - angle_z: Angle = None, origin_id: int = -1): - self._position = Position(x, y, z) - self._rotation = Quaternion(q0, q1, q2, q3, angle_z) - self._origin_id = origin_id - - @property - def position(self) -> Position: - """The position component of this pose.""" - return self._position - - @property - def rotation(self) -> Quaternion: - """The rotation component of this pose.""" - return self._rotation - - @property - def origin_id(self) -> int: - """An ID maintained by the robot which represents which coordinate frame this pose is in.""" - return self._origin_id - - def __repr__(self): - return (f"<{self.__class__.__name__}: {self._position}" - f" {self._rotation} >") - - def define_pose_relative_this(self, new_pose): - """Creates a new pose such that new_pose's origin is now at the location of this pose. - - :param anki_vector.util.Pose new_pose: The pose which origin is being changed. - - Returns: - A :class:`anki_vector.util.Pose` object for which the origin was this pose's origin. - """ - if not isinstance(new_pose, Pose): - raise TypeError("Unsupported type for new_origin, must be of type Pose") - x, y, z = self.position.x_y_z - angle_z = self.rotation.angle_z - new_x, new_y, new_z = new_pose.position.x_y_z - new_angle_z = new_pose.rotation.angle_z - - cos_angle = math.cos(angle_z.radians) - sin_angle = math.sin(angle_z.radians) - res_x = x + (cos_angle * new_x) - (sin_angle * new_y) - res_y = y + (sin_angle * new_x) + (cos_angle * new_y) - res_z = z + new_z - res_angle = angle_z + new_angle_z - return Pose(res_x, - res_y, - res_z, - angle_z=res_angle, - origin_id=self._origin_id) - - @property - def is_valid(self) -> bool: - """True if this is a valid, usable pose.""" - return self.origin_id >= 0 - - def is_comparable(self, other_pose) -> bool: - """Checks whether these two poses are comparable. - - Poses are comparable if they're valid and having matching origin IDs. - - :param other_pose: The other pose to compare against. Type is Pose. - - Returns: - True if the two poses are comparable, False otherwise. - """ - return (self.is_valid and other_pose.is_valid and - (self.origin_id == other_pose.origin_id)) - - def to_matrix(self) -> Matrix44: - """Convert the Pose to a Matrix44. - - Returns: - A matrix representing this Pose's position and rotation. - """ - return self.rotation.to_matrix(*self.position.x_y_z) - - def to_proto_pose_struct(self) -> protocol.PoseStruct: - """Converts the Pose into the robot's messaging pose format. - """ - return protocol.PoseStruct( - x=self._position.x, - y=self._position.y, - z=self._position.z, - q0=self._rotation.q0, - q1=self._rotation.q1, - q2=self._rotation.q2, - q3=self._rotation.q3, - origin_id=self._origin_id) - - -class ImageRect: - """Image coordinates and size""" - - __slots__ = ('_x_top_left', '_y_top_left', '_width', '_height') - - def __init__(self, x_top_left: float, y_top_left: float, width: float, height: float): - self._x_top_left = float(x_top_left) - self._y_top_left = float(y_top_left) - self._width = float(width) - self._height = float(height) - - @property - def x_top_left(self) -> float: - """The top left x value of where the object was last visible within Vector's camera view.""" - return self._x_top_left - - @property - def y_top_left(self) -> float: - """The top left y value of where the object was last visible within Vector's camera view.""" - return self._y_top_left - - @property - def width(self) -> float: - """The width of the object from when it was last visible within Vector's camera view.""" - return self._width - - @property - def height(self) -> float: - """The height of the object from when it was last visible within Vector's camera view.""" - return self._height - - -class Distance: - """Represents a distance. - - The class allows distances to be returned in either millimeters or inches. - - Use the :func:`distance_inches` or :func:`distance_mm` convenience methods to generate - a Distance instance. - - :param distance_mm: The number of millimeters the distance should - represent (cannot be combined with ``distance_inches``). - :param distance_inches: The number of inches the distance should - represent (cannot be combined with ``distance_mm``). - """ - - __slots__ = ('_distance_mm') - - def __init__(self, distance_mm: float = None, distance_inches: float = None): # pylint: disable=redefined-outer-name - if distance_mm is None and distance_inches is None: - raise ValueError("Expected either the distance_mm or distance_inches keyword argument") - if distance_mm and distance_inches: - raise ValueError("Expected either the distance_mm or distance_inches keyword argument, not both") - - if distance_inches is not None: - distance_mm = distance_inches * 25.4 - self._distance_mm = float(distance_mm) - - def __repr__(self): - return "<%s %.2f mm (%.2f inches)>" % (self.__class__.__name__, self.distance_mm, self.distance_inches) - - def __add__(self, other): - if not isinstance(other, Distance): - raise TypeError("Unsupported operand for + expected Distance") - return distance_mm(self.distance_mm + other.distance_mm) - - def __sub__(self, other): - if not isinstance(other, Distance): - raise TypeError("Unsupported operand for - expected Distance") - return distance_mm(self.distance_mm - other.distance_mm) - - def __mul__(self, other): - if not isinstance(other, (int, float)): - raise TypeError("Unsupported operand for * expected number") - return distance_mm(self.distance_mm * other) - - def __truediv__(self, other): - if not isinstance(other, (int, float)): - raise TypeError("Unsupported operand for / expected number") - return distance_mm(self.distance_mm / other) - - @property - def distance_mm(self) -> float: # pylint: disable=redefined-outer-name - """The distance in millimeters""" - return self._distance_mm - - @property - def distance_inches(self) -> float: # pylint: disable=redefined-outer-name - return self._distance_mm / 25.4 - - -def distance_mm(distance_mm: float): # pylint: disable=redefined-outer-name - """Returns an :class:`anki_vector.util.Distance` instance set to the specified number of millimeters.""" - return Distance(distance_mm=distance_mm) - - -def distance_inches(distance_inches: float): # pylint: disable=redefined-outer-name - """Returns an :class:`anki_vector.util.Distance` instance set to the specified number of inches.""" - return Distance(distance_inches=distance_inches) - - -class Speed: - """Represents a speed. - - This class allows speeds to be measured in millimeters per second. - - Use :func:`speed_mmps` convenience methods to generate - a Speed instance. - - :param speed_mmps: The number of millimeters per second the speed - should represent. - """ - - __slots__ = ('_speed_mmps') - - def __init__(self, speed_mmps: float = None): # pylint: disable=redefined-outer-name - if speed_mmps is None: - raise ValueError("Expected speed_mmps keyword argument") - self._speed_mmps = float(speed_mmps) - - def __repr__(self): - return "<%s %.2f mmps>" % (self.__class__.__name__, self.speed_mmps) - - def __add__(self, other): - if not isinstance(other, Speed): - raise TypeError("Unsupported operand for + expected Speed") - return speed_mmps(self.speed_mmps + other.speed_mmps) - - def __sub__(self, other): - if not isinstance(other, Speed): - raise TypeError("Unsupported operand for - expected Speed") - return speed_mmps(self.speed_mmps - other.speed_mmps) - - def __mul__(self, other): - if not isinstance(other, (int, float)): - raise TypeError("Unsupported operand for * expected number") - return speed_mmps(self.speed_mmps * other) - - def __truediv__(self, other): - if not isinstance(other, (int, float)): - raise TypeError("Unsupported operand for / expected number") - return speed_mmps(self.speed_mmps / other) - - @property - def speed_mmps(self: float) -> float: # pylint: disable=redefined-outer-name - """The speed in millimeters per second (mmps).""" - return self._speed_mmps - - -def speed_mmps(speed_mmps: float): # pylint: disable=redefined-outer-name - """:class:`anki_vector.util.Speed` instance set to the specified millimeters per second speed.""" - return Speed(speed_mmps=speed_mmps) - - -class BaseOverlay: - """A base overlay is used as a base class for other forms of overlays that can be drawn on top of an image. - - :param line_thickness: The thickness of the line being drawn. - :param line_color: The color of the line to be drawn. - """ - - def __init__(self, line_thickness: int, line_color: tuple): - self._line_thickness: int = line_thickness - self._line_color: tuple = line_color - - @property - def line_thickness(self) -> int: - """The thickness of the line being drawn.""" - return self._line_thickness - - @property - def line_color(self) -> tuple: - """The color of the line to be drawn.""" - return self._line_color - - -class RectangleOverlay(BaseOverlay): - """A rectangle that can be drawn on top of a given image. - - :param width: The width of the rectangle to be drawn. - :param height: The height of the rectangle to be drawn. - :param line_thickness: The thickness of the line being drawn. - :param line_color: The color of the line to be drawn. - """ - - # @TODO Implement overlay using an ImageRect rather than a raw width & height - def __init__(self, width: int, height: int, line_thickness: int = 5, line_color: tuple = (255, 0, 0)): - super().__init__(line_thickness, line_color) - self._width: int = width - self._height: int = height - - @property - def width(self) -> int: - """The width of the rectangle to be drawn.""" - return self._width - - @property - def height(self) -> int: - """The height of the rectangle to be drawn.""" - return self._height - - def apply_overlay(self, image: Image.Image) -> None: - """Draw a rectangle on top of the given image.""" - d = ImageDraw.Draw(image) - - image_width, image_height = image.size - remaining_width = image_width - self.width - remaining_height = image_height - self.height - x1, y1 = remaining_height // 2, remaining_width // 2 - x2, y2 = (image_height - (remaining_height // 2)), (image_width - (remaining_width // 2)) - - for i in range(0, self.line_thickness): - d.rectangle([x1 + i, y1 + i, x2 - i, y2 - i], outline=self.line_color) - - -class Component: - """ Base class for all components.""" - - def __init__(self, robot): - self.logger = get_class_logger(__name__, self) - self._robot = robot - - @property - def robot(self): - return self._robot - - @property - def conn(self): - return self._robot.conn - - @property - def force_async(self): - return self._robot.force_async - - @property - def grpc_interface(self): - """A direct reference to the connected aiogrpc interface. - """ - return self._robot.conn.grpc_interface diff --git a/anki_vector/version.py b/anki_vector/version.py deleted file mode 100644 index 829dce5..0000000 --- a/anki_vector/version.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -__version__ = "0.5.2.dev0" diff --git a/anki_vector/viewer.py b/anki_vector/viewer.py deleted file mode 100644 index ed2e1f0..0000000 --- a/anki_vector/viewer.py +++ /dev/null @@ -1,428 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Displays camera feed from Vector's camera. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['ViewerComponent', 'Viewer3DComponent'] - -import multiprocessing as mp -import os -import sys -import threading - -try: - import cv2 -except ImportError as exc: - sys.exit("Cannot import opencv-python: Do `pip3 install opencv-python` to install") - -try: - import numpy as np -except ImportError as exc: - sys.exit("Cannot import numpy: Do `pip3 install numpy` to install") - -try: - from PIL import Image -except ImportError: - sys.exit("Cannot import from PIL: Do `pip3 install --user Pillow` to install") - -from . import util -from .events import Events - - -class ViewerComponent(util.Component): - """This component opens a window and renders the images obtained from Vector's camera. - This viewer window is run in a separate process spawned by :func:`~ViewerComponent.show_video`. - Being on a separate process means the rendering of the camera does not block the main thread - of the calling code, and allows the viewer to have its own ui thread which it can operate on. - :func:`~ViewerComponent.stop_video` will stop the viewer process. - - .. testcode:: - - import anki_vector - - import time - - with anki_vector.Robot(enable_camera_feed=True, show_viewer=True) as robot: - time.sleep(5) - - :param robot: A reference to the owner Robot object. (May be :class:`None`) - """ - - def __init__(self, robot): - super().__init__(robot) - self.overlays: list = [] - self._close_event: mp.Event = None - self._frame_queue: mp.Queue = None - self._process = None - - def show_video(self, timeout: float = 10.0) -> None: - """Render a video stream using the images obtained from - Vector's camera feed. - - Be sure to create your Robot object with the camera feed enabled - by using "show_viewer=True" and "enable_camera_feed=True". - - .. testcode:: - - import anki_vector - import time - - with anki_vector.Robot(enable_camera_feed=True) as robot: - robot.viewer.show_video() - time.sleep(10) - - :param timeout: Render video for the given time. (Renders forever, if timeout not given) - """ - ctx = mp.get_context('spawn') - self._close_event = ctx.Event() - self._frame_queue = ctx.Queue(maxsize=4) - self._process = ctx.Process(target=ViewerComponent._render_frames, - args=(self._frame_queue, - self._close_event, - self.overlays, - timeout), - daemon=True, - name="Camera Viewer Process") - self._process.start() - - def stop_video(self) -> None: - """Stop rendering video of Vector's camera feed and close the viewer process. - - .. testcode:: - - import anki_vector - import time - - with anki_vector.Robot(show_viewer=True) as robot: - time.sleep(10) - robot.viewer.stop_video() - """ - if self._close_event: - self._close_event.set() - self._close_event = None - if self._frame_queue: - try: - self._frame_queue.put(None, False) - except mp.queues.Full: - pass - self._frame_queue = None - if self._process: - self._process.join(timeout=5) - if self._process.is_alive(): - self._process.terminate() - self._process = None - - def enqueue_frame(self, image: Image.Image): - """Sends a frame to the viewer's rendering process. Sending `None` to the viewer - will cause it to gracefully shutdown. - - .. note:: - - This function will be called automatically from the camera feed when the - :class:`~anki_vector.robot.Robot` object is created with ``enable_camera_feed=True``. - - .. code-block:: python - - import anki_vector - from PIL.Image import Image - - image = Image() - with anki_vector.Robot(show_viewer=True) as robot: - robot.viewer.enqueue_frame(image) - - :param image: A frame from Vector's camera. - """ - close_event = self._close_event - if self._frame_queue is not None and close_event is not None and not close_event.is_set(): - try: - self._frame_queue.put(image, False) - except mp.queues.Full: - pass - - def _apply_overlays(self, image: Image.Image) -> None: - """Apply all overlays attached to viewer instance on to image from camera feed.""" - for overlay in self.overlays: - overlay.apply_overlay(image) - return image - - @staticmethod - def _render_frames(queue: mp.Queue, event: mp.Event, overlays: list = None, timeout: float = 10.0) -> None: - """Rendering the frames in another process. This allows the UI to have the - main thread of its process while the user code continues to execute. - - :param queue: A queue to send frames between main thread and other process. - :param overlays: overlays to be drawn on the images of the renderer. - :param timeout: The time without a new frame before the process will exit. - """ - is_windows = os.name == 'nt' - window_name = "Vector Camera Feed" - cv2.namedWindow(window_name, cv2.WINDOW_NORMAL) - try: - image = queue.get(True, timeout=timeout) - while image: - if event.is_set(): - break - if overlays: - for overlay in overlays: - overlay.apply_overlay(image) - image = cv2.cvtColor(np.array(image), cv2.COLOR_BGR2RGB) - cv2.imshow(window_name, image) - cv2.waitKey(1) - if not is_windows and cv2.getWindowProperty(window_name, cv2.WND_PROP_VISIBLE) < 1: - break - image = queue.get(True, timeout=timeout) - except TimeoutError: - pass - except KeyboardInterrupt: - pass - finally: - event.set() - cv2.destroyWindow(window_name) - cv2.waitKey(1) - - -class _ExternalRenderCallFunctor(): # pylint: disable=too-few-public-methods - """Externally specified OpenGL render function. - - Allows extra geometry to be rendered into OpenGLViewer. - - :param f: function to call inside the rendering loop - :param f_args: a list of arguments to supply to the callable function - """ - - def __init__(self, f: callable, f_args: list): - self._f = f - self._f_args = f_args - - def invoke(self, user_data_queue): - """Calls the internal function""" - self._f(*self._f_args, user_data_queue=user_data_queue) - - -class Viewer3DComponent(util.Component): - """This component opens a window and renders the a 3D view obtained from Vector's navigation map. - This viewer window is run in a separate process spawned by :func:`~Viewer3DComponent.show`. - Being on a separate process means the rendering of the 3D view does not block the main thread - of the calling code, and allows the viewer to have its own ui thread with which it can render OpenGL. - :func:`~Viewer3DComponent.close` will stop the viewer process. - - .. testcode:: - - import anki_vector - - import time - - with anki_vector.Robot(enable_nav_map_feed=True, show_3d_viewer=True) as robot: - time.sleep(5) - - :param robot: A reference to the owner Robot object. (May be :class:`None`) - """ - - def __init__(self, robot): - super().__init__(robot) - self.overlays: list = [] - self._close_event: mp.Event = None - self._input_intent_queue: mp.Queue = None - self._nav_map_queue: mp.Queue = None - self._world_frame_queue: mp.Queue = None - self._extra_render_function_queue: mp.Queue = None - self._user_data_queue: mp.Queue = None - self._process: mp.process.BaseProcess = None - self._update_thread: threading.Thread = None - self._last_robot_control_intents = None - - def show(self): - """Spawns a background process that shows the navigation map in a 3D view. - - .. testcode:: - - import anki_vector - - import time - - with anki_vector.Robot(enable_nav_map_feed=True) as robot: - robot.viewer_3d.show() - time.sleep(5) - robot.viewer_3d.close() - """ - from . import opengl - ctx = mp.get_context('spawn') - self._close_event = ctx.Event() - self._input_intent_queue = ctx.Queue(maxsize=10) - self._nav_map_queue = ctx.Queue(maxsize=10) - self._world_frame_queue = ctx.Queue(maxsize=10) - self._extra_render_function_queue = ctx.Queue(maxsize=1) - self._user_data_queue = ctx.Queue() - self._update_thread = threading.Thread(target=self._update, - args=(), - daemon=True, - name="3D Viewer Update Thread") - self._update_thread.start() - self._process = ctx.Process(target=opengl.main, - args=(self._close_event, - self._input_intent_queue, - self._nav_map_queue, - self._world_frame_queue, - self._extra_render_function_queue, - self._user_data_queue), - daemon=True, - name="3D Viewer Process") - self._process.start() - self.robot.events.subscribe(self._on_robot_state_update, Events.robot_state) - self.robot.events.subscribe(self._on_nav_map_update, Events.nav_map_update) - - @property - def user_data_queue(self): - """A queue to send custom data to the 3D viewer process. - - Best used in conjunction with :func:`~Viewer3DComponent.add_render_call` to place - a process on the 3D viewer process then obtain data from this queue. - """ - return self._user_data_queue - - def add_render_call(self, render_function: callable, *args): - """Allows external functions to be injected into the viewer process which - will be called at the appropriate time in the rendering pipeline. - - Example usage to draw a dot at the world origin: - - .. code-block:: python - - import time - - import anki_vector - - def my_render_function(user_data_queue): - glBegin(GL_POINTS) - glVertex3f(0, 0, 0) - glEnd() - - with anki_vector.Robot(enable_nav_map_feed=True, show_3d_viewer=True) as robot: - robot.viewer_3d.add_render_call(my_render_function) - time.sleep(10) - - :param render_function: The delegated function to be invoked in the pipeline. - :param args: An optional list of arguments to send to the render_function - the arguments list must match the parameters accepted by the - supplied function. - """ - self._extra_render_function_queue.put(_ExternalRenderCallFunctor(render_function, args)) - - def close(self): - """Closes the background process showing the 3D view. - - .. testcode:: - - import anki_vector - - import time - - with anki_vector.Robot(enable_nav_map_feed=True) as robot: - robot.viewer_3d.show() - time.sleep(5) - robot.viewer_3d.close() - """ - if self._close_event: - self._close_event.set() - self._close_event = None - if self._update_thread: - self._update_thread.join(timeout=2) - self._update_thread = None - self._input_intent_queue = None - self._nav_map_queue = None - self._world_frame_queue = None - if self._process: - self._process.join(timeout=5) - if self._process.is_alive(): - self._process.terminate() - self._process = None - - def _update(self): - """Reads most recently stored user-triggered intents, and sends - motor messages to the robot if the intents should effect the robot's - current motion. - - Called on SDK thread, for controlling robot from input intents - pushed from the OpenGL thread. - - :param robot: the robot being updated by this View Controller - """ - close_event = self._close_event - while close_event and not close_event.is_set(): - try: - input_intents = self._input_intent_queue.get(True, timeout=2) # type: RobotControlIntents - - # Track last-used intents so that we only issue motor controls - # if different from the last frame (to minimize it fighting with an SDK - # program controlling the robot): - old_intents = self._last_robot_control_intents - self._last_robot_control_intents = input_intents - - if not old_intents or (old_intents.left_wheel_speed != input_intents.left_wheel_speed - or old_intents.right_wheel_speed != input_intents.right_wheel_speed): - self.robot.motors.set_wheel_motors(input_intents.left_wheel_speed, - input_intents.right_wheel_speed, - input_intents.left_wheel_speed * 4, - input_intents.right_wheel_speed * 4, - _return_future=True) - - if not old_intents or old_intents.lift_speed != input_intents.lift_speed: - self.robot.motors.set_lift_motor(input_intents.lift_speed, _return_future=True) - - if not old_intents or old_intents.head_speed != input_intents.head_speed: - self.robot.motors.set_head_motor(input_intents.head_speed, _return_future=True) - except mp.queues.Empty: - pass - close_event = self._close_event - - def _on_robot_state_update(self, *_): - """Called from SDK process whenever the robot state is updated (so i.e. every engine tick). - - Note: - - This is called from the SDK process, and will pass the nav map data to the - 3D viewer process. - - We can safely capture any robot and world state here, and push to OpenGL - (main) process via a multiprocessing queue. - """ - from .opengl import opengl_vector - world_frame = opengl_vector.WorldRenderFrame(self.robot) - queue = self._world_frame_queue - if queue: - try: - queue.put(world_frame, False) - except mp.queues.Full: - pass - # self._view_controller.update(self.robot) # TODO: <- sounds like this has something to do with keyboard input... - - def _on_nav_map_update(self, _, msg): - """Called from SDK process whenever the nav map is updated. - - Note: - - This is called from the SDK process, and will pass the nav map data to the - 3D viewer process. - - We can safely capture any robot and world state here, and push to OpenGL - (main) process via a multiprocessing queue. - """ - queue = self._nav_map_queue - if queue: - try: - queue.put(msg, False) - except mp.queues.Full: - pass diff --git a/anki_vector/vision.py b/anki_vector/vision.py deleted file mode 100644 index 29172c5..0000000 --- a/anki_vector/vision.py +++ /dev/null @@ -1,167 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Utility methods for Vector's vision - -Vector's can detect various types of objects through his camera feed. - -The :class:`VisionComponent` class defined in this module is made available as -:attr:`anki_vector.robot.Robot.vision` and can be used to enable/disable vision -processing on the robot. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['VisionComponent'] - -from concurrent import futures - -from . import util, connection, events -from .messaging import protocol - - -class VisionComponent(util.Component): # pylint: disable=too-few-public-methods - """VisionComponent exposes controls for the robot's internal image processing. - - The :class:`anki_vector.robot.Robot` or :class:`anki_vector.robot.AsyncRobot` instance owns this vision component. - - :param robot: A reference to the owner Robot object. - """ - - def __init__(self, robot): - super().__init__(robot) - - self._detect_faces = False - self._detect_custom_objects = False - # TODO implement - # self._detect_motion = False - self._display_camera_feed_on_face = False - - robot.events.subscribe(self._handle_mirror_mode_disabled_event, events.Events.mirror_mode_disabled) - robot.events.subscribe(self._handle_vision_modes_auto_disabled_event, events.Events.vision_modes_auto_disabled) - - def close(self): - """Close all the running vision modes and wait for a response.""" - vision_mode = self.disable_all_vision_modes() # pylint: disable=assignment-from-no-return - if isinstance(vision_mode, futures.Future): - vision_mode.result() - - def _handle_mirror_mode_disabled_event(self, _, _msg): - self._display_camera_feed_on_face = False - - def _handle_vision_modes_auto_disabled_event(self, _, _msg): - self._detect_faces = False - self._detect_custom_objects = False - # self._detect_motion = False - self._display_camera_feed_on_face = False - - @property - def detect_faces(self): - return self._detect_faces - - @property - def detect_custom_objects(self): - return self._detect_custom_objects - - # TODO implement - # @property - # def detect_motion(self): - # return self._detect_motion - - @property - def display_camera_feed_on_face(self): - return self._display_camera_feed_on_face - - @connection.on_connection_thread() - async def disable_all_vision_modes(self): - if self.detect_faces: - await self.enable_face_detection(False, False) - if self.detect_custom_objects: - await self.enable_custom_object_detection(False) - # if self.detect_motion: - # await self.enable_motion_detection(False) - if self.display_camera_feed_on_face: - await self.enable_display_camera_feed_on_face(False) - - @connection.on_connection_thread() - async def enable_custom_object_detection(self, detect_custom_objects: bool = True): - """Enable custom object detection on the robot's camera - - :param detect_custom_objects: Specify whether we want the robot to detect custom objects. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - robot.vision.enable_custom_object_detection() - """ - self._detect_custom_objects = detect_custom_objects - - enable_marker_detection_request = protocol.EnableMarkerDetectionRequest(enable=detect_custom_objects) - return await self.grpc_interface.EnableMarkerDetection(enable_marker_detection_request) - - @connection.on_connection_thread() - async def enable_face_detection( - self, - detect_faces: bool = True, - # detect_smile: bool = False, - estimate_expression: bool = False, - # detect_blink: bool = False, - # detect_gaze: bool = False - ): - """Enable face detection on the robot's camera - - :param detect_faces: Specify whether we want the robot to detect faces. - :param detect_smile: Specify whether we want the robot to detect smiles in detected faces. - :param estimate_expression: Specify whether we want the robot to estimate what expression detected faces are showing. - :param detect_blink: Specify whether we want the robot to detect how much detected faces are blinking. - :param detect_gaze: Specify whether we want the robot to detect where detected faces are looking. - """ - self._detect_faces = detect_faces - - enable_face_detection_request = protocol.EnableFaceDetectionRequest( - enable=detect_faces, - enable_smile_detection=False, - enable_expression_estimation=estimate_expression, - enable_blink_detection=False, - enable_gaze_detection=False) - return await self.grpc_interface.EnableFaceDetection(enable_face_detection_request) - - # TODO implement - # @connection.on_connection_thread() - # async def enable_motion_detection(self, detect_motion: bool = True): - # """Enable motion detection on the robot's camera - - # :param detect_motion: Specify whether we want the robot to detect motion. - - # .. testcode:: - - # import anki_vector - # with anki_vector.Robot() as robot: - # robot.vision.enable_motion_detection(detect_motion=True) - # """ - # self._detect_motion = detect_motion - - # enable_motion_detection_request = protocol.EnableMotionDetectionRequest(enable=detect_motion) - # return await self.grpc_interface.EnableMotionDetection(enable_motion_detection_request) - - @connection.on_connection_thread() - async def enable_display_camera_feed_on_face(self, display_camera_feed_on_face: bool = True): - """Display the robot's camera feed on its face along with any detections (if enabled) - - :param display_camera_feed_on_face: Specify whether we want to display the robot's camera feed on its face. - """ - self._display_camera_feed_on_face = display_camera_feed_on_face - - display_camera_feed_request = protocol.EnableMirrorModeRequest(enable=display_camera_feed_on_face) - return await self.grpc_interface.EnableMirrorMode(display_camera_feed_request) diff --git a/anki_vector/world.py b/anki_vector/world.py deleted file mode 100644 index 43e6b3a..0000000 --- a/anki_vector/world.py +++ /dev/null @@ -1,818 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Vector's known view of his world. - -This view includes objects and faces it knows about and can currently -see with its camera. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['World'] - -from concurrent import futures -from typing import Iterable - -from . import faces -from . import connection -from . import objects -from . import util - -from .events import Events -from .messaging import protocol - - -class World(util.Component): - """Represents the state of the world, as known to Vector.""" - - #: callable: The factory function that returns a - #: :class:`faces.Face` class or subclass instance - face_factory = faces.Face - - #: callable: The factory function that returns an - #: :class:`objects.LightCube` class or subclass instance. - light_cube_factory = objects.LightCube - - #: callable: The factory function that returns an - #: :class:`objects.Charger` class or subclass instance. - charger_factory = objects.Charger - - #: callable: The factory function that returns an - #: :class:`objects.CustomObject` class or subclass instance. - custom_object_factory = objects.CustomObject - - #: callable: The factory function that returns an - #: :class:`objects.FixedCustomObject` class or subclass instance. - fixed_custom_object_factory = objects.FixedCustomObject - - def __init__(self, robot): - super().__init__(robot) - - self._custom_object_archetypes = {} - - # Objects by type - self._faces = {} - self._light_cube = {objects.LIGHT_CUBE_1_TYPE: self.light_cube_factory(robot=robot)} - self._custom_objects = {} - - #: :class:`anki_vector.objects.Charger`: Vector's charger. - #: ``None`` if no charger connected or known about yet. - self._charger = None # type: anki_vector.objects.Charger - - # All objects - self._objects = {} - - # Subscribe to callbacks that updates the world view - self._robot.events.subscribe(self._on_face_observed, - Events.robot_observed_face, - on_connection_thread=True) - - self._robot.events.subscribe(self._on_object_observed, - Events.robot_observed_object, - on_connection_thread=True) - - #### Public Properties #### - - @property - def all_objects(self): - """generator: yields each object in the world. - - .. testcode:: - - # Print the all objects' class details - import anki_vector - with anki_vector.Robot() as robot: - for obj in robot.world.all_objects: - print(obj) - - Returns: - A generator yielding :class:`anki_vector.faces.Face`, :class:`anki_vector.faces.LightCube`, - :class:`anki_vector.faces.Charger`, :class:`anki_vector.faces.CustomObject` and - :class:`anki_vector.faces.FixedCustomObject` instances. - """ - for obj in self._objects.values(): - yield obj - - @property - def visible_faces(self) -> Iterable[faces.Face]: - """generator: yields each face that Vector can currently see. - - .. testcode:: - - # Print the visible face's attributes - import anki_vector - with anki_vector.Robot() as robot: - for face in robot.world.visible_faces: - print("Face attributes:") - print(f"Face id: {face.face_id}") - print(f"Updated face id: {face.updated_face_id}") - print(f"Name: {face.name}") - print(f"Expression: {face.expression}") - print(f"Timestamp: {face.timestamp}") - print(f"Pose: {face.pose}") - print(f"Image Rect: {face.face_rect}") - print(f"Expression score: {face.expression_score}") - print(f"Left eye: {face.left_eye}") - print(f"Right eye: {face.right_eye}") - print(f"Nose: {face.nose}") - print(f"Mouth: {face.mouth}") - - Returns: - A generator yielding :class:`anki_vector.faces.Face` instances. - """ - for face in self._faces.values(): - if face.is_visible: - yield face - - @property - def custom_object_archetypes(self) -> Iterable[objects.CustomObjectArchetype]: - """generator: yields each custom object archetype that Vector will look for. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - for obj in robot.world.custom_object_archetypes: - print(obj) - - Returns: - A generator yielding CustomObjectArchetype instances - """ - for obj in self._custom_object_archetypes.values(): - yield obj - - @property - def visible_custom_objects(self) -> Iterable[objects.CustomObject]: - """generator: yields each custom object that Vector can currently see. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - for obj in robot.world.visible_custom_objects: - print(obj) - - Returns: - A generator yielding CustomObject instances - """ - for obj in self._custom_objects.values(): - if obj.is_visible: - yield obj - - @property - def connected_light_cube(self) -> objects.LightCube: - """A light cube connected to Vector, if any. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.world.connect_cube() - if robot.world.connected_light_cube: - dock_response = robot.behavior.dock_with_cube(robot.world.connected_light_cube) - """ - result = None - cube = self._light_cube.get(objects.LIGHT_CUBE_1_TYPE) - if cube and cube.is_connected: - result = cube - - return result - - @property - def light_cube(self) -> objects.LightCube: - """Returns the vector light cube object, regardless of its connection status. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - cube = robot.world.light_cube - if cube: - if cube.is_connected: - print("LightCube is connected.") - else: - print("LightCube isn't connected") - - Raises: - :class:`ValueError` if the cube_id is invalid. - """ - cube = self._light_cube.get(objects.LIGHT_CUBE_1_TYPE) - # Only return the cube if it has an object_id - if cube.object_id is not None: - return cube - return None - - @property - def charger(self) -> objects.Charger: - """Returns the most recently observed Vector charger object, or None if no chargers have been observed. - - .. testcode:: - - import anki_vector - - # First, place Vector directly in front of his charger so he can observe it. - - with anki_vector.Robot() as robot: - print('most recently observed charger: {0}.'.format(robot.world.charger)) - """ - if self._charger is not None: - return self._charger - return None - - #### Public Methods #### - - def close(self): - """The world will tear down all its faces and objects.""" - - # delete_custom_objects is called before the _objects are torn down to make sure the - # robot receives cues to remove the internal representations of these objects before - # we release the SDK side representations - self.delete_custom_objects() - - for obj in self._objects.values(): - obj.teardown() - - self._robot.events.unsubscribe(self._on_face_observed, - Events.robot_observed_face) - - self._robot.events.unsubscribe(self._on_object_observed, - Events.robot_observed_object) - - def get_object(self, object_id: int): - """Fetches an object instance with the given id. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - # First get an existing object id, for instance: - valid_object_id = 1 - - # Then use the object_id to retrieve the object instance: - my_obj = robot.world.get_object(valid_object_id) - """ - return self._objects.get(object_id) - - def get_face(self, face_id: int) -> faces.Face: - """Fetches a Face instance with the given id. - - .. testcode:: - - with anki_vector.Robot() as robot: - # First get an existing face_id, for instance: - previously_observed_face_id = 1 - - # Then use the face_id to retrieve the Face instance - my_face = robot.world.get_face(previously_observed_face_id) - """ - return self._faces.get(face_id) - - @connection.on_connection_thread() - async def connect_cube(self) -> protocol.ConnectCubeResponse: - """Attempt to connect to a cube. - - If a cube is currently connected, this will do nothing. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.world.connect_cube() - """ - req = protocol.ConnectCubeRequest() - result = await self.grpc_interface.ConnectCube(req) - - # dispatch cube connected message - event = protocol.ObjectConnectionState( - object_id=result.object_id, - factory_id=result.factory_id, - connected=result.success, - object_type=objects.LIGHT_CUBE_1_TYPE) - - await self._robot.events.dispatch_event(event, Events.object_connection_state) - - return result - - @connection.on_connection_thread() - async def disconnect_cube(self) -> protocol.DisconnectCubeResponse: - """Requests a disconnection from the currently connected cube. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.world.disconnect_cube() - """ - req = protocol.DisconnectCubeRequest() - return await self.grpc_interface.DisconnectCube(req) - - @connection.on_connection_thread() - async def flash_cube_lights(self) -> protocol.FlashCubeLightsResponse: - """Flash cube lights - - Plays the default cube connection animation on the currently - connected cube's lights. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - robot.world.flash_cube_lights() - """ - req = protocol.FlashCubeLightsRequest() - return await self.grpc_interface.FlashCubeLights(req) - - @connection.on_connection_thread(requires_control=False) - async def forget_preferred_cube(self) -> protocol.ForgetPreferredCubeResponse: - """Forget preferred cube. - - 'Forget' the robot's preferred cube. This will cause the robot to - connect to the cube with the highest RSSI (signal strength) next - time a connection is requested. - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - robot.world.forget_preferred_cube() - """ - req = protocol.ForgetPreferredCubeRequest() - return await self.grpc_interface.ForgetPreferredCube(req) - - @connection.on_connection_thread(requires_control=False) - async def set_preferred_cube(self, factory_id: str) -> protocol.SetPreferredCubeResponse: - """Set preferred cube. - - Set the robot's preferred cube and save it to disk. The robot - will always attempt to connect to this cube if it is available. - This is only used in simulation (for now). - - .. testcode:: - - import anki_vector - - with anki_vector.Robot() as robot: - connected_cube = robot.world.connected_light_cube - if connected_cube: - robot.world.set_preferred_cube(connected_cube.factory_id) - - :param factory_id: The unique hardware id of the physical cube. - """ - req = protocol.SetPreferredCubeRequest(factory_id=factory_id) - return await self.grpc_interface.SetPreferredCube(req) - - @connection.on_connection_thread(requires_control=False) - async def delete_custom_objects(self, - delete_custom_marker_objects: bool = True, - delete_fixed_custom_objects: bool = True, - delete_custom_object_archetypes: bool = True): - """Causes the robot to forget about custom objects it currently knows about. - - .. testcode:: - - import anki_vector - with anki_vector.Robot() as robot: - robot.world.delete_custom_objects() - """ - - last_blocking_call = None - - if delete_custom_object_archetypes: - self._custom_object_archetypes.clear() - req = protocol.DeleteCustomObjectsRequest(mode=protocol.CustomObjectDeletionMode.Value("DELETION_MASK_ARCHETYPES")) - last_blocking_call = await self.grpc_interface.DeleteCustomObjects(req) - delete_custom_marker_objects = True - - if delete_custom_marker_objects: - self._remove_all_custom_marker_object_instances() - req = protocol.DeleteCustomObjectsRequest(mode=protocol.CustomObjectDeletionMode.Value("DELETION_MASK_CUSTOM_MARKER_OBJECTS")) - last_blocking_call = await self.grpc_interface.DeleteCustomObjects(req) - - if delete_fixed_custom_objects: - self._remove_all_fixed_custom_object_instances() - req = protocol.DeleteCustomObjectsRequest(mode=protocol.CustomObjectDeletionMode.Value("DELETION_MASK_FIXED_CUSTOM_OBJECTS")) - last_blocking_call = await self.grpc_interface.DeleteCustomObjects(req) - - return last_blocking_call - - @connection.on_connection_thread(requires_control=False) - async def define_custom_box(self, - custom_object_type: objects.CustomObjectTypes, - marker_front: objects.CustomObjectMarkers, - marker_back: objects.CustomObjectMarkers, - marker_top: objects.CustomObjectMarkers, - marker_bottom: objects.CustomObjectMarkers, - marker_left: objects.CustomObjectMarkers, - marker_right: objects.CustomObjectMarkers, - depth_mm: float, - width_mm: float, - height_mm: float, - marker_width_mm: float, - marker_height_mm: float, - is_unique: bool = True) -> objects.CustomObject: - """Defines a cuboid of custom size and binds it to a specific custom object type. - - The robot will now detect the markers associated with this object and send an - object_observed message when they are seen. The markers must be placed in the center - of their respective sides. All 6 markers must be unique. - - :param custom_object_type: the object type you are binding this custom object to. - :param marker_front: the marker affixed to the front of the object. - :param marker_back: the marker affixed to the back of the object. - :param marker_top: the marker affixed to the top of the object. - :param marker_bottom: the marker affixed to the bottom of the object. - :param marker_left: the marker affixed to the left of the object. - :param marker_right: the marker affixed to the right of the object. - :param depth_mm: depth of the object (in millimeters) (X axis). - :param width_mm: width of the object (in millimeters) (Y axis). - :param height_mm: height of the object (in millimeters) (Z axis). - (the height of the object) - :param marker_width_mm: width of the printed marker (in millimeters). - :param maker_height_mm: height of the printed marker (in millimeters). - :param is_unique: If True, the robot will assume there is only 1 of this object. - (and therefore only 1 of each of any of these markers) in the world. - - .. testcode:: - - import anki_vector - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - robot.world.define_custom_box(custom_object_type=anki_vector.objects.CustomObjectTypes.CustomType00, - marker_front= anki_vector.objects.CustomObjectMarkers.Circles2, - marker_back= anki_vector.objects.CustomObjectMarkers.Circles3, - marker_top= anki_vector.objects.CustomObjectMarkers.Circles4, - marker_bottom= anki_vector.objects.CustomObjectMarkers.Circles5, - marker_left= anki_vector.objects.CustomObjectMarkers.Triangles2, - marker_right= anki_vector.objects.CustomObjectMarkers.Triangles3, - depth_mm=20.0, width_mm=20.0, height_mm=20.0, - marker_width_mm=50.0, marker_height_mm=50.0) - - Returns: - CustomObject instance with the specified dimensions. - This is None if the definition failed internally. - Note: No instances of this object are added to the world until they have been seen. - - Raises: - TypeError if the custom_object_type is of the wrong type. - ValueError if the 6 markers aren't unique. - """ - if not isinstance(custom_object_type, objects._CustomObjectType): # pylint: disable=protected-access - raise TypeError("Unsupported object_type, requires CustomObjectType") - - # verify all 6 markers are unique - markers = {marker_front, marker_back, marker_top, marker_bottom, marker_left, marker_right} - if len(markers) != 6: - raise ValueError("all markers must be unique for a custom box") - - custom_object_archetype = objects.CustomObjectArchetype(custom_object_type, - depth_mm, width_mm, height_mm, - marker_width_mm, marker_height_mm, - is_unique) - - definition = protocol.CustomBoxDefinition(marker_front=marker_front.id, - marker_back=marker_back.id, - marker_top=marker_top.id, - marker_bottom=marker_bottom.id, - marker_left=marker_left.id, - marker_right=marker_right.id, - x_size_mm=depth_mm, - y_size_mm=width_mm, - z_size_mm=height_mm, - marker_width_mm=marker_width_mm, - marker_height_mm=marker_height_mm) - - req = protocol.DefineCustomObjectRequest(custom_type=custom_object_type.id, - is_unique=is_unique, - custom_box=definition) - - response = await self.grpc_interface.DefineCustomObject(req) - - if response.success: - type_id = custom_object_archetype.custom_type.id - self._custom_object_archetypes[type_id] = custom_object_archetype - return custom_object_archetype - - self.logger.error("Failed to define Custom Object %s", custom_object_archetype) - return None - - @connection.on_connection_thread(requires_control=False) - async def define_custom_cube(self, - custom_object_type: objects.CustomObjectTypes, - marker: objects.CustomObjectMarkers, - size_mm: float, - marker_width_mm: float, - marker_height_mm: float, - is_unique: bool = True) -> objects.CustomObject: - """Defines a cube of custom size and binds it to a specific custom object type. - - The robot will now detect the markers associated with this object and send an - object_observed message when they are seen. The markers must be placed in the center - of their respective sides. - - :param custom_object_type: the object type you are binding this custom object to. - :param marker: the marker affixed to every side of the cube. - :param size_mm: size of each side of the cube (in millimeters). - :param marker_width_mm: width of the printed marker (in millimeters). - :param maker_height_mm: height of the printed marker (in millimeters). - :param is_unique: If True, the robot will assume there is only 1 of this object - (and therefore only 1 of each of any of these markers) in the world. - - .. testcode:: - - import anki_vector - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - robot.world.define_custom_cube(custom_object_type=anki_vector.objects.CustomObjectTypes.CustomType00, - marker=anki_vector.objects.CustomObjectMarkers.Circles2, - size_mm=20.0, - marker_width_mm=50.0, marker_height_mm=50.0) - - Returns: - CustomObject instance with the specified dimensions. - This is None if the definition failed internally. - Note: No instances of this object are added to the world until they have been seen. - - Raises: - TypeError if the custom_object_type is of the wrong type. - """ - - if not isinstance(custom_object_type, objects._CustomObjectType): # pylint: disable=protected-access - raise TypeError("Unsupported object_type, requires CustomObjectType") - - custom_object_archetype = objects.CustomObjectArchetype(custom_object_type, - size_mm, size_mm, size_mm, - marker_width_mm, marker_height_mm, - is_unique) - - definition = protocol.CustomCubeDefinition(marker=marker.id, - size_mm=size_mm, - marker_width_mm=marker_width_mm, - marker_height_mm=marker_height_mm) - - req = protocol.DefineCustomObjectRequest(custom_type=custom_object_type.id, - is_unique=is_unique, - custom_cube=definition) - - response = await self.grpc_interface.DefineCustomObject(req) - - if response.success: - type_id = custom_object_archetype.custom_type.id - self._custom_object_archetypes[type_id] = custom_object_archetype - return custom_object_archetype - - self.logger.error("Failed to define Custom Object %s", custom_object_archetype) - return None - - @connection.on_connection_thread(requires_control=False) - async def define_custom_wall(self, - custom_object_type: objects.CustomObjectTypes, - marker: objects.CustomObjectMarkers, - width_mm: float, - height_mm: float, - marker_width_mm: float, - marker_height_mm: float, - is_unique: bool = True) -> objects.CustomObject: - """Defines a wall of custom width and height, with a fixed depth of 10mm, and binds it to a specific custom object type. - - The robot will now detect the markers associated with this object and send an - object_observed message when they are seen. The markers must be placed in the center - of their respective sides. - - :param custom_object_type: the object type you are binding this custom object to. - :param marker: the marker affixed to the front and back of the wall. - :param width_mm: width of the object (in millimeters). (Y axis). - :param height_mm: height of the object (in millimeters). (Z axis). - :param width_mm: width of the wall (along Y axis) (in millimeters). - :param height_mm: height of the wall (along Z axis) (in millimeters). - :param marker_width_mm: width of the printed marker (in millimeters). - :param maker_height_mm: height of the printed marker (in millimeters). - :param is_unique: If True, the robot will assume there is only 1 of this object - (and therefore only 1 of each of any of these markers) in the world. - - .. testcode:: - - import anki_vector - with anki_vector.Robot(enable_custom_object_detection=True) as robot: - robot.world.define_custom_wall(custom_object_type=anki_vector.objects.CustomObjectTypes.CustomType00, - marker=anki_vector.objects.CustomObjectMarkers.Circles2, - width_mm=20.0, height_mm=20.0, - marker_width_mm=50.0, marker_height_mm=50.0) - - Returns: - CustomObject instance with the specified dimensions. - This is None if the definition failed internally. - Note: No instances of this object are added to the world until they have been seen. - - Raises: - TypeError if the custom_object_type is of the wrong type. - """ - - if not isinstance(custom_object_type, objects._CustomObjectType): # pylint: disable=protected-access - raise TypeError("Unsupported object_type, requires CustomObjectType") - - thickness_mm = protocol.ObjectConstants.Value("FIXED_CUSTOM_WALL_THICKNESS_MM") - - custom_object_archetype = objects.CustomObjectArchetype(custom_object_type, - thickness_mm, width_mm, height_mm, - marker_width_mm, marker_height_mm, - is_unique) - - definition = protocol.CustomWallDefinition(marker=marker.id, - width_mm=width_mm, - height_mm=height_mm, - marker_width_mm=marker_width_mm, - marker_height_mm=marker_height_mm) - - req = protocol.DefineCustomObjectRequest(custom_type=custom_object_type.id, - is_unique=is_unique, - custom_wall=definition) - - response = await self.grpc_interface.DefineCustomObject(req) - - if response.success: - type_id = custom_object_archetype.custom_type.id - self._custom_object_archetypes[type_id] = custom_object_archetype - return custom_object_archetype - - self.logger.error("Failed to define Custom Object %s", custom_object_archetype) - return None - - def create_custom_fixed_object(self, - pose: util.Pose, - x_size_mm: float, - y_size_mm: float, - z_size_mm: float, - relative_to_robot: bool = False, - use_robot_origin: bool = True) -> objects.FixedCustomObject: - """Defines a cuboid of custom size and places it in the world. It cannot be observed. - - :param pose: The pose of the object we are creating. - :param x_size_mm: size of the object (in millimeters) in the x axis. - :param y_size_mm: size of the object (in millimeters) in the y axis. - :param z_size_mm: size of the object (in millimeters) in the z axis. - :param relative_to_robot: whether or not the pose given assumes the robot's pose as its origin. - :param use_robot_origin: whether or not to override the origin_id in the given pose to be - the origin_id of Vector. - - .. testcode:: - - import anki_vector - from anki_vector.util import degrees, Pose - - with anki_vector.Robot() as robot: - robot.world.create_custom_fixed_object(Pose(100, 0, 0, angle_z=degrees(0)), - x_size_mm=10, y_size_mm=100, z_size_mm=100, - relative_to_robot=True) - - Returns: - FixedCustomObject instance with the specified dimensions and pose. - """ - # Override the origin of the pose to be the same as the robot's. This will make sure they are in - # the same space in the robot every time. - if use_robot_origin: - pose = util.Pose(x=pose.position.x, y=pose.position.y, z=pose.position.z, - q0=pose.rotation.q0, q1=pose.rotation.q1, - q2=pose.rotation.q2, q3=pose.rotation.q3, - origin_id=self._robot.pose.origin_id) - - # In this case define the given pose to be with respect to the robot's pose as its origin. - if relative_to_robot: - pose = self._robot.pose.define_pose_relative_this(pose) - - response = self._create_custom_fixed_object(pose, x_size_mm, y_size_mm, z_size_mm) - if isinstance(response, futures.Future): - response = response.result() - - fixed_custom_object = self.fixed_custom_object_factory( - self._robot, - pose, - x_size_mm, - y_size_mm, - z_size_mm, - response.object_id) - - if fixed_custom_object: - self._objects[fixed_custom_object.object_id] = fixed_custom_object - return fixed_custom_object - - @connection.on_connection_thread(requires_control=False) - async def _create_custom_fixed_object(self, - pose: util.Pose, - x_size_mm: float, - y_size_mm: float, - z_size_mm: float): - """Send the CreateFixedCustomObject rpc call on the connection thread.""" - req = protocol.CreateFixedCustomObjectRequest( - pose=pose.to_proto_pose_struct(), - x_size_mm=x_size_mm, - y_size_mm=y_size_mm, - z_size_mm=z_size_mm) - - return await self.grpc_interface.CreateFixedCustomObject(req) - - #### Private Methods #### - - def _allocate_custom_marker_object(self, msg): - # obj is the base object type for this custom object. We make instances of this for every - # unique object_id we see of this custom object type. - first_custom_type = protocol.ObjectType.Value("FIRST_CUSTOM_OBJECT_TYPE") - if msg.object_type < first_custom_type or msg.object_type >= first_custom_type + protocol.CustomType.Value("CUSTOM_TYPE_COUNT"): - self.logger.error('Received a custom object observation with a type not inside the custom object range: %s. Msg=%s', - msg.object_type, msg) - return None - - # Object observation events contain an object_type. A subset of that object_type enum maps to the - # custom_type enum, so we perform the conversion. - custom_type = msg.object_type - first_custom_type + objects.CustomObjectTypes.CustomType00.id - archetype = self._custom_object_archetypes.get(custom_type) - if not archetype: - self.logger.error('Received a custom object type: %s that has not been defined yet. Msg=%s', - msg.object_type, msg) - return None - - custom_object = self.custom_object_factory(self._robot, - archetype, - msg.object_id) - - self.logger.debug('Allocated object_id=%s to CustomObject %s', msg.object_id, custom_object) - - if custom_object: - self._custom_objects[msg.object_id] = custom_object - return custom_object - - def _allocate_charger(self, msg): - charger = self.charger_factory(self._robot, msg.object_id) - if self._charger: - self.logger.warning('Allocating multiple chargers: existing charger=%s msg=%s', self._charger, msg) - return None - - self._charger = charger - - self.logger.debug('Allocated object_id=%s to Charger %s', msg.object_id, charger) - return charger - - def _remove_all_custom_marker_object_instances(self): - for obj_id, obj in list(self._custom_objects.items()): - if isinstance(obj, objects.CustomObject): - self.logger.info("Removing CustomObject instance: id %s = obj '%s'", obj_id, obj) - self._custom_objects.pop(obj_id, None) - - def _remove_all_fixed_custom_object_instances(self): - for obj_id, obj in list(self._custom_objects.items()): - if isinstance(obj, objects.FixedCustomObject): - self.logger.info("Removing FixedCustomObject instance: id %s = obj '%s'", obj_id, obj) - self._custom_objects.pop(obj_id, None) - - #### Private Event Handlers #### - - def _on_face_observed(self, _, msg): - """Adds a newly observed face to the world view.""" - if msg.face_id not in self._faces or msg.face_id not in self._objects: - pose = util.Pose(x=msg.pose.x, y=msg.pose.y, z=msg.pose.z, - q0=msg.pose.q0, q1=msg.pose.q1, - q2=msg.pose.q2, q3=msg.pose.q3, - origin_id=msg.pose.origin_id) - image_rect = util.ImageRect(msg.img_rect.x_top_left, - msg.img_rect.y_top_left, - msg.img_rect.width, - msg.img_rect.height) - face = self.face_factory(self.robot, - pose, image_rect, msg.face_id, msg.name, msg.expression, msg.expression_values, - msg.left_eye, msg.right_eye, msg.nose, msg.mouth, msg.timestamp) - if face: - self._faces[face.face_id] = face - self._objects[face.face_id] = face - - def _on_object_observed(self, _, msg): - """Adds a newly observed custom object to the world view.""" - if msg.object_family == protocol.ObjectFamily.Value("LIGHT_CUBE"): - if msg.object_id not in self._objects: - if self.light_cube: - self._objects[msg.object_id] = self.light_cube - - if msg.object_family == protocol.ObjectFamily.Value("CHARGER"): - if msg.object_id not in self._objects: - charger = self._allocate_charger(msg) - if charger: - self._objects[msg.object_id] = charger - - if msg.object_family == protocol.ObjectFamily.Value("CUSTOM_OBJECT"): - if msg.object_id not in self._objects: - custom_object = self._allocate_custom_marker_object(msg) - if custom_object: - self._objects[msg.object_id] = custom_object diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 701c5ae..0000000 --- a/docs/Makefile +++ /dev/null @@ -1,229 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -ifeq ($(VERBOSE),1) - VERBOSE_OPTS = -vv -endif -SPHINXOPTS = $(VERBOSE_OPTS) -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source - -.PHONY: help -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " applehelp to make an Apple Help Book" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " epub3 to make an epub3" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " coverage to run coverage check of the documentation (if enabled)" - @echo " dummy to check syntax errors of document sources" - -.PHONY: clean -clean: - rm -rf $(BUILDDIR)/* - rm -rf source/generated - -.PHONY: html -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -.PHONY: dirhtml -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -.PHONY: singlehtml -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -.PHONY: pickle -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -.PHONY: json -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -.PHONY: htmlhelp -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -.PHONY: qthelp -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/CozmoSDK.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/CozmoSDK.qhc" - -.PHONY: applehelp -applehelp: - $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp - @echo - @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." - @echo "N.B. You won't be able to view it unless you put it in" \ - "~/Library/Documentation/Help or install it in your application" \ - "bundle." - -.PHONY: devhelp -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/CozmoSDK" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/CozmoSDK" - @echo "# devhelp" - -.PHONY: epub -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -.PHONY: epub3 -epub3: - $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 - @echo - @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." - -.PHONY: latex -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -.PHONY: latexpdf -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: latexpdfja -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: text -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -.PHONY: man -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -.PHONY: texinfo -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -.PHONY: info -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -.PHONY: gettext -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -.PHONY: changes -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -.PHONY: linkcheck -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -.PHONY: doctest -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -.PHONY: coverage -coverage: - $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage - @echo "Testing of coverage in the sources finished, look at the " \ - "results in $(BUILDDIR)/coverage/python.txt." - -.PHONY: xml -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -.PHONY: pseudoxml -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." - -.PHONY: dummy -dummy: - $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy - @echo - @echo "Build finished. Dummy builder generates no files." diff --git a/docs/ext/custopoleon/__init__.py b/docs/ext/custopoleon/__init__.py deleted file mode 100644 index 72a4120..0000000 --- a/docs/ext/custopoleon/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -""" -Due to deficiencies in the design of Sphinx, two modules cannot both -observe the same event. Napaleon hooks the autodoc-skip-member event -to determine which members to show.. We want to use the same thing -to special case the AnimTriggers and BehaviorTypes classes so that -their undocumented members show up in the docs. - -As a workaround this module monkey patches Napoleon to wrap their -autodoc-skip-member implementation and special case the response for -our classes. -""" - - -import sphinx.ext.napoleon - - -_org_skip_member = sphinx.ext.napoleon._skip_member - -# TODO: determine if this is still necessary -def _skip_member(app, what, name, obj, skip, options): - clsname = obj.__class__.__name__ - if clsname in ('_AnimTrigger', '_BehaviorType'): - return False - if name in ('GatewayWrapper', 'FindInitializationErrors', 'IsInitialized', 'SetInParent', 'WhichOneof'): - return True - return _org_skip_member(app, what, name, obj, skip, options) - -sphinx.ext.napoleon._skip_member = _skip_member - -def setup(app): - return sphinx.ext.napoleon.setup(app) - diff --git a/docs/ext/verlink.py b/docs/ext/verlink.py deleted file mode 100644 index 7fe5b1f..0000000 --- a/docs/ext/verlink.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Generate versioned links for example files. - -This extension adds a new role to generate links to the correct version -of files referenced by the documentation. - -It substitutes the string "0.0.0" with a version number defined by the -"verlink_version" configuration value. - -Roles can optionally include text to use for the link, else it defaults -to the supplied filename. the URL is prefixed with the -"verlink_base_url" value to make a complete URL. - -For example, if verlink_base_url="https://example.com/files/0.0.0/" -and verlink_version="1.2.3" then - -:verlink:`examples-0.0.0.zip` will display "examples-1.2.3.zip" and link -to https:/example.com/files/1.2.3/examples-1.2.3.zip - -:verlink:`Examples for 0.0.0 ` will display -"Examples for 1.2.3" and link to https:/example.com/files/1.2.3/examples-1.2.3.zip -""" - - -from docutils import nodes, utils - -import sphinx -from sphinx.util.nodes import split_explicit_title - - -def replace_version(app, str): - try: - ver = app.config.verlink_version - except AttributeError as err: - raise ValueError("verlink_version configuration value is not set") - return str.replace('0.0.0', ver) - - -def verlink_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): - app = inliner.document.settings.env.app - try: - base_url = app.config.verlink_base_url - except AttributeError as err: - raise ValueError("verlink_base_url configuration value is not set") - - text = utils.unescape(text) - has_explicit_title, title, fn = split_explicit_title(text) - full_url = replace_version(app, base_url + fn) - if not has_explicit_title: - title = fn - title = replace_version(app, title) - pnode = nodes.reference(title, title, internal=False, refuri=full_url) - return [pnode], [] - - -def setup(app): - app.add_role('verlink', verlink_role) - app.add_config_value('verlink_base_url', None, {}) - app.add_config_value('verlink_version', None, {}) diff --git a/docs/source/.gitignore b/docs/source/.gitignore deleted file mode 100644 index 9ab870d..0000000 --- a/docs/source/.gitignore +++ /dev/null @@ -1 +0,0 @@ -generated/ diff --git a/docs/source/_static/.gitignore b/docs/source/_static/.gitignore deleted file mode 100644 index d2b263c..0000000 --- a/docs/source/_static/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# No files should be checked into this directory -* -!.gitignore diff --git a/docs/source/_templates/layout.html b/docs/source/_templates/layout.html deleted file mode 100644 index 7d57882..0000000 --- a/docs/source/_templates/layout.html +++ /dev/null @@ -1,94 +0,0 @@ -{% extends "!layout.html" %} -{% block extrahead %} - - - - {{ super() }} -{% endblock %} diff --git a/docs/source/advanced-tips.rst b/docs/source/advanced-tips.rst deleted file mode 100644 index fa9c196..0000000 --- a/docs/source/advanced-tips.rst +++ /dev/null @@ -1,74 +0,0 @@ -.. _advanced-tips: - -############# -Advanced Tips -############# - -.. _moving_between_wifi: - -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Moving Vector between WiFi networks -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -When you move Vector from one WiFi network to another (using the Vector App), -or if your Vector's IP changes, you will also need to make some changes to -your SDK setup. To assist in this migration, the ``anki_vector.configure`` -executable submodule provides a ``-u`` parameter to quickly reconnect to Vector. - -To update your connection, you will need to find the IP address on -Vector's face, and the serial number of the robot you are updating. -Then from your terminal run:: - - python3 -m anki_vector.configure -u "" -s "" - - -^^^^^^^^^^^^^^^^^^^^^^ -Using multiple Vectors -^^^^^^^^^^^^^^^^^^^^^^ - -If your device is configured to use more than one robot, you can specify -which robot you want to use by passing its serial number as a parameter -to the Robot constructor:: - - - with anki_vector.Robot("00e20142") as robot: - robot.anim.play_animation('anim_pounce_success_02') - - -Alternatively, you can pass a ``--serial`` flag on the command -line, and ``anki_vector.util.parse_command_args`` will parse out -the serial number:: - - ./01_hello_world.py --serial 00e20142 - - -^^^^^^^^^^^^^^^^^^^^^ -Set ANKI_ROBOT_SERIAL -^^^^^^^^^^^^^^^^^^^^^ - -In order to avoid entering Vector's serial number for each program run, -you can create environment variable ``ANKI_ROBOT_SERIAL`` -and set it to Vector's serial number:: - - export ANKI_ROBOT_SERIAL=00e20100 - - -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Set ANKI_ROBOT_HOST and VECTOR_ROBOT_NAME -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -When running the ``anki_vector.configure`` executable submodule, you must provide Vector's ip and name. -To avoid typing these in, you can instead create environment variables -ANKI_ROBOT_HOST and VECTOR_ROBOT_NAME. Then ``anki_vector.configure`` will automatically pick -up those settings:: - - export ANKI_ROBOT_HOST="192.168.42.42" - export VECTOR_ROBOT_NAME=Vector-A1B2 - - - ----- - -`Terms and Conditions `_ and `Privacy Policy `_ - -`Click here to return to the Anki Developer website. `_ diff --git a/docs/source/api.rst b/docs/source/api.rst deleted file mode 100644 index eb2c643..0000000 --- a/docs/source/api.rst +++ /dev/null @@ -1,46 +0,0 @@ -The API -======= - - -.. autosummary:: - :nosignatures: - :toctree: generated - - anki_vector - anki_vector.animation - anki_vector.audio - anki_vector.behavior - anki_vector.camera - anki_vector.color - anki_vector.connection - anki_vector.events - anki_vector.exceptions - anki_vector.faces - anki_vector.lights - anki_vector.motors - anki_vector.nav_map - anki_vector.objects - anki_vector.opengl - anki_vector.opengl.opengl - anki_vector.opengl.opengl_vector - anki_vector.opengl.opengl_viewer - anki_vector.photos - anki_vector.proximity - anki_vector.robot - anki_vector.screen - anki_vector.status - anki_vector.touch - anki_vector.util - anki_vector.viewer - anki_vector.vision - anki_vector.world - - anki_vector.messaging.client - -.. - ----- - -`Terms and Conditions `_ and `Privacy Policy `_ - -`Click here to return to the Anki Developer website. `_ diff --git a/docs/source/conf.py b/docs/source/conf.py deleted file mode 100644 index d2c7dab..0000000 --- a/docs/source/conf.py +++ /dev/null @@ -1,405 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# Vector SDK documentation build configuration file, created by -# sphinx-quickstart on Tue Jul 19 17:16:49 2016. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os -import subprocess -import sys - -sys.path.extend([os.path.abspath('../..'), os.path.abspath('..')]) -here = os.path.abspath(os.path.dirname(__file__)) -sdk_base_dir = os.path.join(here, '..', '..') - - -def fetch_sdk_version(): - with open(os.path.join(sdk_base_dir, 'anki_vector', 'version.py')) as f: - ns = {} - exec(f.read(), ns) - return ns - -version_data = fetch_sdk_version() -sdk_version = version_data['__version__'] - - -version = sdk_version - -if '.dev' in version: - try: - git_branch = subprocess.check_output( - ('git', 'symbolic-ref', '--short', 'HEAD'), - universal_newlines=True) - - git_commit = subprocess.check_output( - ('git', 'rev-parse', 'HEAD'), - universal_newlines=True) - - version = "%s - %s (%s)" % (git_branch, git_commit[:8], sdk_version) - - except subprocess.CalledProcessError as e: - print("Failed to run git: %s" % e) - - - - - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.autodoc', - 'sphinx_autodoc_typehints', - 'sphinx.ext.autosummary', - 'sphinx.ext.intersphinx', - 'sphinx.ext.doctest', # Test sample code snippets in the docs - 'ext.verlink', # build versioned links for example packages - 'ext.custopoleon' # Customizes the Napoleon package - #'sphinx.ext.napoleon' -] - -verlink_base_url = 'https://sdk-resources.anki.com/vector/%s/' % sdk_version -verlink_version = sdk_version - -intersphinx_mapping = { - 'python': ('https://docs.python.org/3.6', None), - 'numpy': ('https://docs.scipy.org/doc/numpy/', None), - 'PIL': ('https://pillow.readthedocs.io/en/latest/', None) - } - -autosummary_generate = True -autodoc_default_flags = ['members'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The encoding of source files. -# -# source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = 'Vector SDK' -copyright = '2018, Anki' -author = 'Anki' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -#version = '0.1' - -# The full version, including alpha/beta/rc tags. -release = '0.1' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# -# today = '' -# -# Else, today_fmt is used as the format for a strftime call. -# -# today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = [] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -# -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# -# add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# -# show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -# keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -#html_theme = 'alabaster' -#html_theme = 'default' -html_theme = 'sphinx_rtd_theme' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -html_theme_path = [] - -# The name for this set of Sphinx documents. -# " v documentation" by default. -# -# html_title = 'Vector SDK v0.1' - -# A shorter title for the navigation bar. Default is the same as html_title. -# -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# -# html_logo = None - -# The name of an image file (relative to this directory) to use as a favicon of -# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# -# html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -# -# html_extra_path = [] - -# If not None, a 'Last updated on:' timestamp is inserted at every page -# bottom, using the given strftime format. -# The empty string is equivalent to '%b %d, %Y'. -# -html_last_updated_fmt = '%b, %d, %Y %I:%M:%S %Z' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# -# html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -# -# html_sidebars = {} -#html_sidebars = { -# '**': ['globaltoc.html', 'sourcelink.html', 'searchbox.html'] -#} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# -# html_additional_pages = {} - -# If false, no module index is generated. -# -# html_domain_indices = True - -# If false, no index is generated. -# -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr', 'zh' -# -# html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# 'ja' uses this config value. -# 'zh' user can custom change `jieba` dictionary path. -# -# html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -# -# html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'VectorSDKdoc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'VectorSDK.tex', 'Vector SDK Documentation', - 'Anki', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# -# latex_use_parts = False - -# If true, show page references after internal links. -# -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# -# latex_appendices = [] - -# It false, will not define \strong, \code, itleref, \crossref ... but only -# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added -# packages. -# -# latex_keep_old_macro_names = True - -# If false, no module index is generated. -# -# latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'vectorsdk', 'Vector SDK Documentation', - [author], 1) -] - -# If true, show URL addresses after external links. -# -# man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'VectorSDK', 'Vector SDK Documentation', - author, 'VectorSDK', 'The SDK for directly controlling your Vector', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -# -# texinfo_appendices = [] - -# If false, no module index is generated. -# -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# -# texinfo_no_detailmenu = False - - -# Customized stuff appears below here diff --git a/docs/source/downloads.rst b/docs/source/downloads.rst deleted file mode 100644 index 6cf7a60..0000000 --- a/docs/source/downloads.rst +++ /dev/null @@ -1,25 +0,0 @@ -######### -Downloads -######### - ------------- -SDK Examples ------------- - -Download Python example scripts that use the Vector SDK. - -:verlink:`macOS/Linux SDK Examples ` - -:verlink:`Windows SDK Examples ` - ------- -GitHub ------- - -Clone, fork, or report issues on the `GitHub vector-python-sdk repository `_. - ----- - -`Terms and Conditions `_ and `Privacy Policy `_ - -`Click here to return to the Anki Developer website. `_ diff --git a/docs/source/getstarted.rst b/docs/source/getstarted.rst deleted file mode 100644 index dd47874..0000000 --- a/docs/source/getstarted.rst +++ /dev/null @@ -1,92 +0,0 @@ -=================================== -Getting Started With the Vector SDK -=================================== - -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 `. - ---------------------- -Anki Developer Forums ---------------------- - -Please visit our `Anki Developer Forums `_ where you can: - -* Get assistance with your code - -* Hear about upcoming SDK additions - -* Share your work - -* Join discussion about the SDK - -* Be a part of the Vector SDK Community! - - -------------- -Prerequisites -------------- - -* You have completed the Installation steps, found here: :ref:`initial` -* The Vector companion app is *not* currently connected to Vector. -* Vector is connected to the same network as your computer. -* You can see Vector's eyes on his screen. - -------------------- -Starting Up the SDK -------------------- - -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**. - ----------------- -Example Program ----------------- - -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -First Steps - "Hello, World!" -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -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. - -""""""""""" -The Program -""""""""""" - -1. Run the program using the same Terminal (macOS/Linux) / Command Prompt (Windows) window mentioned above. First, change to the ``tutorials`` sub-directory:: - - cd tutorials - -Then, run the program. - - a. For macOS and Ubuntu 18.04 systems, type the following and press **Enter**:: - - ./01_hello_world.py - - The same can also be achieved with:: - - python3 01_hello_world.py - - b. For Windows systems, type the following and press **Enter**:: - - py 01_hello_world.py - - c. For Ubuntu 16.04 systems, type the following and press **Enter**:: - - python3.6 01_hello_world.py - - -2. If done correctly, Vector will say "Hello, World!" - -.. 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. - -.. 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: - ``./01_hello_world.py --serial {robot_serial_number}`` - - -You are now all set up to run Python programs on Vector. - - - -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. - -`Terms and Conditions `_ and `Privacy Policy `_ - -`Click here to return to the Anki Developer website. `_ diff --git a/docs/source/images/custom_markers/LICENSE.txt b/docs/source/images/custom_markers/LICENSE.txt deleted file mode 100644 index fd011d5..0000000 --- a/docs/source/images/custom_markers/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -Anki, Inc. Image License Agreement Version 1.1 (last updated November 15, 2018) - -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. - -The "Licensed Materials" are the digital images that we make available to you from time to time in connection with this Agreement. - -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. - -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. - -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. - -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. - -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. - -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. - -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. - -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. diff --git a/docs/source/images/custom_markers/SDK_2Circles.png b/docs/source/images/custom_markers/SDK_2Circles.png deleted file mode 100644 index 5dd3108..0000000 Binary files a/docs/source/images/custom_markers/SDK_2Circles.png and /dev/null differ diff --git a/docs/source/images/custom_markers/SDK_2Diamonds.png b/docs/source/images/custom_markers/SDK_2Diamonds.png deleted file mode 100644 index 93d45f6..0000000 Binary files a/docs/source/images/custom_markers/SDK_2Diamonds.png and /dev/null differ diff --git a/docs/source/images/custom_markers/SDK_2Hexagons.png b/docs/source/images/custom_markers/SDK_2Hexagons.png deleted file mode 100644 index 3824347..0000000 Binary files a/docs/source/images/custom_markers/SDK_2Hexagons.png and /dev/null differ diff --git a/docs/source/images/custom_markers/SDK_2Triangles.png b/docs/source/images/custom_markers/SDK_2Triangles.png deleted file mode 100644 index acc57d4..0000000 Binary files a/docs/source/images/custom_markers/SDK_2Triangles.png and /dev/null differ diff --git a/docs/source/images/custom_markers/SDK_3Circles.png b/docs/source/images/custom_markers/SDK_3Circles.png deleted file mode 100644 index c138c11..0000000 Binary files a/docs/source/images/custom_markers/SDK_3Circles.png and /dev/null differ diff --git a/docs/source/images/custom_markers/SDK_3Diamonds.png b/docs/source/images/custom_markers/SDK_3Diamonds.png deleted file mode 100644 index 750a1dc..0000000 Binary files a/docs/source/images/custom_markers/SDK_3Diamonds.png and /dev/null differ diff --git a/docs/source/images/custom_markers/SDK_3Hexagons.png b/docs/source/images/custom_markers/SDK_3Hexagons.png deleted file mode 100644 index b002d34..0000000 Binary files a/docs/source/images/custom_markers/SDK_3Hexagons.png and /dev/null differ diff --git a/docs/source/images/custom_markers/SDK_3Triangles.png b/docs/source/images/custom_markers/SDK_3Triangles.png deleted file mode 100644 index 901b855..0000000 Binary files a/docs/source/images/custom_markers/SDK_3Triangles.png and /dev/null differ diff --git a/docs/source/images/custom_markers/SDK_4Circles.png b/docs/source/images/custom_markers/SDK_4Circles.png deleted file mode 100644 index 75408ac..0000000 Binary files a/docs/source/images/custom_markers/SDK_4Circles.png and /dev/null differ diff --git a/docs/source/images/custom_markers/SDK_4Diamonds.png b/docs/source/images/custom_markers/SDK_4Diamonds.png deleted file mode 100644 index 0ec8471..0000000 Binary files a/docs/source/images/custom_markers/SDK_4Diamonds.png and /dev/null differ diff --git a/docs/source/images/custom_markers/SDK_4Hexagons.png b/docs/source/images/custom_markers/SDK_4Hexagons.png deleted file mode 100644 index b80002e..0000000 Binary files a/docs/source/images/custom_markers/SDK_4Hexagons.png and /dev/null differ diff --git a/docs/source/images/custom_markers/SDK_4Triangles.png b/docs/source/images/custom_markers/SDK_4Triangles.png deleted file mode 100644 index d163327..0000000 Binary files a/docs/source/images/custom_markers/SDK_4Triangles.png and /dev/null differ diff --git a/docs/source/images/custom_markers/SDK_5Circles.png b/docs/source/images/custom_markers/SDK_5Circles.png deleted file mode 100644 index 39a4657..0000000 Binary files a/docs/source/images/custom_markers/SDK_5Circles.png and /dev/null differ diff --git a/docs/source/images/custom_markers/SDK_5Diamonds.png b/docs/source/images/custom_markers/SDK_5Diamonds.png deleted file mode 100644 index e033799..0000000 Binary files a/docs/source/images/custom_markers/SDK_5Diamonds.png and /dev/null differ diff --git a/docs/source/images/custom_markers/SDK_5Hexagons.png b/docs/source/images/custom_markers/SDK_5Hexagons.png deleted file mode 100644 index 00fc45a..0000000 Binary files a/docs/source/images/custom_markers/SDK_5Hexagons.png and /dev/null differ diff --git a/docs/source/images/custom_markers/SDK_5Triangles.png b/docs/source/images/custom_markers/SDK_5Triangles.png deleted file mode 100644 index a451b29..0000000 Binary files a/docs/source/images/custom_markers/SDK_5Triangles.png and /dev/null differ diff --git a/docs/source/images/vector-sdk-alpha.jpg b/docs/source/images/vector-sdk-alpha.jpg deleted file mode 100644 index 91c5389..0000000 Binary files a/docs/source/images/vector-sdk-alpha.jpg and /dev/null differ diff --git a/docs/source/index.rst b/docs/source/index.rst deleted file mode 100644 index 3581af4..0000000 --- a/docs/source/index.rst +++ /dev/null @@ -1,56 +0,0 @@ -.. image:: images/vector-sdk-alpha.jpg - -| - -=============================== -Welcome to the Vector SDK Alpha -=============================== - -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. - -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. - -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. Please visit the official `Anki Developer Forums `_ for more details. - -.. toctree:: - :maxdepth: 1 - :caption: Installation - - initial - install-macos.rst - install-windows.rst - install-linux.rst - troubleshooting.rst - advanced-tips.rst - -.. toctree:: - :maxdepth: 2 - :caption: Downloads - - downloads.rst - -.. toctree:: - :maxdepth: 2 - :caption: Get Started - - getstarted.rst - -.. toctree:: - :maxdepth: 2 - :caption: API Reference - - api - ------------------- -Indices and tables ------------------- - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - ----- - -`Terms and Conditions `_ and `Privacy Policy `_ - -`Click here to return to the Anki Developer website. `_ diff --git a/docs/source/initial.rst b/docs/source/initial.rst deleted file mode 100644 index 089d859..0000000 --- a/docs/source/initial.rst +++ /dev/null @@ -1,44 +0,0 @@ -.. _initial: - -############# -Initial Setup -############# - ------------- -Installation ------------- - -To install the SDK on your system, select the instructions for your computer's operating system. - -* :ref:`install-macos` -* :ref:`install-windows` -* :ref:`install-linux` - - --------------------- -SDK Example Programs --------------------- - -Anki provides example programs for novice and advanced users to run with the SDK. Download the SDK example programs here: - - * :verlink:`macOS/Linux SDK Examples ` - - * :verlink:`Windows SDK Examples ` - -Once downloaded, extract the packaged files to a new directory. - -.. - -.. _trouble: - -^^^^^^^^^^^^^^^^^^^^^ -Anki Developer Forums -^^^^^^^^^^^^^^^^^^^^^ - -Please visit the `Anki Developer Forums `_ to ask questions, find solutions and for general discussion. - ----- - -`Terms and Conditions `_ and `Privacy Policy `_ - -`Click here to return to the Anki Developer website. `_ diff --git a/docs/source/install-linux.rst b/docs/source/install-linux.rst deleted file mode 100644 index e5c48a9..0000000 --- a/docs/source/install-linux.rst +++ /dev/null @@ -1,133 +0,0 @@ -.. _install-linux: - -#################### -Installation - Linux -#################### - -^^^^^^^^^^^^^ -Prerequisites -^^^^^^^^^^^^^ - -* Vector is powered on. -* You have successfully created an Anki account. -* Vector has been set up with the Vector companion app. -* The Vector companion app is *not* currently connected to Vector. -* Vector is connected to the same network as your computer. -* You can see Vector's eyes on his screen. - - -This guide provides instructions on installing the Vector SDK for computers running with an Ubuntu Linux operating system. - -.. warning:: The Vector SDK is tested and and supported on Ubuntu 18.04 and 16.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 18.04 or 16.04, please ensure the following dependencies are installed: - - * Python 3.6.1 or later - * pip for Python 3 (Python package installer) - - - -^^^^^^^^^^^^ -Ubuntu 18.04 -^^^^^^^^^^^^ - -""""""""""""""""""" -Python Installation -""""""""""""""""""" - -1. Type the following into your Terminal window to install Python:: - - sudo apt-get update - sudo apt-get install python3 - -2. Then install pip by typing in the following into the Terminal window:: - - sudo apt install python3-pip - -"""""""""""""""" -SDK Installation -"""""""""""""""" - -To install the SDK, type the following into the Terminal window:: - - python3 -m pip install --user anki_vector - -^^^^^^^^^^^^^^^^^^^^^ -Vector Authentication -^^^^^^^^^^^^^^^^^^^^^ - -To authenticate with the robot, type the following into the Terminal window:: - - python3 -m anki_vector.configure - -You will be prompted for your robot's name, ip address and serial number. You will also be asked for your Anki login and password. Make sure to use the same account that was used to set up your Vector. - -You will see "SUCCESS!" when this script successfully completes. - -.. note:: By running the ``anki_vector.configure`` executable submodule, you will be asked to provide your Anki account credentials, 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). - - 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. - -.. warning:: These credentials give full access to your robot, including camera stream, audio stream and data. Do not share these credentials. - - - -^^^^^^^^^^^^ -Ubuntu 16.04 -^^^^^^^^^^^^ - -"""""""""""""""""""""""""""""" -Python and Module Installation -"""""""""""""""""""""""""""""" - -1. Type the following into your Terminal window to install Python 3.6:: - - sudo add-apt-repository ppa:deadsnakes/ppa - sudo apt-get update - sudo apt-get install python3.6 - -2. Then install pip by typing in the following into the Terminal window:: - - sudo apt install python3-pip - -3. Install the following additional packages:: - - sudo apt-get install build-essential libssl-dev libffi-dev python3.6-dev - - -"""""""""""""""" -SDK Installation -"""""""""""""""" - -To install the SDK, type the following into the Terminal window:: - - python3.6 -m pip install --user anki_vector - -^^^^^^^^^^^^^^^^^^^^^ -Vector Authentication -^^^^^^^^^^^^^^^^^^^^^ - -To authenticate with the robot, type the following into the Terminal window:: - - python3.6 -m anki_vector.configure - -You will be prompted for your robot's name, ip address and serial number. You will also be asked for your Anki login and password. Make sure to use the same account that was used to set up your Vector. - -You will see "SUCCESS!" when this script successfully completes. - -.. note:: By running the ``anki_vector.configure`` executable submodule, you will be asked to provide your Anki account credentials, 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). - - 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. - -.. warning:: These credentials give full access to your robot, including camera stream, audio stream and data. Do not share these credentials. - - -^^^^^^^^^^^^^^^ -Troubleshooting -^^^^^^^^^^^^^^^ - -Please see the :doc:`Troubleshooting ` page for tips, or visit the `Anki Developer Forums `_ to ask questions, find solutions, or for general discussion. - ----- - -`Terms and Conditions `_ and `Privacy Policy `_ - -`Click here to return to the Anki Developer website. `_ diff --git a/docs/source/install-macos.rst b/docs/source/install-macos.rst deleted file mode 100644 index e229cca..0000000 --- a/docs/source/install-macos.rst +++ /dev/null @@ -1,72 +0,0 @@ -.. _install-macos: - -########################### -Installation - macOS / OS X -########################### - -This guide provides instructions on installing the Vector SDK for computers running with a macOS operating system. - -^^^^^^^^^^^^^ -Prerequisites -^^^^^^^^^^^^^ - -* Vector is powered on. -* You have successfully created an Anki account. -* Vector has been set up with the Vector companion app. -* The Vector companion app is *not* currently connected to Vector. -* Vector is connected to the same network as your computer. -* You can see Vector's eyes on his screen. - - -^^^^^^^^^^^^^^^^^^^ -Python Installation -^^^^^^^^^^^^^^^^^^^ - -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:: - - brew update - -2. Once Homebrew is installed and updated, type the following into the Terminal window to install the latest version of Python 3:: - - brew install python3 - -The Vector SDK supports Python 3.6.1 or later. - - -^^^^^^^^^^^^^^^^ -SDK Installation -^^^^^^^^^^^^^^^^ - -To install the SDK, navigate into the SDK folder and type the following into a Terminal window:: - - python3 -m pip install --user anki_vector - -^^^^^^^^^^^^^^^^^^^^^ -Vector Authentication -^^^^^^^^^^^^^^^^^^^^^ - -To authenticate with the robot, type the following into the Terminal window:: - - python3 -m anki_vector.configure - -You will be prompted for your robot's name, ip address and serial number. You will also be asked for your Anki login and password. Make sure to use the same account that was used to set up your Vector. - -You will see "SUCCESS!" when this script successfully completes. - -.. note:: By running the ``anki_vector.configure`` executable submodule, you will be asked to provide your Anki account credentials, 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). - - 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. - -.. warning:: These credentials give full access to your robot, including camera stream, audio stream and data. Do not share these credentials. - -^^^^^^^^^^^^^^^ -Troubleshooting -^^^^^^^^^^^^^^^ - -Please see the :doc:`Troubleshooting ` page for tips, or visit the `Anki Developer Forums `_ to ask questions, find solutions, or for general discussion. - ----- - -`Terms and Conditions `_ and `Privacy Policy `_ - -`Click here to return to the Anki Developer website. `_ diff --git a/docs/source/install-windows.rst b/docs/source/install-windows.rst deleted file mode 100644 index fd750ae..0000000 --- a/docs/source/install-windows.rst +++ /dev/null @@ -1,70 +0,0 @@ -.. _install-windows: - -###################### -Installation - Windows -###################### - -This guide provides instructions on installing the Vector SDK for computers running with a Windows operating system. - -^^^^^^^^^^^^^ -Prerequisites -^^^^^^^^^^^^^ - -* Vector is powered on. -* You have successfully created an Anki account. -* Vector has been set up with the Vector companion app. -* The Vector companion app is *not* currently connected to Vector. -* Vector is connected to the same network as your computer. -* You can see Vector's eyes on his screen. - - -^^^^^^^^^^^^^^^^^^^ -Python Installation -^^^^^^^^^^^^^^^^^^^ - -Download the `Python 3.6.1 (or later) executable file from Python.org `_ and -run it on your computer. - -.. important:: Be sure to tick the "Add Python 3.6 to PATH" checkbox on the Setup screen. Then tap "Install Now" and complete the Python installation. - -^^^^^^^^^^^^^^^^ -SDK Installation -^^^^^^^^^^^^^^^^ - -To install the SDK, navigate into the SDK folder and type the following into a Command Prompt window:: - - py -3 -m pip install --user anki_vector - -.. 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`` - -.. 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`` - -^^^^^^^^^^^^^^^^^^^^^ -Vector Authentication -^^^^^^^^^^^^^^^^^^^^^ - -To authenticate with the robot, type the following into the Terminal window:: - - py -m anki_vector.configure - -You will be prompted for your robot's name, ip address and serial number. You will also be asked for your Anki login and password. Make sure to use the same account that was used to set up your Vector. - -You will see "SUCCESS!" when this script successfully completes. - -.. note:: By running the ``anki_vector.configure`` executable submodule, you will be asked to provide your Anki account credentials, 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). - - 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. - -.. warning:: These credentials give full access to your robot, including camera stream, audio stream and data. Do not share these credentials. - -^^^^^^^^^^^^^^^ -Troubleshooting -^^^^^^^^^^^^^^^ - -Please see the :doc:`Troubleshooting ` page for tips, or visit the `Anki Developer Forums `_ to ask questions, find solutions, or for general discussion. - ----- - -`Terms and Conditions `_ and `Privacy Policy `_ - -`Click here to return to the Anki Developer website. `_ diff --git a/docs/source/troubleshooting.rst b/docs/source/troubleshooting.rst deleted file mode 100644 index 863af48..0000000 --- a/docs/source/troubleshooting.rst +++ /dev/null @@ -1,94 +0,0 @@ -.. _troubleshooting: - -############### -Troubleshooting -############### - - -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Failure to Install Python Package -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -If you run into trouble installing Python packages, please upgrade your pip install as follows: - - On macOS and Linux:: - - pip3 install -U pip - - On Windows:: - - python -m pip install --upgrade pip - - Alternatively on Windows, try:: - - py -3 -m pip install --upgrade pip - - You may also need to update Python setuptools (for instance, for error ``AttributeError: '_NamespacePath' object has no attribute 'sort'``):: - - pip install --upgrade setuptools - - After applying these updates, retry your Python package installation. - - -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Tutorial program does not run -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -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. - -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. - - -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Failure to run anki_vector.configure -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The prerequisites to run the ``anki_vector.configure`` executable submodule successfully are: - -* You have successfully created an Anki account. -* Vector has been set up with the Vector companion app. -* The Vector companion app is *not* currently connected to Vector. -* Vector is connected to the same network as your computer. -* The ``anki_vector`` Python package must be installed. -* You can see Vector's eyes on his screen. - - -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Vector behaves unexpectedly -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -You may need to reboot your robot when you are finished running programs with the pre-alpha Vector SDK. - - -^^^^^^^^^^^^^^^^^^^^^ -Can't find robot name -^^^^^^^^^^^^^^^^^^^^^ - -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. - - -^^^^^^^^^^^^^^^^^^^^^^^^ -Can't find serial number -^^^^^^^^^^^^^^^^^^^^^^^^ - -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. - - -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Can't find Vector's IP address -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -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. - - -^^^^^^^^^^^^^^^^^^^^^ -Anki Developer Forums -^^^^^^^^^^^^^^^^^^^^^ - -Please visit the `Anki Developer Forums `_ to ask questions, find solutions and for general discussion. - ----- - -`Terms and Conditions `_ and `Privacy Policy `_ - -`Click here to return to the Anki Developer website. `_ diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index 195e77a..0000000 --- a/examples/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Example programs for the anki_vector Python SDK - -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. - -See the [apps](apps) directory for some fun fully-featured programs like a remote control. diff --git a/examples/apps/3d_viewer/3d_viewer.py b/examples/apps/3d_viewer/3d_viewer.py deleted file mode 100755 index 125158b..0000000 --- a/examples/apps/3d_viewer/3d_viewer.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""3d Viewer example, with remote control. - -This is an example of how you can use the 3D viewer with a program, and the -3D Viewer and controls will work automatically. -""" - -import time - -import anki_vector - - -def main(): - args = anki_vector.util.parse_command_args() - with anki_vector.Robot(args.serial, - show_viewer=True, - enable_camera_feed=True, - show_3d_viewer=True, - enable_face_detection=True, - enable_custom_object_detection=True, - enable_nav_map_feed=True): - print("Starting 3D Viewer. Use Ctrl+C to quit.") - try: - while True: - time.sleep(0.5) - except KeyboardInterrupt: - pass - - -if __name__ == "__main__": - main() diff --git a/examples/apps/interactive_shell/interactive_shell.py b/examples/apps/interactive_shell/interactive_shell.py deleted file mode 100755 index a9d3cbb..0000000 --- a/examples/apps/interactive_shell/interactive_shell.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Command Line Interface for Vector - -This is an example of integrating Vector with an ipython-based command line interface. -""" - -import sys - -try: - from IPython.terminal.embed import InteractiveShellEmbed -except ImportError: - sys.exit('Cannot import from ipython: Do `pip3 install ipython` to install') - -import anki_vector - -usage = """Use the [tab] key to auto-complete commands, and see all available methods and properties. - -For example, type 'robot.' then press the [tab] key and you'll see all the robot functions. -Keep pressing tab to cycle through all of the available options. - -All IPython commands work as usual. -Here's some useful syntax: - robot? -> Details about 'robot'. - robot?? -> More detailed information including code for 'robot'. -These commands will work on all objects inside of the shell. - -You can even call the functions that send messages to Vector, and he'll respond just like he would in a script. -Try it out! Type: - robot.anim.play_animation('anim_pounce_success_02') -""" - -args = anki_vector.util.parse_command_args() - -ipyshell = InteractiveShellEmbed(banner1='\nWelcome to the Vector Interactive Shell!', - exit_msg='Goodbye\n') - -if __name__ == "__main__": - with anki_vector.Robot(args.serial, - enable_camera_feed=True, - show_viewer=True) as robot: - # Invoke the ipython shell while connected to Vector - ipyshell(usage) diff --git a/examples/apps/proximity_mapper/lib/proximity_mapper_state.py b/examples/apps/proximity_mapper/lib/proximity_mapper_state.py deleted file mode 100755 index 5bcd1c1..0000000 --- a/examples/apps/proximity_mapper/lib/proximity_mapper_state.py +++ /dev/null @@ -1,354 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Contains the state of an environment being explored by the robot. -This is a support class for the proximity_mapper example. - -Includes a utility for rendering the state in OpenGL. -""" - -# __all__ should order by constants, event classes, other classes, functions. -__all__ = ['ClearedTerritory', 'MapState', 'Wall', 'WallSegment'] - -from math import cos, sin, pi -import multiprocessing as mp -from typing import List - -from anki_vector.opengl import opengl -from anki_vector.util import Vector3 - -try: - from OpenGL.GL import (GL_AMBIENT, GL_BLEND, GL_DIFFUSE, GL_FILL, GL_FRONT, GL_FRONT_AND_BACK, GL_LIGHTING, - GL_LINES, GL_ONE_MINUS_SRC_ALPHA, GL_POINTS, GL_QUADS, GL_SHININESS, GL_SPECULAR, GL_SRC_ALPHA, - glBegin, glBlendFunc, glColor, glDisable, glEnable, glEnd, glMaterialfv, glNormal3f, - glPointSize, glPolygonMode, glVertex3f) - -except ImportError as import_exc: - opengl.raise_opengl_or_pillow_import_error(import_exc) - - -# Constants - -#: Visually represent not just walls, but open/loose nodes, territories and navigation -#: points in the 3D Viewer. -RENDER_METADATA_OBJECTS = True - -#: Display color of potential exploration targets in the 3D Viewer. -NODE_OPEN_RENDER_COLOR = [0.0, 1.0, 1.0, 0.75] -#: Display size (in pixels) of potential exploration targets in the 3D Viewer. -NODE_OPEN_RENDER_SIZE = 5.0 - -#: Display color of detected proximity collisions in the 3D Viewer. -#: These nodes will be collected into walls, and will only live long term if isolated -#: too far from any other contact points -NODE_CONTACT_RENDER_COLOR = [1.0, 0.0, 0.0, 0.75] -#: Display size (in pixels) of detected proximity collisions in the 3D Viewer. -NODE_CONTACT_RENDER_SIZE = 2.0 - -#: Display color of the rendered disc for the position the robot will next navigate to. -NAV_POINT_RENDER_COLOR = [0.0, 1.0, 0.0, 1.0] -#: Sections of the rendered disc for the position the robot will next navigate to. -NAV_POINT_RENDER_SECTIONS = 16 -#: Display size of the rendered disc for the position the robot will next navigate to. -NAV_POINT_RENDER_SIZE = 25.0 - -#: Display color of the rendered disc for the territories the robot has already explored. -TERRITORY_RENDER_COLOR = [0.15, 0.6, 1.0, 1.0] -#: Sections of the rendered disc for the territories the robot has already explored. -TERRITORY_RENDER_SECTIONS = 32 - -#: Display color for the walls the robot has identified in the environment. -WALL_RENDER_COLOR = [1.0, 0.4, 0.1, 1.0] -#: Render height of the walls the robot has identified in the environment. -#: This values is purely cosmetic. As the proximity sensor is at a static height and -#: always faces forward, the robot has no way of detecting through this method how tall the -#: obstacles are, so the 100mm height was tuned to be similar to Vector in the viewer -#: rather than reflecting the objects in the environment. -WALL_RENDER_HEIGHT_MM = 100.0 - - -class WallSegment: - """Two points defining a segment of wall in the world - - :param a: The first end of the wall segment expected to be in the xy plane - :param b: The second end of the wall segment expected to be in the xy plane - """ - - def __init__(self, a: Vector3, b: Vector3): - self._a = a - self._b = b - - # precalculate the normal for use in the render call - aToB = b - a - facing_vector = aToB.cross(Vector3(0, 0, 1)) - self._normal = facing_vector.normalized - - @property - def a(self) -> Vector3: - """:return: The first end of the wall segment.""" - return self._a - - @property - def b(self) -> Vector3: - """:return: The second end of the wall segment.""" - return self._b - - @property - def normal(self) -> Vector3: - """:return: The precalculated normal of the wall segment.""" - return self._normal - - -class Wall: - """A chain of WallSegments making up a continuous wall in 3d space - - :param segment: The initial wall segment for this wall - """ - - def __init__(self, segment: WallSegment): - self._vertices = [segment.a, segment.b] - - def insert_head(self, vertex: Vector3): - """Adds a new vertex to the front of the wall - - :param vertex: The coordinates of the vertex being added to the front of the wall. - This point is expected to be near the current head, and in the same xy plane. - """ - self._vertices.insert(0, vertex) - - def insert_tail(self, vertex: Vector3): - """Adds a new vertex to the end of the wall - - :param vertex: The coordinates of the vertex being added to the end of the wall. - This point is expected to be near the current tail, and in the same xy plane. - """ - self._vertices.append(vertex) - - @property - def vertices(self) -> List[Vector3]: - """:return: All the vertices defining the ground vertices of the wall.""" - return self._vertices - - @property - def segments(self) -> List[WallSegment]: - """:return: Constructs and returns the WallSegments which make up this wall.""" - result: List[WallSegment] = [] - for i in range(len(self._vertices) - 1): - result.append(WallSegment(self._vertices[i], self._vertices[i + 1])) - return result - - -class ClearedTerritory: - """A zone of space that the robot has already explored. These are used to - prevent the robot from populating new open nodes in finished areas. - - Cleared Territories always exist in the x-y plane. - - :param center: Centerpoint of the zone - :param radius: The size of the zone - """ - - def __init__(self, center: Vector3, radius: Vector3): - self._center = center - self._radius = radius - - @property - def center(self) -> Vector3: - """:return: The centerpoint of the territory.""" - return self._center - - @property - def radius(self) -> float: - """:return: The radius of the territory.""" - return self._radius - - -class MapState: - """A collection of walls, nodes, and territories defining the area the robot - is exploring. - """ - - def __init__(self): - self._open_nodes: List[Vector3] = [] - self._contact_nodes: List[Vector3] = [] - self._walls: List[Wall] = [] - self._cleared_territories: List[ClearedTerritory] = [] - self._collection_active: bool = False - - @staticmethod - def _set_color(color: List[float]): - """Modifies the OpenGL state's active material with a specific color - used on the specular & diffuse channels, with limited ambient. - - This function must be invoked inside the OpenGL render loop. - - :param color: the color to use for the material - """ - glColor(color) - glMaterialfv(GL_FRONT, GL_AMBIENT, [color[0] * 0.1, color[1] * 0.1, color[2] * 0.1, 1.0]) - glMaterialfv(GL_FRONT, GL_DIFFUSE, color) - glMaterialfv(GL_FRONT, GL_SPECULAR, color) - - glMaterialfv(GL_FRONT, GL_SHININESS, 10.0) - - @classmethod - def _render_points(cls, point_list: List[Vector3], size: float, color: List[float]): - """Draws a collection of points in the OpenGL 3D worldspace. - - This function must be invoked inside the OpenGL render loop. - - :param point_list: the points to render in the view context - :param size: the size in pixels of each point - :param color: the color to render the points - """ - glPointSize(size) - cls._set_color(color) - glBegin(GL_POINTS) - for point in point_list: - glVertex3f(point.x, point.y, point.z) - glEnd() - - @classmethod - def _render_circle(cls, center: Vector3, radius: float, sections: int, color: List[float]): - """Draws a circle out of dashed lines around a center point in the x-y plane. - - This function must be invoked inside the OpenGL render loop. - - :param center: the center point of the rendered circle - :param radius: the size of the rendered circle - :param sections: the number of vertices used in the dashed line circle - :param color: the color to render the points - """ - cls._set_color(color) - glBegin(GL_LINES) - for i in range(sections): - theta = pi * 2.0 * float(i) / float(sections - 1) - glVertex3f(center.x + cos(theta) * radius, - center.y + sin(theta) * radius, - center.z) - glEnd() - - @classmethod - def _render_wall(cls, wall: Wall, height: float, color: List[float]): - """Draws walls out of quads in the 3D Viewer. The walls are drawn a - constant height above their ground-plane points, as a convention. - - This function must be invoked inside the OpenGL render loop. - - :param wall_list: the walls to draw - :param radius: the size of the rendered circle - :param sections: the number of vertices used in the dashed line circle - :param color: the color to render the points - """ - cls._set_color(color) - - glBegin(GL_QUADS) - for wall_segment in wall.segments: - glNormal3f(wall_segment.normal.x, wall_segment.normal.y, wall_segment.normal.z) - glVertex3f(wall_segment.a.x, wall_segment.a.y, wall_segment.a.z) - glVertex3f(wall_segment.b.x, wall_segment.b.y, wall_segment.b.z) - glVertex3f(wall_segment.b.x, wall_segment.b.y, wall_segment.b.z + height) - glVertex3f(wall_segment.a.x, wall_segment.a.y, wall_segment.a.z + height) - glEnd() - - @property - def open_nodes(self) -> List[Vector3]: - """:return: Points on the map which have no proximity detections between - themselves and the proximity scan origin point that found them. - - These are safe points for the robot to drive to. - """ - return self._open_nodes - - @open_nodes.setter - def open_nodes(self, open_nodes: List[Vector3]): - self._open_nodes = open_nodes - - @property - def contact_nodes(self) -> List[Vector3]: - """:return: Points where an obstacle has been detected, but are too far - from other contacts to construct a wall from. - """ - return self._contact_nodes - - @property - def walls(self) -> List[Wall]: - """:return: Chains of points denoting barriers detected by the proximity - sensor. - """ - return self._walls - - @property - def cleared_territories(self) -> List[ClearedTerritory]: - """:return: Regions of space the robot has finished scanning. Any points - inside one of these regions can be considered accurate in terms of - detected boundaries. - """ - return self._cleared_territories - - @property - def collection_active(self) -> bool: - """:return: Whether or not proximity data should currently be collected.""" - return self._collection_active - - @collection_active.setter - def collection_active(self, collection_active: bool): - self._collection_active = collection_active - - def render(self, user_data_queue: mp.Queue = None): - """Low level OpenGL calls to render the current state in an opengl_viewer. This - code will be executed inside the viewer's process. - - Can be added to a viewer with the following code, telling the viewer to call this - whenever it redraws its geometry. - - .. code-block:: python - - robot.viewer_3d.add_render_call(my_map_state.render) - - :param user_data_queue: The queue to read MapState messages from the main process. - :type user_data_queue: mulitprocessing.Queue - """ - try: - latest: MapState = user_data_queue.get(False) - - self._open_nodes = latest._open_nodes # pylint: disable=protected-access - self._contact_nodes = latest._contact_nodes # pylint: disable=protected-access - self._walls = latest._walls # pylint: disable=protected-access - self._cleared_territories = latest._cleared_territories # pylint: disable=protected-access - self._collection_active = latest._collection_active # pylint: disable=protected-access - except mp.queues.Empty: - pass - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_BLEND) - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) - glDisable(GL_LIGHTING) - - if RENDER_METADATA_OBJECTS: - self._render_points(self._contact_nodes, NODE_CONTACT_RENDER_SIZE, NODE_CONTACT_RENDER_COLOR) - self._render_points(self._open_nodes, NODE_OPEN_RENDER_SIZE, NODE_OPEN_RENDER_COLOR) - - # render the nav point open sample - if self._cleared_territories and self._open_nodes: - self._render_circle(self._open_nodes[0], NAV_POINT_RENDER_SIZE, NAV_POINT_RENDER_SECTIONS, NAV_POINT_RENDER_COLOR) - - for cleared_territory in self._cleared_territories: - self._render_circle(cleared_territory.center, cleared_territory.radius, TERRITORY_RENDER_SECTIONS, TERRITORY_RENDER_COLOR) - - glEnable(GL_LIGHTING) - for wall in self._walls: - self._render_wall(wall, WALL_RENDER_HEIGHT_MM, WALL_RENDER_COLOR) diff --git a/examples/apps/proximity_mapper/proximity_mapper.py b/examples/apps/proximity_mapper/proximity_mapper.py deleted file mode 100755 index f67b0f0..0000000 --- a/examples/apps/proximity_mapper/proximity_mapper.py +++ /dev/null @@ -1,314 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Maps a region around Vector using the proximity sensor. - -Vector will turn in place and use his sensor to detect walls in his -local environment. These walls are displayed in the 3D Viewer. The -visualizer does not effect the robot's internal state or behavior. - -Vector expects this environment to be static - if objects are moved -he will have no knowledge of them. -""" - -import asyncio -import concurrent -from math import cos, sin, inf, acos -import os -import sys - -sys.path.append(os.path.join(os.path.dirname(__file__), 'lib')) -from proximity_mapper_state import ClearedTerritory, MapState, Wall, WallSegment # pylint: disable=wrong-import-position - -import anki_vector # pylint: disable=wrong-import-position -from anki_vector.util import parse_command_args, radians, degrees, distance_mm, speed_mmps, Vector3 # pylint: disable=wrong-import-position - -# Constants - -#: The maximum distance (in millimeters) the scan considers valid for a proximity respons. -#: Wall detection past this threshold will be disregarded, and an 'open' node will -#: be created at this distance instead. Increasing this value may degrade the -#: reliability of this program, see note below: -#: -#: NOTE: The proximity sensor works by sending a light pulse, and seeing how long that pulse takes -#: to reflect and return to the sensor. The proximity sensor does not specifically have a maximum -#: range, but will get unreliable results below a certain return signal strength. This return signal -#: is impacted by environmental conditions (such as the orientation and material of the detected obstacle) -#: as well as the distance. Additionally, increasing this radius will reduce the resolution of contact -#: points, necessitating changes to PROXIMITY_SCAN_SAMPLE_FREQUENCY_HZ and PROXIMITY_SCAN_BIND_THRESHOLD_MM -#: to maintain effective wall prediction. -PROXIMITY_SCAN_DISTANCE_THRESHOLD_MM = 300 - -#: The distance (in millimeters) to place an open node if no proximity results are detected along -#: a given line of sight. This should be smaller than the distance threshold, since these nodes -#: indicate safe points for the robot to drive to, and the robot's size should be taken into account -#: when estimating a maximum safe driving distance -PROXIMITY_SCAN_OPEN_NODE_DISTANCE_MM = 230 - -#: How frequently (in hertz) the robot checks proximity data while doing a scan. -PROXIMITY_SCAN_SAMPLE_FREQUENCY_HZ = 15.0 - -#: How long (in seconds) the robot spends doing it's 360 degree scan. -PROXIMITY_SCAN_TURN_DURATION_S = 10.0 - -#: How close (in millimeters) together two detected contact points need to be for the robot to -#: consider them part of a continuous wall. -PROXIMITY_SCAN_BIND_THRESHOLD_MM = 30.0 - -#: A delay (in seconds) the program waits after the scan finishes before shutting down. -#: This allows the user time to explore the mapped 3d environment in the viewer and can be -#: Tuned to any desired length. A value of 0.0 will prevent the viewer from closing. -PROXIMITY_EXPLORATION_SHUTDOWN_DELAY_S = 8.0 - - -# @TODO enable when testing shows it is ready to go -#: ACTIVELY_EXPLORE_SPACE can be activated to allow the robot to move -#: into an open space after scanning, and continue the process until all open -#: spaces are explored. -ACTIVELY_EXPLORE_SPACE = True -#: The speed (in millimeters/second) the robot drives while exploring. -EXPLORE_DRIVE_SPEED_MMPS = 40.0 -#: The speed (in degrees/second) the robot turns while exploring. -EXPLORE_TURN_SPEED_DPS = 90.0 - - -#: Takes a position in 3d space where a collection was detected, and adds it to the map state -#: by either creating a wall, adding to wall or storing a loose contact point. -async def add_proximity_contact_to_state(node_position: Vector3, state: MapState): - - # Comparison function for sorting points by distance. - def compare_distance(elem): - return (elem - node_position).magnitude_squared - - # Comparison function for sorting walls by distance using their head as a reference point. - def compare_head_distance(elem): - return (elem.vertices[0] - node_position).magnitude_squared - - # Comparison function for sorting walls by distance using their tail as a reference point. - def compare_tail_distance(elem): - return (elem.vertices[-1] - node_position).magnitude_squared - - # Sort all the loose contact nodes not yet incorporated into walls by - # their distance to our reading position. If the nearest one is within - # our binding threshold - store it as a viable wall creation partner. - # (infinity is used as a standin for 'nothing') - closest_contact_distance = inf - if state.contact_nodes: - state.contact_nodes.sort(key=compare_distance) - closest_contact_distance = (state.contact_nodes[0] - node_position).magnitude - if closest_contact_distance > PROXIMITY_SCAN_BIND_THRESHOLD_MM: - closest_contact_distance = inf - - # Sort all the walls both by head and tail distance from our sample - # if either of the results are within our binding threshold, store them - # as potential wall extension candidates for our sample. - # (infinity is used as a standin for 'nothing') - closest_head_distance = inf - closest_tail_distance = inf - if state.walls: - state.walls.sort(key=compare_tail_distance) - closest_tail_distance = (state.walls[0].vertices[-1] - node_position).magnitude - if closest_tail_distance > PROXIMITY_SCAN_BIND_THRESHOLD_MM: - closest_tail_distance = inf - - state.walls.sort(key=compare_head_distance) - closest_head_distance = (state.walls[0].vertices[0] - node_position).magnitude - if closest_head_distance > PROXIMITY_SCAN_BIND_THRESHOLD_MM: - closest_head_distance = inf - - # Create a new wall if a loose contact node is in bind range and - # is closer than any existing wall. The contact node will be removed. - if closest_contact_distance <= PROXIMITY_SCAN_BIND_THRESHOLD_MM and closest_contact_distance < closest_head_distance and closest_contact_distance < closest_tail_distance: - state.walls.append(Wall(WallSegment(state.contact_nodes[0], node_position))) - state.contact_nodes.pop(0) - - # Extend a wall if it's head is within bind range and is closer than - # any loose contacts or wall tails. - elif closest_head_distance <= PROXIMITY_SCAN_BIND_THRESHOLD_MM and closest_head_distance < closest_contact_distance and closest_head_distance < closest_tail_distance: - state.walls[0].insert_head(node_position) - - # Extend a wall if it's tail is within bind range and is closer than - # any loose contacts or wall heads. - elif closest_tail_distance <= PROXIMITY_SCAN_BIND_THRESHOLD_MM and closest_tail_distance < closest_contact_distance and closest_tail_distance < closest_head_distance: - state.walls.sort(key=compare_tail_distance) - state.walls[0].insert_tail(node_position) - - # If nothing was found to bind with, store the sample as a loose contact node. - else: - state.contact_nodes.append(node_position) - - -#: Takes a position in 3d space and adds it to the map state as an open node -async def add_proximity_non_contact_to_state(node_position: Vector3, state: MapState): - # Check to see if the uncontacted sample is inside of any area considered already explored. - is_open_unexplored = True - for ct in state.cleared_territories: - if (node_position - ct.center).magnitude < ct.radius: - is_open_unexplored = False - - # If the uncontacted sample is in unfamiliar ground, store it as an open node. - if is_open_unexplored: - state.open_nodes.append(node_position) - - -#: Modifies the map state with the details of a proximity reading -async def analyze_proximity_sample(reading: anki_vector.proximity.ProximitySensorData, robot: anki_vector.robot.Robot, state: MapState): - # Check if the reading meets the engine's metrics for valid, and that its within our specified distance threshold. - reading_contacted = reading.is_valid and reading.distance.distance_mm < PROXIMITY_SCAN_DISTANCE_THRESHOLD_MM - - if reading_contacted: - # The distance will either be the reading data, or our threshold distance if the reading is considered uncontacted. - reading_distance = reading.distance.distance_mm if reading_contacted else PROXIMITY_SCAN_DISTANCE_THRESHOLD_MM - - # Convert the distance to a 3d position in worldspace. - reading_position = Vector3( - robot.pose.position.x + cos(robot.pose_angle_rad) * reading_distance, - robot.pose.position.y + sin(robot.pose_angle_rad) * reading_distance, - robot.pose.position.z) - - await add_proximity_contact_to_state(reading_position, state) - else: - # Convert the distance to a 3d position in worldspace. - safe_driving_position = Vector3( - robot.pose.position.x + cos(robot.pose_angle_rad) * PROXIMITY_SCAN_OPEN_NODE_DISTANCE_MM, - robot.pose.position.y + sin(robot.pose_angle_rad) * PROXIMITY_SCAN_OPEN_NODE_DISTANCE_MM, - robot.pose.position.z) - - await add_proximity_non_contact_to_state(safe_driving_position, state) - - -#: repeatedly collects proximity data sample and converts them to nodes and walls for the map state -async def collect_proximity_data_loop(robot: anki_vector.robot.Robot, future: concurrent.futures.Future, state: MapState): - try: - scan_interval = 1.0 / PROXIMITY_SCAN_SAMPLE_FREQUENCY_HZ - - # Runs until the collection_active flag is cleared. - # This flag is cleared external to this function. - while state.collection_active: - # Collect proximity data from the sensor. - reading = robot.proximity.last_sensor_reading - if reading is not None: - await analyze_proximity_sample(reading, robot, state) - robot.viewer_3d.user_data_queue.put(state) - await asyncio.sleep(scan_interval) - - # Exceptions raised in this process are ignored, unless we set them on the future, and then run future.result() at a later time - except Exception as e: # pylint: disable=broad-except - future.set_exception(e) - finally: - future.set_result(state) - - -#: Updates the map state by rotating 360 degrees and collecting/applying proximity data samples. -async def scan_area(robot: anki_vector.robot.Robot, state: MapState): - collect_future = concurrent.futures.Future() - - # The collect_proximity_data task relies on this external trigger to know when its finished. - state.collection_active = True - - # Activate the collection task while the robot turns in place. - collect_task = robot.conn.loop.create_task(collect_proximity_data_loop(robot, collect_future, state)) - - # Turn around in place, then send the signal to kill the collection task. - robot.behavior.turn_in_place(angle=degrees(360.0), speed=degrees(360.0 / PROXIMITY_SCAN_TURN_DURATION_S)) - state.collection_active = False - - # Wait for the collection task to finish. - robot.conn.run_coroutine(collect_task) - # While the result of the task is not used, this call will propagate any exceptions that - # occured in the task, allowing for debug visibility. - collect_future.result() - - -#: Top level call to perform exploration and environment mapping -async def map_explorer(robot: anki_vector.robot.Robot): - # Drop the lift, so that it does not block the proximity sensor - robot.behavior.set_lift_height(0.0) - - # Create the map state, and add it's rendering function to the viewer's render pipeline - state = MapState() - robot.viewer_3d.add_render_call(state.render) - - # Comparison function used for sorting which open nodes are the furthest from all existing - # walls and loose contacts. - # (Using 1/r^2 to respond strongly to small numbers of close contact and weaking to many distant contacts) - def open_point_sort_func(position: Vector3): - proximity_sum = 0 - for p in state.contact_nodes: - proximity_sum = proximity_sum + 1 / (p - position).magnitude_squared - for c in state.walls: - for p in c.vertices: - proximity_sum = proximity_sum + 1 / (p - position).magnitude_squared - return proximity_sum - - # Loop until running out of open samples to navigate to, - # or if the process has yet to start (indicated by a lack of cleared_territories). - while (state.open_nodes and ACTIVELY_EXPLORE_SPACE) or not state.cleared_territories: - if robot.pose: - # Delete any open samples range of the robot. - state.open_nodes = [position for position in state.open_nodes if (position - robot.pose.position).magnitude > PROXIMITY_SCAN_DISTANCE_THRESHOLD_MM] - - # Collect map data for the robot's current location. - await scan_area(robot, state) - - # Add where the robot is to the map's cleared territories. - state.cleared_territories.append(ClearedTerritory(robot.pose.position, PROXIMITY_SCAN_DISTANCE_THRESHOLD_MM)) - - # @TODO: This whole block should ideally be replaced with the go_to_pose actions when that is ready to go. - # Alternatively, the turn&drive commands can be modified to respond to collisions by cancelling. After - # either change, ACTIVELY_EXPLORE_SPACE should be defaulted True - if ACTIVELY_EXPLORE_SPACE and state.open_nodes: - # Sort the open nodes and find our next navigation point. - state.open_nodes.sort(key=open_point_sort_func) - nav_point = state.open_nodes[0] - - # Calculate the distance and direction of this next navigation point. - nav_point_delta = Vector3( - nav_point.x - robot.pose.position.x, - nav_point.y - robot.pose.position.y, - 0) - nav_distance = nav_point_delta.magnitude - nav_direction = nav_point_delta.normalized - - # Convert the nav_direction into a turn angle relative to the robot's current facing. - robot_forward = Vector3(*robot.pose.rotation.to_matrix().forward_xyz).normalized - turn_angle = acos(nav_direction.dot(robot_forward)) - if nav_direction.cross(robot_forward).z > 0: - turn_angle = -turn_angle - - # Turn toward the nav point, and drive to it. - robot.behavior.turn_in_place(angle=radians(turn_angle), speed=degrees(EXPLORE_TURN_SPEED_DPS)) - robot.behavior.drive_straight(distance=distance_mm(nav_distance), speed=speed_mmps(EXPLORE_DRIVE_SPEED_MMPS)) - - if PROXIMITY_EXPLORATION_SHUTDOWN_DELAY_S == 0.0: - while True: - await asyncio.sleep(1.0) - else: - print('finished exploring - waiting an additional {0} seconds, then shutting down'.format(PROXIMITY_EXPLORATION_SHUTDOWN_DELAY_S)) - await asyncio.sleep(PROXIMITY_EXPLORATION_SHUTDOWN_DELAY_S) - - -if __name__ == '__main__': - # Connect to the robot - args = parse_command_args() - with anki_vector.Robot(args.serial, - enable_camera_feed=True, - show_viewer=True, - enable_nav_map_feed=False, - show_3d_viewer=True) as robotInstance: - robotInstance.behavior.drive_off_charger() - loop = asyncio.get_event_loop() - loop.run_until_complete(map_explorer(robotInstance)) diff --git a/examples/apps/remote_control/lib/__init__.py b/examples/apps/remote_control/lib/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/examples/face_images/cozmo_image.jpg b/examples/face_images/cozmo_image.jpg deleted file mode 100644 index 690c84b..0000000 Binary files a/examples/face_images/cozmo_image.jpg and /dev/null differ diff --git a/examples/tutorials/01_hello_world.py b/examples/tutorials/01_hello_world.py deleted file mode 100755 index d7d57ce..0000000 --- a/examples/tutorials/01_hello_world.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Hello World - -Make Vector say 'Hello World' in this simple Vector SDK example program. -""" - -import anki_vector - - -def main(): - args = anki_vector.util.parse_command_args() - with anki_vector.Robot(args.serial) as robot: - print("Say 'Hello World'...") - robot.say_text("Hello World") - - -if __name__ == "__main__": - main() diff --git a/examples/tutorials/02_drive_square.py b/examples/tutorials/02_drive_square.py deleted file mode 100755 index c1622dd..0000000 --- a/examples/tutorials/02_drive_square.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Make Vector drive in a square. - -Make Vector drive in a square by going forward and turning left 4 times in a row. -""" - -import anki_vector -from anki_vector.util import degrees, distance_mm, speed_mmps - - -def main(): - args = anki_vector.util.parse_command_args() - - # The robot drives straight, stops and then turns around - with anki_vector.Robot(args.serial) as robot: - robot.behavior.drive_off_charger() - - # Use a "for loop" to repeat the indented code 4 times - # Note: the _ variable name can be used when you don't need the value - for _ in range(4): - print("Drive Vector straight...") - robot.behavior.drive_straight(distance_mm(200), speed_mmps(50)) - - print("Turn Vector in place...") - robot.behavior.turn_in_place(degrees(90)) - - -if __name__ == "__main__": - main() diff --git a/examples/tutorials/03_motors.py b/examples/tutorials/03_motors.py deleted file mode 100755 index 0a1414a..0000000 --- a/examples/tutorials/03_motors.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Drive Vector's wheels, lift and head motors directly - -This is an example of how you can also have low-level control of Vector's motors -(wheels, lift and head) for fine-grained control and ease of controlling -multiple things at once. -""" - -import time -import anki_vector - - -def main(): - args = anki_vector.util.parse_command_args() - with anki_vector.Robot(args.serial) as robot: - robot.behavior.drive_off_charger() - - # Tell the head motor to start lowering the head (at 5 radians per second) - print("Lower Vector's head...") - robot.motors.set_head_motor(-5.0) - - # Tell the lift motor to start lowering the lift (at 5 radians per second) - print("Lower Vector's lift...") - robot.motors.set_lift_motor(-5.0) - - # Tell Vector to drive the left wheel at 25 mmps (millimeters per second), - # and the right wheel at 50 mmps (so Vector will drive Forwards while also - # turning to the left - print("Set Vector's wheel motors...") - robot.motors.set_wheel_motors(25, 50) - - # wait for 3 seconds (the head, lift and wheels will move while we wait) - time.sleep(3) - - # Tell the head motor to start raising the head (at 5 radians per second) - print("Raise Vector's head...") - robot.motors.set_head_motor(5) - - # Tell the lift motor to start raising the lift (at 5 radians per second) - print("Raise Vector's lift...") - robot.motors.set_lift_motor(5) - - # Tell Vector to drive the left wheel at 50 mmps (millimeters per second), - # and the right wheel at -50 mmps (so Vector will turn in-place to the right) - print("Set Vector's wheel motors...") - robot.motors.set_wheel_motors(50, -50) - - # Wait for 3 seconds (the head, lift and wheels will move while we wait) - time.sleep(3) - - # Stop the motors, which unlocks the tracks - robot.motors.set_wheel_motors(0, 0) - robot.motors.set_lift_motor(0) - robot.motors.set_head_motor(0) - - -if __name__ == "__main__": - main() diff --git a/examples/tutorials/04_animation.py b/examples/tutorials/04_animation.py deleted file mode 100755 index 614b231..0000000 --- a/examples/tutorials/04_animation.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Play an animation on Vector -""" - -import anki_vector - - -def main(): - args = anki_vector.util.parse_command_args() - with anki_vector.Robot(args.serial) as robot: - robot.behavior.drive_off_charger() - - # Play an animation via its name. - # - # Warning: Future versions of the app might change these, so for future-proofing - # we recommend using play_animation_trigger when it becomes available. - # - # See the remote_control.py example in apps for an easy way to see - # the available animations. - animation = 'anim_pounce_success_02' - print("Playing animation by name: " + animation) - robot.anim.play_animation(animation) - - -if __name__ == "__main__": - main() diff --git a/examples/tutorials/05_play_behaviors.py b/examples/tutorials/05_play_behaviors.py deleted file mode 100755 index 536379d..0000000 --- a/examples/tutorials/05_play_behaviors.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Tell Vector to drive on and off the charger. -""" - -import anki_vector - - -def main(): - args = anki_vector.util.parse_command_args() - - with anki_vector.Robot(args.serial) as robot: - print("Drive Vector onto charger...") - robot.behavior.drive_on_charger() - - print("Drive Vector off of charger...") - robot.behavior.drive_off_charger() - - -if __name__ == '__main__': - main() diff --git a/examples/tutorials/06_face_image.py b/examples/tutorials/06_face_image.py deleted file mode 100755 index 6106a9c..0000000 --- a/examples/tutorials/06_face_image.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Display an image on Vector's face -""" - -import os -import sys -import time - -try: - from PIL import Image -except ImportError: - sys.exit("Cannot import from PIL: Do `pip3 install --user Pillow` to install") - -import anki_vector -from anki_vector.util import degrees - - -def main(): - args = anki_vector.util.parse_command_args() - - with anki_vector.Robot(args.serial) as robot: - # If necessary, move Vector's Head and Lift to make it easy to see his face - robot.behavior.set_head_angle(degrees(45.0)) - robot.behavior.set_lift_height(0.0) - - current_directory = os.path.dirname(os.path.realpath(__file__)) - image_path = os.path.join(current_directory, "..", "face_images", "cozmo_image.jpg") - - # Load an image - image_file = Image.open(image_path) - - # Convert the image to the format used by the Screen - print("Display image on Vector's face...") - screen_data = anki_vector.screen.convert_image_to_screen_data(image_file) - robot.screen.set_screen_with_image_data(screen_data, 4.0) - time.sleep(5) - - -if __name__ == "__main__": - main() diff --git a/examples/tutorials/07_dock_with_cube.py b/examples/tutorials/07_dock_with_cube.py deleted file mode 100755 index c7f1c4c..0000000 --- a/examples/tutorials/07_dock_with_cube.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Tell Vector to drive up to a seen cube. - -This example demonstrates Vector driving to and docking with a cube, without -picking it up. Vector will line his arm hooks up with the cube so that they are -inserted into the cube's corners. - -You must place a cube in front of Vector so that he can see it. -""" - -import anki_vector -from anki_vector.util import degrees - - -def main(): - args = anki_vector.util.parse_command_args() - - docking_result = None - with anki_vector.Robot(args.serial) as robot: - robot.behavior.drive_off_charger() - - # If necessary, move Vector's Head and Lift down - robot.behavior.set_head_angle(degrees(-5.0)) - robot.behavior.set_lift_height(0.0) - - print("Connecting to a cube...") - robot.world.connect_cube() - - if robot.world.connected_light_cube: - print("Begin cube docking...") - dock_response = robot.behavior.dock_with_cube( - robot.world.connected_light_cube, - num_retries=3) - if dock_response: - docking_result = dock_response.result - - robot.world.disconnect_cube() - - if docking_result: - if docking_result.code != anki_vector.messaging.protocol.ActionResult.ACTION_RESULT_SUCCESS: - print("Cube docking failed with code {0} ({1})".format(str(docking_result).rstrip('\n\r'), docking_result.code)) - else: - print("Cube docking failed.") - - -if __name__ == "__main__": - main() diff --git a/examples/tutorials/08_drive_to_cliff_and_back_up.py b/examples/tutorials/08_drive_to_cliff_and_back_up.py deleted file mode 100755 index 9991ac6..0000000 --- a/examples/tutorials/08_drive_to_cliff_and_back_up.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Make Vector drive to a cliff and back up. - -Place the robot about a foot from a "cliff" (such as a tabletop edge), -then run this script. - -This tutorial is an advanced example that shows the SDK's integration -with the Vector behavior system. - -The Vector behavior system uses an order of prioritizations to determine -what the robot will do next. The highest priorities in the behavior -system including the following: -* When Vector reaches a cliff, he will back up to avoid falling. -* When Vector is low on battery, he will start searching for his charger -and self-dock. - -When the SDK is running at a lower priority level than high priorities -like cliff and low battery, an SDK program can lose its ability to -control the robot when a cliff if reached or when battery is low. - -This example shows how, after reaching a cliff, the SDK program can -re-request control so it can continue controlling the robot after -reaching the cliff. -""" - -import anki_vector -from anki_vector.util import distance_mm, speed_mmps - - -def main(): - args = anki_vector.util.parse_command_args() - - with anki_vector.Robot(args.serial) as robot: - print("Vector SDK has behavior control...") - robot.behavior.drive_off_charger() - - print("Drive Vector straight until he reaches cliff...") - # Once robot reaches cliff, he will play his typical cliff reactions. - robot.behavior.drive_straight(distance_mm(5000), speed_mmps(100)) - - robot.conn.run_coroutine(robot.conn.control_lost_event.wait()).result() - - print("Lost SDK behavior control. Request SDK behavior control again...") - robot.conn.request_control() - - print("Drive Vector backward away from the cliff...") - robot.behavior.drive_straight(distance_mm(-300), speed_mmps(100)) - - -if __name__ == "__main__": - main() diff --git a/examples/tutorials/09_show_photo.py b/examples/tutorials/09_show_photo.py deleted file mode 100755 index 11e2907..0000000 --- a/examples/tutorials/09_show_photo.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Show a photo taken by Vector. - -Grabs the pictures off of Vector and open them via PIL. - -Before running this script, please make sure you have successfully -had Vector take a photo by saying, "Hey Vector! Take a photo." -""" - -import io -import sys - -try: - from PIL import Image -except ImportError: - sys.exit("Cannot import from PIL: Do `pip3 install --user Pillow` to install") - -import anki_vector - - -def main(): - args = anki_vector.util.parse_command_args() - with anki_vector.Robot(args.serial) as robot: - if len(robot.photos.photo_info) == 0: - print('\n\nNo photos found on Vector. Ask him to take a photo first by saying, "Hey Vector! Take a photo."\n\n') - return - for photo in robot.photos.photo_info: - print(f"Opening photo {photo.photo_id}") - val = robot.photos.get_photo(photo.photo_id) - image = Image.open(io.BytesIO(val.image)) - image.show() - - -if __name__ == "__main__": - main() diff --git a/examples/tutorials/10_eye_color.py b/examples/tutorials/10_eye_color.py deleted file mode 100755 index 988ce80..0000000 --- a/examples/tutorials/10_eye_color.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Set Vector's eye color. -""" - -import time -import anki_vector - - -def main(): - args = anki_vector.util.parse_command_args() - - with anki_vector.Robot(args.serial) as robot: - print("Set Vector's eye color to purple...") - robot.behavior.set_eye_color(hue=0.83, saturation=0.76) - - print("Sleep 5 seconds...") - time.sleep(5) - - -if __name__ == '__main__': - main() diff --git a/examples/tutorials/11_face_event_subscription.py b/examples/tutorials/11_face_event_subscription.py deleted file mode 100755 index 0391303..0000000 --- a/examples/tutorials/11_face_event_subscription.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Wait for Vector to see a face, and then print output to the console. - -This script demonstrates how to set up a listener for an event. It -subscribes to event 'robot_observed_face'. When that event is dispatched, -method 'on_robot_observed_face' is called, which prints text to the console. -Vector will also say "I see a face" one time, and the program will exit when -he finishes speaking. -""" - -import functools -import threading - -import anki_vector -from anki_vector.events import Events -from anki_vector.util import degrees - -said_text = False - - -def main(): - evt = threading.Event() - - def on_robot_observed_face(robot, event_type, event): - print("Vector sees a face") - global said_text - if not said_text: - said_text = True - robot.say_text("I see a face!") - evt.set() - - args = anki_vector.util.parse_command_args() - with anki_vector.Robot(args.serial, enable_face_detection=True) as robot: - - # If necessary, move Vector's Head and Lift to make it easy to see his face - robot.behavior.set_head_angle(degrees(45.0)) - robot.behavior.set_lift_height(0.0) - - on_robot_observed_face = functools.partial(on_robot_observed_face, robot) - robot.events.subscribe(on_robot_observed_face, Events.robot_observed_face) - - print("------ waiting for face events, press ctrl+c to exit early ------") - - try: - if not evt.wait(timeout=5): - print("------ Vector never saw your face! ------") - except KeyboardInterrupt: - pass - - robot.events.unsubscribe(on_robot_observed_face, Events.robot_observed_face) - - -if __name__ == '__main__': - main() diff --git a/examples/tutorials/12_wake_word_subscription.py b/examples/tutorials/12_wake_word_subscription.py deleted file mode 100755 index 7ef8ca3..0000000 --- a/examples/tutorials/12_wake_word_subscription.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Wait for Vector to hear "Hey Vector!" and then play an animation. - -The wake_word event only is dispatched when the SDK program has -not requested behavior control. After the robot hears "Hey Vector!" -and the event is received, you can then request behavior control -and control the robot. See the 'requires_behavior_control' method in -connection.py for more information. -""" - -import functools -import threading - -import anki_vector -from anki_vector.events import Events - -wake_word_heard = False - - -def main(): - evt = threading.Event() - - def on_wake_word(robot, event_type, event): - robot.conn.request_control() - - global wake_word_heard - if not wake_word_heard: - wake_word_heard = True - robot.say_text("Hello") - evt.set() - - args = anki_vector.util.parse_command_args() - with anki_vector.Robot(args.serial, requires_behavior_control=False, cache_animation_list=False) as robot: - on_wake_word = functools.partial(on_wake_word, robot) - robot.events.subscribe(on_wake_word, Events.wake_word) - - print('------ Vector is waiting to hear "Hey Vector!" Press ctrl+c to exit early ------') - - try: - if not evt.wait(timeout=10): - print('------ Vector never heard "Hey Vector!" ------') - except KeyboardInterrupt: - pass - - -if __name__ == '__main__': - main() diff --git a/examples/tutorials/13_custom_objects.py b/examples/tutorials/13_custom_objects.py deleted file mode 100755 index a7398a8..0000000 --- a/examples/tutorials/13_custom_objects.py +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""This example demonstrates how you can define custom objects. - -The example defines several custom objects (2 cubes, a wall and a box). When -Vector sees the markers for those objects he will report that he observed an -object of that size and shape there. - -You can adjust the markers, marker sizes, and object sizes to fit whatever -object you have and the exact size of the markers that you print out. -""" - -import time - -import anki_vector -from anki_vector.objects import CustomObjectMarkers, CustomObjectTypes - - -def handle_object_appeared(event_type, event): - # This will be called whenever an EvtObjectAppeared is dispatched - - # whenever an Object comes into view. - print(f"--------- Vector started seeing an object --------- \n{event.obj}") - - -def handle_object_disappeared(event_type, event): - # This will be called whenever an EvtObjectDisappeared is dispatched - - # whenever an Object goes out of view. - print(f"--------- Vector stopped seeing an object --------- \n{event.obj}") - - -def main(): - args = anki_vector.util.parse_command_args() - with anki_vector.Robot(args.serial, - default_logging=False, - show_viewer=True, - show_3d_viewer=True, - enable_camera_feed=True, - enable_custom_object_detection=True, - enable_nav_map_feed=True) as robot: - # Add event handlers for whenever Vector sees a new object - robot.events.subscribe(handle_object_appeared, anki_vector.events.Events.object_appeared) - robot.events.subscribe(handle_object_disappeared, anki_vector.events.Events.object_disappeared) - - # define a unique cube (44mm x 44mm x 44mm) (approximately the same size as Vector's light cube) - # with a 50mm x 50mm Circles2 image on every face. Note that marker_width_mm and marker_height_mm - # parameter values must match the dimensions of the printed marker. - cube_obj = robot.world.define_custom_cube(custom_object_type=CustomObjectTypes.CustomType00, - marker=CustomObjectMarkers.Circles2, - size_mm=44.0, - marker_width_mm=50.0, - marker_height_mm=50.0, - is_unique=True) - - # define a unique cube (88mm x 88mm x 88mm) (approximately 2x the size of Vector's light cube) - # with a 50mm x 50mm Circles3 image on every face. - big_cube_obj = robot.world.define_custom_cube(custom_object_type=CustomObjectTypes.CustomType01, - marker=CustomObjectMarkers.Circles3, - size_mm=88.0, - marker_width_mm=50.0, - marker_height_mm=50.0, - is_unique=True) - - # define a unique wall (150mm x 120mm (x10mm thick for all walls) - # with a 50mm x 30mm Triangles2 image on front and back - wall_obj = robot.world.define_custom_wall(custom_object_type=CustomObjectTypes.CustomType02, - marker=CustomObjectMarkers.Triangles2, - width_mm=150, - height_mm=120, - marker_width_mm=50, - marker_height_mm=30, - is_unique=True) - - # define a unique box (20mm deep x 20mm width x20mm tall) - # with a different 50mm x 50mm image on each of the 6 faces - box_obj = robot.world.define_custom_box(custom_object_type=CustomObjectTypes.CustomType03, - marker_front=CustomObjectMarkers.Diamonds2, # front - marker_back=CustomObjectMarkers.Hexagons2, # back - marker_top=CustomObjectMarkers.Hexagons3, # top - marker_bottom=CustomObjectMarkers.Hexagons4, # bottom - marker_left=CustomObjectMarkers.Triangles3, # left - marker_right=CustomObjectMarkers.Triangles4, # right - depth_mm=20.0, - width_mm=20.0, - height_mm=20.0, - marker_width_mm=50.0, - marker_height_mm=50.0, - is_unique=True) - - if ((cube_obj is not None) and (big_cube_obj is not None) and - (wall_obj is not None) and (box_obj is not None)): - print("All objects defined successfully!") - else: - print("One or more object definitions failed!") - return - - print("\n\nShow a marker specified in the Python script to Vector and you will see the related 3d objects\n" - "display in Vector's 3d_viewer window. You will also see messages print every time a custom object\n" - "enters or exits Vector's view. Markers can be found from the docs under CustomObjectMarkers.\n\n") - - try: - while True: - time.sleep(0.5) - except KeyboardInterrupt: - pass - - -if __name__ == "__main__": - main() diff --git a/requirements.txt b/requirements.txt index b015a67..41df567 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,3 @@ -aiogrpc>=1.4 -cryptography -flask -googleapis-common-protos -numpy>=1.11 -opencv-python>=3.4 -Pillow>=3.3 -requests \ No newline at end of file +anki-vector==0.5.1 +Flask==1.0.2 +Pillow==5.4.1 \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..9af7e6f --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[aliases] +test=pytest \ No newline at end of file diff --git a/setup.py b/setup.py index bc8de24..91558c6 100644 --- a/setup.py +++ b/setup.py @@ -1,86 +1,28 @@ -# Copyright (c) 2018 Anki, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License in the file LICENSE.txt or at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +from setuptools import setup, find_packages +from os import path -""" -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. +here = path.abspath(path.dirname(__file__)) -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 - -Vector SDK documentation: https://developer.anki.com/vector/docs/ - -Official developer forum: https://forums.anki.com/ - -Requirements: - * Python 3.6.1 or later -""" - -import os.path -import sys -from setuptools import setup - -if sys.version_info < (3, 6, 1): - sys.exit('The Vector SDK requires Python 3.6.1 or later') - -HERE = os.path.abspath(os.path.dirname(__file__)) - -def fetch_version(): - """Get the version from the package""" - with open(os.path.join(HERE, 'anki_vector', 'version.py')) as version_file: - versions = {} - exec(version_file.read(), versions) - return versions - -VERSION_DATA = fetch_version() -VERSION = VERSION_DATA['__version__'] - -def get_requirements(): - """Load the requirements from requirements.txt into a list""" - reqs = [] - with open(os.path.join(HERE, 'requirements.txt')) as requirements_file: - for line in requirements_file: - reqs.append(line.strip()) - return reqs +# Get the long description from the README file +with open(path.join(here, 'README.md'), encoding='utf-8') as f: + long_description = f.read() setup( - name='anki_vector', - version=VERSION, - description="The Vector SDK is a connected vision- and character-based robotics platform for everyone.", - long_description=__doc__, - url='https://developer.anki.com', - author='Anki, Inc', - author_email='developer@anki.com', - license='Apache License, Version 2.0', - # See https://pypi.python.org/pypi?%3Aaction=list_classifiers - classifiers=[ - 'Development Status :: 3 - Alpha', - 'Intended Audience :: Developers', - 'Topic :: Software Development :: Libraries', - 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: Python :: 3.6', - ], - zip_safe=True, - keywords='anki vector robot robotics sdk ai vision'.split(), - packages=['anki_vector', 'anki_vector.configure', 'anki_vector.messaging', 'anki_vector.opengl'], - package_data={ - 'anki_vector': ['LICENSE.txt', 'opengl/assets/*.obj', 'opengl/assets/*.mtl', 'opengl/assets/*.jpg', - 'opengl/assets/LICENSE.txt'] + name='vector-controller', + version='0.5.1', + description='A webpage-based controller for Anki Vector', + long_description=long_description, + long_description_content_type='text/markdown', + url='https://github.com/krconv/vector-controller', + author='Kodey Converse', + author_email='kodey@krconv.com', + packages=find_packages(exclude=['tests']), + entry_points={ + 'console_scripts': [ + 'vector_controller=vector_controller.__main__:main', + ], }, - install_requires=get_requirements(), - extras_require={ - '3dviewer': ['PyOpenGL>=3.1'], - 'docs': ['sphinx', 'sphinx_rtd_theme', 'sphinx_autodoc_typehints'], - 'experimental': ['keras', 'scikit-learn', 'scipy', 'tensorflow'], - 'test': ['pytest', 'requests', 'requests_toolbelt'], - } -) + install_requires=['anki_vector', 'flask', 'Pillow'], + setup_requires=['pytest-runner'], + tests_require=['pytest', 'pytest-mock'], +) \ No newline at end of file diff --git a/tests/vector_controller/controller_test.py b/tests/vector_controller/controller_test.py new file mode 100644 index 0000000..ff09951 --- /dev/null +++ b/tests/vector_controller/controller_test.py @@ -0,0 +1,52 @@ +import vector_controller + +import pytest + +class TestFreePlayMode: + @pytest.fixture + def vector_mock(self, mocker): + vector = mocker.Mock() + vector.anim.anim_list = [] + return vector + + def test_exits_freeplay_mode(self, vector_mock): + remote = vector_controller.RemoteControlVector(vector_mock) + + remote.set_freeplay(enabled=False) + + vector_mock.conn.request_control.assert_called_once() + + def test_enters_freeplay_mode(self, vector_mock): + remote = vector_controller.RemoteControlVector(vector_mock) + + remote.set_freeplay(enabled=True) + + vector_mock.conn.release_control.assert_called_once() + +class TestKeys: + @pytest.fixture + def vector_mock(self, mocker): + vector = mocker.Mock() + vector.anim.anim_list = [] + return vector + + def test_starts_wheel_motors(self, vector_mock): + remote = vector_controller.RemoteControlVector(vector_mock) + + remote.handle_key(ord('W'), False, False, True) + vector_mock.motors.set_wheel_motors.assert_called_once_with(75, 75, 300, 300) + + def test_stops_wheel_motors(self, vector_mock): + remote = vector_controller.RemoteControlVector(vector_mock) + + remote.handle_key(ord('W'), False, False, False) + vector_mock.motors.set_wheel_motors.assert_called_once_with(0, 0, 0, 0) + + def test_multiple_keys_set_wheel_motors(self, vector_mock): + remote = vector_controller.RemoteControlVector(vector_mock) + + remote.handle_key(ord('W'), False, False, True) + remote.handle_key(ord('S'), False, False, True) + remote.handle_key(ord('S'), False, False, False) + remote.handle_key(ord('D'), False, False, True) + vector_mock.motors.set_wheel_motors.assert_called_with(125, 25, 500, 100) \ No newline at end of file diff --git a/vector_controller/__init__.py b/vector_controller/__init__.py new file mode 100644 index 0000000..e1fa6a7 --- /dev/null +++ b/vector_controller/__init__.py @@ -0,0 +1 @@ +from .controller import RemoteControlVector \ No newline at end of file diff --git a/vector_controller/__main__.py b/vector_controller/__main__.py new file mode 100644 index 0000000..11eb712 --- /dev/null +++ b/vector_controller/__main__.py @@ -0,0 +1,14 @@ +from . import controller + +import anki_vector + +import sys + + +def main(): + try: + controller.run() + except KeyboardInterrupt as e: + pass + except anki_vector.exceptions.VectorConnectionException as e: + sys.exit("A connection error occurred: %s" % e) \ No newline at end of file diff --git a/examples/apps/remote_control/remote_control.py b/vector_controller/controller.py similarity index 98% rename from examples/apps/remote_control/remote_control.py rename to vector_controller/controller.py index 99e5529..f5cc80a 100755 --- a/examples/apps/remote_control/remote_control.py +++ b/vector_controller/controller.py @@ -23,7 +23,7 @@ import json import sys import time -from lib import flask_helpers +from .lib import flask_helpers import anki_vector from anki_vector import util @@ -305,6 +305,11 @@ def update_mouse_driving(self): self.vector.motors.set_wheel_motors(l_wheel_speed, r_wheel_speed, l_wheel_speed * 4, r_wheel_speed * 4) + def set_freeplay(self, enabled): + connection = self.vector.conn + + connection.release_control() if enabled else connection.request_control() + def get_anim_sel_drop_down(selectorIndex): html_text = """