diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..1280b84 --- /dev/null +++ b/.flake8 @@ -0,0 +1,14 @@ +[flake8] +max-line-length = 160 +exclude = + **/pulse_utils/pulse_lib.py + kuri_slack_bot/app.py +max-complexity = 20 +# We import modules here to make the API cleaner +per-file-ignores = + **/kuri_api/lights.py:W293 + **/kuri_api/__init__.py:F401 + **/kuri_navigation/__init__.py:F401 + **/anim/__init__.py:F401 + **/utils/__init__.py:F401 + **/kuri_api/base.py:N801 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 028dd7c..7b85b11 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -4,12 +4,32 @@ on: [push, pull_request] jobs: industrial_ci: + env: + AFTER_INSTALL_TARGET_DEPENDENCIES: 'pip2 install --upgrade pip && pip2 install --upgrade "setuptools<0.45"' + CATKIN_LINT: true + ROS_REPO: main strategy: matrix: env: - - {ROS_DISTRO: indigo, ROS_REPO: main} + - {ROS_DISTRO: indigo} + - {ROS_DISTRO: noetic} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: 'ros-industrial/industrial_ci@master' - env: ${{matrix.env}} \ No newline at end of file + - uses: actions/checkout@v2 + - uses: 'ros-industrial/industrial_ci@master' + env: ${{matrix.env}} + continue-on-error: ${{ matrix.env.ROS_DISTRO == 'noetic' }} + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: 2.7 + - name: Install dependencies + run: | + pip install flake8 pep8-naming + - name: Lint + run: | + flake8 -v diff --git a/audio_msgs/CMakeLists.txt b/audio_msgs/CMakeLists.txt index 85aabd8..8378119 100644 --- a/audio_msgs/CMakeLists.txt +++ b/audio_msgs/CMakeLists.txt @@ -44,6 +44,9 @@ generate_messages( catkin_package( CATKIN_DEPENDS + geometry_msgs + mayfield_msgs + message_runtime std_msgs ) diff --git a/gizmo_description/CMakeLists.txt b/gizmo_description/CMakeLists.txt index 7ba3444..a7c962c 100644 --- a/gizmo_description/CMakeLists.txt +++ b/gizmo_description/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 2.8.3) project(gizmo_description) -find_package(catkin) +find_package(catkin REQUIRED COMPONENTS) catkin_package() diff --git a/kuri_api/CMakeLists.txt b/kuri_api/CMakeLists.txt index 9b104eb..86792d0 100644 --- a/kuri_api/CMakeLists.txt +++ b/kuri_api/CMakeLists.txt @@ -22,14 +22,9 @@ generate_messages( ) catkin_package( -# INCLUDE_DIRS include -# LIBRARIES robot_api - CATKIN_DEPENDS roscpp rospy + CATKIN_DEPENDS message_runtime roscpp rospy std_msgs ) +catkin_install_python(PROGRAMS scripts/base_demo scripts/volume_interface + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) - -include_directories( - include - ${catkin_INCLUDE_DIRS} -) diff --git a/kuri_api/package.xml b/kuri_api/package.xml index 531ecb5..5f748ec 100644 --- a/kuri_api/package.xml +++ b/kuri_api/package.xml @@ -3,14 +3,18 @@ kuri_api 0.1.0 High-level API for controlling the Kuri robot. - Nick Walker + Nick Walker None catkin - actionlib - control_msgs + + actionlib roscpp rospy - trajectory_msgs + trajectory_msgs + + message_generation + message_runtime + std_msgs diff --git a/kuri_api/setup.py b/kuri_api/setup.py index 5f77785..01533d2 100644 --- a/kuri_api/setup.py +++ b/kuri_api/setup.py @@ -1,11 +1,11 @@ -## ! DO NOT MANUALLY INVOKE THIS setup.py, USE CATKIN INSTEAD +# DO NOT MANUALLY INVOKE THIS setup.py, USE CATKIN INSTEAD from distutils.core import setup from catkin_pkg.python_setup import generate_distutils_setup # fetch values from package.xml setup_args = generate_distutils_setup( - packages=['kuri_api','assets'], + packages=['kuri_api', 'assets'], package_dir={'': 'src'}) setup(**setup_args) diff --git a/kuri_api/src/assets/__init__.py b/kuri_api/src/assets/__init__.py index e24d11d..1a65365 100644 --- a/kuri_api/src/assets/__init__.py +++ b/kuri_api/src/assets/__init__.py @@ -1,8 +1,9 @@ from .memoize import memoize from .mov import img_to_pix, mov_to_wav, mov_to_pixels, pixel_positions + __all__ = [ - 'memoize', - 'img_to_pix', - 'mov_to_wav', - 'mov_to_pixels', - 'pixel_positions'] + 'memoize', + 'img_to_pix', + 'mov_to_wav', + 'mov_to_pixels', + 'pixel_positions'] diff --git a/kuri_api/src/assets/config.py b/kuri_api/src/assets/config.py index 4ea0bff..ac04038 100644 --- a/kuri_api/src/assets/config.py +++ b/kuri_api/src/assets/config.py @@ -1,5 +1,6 @@ import os + def get_data_path(): """ Return the data path for either the GBZ or a development workspace. diff --git a/kuri_api/src/assets/memoize.py b/kuri_api/src/assets/memoize.py index a17c5ce..ecb6708 100644 --- a/kuri_api/src/assets/memoize.py +++ b/kuri_api/src/assets/memoize.py @@ -1,4 +1,8 @@ -import functools, hashlib, os, cPickle as pickle +import cPickle +import functools +import hashlib +import os + def _sha1(s): return hashlib.sha1(s).hexdigest() @@ -14,7 +18,7 @@ def _store(cache_dir, key, val): if not os.path.isdir(objd): os.makedirs(objd) with open(os.path.join(objd, hash[2:]), 'w') as (f): - pickle.dump(val, f) + cPickle.dump(val, f) def _load(cache_dir, key): @@ -24,12 +28,12 @@ def _load(cache_dir, key): hash = _keyhash(key) objd = os.path.join(cache_dir, hash[:2]) with open(os.path.join(objd, hash[2:])) as (f): - return pickle.load(f) + return cPickle.load(f) def memoize(root_dir): """ A better memoize: - - pickle objects instead of yaml + - cPickle objects instead of yaml - one file per object instead of a big dict - objects are lazily loaded from disk when first used """ @@ -41,7 +45,7 @@ def memoize_helper(f): @functools.wraps(f) def cached(*args, **kwargs): - key = ('{}{}{}').format(f.func_name, pickle.dumps(args), pickle.dumps(kwargs)) + key = '{}{}{}'.format(f.func_name, cPickle.dumps(args), cPickle.dumps(kwargs)) if key not in cache: try: cache[key] = _load(cache_dir, key) diff --git a/kuri_api/src/assets/mov.py b/kuri_api/src/assets/mov.py index bf0e764..460c9b2 100644 --- a/kuri_api/src/assets/mov.py +++ b/kuri_api/src/assets/mov.py @@ -1,11 +1,17 @@ -import glob, os, subprocess +import glob +import os +import subprocess from PIL import Image + import numpy as np + from . import config from . import memoize + MOVIE_WIDTH_HEIGHT = 720 -@memoize(lambda : config.get_assets_path()) + +@memoize(lambda: config.get_assets_path()) def mov_to_pixels(mov_name): """ These pixels are generated at build-time and cached through memoization. @@ -14,7 +20,7 @@ def mov_to_pixels(mov_name): return _pixels_for_file(mov_path) -@memoize(lambda : config.get_assets_path()) +@memoize(lambda: config.get_assets_path()) def mov_to_wav(mov_name): """ These wavs are generated at build-time and cached through memoization. @@ -32,10 +38,10 @@ def _pixels_for_file(mov_path): _, fname = os.path.split(mov_path) mov_name = os.path.splitext(fname)[0] subprocess.call([ - 'avconv', '-y', '-i', mov_path, ('/tmp/{}%06d.png').format(mov_name)]) + 'avconv', '-y', '-i', mov_path, ('/tmp/{}%06d.png').format(mov_name)]) imgs_list = glob.glob(('/tmp/{}*.png').format(mov_name)) imgs_list.sort() - pixels = [ img_to_pix(img_name) for img_name in imgs_list ] + pixels = [img_to_pix(img_name) for img_name in imgs_list] for img_name in imgs_list: subprocess.call(['rm', img_name]) @@ -53,8 +59,8 @@ def _wav_for_file(mov_path): wav_name = os.path.splitext(mov_name)[0] + '.wav' wav_loc = os.path.join(config.get_sounds_path(), wav_name) ret = subprocess.call([ - 'avconv', '-y', '-i', mov_path, '-vn', '-ar', '48000', '-ac', '2', - '-ab', '192', '-f', 'wav', wav_loc]) + 'avconv', '-y', '-i', mov_path, '-vn', '-ar', '48000', '-ac', '2', + '-ab', '192', '-f', 'wav', wav_loc]) if ret: raise RuntimeError(('Unable to convert {} to wav at {}.').format(mov_path, wav_loc)) return wav_name @@ -67,7 +73,7 @@ def _add_pixel_ring(width, height, count, radius, angle): for i in range(count): a = float(angle) + float(i) * 2 * np.pi / float(count) pixels.append((int(x - float(radius) * np.cos(a) + 0.5), - int(y - float(radius) * np.sin(a) + 0.5))) + int(y - float(radius) * np.sin(a) + 0.5))) return pixels @@ -84,4 +90,4 @@ def pixel_positions(): def img_to_pix(fname): pixels = pixel_positions() img = Image.open(fname) - return [ img.getpixel(p) for p in pixels ] + return [img.getpixel(p) for p in pixels] diff --git a/kuri_api/src/kuri_api/__init__.py b/kuri_api/src/kuri_api/__init__.py index d157b83..0cc4308 100644 --- a/kuri_api/src/kuri_api/__init__.py +++ b/kuri_api/src/kuri_api/__init__.py @@ -6,4 +6,4 @@ from .listener import Listener from .power import PowerMonitor from .voice import Voice -from .volume import Volume \ No newline at end of file +from .volume import Volume diff --git a/kuri_api/src/kuri_api/alive.py b/kuri_api/src/kuri_api/alive.py index 12c29c3..9242d4b 100644 --- a/kuri_api/src/kuri_api/alive.py +++ b/kuri_api/src/kuri_api/alive.py @@ -1,9 +1,11 @@ import random -from threading import Lock, RLock import time -from kuri_api.utils.timeouts import EventTimeout +from threading import Lock, RLock + from kuri_api.anim import AnimationPlayer from kuri_api.anim.library.blink_animations import BlinkAnimations +from kuri_api.utils.timeouts import EventTimeout + class Alive(object): """ @@ -127,4 +129,4 @@ def _kill_timer(self, blocking=False): if self._blink_timer: self._blink_timer.shutdown(blocking=blocking) self._blink_timer = None - return \ No newline at end of file + return diff --git a/kuri_api/src/kuri_api/anim/__init__.py b/kuri_api/src/kuri_api/anim/__init__.py index 85c9fa2..d3a89db 100644 --- a/kuri_api/src/kuri_api/anim/__init__.py +++ b/kuri_api/src/kuri_api/anim/__init__.py @@ -1,3 +1,3 @@ -from .track import Track, TrackPlayer from .animation_group import AnimationGroup -from .player import AnimationPlayer, LoopingAnimationPlayer \ No newline at end of file +from .player import AnimationPlayer, LoopingAnimationPlayer +from .track import Track, TrackPlayer diff --git a/kuri_api/src/kuri_api/anim/animation_group.py b/kuri_api/src/kuri_api/anim/animation_group.py index 4c80d90..cf8edc4 100644 --- a/kuri_api/src/kuri_api/anim/animation_group.py +++ b/kuri_api/src/kuri_api/anim/animation_group.py @@ -1,8 +1,9 @@ from kuri_api.anim.primitives.head import HeadMotions -from kuri_api.anim.primitives.wheels import WheelMotions from kuri_api.anim.primitives.light import Light -from kuri_api.anim.primitives.sound import Sound from kuri_api.anim.primitives.movies import Movies +from kuri_api.anim.primitives.sound import Sound +from kuri_api.anim.primitives.wheels import WheelMotions + class AnimationGroup(object): """ @@ -24,4 +25,4 @@ def __init__(self, head=None, wheels=None, chest_leds=None, sound_srcs=None, mov self.movies = Movies(lights=self.lights_mot, sound=self.sound_mot) else: self.movies = None - return \ No newline at end of file + return diff --git a/kuri_api/src/kuri_api/anim/animator.py b/kuri_api/src/kuri_api/anim/animator.py index 08916b2..ab16355 100644 --- a/kuri_api/src/kuri_api/anim/animator.py +++ b/kuri_api/src/kuri_api/anim/animator.py @@ -1,15 +1,19 @@ +import logging import threading + from gizmo.utils.animation import AnimationParser from gizmo.utils.animation import AnimationTrackAssembler from kuri_api.anim import Track -import logging + logger = logging.getLogger(__name__) + class Animator(object): def __init__(self, comm_interface, head=None, wheels=None, sound_srcs=None, chest_leds=None): self._lock = threading.RLock() - self.animation_assembler = AnimationTrackAssembler(head=head, wheels=wheels, sound_srcs=sound_srcs, chest_leds=chest_leds) + self.animation_assembler = AnimationTrackAssembler(head=head, wheels=wheels, sound_srcs=sound_srcs, + chest_leds=chest_leds) self.currentTrackPlayer = None return @@ -37,8 +41,8 @@ def cancel(self, timeout=1.0): return def play_live_animation(self, command): - animationCommand = command - animation = AnimationParser.parse_animation(animationCommand.json) + animation_command = command + animation = AnimationParser.parse_animation(animation_command.json) if animation is not None and not animation.hasParseErrors: track = Track() self.animation_assembler.add_animation_to_track(animation, track) @@ -52,4 +56,4 @@ def play_animation_from_container_json(self, container_json, done_cb=None): self._play_track(track, done_cb) def shutdown(self): - self.cancel() \ No newline at end of file + self.cancel() diff --git a/kuri_api/src/kuri_api/anim/helpers.py b/kuri_api/src/kuri_api/anim/helpers.py index 484cb22..df025c6 100644 --- a/kuri_api/src/kuri_api/anim/helpers.py +++ b/kuri_api/src/kuri_api/anim/helpers.py @@ -1,8 +1,10 @@ +import logging + from kuri_api.anim.library.blink_animations import BlinkAnimations from kuri_api.anim.library.common_animations import CommonAnimations from kuri_api.anim.library.docking_animations import DockingAnimations -from kuri_api.anim.library.docking_animations import DockingSupportAnimations from kuri_api.anim.library.docking_animations import DockingLEDAnimations +from kuri_api.anim.library.docking_animations import DockingSupportAnimations from kuri_api.anim.library.idle_animations import IdleAnimations from kuri_api.anim.library.led_emotion_animations import LEDEmotionAnimations from kuri_api.anim.library.observer_animations import ObserverModeAnimations @@ -14,25 +16,26 @@ from kuri_api.anim.library.social_animations import SocialAnimations from kuri_api.anim.library.system_animations import SystemAnimations from kuri_api.anim.library.test_animations import TestAnimations -import logging + logger = logging.getLogger(__name__) PRODUCTION_ANIMATIONS = [ - BlinkAnimations, - CommonAnimations, - DockingSupportAnimations, - IdleAnimations, - LEDEmotionAnimations, - ObserverModeAnimations, - OnboardingAnimations, - ReactionAnimations, - RelocalizeAnimations, - RomojiAnimations, - SleepAndWakeAnimations, - SocialAnimations, - SystemAnimations, - DockingAnimations, - DockingLEDAnimations, - TestAnimations] + BlinkAnimations, + CommonAnimations, + DockingSupportAnimations, + IdleAnimations, + LEDEmotionAnimations, + ObserverModeAnimations, + OnboardingAnimations, + ReactionAnimations, + RelocalizeAnimations, + RomojiAnimations, + SleepAndWakeAnimations, + SocialAnimations, + SystemAnimations, + DockingAnimations, + DockingLEDAnimations, + TestAnimations] + def generate_all_animations(head_mux=None, wheel_mux=None, light_mux=None, sound_mux=None): """ diff --git a/kuri_api/src/kuri_api/anim/library/blink_animations.py b/kuri_api/src/kuri_api/anim/library/blink_animations.py index aa5b96f..49e55b7 100644 --- a/kuri_api/src/kuri_api/anim/library/blink_animations.py +++ b/kuri_api/src/kuri_api/anim/library/blink_animations.py @@ -1,7 +1,9 @@ from random import normalvariate + from kuri_api.anim import AnimationGroup from kuri_api.anim import Track + class BlinkAnimations(AnimationGroup): """ Blink animations. diff --git a/kuri_api/src/kuri_api/anim/library/common_animations.py b/kuri_api/src/kuri_api/anim/library/common_animations.py index c4645c3..a2ed63f 100644 --- a/kuri_api/src/kuri_api/anim/library/common_animations.py +++ b/kuri_api/src/kuri_api/anim/library/common_animations.py @@ -1,12 +1,15 @@ +import logging from math import radians, pi from random import choice, random -from numpy import clip + from kuri_api.anim import AnimationGroup from kuri_api.anim import Track from kuri_api.head import Head -import logging +from numpy import clip + logger = logging.getLogger(__name__) + class CommonAnimations(AnimationGroup): def no(self): @@ -21,19 +24,25 @@ def no(self): init_tilt = self.head.cur_tilt init_direction = choice([-1, 1]) do_extra_shake = False - PAN_CUTOFF = 0.5 - if init_pan > PAN_CUTOFF: + pan_cutoff = 0.5 + if init_pan > pan_cutoff: init_direction = -1 do_extra_shake = True else: - if init_pan < PAN_CUTOFF * -1: + if init_pan < pan_cutoff * -1: init_direction = 1 do_extra_shake = True - tk.add(0.0, self.head_mot.pantilt(clip(init_pan + init_direction * 0.15, Head.PAN_RIGHT, Head.PAN_LEFT), init_tilt, 0.2)) - tk.add(0.3, self.head_mot.pantilt(clip(init_pan + init_direction * -0.3, Head.PAN_RIGHT, Head.PAN_LEFT), init_tilt, 0.3)) + tk.add(0.0, + self.head_mot.pantilt(clip(init_pan + init_direction * 0.15, Head.PAN_RIGHT, Head.PAN_LEFT), init_tilt, + 0.2)) + tk.add(0.3, + self.head_mot.pantilt(clip(init_pan + init_direction * -0.3, Head.PAN_RIGHT, Head.PAN_LEFT), init_tilt, + 0.3)) if do_extra_shake: - tk.add(0.6, self.head_mot.pantilt(clip(init_pan + init_direction * 0.3, Head.PAN_RIGHT, Head.PAN_LEFT), init_tilt, 0.3)) - tk.add(0.9, self.head_mot.pantilt(clip(init_pan + init_direction * -0.3, Head.PAN_RIGHT, Head.PAN_LEFT), init_tilt, 0.3)) + tk.add(0.6, self.head_mot.pantilt(clip(init_pan + init_direction * 0.3, Head.PAN_RIGHT, Head.PAN_LEFT), + init_tilt, 0.3)) + tk.add(0.9, self.head_mot.pantilt(clip(init_pan + init_direction * -0.3, Head.PAN_RIGHT, Head.PAN_LEFT), + init_tilt, 0.3)) tk.add(1.3, self.head_mot.pantilt(init_pan, init_tilt, 0.3)) else: tk.add(0.7, self.head_mot.pantilt(init_pan, init_tilt, 0.3)) @@ -96,8 +105,8 @@ def attention_look_around_3(self): return tk def search_user_capture(self, starting_pose=( - Head.PAN_NEUTRAL, - Head.TILT_UP * 0.8, 0)): + Head.PAN_NEUTRAL, + Head.TILT_UP * 0.8, 0)): """ Search for a user by looking up and around. :param: starting pose in radians, (pan, tilt, heading) @@ -105,18 +114,18 @@ def search_user_capture(self, starting_pose=( """ start_pan = starting_pose[0] start_tilt = starting_pose[1] - CENTER_THRESHOLD = 0.25 + center_threshold = 0.25 pan_2 = Head.PAN_RIGHT * 0.8 tilt_2 = Head.TILT_UP * 0.74 pan_3 = Head.PAN_LEFT * 0.75 tilt_3 = Head.TILT_UP * 0.8 - if start_pan > Head.PAN_LEFT * CENTER_THRESHOLD: + if start_pan > Head.PAN_LEFT * center_threshold: pan_2 = Head.PAN_NEUTRAL tilt_2 = Head.TILT_UP * 0.8 pan_3 = Head.PAN_RIGHT * 0.75 tilt_3 = Head.TILT_UP * 0.7 else: - if start_pan < Head.PAN_RIGHT * CENTER_THRESHOLD: + if start_pan < Head.PAN_RIGHT * center_threshold: pan_2 = Head.PAN_NEUTRAL tilt_2 = Head.TILT_UP * 0.75 pan_3 = Head.PAN_LEFT * 0.75 @@ -163,16 +172,16 @@ def turn_to(self, turn_angle_radians=0.0, tilt_radians=-0.5, periphery=radians(3 Duration is 0.7 to 1.67 seconds (for just a head look in periphery) or 1.53 to 2.82 seconds for a full turn (depending on the angle). """ - TURN_TIME_BASE = 1.0 + turn_time_base = 1.0 if turn_angle_radians > pi: turn_angle_radians -= pi - logger.warning(('angle outside [-pi, pi]: {}').format(turn_angle_radians)) + logger.warning('angle outside [-pi, pi]: {}'.format(turn_angle_radians)) else: if turn_angle_radians < pi * -1: turn_angle_radians += pi - logger.warning(('angle outside [-pi, pi]: {}').format(turn_angle_radians)) + logger.warning('angle outside [-pi, pi]: {}'.format(turn_angle_radians)) outside_periphery = abs(turn_angle_radians) > periphery - time_to_turn = TURN_TIME_BASE + abs(turn_angle_radians) * 0.5 + time_to_turn = turn_time_base + abs(turn_angle_radians) * 0.5 tk = Track() tk.add(0.0, self.head_mot.openeyes()) if random() < 0.65: @@ -251,4 +260,4 @@ def capture_start(self): tk.add(0.05, self.lights_mot.pulse(color=(90, 90, 90), pulse_up_time=0.4, pulse_down_time=0.2)) tk.add(1.05, self.lights_mot.pulse(color=(120, 120, 120), pulse_up_time=0.35, pulse_down_time=0.2)) tk.add(2.05, self.lights_mot.pulse(color=(155, 155, 155), pulse_up_time=0.3, pulse_down_time=0.2)) - return tk \ No newline at end of file + return tk diff --git a/kuri_api/src/kuri_api/anim/library/docking_animations.py b/kuri_api/src/kuri_api/anim/library/docking_animations.py index 6042bf9..70ce2b8 100644 --- a/kuri_api/src/kuri_api/anim/library/docking_animations.py +++ b/kuri_api/src/kuri_api/anim/library/docking_animations.py @@ -1,13 +1,16 @@ -import math, random +import math +import random + +from kuri_api import Head from kuri_api.anim import AnimationGroup from kuri_api.anim import Track -from kuri_api import Head + class DockingAnimations(AnimationGroup): """ Animation class for having Kuri perform docking animations while wheels are being controlled by the docking service. - + Any animation called in this class will cancel any active docking head animation. """ @@ -79,7 +82,8 @@ def docking_approaching(self, mood=0.0): tk.add(2.3 * speed, self.head_mot.moveeyes(Head.EYES_CLOSED, 0.15)) tk.add(2.4 * speed, self.head_mot.pantilt(pan=-0.3 * random_side, tilt=0.45, duration=0.22 * speed)) tk.add(2.5 * speed, self.head_mot.moveeyes(Head.EYES_OPEN, 0.3)) - tk.add(3.3 * speed, self.head_mot.pantilt(pan=Head.PAN_NEUTRAL * random_side, tilt=Head.TILT_NEUTRAL, duration=0.3 * speed)) + tk.add(3.3 * speed, + self.head_mot.pantilt(pan=Head.PAN_NEUTRAL * random_side, tilt=Head.TILT_NEUTRAL, duration=0.3 * speed)) tk.add(5.1 * speed, self.head_mot.pantilt(pan=0.1 * random_side, tilt=Head.TILT_NEUTRAL, duration=0.3 * speed)) return tk @@ -123,7 +127,8 @@ def docking_preparing_to_back_in(self, mood=0.0): random_tilt = random.uniform(0.25, 0.55) tk.add(0.0, self.head_mot.moveeyes(Head.EYES_OPEN)) tk.add(0.0, self.head_mot.pantilt(pan=0.8 * random_side, tilt=random_tilt, duration=0.45 * speed)) - tk.add(0.6 * speed + random_time_add, self.head_mot.pantilt(pan=0.8 * random_side, tilt=random_tilt, duration=0.1 * speed)) + tk.add(0.6 * speed + random_time_add, + self.head_mot.pantilt(pan=0.8 * random_side, tilt=random_tilt, duration=0.1 * speed)) return tk def docking_back_in(self, mood=0.0): @@ -138,9 +143,11 @@ def docking_back_in(self, mood=0.0): tk.add(0.0, self.head_mot.moveeyes(Head.EYES_OPEN)) tk.add(1.5 * speed, self.head_mot.pantilt(pan=random_pan, tilt=0.35, duration=0.4 * speed)) tk.add(2.2 * speed + random_time_add, self.head_mot.moveeyes(Head.EYES_CLOSED, 0.15)) - tk.add(2.3 * speed + random_time_add, self.head_mot.pantilt(pan=0.8 * random_side, tilt=0.25, duration=0.5 * speed)) + tk.add(2.3 * speed + random_time_add, + self.head_mot.pantilt(pan=0.8 * random_side, tilt=0.25, duration=0.5 * speed)) tk.add(2.5 * speed + random_time_add, self.head_mot.moveeyes(Head.EYES_OPEN, 0.3)) - tk.add(3.8 * speed + random_time_add, self.head_mot.pantilt(pan=0.2 * random_side, tilt=0.25, duration=0.5 * speed)) + tk.add(3.8 * speed + random_time_add, + self.head_mot.pantilt(pan=0.2 * random_side, tilt=0.25, duration=0.5 * speed)) return tk def docking_reset(self): @@ -156,7 +163,7 @@ class DockingLEDAnimations(AnimationGroup): """ Animation class for having Kuri perform docking LED animations Does LED only so it can run independently of head and wheel movements - + Any animation called in this class will cancel any active docking LED animation. """ @@ -260,15 +267,21 @@ def undock_from_old_home(self): tk.add(4.4, self.head_mot.pantilt(pan=-0.1 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, duration=0.1)) tk.add(5.2, self.head_mot.pantilt(pan=0.25 * random_pan_side, tilt=Head.TILT_DOWN * 0.1, duration=0.45)) tk.add(8.0, self.head_mot.blinkeyes()) - tk.add(8.1, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.7 * random_pan_side, tilt=Head.TILT_DOWN * 0.15, duration=0.4)) + tk.add(8.1, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.7 * random_pan_side, tilt=Head.TILT_DOWN * 0.15, + duration=0.4)) tk.add(8.5, self.wheels_mot.rotate_by(angle=-math.pi * random_pan_side, duration=4.0)) - tk.add(6.8, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.3 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, duration=0.55)) - tk.add(7.5, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.55 * random_pan_side, tilt=Head.TILT_DOWN * 0.1, duration=0.4)) + tk.add(6.8, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.3 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, + duration=0.55)) + tk.add(7.5, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.55 * random_pan_side, tilt=Head.TILT_DOWN * 0.1, + duration=0.4)) tk.add(8.2, self.head_mot.blinkeyes()) - tk.add(8.2, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.75 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, duration=0.5)) - tk.add(9.3, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.45 * random_pan_side, tilt=Head.TILT_DOWN * 0.7, duration=0.5)) + tk.add(8.2, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.75 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, + duration=0.5)) + tk.add(9.3, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.45 * random_pan_side, tilt=Head.TILT_DOWN * 0.7, + duration=0.5)) tk.add(10.3, self.head_mot.blinkeyes()) - tk.add(10.8, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.8 * random_pan_side, tilt=Head.TILT_DOWN * 0.1, duration=0.3)) + tk.add(10.8, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.8 * random_pan_side, tilt=Head.TILT_DOWN * 0.1, + duration=0.3)) tk.add(11.5, self.head_mot.openeyes()) tk.add(11.5, self.head_mot.pantilt(pan=Head.PAN_NEUTRAL, tilt=Head.TILT_NEUTRAL, duration=0.8)) tk.add(12.5, self.head_mot.blinkeyes()) diff --git a/kuri_api/src/kuri_api/anim/library/idle_animations.py b/kuri_api/src/kuri_api/anim/library/idle_animations.py index 21e64f6..c8af002 100644 --- a/kuri_api/src/kuri_api/anim/library/idle_animations.py +++ b/kuri_api/src/kuri_api/anim/library/idle_animations.py @@ -1,15 +1,18 @@ +import logging import random + +from kuri_api import Head from kuri_api.anim import AnimationGroup from kuri_api.anim import Track -from kuri_api import Head from kuri_api.utils.social import random_adult_tilt, random_child_tilt -import logging + logger = logging.getLogger(__name__) + class IdleAnimations(AnimationGroup): """ Animations for Kuri's idle behaviors. - + Currently holds scripted idle animation. """ @@ -33,25 +36,37 @@ def scripted_idle(self, move_base=True): for _ in range(0, 5): for _ in range(0, random_range): tk.add(0.7 + add, self.head_mot.openeyes(time=0.14, amplitude=-0.35 * speed)) - tk.add(0.8 + add, self.head_mot.pantilt(pan=0.2 * random_side * speed_amount, tilt=0, duration=0.7 * speed)) + tk.add(0.8 + add, + self.head_mot.pantilt(pan=0.2 * random_side * speed_amount, tilt=0, duration=0.7 * speed)) tk.add(0.9 + add, self.head_mot.openeyes(time=0.25, amplitude=1.1)) - tk.add(2.8 + add, self.head_mot.pantilt(pan=0.3 * random_side * speed_amount, tilt=0.15 * speed_amount, duration=0.15 * speed)) - tk.add(4.1 + add, self.head_mot.pantilt(pan=0.2 * random_side * speed_amount, tilt=0.15 * speed_amount, duration=0.15 * speed)) + tk.add(2.8 + add, self.head_mot.pantilt(pan=0.3 * random_side * speed_amount, tilt=0.15 * speed_amount, + duration=0.15 * speed)) + tk.add(4.1 + add, self.head_mot.pantilt(pan=0.2 * random_side * speed_amount, tilt=0.15 * speed_amount, + duration=0.15 * speed)) tk.add(4.7 + add + spacing, self.head_mot.openeyes(time=0.15, amplitude=-0.5)) - tk.add(4.8 + add + spacing, self.head_mot.pantilt(pan=0.3 * random_side * speed_amount, tilt=-0.2 * random_side2 * multiplier * speed_amount, duration=0.53 * speed)) + tk.add(4.8 + add + spacing, self.head_mot.pantilt(pan=0.3 * random_side * speed_amount, + tilt=-0.2 * random_side2 * multiplier * speed_amount, + duration=0.53 * speed)) tk.add(4.9 + add + spacing, self.head_mot.openeyes(time=0.25, amplitude=1.1)) - tk.add(5.8 + add + spacing, self.head_mot.pantilt(pan=0.1 * random_side * speed_amount, tilt=-0.2 * random_side2 * multiplier * speed_amount, duration=0.15 * speed)) + tk.add(5.8 + add + spacing, self.head_mot.pantilt(pan=0.1 * random_side * speed_amount, + tilt=-0.2 * random_side2 * multiplier * speed_amount, + duration=0.15 * speed)) tk.add(7.3 + add + spacing * 2, self.head_mot.openeyes(time=0.15, amplitude=-0.5)) - tk.add(7.38 + add + spacing * 2, self.head_mot.pantilt(pan=-0.8 * random_side * speed_amount, tilt=0, duration=0.6 * speed)) + tk.add(7.38 + add + spacing * 2, + self.head_mot.pantilt(pan=-0.8 * random_side * speed_amount, tilt=0, duration=0.6 * speed)) tk.add(7.48 + add + spacing * 2, self.head_mot.openeyes(time=0.25, amplitude=1.1)) if move_base: tk.add(7.7 + add + spacing * 2, self.wheels_mot.rotate(-0.8 * random_side, 1 * speed)) - tk.add(9.0 + add + spacing * 2, self.head_mot.pantilt(pan=-0.6 * random_side * speed_amount, tilt=0, duration=0.15 * speed)) + tk.add(9.0 + add + spacing * 2, + self.head_mot.pantilt(pan=-0.6 * random_side * speed_amount, tilt=0, duration=0.15 * speed)) tk.add(10.5 + add + spacing * 3, self.head_mot.openeyes(time=0.15, amplitude=-0.5)) tk.add(10.68 + add + spacing * 3, self.head_mot.openeyes(time=0.25, amplitude=1.1)) - tk.add(11.3 + add + spacing * 3, self.head_mot.pantilt(pan=-0.7 * random_side * speed_amount, tilt=0, duration=0.15 * speed)) + tk.add(11.3 + add + spacing * 3, + self.head_mot.pantilt(pan=-0.7 * random_side * speed_amount, tilt=0, duration=0.15 * speed)) tk.add(12.9 + add + spacing * 4, self.head_mot.openeyes(time=0.15, amplitude=-1.5 * on_off + 1)) - tk.add(13.0 + add + spacing * 4, self.head_mot.pantilt(pan=0.2 * random_side * speed_amount, tilt=-0.2 * random_side2 * multiplier * speed_amount, duration=0.5 * speed)) + tk.add(13.0 + add + spacing * 4, self.head_mot.pantilt(pan=0.2 * random_side * speed_amount, + tilt=-0.2 * random_side2 * multiplier * speed_amount, + duration=0.5 * speed)) tk.add(13.08 + add + spacing * 4, self.head_mot.openeyes(time=0.25, amplitude=1.1)) if move_base: tk.add(13.15 + add + spacing * 4, self.wheels_mot.rotate(0.8 * random_side, 1 * speed)) @@ -68,20 +83,27 @@ def scripted_idle(self, move_base=True): tk.add(0.3 + add, self.head_mot.pantilt(pan=0.2 * random_side, tilt=0.1 * random_side, duration=0.3)) tk.add(0.4 + add, self.head_mot.openeyes(time=0.25, amplitude=1.1)) tk.add(2 + add, self.head_mot.pantilt(pan=-0.1 * random_side, tilt=0.4 * random_side, duration=0.3 * speed)) - tk.add(4.1 + add, self.head_mot.pantilt(pan=0.5 * random_side, tilt=0.4 * random_side, duration=0.4 * speed)) - tk.add(5.4 + add, self.head_mot.pantilt(pan=0.3 * random_side, tilt=0.4 * random_side, duration=0.2 * speed)) + tk.add(4.1 + add, + self.head_mot.pantilt(pan=0.5 * random_side, tilt=0.4 * random_side, duration=0.4 * speed)) + tk.add(5.4 + add, + self.head_mot.pantilt(pan=0.3 * random_side, tilt=0.4 * random_side, duration=0.2 * speed)) tk.add(7.6 + add, self.head_mot.openeyes(time=0.15, amplitude=-0.5)) - tk.add(7.7 + add, self.head_mot.pantilt(pan=0.9 * random_side, tilt=0.4 * random_side, duration=0.8 * speed)) + tk.add(7.7 + add, + self.head_mot.pantilt(pan=0.9 * random_side, tilt=0.4 * random_side, duration=0.8 * speed)) tk.add(7.78 + add, self.head_mot.openeyes(time=0.25, amplitude=1.1)) if move_base: tk.add(8.0 + add, self.wheels_mot.rotate(random_body * random_side, 1.5 * speed)) - tk.add(10.7 + add + spacing, self.head_mot.pantilt(pan=0.7 * random_side, tilt=0.4 * random_side, duration=0.3 * speed)) - tk.add(11.8 + add + spacing, self.head_mot.pantilt(pan=0.8 * random_side, tilt=0.4 * random_side, duration=0.2 * speed)) + tk.add(10.7 + add + spacing, + self.head_mot.pantilt(pan=0.7 * random_side, tilt=0.4 * random_side, duration=0.3 * speed)) + tk.add(11.8 + add + spacing, + self.head_mot.pantilt(pan=0.8 * random_side, tilt=0.4 * random_side, duration=0.2 * speed)) tk.add(12.9 + add + spacing * 2, self.head_mot.openeyes(time=0.15, amplitude=-0.5)) - tk.add(13.0 + add + spacing * 2, self.head_mot.pantilt(pan=-0.55 * random_side, tilt=0.2 * random_side, duration=0.6 * speed)) + tk.add(13.0 + add + spacing * 2, + self.head_mot.pantilt(pan=-0.55 * random_side, tilt=0.2 * random_side, duration=0.6 * speed)) if move_base: tk.add(13.2 + add + spacing * 2, self.wheels_mot.rotate(-1 * random_body * random_side, 1.5 * speed)) - tk.add(13.7 + add + spacing * 2, self.head_mot.pantilt(pan=-0.2 * random_side, tilt=0.1 * random_side, duration=0.4 * speed)) + tk.add(13.7 + add + spacing * 2, + self.head_mot.pantilt(pan=-0.2 * random_side, tilt=0.1 * random_side, duration=0.4 * speed)) tk.add(13.3 + add + spacing * 2, self.head_mot.openeyes(time=0.15, amplitude=1.1)) tk.add(15.9 + add + spacing * 3, self.head_mot.openeyes(time=0.15, amplitude=-0.5)) tk.add(18.42 + add + spacing * 3, self.head_mot.pantilt(pan=-0.4, tilt=0, duration=0.4 * speed)) @@ -97,19 +119,19 @@ def scripted_idle(self, move_base=True): return tk - def look_around_common(self, tilt_func=lambda : 0): + def look_around_common(self, tilt_func=lambda: 0): start_pan = random.uniform(Head.PAN_RIGHT, Head.PAN_LEFT) start_tilt = tilt_func() - CENTER_THRESHOLD = 0.25 + center_threshold = 0.25 pan_2 = Head.PAN_RIGHT * random.uniform(0.5, 1.0) tilt_2 = tilt_func() pan_3 = Head.PAN_LEFT * random.uniform(0.5, 1.0) tilt_3 = tilt_func() - if start_pan > Head.PAN_LEFT * CENTER_THRESHOLD: + if start_pan > Head.PAN_LEFT * center_threshold: pan_2 = Head.PAN_NEUTRAL pan_3 = Head.PAN_RIGHT * random.uniform(0.5, 1.0) else: - if start_pan < Head.PAN_RIGHT * CENTER_THRESHOLD: + if start_pan < Head.PAN_RIGHT * center_threshold: pan_2 = Head.PAN_NEUTRAL pan_3 = Head.PAN_LEFT * random.uniform(0.5, 1.0) tk = Track() diff --git a/kuri_api/src/kuri_api/anim/library/led_emotion_animations.py b/kuri_api/src/kuri_api/anim/library/led_emotion_animations.py index 79b9876..3a8d999 100644 --- a/kuri_api/src/kuri_api/anim/library/led_emotion_animations.py +++ b/kuri_api/src/kuri_api/anim/library/led_emotion_animations.py @@ -2,6 +2,7 @@ from kuri_api.anim import Track from kuri_api.utils.heartbeat_utils import happiness_to_color, happiness_to_fade, excitation_to_period + class LEDEmotionAnimations(AnimationGroup): """ Emotional animations run in the background on the chest light @@ -9,6 +10,7 @@ class LEDEmotionAnimations(AnimationGroup): def breath(self, excited, happy): tk = Track() - one_breath = self.lights_mot.heartbeat(happiness_to_color(happy), happiness_to_fade(happy), excitation_to_period(excited)) + one_breath = self.lights_mot.heartbeat(happiness_to_color(happy), happiness_to_fade(happy), + excitation_to_period(excited)) tk.add(0.0, one_breath) - return tk \ No newline at end of file + return tk diff --git a/kuri_api/src/kuri_api/anim/library/observer_animations.py b/kuri_api/src/kuri_api/anim/library/observer_animations.py index 1125ba7..a66b088 100644 --- a/kuri_api/src/kuri_api/anim/library/observer_animations.py +++ b/kuri_api/src/kuri_api/anim/library/observer_animations.py @@ -1,6 +1,7 @@ +from kuri_api import Lights from kuri_api.anim import AnimationGroup from kuri_api.anim import Track -from kuri_api import Lights + class ObserverModeAnimations(AnimationGroup): """ @@ -30,4 +31,4 @@ def observer_start(self): def observer_end(self): tk = Track() tk.add(0.0, self.movies.to_animated('observer-mode-exit.mov')) - return tk \ No newline at end of file + return tk diff --git a/kuri_api/src/kuri_api/anim/library/onboarding_animations.py b/kuri_api/src/kuri_api/anim/library/onboarding_animations.py index 5e9590e..d71d028 100644 --- a/kuri_api/src/kuri_api/anim/library/onboarding_animations.py +++ b/kuri_api/src/kuri_api/anim/library/onboarding_animations.py @@ -1,7 +1,10 @@ -import math, random +import math +import random + +from kuri_api import Head from kuri_api.anim import AnimationGroup from kuri_api.anim import Track -from kuri_api import Head + class OnboardingAnimations(AnimationGroup): @@ -109,33 +112,47 @@ def undock_and_scan(self): tk.add(4.4, self.head_mot.pantilt(pan=-0.1 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, duration=0.1)) tk.add(5.2, self.head_mot.pantilt(pan=0.25 * random_pan_side, tilt=Head.TILT_DOWN * 0.1, duration=0.45)) tk.add(6.4, self.head_mot.blinkeyes()) - tk.add(6.5, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.7 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, duration=0.55)) + tk.add(6.5, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.7 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, + duration=0.55)) tk.add(7.0, self.sound_mot.open(sound1)) tk.add(7.0, self.wheels_mot.rotate_by(angle=math.pi / 2 * random_pan_side, duration=3.0)) - tk.add(7.6, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.55 * random_pan_side, tilt=Head.TILT_DOWN * 0.1, duration=0.4)) - tk.add(8.7, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.75 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, duration=0.4)) + tk.add(7.6, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.55 * random_pan_side, tilt=Head.TILT_DOWN * 0.1, + duration=0.4)) + tk.add(8.7, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.75 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, + duration=0.4)) tk.add(8.8, self.head_mot.blinkeyes()) - tk.add(9.6, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.45 * random_pan_side, tilt=Head.TILT_DOWN * 0.3, duration=0.4)) + tk.add(9.6, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.45 * random_pan_side, tilt=Head.TILT_DOWN * 0.3, + duration=0.4)) tk.add(9.7, self.head_mot.blinkeyes()) tk.add(9.9, self.head_mot.pantilt(pan=Head.PAN_NEUTRAL, tilt=Head.TILT_DOWN * 0.6, duration=0.3)) tk.add(10.5, self.sound_mot.open(sound2)) tk.add(10.5, self.head_mot.blinkeyes()) tk.add(10.5, self.wheels_mot.rotate_by(angle=-math.pi * random_pan_side, duration=6.0)) - tk.add(10.7, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.7 * random_pan_side, tilt=Head.TILT_DOWN * 0.15, duration=0.4)) - tk.add(11.3, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.3 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, duration=0.55)) - tk.add(12.0, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.55 * random_pan_side, tilt=Head.TILT_DOWN * 0.1, duration=0.4)) + tk.add(10.7, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.7 * random_pan_side, tilt=Head.TILT_DOWN * 0.15, + duration=0.4)) + tk.add(11.3, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.3 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, + duration=0.55)) + tk.add(12.0, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.55 * random_pan_side, tilt=Head.TILT_DOWN * 0.1, + duration=0.4)) tk.add(12.1, self.head_mot.blinkeyes()) - tk.add(12.7, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.75 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, duration=0.5)) - tk.add(14.2, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.45 * random_pan_side, tilt=Head.TILT_DOWN * 0.7, duration=0.5)) + tk.add(12.7, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.75 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, + duration=0.5)) + tk.add(14.2, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.45 * random_pan_side, tilt=Head.TILT_DOWN * 0.7, + duration=0.5)) tk.add(14.7, self.head_mot.blinkeyes()) - tk.add(15.3, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.8 * random_pan_side, tilt=Head.TILT_DOWN * 0.1, duration=0.3)) + tk.add(15.3, self.head_mot.pantilt(pan=Head.PAN_RIGHT * 0.8 * random_pan_side, tilt=Head.TILT_DOWN * 0.1, + duration=0.3)) tk.add(16.0, self.head_mot.blinkeyes()) - tk.add(16.1, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.5 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, duration=0.55)) + tk.add(16.1, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.5 * random_pan_side, tilt=Head.TILT_DOWN * 0.6, + duration=0.55)) tk.add(16.6, self.wheels_mot.rotate_by(angle=math.pi / 2 * random_pan_side, duration=3.0)) - tk.add(17.2, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.75 * random_pan_side, tilt=Head.TILT_DOWN * 0.1, duration=0.4)) - tk.add(18.3, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.55 * random_pan_side, tilt=Head.TILT_DOWN * 0.3, duration=0.4)) + tk.add(17.2, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.75 * random_pan_side, tilt=Head.TILT_DOWN * 0.1, + duration=0.4)) + tk.add(18.3, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.55 * random_pan_side, tilt=Head.TILT_DOWN * 0.3, + duration=0.4)) tk.add(18.4, self.head_mot.blinkeyes()) - tk.add(19.2, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.35 * random_pan_side, tilt=Head.TILT_DOWN * 0.7, duration=0.4)) + tk.add(19.2, self.head_mot.pantilt(pan=Head.PAN_LEFT * 0.35 * random_pan_side, tilt=Head.TILT_DOWN * 0.7, + duration=0.4)) tk.add(19.3, self.head_mot.blinkeyes()) tk.add(19.5, self.head_mot.pantilt(pan=Head.PAN_NEUTRAL, tilt=Head.TILT_DOWN * 0.3, duration=0.3)) tk.add(20.0, self.head_mot.openeyes()) diff --git a/kuri_api/src/kuri_api/anim/library/reaction_animations.py b/kuri_api/src/kuri_api/anim/library/reaction_animations.py index ccbca52..b6126a2 100644 --- a/kuri_api/src/kuri_api/anim/library/reaction_animations.py +++ b/kuri_api/src/kuri_api/anim/library/reaction_animations.py @@ -1,8 +1,11 @@ -import math, random -from kuri_api.utils import interp +import math +import random + +from kuri_api import Head, Lights from kuri_api.anim import AnimationGroup from kuri_api.anim import Track -from kuri_api import Head, Lights +from kuri_api.utils import interp + class ReactionAnimations(AnimationGroup): @@ -255,16 +258,16 @@ def huh1_docked(self, pan_face=Head.PAN_NEUTRAL, chest_movie='starburst-orange.m """ - Modified by Patrick & Paul on 2016-04-20, out of sync with Doug's scriptk. - + From Doug Dooley's Notes: - + #HUH? -1st time it happens #Robot stops if it hasn't already #Robot may or may not be facial tracking 00:00 Chest Light OFF .08 Sec # This chest light blink has pause 00:00 Head Rotates UP 12 degrees from current position .41sec # add on top of facial tracking number if need be - + 00:00 EyeLid drops to neutral if it isn't already in neutral. * 00:10 Light turns from blue to orange 00:25 Chest Light ON .17sec @@ -279,7 +282,7 @@ def huh1_docked(self, pan_face=Head.PAN_NEUTRAL, chest_movie='starburst-orange.m tracking number if need be * 03:09 Start Thinking animation #Put thinking animation on top of facial tracking, if robot currently tracking face - + * => Unimplemented """ tk = Track() @@ -304,7 +307,7 @@ def huh2(self, pan_face=Head.PAN_NEUTRAL, move_base=True): """ - Modified by Patrick & Paul on 2016-04-20, out of sync with Doug's scriptk. - + 00:00 Chest Light OFF .08 Sec # This chest light blink has pause 00:00 Head Rotates UP 12 degrees from current position .41sec # add on top of facial tracking number if need be @@ -331,7 +334,7 @@ def huh2(self, pan_face=Head.PAN_NEUTRAL, move_base=True): 03:62 EyeLid Opens to Fully open eye .21sec *04:32 Start "Thinking animation" #Put thinking animation on top of facial tracking, if robot currently tracking face - + * => Unimplemented """ tk = Track() @@ -368,10 +371,10 @@ def listening(self): return tk def listening_pose(self): - TILT_LOOK_USER_RADIANS = -0.8 + tilt_look_user_radians = -0.8 tk = Track() tk.add(0.04, self.head_mot.happyeyes(0.17)) - tk.add(0.0, self.head_mot.pantilt(Head.PAN_NEUTRAL, TILT_LOOK_USER_RADIANS, 0.25)) + tk.add(0.0, self.head_mot.pantilt(Head.PAN_NEUTRAL, tilt_look_user_radians, 0.25)) return tk def lost(self): diff --git a/kuri_api/src/kuri_api/anim/library/relocalize_animations.py b/kuri_api/src/kuri_api/anim/library/relocalize_animations.py index 37b859a..f03e4ba 100644 --- a/kuri_api/src/kuri_api/anim/library/relocalize_animations.py +++ b/kuri_api/src/kuri_api/anim/library/relocalize_animations.py @@ -1,6 +1,7 @@ from kuri_api.anim import AnimationGroup from kuri_api.anim import Track + class RelocalizeAnimations(AnimationGroup): """ Turn the robots through facing @@ -41,7 +42,8 @@ def relocalize_part3(self): keep_alive_speed = 0 spacing = (keep_alive_speed * 0.6 + 10) * 0.1 tk = Track() - tk.add(0.9 * spacing, self.head_mot.blinkeyes(open_amplitude=1.0, close_amplitude=1.0, open_time=0.27, close_time=0.15)) + tk.add(0.9 * spacing, + self.head_mot.blinkeyes(open_amplitude=1.0, close_amplitude=1.0, open_time=0.27, close_time=0.15)) tk.add(1.0 * spacing, self.wheels_mot.rotate(-10, 1.5)) tk.add(1.0 * spacing, self.head_mot.pantilt(pan=0, tilt=0, duration=1.5)) return tk @@ -67,7 +69,8 @@ def relocalize_part6(self): keep_alive_speed = 0 spacing = (keep_alive_speed * 0.6 + 10) * 0.1 tk = Track() - tk.add(0.6 * spacing, self.head_mot.blinkeyes(open_amplitude=1.0, close_amplitude=1.0, open_time=0.27, close_time=0.15)) + tk.add(0.6 * spacing, + self.head_mot.blinkeyes(open_amplitude=1.0, close_amplitude=1.0, open_time=0.27, close_time=0.15)) tk.add(0.7 * spacing, self.wheels_mot.rotate(-10, 1.5)) tk.add(0.7 * spacing, self.head_mot.pantilt(pan=0, tilt=0, duration=1.5)) return tk @@ -86,10 +89,12 @@ def relocalize_part8(self): speed = (keep_alive_speed + 10) * 0.1 tk = Track() tk.add(0.7 * spacing, self.head_mot.pantilt(pan=-0.78, tilt=0.3, duration=0.32 * speed)) - tk.add(1.25 * spacing, self.head_mot.blinkeyes(open_amplitude=1.0, close_amplitude=1.0, open_time=0.27, close_time=0.15)) + tk.add(1.25 * spacing, + self.head_mot.blinkeyes(open_amplitude=1.0, close_amplitude=1.0, open_time=0.27, close_time=0.15)) tk.add(1.3 * spacing, self.head_mot.pantilt(pan=-0.78, tilt=0, duration=0.2 * speed)) tk.add(1.5 * spacing, self.wheels_mot.rotate(-9, 1)) - tk.add(1.4 * spacing, self.head_mot.blinkeyes(open_amplitude=1.0, close_amplitude=1.0, open_time=0.27, close_time=0.15)) + tk.add(1.4 * spacing, + self.head_mot.blinkeyes(open_amplitude=1.0, close_amplitude=1.0, open_time=0.27, close_time=0.15)) tk.add(1.4 * spacing, self.head_mot.pantilt(pan=0, tilt=0, duration=1)) tk.add(2.5 * spacing, self.head_mot.pantilt(pan=-0.4, tilt=-0.5, duration=0.4 * speed)) tk.add(3.7 * spacing, self.head_mot.pantilt(pan=0, tilt=0, duration=0.4 * speed)) diff --git a/kuri_api/src/kuri_api/anim/library/romoji_animations.py b/kuri_api/src/kuri_api/anim/library/romoji_animations.py index d371c5e..d5b35f6 100644 --- a/kuri_api/src/kuri_api/anim/library/romoji_animations.py +++ b/kuri_api/src/kuri_api/anim/library/romoji_animations.py @@ -1,7 +1,9 @@ from math import radians + from kuri_api.anim import AnimationGroup from kuri_api.anim import Track + class RomojiAnimations(AnimationGroup): def happy_birthday(self): @@ -31,8 +33,10 @@ def i_love_you(self): head_wiggle = self.head_mot.headwiggle(self.head.cur_pan, self.head.cur_tilt) tk.add(0.04, head_wiggle) tk.add(0.04, self.wheels_mot.bodywiggle(direction=-1)) - tk.add(head_wiggle.length() + 0.12, self.head_mot.pantilt(self.head.cur_pan, self.head.cur_tilt - radians(5), 0.29)) - tk.add(head_wiggle.length() + 1.04, self.head_mot.pantilt(self.head.cur_pan, self.head.cur_tilt + radians(5), 0.5)) + tk.add(head_wiggle.length() + 0.12, + self.head_mot.pantilt(self.head.cur_pan, self.head.cur_tilt - radians(5), 0.29)) + tk.add(head_wiggle.length() + 1.04, + self.head_mot.pantilt(self.head.cur_pan, self.head.cur_tilt + radians(5), 0.5)) tk.add(head_wiggle.length() + 3.0, self.head_mot.reset()) return tk @@ -49,4 +53,4 @@ def night_light(self): lullaby = self.sound_mot.open('Lullaby.wav') tk.add(0, lullaby) tk.add(0, self.lights_mot.night_light(lullaby.length(), period=10.0)) - return tk \ No newline at end of file + return tk diff --git a/kuri_api/src/kuri_api/anim/library/sleep_wake_animations.py b/kuri_api/src/kuri_api/anim/library/sleep_wake_animations.py index 6484e0e..6e5d337 100644 --- a/kuri_api/src/kuri_api/anim/library/sleep_wake_animations.py +++ b/kuri_api/src/kuri_api/anim/library/sleep_wake_animations.py @@ -1,7 +1,9 @@ from random import choice + +from kuri_api import Head from kuri_api.anim import AnimationGroup from kuri_api.anim import Track -from kuri_api import Head + class SleepAndWakeAnimations(AnimationGroup): diff --git a/kuri_api/src/kuri_api/anim/library/social_animations.py b/kuri_api/src/kuri_api/anim/library/social_animations.py index b803424..ba13f4b 100644 --- a/kuri_api/src/kuri_api/anim/library/social_animations.py +++ b/kuri_api/src/kuri_api/anim/library/social_animations.py @@ -1,8 +1,10 @@ +import random +from math import radians + from kuri_api.anim import AnimationGroup from kuri_api.anim import Track from kuri_api.utils.social import random_photo_tilt -import random -from math import radians + class SocialAnimations(AnimationGroup): """ @@ -31,14 +33,14 @@ def reposition(self): tk.add(0.35, self.head_mot.blinkeyes()) tilt = random_photo_tilt() init_pan = self.head.cur_pan - PAN_CUTOFF = 0.5 - if init_pan > PAN_CUTOFF: + pan_cutoff = 0.5 + if init_pan > pan_cutoff: pan_dir = -1 else: - if init_pan < -1 * PAN_CUTOFF: + if init_pan < -1 * pan_cutoff: pan_dir = 1 else: pan_dir = random.choice([1, -1]) rand_pan = init_pan + radians(pan_dir * random.uniform(15, 45)) tk.add(0.35, self.head_mot.pantilt(rand_pan, tilt, 0.33)) - return tk \ No newline at end of file + return tk diff --git a/kuri_api/src/kuri_api/anim/library/system_animations.py b/kuri_api/src/kuri_api/anim/library/system_animations.py index 2593611..0a5f9e8 100644 --- a/kuri_api/src/kuri_api/anim/library/system_animations.py +++ b/kuri_api/src/kuri_api/anim/library/system_animations.py @@ -1,6 +1,7 @@ from kuri_api.anim import AnimationGroup from kuri_api.anim import Track + class SystemAnimations(AnimationGroup): """ System-level animations. @@ -19,4 +20,4 @@ def start_sound(self): def critical_battery(self): tk = Track() tk.add(0.0, self.movies.to_animated('critical_battery.mov')) - return tk \ No newline at end of file + return tk diff --git a/kuri_api/src/kuri_api/anim/library/test_animations.py b/kuri_api/src/kuri_api/anim/library/test_animations.py index d1ba019..c6af186 100644 --- a/kuri_api/src/kuri_api/anim/library/test_animations.py +++ b/kuri_api/src/kuri_api/anim/library/test_animations.py @@ -1,7 +1,9 @@ from math import radians + from kuri_api.anim import AnimationGroup from kuri_api.anim import Track + class TestAnimations(AnimationGroup): def seizure(self): diff --git a/kuri_api/src/kuri_api/anim/player.py b/kuri_api/src/kuri_api/anim/player.py index e344d0f..c5c1e4f 100644 --- a/kuri_api/src/kuri_api/anim/player.py +++ b/kuri_api/src/kuri_api/anim/player.py @@ -1,8 +1,10 @@ +import logging import threading from collections import Counter -import logging + logger = logging.getLogger(__name__) + def get_animations_in_class(anim): """ Returns the name of all animations in a class. @@ -16,10 +18,10 @@ def anim_clash_detected(anims): """ Check for clashes in naming of animation tracks. """ - all_funcs = [ f for anim_class in anims for f in get_animations_in_class(anim_class) ] + all_funcs = [f for anim_class in anims for f in get_animations_in_class(anim_class)] clash = len(all_funcs) != len(set(all_funcs)) if clash: - clash_anims = [ item for item, count in Counter(all_funcs).items() if count > 1 ] + clash_anims = [item for item, count in Counter(all_funcs).items() if count > 1] logger.error(('Animation clash: {}').format(clash_anims)) return clash @@ -28,7 +30,7 @@ def build_animation_map(anims): """ Build a map of animation names to track objects. """ - return {x:a_cls for a_cls in anims for x in get_animations_in_class(a_cls)} + return {x: a_cls for a_cls in anims for x in get_animations_in_class(a_cls)} def parse_animations(anims): @@ -37,11 +39,12 @@ def parse_animations(anims): """ if not isinstance(anims, list): anims = [ - anims] + anims] if anim_clash_detected(anims): raise KeyError('Animations have clashing names') return build_animation_map(anims) + class AnimationPlayer(object): """ Player for canned `Animations`. It just tracks and auto-plays a single @@ -266,4 +269,4 @@ def _autoplay(*args, **kwargs): return self.player return - return _autoplay \ No newline at end of file + return _autoplay diff --git a/kuri_api/src/kuri_api/anim/primitives/__init__.py b/kuri_api/src/kuri_api/anim/primitives/__init__.py index bd3ce32..c01d4e9 100644 --- a/kuri_api/src/kuri_api/anim/primitives/__init__.py +++ b/kuri_api/src/kuri_api/anim/primitives/__init__.py @@ -1,11 +1,12 @@ from .head import HeadMotions -from .wheels import WheelMotions from .light import Light -from .sound import Sound from .movies import Movies +from .sound import Sound +from .wheels import WheelMotions + __all__ = [ - 'HeadMotions', - 'WheelMotions', - 'Light', - 'Sound', - 'Movies'] \ No newline at end of file + 'HeadMotions', + 'WheelMotions', + 'Light', + 'Sound', + 'Movies'] diff --git a/kuri_api/src/kuri_api/anim/primitives/head.py b/kuri_api/src/kuri_api/anim/primitives/head.py index eec16d5..8282bbf 100644 --- a/kuri_api/src/kuri_api/anim/primitives/head.py +++ b/kuri_api/src/kuri_api/anim/primitives/head.py @@ -1,7 +1,12 @@ -import math, time, sys, threading as tr, traceback as tb -from numpy import clip +import math +import sys +import threading as tr +import time +import traceback as tb + from kuri_api.anim import track from kuri_api.head import Head +from numpy import clip class HeadPlayer(track.Player): @@ -21,7 +26,8 @@ def run(self): with self._svc as (head): if self._content_head.pan_traj or self._content_head.tilt_traj: numtraj += 1 - head.pan_and_tilt_sequence(self._content_head.pan_traj, self._content_head.tilt_traj, done_cb=self._head_cb) + head.pan_and_tilt_sequence(self._content_head.pan_traj, self._content_head.tilt_traj, + done_cb=self._head_cb) if self._content_head.eyes_traj: numtraj += 1 head.eyes_sequence(self._content_head.eyes_traj, done_cb=self._eye_cb) @@ -53,33 +59,34 @@ def cancel(self, timeout=1.0): with self._cv: self._cv.notify_all() self.join(timeout) - assert self._thread_is_dead(), ('Could not cancel: {}. HeadPlayer thread ID was `{}`').format(self._content_head, self.ident) + assert self._thread_is_dead(), 'Could not cancel: {}. HeadPlayer thread ID was `{}`'.format( + self._content_head, self.ident) def _thread_is_dead(self): """ Checks that our thread is not alive. If it's still alive, print diagnostic information to help debug the problem - + This was added to debug a fuzz test failure. When this is no longer a problem, this method can be removed. We're mainly interested in the side-effect for debugging. Seeing if the thread is alive or not is trivial - + See PM-4010 """ alive = self.is_alive() if alive: with self._printlock: - print ('Content length was {}').format(self._content_head.length()) + print 'Content length was {}'.format(self._content_head.length()) print '\n*** STACKTRACE - START ***\n' code = [] - for threadId, stack in sys._current_frames().items(): - code.append('\n# ThreadID: %s' % threadId) + for thread_id, stack in sys._current_frames().items(): + code.append('\n# ThreadID: %s' % thread_id) for fname, lineno, name, ln in tb.extract_stack(stack): code.append('File: "%s", line %d, in %s' % (fname, - lineno, - name)) + lineno, + name)) if ln: code.append(' %s' % ln.strip()) @@ -117,7 +124,9 @@ def length(self): return max(zip(*(self.pan_traj + self.tilt_traj + self.eyes_traj))[0]) def __str__(self): - return ('HeadMotion ({},{},{}) len={}s').format('pan' if self.pan_traj else ' ', 'tlt' if self.tilt_traj else ' ', 'eye' if self.eyes_traj else ' ', round(self.length(), 3)) + return 'HeadMotion ({},{},{}) len={}s'.format('pan' if self.pan_traj else ' ', + 'tlt' if self.tilt_traj else ' ', + 'eye' if self.eyes_traj else ' ', round(self.length(), 3)) class HeadMotions(object): @@ -130,72 +139,70 @@ def pantilt(self, pan, tilt, duration=0.5): """ Move the head's pan and tilt to desired angles (radians) with an optional duration - Ensures the pan and tilt angles are in the valid range """ pan = clip(pan, Head.PAN_RIGHT, Head.PAN_LEFT) tilt = clip(tilt, Head.TILT_UP, Head.TILT_DOWN) return HeadMotion(self._svc, pan_traj=[ - ( - duration, pan)], tilt_traj=[ - ( - duration, tilt)]) + ( + duration, pan)], tilt_traj=[ + ( + duration, tilt)]) def lookat(self, pan, duration=0.5): """ Move the head's pan to a desired angle (radians) with an optional duration - Ensures the pan angle is in the valid range """ pan = clip(pan, Head.PAN_RIGHT, Head.PAN_LEFT) return HeadMotion(self._svc, pan_traj=[ - ( - duration, pan)]) + ( + duration, pan)]) def neutral(self, duration=0.46): """ Moves the head to the neutral position with an optional time. """ return HeadMotion(self._svc, pan_traj=[ - ( - duration, Head.PAN_NEUTRAL)], tilt_traj=[ - ( - duration, Head.TILT_NEUTRAL)]) + ( + duration, Head.PAN_NEUTRAL)], tilt_traj=[ + ( + duration, Head.TILT_NEUTRAL)]) def moveeyes(self, position, time=0.17): """ Moves the eyes to a position with an optional time. - Ensures the position is in the valid range for the eyes """ position = clip(position, Head.EYES_HAPPY, Head.EYES_CLOSED) return HeadMotion(self._svc, eyes_traj=[ - ( - time, position)]) + ( + time, position)]) def openeyes(self, time=0.17, amplitude=1.0): amplitude = clip(amplitude, 0.0, 1.0) eyes = (1.0 - amplitude) * (Head.EYES_CLOSED - Head.EYES_OPEN) + Head.EYES_OPEN return HeadMotion(self._svc, eyes_traj=[ - ( - time, eyes)]) + ( + time, eyes)]) def closeeyes(self, time=0.17, amplitude=1.0): amplitude = clip(amplitude, 0.0, 1.0) eyes = amplitude * (Head.EYES_CLOSED - Head.EYES_OPEN) + Head.EYES_OPEN return HeadMotion(self._svc, eyes_traj=[ - ( - time, eyes)]) + ( + time, eyes)]) - def blinkeyes(self, open_amplitude=1.0, close_amplitude=1.0, open_time=0.21, close_time=0.12, eyes_closed_blink=Head.EYES_CLOSED_BLINK): + def blinkeyes(self, open_amplitude=1.0, close_amplitude=1.0, open_time=0.21, close_time=0.12, + eyes_closed_blink=Head.EYES_CLOSED_BLINK): close_eyes = close_amplitude * (eyes_closed_blink - Head.EYES_OPEN) + Head.EYES_OPEN open_eyes = open_amplitude * (Head.EYES_OPEN - eyes_closed_blink) + eyes_closed_blink return HeadMotion(self._svc, eyes_traj=[ - ( - close_time, close_eyes), - ( - open_time, open_eyes)]) + ( + close_time, close_eyes), + ( + open_time, open_eyes)]) def blink(self, speed=0.0, done_eye_position=None): blink_close_time = 0.13 @@ -206,58 +213,58 @@ def blink(self, speed=0.0, done_eye_position=None): blink_open_time -= speed_add done_pos = done_eye_position or Head.EYES_OPEN return HeadMotion(self._svc, eyes_traj=[ - ( - blink_close_time, Head.EYES_CLOSED), - ( - blink_open_time, done_pos)]) + ( + blink_close_time, Head.EYES_CLOSED), + ( + blink_open_time, done_pos)]) def happyeyes(self, time=0.25): """ Sets the eyes to the happy position with an optional time. """ return HeadMotion(self._svc, eyes_traj=[ - ( - time, Head.EYES_HAPPY)]) + ( + time, Head.EYES_HAPPY)]) def sadeyes(self, time=0.25): """ Sets the eyes to the sad position with an optional time. """ return HeadMotion(self._svc, eyes_traj=[ - ( - time, Head.EYES_SUPER_SAD)]) + ( + time, Head.EYES_SUPER_SAD)]) def happyposture(self, time=0.25): """ Sets the eyes and head tilt to the happy posture with an optional time. """ return HeadMotion(self._svc, tilt_traj=[ - ( - time, Head.TILT_NEUTRAL - 0.18)], eyes_traj=[ - ( - time, Head.EYES_HAPPY)]) + ( + time, Head.TILT_NEUTRAL - 0.18)], eyes_traj=[ + ( + time, Head.EYES_HAPPY)]) def sadposture(self, time=0.25): """ Sets the eyes and head tilt to the sad posture with an optional time. """ return HeadMotion(self._svc, eyes_traj=[ - ( - time, Head.EYES_SUPER_SAD)], tilt_traj=[ - ( - time, Head.TILT_NEUTRAL)]) + ( + time, Head.EYES_SUPER_SAD)], tilt_traj=[ + ( + time, Head.TILT_NEUTRAL)]) def reset(self): """ Reset the pan, tilt, and eyes to neutral positions. """ return HeadMotion(self._svc, pan_traj=[ - ( - 0.3, Head.PAN_NEUTRAL)], tilt_traj=[ - ( - 0.3, Head.TILT_NEUTRAL)], eyes_traj=[ - ( - 0.3, Head.EYES_OPEN)]) + ( + 0.3, Head.PAN_NEUTRAL)], tilt_traj=[ + ( + 0.3, Head.TILT_NEUTRAL)], eyes_traj=[ + ( + 0.3, Head.EYES_OPEN)]) def headwiggle(self, pan_reference, tilt): """ @@ -265,20 +272,20 @@ def headwiggle(self, pan_reference, tilt): """ gain = 4.0 return HeadMotion(self._svc, pan_traj=[ - ( - 0.33, pan_reference + gain * math.radians(-5)), - ( - 0.71, pan_reference + gain * math.radians(3.4)), - ( - 1.0899999999999999, pan_reference + gain * math.radians(-2.85)), - ( - 1.3399999999999999, - pan_reference + gain * math.radians(2.15))], tilt_traj=[ - ( - 0.33, tilt), - ( - 0.71, tilt), - ( - 1.0899999999999999, tilt), - ( - 1.3399999999999999, tilt)]) + ( + 0.33, pan_reference + gain * math.radians(-5)), + ( + 0.71, pan_reference + gain * math.radians(3.4)), + ( + 1.0899999999999999, pan_reference + gain * math.radians(-2.85)), + ( + 1.3399999999999999, + pan_reference + gain * math.radians(2.15))], tilt_traj=[ + ( + 0.33, tilt), + ( + 0.71, tilt), + ( + 1.0899999999999999, tilt), + ( + 1.3399999999999999, tilt)]) diff --git a/kuri_api/src/kuri_api/anim/primitives/light.py b/kuri_api/src/kuri_api/anim/primitives/light.py index 1eabb40..59e1e19 100644 --- a/kuri_api/src/kuri_api/anim/primitives/light.py +++ b/kuri_api/src/kuri_api/anim/primitives/light.py @@ -1,18 +1,26 @@ -import math, time, random, rospy, threading as tr -from kuri_api.utils import interp as lo +import logging +import math +import random +import rospy +import threading as tr +import time + from kuri_api.anim import track from kuri_api.lights import Lights +from kuri_api.utils import interp as lo from kuri_api.utils.rate import Rate -from .reactive_light.listening_light import ListeningLedPlayer + from .reactive_light.dance_light import MusicLedPlayer -import logging +from .reactive_light.listening_light import ListeningLedPlayer + logger = logging.getLogger(__name__) ANIM_FREQUENCY = 60 + class Light(object): """ Top-level container for chest LED primitives - + Parameters ---------- lights_svc: light service @@ -26,7 +34,7 @@ def circle_boot(self, length): pts = [] for i in range(Lights.NUM_LEDS - 1): p = [ - (0, 0, 0)] * Lights.NUM_LEDS + (0, 0, 0)] * Lights.NUM_LEDS p[i + 1] = (255, 255, 255) pts.append(p) @@ -37,7 +45,7 @@ def off(self, length): def flash(self, color, frequency): return Flash(self._lights_svc, [ - color] * Lights.NUM_LEDS, frequency) + color] * Lights.NUM_LEDS, frequency) def glow_pattern(self, pattern, fade_length, hold_length): fade_up = self.animate(self._lights_svc.get_pixels(), pattern, lo.quad_in, fade_length) @@ -46,8 +54,8 @@ def glow_pattern(self, pattern, fade_length, hold_length): def glow(self, r, g, b, fade_length, hold_length): final_pat = [ - ( - r, g, b)] * Lights.NUM_LEDS + ( + r, g, b)] * Lights.NUM_LEDS fade_up = self.animate(self._lights_svc.get_pixels(), final_pat, lo.quad_in, fade_length) hold_on = LedPattern(self._lights_svc, [final_pat], hold_length, hold=True) return fade_up + hold_on @@ -57,7 +65,7 @@ def white_glow(self, v, fade_length, hold_length): def white_pulse(self, length, frequency=0.5): return Pulse(self._lights_svc, [ - (255, 255, 255)] * Lights.NUM_LEDS, frequency, length) + (255, 255, 255)] * Lights.NUM_LEDS, frequency, length) def pulse(self, color, pulse_up_time=0.3, pulse_down_time=0.3, indeces=None, loop=False): if not indeces: @@ -80,7 +88,7 @@ def animate(self, start_pat, end_pat, func, length, fps=ANIM_FREQUENCY, loop=Fal """ Given a start pattern, end pattern and a linear interpolation function return a series of patterns that interpolates between the two. - + Parameters ---------- start_pat (list of n 3 tuples): pattern to start with @@ -110,19 +118,19 @@ def heartbeat(self, color, fade_off_color, period): low_glow_frame = int(math.ceil(0.4 * period * ANIM_FREQUENCY)) low_deglow_frame = bottom_frames low_pat = lo.interp_keyframes([ - lo.KeyFrame(0, [fade_off_color], lo.quad_in), - lo.KeyFrame(low_glow_frame, [color], lo.quad_in), - lo.KeyFrame(low_deglow_frame, [fade_off_color], lo.quad_out)]) + lo.KeyFrame(0, [fade_off_color], lo.quad_in), + lo.KeyFrame(low_glow_frame, [color], lo.quad_in), + lo.KeyFrame(low_deglow_frame, [fade_off_color], lo.quad_out)]) mid_lowglow_frame = int(math.ceil(0.267 * period * ANIM_FREQUENCY)) mid_glow_frame = int(math.ceil(0.534 * period * ANIM_FREQUENCY)) mid_deglow_frame = int(math.ceil(0.869 * period * ANIM_FREQUENCY)) mid_end_frame = bottom_frames middle_pat = lo.interp_keyframes([ - lo.KeyFrame(0, [off], lo.quad_in), - lo.KeyFrame(mid_lowglow_frame, [fade_off_color], lo.quad_in), - lo.KeyFrame(mid_glow_frame, [color], lo.quad_in), - lo.KeyFrame(mid_deglow_frame, [fade_off_color], lo.quad_out), - lo.KeyFrame(mid_end_frame, [off], lo.quad_out)]) + lo.KeyFrame(0, [off], lo.quad_in), + lo.KeyFrame(mid_lowglow_frame, [fade_off_color], lo.quad_in), + lo.KeyFrame(mid_glow_frame, [color], lo.quad_in), + lo.KeyFrame(mid_deglow_frame, [fade_off_color], lo.quad_out), + lo.KeyFrame(mid_end_frame, [off], lo.quad_out)]) top_off_color = off top_period = period top_frames = bottom_frames @@ -136,18 +144,18 @@ def heartbeat(self, color, fade_off_color, period): top_deglow_frame = int(math.ceil(0.801 * top_period * ANIM_FREQUENCY)) top_endoff_frame = int(math.ceil(0.86 * top_period * ANIM_FREQUENCY)) top_pat = lo.interp_keyframes([ - lo.KeyFrame(0, [top_off_color], lo.quad_in), - lo.KeyFrame(top_off_frame, [top_off_color], lo.quad_in), - lo.KeyFrame(top_lowglow_frame, [fade_off_color], lo.quad_in), - lo.KeyFrame(top_glow_frame, [color], lo.quad_in), - lo.KeyFrame(top_deglow_frame, [fade_off_color], lo.quad_out), - lo.KeyFrame(top_endoff_frame, [top_off_color], lo.quad_out), - lo.KeyFrame(top_frames, [top_off_color], lo.quad_out)]) + lo.KeyFrame(0, [top_off_color], lo.quad_in), + lo.KeyFrame(top_off_frame, [top_off_color], lo.quad_in), + lo.KeyFrame(top_lowglow_frame, [fade_off_color], lo.quad_in), + lo.KeyFrame(top_glow_frame, [color], lo.quad_in), + lo.KeyFrame(top_deglow_frame, [fade_off_color], lo.quad_out), + lo.KeyFrame(top_endoff_frame, [top_off_color], lo.quad_out), + lo.KeyFrame(top_frames, [top_off_color], lo.quad_out)]) top_index = random.choice([ - led.IDX_OUTER_UPPER_MID_RIGHT, - led.IDX_OUTER_UPPER_TOP_RIGHT, - led.IDX_OUTER_UPPER_TOP_LEFT, - led.IDX_OUTER_UPPER_MID_LEFT]) + led.IDX_OUTER_UPPER_MID_RIGHT, + led.IDX_OUTER_UPPER_TOP_RIGHT, + led.IDX_OUTER_UPPER_TOP_LEFT, + led.IDX_OUTER_UPPER_MID_LEFT]) base_pattern = list(led.ALL_OFF) if period < 2.0: base_pattern[led.IDX_OUTER_UPPER_MID_RIGHT] = list(fade_off_color) @@ -293,16 +301,16 @@ class LedPattern(track.Content): """ Parameters ---------- - + patterns (list of list of 3-tuples and boolean): for each led the 3-tuple specify the rgb value and the boolean specifies whether to interpolate - + length (float): num secs to play this animation if inf then play forever. - + frequency (int): frame rate - + hold (bool): If true, hold the last frame rather than looping """ @@ -322,24 +330,25 @@ def play(self, done_cb=None): p.start() return p - def set_length(self, l): - self._length = l + def set_length(self, length): + self._length = length def length(self): return self._length def __add__(self, other): """ - Adds two animated sequences. - - Frequencies have to match and if either has inf length then the - result will have inf length. - - Only the second pattern can have hold true + Adds two animated sequences. + Frequencies have to match and if either has inf length then the + result will have inf length. + + Only the second pattern can have hold true """ joined_pat = self._patterns + other._patterns if other._frequency != self._frequency: - raise TypeError(('Tried to add LedPattern object with different frequencies ({} and {})').format(self._frequency, other._frequency)) + raise TypeError( + ('Tried to add LedPattern object with different frequencies ({} and {})').format(self._frequency, + other._frequency)) if self._hold: raise TypeError('Tried to add to LedPattern which holds') if math.isinf(other._length) or math.isinf(self._length): @@ -355,12 +364,13 @@ class Pulse(LedPattern): def __init__(self, lights_svc, pattern, pulse_frequency, length): super(Pulse, self).__init__(lights_svc, [pattern, - Lights.ALL_OFF], length=length, frequency=pulse_frequency * 2) + Lights.ALL_OFF], length=length, frequency=pulse_frequency * 2) self._pulse_frequency = pulse_frequency class Flash(LedPattern): def __init__(self, lights_svc, pattern, pulse_frequency): - super(Flash, self).__init__(lights_svc, [pattern, Lights.ALL_OFF], length=1.0 / pulse_frequency, frequency=pulse_frequency * 2) - self._pulse_frequency = pulse_frequency \ No newline at end of file + super(Flash, self).__init__(lights_svc, [pattern, Lights.ALL_OFF], length=1.0 / pulse_frequency, + frequency=pulse_frequency * 2) + self._pulse_frequency = pulse_frequency diff --git a/kuri_api/src/kuri_api/anim/primitives/movies.py b/kuri_api/src/kuri_api/anim/primitives/movies.py index e0a4104..4f0e33b 100644 --- a/kuri_api/src/kuri_api/anim/primitives/movies.py +++ b/kuri_api/src/kuri_api/anim/primitives/movies.py @@ -1,9 +1,9 @@ from PIL import Image +from assets import config from assets import memoize from assets import mov_to_pixels, mov_to_wav -from assets import config -import os + class Movies(object): @@ -19,7 +19,7 @@ def to_animated(self, mov_name, loop=False): def to_sound(self, mov_name): return self.sound.open(mov_to_wav(mov_name)) - @memoize(lambda : config.get_assets_path()) + @memoize(lambda: config.get_assets_path()) def get_pixels(self, filename): r""" \param filename: the animated gif file to extract the pixels from @@ -31,18 +31,18 @@ def get_pixels(self, filename): """ gif = Image.open(filename) pixels = [ - (256, 256), - (386, 255), - (320, 144), - (192, 144), - (128, 258), - (192, 366), - (320, 366)] + (256, 256), + (386, 255), + (320, 144), + (192, 144), + (128, 258), + (192, 366), + (320, 366)] led_frames = [] fps = None for f in frames(gif): pal = palette(gif.getpalette()) - led_frames.append(([ pal[gif.getpixel(p)] for p in pixels ], True)) + led_frames.append(([pal[gif.getpixel(p)] for p in pixels], True)) fps = 1000.0 / f.info['duration'] return self.lights.Animated(led_frames, fps, len(led_frames) / fps) @@ -69,4 +69,4 @@ def palette(p): \param p: a flat list of [r, g, b, r, g, b, ...] \output : a list of tuples [(r, g, b), (r, g, b), ...] """ - return zip(p[0::3], p[1::3], p[2::3]) \ No newline at end of file + return zip(p[0::3], p[1::3], p[2::3]) diff --git a/kuri_api/src/kuri_api/anim/primitives/reactive_light/__init__.py b/kuri_api/src/kuri_api/anim/primitives/reactive_light/__init__.py index fc80254..2ae2839 100644 --- a/kuri_api/src/kuri_api/anim/primitives/reactive_light/__init__.py +++ b/kuri_api/src/kuri_api/anim/primitives/reactive_light/__init__.py @@ -1 +1 @@ -pass \ No newline at end of file +pass diff --git a/kuri_api/src/kuri_api/anim/primitives/reactive_light/dance_light.py b/kuri_api/src/kuri_api/anim/primitives/reactive_light/dance_light.py index 1f809ce..e00c5f1 100644 --- a/kuri_api/src/kuri_api/anim/primitives/reactive_light/dance_light.py +++ b/kuri_api/src/kuri_api/anim/primitives/reactive_light/dance_light.py @@ -1,15 +1,19 @@ -import random, threading, rospy -from numpy import interp -from kuri_api.lights import Lights +import random +import rospy +import threading + from assets import mov_to_pixels +from kuri_api.lights import Lights from kuri_api.utils.dance import get_bpm_range from kuri_api.utils.rate import Rate +from numpy import interp + class MusicLedPlayer(threading.Thread): """ Specialized thread (mocks track player's interface) for realtime LED control during music playback. - + This pattern picks from 6 random snake animations and picks a random color for the snake. The snake runs around the chest LED over a blue background. @@ -143,12 +147,12 @@ def _scale_color(self, pixel): Scales a snake color to an intensity. """ return ( - int(pixel[0] / 255.0 * self._current_snake_color[0]), - int(pixel[1] / 255.0 * self._current_snake_color[1]), - int(pixel[2] / 255.0 * self._current_snake_color[2])) + int(pixel[0] / 255.0 * self._current_snake_color[0]), + int(pixel[1] / 255.0 * self._current_snake_color[1]), + int(pixel[2] / 255.0 * self._current_snake_color[2])) def _framerate_for_bpm(self, bpm): """ Maps a bpm to an LED update framerate. """ - return int(interp(bpm, get_bpm_range(), self.FRAMERATE_RANGE)) \ No newline at end of file + return int(interp(bpm, get_bpm_range(), self.FRAMERATE_RANGE)) diff --git a/kuri_api/src/kuri_api/anim/primitives/reactive_light/listening_light.py b/kuri_api/src/kuri_api/anim/primitives/reactive_light/listening_light.py index e976214..f7aae24 100644 --- a/kuri_api/src/kuri_api/anim/primitives/reactive_light/listening_light.py +++ b/kuri_api/src/kuri_api/anim/primitives/reactive_light/listening_light.py @@ -1,12 +1,16 @@ -import threading, rospy -from numpy import clip -from kuri_api.lights import Lights +import logging +import rospy +import threading + from assets import mov_to_pixels +from kuri_api.lights import Lights from kuri_api.utils.pulse_utils import PeakMonitor from kuri_api.utils.rate import Rate -import logging +from numpy import clip + logger = logging.getLogger(__name__) + class ListeningLedPlayer(threading.Thread): """ Specialized thread (mocks track player's interface) for realtime LED @@ -22,11 +26,11 @@ class ListeningLedPlayer(threading.Thread): STAGE_INTRO = 0 STAGE_REACT = 1 REACTIVE_LEDS = [ - Lights.IDX_CENTER, - Lights.IDX_INNER_BOTTOM_LEFT, - Lights.IDX_INNER_BOTTOM_RIGHT, - Lights.IDX_INNER_UPPER_RIGHT, - Lights.IDX_INNER_UPPER_LEFT] + Lights.IDX_CENTER, + Lights.IDX_INNER_BOTTOM_LEFT, + Lights.IDX_INNER_BOTTOM_RIGHT, + Lights.IDX_INNER_UPPER_RIGHT, + Lights.IDX_INNER_UPPER_LEFT] def __init__(self, content, chestlight): super(ListeningLedPlayer, self).__init__() @@ -41,7 +45,8 @@ def __init__(self, content, chestlight): self._num_frames_intro = len(self._intro_pixels) self._level = 0 self._last_display_level = 0 - self._peak_monitor = PeakMonitor(source_name=self.MIC_SOURCE, source_chans=self.MIC_CHANNELS, window_hz=self.WINDOW_SIZE) + self._peak_monitor = PeakMonitor(source_name=self.MIC_SOURCE, source_chans=self.MIC_CHANNELS, + window_hz=self.WINDOW_SIZE) def cancel(self): self._peak_monitor.shutdown() @@ -114,10 +119,10 @@ def _apply_reactive(self, pattern, level): that. Loud, direct voice usually gets over 0.1 Spike instantly but decay over time """ - DECAY_MAX = 0.035 + decay_max = 0.035 new_level = clip(level * 2.9, 0.0, 1.0) - if new_level < self._last_display_level - DECAY_MAX: - new_level = self._last_display_level - DECAY_MAX + if new_level < self._last_display_level - decay_max: + new_level = self._last_display_level - decay_max for led in self.REACTIVE_LEDS: pattern[led] = self._color_for_level(new_level) @@ -129,6 +134,6 @@ def _color_for_level(self, level): Scales the reactive listening color by the current sound level. """ return ( - int(self.HI_COLOR[0] * level), - int(self.HI_COLOR[1] * level), - int(self.HI_COLOR[2] * level)) \ No newline at end of file + int(self.HI_COLOR[0] * level), + int(self.HI_COLOR[1] * level), + int(self.HI_COLOR[2] * level)) diff --git a/kuri_api/src/kuri_api/anim/primitives/sound.py b/kuri_api/src/kuri_api/anim/primitives/sound.py index 8561b82..d207bbe 100644 --- a/kuri_api/src/kuri_api/anim/primitives/sound.py +++ b/kuri_api/src/kuri_api/anim/primitives/sound.py @@ -1,18 +1,22 @@ -import os, threading +import os +import threading + +from assets import config from kuri_api.anim import track from kuri_api.sound import WaveFile -from assets import config + sounds_path = config.get_sounds_path() + class Sound(object): """ Top-level container for sound primitives - + Parameters ---------- - + sounds_svc: sound service - + Example ------- t = Track() @@ -52,10 +56,10 @@ def cancel(self, timeout=1.0): class SoundFile(track.Content): """ Class which loads a sound from a filename and plays it. - + Parameters ---------- - + sounds_svc: sound service filename: str, name of file to play """ @@ -80,4 +84,4 @@ def length(self): return self.wav.duration def __str__(self): - return str(self.wav) \ No newline at end of file + return str(self.wav) diff --git a/kuri_api/src/kuri_api/anim/primitives/wheels.py b/kuri_api/src/kuri_api/anim/primitives/wheels.py index 1af5fa7..9c03f04 100644 --- a/kuri_api/src/kuri_api/anim/primitives/wheels.py +++ b/kuri_api/src/kuri_api/anim/primitives/wheels.py @@ -1,12 +1,15 @@ -import itertools as it, threading +import itertools as it +import threading + from geometry_msgs.msg import Twist from geometry_msgs.msg import Vector3 from kuri_api.anim import track + class WheelMotions: """ Top-level container for wheel motion primitives - + Parameters ---------- wheels: wheel service @@ -44,12 +47,12 @@ def trig_profile(length): r""" A triangular velocity profile going from 0.0 to 1.0 and then back to 0.0 - + \params length: number of points in the profile """ points = [] - points += [ 2.0 * x / (length - 1) for x in range(length / 2) ] - points += [ 2.0 - 2.0 * x / (length - 1) for x in range(length / 2, length) ] + points += [2.0 * x / (length - 1) for x in range(length / 2)] + points += [2.0 - 2.0 * x / (length - 1) for x in range(length / 2, length)] return points @@ -90,7 +93,7 @@ def run(self): if self._wheel_svc is None: return with self._wheel_svc as (wheels): - traj = [ (i * self._content._interval, t.linear.x, t.angular.z) for i, t in enumerate(self._content._twists) ] + traj = [(i * self._content._interval, t.linear.x, t.angular.z) for i, t in enumerate(self._content._twists)] wheels.send_trajectory(traj) self._signal_cancel.wait(self._content.length()) if self._done_cb and not self._signal_cancel.is_set(): @@ -161,7 +164,8 @@ def run(self): duration -= self.FIXED_ACCEL_TIME linear_velocity = arc_len / duration linear_velocity += linear_velocity * self.VEL_COMP - wheels.arc_move(angle=angle, angular_velocity=angular_velocity, arc_len=arc_len, linear_velocity=linear_velocity, duration=duration) + wheels.arc_move(angle=angle, angular_velocity=angular_velocity, arc_len=arc_len, + linear_velocity=linear_velocity, duration=duration) return def _done(self, msg): @@ -177,7 +181,7 @@ def cancel(self): class RotateMotion(track.Content): """ - A basic rotation motion object. + A basic rotation motion object. """ def __init__(self): @@ -245,8 +249,8 @@ def cancel(self): class Inch(WheelMotion): """ - Using a triangular velocity profile, go straight - with the given speed for the given time + Using a triangular velocity profile, go straight + with the given speed for the given time """ def __init__(self, speed, length): @@ -260,8 +264,8 @@ def __init__(self, speed, length): class Rotate(WheelMotion): """ - Using a triangular velocity profile, turn in place - with the given speed for the given time + Using a triangular velocity profile, turn in place + with the given speed for the given time """ def __init__(self, speed, length): @@ -306,7 +310,7 @@ def __init__(self, direction=1): self._direction = direction self._interval = 0.05 dilate = 1.0 - self._times = [ t * dilate for t in [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4] ] + self._times = [t * dilate for t in [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]] self._speeds = [2.5, -5.0, 5.0, -4.0, 4.0, -2.0, 2.0, -1.0] self._twists = self._wiggle_twists() @@ -314,8 +318,8 @@ def _wiggle_twists(self): gain = self._direction trajs = [] for t, s in zip(self._times, self._speeds): - trajs.append([ Twist(angular=Vector3(0, 0, gain * p * s)) for p in trig_profile(int(t / self._interval)) - ]) + trajs.append([Twist(angular=Vector3(0, 0, gain * p * s)) for p in trig_profile(int(t / self._interval)) + ]) return it.chain(*trajs) @@ -365,4 +369,4 @@ def _done(self, msg): self._done_cb() def cancel(self): - self.join() \ No newline at end of file + self.join() diff --git a/kuri_api/src/kuri_api/anim/track.py b/kuri_api/src/kuri_api/anim/track.py index 27ecea0..9c2ed77 100644 --- a/kuri_api/src/kuri_api/anim/track.py +++ b/kuri_api/src/kuri_api/anim/track.py @@ -1,4 +1,6 @@ -import abc, threading as tr, time +import abc +import threading as tr +import time class Content(object): @@ -242,4 +244,4 @@ def cancel(self, timeout=1.0): with self._cv: self._cv.notify_all() self.join(timeout) - assert not self.is_alive(), ('could not cancel: {}').format(self._content_obj) \ No newline at end of file + assert not self.is_alive(), ('could not cancel: {}').format(self._content_obj) diff --git a/kuri_api/src/kuri_api/base.py b/kuri_api/src/kuri_api/base.py index 0cd16d1..1ac4fa4 100644 --- a/kuri_api/src/kuri_api/base.py +++ b/kuri_api/src/kuri_api/base.py @@ -1,16 +1,16 @@ #! /usr/bin/env python +import copy +import math +import threading + import actionlib +import mobile_base_driver.msg as mbdm +import nav_msgs.msg._Odometry import rospy -import math -import copy import rospy.rostime -import tf.transformations as tft from geometry_msgs.msg import Twist -import nav_msgs.msg._Odometry -import mobile_base_driver.msg as mbdm -import threading -from kuri_api.utils import Mux, MuxChannel from kuri_api.utils import Events +from kuri_api.utils import Mux, MuxChannel def normalize_angle_positive(angle): @@ -24,7 +24,7 @@ def normalize_angle(angle): """ pos = normalize_angle_positive(angle) if pos >= math.pi: - return pos - 2.0 * math.pi + return pos - 2.0 * math.pi return pos @@ -33,9 +33,9 @@ def quat_heading(quat): return math.atan2(2.0 * (x * y + w * z), 1.0 - 2.0 * (y * y + z * z)) -trajectory_topic ='mobile_base/commands/wheel_traj' -controller='mobile_base_controller' -switch_service='controller_manager/switch_controller', +trajectory_topic = 'mobile_base/commands/wheel_traj' +controller = 'mobile_base_controller' +switch_service = 'controller_manager/switch_controller', class Base(Events): @@ -82,14 +82,16 @@ def send_trajectory(self, traj): traj -- list of tuples (time, linear, angular) """ if not self._traj_pub: - rospy.logerr("Tried to send a trajectory in simulation, but this functionality is only present on the real robot.") + rospy.logerr( + "Tried to send a trajectory in simulation, but this functionality is only present on the real robot.") return t = mbdm.WheelTraj() for p in traj: - t.points.append(mbdm.WheelTrajPoint(time_from_start=rospy.Duration(p[0]), linear_vel=p[1], angular_vel=p[2])) + t.points.append( + mbdm.WheelTrajPoint(time_from_start=rospy.Duration(p[0]), linear_vel=p[1], angular_vel=p[2])) self._traj_pub.publish(t) - + def go_forward(self, distance, speed): """Moves the robot a certain distance. @@ -106,11 +108,10 @@ def go_forward(self, distance, speed): if self.arc_move_client: # We don't want duration to be a limit, so set it to a high number self.arc_move_client.arc_move(angle=0.0, angular_velocity=0.0, arc_len=distance, linear_velocity=speed, - duration=1000.0, done_cb=lambda : self.arc_event('done')) + duration=1000.0, done_cb=lambda: self.arc_event('done')) return - # rospy.sleep until the base has received at least one message on /odom while self.no_odom_received and not rospy.is_shutdown(): rospy.loginfo_throttle(10, "Waiting for odom message before moving...") @@ -128,10 +129,11 @@ def go_forward(self, distance, speed): p = min(speed, speed * distance_error + 0.1) self.move(direction * p, 0) # We're controlling the distance that the robot travels, trying to make it as close to abs(distance) as possible - distance_error = abs(distance) - math.sqrt(((self.latest_pose.x - start_pose.x) ** 2)+((self.latest_pose.y - start_pose.y) ** 2)) + distance_error = abs(distance) - math.sqrt( + ((self.latest_pose.x - start_pose.x) ** 2) + ((self.latest_pose.y - start_pose.y) ** 2)) rate.sleep() self.stop() - + def rotate_by(self, angular_distance, velocity, duration): """Rotates the robot a certain angle. @@ -142,19 +144,19 @@ def rotate_by(self, angular_distance, velocity, duration): """ if self.arc_move_client: - self.arc_move_client.arc_move(angle=angular_distance, angular_velocity=velocity, arc_len=0.0, linear_velocity=0.0, - duration=duration, done_cb=lambda : self.arc_event('done')) + self.arc_move_client.arc_move(angle=angular_distance, angular_velocity=velocity, arc_len=0.0, + linear_velocity=0.0, + duration=duration, done_cb=lambda: self.arc_event('done')) return - # rospy.sleep until the base has received at least one message on /odom while self.no_odom_received and not rospy.is_shutdown(): rospy.loginfo_throttle(10, "Waiting for odom message before moving...") rospy.sleep(0.3) - start_yaw = normalize_angle_positive(quat_heading(self.latest_odom.pose.pose.orientation)) - last_yaw = start_yaw - target_yaw = normalize_angle_positive(start_yaw + angular_distance) + start_yaw = normalize_angle_positive(quat_heading(self.latest_odom.pose.pose.orientation)) + last_yaw = start_yaw + target_yaw = normalize_angle_positive(start_yaw + angular_distance) # How much we have left to go. When we haven't moved, we're either # already spot on, or the error is the angular distance provided in the command @@ -162,9 +164,9 @@ def rotate_by(self, angular_distance, velocity, duration): # We'll always turn in the direction of the command, even if it would be # shorter to go the other way. - # This will cause issues if we overshoot, because we'll just go back aroud + # This will cause issues if we overshoot, because we'll just go back around # the long way. - direction = -1 if angular_distance < 0 else 1 + direction = -1 if angular_distance < 0 else 1 rate = rospy.Rate(50) # We'll tolerate an error slightly smaller than a degree while yaw_error > 0.01 and not rospy.is_shutdown(): @@ -281,8 +283,8 @@ def shutdown(self): self.ac = None return -class BaseMux(Mux): +class BaseMux(Mux): class Channel(Base, MuxChannel): class __metaclass__(Base.__metaclass__, MuxChannel.__metaclass__): @@ -344,19 +346,19 @@ class __metaclass__(Events.__metaclass__, Mux.__metaclass__): pass priority = [ - 'nav', - 'teleop', - 'romoji', - 'safety'] + 'nav', + 'teleop', + 'romoji', + 'safety'] def __init__(self, priority=None): Mux.__init__(self) priority = priority or self.priority self.safety = self.Channel(self, 'safety', self.priority.index('safety') or -1) self.teleop = self.Channel(self, 'teleop', self.priority.index('teleop') or -1) - self.nav = self.Channel(self, 'nav', self.priority.index('nav') or -1,) + self.nav = self.Channel(self, 'nav', self.priority.index('nav') or -1, ) self.animations = self.Channel(self, 'animations', self.priority.index('romoji') or -1) def shutdown(self): for channel in [self.safety, self.teleop, self.nav, self.romoji]: - channel.shutdown() \ No newline at end of file + channel.shutdown() diff --git a/kuri_api/src/kuri_api/head.py b/kuri_api/src/kuri_api/head.py index c7085cd..5331a6f 100644 --- a/kuri_api/src/kuri_api/head.py +++ b/kuri_api/src/kuri_api/head.py @@ -1,11 +1,15 @@ +import logging +import math + import actionlib +import control_msgs.msg +import rospy +import trajectory_msgs.msg +from actionlib.action_client import CommState from actionlib_msgs.msg import GoalStatus +from kuri_api.utils import Mux, MuxChannel from std_msgs.msg import Header -from actionlib.action_client import CommState -import control_msgs.msg, rospy, trajectory_msgs.msg -from kuri_api.utils import Mux, MuxChannel, Events -import math -import logging + def _fill_traj_blanks(pts, values): """ filter a trajectory by forward propagating missing values @@ -21,8 +25,8 @@ def _fill_traj_blanks(pts, values): pt = pts[0] vals = tuple((x if 1 else y for x, y in zip(pt[1:], values) if x is not None)) return [ - ( - pt[0],) + vals] + _fill_traj_blanks(pts[1:], vals) + ( + pt[0],) + vals] + _fill_traj_blanks(pts[1:], vals) def _merge_traj_points(pts): @@ -35,7 +39,7 @@ def filt(lst): if lst[0][0] == lst[1][0]: return filt([mrg(lst[0], lst[1])] + lst[2:]) return [ - lst[0]] + filt(lst[1:]) + lst[0]] + filt(lst[1:]) def mrg(fst, sec): vals = tuple((x if x is not None else y for x, y in zip(sec[1:], fst[1:]))) @@ -43,6 +47,7 @@ def mrg(fst, sec): return filt(pts) + class Head(object): JOINT_PAN = 'head_1_joint' JOINT_TILT = 'head_2_joint' @@ -103,21 +108,17 @@ def eyes_to(self, radians, duration=1.0, feedback_cb=None, done_cb=None): """ Moves the robot's eye lids to the specified location in the duration specified - :param radians: The eye position. Expected to be between HeadClient.EYES_HAPPY and HeadClient.EYES_CLOSED - :param duration: The amount of time to take to get the eyes to the specified location. - :param feedback_cb: Same as send_trajectory's feedback_cb - :param done_cb: Same as send_trajectory's done_cb """ point = trajectory_msgs.msg.JointTrajectoryPoint([ - radians], [], [], [], duration) + radians], [], [], [], duration) trajectory = trajectory_msgs.msg.JointTrajectory(joint_names=[ - self.JOINT_EYES], points=[point]) + self.JOINT_EYES], points=[point]) return self.send_trajectory(trajectory, feedback_cb=feedback_cb, done_cb=done_cb) def eyes_sequence(self, seq, **kwargs): @@ -129,14 +130,15 @@ def eyes_sequence(self, seq, **kwargs): pts.sort(key=lambda pt: pt[0]) pts = _merge_traj_points(pts) traj = trajectory_msgs.msg.JointTrajectory(joint_names=[ - self.JOINT_EYES], points=[ trajectory_msgs.msg.JointTrajectoryPoint([pos], [], [], [], time) for time, pos in pts - ]) + self.JOINT_EYES], + points=[trajectory_msgs.msg.JointTrajectoryPoint([pos], [], [], [], time) for time, pos in pts + ]) return self.send_trajectory(traj, **kwargs) def is_done(self): active = { - GoalStatus.PENDING, GoalStatus.RECALLING, - GoalStatus.ACTIVE, GoalStatus.PREEMPTING} + GoalStatus.PENDING, GoalStatus.RECALLING, + GoalStatus.ACTIVE, GoalStatus.PREEMPTING} if self._head_gh: if self._head_gh.get_goal_status() in active: return False @@ -149,25 +151,20 @@ def pan_and_tilt(self, pan, tilt, duration=1.0, feedback_cb=None, done_cb=None): """ Moves the robot's head to the point specified in the duration specified - :param pan: The pan - expected to be between HeadClient.PAN_LEFT and HeadClient.PAN_RIGHT - :param tilt: The tilt - expected to be between HeadClient.TILT_UP and HeadClient.TILT_DOWN - :param duration: The amount of time to take to get the head to the specified location. - :param feedback_cb: Same as send_trajectory's feedback_cb - :param done_cb: Same as send_trajectory's done_cb """ point = trajectory_msgs.msg.JointTrajectoryPoint([ - pan, tilt], [], [], [], duration) + pan, tilt], [], [], [], duration) trajectory = trajectory_msgs.msg.JointTrajectory(joint_names=[ - self.JOINT_PAN, self.JOINT_TILT], points=[ - point]) + self.JOINT_PAN, self.JOINT_TILT], points=[ + point]) return self.send_trajectory(traj=trajectory, feedback_cb=feedback_cb, done_cb=done_cb) def pan_and_tilt_sequence(self, pans, tilts, **kwargs): @@ -182,19 +179,18 @@ def pan_and_tilt_sequence(self, pans, tilts, **kwargs): pts = _merge_traj_points(pts) pts = _fill_traj_blanks(pts, [self.cur_pan, self.cur_tilt]) traj = trajectory_msgs.msg.JointTrajectory(joint_names=[ - self.JOINT_PAN, self.JOINT_TILT], points=[ trajectory_msgs.msg.JointTrajectoryPoint([pan_pt, tilt_pt], [], [], [], time) for time, pan_pt, tilt_pt in pts - ]) + self.JOINT_PAN, self.JOINT_TILT], + points=[trajectory_msgs.msg.JointTrajectoryPoint([pan_pt, tilt_pt], [], [], [], time) for + time, pan_pt, tilt_pt in pts + ]) return self.send_trajectory(traj, **kwargs) def send_trajectory(self, traj, feedback_cb=None, done_cb=None): """ Sends the specified trajectories to the head and eye controllers - :param traj: A trajectory_msgs.msg.JointTrajectory. joint_names are expected to match HeadClient.JOINT_PAN, JOINT_TILT and JOINT_EYES - :param feedback_cb: A callable that takes one parameter - the feedback - :param done_cb: A callable that takes two parameters - the goal status the goal handle result """ @@ -240,7 +236,7 @@ def pose_stamped_to_pan_and_tilt(self, pose_stamped): """ pose_in_base_frame = self._tf.transform_pose_stamped(pose_stamped, 'base_footprint') if pose_in_base_frame is None: - logging.error(("Couldn't transform from frame {} to base_footprint!").format(pose_stamped.header.frame_id)) + logging.error("Couldn't transform from frame {} to base_footprint!".format(pose_stamped.header.frame_id)) return False return self.position_to_pan_and_tilt(self.JOINT_HEIGHT, pose_in_base_frame.pose.position) @@ -309,20 +305,19 @@ def wait_for_done(self, timeout): class HeadMux(Mux): - class Channel(Head, MuxChannel): def __init__(self, mux, name, priority, js, tf, namespace=None): Head.__init__(self, js, tf) MuxChannel.__init__(self, mux, name, priority) - send_trajectory = Mux.protect(fail=False) + send_trajectory = Mux.Protect(fail=False) priority = [ - 'behavior', - 'teleop', - 'animations', - 'safety'] + 'behavior', + 'teleop', + 'animations', + 'safety'] def __init__(self, js, tf, priority=None): super(HeadMux, self).__init__() diff --git a/kuri_api/src/kuri_api/joint_states.py b/kuri_api/src/kuri_api/joint_states.py index 8dcca67..0a7a7b7 100644 --- a/kuri_api/src/kuri_api/joint_states.py +++ b/kuri_api/src/kuri_api/joint_states.py @@ -1,6 +1,9 @@ -import threading, rospy +import rospy +import threading + from sensor_msgs.msg import JointState + class JointStates(object): """ JointStates keeps track of the latest position of the robot's eyes, @@ -55,4 +58,6 @@ def update(self, joint_state): self._eye_pos = joint_pos['eyelids_joint'] def _is_identical(self, joint_pos): - return self._right_wheel_pos == joint_pos['wheel_right_joint'] and self._left_wheel_pos == joint_pos['wheel_left_joint'] and self._pan_pos == joint_pos['head_1_joint'] and self._tilt_pos == joint_pos['head_2_joint'] and self._eye_pos == joint_pos['eyelids_joint'] \ No newline at end of file + return self._right_wheel_pos == joint_pos['wheel_right_joint'] and self._left_wheel_pos == joint_pos[ + 'wheel_left_joint'] and self._pan_pos == joint_pos['head_1_joint'] and self._tilt_pos == joint_pos[ + 'head_2_joint'] and self._eye_pos == joint_pos['eyelids_joint'] diff --git a/kuri_api/src/kuri_api/lights.py b/kuri_api/src/kuri_api/lights.py index f8f0ff9..42c4636 100644 --- a/kuri_api/src/kuri_api/lights.py +++ b/kuri_api/src/kuri_api/lights.py @@ -1,7 +1,7 @@ import rospy -from mobile_base_driver.msg import ChestLeds -from mobile_base_driver.msg import Led from kuri_api.utils.mux import Mux, MuxChannel +from mobile_base_driver.msg import ChestLeds, Led + class Lights(object): """ @@ -56,7 +56,7 @@ class Lights(object): LED_MID_RING = range(IDX_INNER_BOTTOM_LEFT, IDX_INNER_LEFT + 1) LED_OUTER_RING = range(IDX_OUTER_BOTTOM_MID_LEFT, IDX_OUTER_UPPER_MID_LEFT + 1) ALL_OFF = [ - OFF] * NUM_LEDS + OFF] * NUM_LEDS ALL_ON = [ON] * NUM_LEDS ALL_HALF = [HALF] * NUM_LEDS @@ -72,7 +72,7 @@ def shutdown(self): self._light_pub.unregister() def put_pixels(self, pixels): - """ set the LEDs to the values in pixels. + """ set the LEDs to the values in pixels. :param pixels: an array of 3-ary tuples """ self._last_pixels = pixels @@ -90,7 +90,6 @@ def off(self): class LightsMux(Mux): - class Channel(Lights, MuxChannel): def __init__(self, mux, name, priority): @@ -100,16 +99,16 @@ def __init__(self, mux, name, priority): def on_release(self): self.off() - put_pixels = Mux.protect(fail=False) - off = Mux.protect(fail=False) + put_pixels = Mux.Protect(fail=False) + off = Mux.Protect(fail=False) priority = [ - 'emotion', - 'power_status', - 'performance', - 'teleop', - 'listening', - 'romoji'] + 'emotion', + 'power_status', + 'performance', + 'teleop', + 'listening', + 'romoji'] def __init__(self, priority=None): super(LightsMux, self).__init__() @@ -129,4 +128,4 @@ def shutdown(self): self.listening = None self.romoji = None del self._channels[:] - return \ No newline at end of file + return diff --git a/kuri_api/src/kuri_api/listener.py b/kuri_api/src/kuri_api/listener.py index a52a103..d5c6e48 100644 --- a/kuri_api/src/kuri_api/listener.py +++ b/kuri_api/src/kuri_api/listener.py @@ -1,5 +1,7 @@ -import logging, threading, json, rospy -from std_msgs.msg import Empty, String +import logging +import rospy +import threading + from audio_msgs.msg import Awake, Exchange from audio_msgs.srv import Stat, WakeUp, Snooze from kuri_api.utils import Events @@ -24,7 +26,6 @@ def __repr__(self): class Listener(Events): """ Used to listen for: - - a wake word (e.g. the name of the robot) while asleep - commands to execute while awake @@ -42,7 +43,6 @@ def on_voice_command(msg): listener = Listener() listener.wake_event.connect(on_voice_command) listener.voice_command_event.connect(on_voice_command) - """ NAMESPACE = 'audio' PROCESS_DELAY = 4 @@ -69,8 +69,9 @@ def shutdown(self): def wait_until_ready(self, timeout=0): return wait_for_servers([ - self._stat, self._wake_up, self._snooze], timeout=timeout) and wait_for_topics([ - self._awake_sub, self._exchange_sub], timeout=timeout, poll=0.1) + self._stat, self._wake_up, self._snooze], timeout=timeout) and wait_for_topics( + [self._awake_sub, self._exchange_sub], + timeout=timeout, poll=0.1) @property def awake_timeout(self): @@ -110,13 +111,14 @@ def _on_exchange(self, exchange): if len(exchange.commands) > 0 and len(exchange.commands[0].params) == 0 and exchange.transcription != "": name = 'custom' params = {"transcript": exchange.transcription} - elif len(exchange.commands) > 0 and len(exchange.commands[0].params) > 0 and len(exchange.commands[0].params[0].k) > 0 and len(exchange.commands[0].params[0].v) > 0: + elif len(exchange.commands) > 0 and len(exchange.commands[0].params) > 0 and len( + exchange.commands[0].params[0].k) > 0 and len(exchange.commands[0].params[0].v) > 0: command = exchange.commands[0] name = command.name.replace('Command', '').replace('Kuri', '').lower() params = {param.k: param.v for param in command.params} params["transcript"] = exchange.transcription else: - #print("empty exchange") + # print("empty exchange") return command = VoiceCommand(name=name, params=params) - self.voice_command_event(command) \ No newline at end of file + self.voice_command_event(command) diff --git a/kuri_api/src/kuri_api/power.py b/kuri_api/src/kuri_api/power.py index db1897a..b9bde19 100644 --- a/kuri_api/src/kuri_api/power.py +++ b/kuri_api/src/kuri_api/power.py @@ -1,11 +1,9 @@ +import logging import rospy -from kuri_api.utils import Events import mobile_base_driver.msg - -import logging, rospy +from kuri_api.utils import Events from numpy import clip -import mobile_base_driver.msg logger = logging.getLogger(__name__) @@ -71,7 +69,7 @@ def _power_cb(self, msg): self._check_for_low_power(msg.battery) self._check_for_critical_power(msg.battery) if dock_changed or last_power_level != self._power_level: - #self._status_srv.log_power(self.power_status(), self._power_level) + # self._status_srv.log_power(self.power_status(), self._power_level) pass def _check_docking_events(self, msg): @@ -87,13 +85,13 @@ def _check_docking_events(self, msg): self._last_docked_time = rospy.get_time() self.docked_event('docked') logger.info('docked') - #self._anim.cancel() + # self._anim.cancel() return True if self._is_docked and not msg.dock_present: self._is_docked = False self.undocked_event('undocked') if self._is_critical and not self._anim.is_playing: - pass#self._anim.critical_battery() + pass # self._anim.critical_battery() return True return False @@ -112,11 +110,11 @@ def _check_for_critical_power(self, battery_msg): if not self._is_critical and battery_msg.rounded_pct < self.critical_power: self._is_critical = True if not self._is_docked: - #self._anim.critical_battery() + # self._anim.critical_battery() self.critical_power_event('battery_critical') if self._is_critical and battery_msg.rounded_pct > self.critical_power: self._is_critical = False - pass#self._anim.cancel() + pass # self._anim.cancel() return self._is_critical def _check_for_low_power(self, battery_msg): @@ -136,4 +134,4 @@ def _check_for_low_power(self, battery_msg): def shutdown(self): if self.dock_sub: - self.dock_sub.unregister() \ No newline at end of file + self.dock_sub.unregister() diff --git a/kuri_api/src/kuri_api/sound.py b/kuri_api/src/kuri_api/sound.py index f8d25d5..3e8009e 100644 --- a/kuri_api/src/kuri_api/sound.py +++ b/kuri_api/src/kuri_api/sound.py @@ -1,4 +1,11 @@ -import abc, collections, logging, math, sys, threading, wave, alsaaudio +import abc +import alsaaudio +import collections +import logging +import math +import sys +import threading +import wave logger = logging.getLogger(__name__) @@ -267,4 +274,4 @@ def run(self): break self._pcm.write(samples) - return \ No newline at end of file + return diff --git a/kuri_api/src/kuri_api/utils/__init__.py b/kuri_api/src/kuri_api/utils/__init__.py index 69a2fe9..2b815fa 100644 --- a/kuri_api/src/kuri_api/utils/__init__.py +++ b/kuri_api/src/kuri_api/utils/__init__.py @@ -1,2 +1,2 @@ from .event import Events, EventSource, EventsMeta, EventField -from .mux import Mux, MuxChannel, MuxChannelMeta \ No newline at end of file +from .mux import Mux, MuxChannel, MuxChannelMeta diff --git a/kuri_api/src/kuri_api/utils/dance/__init__.py b/kuri_api/src/kuri_api/utils/dance/__init__.py index 89a6226..9cd4635 100644 --- a/kuri_api/src/kuri_api/utils/dance/__init__.py +++ b/kuri_api/src/kuri_api/utils/dance/__init__.py @@ -1,7 +1,8 @@ from .dance_routines import choreographed_performances, dance_routines, dance_routine_names, dance_routine_pools from .dance_utils import get_bpm_range, build_dance_pose, scale_duration, DancePerformance, DanceRoutine, DancePose + __all__ = [ - 'dance_routines', 'dance_routine_names', 'dance_routine_pools', - 'choreographed_performances', - 'get_bpm_range', 'build_dance_pose', 'scale_duration', - 'DancePerformance', 'DanceRoutine', 'DancePose'] + 'dance_routines', 'dance_routine_names', 'dance_routine_pools', + 'choreographed_performances', + 'get_bpm_range', 'build_dance_pose', 'scale_duration', + 'DancePerformance', 'DanceRoutine', 'DancePose'] diff --git a/kuri_api/src/kuri_api/utils/dance/dance_routines.py b/kuri_api/src/kuri_api/utils/dance/dance_routines.py index 017f7cc..4fabd1c 100644 --- a/kuri_api/src/kuri_api/utils/dance/dance_routines.py +++ b/kuri_api/src/kuri_api/utils/dance/dance_routines.py @@ -2,123 +2,126 @@ Dance routines (pseudo-animations). """ from math import radians as rad + from kuri_api.head import Head + CHOREOGRAPHED_SONGS = {'pancake_robot': {'intro': [ - 'interested_pancake', 'full_body_bob', 'full_body_up_nod'], - 'warm_up': [ - 'full_body_groove', 'funky_alt', - 'full_body_groove_rev', 'robot', - 'full_body_groove_excited', 'moonwalk', 'full_body_up_nod', - 'full_body_bob'], - 'apex': [ - 'this_is_my_jam'], - 'cool_down': [ - 'funky', 'full_body_bob_rev', 'skate_back', - 'full_body_up_nod_rev', - 'done_dummy']}} + 'interested_pancake', 'full_body_bob', 'full_body_up_nod'], + 'warm_up': [ + 'full_body_groove', 'funky_alt', + 'full_body_groove_rev', 'robot', + 'full_body_groove_excited', 'moonwalk', 'full_body_up_nod', + 'full_body_bob'], + 'apex': [ + 'this_is_my_jam'], + 'cool_down': [ + 'funky', 'full_body_bob_rev', 'skate_back', + 'full_body_up_nod_rev', + 'done_dummy']}} + def dance_routine_pools(): """ Pools of routines to draw from when generating performances. """ pools = {'slow': {'natural': {'intro': [ - 'interested', 'interested_up', 'interested_down'], - 'warm_up': [ - 'center_head_bob', 'longbob', - 'full_body_groove', 'full_body_groove_rev', - 'full_body_up_nod', 'full_body_up_nod_rev', - 'full_body_bob', 'full_body_bob_rev'], - 'apex': [ - 'clover', 'this_is_my_jam', 'moonwalk', 'twirl'], - 'cool_down': [ - 'center_head_bob', 'longbob', - 'full_body_groove', 'full_body_groove_rev', - 'full_body_up_nod', 'full_body_up_nod_rev', - 'full_body_bob', 'full_body_bob_rev']}, - 'robot': {'intro': [ - 'interested', 'interested_up', 'interested_down'], - 'warm_up': [ - 'center_head_bob', 'full_body_bob', 'longbob', - 'full_body_groove', 'longbob', 'funky_alt'], - 'apex': [ - 'full_body_groove_excited', 'full_body_groove_excited_rev', - 'robot', 'twirl'], - 'cool_down': [ - 'center_head_bob', 'longbob', - 'full_body_up_nod', 'full_body_up_nod_rev', - 'full_body_bob', 'full_body_bob_rev']}}, - 'regular': {'natural': {'intro': [ - 'interested', 'interested_up', 'interested_down'], - 'warm_up': [ - 'center_head_bob', 'longbob', - 'full_body_bob', 'full_body_bob_rev', - 'full_body_groove', 'full_body_groove_rev', - 'full_body_up_nod', 'full_body_up_nod_rev', - 'funky', 'funky_alt'], - 'apex': [ - 'clover', 'moonwalk', 'robot', - 'skate_back', 'this_is_my_jam', 'twirl', - 'full_body_groove_excited', 'full_body_groove_excited_rev'], - 'cool_down': [ - 'center_head_bob', 'longbob', - 'full_body_bob', 'full_body_bob_rev', - 'full_body_groove', 'full_body_groove_rev', - 'full_body_up_nod', 'full_body_up_nod_rev', - 'funky', 'funky_alt']}, - 'robot': {'intro': [ - 'interested', 'interested_up', 'interested_down'], - 'warm_up': [ - 'center_head_bob', 'full_body_bob', - 'full_body_groove', 'longbob', 'funky_alt', - 'full_body_groove_excited'], - 'apex': [ - 'clover', 'moonwalk', 'robot', - 'skate_back', 'this_is_my_jam', 'twirl', - 'full_body_groove_excited', 'full_body_groove_excited_rev', - 'robot', 'robot', 'robot', 'robot', 'robot'], - 'cool_down': [ - 'center_head_bob', 'longbob', - 'full_body_bob', 'full_body_bob_rev', - 'full_body_groove', 'full_body_groove_rev', - 'full_body_up_nod', 'full_body_up_nod_rev', - 'funky', 'funky_alt']}}, - 'fast': {'natural': {'intro': [ - 'interested', 'interested_up', 'interested_down'], - 'warm_up': [ - 'center_head_bob', 'longbob', - 'full_body_bob', 'full_body_bob_rev', - 'full_body_groove', 'full_body_groove_rev', - 'full_body_up_nod', 'full_body_up_nod_rev', - 'funky', 'funky_alt'], - 'apex': [ - 'clover', 'moonwalk', 'robot', - 'skate_back', 'this_is_my_jam', 'twirl', - 'full_body_groove_excited', 'full_body_groove_excited_rev'], - 'cool_down': [ - 'center_head_bob', 'longbob', - 'full_body_bob', 'full_body_bob_rev', - 'full_body_groove', 'full_body_groove_rev', - 'full_body_up_nod', 'full_body_up_nod_rev', - 'funky', 'funky_alt']}, - 'robot': {'intro': [ - 'interested', 'interested_up', 'interested_down'], - 'warm_up': [ - 'center_head_bob', 'longbob', - 'full_body_bob', 'full_body_bob_rev', - 'full_body_groove', 'full_body_groove_rev', - 'full_body_up_nod', 'full_body_up_nod_rev', - 'funky', 'funky_alt'], - 'apex': [ - 'clover', 'moonwalk', 'robot', - 'skate_back', 'this_is_my_jam', 'twirl', - 'full_body_groove_excited', 'full_body_groove_excited_rev', - 'robot', 'robot', 'robot', 'robot', 'robot'], - 'cool_down': [ - 'center_head_bob', 'longbob', - 'full_body_bob', 'full_body_bob_rev', - 'full_body_groove', 'full_body_groove_rev', - 'full_body_up_nod', 'full_body_up_nod_rev', - 'funky', 'funky_alt']}}} + 'interested', 'interested_up', 'interested_down'], + 'warm_up': [ + 'center_head_bob', 'longbob', + 'full_body_groove', 'full_body_groove_rev', + 'full_body_up_nod', 'full_body_up_nod_rev', + 'full_body_bob', 'full_body_bob_rev'], + 'apex': [ + 'clover', 'this_is_my_jam', 'moonwalk', 'twirl'], + 'cool_down': [ + 'center_head_bob', 'longbob', + 'full_body_groove', 'full_body_groove_rev', + 'full_body_up_nod', 'full_body_up_nod_rev', + 'full_body_bob', 'full_body_bob_rev']}, + 'robot': {'intro': [ + 'interested', 'interested_up', 'interested_down'], + 'warm_up': [ + 'center_head_bob', 'full_body_bob', 'longbob', + 'full_body_groove', 'longbob', 'funky_alt'], + 'apex': [ + 'full_body_groove_excited', 'full_body_groove_excited_rev', + 'robot', 'twirl'], + 'cool_down': [ + 'center_head_bob', 'longbob', + 'full_body_up_nod', 'full_body_up_nod_rev', + 'full_body_bob', 'full_body_bob_rev']}}, + 'regular': {'natural': {'intro': [ + 'interested', 'interested_up', 'interested_down'], + 'warm_up': [ + 'center_head_bob', 'longbob', + 'full_body_bob', 'full_body_bob_rev', + 'full_body_groove', 'full_body_groove_rev', + 'full_body_up_nod', 'full_body_up_nod_rev', + 'funky', 'funky_alt'], + 'apex': [ + 'clover', 'moonwalk', 'robot', + 'skate_back', 'this_is_my_jam', 'twirl', + 'full_body_groove_excited', 'full_body_groove_excited_rev'], + 'cool_down': [ + 'center_head_bob', 'longbob', + 'full_body_bob', 'full_body_bob_rev', + 'full_body_groove', 'full_body_groove_rev', + 'full_body_up_nod', 'full_body_up_nod_rev', + 'funky', 'funky_alt']}, + 'robot': {'intro': [ + 'interested', 'interested_up', 'interested_down'], + 'warm_up': [ + 'center_head_bob', 'full_body_bob', + 'full_body_groove', 'longbob', 'funky_alt', + 'full_body_groove_excited'], + 'apex': [ + 'clover', 'moonwalk', 'robot', + 'skate_back', 'this_is_my_jam', 'twirl', + 'full_body_groove_excited', 'full_body_groove_excited_rev', + 'robot', 'robot', 'robot', 'robot', 'robot'], + 'cool_down': [ + 'center_head_bob', 'longbob', + 'full_body_bob', 'full_body_bob_rev', + 'full_body_groove', 'full_body_groove_rev', + 'full_body_up_nod', 'full_body_up_nod_rev', + 'funky', 'funky_alt']}}, + 'fast': {'natural': {'intro': [ + 'interested', 'interested_up', 'interested_down'], + 'warm_up': [ + 'center_head_bob', 'longbob', + 'full_body_bob', 'full_body_bob_rev', + 'full_body_groove', 'full_body_groove_rev', + 'full_body_up_nod', 'full_body_up_nod_rev', + 'funky', 'funky_alt'], + 'apex': [ + 'clover', 'moonwalk', 'robot', + 'skate_back', 'this_is_my_jam', 'twirl', + 'full_body_groove_excited', 'full_body_groove_excited_rev'], + 'cool_down': [ + 'center_head_bob', 'longbob', + 'full_body_bob', 'full_body_bob_rev', + 'full_body_groove', 'full_body_groove_rev', + 'full_body_up_nod', 'full_body_up_nod_rev', + 'funky', 'funky_alt']}, + 'robot': {'intro': [ + 'interested', 'interested_up', 'interested_down'], + 'warm_up': [ + 'center_head_bob', 'longbob', + 'full_body_bob', 'full_body_bob_rev', + 'full_body_groove', 'full_body_groove_rev', + 'full_body_up_nod', 'full_body_up_nod_rev', + 'funky', 'funky_alt'], + 'apex': [ + 'clover', 'moonwalk', 'robot', + 'skate_back', 'this_is_my_jam', 'twirl', + 'full_body_groove_excited', 'full_body_groove_excited_rev', + 'robot', 'robot', 'robot', 'robot', 'robot'], + 'cool_down': [ + 'center_head_bob', 'longbob', + 'full_body_bob', 'full_body_bob_rev', + 'full_body_groove', 'full_body_groove_rev', + 'full_body_up_nod', 'full_body_up_nod_rev', + 'funky', 'funky_alt']}}} return pools @@ -135,468 +138,468 @@ def dance_routines(): eh = Head.EYES_HAPPY ec = Head.EYES_CLOSED en = Head.EYES_NEUTRAL - routines = {'interested': {'repeat': 2, - 'relative': True, - 'poses': [ - [ - 0, 0.15], - [ - 0, -0.1], - [ - 0, 0.15], - [ - 0, -0.1]]}, - 'interested_up': {'repeat': 2, - 'relative': True, - 'poses': [ - [ - 0.25, -0.18], - [ - 0, 0.12], - [ - -0.25, -0.18], - [ - 0, 0.12]]}, - 'interested_down': {'repeat': 2, - 'relative': True, - 'poses': [ + routines = {'interested': {'repeat': 2, + 'relative': True, + 'poses': [ [ - 0.25, 0.15], + 0, 0.15], [ - 0, -0.12], + 0, -0.1], [ - -0.25, 0.15], + 0, 0.15], [ - 0, -0.12]]}, - 'interested_pancake': {'repeat': 2, - 'poses': [ + 0, -0.1]]}, + 'interested_up': {'repeat': 2, + 'relative': True, + 'poses': [ [ - pn, -0.3], + 0.25, -0.18], [ - pn, -0.55], + 0, 0.12], [ - pn, -0.3], + -0.25, -0.18], [ - pn, -0.55]]}, - 'interested_down_pancake': {'repeat': 2, - 'poses': [ - [ - pl * 0.4, -0.4], - [ - pn, -0.65], - [ - pr * 0.4, -0.4], - [ - pn, -0.65]]}, - 'center_head_bob': {'repeat': 2, - 'poses': [ - [ - pn, td * 0.25], - [ - pn, tu * 0.2], - [ - pn, td * 0.25], - [ - pn, tu * 0.2]]}, - 'full_body_bob': {'repeat': 2, - 'poses': [ - [ - pl * 0.2, td * 0.5, 0.2], - [ - pl * 0.2, tu * 0.3, 0], - [ - pr * 0.2, td * 0.5, -0.2], - [ - pr * 0.2, tu * 0.3, 0]]}, - 'full_body_bob_rev': {'repeat': 2, - 'poses': [ - [ - pl * 0.2, td * 0.5, -0.15], - [ - pl * 0.2, tu * 0.3, 0], - [ - pr * 0.2, td * 0.5, 0.15], - [ - pr * 0.2, tu * 0.3, 0]]}, - 'full_body_up_nod': {'repeat': 2, - 'poses': [ - [ - pr * 0.2, tu * 0.6, 0.25], - [ - pr * 0.2, tu * 0.1, 0], - [ - pl * 0.2, tu * 0.5, -0.25], - [ - pl * 0.2, tu * 0.1, 0]]}, - 'full_body_up_nod_rev': {'repeat': 2, - 'poses': [ - [ - pl * 0.2, tu * 0.5, 0.2], - [ - pl * 0.2, tu * 0.2, 0], - [ - pr * 0.2, tu * 0.6, -0.2], - [ - pr * 0.2, tu * 0.1, 0]]}, - 'longbob': {'poses': [ - [ - pl * 0.7, td * 0.45, 0.05], - [ - pl * 0.7, tu * 0.2], - [ - pl * 0.7, td * 0.45], - [ - pl * 0.7, tu * 0.2], - [ - pl * 0.7, td * 0.45, 0.05], - [ - pl * 0.7, tu * 0.2], - [ - pl * 0.7, td * 0.45], - [ - pl * 0.15, tu * 0.2], - [ - pr * 0.7, td * 0.45, -0.05], - [ - pr * 0.7, tu * 0.2], - [ - pr * 0.7, td * 0.45], - [ - pr * 0.7, tu * 0.2], - [ - pr * 0.7, td * 0.45, -0.05], - [ - pr * 0.7, tu * 0.2], - [ - pr * 0.4, td * 0.45], - [ - pn, tu * 0.35]]}, - 'full_body_groove': {'randomness': ( - True, False), - 'repeat': 2, - 'poses': [ - [ - pl * 0.5, td * 0.7, 0.4, 0.0], - [ - pl * 0.5, tu * 0.2, 0.0, 0.0], - [ - pr * 0.5, td * 0.7, -0.4, 0.0], - [ - pr * 0.5, tu * 0.2, 0.0, 0.0]]}, - 'full_body_groove_rev': {'randomness': ( - True, False), - 'repeat': 2, - 'poses': [ + 0, 0.12]]}, + 'interested_down': {'repeat': 2, + 'relative': True, + 'poses': [ [ - pl * 0.5, td * 0.7, -0.4, 0.0], + 0.25, 0.15], [ - pl * 0.5, tu * 0.2, 0.0, 0.0], + 0, -0.12], [ - pr * 0.5, td * 0.7, 0.4, 0.0], + -0.25, 0.15], [ - pr * 0.5, tu * 0.2, 0.0, 0.0]]}, - 'full_body_groove_excited': {'randomness': ( - True, False), - 'repeat': 2, - 'poses': [ - [ - pl * 0.4, td * 0.6, 0.55], - [ - pl * 0.4, tu * 0.5, 0.0], - [ - pr * 0.4, td * 0.6, -0.55], - [ - pr * 0.4, tu * 0.4, 0.0]]}, - 'full_body_groove_excited_rev': {'randomness': ( - True, False), - 'repeat': 2, - 'poses': [ + 0, -0.12]]}, + 'interested_pancake': {'repeat': 2, + 'poses': [ + [ + pn, -0.3], + [ + pn, -0.55], + [ + pn, -0.3], + [ + pn, -0.55]]}, + 'interested_down_pancake': {'repeat': 2, + 'poses': [ [ - pl * 0.4, td * 0.6, -0.55], + pl * 0.4, -0.4], [ - pl * 0.4, tu * 0.5, 0.0], + pn, -0.65], [ - pr * 0.4, td * 0.6, 0.55], + pr * 0.4, -0.4], [ - pr * 0.4, tu * 0.4, 0.0]]}, - 'robot': {'poses': [ - [ - pl * 0.7, tu * 0.1, 0.0, 0], - [ - pl * 0.7, tu * 0.3, 0.4, 0], - [ - pl * 0.7, tu * 0.1, 0.4, 0], - [ - pl * 0.7, tu * 0.3, 0.4, 0], - [ - pl * 0.3, tu * 0.1, -0.3, 0.0], - [ - pr * 0.3, tu * 0.2, 0.3, 0.0], - [ - pl * 0.3, tu * 0.1, -0.3, 0.0], - [ - pr * 0.3, tu * 0.2, 0.3, 0.0], - [ - pr * 0.6, tn, -0.3, 0], - [ - pr * 0.65, tn, -0.3, 0], - [ - pr * 0.7, tn, -0.3, 0], - [ - pr * 0.75, tn, -0.3, 0], - [ - pr * 0.8, tn, -0.3, 0], - [ - pr * 0.85, tn, -0.3, 0], - [ - pr * 0.5, tn, -0.3, 0], - [ - pr * 0.1, tu * 0.7, 0.2, 0]]}, - 'funky': {'randomness': ( - True, False), - 'repeat': 2, - 'poses': [ - [ - pn, tu * 0.3, 0, 0.5], - [ - pn, td * 0.2, 0, -0.4], - [ - pn, tu * 0.3, 0, 0.5], - [ - pn, td * 0.2, 0, -0.4], - [ - pn, tu * 0.3, 0, 0.5], - [ - pn, td * 0.2, 0, -0.4], - [ - pn, tu * 0.3, 0, 0.5], - [ - pn, td * 0.2, 0, -0.4], - [ - pr, tn, 0.5, 0], - [ - pl, tn, 0.0, 0], - [ - pn, tn, -0.5, 0], - [ - pn, tu * 0.1, 0, 0]]}, - 'funky_alt': {'poses': [ - [ - pn, tu * 0.2, 0, 0.4], - [ - pn, td * 0.1, 0, 0], - [ - pn, tu * 0.3, 0, 0.4], - [ - pn, td * 0.1, 0, 0], - [ - pn, tu * 0.4, 0, 0.4], - [ - pn, td * 0.1, 0, 0], - [ - pn, tu * 0.5, 0, 0.4], - [ - pn, td * 0.1, 0, 0], - [ - pl * 0.7, td * 0.3, 0, -0.2], - [ - pl * 0.7, tu * 0.1, 0, -0.2], - [ - pr * 0.7, td * 0.5, 0, -0.2], - [ - pr * 0.7, tu * 0.2, 0, -0.2], - [ - pn, td * 0.8, 0, -0.2], - [ - pn, tu * 0.6, 0, -0.2], - [ - pn, tn, 0, -0.2], - [ - pn, tn, 0, 0]]}, - 'twirl': {'poses': [ - [ - pr * 0.3, tu * 0.3, -1.0], - [ - pr * 0.4, tu * 0.4, -1.0], - [ - pr * 0.5, tu * 0.5, -1.0], - [ - pn, td * 0.1, -1.0], - [ - pr * 0.3, tu * 0.5, -1.0], - [ - pr * 0.4, tu * 0.4, -1.0], - [ - pr * 0.5, tu * 0.3, -1.0], - [ - pn, tn, -1.0], - [ - pl * 0.3, tu * 0.3, 1.0], - [ - pl * 0.4, tu * 0.4, 1.0], - [ - pl * 0.5, tu * 0.5, 1.0], - [ - pn, td * 0.1, 1.0], - [ - pl * 0.3, tu * 0.5, 1.0], - [ - pl * 0.4, tu * 0.4, 1.0], - [ - pl * 0.5, tu * 0.3, 1.0], - [ - pn, tn, 1.0]]}, - 'this_is_my_jam': {'poses': [ - [ - pl * 0.7, tu * 0.6, 0, 0, (0, 0), eh], - [ - pr * 0.7, tu * 0.6, 0, 0, (0, 0), eh], - [ - pl * 0.7, tu * 0.6, 0, 0, (0, 0), eh], - [ - pr * 0.7, tu * 0.6, 0, 0, (0, 0), eh], - [ - pl * 0.7, tu * 0.6, 0, 0, (0, 0), ec], - [ - pr * 0.7, tu * 0.6, 0, 0, (0, 0), ec], - [ - pl * 0.7, tu * 0.6, 0, 0, (0, 0), ec], - [ - pr * 0.7, tu * 0.6, 0, 0, (0, 0), ec], - [ - pl * 0.7, tu * 0.4, 0, 0, (rad(-60), -0.1), eh], - [ - pl * 0.5, tn, 0, 0, (rad(-60), -0.1), eh], - [ - pl * 0.3, tu * 0.2, 0, 0, (rad(-60), -0.1), eh], - [ - pn, tu * 0.7, 0, 0, (rad(-60), -0.1), ec], - [ - pl * 0.5, tu * 0.7, 0.4, 0, (0, 0), ec], - [ - pl * 0.5, tu * 0.7, 0.0, 0, (0, 0), ec], - [ - pr * 0.5, tu * 0.7, -0.4, 0, (0, 0), ec], - [ - pr * 0.5, tu * 0.7, 0.0, 0, (0, 0), ec], - [ - pl * 0.5, tu * 0.7, 0.4, 0, (0, 0), ec], - [ - pl * 0.5, tu * 0.7, 0.0, 0, (0, 0), ec], - [ - pr * 0.5, tu * 0.7, -0.4, 0, (0, 0), ec], - [ - pn, tu * 0.1, 0.0, 0, (0, 0), en]]}, - 'moonwalk': {'repeat': 2, + pn, -0.65]]}, + 'center_head_bob': {'repeat': 2, + 'poses': [ + [ + pn, td * 0.25], + [ + pn, tu * 0.2], + [ + pn, td * 0.25], + [ + pn, tu * 0.2]]}, + 'full_body_bob': {'repeat': 2, + 'poses': [ + [ + pl * 0.2, td * 0.5, 0.2], + [ + pl * 0.2, tu * 0.3, 0], + [ + pr * 0.2, td * 0.5, -0.2], + [ + pr * 0.2, tu * 0.3, 0]]}, + 'full_body_bob_rev': {'repeat': 2, + 'poses': [ + [ + pl * 0.2, td * 0.5, -0.15], + [ + pl * 0.2, tu * 0.3, 0], + [ + pr * 0.2, td * 0.5, 0.15], + [ + pr * 0.2, tu * 0.3, 0]]}, + 'full_body_up_nod': {'repeat': 2, + 'poses': [ + [ + pr * 0.2, tu * 0.6, 0.25], + [ + pr * 0.2, tu * 0.1, 0], + [ + pl * 0.2, tu * 0.5, -0.25], + [ + pl * 0.2, tu * 0.1, 0]]}, + 'full_body_up_nod_rev': {'repeat': 2, + 'poses': [ + [ + pl * 0.2, tu * 0.5, 0.2], + [ + pl * 0.2, tu * 0.2, 0], + [ + pr * 0.2, tu * 0.6, -0.2], + [ + pr * 0.2, tu * 0.1, 0]]}, + 'longbob': {'poses': [ + [ + pl * 0.7, td * 0.45, 0.05], + [ + pl * 0.7, tu * 0.2], + [ + pl * 0.7, td * 0.45], + [ + pl * 0.7, tu * 0.2], + [ + pl * 0.7, td * 0.45, 0.05], + [ + pl * 0.7, tu * 0.2], + [ + pl * 0.7, td * 0.45], + [ + pl * 0.15, tu * 0.2], + [ + pr * 0.7, td * 0.45, -0.05], + [ + pr * 0.7, tu * 0.2], + [ + pr * 0.7, td * 0.45], + [ + pr * 0.7, tu * 0.2], + [ + pr * 0.7, td * 0.45, -0.05], + [ + pr * 0.7, tu * 0.2], + [ + pr * 0.4, td * 0.45], + [ + pn, tu * 0.35]]}, + 'full_body_groove': {'randomness': ( + True, False), + 'repeat': 2, + 'poses': [ + [ + pl * 0.5, td * 0.7, 0.4, 0.0], + [ + pl * 0.5, tu * 0.2, 0.0, 0.0], + [ + pr * 0.5, td * 0.7, -0.4, 0.0], + [ + pr * 0.5, tu * 0.2, 0.0, 0.0]]}, + 'full_body_groove_rev': {'randomness': ( + True, False), + 'repeat': 2, + 'poses': [ + [ + pl * 0.5, td * 0.7, -0.4, 0.0], + [ + pl * 0.5, tu * 0.2, 0.0, 0.0], + [ + pr * 0.5, td * 0.7, 0.4, 0.0], + [ + pr * 0.5, tu * 0.2, 0.0, 0.0]]}, + 'full_body_groove_excited': {'randomness': ( + True, False), + 'repeat': 2, + 'poses': [ + [ + pl * 0.4, td * 0.6, 0.55], + [ + pl * 0.4, tu * 0.5, 0.0], + [ + pr * 0.4, td * 0.6, -0.55], + [ + pr * 0.4, tu * 0.4, 0.0]]}, + 'full_body_groove_excited_rev': {'randomness': ( + True, False), + 'repeat': 2, 'poses': [ - [ - pr * 0.5, td * 0.7, 0, -0.5], - [ - pr * 0.1, td * 0.8, 0, 0], - [ - pl * 0.4, td * 0.6, 0, -0.5], - [ - pn, td * 0.3, 0, 0], - [ - pl * 0.6, tu * 0.5, 0, -0.5], - [ - pl * 0.1, tu * 0.7, 0, 0], - [ - pr * 0.5, tu * 0.4, 0, -0.5], - [ - pn, tu * 0.3, 0, 0]]}, - 'skate_back': {'poses': [ - [ - pl * 0.2, tu * 0.1, 0, 0, (rad(-10), -0.04), eh], - [ - pr * 0.2, tu * 0.1, 0, 0, (rad(10), -0.04), eh], - [ - pl * 0.2, tu * 0.2, 0, 0, (rad(-10), -0.04), eh], - [ - pr * 0.2, tu * 0.2, 0, 0, (rad(10), -0.04), eh], - [ - pl * 0.2, tu * 0.1, 0, 0, (rad(-10), -0.04)], - [ - pr * 0.2, tu * 0.1, 0, 0, (rad(10), -0.04)], - [ - pr * 0.2, tu * 0.2, 0, 0, (rad(-10), -0.04)], - [ - pl * 0.2, tu * 0.2, 0, 0, (rad(10), -0.04), en]]}, - 'clover': {'poses': [ - [ - pr * 0.2, tu * 0.3, 0, 0, (rad(-90), 0.1), eh], - [ - pr * 0.3, tu * 0.4, 0, 0, (rad(-90), 0.1), eh], - [ - pr * 0.4, tu * 0.5, 0, 0, (rad(-90), 0.1), eh], - [ - pr * 0.5, tu * 0.5, 0, 0, (rad(-90), 0.1), eh], - [ - pr * 0.5, tu * 0.4, 0, 0, (rad(-90), -0.1), eh], - [ - pr * 0.3, tu * 0.4, 0, 0, (rad(-90), -0.1), eh], - [ - pr * 0.2, tu * 0.3, 0, 0, (rad(-90), -0.1), eh], - [ - pr * 0.1, tu * 0.2, 0, 0, (rad(-90), -0.1), en], - [ - pl * 0.1, tu * 0.2, 0, 0, (rad(90), 0.1)], - [ - pl * 0.2, tu * 0.3, 0, 0, (rad(90), 0.1)], - [ - pl * 0.3, tu * 0.5, 0, 0, (rad(90), 0.1)], - [ - pl * 0.4, tu * 0.6, 0, 0, (rad(90), 0.1)], - [ - pl * 0.5, tu * 0.7, 0, 0, (rad(90), -0.1)], - [ - pl * 0.4, tu * 0.6, 0, 0, (rad(90), -0.1)], - [ - pl * 0.3, tu * 0.5, 0, 0, (rad(90), -0.1)], - [ - pl * 0.2, tu * 0.4, 0, 0, (rad(90), -0.1)], - [ - pr * 0.2, tu * 0.3, 0, 0, (rad(-90), -0.1)], - [ - pr * 0.4, tu * 0.5, 0, 0, (rad(-90), -0.1)], - [ - pr * 0.5, tu * 0.6, 0, 0, (rad(-90), -0.1)], - [ - pr * 0.6, tu * 0.7, 0, 0, (rad(-90), -0.1)], - [ - pr * 0.7, tu * 0.8, 0, 0, (rad(-90), 0.1)], - [ - pr * 0.6, tu * 0.6, 0, 0, (rad(-90), 0.1)], - [ - pr * 0.3, tu * 0.4, 0, 0, (rad(-90), 0.1)], - [ - pr * 0.2, tu * 0.3, 0, 0, (rad(-90), 0.1)], - [ - pl * 0.1, tu * 0.2, 0, 0, (rad(90), -0.1)], - [ - pl * 0.2, tu * 0.1, 0, 0, (rad(90), -0.1)], - [ - pl * 0.3, tn, 0, 0, (rad(90), -0.1)], - [ - pl * 0.4, td * 0.2, 0, 0, (rad(90), -0.1), eh], - [ - pl * 0.3, td * 0.3, 0, 0, (rad(90), 0.1), eh], - [ - pl * 0.2, td * 0.5, 0, 0, (rad(90), 0.1), eh], - [ - pl * 0.1, td * 0.3, 0, 0, (rad(90), 0.1), eh], - [ - pn, td * 0.2, 0, 0, (rad(90), 0.1), en]]}, - 'done_dummy': {'repeat': 8, - 'poses': [ - [ - pn, tn], - [ - pn, tn], - [ - pn, tn], - [ - pn, tn]]}} + [ + pl * 0.4, td * 0.6, -0.55], + [ + pl * 0.4, tu * 0.5, 0.0], + [ + pr * 0.4, td * 0.6, 0.55], + [ + pr * 0.4, tu * 0.4, 0.0]]}, + 'robot': {'poses': [ + [ + pl * 0.7, tu * 0.1, 0.0, 0], + [ + pl * 0.7, tu * 0.3, 0.4, 0], + [ + pl * 0.7, tu * 0.1, 0.4, 0], + [ + pl * 0.7, tu * 0.3, 0.4, 0], + [ + pl * 0.3, tu * 0.1, -0.3, 0.0], + [ + pr * 0.3, tu * 0.2, 0.3, 0.0], + [ + pl * 0.3, tu * 0.1, -0.3, 0.0], + [ + pr * 0.3, tu * 0.2, 0.3, 0.0], + [ + pr * 0.6, tn, -0.3, 0], + [ + pr * 0.65, tn, -0.3, 0], + [ + pr * 0.7, tn, -0.3, 0], + [ + pr * 0.75, tn, -0.3, 0], + [ + pr * 0.8, tn, -0.3, 0], + [ + pr * 0.85, tn, -0.3, 0], + [ + pr * 0.5, tn, -0.3, 0], + [ + pr * 0.1, tu * 0.7, 0.2, 0]]}, + 'funky': {'randomness': ( + True, False), + 'repeat': 2, + 'poses': [ + [ + pn, tu * 0.3, 0, 0.5], + [ + pn, td * 0.2, 0, -0.4], + [ + pn, tu * 0.3, 0, 0.5], + [ + pn, td * 0.2, 0, -0.4], + [ + pn, tu * 0.3, 0, 0.5], + [ + pn, td * 0.2, 0, -0.4], + [ + pn, tu * 0.3, 0, 0.5], + [ + pn, td * 0.2, 0, -0.4], + [ + pr, tn, 0.5, 0], + [ + pl, tn, 0.0, 0], + [ + pn, tn, -0.5, 0], + [ + pn, tu * 0.1, 0, 0]]}, + 'funky_alt': {'poses': [ + [ + pn, tu * 0.2, 0, 0.4], + [ + pn, td * 0.1, 0, 0], + [ + pn, tu * 0.3, 0, 0.4], + [ + pn, td * 0.1, 0, 0], + [ + pn, tu * 0.4, 0, 0.4], + [ + pn, td * 0.1, 0, 0], + [ + pn, tu * 0.5, 0, 0.4], + [ + pn, td * 0.1, 0, 0], + [ + pl * 0.7, td * 0.3, 0, -0.2], + [ + pl * 0.7, tu * 0.1, 0, -0.2], + [ + pr * 0.7, td * 0.5, 0, -0.2], + [ + pr * 0.7, tu * 0.2, 0, -0.2], + [ + pn, td * 0.8, 0, -0.2], + [ + pn, tu * 0.6, 0, -0.2], + [ + pn, tn, 0, -0.2], + [ + pn, tn, 0, 0]]}, + 'twirl': {'poses': [ + [ + pr * 0.3, tu * 0.3, -1.0], + [ + pr * 0.4, tu * 0.4, -1.0], + [ + pr * 0.5, tu * 0.5, -1.0], + [ + pn, td * 0.1, -1.0], + [ + pr * 0.3, tu * 0.5, -1.0], + [ + pr * 0.4, tu * 0.4, -1.0], + [ + pr * 0.5, tu * 0.3, -1.0], + [ + pn, tn, -1.0], + [ + pl * 0.3, tu * 0.3, 1.0], + [ + pl * 0.4, tu * 0.4, 1.0], + [ + pl * 0.5, tu * 0.5, 1.0], + [ + pn, td * 0.1, 1.0], + [ + pl * 0.3, tu * 0.5, 1.0], + [ + pl * 0.4, tu * 0.4, 1.0], + [ + pl * 0.5, tu * 0.3, 1.0], + [ + pn, tn, 1.0]]}, + 'this_is_my_jam': {'poses': [ + [ + pl * 0.7, tu * 0.6, 0, 0, (0, 0), eh], + [ + pr * 0.7, tu * 0.6, 0, 0, (0, 0), eh], + [ + pl * 0.7, tu * 0.6, 0, 0, (0, 0), eh], + [ + pr * 0.7, tu * 0.6, 0, 0, (0, 0), eh], + [ + pl * 0.7, tu * 0.6, 0, 0, (0, 0), ec], + [ + pr * 0.7, tu * 0.6, 0, 0, (0, 0), ec], + [ + pl * 0.7, tu * 0.6, 0, 0, (0, 0), ec], + [ + pr * 0.7, tu * 0.6, 0, 0, (0, 0), ec], + [ + pl * 0.7, tu * 0.4, 0, 0, (rad(-60), -0.1), eh], + [ + pl * 0.5, tn, 0, 0, (rad(-60), -0.1), eh], + [ + pl * 0.3, tu * 0.2, 0, 0, (rad(-60), -0.1), eh], + [ + pn, tu * 0.7, 0, 0, (rad(-60), -0.1), ec], + [ + pl * 0.5, tu * 0.7, 0.4, 0, (0, 0), ec], + [ + pl * 0.5, tu * 0.7, 0.0, 0, (0, 0), ec], + [ + pr * 0.5, tu * 0.7, -0.4, 0, (0, 0), ec], + [ + pr * 0.5, tu * 0.7, 0.0, 0, (0, 0), ec], + [ + pl * 0.5, tu * 0.7, 0.4, 0, (0, 0), ec], + [ + pl * 0.5, tu * 0.7, 0.0, 0, (0, 0), ec], + [ + pr * 0.5, tu * 0.7, -0.4, 0, (0, 0), ec], + [ + pn, tu * 0.1, 0.0, 0, (0, 0), en]]}, + 'moonwalk': {'repeat': 2, + 'poses': [ + [ + pr * 0.5, td * 0.7, 0, -0.5], + [ + pr * 0.1, td * 0.8, 0, 0], + [ + pl * 0.4, td * 0.6, 0, -0.5], + [ + pn, td * 0.3, 0, 0], + [ + pl * 0.6, tu * 0.5, 0, -0.5], + [ + pl * 0.1, tu * 0.7, 0, 0], + [ + pr * 0.5, tu * 0.4, 0, -0.5], + [ + pn, tu * 0.3, 0, 0]]}, + 'skate_back': {'poses': [ + [ + pl * 0.2, tu * 0.1, 0, 0, (rad(-10), -0.04), eh], + [ + pr * 0.2, tu * 0.1, 0, 0, (rad(10), -0.04), eh], + [ + pl * 0.2, tu * 0.2, 0, 0, (rad(-10), -0.04), eh], + [ + pr * 0.2, tu * 0.2, 0, 0, (rad(10), -0.04), eh], + [ + pl * 0.2, tu * 0.1, 0, 0, (rad(-10), -0.04)], + [ + pr * 0.2, tu * 0.1, 0, 0, (rad(10), -0.04)], + [ + pr * 0.2, tu * 0.2, 0, 0, (rad(-10), -0.04)], + [ + pl * 0.2, tu * 0.2, 0, 0, (rad(10), -0.04), en]]}, + 'clover': {'poses': [ + [ + pr * 0.2, tu * 0.3, 0, 0, (rad(-90), 0.1), eh], + [ + pr * 0.3, tu * 0.4, 0, 0, (rad(-90), 0.1), eh], + [ + pr * 0.4, tu * 0.5, 0, 0, (rad(-90), 0.1), eh], + [ + pr * 0.5, tu * 0.5, 0, 0, (rad(-90), 0.1), eh], + [ + pr * 0.5, tu * 0.4, 0, 0, (rad(-90), -0.1), eh], + [ + pr * 0.3, tu * 0.4, 0, 0, (rad(-90), -0.1), eh], + [ + pr * 0.2, tu * 0.3, 0, 0, (rad(-90), -0.1), eh], + [ + pr * 0.1, tu * 0.2, 0, 0, (rad(-90), -0.1), en], + [ + pl * 0.1, tu * 0.2, 0, 0, (rad(90), 0.1)], + [ + pl * 0.2, tu * 0.3, 0, 0, (rad(90), 0.1)], + [ + pl * 0.3, tu * 0.5, 0, 0, (rad(90), 0.1)], + [ + pl * 0.4, tu * 0.6, 0, 0, (rad(90), 0.1)], + [ + pl * 0.5, tu * 0.7, 0, 0, (rad(90), -0.1)], + [ + pl * 0.4, tu * 0.6, 0, 0, (rad(90), -0.1)], + [ + pl * 0.3, tu * 0.5, 0, 0, (rad(90), -0.1)], + [ + pl * 0.2, tu * 0.4, 0, 0, (rad(90), -0.1)], + [ + pr * 0.2, tu * 0.3, 0, 0, (rad(-90), -0.1)], + [ + pr * 0.4, tu * 0.5, 0, 0, (rad(-90), -0.1)], + [ + pr * 0.5, tu * 0.6, 0, 0, (rad(-90), -0.1)], + [ + pr * 0.6, tu * 0.7, 0, 0, (rad(-90), -0.1)], + [ + pr * 0.7, tu * 0.8, 0, 0, (rad(-90), 0.1)], + [ + pr * 0.6, tu * 0.6, 0, 0, (rad(-90), 0.1)], + [ + pr * 0.3, tu * 0.4, 0, 0, (rad(-90), 0.1)], + [ + pr * 0.2, tu * 0.3, 0, 0, (rad(-90), 0.1)], + [ + pl * 0.1, tu * 0.2, 0, 0, (rad(90), -0.1)], + [ + pl * 0.2, tu * 0.1, 0, 0, (rad(90), -0.1)], + [ + pl * 0.3, tn, 0, 0, (rad(90), -0.1)], + [ + pl * 0.4, td * 0.2, 0, 0, (rad(90), -0.1), eh], + [ + pl * 0.3, td * 0.3, 0, 0, (rad(90), 0.1), eh], + [ + pl * 0.2, td * 0.5, 0, 0, (rad(90), 0.1), eh], + [ + pl * 0.1, td * 0.3, 0, 0, (rad(90), 0.1), eh], + [ + pn, td * 0.2, 0, 0, (rad(90), 0.1), en]]}, + 'done_dummy': {'repeat': 8, + 'poses': [ + [ + pn, tn], + [ + pn, tn], + [ + pn, tn], + [ + pn, tn]]}} return routines @@ -611,4 +614,4 @@ def choreographed_performances(): """ Get the intro order of dance routines """ - return CHOREOGRAPHED_SONGS \ No newline at end of file + return CHOREOGRAPHED_SONGS diff --git a/kuri_api/src/kuri_api/utils/dance/dance_utils.py b/kuri_api/src/kuri_api/utils/dance/dance_utils.py index 311c58b..4d26b82 100644 --- a/kuri_api/src/kuri_api/utils/dance/dance_utils.py +++ b/kuri_api/src/kuri_api/utils/dance/dance_utils.py @@ -1,40 +1,42 @@ -import rospy -from numpy import clip +import logging from random import choice, random, randint, uniform +import rospy from kuri_api.head import Head +from numpy import clip + from .dance_routines import choreographed_performances, dance_routine_pools, dance_routines, dance_routine_names -import logging params = {} logger = logging.getLogger(__name__) BPM_DANCE_RANGE = ( - params.get('dance_bpm_min', 40), - params.get('dance_bpm_max', 180)) + params.get('dance_bpm_min', 40), + params.get('dance_bpm_max', 180)) SLOW_DANCE_THRESHOLD = params.get('dance_slow_threshold', 64) FAST_DANCE_THRESHOLD = params.get('dance_fast_threshold', 138) SLOW_ROUTINE_RANGE = ( - BPM_DANCE_RANGE[0], SLOW_DANCE_THRESHOLD) + BPM_DANCE_RANGE[0], SLOW_DANCE_THRESHOLD) FAST_ROUTINE_RANGE = (FAST_DANCE_THRESHOLD, BPM_DANCE_RANGE[1]) MAX_DANCE_ROT_VEL = params.get('dance_max_rot_vel', 3.0) MAX_DANCE_TRANS_VEL = params.get('dance_max_trans_vel', 0.5) DANCE_SPEEDS = [ - 'slow', 'regular', 'fast'] + 'slow', 'regular', 'fast'] DANCE_SPEED_SLOW = 0 DANCE_SPEED_REG = 1 DANCE_SPEED_FAST = 2 DANCE_PROFILES = [ - 'natural', 'robot'] + 'natural', 'robot'] DANCE_PROFILE_NATURAL = 0 DANCE_PROFILE_ROBOT = 1 PERFORMANCE_STAGES = [ - 'intro', 'warm_up', 'apex', 'cool_down'] + 'intro', 'warm_up', 'apex', 'cool_down'] PERFORMANCE_STAGE_INTRO = 0 PERFORMANCE_STAGE_WARM_UP = 1 PERFORMANCE_STAGE_APEX = 2 PERFORMANCE_STAGE_COOL_DOWN = 3 + def get_bpm_range(): """ Get the danceable BPM range. @@ -63,7 +65,8 @@ class DancePerformance(object): def __init__(self, bpm=None, song=None): self._routine_map, self.profile, self._seed = _gen_performance(bpm, song) - logger.info(('\n\x1b[1;35mGenerated Dance Performance!\n\tSeed: {}\n\tProfile: {}\x1b[1;0m').format(self._seed, self.profile)) + logger.info(('\n\x1b[1;35mGenerated Dance Performance!\n\tSeed: {}\n\tProfile: {}\x1b[1;0m').format(self._seed, + self.profile)) self.last_pose = None self._time_start = rospy.get_time() self._performance_stage = PERFORMANCE_STAGES[PERFORMANCE_STAGE_INTRO] @@ -108,7 +111,7 @@ def update(self): routines_in_stage = len(self._routine_map[self._performance_stage]) if self._routine_index == routines_in_stage: self._performance_stage = self._next_performance_stage() - logger.info(('\n\x1b[1;35mNext dance stage: {} \x1b[1;0m').format(self._performance_stage)) + logger.info('\n\x1b[1;35mNext dance stage: {} \x1b[1;0m'.format(self._performance_stage)) self._routine_index = 0 self._current_routine = self._routine_map[self._performance_stage][self._routine_index] @@ -127,8 +130,8 @@ def _next_performance_stage(self): def __str__(self): perf_str = 'Dance Performance:' - perf_str += ('\n\tStage: {}').format(self._performance_stage) - perf_str += ('\n\t{}').format(self._current_routine) + perf_str += '\n\tStage: {}'.format(self._performance_stage) + perf_str += '\n\t{}'.format(self._current_routine) return perf_str @@ -229,17 +232,17 @@ def reset(self): def __str__(self): routine_str = 'DanceRoutine:' - routine_str += ('\n\t\tName: {}').format(self.name) + routine_str += '\n\t\tName: {}'.format(self.name) if self.relative: routine_str += ' (relative),' if self.randomness[0]: routine_str += ' (random Head),' if self.randomness[1]: routine_str += ' (random Wheels),' - routine_str += ('\n\t\tIndex: {} / {}').format(self._index, self.length - 1) - routine_str += ('\n\t\tRepeat: {} / {}').format(self._times_performed_routine + 1, self.num_repeats) + routine_str += '\n\t\tIndex: {} / {}'.format(self._index, self.length - 1) + routine_str += '\n\t\tRepeat: {} / {}'.format(self._times_performed_routine + 1, self.num_repeats) if self._cur_pose: - routine_str += ('\n\t\t{}').format(self._cur_pose) + routine_str += '\n\t\t{}'.format(self._cur_pose) return routine_str @@ -259,17 +262,17 @@ def __init__(self, pan=None, tilt=None, wheel_rotate=None, wheel_translate=None, def __str__(self): pose_str = 'DancePose:' if self.pan: - pose_str += ('\n\t\t\tPan: {}').format(self.pan) + pose_str += '\n\t\t\tPan: {}'.format(self.pan) if self.tilt: - pose_str += ('\n\t\t\tTilt: {}').format(self.tilt) + pose_str += '\n\t\t\tTilt: {}'.format(self.tilt) if self.eyes: - pose_str += ('\n\t\t\tEyes: {}').format(self.eyes) + pose_str += '\n\t\t\tEyes: {}'.format(self.eyes) if self.wheel_rotate: - pose_str += ('\n\t\t\tWheel Rotate: {}').format(self.wheel_rotate) + pose_str += '\n\t\t\tWheel Rotate: {}'.format(self.wheel_rotate) if self.wheel_translate: - pose_str += ('\n\t\t\tWheel Translate: {}').format(self.wheel_translate) + pose_str += '\n\t\t\tWheel Translate: {}'.format(self.wheel_translate) if self.wheel_arc: - pose_str += ('\n\t\t\tWheel Arc: {}').format(self.wheel_arc) + pose_str += '\n\t\t\tWheel Arc: {}'.format(self.wheel_arc) return pose_str @@ -277,18 +280,18 @@ def build_dance_pose(pose_array): """ Builds a DancePose object from the shorthand performance notation """ - NUM_POSE_ELEMENTS = 6 - WHEEL_ROTATE_INDEX = 2 - WHEEL_TRANSLATE_INDEX = 3 - WHEEL_ARC_INDEX = 4 - pose = DancePose(*pose_array[0:NUM_POSE_ELEMENTS]) + num_pose_elements = 6 + wheel_rotate_index = 2 + wheel_translate_index = 3 + wheel_arc_index = 4 + pose = DancePose(*pose_array[0:num_pose_elements]) pose = _clamp_head(pose) - if len(pose_array) > WHEEL_ROTATE_INDEX and pose_array[WHEEL_ROTATE_INDEX] == 0: + if len(pose_array) > wheel_rotate_index and pose_array[wheel_rotate_index] == 0: pose.wheel_rotate = None - if len(pose_array) > WHEEL_TRANSLATE_INDEX and pose_array[WHEEL_TRANSLATE_INDEX] == 0: + if len(pose_array) > wheel_translate_index and pose_array[wheel_translate_index] == 0: pose.wheel_translate = None - if len(pose_array) > WHEEL_ARC_INDEX: - arc = pose_array[WHEEL_ARC_INDEX] + if len(pose_array) > wheel_arc_index: + arc = pose_array[wheel_arc_index] arc_is_ok = isinstance(arc, tuple) or isinstance(arc, list) if not arc_is_ok or len(arc) != 2 or arc == (0, 0): pose.wheel_arc = None @@ -314,13 +317,13 @@ def _clamp_wheels(pose): """ Ensures we don't send the robot a head position outside of its valid range. """ - ROTATE_VELOCITY_RANGE = ( - -MAX_DANCE_ROT_VEL, MAX_DANCE_ROT_VEL) - TRANSLATE_VELOCITY_RANGE = (-MAX_DANCE_TRANS_VEL, MAX_DANCE_TRANS_VEL) + rotate_velocity_range = ( + -MAX_DANCE_ROT_VEL, MAX_DANCE_ROT_VEL) + translate_velocity_range = (-MAX_DANCE_TRANS_VEL, MAX_DANCE_TRANS_VEL) if pose.wheel_rotate: - pose.wheel_rotate = clip(pose.wheel_rotate, ROTATE_VELOCITY_RANGE[0], ROTATE_VELOCITY_RANGE[1]) + pose.wheel_rotate = clip(pose.wheel_rotate, rotate_velocity_range[0], rotate_velocity_range[1]) if pose.wheel_translate: - pose.wheel_translate = clip(pose.wheel_translate, TRANSLATE_VELOCITY_RANGE[0], TRANSLATE_VELOCITY_RANGE[1]) + pose.wheel_translate = clip(pose.wheel_translate, translate_velocity_range[0], translate_velocity_range[1]) return pose @@ -358,16 +361,16 @@ def _performance_for_song(song): """ choreo = choreographed_performances() if song not in choreo.keys(): - logger.warn(('Song not in list of choreographed performances: {}').format(song)) + logger.warn('Song not in list of choreographed performances: {}'.format(song)) song = 'pancake_robot' stages = [ - _names_to_routines(choreo[song][PERFORMANCE_STAGES[PERFORMANCE_STAGE_INTRO]]), - _names_to_routines(choreo[song][PERFORMANCE_STAGES[PERFORMANCE_STAGE_WARM_UP]]), - _names_to_routines(choreo[song][PERFORMANCE_STAGES[PERFORMANCE_STAGE_APEX]]), - _names_to_routines(choreo[song][PERFORMANCE_STAGES[PERFORMANCE_STAGE_COOL_DOWN]])] + _names_to_routines(choreo[song][PERFORMANCE_STAGES[PERFORMANCE_STAGE_INTRO]]), + _names_to_routines(choreo[song][PERFORMANCE_STAGES[PERFORMANCE_STAGE_WARM_UP]]), + _names_to_routines(choreo[song][PERFORMANCE_STAGES[PERFORMANCE_STAGE_APEX]]), + _names_to_routines(choreo[song][PERFORMANCE_STAGES[PERFORMANCE_STAGE_COOL_DOWN]])] perf = _build_performance_with_stages(stages) return ( - perf, 'natural', song) + perf, 'natural', song) def _build_performance_with_stages(stages): @@ -389,8 +392,8 @@ def _performance_for_bpm(bpm): :param: bpm The beats-per-minute of the song :return: (performance map with routines, motion profile) """ - assert bpm >= BPM_DANCE_RANGE[0] and bpm <= BPM_DANCE_RANGE[1] - logger.info(('\n\x1b[1;35mBPM Seed: {}\x1b[1;0m').format(bpm)) + assert BPM_DANCE_RANGE[0] <= bpm <= BPM_DANCE_RANGE[1] + logger.info('\n\x1b[1;35mBPM Seed: {}\x1b[1;0m'.format(bpm)) pools = dance_routine_pools() motion_profile = DANCE_PROFILES[DANCE_PROFILE_NATURAL] routines = None @@ -398,54 +401,57 @@ def _performance_for_bpm(bpm): seed = 'regular' if _is_slow_bpm(bpm): seed = 'slow' - ROBOT_PROBABILITY = 0.15 - if random() < ROBOT_PROBABILITY: + robot_probability = 0.15 + if random() < robot_probability: motion_profile = DANCE_PROFILES[DANCE_PROFILE_ROBOT] pool = pools[DANCE_SPEEDS[DANCE_SPEED_SLOW]][motion_profile] num_routines_per_segment = (randint(1, 2), - randint(3, 5), - randint(1, 2), - randint(3, 5)) + randint(3, 5), + randint(1, 2), + randint(3, 5)) else: if _is_fast_bpm(bpm): seed = 'fast' - ROBOT_PROBABILITY = 0.625 - if random() < ROBOT_PROBABILITY: + robot_probability = 0.625 + if random() < robot_probability: motion_profile = DANCE_PROFILES[DANCE_PROFILE_ROBOT] pool = pools[DANCE_SPEEDS[DANCE_SPEED_FAST]][motion_profile] num_routines_per_segment = (1, - randint(3, 5), - randint(3, 5), - randint(4, 5)) + randint(3, 5), + randint(3, 5), + randint(4, 5)) else: - ROBOT_PROBABILITY = 0.35 - if random() < ROBOT_PROBABILITY: + robot_probability = 0.35 + if random() < robot_probability: motion_profile = DANCE_PROFILES[DANCE_PROFILE_ROBOT] pool = pools[DANCE_SPEEDS[DANCE_SPEED_REG]][motion_profile] num_routines_per_segment = (1, - randint(3, 5), - randint(2, 3), - randint(3, 6)) + randint(3, 5), + randint(2, 3), + randint(3, 6)) routines = _performance_from_pool(pool, *num_routines_per_segment) assert routines is not None return ( - routines, motion_profile, seed) + routines, motion_profile, seed) def _is_slow_bpm(bpm): - return bpm > SLOW_ROUTINE_RANGE[0] and bpm <= SLOW_ROUTINE_RANGE[1] + return SLOW_ROUTINE_RANGE[0] < bpm <= SLOW_ROUTINE_RANGE[1] def _is_fast_bpm(bpm): - return bpm > FAST_ROUTINE_RANGE[0] and bpm <= FAST_ROUTINE_RANGE[1] + return FAST_ROUTINE_RANGE[0] < bpm <= FAST_ROUTINE_RANGE[1] def _performance_from_pool(routine_pools, num_intros, num_warm_up, num_apex, num_cool_down): - perf = {} - perf[PERFORMANCE_STAGES[PERFORMANCE_STAGE_INTRO]] = _gen_unique_pool(routine_pools[PERFORMANCE_STAGES[PERFORMANCE_STAGE_INTRO]], num_intros) - perf[PERFORMANCE_STAGES[PERFORMANCE_STAGE_WARM_UP]] = _gen_unique_pool(routine_pools[PERFORMANCE_STAGES[PERFORMANCE_STAGE_WARM_UP]], num_warm_up) - perf[PERFORMANCE_STAGES[PERFORMANCE_STAGE_APEX]] = _gen_unique_pool(routine_pools[PERFORMANCE_STAGES[PERFORMANCE_STAGE_APEX]], num_apex) - perf[PERFORMANCE_STAGES[PERFORMANCE_STAGE_COOL_DOWN]] = _gen_unique_pool(routine_pools[PERFORMANCE_STAGES[PERFORMANCE_STAGE_COOL_DOWN]], num_cool_down) + perf = {PERFORMANCE_STAGES[PERFORMANCE_STAGE_INTRO]: _gen_unique_pool( + routine_pools[PERFORMANCE_STAGES[PERFORMANCE_STAGE_INTRO]], num_intros), + PERFORMANCE_STAGES[PERFORMANCE_STAGE_WARM_UP]: _gen_unique_pool( + routine_pools[PERFORMANCE_STAGES[PERFORMANCE_STAGE_WARM_UP]], num_warm_up), + PERFORMANCE_STAGES[PERFORMANCE_STAGE_APEX]: _gen_unique_pool( + routine_pools[PERFORMANCE_STAGES[PERFORMANCE_STAGE_APEX]], num_apex), + PERFORMANCE_STAGES[PERFORMANCE_STAGE_COOL_DOWN]: _gen_unique_pool( + routine_pools[PERFORMANCE_STAGES[PERFORMANCE_STAGE_COOL_DOWN]], num_cool_down)} return perf @@ -453,7 +459,7 @@ def _names_to_routines(routine_names): routines = [] for routine_name in routine_names: if routine_name not in dance_routine_names(): - logger.warn(('INVALID ROUTINE: {}').format(routine_name)) + logger.warn('INVALID ROUTINE: {}'.format(routine_name)) else: routines.append(DanceRoutine(routine_name)) @@ -471,4 +477,4 @@ def _gen_unique_pool(pool, num_routines): routine_names.append(rand_routine) routine_idx += 1 - return _names_to_routines(routine_names) \ No newline at end of file + return _names_to_routines(routine_names) diff --git a/kuri_api/src/kuri_api/utils/event.py b/kuri_api/src/kuri_api/utils/event.py index 7cae227..3ae3601 100644 --- a/kuri_api/src/kuri_api/utils/event.py +++ b/kuri_api/src/kuri_api/utils/event.py @@ -1,4 +1,6 @@ -import collections, inspect, weakref +import collections +import inspect +import weakref class EventField(object): @@ -149,4 +151,4 @@ def _first_event_connect(self, event): pass def _last_event_disconnect(self, event): - pass \ No newline at end of file + pass diff --git a/kuri_api/src/kuri_api/utils/heartbeat_utils.py b/kuri_api/src/kuri_api/utils/heartbeat_utils.py index a5a1859..6f1e6cf 100644 --- a/kuri_api/src/kuri_api/utils/heartbeat_utils.py +++ b/kuri_api/src/kuri_api/utils/heartbeat_utils.py @@ -1,39 +1,40 @@ import numpy as np + def happiness_to_fade(happiness): """ Currently just rounds to the nearest bin. """ - HAPPINESS_RANGE = 6.0 - HAPPINESS_COLORS = [ - (94, 31, 0), - (101, 57, 26), - (81, 71, 65), - (63, 61, 61), - (73, 73, 73), - (91, 91, 91), - (166, 166, 166)] - num_colors = len(HAPPINESS_COLORS) - 1 - nearest_index = np.clip(int(round(happiness + HAPPINESS_RANGE / 2.0)), 0, num_colors) - return HAPPINESS_COLORS[nearest_index] + happiness_range = 6.0 + happiness_colors = [ + (94, 31, 0), + (101, 57, 26), + (81, 71, 65), + (63, 61, 61), + (73, 73, 73), + (91, 91, 91), + (166, 166, 166)] + num_colors = len(happiness_colors) - 1 + nearest_index = np.clip(int(round(happiness + happiness_range / 2.0)), 0, num_colors) + return happiness_colors[nearest_index] def happiness_to_color(happiness): """ Currently just rounds to the nearest bin. """ - HAPPINESS_RANGE = 6.0 - HAPPINESS_COLORS = [ - (255, 91, 0), - (255, 158, 92), - (244, 218, 201), - (244, 234, 232), - (178, 178, 178), - (219, 219, 219), - (255, 255, 255)] - num_colors = len(HAPPINESS_COLORS) - 1 - nearest_index = np.clip(int(round(happiness + HAPPINESS_RANGE / 2.0)), 0, num_colors) - return HAPPINESS_COLORS[nearest_index] + happiness_range = 6.0 + happiness_colors = [ + (255, 91, 0), + (255, 158, 92), + (244, 218, 201), + (244, 234, 232), + (178, 178, 178), + (219, 219, 219), + (255, 255, 255)] + num_colors = len(happiness_colors) - 1 + nearest_index = np.clip(int(round(happiness + happiness_range / 2.0)), 0, num_colors) + return happiness_colors[nearest_index] def excitation_to_period(excitation): @@ -41,9 +42,9 @@ def excitation_to_period(excitation): Maps a value in the excitation range [-3 : 3] to the pulse range [4.825 : 1.075] """ - MOOD_RANGE = (-3, 3) - EXCITATION_CYCLE_RANGE_SECS = (4.825, 1.075) - return map_range(excitation, MOOD_RANGE, EXCITATION_CYCLE_RANGE_SECS) + mood_range = (-3, 3) + excitation_cycle_range_secs = (4.825, 1.075) + return map_range(excitation, mood_range, excitation_cycle_range_secs) def map_range(value, in_range, out_range): diff --git a/kuri_api/src/kuri_api/utils/interp.py b/kuri_api/src/kuri_api/utils/interp.py index ac4bdd3..b2485a0 100644 --- a/kuri_api/src/kuri_api/utils/interp.py +++ b/kuri_api/src/kuri_api/utils/interp.py @@ -141,4 +141,4 @@ def interp_keyframes(keyframes): keyframe.frame_idx - last_keyframe.frame_idx) last_keyframe = keyframe - return frames \ No newline at end of file + return frames diff --git a/kuri_api/src/kuri_api/utils/mux.py b/kuri_api/src/kuri_api/utils/mux.py index 10f00fb..d65533f 100644 --- a/kuri_api/src/kuri_api/utils/mux.py +++ b/kuri_api/src/kuri_api/utils/mux.py @@ -1,4 +1,7 @@ -import bisect, collections, inspect, threading +import bisect +import collections +import inspect +import threading class Mux(collections.Sequence): @@ -7,7 +10,7 @@ def __init__(self): self._lock = threading.RLock() self._channels = [] - class protect(object): + class Protect(object): """ Descriptor used to protect methods from being accessed from inactive channels. @@ -95,7 +98,7 @@ class MuxChannelMeta(type): def __new__(cls, name, bases, dct): type_ = type.__new__(cls, name, bases, dct) - protects = inspect.getmembers(type_, lambda t: isinstance(t, Mux.protect)) + protects = inspect.getmembers(type_, lambda t: isinstance(t, Mux.Protect)) for n, protect in protects: protect.name = n for base in bases: @@ -103,7 +106,7 @@ def __new__(cls, name, bases, dct): protect.func = getattr(base, n) break else: - raise TypeError(('{}.{} protects nothing').format(name, n)) + raise TypeError('{}.{} protects nothing'.format(name, n)) return type_ @@ -164,6 +167,6 @@ def __cmp__(self, other): return cmp(self.priority, other.priority) def __str__(self): - return ('{}(name="{}", priority={}, is_acquired={}, is_active={})').format(type(self).__name__, self.name, - self.priority, self.is_acquired, - self.is_active) \ No newline at end of file + return '{}(name="{}", priority={}, is_acquired={}, is_active={})'.format(type(self).__name__, self.name, + self.priority, self.is_acquired, + self.is_active) diff --git a/kuri_api/src/kuri_api/utils/pulse_utils/__init__.py b/kuri_api/src/kuri_api/utils/pulse_utils/__init__.py index b349530..c7d8171 100644 --- a/kuri_api/src/kuri_api/utils/pulse_utils/__init__.py +++ b/kuri_api/src/kuri_api/utils/pulse_utils/__init__.py @@ -1,3 +1,4 @@ from .pulse_mon import PeakMonitor + __all__ = [ - 'PeakMonitor'] \ No newline at end of file + 'PeakMonitor'] diff --git a/kuri_api/src/kuri_api/utils/pulse_utils/pulse_lib.py b/kuri_api/src/kuri_api/utils/pulse_utils/pulse_lib.py index 3e319a8..0881a2c 100644 --- a/kuri_api/src/kuri_api/utils/pulse_utils/pulse_lib.py +++ b/kuri_api/src/kuri_api/utils/pulse_utils/pulse_lib.py @@ -1,4 +1,5 @@ from ctypes import * + _libraries = {} _libraries['libpulse.so.0'] = CDLL('libpulse.so.0') STRING = c_char_p @@ -241,16 +242,17 @@ pa_channel_map_def = c_int pa_channel_map_def_t = pa_channel_map_def + class pa_channel_map(Structure): pass uint8_t = c_uint8 pa_channel_map._fields_ = [ - ( - 'channels', uint8_t), - ( - 'map', pa_channel_position_t * 32)] + ( + 'channels', uint8_t), + ( + 'map', pa_channel_position_t * 32)] pa_channel_map_init = _libraries['libpulse.so.0'].pa_channel_map_init pa_channel_map_init.restype = POINTER(pa_channel_map) pa_channel_map_init.argtypes = [POINTER(pa_channel_map)] @@ -289,6 +291,7 @@ class pa_channel_map(Structure): pa_channel_map_valid.restype = c_int pa_channel_map_valid.argtypes = [POINTER(pa_channel_map)] + class pa_sample_spec(Structure): pass @@ -318,6 +321,7 @@ class pa_sample_spec(Structure): pa_channel_map_mask.restype = pa_channel_position_mask_t pa_channel_map_mask.argtypes = [POINTER(pa_channel_map)] + class pa_context(Structure): pass @@ -326,12 +330,14 @@ class pa_context(Structure): pa_context_notify_cb_t = CFUNCTYPE(None, POINTER(pa_context), c_void_p) pa_context_success_cb_t = CFUNCTYPE(None, POINTER(pa_context), c_int, c_void_p) + class pa_proplist(Structure): pass pa_context_event_cb_t = CFUNCTYPE(None, POINTER(pa_context), STRING, POINTER(pa_proplist), c_void_p) + class pa_mainloop_api(Structure): pass @@ -368,6 +374,7 @@ class pa_mainloop_api(Structure): pa_context_flags = c_int pa_context_flags_t = pa_context_flags + class pa_spawn_api(Structure): pass @@ -379,6 +386,7 @@ class pa_spawn_api(Structure): pa_context_disconnect.restype = None pa_context_disconnect.argtypes = [POINTER(pa_context)] + class pa_operation(Structure): pass @@ -415,7 +423,8 @@ class pa_operation(Structure): pa_update_mode_t = pa_update_mode pa_context_proplist_update = _libraries['libpulse.so.0'].pa_context_proplist_update pa_context_proplist_update.restype = POINTER(pa_operation) -pa_context_proplist_update.argtypes = [POINTER(pa_context), pa_update_mode_t, POINTER(pa_proplist), pa_context_success_cb_t, c_void_p] +pa_context_proplist_update.argtypes = [POINTER(pa_context), pa_update_mode_t, POINTER(pa_proplist), + pa_context_success_cb_t, c_void_p] pa_context_proplist_remove = _libraries['libpulse.so.0'].pa_context_proplist_remove pa_context_proplist_remove.restype = POINTER(pa_operation) pa_context_proplist_remove.argtypes = [POINTER(pa_context), POINTER(STRING), pa_context_success_cb_t, c_void_p] @@ -423,12 +432,14 @@ class pa_operation(Structure): pa_context_get_index.restype = uint32_t pa_context_get_index.argtypes = [POINTER(pa_context)] + class pa_time_event(Structure): pass pa_usec_t = uint64_t + class timeval(Structure): pass @@ -436,10 +447,10 @@ class timeval(Structure): __time_t = c_long __suseconds_t = c_long timeval._fields_ = [ - ( - 'tv_sec', __time_t), - ( - 'tv_usec', __suseconds_t)] + ( + 'tv_sec', __time_t), + ( + 'tv_usec', __suseconds_t)] pa_time_event_cb_t = CFUNCTYPE(None, POINTER(pa_mainloop_api), POINTER(pa_time_event), POINTER(timeval), c_void_p) pa_context_rttime_new = _libraries['libpulse.so.0'].pa_context_rttime_new pa_context_rttime_new.restype = POINTER(pa_time_event) @@ -461,65 +472,67 @@ class timeval(Structure): pa_stream_flags = c_int pa_stream_flags_t = pa_stream_flags + class pa_buffer_attr(Structure): pass pa_buffer_attr._fields_ = [ - ( - 'maxlength', uint32_t), - ( - 'tlength', uint32_t), - ( - 'prebuf', uint32_t), - ( - 'minreq', uint32_t), - ( - 'fragsize', uint32_t)] + ( + 'maxlength', uint32_t), + ( + 'tlength', uint32_t), + ( + 'prebuf', uint32_t), + ( + 'minreq', uint32_t), + ( + 'fragsize', uint32_t)] pa_subscription_mask = c_int pa_subscription_mask_t = pa_subscription_mask pa_subscription_event_type = c_int pa_subscription_event_type_t = pa_subscription_event_type + class pa_timing_info(Structure): pass int64_t = c_int64 pa_timing_info._fields_ = [ - ( - 'timestamp', timeval), - ( - 'synchronized_clocks', c_int), - ( - 'sink_usec', pa_usec_t), - ( - 'source_usec', pa_usec_t), - ( - 'transport_usec', pa_usec_t), - ( - 'playing', c_int), - ( - 'write_index_corrupt', c_int), - ( - 'write_index', int64_t), - ( - 'read_index_corrupt', c_int), - ( - 'read_index', int64_t), - ( - 'configured_sink_usec', pa_usec_t), - ( - 'configured_source_usec', pa_usec_t), - ( - 'since_underrun', int64_t)] + ( + 'timestamp', timeval), + ( + 'synchronized_clocks', c_int), + ( + 'sink_usec', pa_usec_t), + ( + 'source_usec', pa_usec_t), + ( + 'transport_usec', pa_usec_t), + ( + 'playing', c_int), + ( + 'write_index_corrupt', c_int), + ( + 'write_index', int64_t), + ( + 'read_index_corrupt', c_int), + ( + 'read_index', int64_t), + ( + 'configured_sink_usec', pa_usec_t), + ( + 'configured_source_usec', pa_usec_t), + ( + 'since_underrun', int64_t)] pa_spawn_api._fields_ = [ - ( - 'prefork', CFUNCTYPE(None)), - ( - 'postfork', CFUNCTYPE(None)), - ( - 'atfork', CFUNCTYPE(None))] + ( + 'prefork', CFUNCTYPE(None)), + ( + 'postfork', CFUNCTYPE(None)), + ( + 'atfork', CFUNCTYPE(None))] pa_seek_mode = c_int pa_seek_mode_t = pa_seek_mode pa_sink_flags = c_int @@ -540,15 +553,16 @@ class pa_timing_info(Structure): pa_encoding_to_string.restype = STRING pa_encoding_to_string.argtypes = [pa_encoding_t] + class pa_format_info(Structure): pass pa_format_info._fields_ = [ - ( - 'encoding', pa_encoding_t), - ( - 'plist', POINTER(pa_proplist))] + ( + 'encoding', pa_encoding_t), + ( + 'plist', POINTER(pa_proplist))] pa_format_info_new = _libraries['libpulse.so.0'].pa_format_info_new pa_format_info_new.restype = POINTER(pa_format_info) pa_format_info_new.argtypes = [] @@ -603,29 +617,32 @@ class pa_format_info(Structure): pa_format_info_set_channel_map.restype = None pa_format_info_set_channel_map.argtypes = [POINTER(pa_format_info), POINTER(pa_channel_map)] + class pa_sink_port_info(Structure): pass pa_sink_port_info._fields_ = [ - ( - 'name', STRING), - ( - 'description', STRING), - ( - 'priority', uint32_t)] + ( + 'name', STRING), + ( + 'description', STRING), + ( + 'priority', uint32_t)] + class pa_sink_info(Structure): pass pa_sample_spec._fields_ = [ - ( - 'format', pa_sample_format_t), - ( - 'rate', uint32_t), - ( - 'channels', uint8_t)] + ( + 'format', pa_sample_format_t), + ( + 'rate', uint32_t), + ( + 'channels', uint8_t)] + class pa_cvolume(Structure): pass @@ -633,59 +650,59 @@ class pa_cvolume(Structure): pa_volume_t = uint32_t pa_cvolume._fields_ = [ - ( - 'channels', uint8_t), - ( - 'values', pa_volume_t * 32)] + ( + 'channels', uint8_t), + ( + 'values', pa_volume_t * 32)] pa_sink_info._fields_ = [ - ( - 'name', STRING), - ( - 'index', uint32_t), - ( - 'description', STRING), - ( - 'sample_spec', pa_sample_spec), - ( - 'channel_map', pa_channel_map), - ( - 'owner_module', uint32_t), - ( - 'volume', pa_cvolume), - ( - 'mute', c_int), - ( - 'monitor_source', uint32_t), - ( - 'monitor_source_name', STRING), - ( - 'latency', pa_usec_t), - ( - 'driver', STRING), - ( - 'flags', pa_sink_flags_t), - ( - 'proplist', POINTER(pa_proplist)), - ( - 'configured_latency', pa_usec_t), - ( - 'base_volume', pa_volume_t), - ( - 'state', pa_sink_state_t), - ( - 'n_volume_steps', uint32_t), - ( - 'card', uint32_t), - ( - 'n_ports', uint32_t), - ( - 'ports', POINTER(POINTER(pa_sink_port_info))), - ( - 'active_port', POINTER(pa_sink_port_info)), - ( - 'n_formats', uint8_t), - ( - 'formats', POINTER(POINTER(pa_format_info)))] + ( + 'name', STRING), + ( + 'index', uint32_t), + ( + 'description', STRING), + ( + 'sample_spec', pa_sample_spec), + ( + 'channel_map', pa_channel_map), + ( + 'owner_module', uint32_t), + ( + 'volume', pa_cvolume), + ( + 'mute', c_int), + ( + 'monitor_source', uint32_t), + ( + 'monitor_source_name', STRING), + ( + 'latency', pa_usec_t), + ( + 'driver', STRING), + ( + 'flags', pa_sink_flags_t), + ( + 'proplist', POINTER(pa_proplist)), + ( + 'configured_latency', pa_usec_t), + ( + 'base_volume', pa_volume_t), + ( + 'state', pa_sink_state_t), + ( + 'n_volume_steps', uint32_t), + ( + 'card', uint32_t), + ( + 'n_ports', uint32_t), + ( + 'ports', POINTER(POINTER(pa_sink_port_info))), + ( + 'active_port', POINTER(pa_sink_port_info)), + ( + 'n_formats', uint8_t), + ( + 'formats', POINTER(POINTER(pa_format_info)))] pa_sink_info_cb_t = CFUNCTYPE(None, POINTER(pa_context), POINTER(pa_sink_info), c_int, c_void_p) pa_context_get_sink_info_by_name = _libraries['libpulse.so.0'].pa_context_get_sink_info_by_name pa_context_get_sink_info_by_name.restype = POINTER(pa_operation) @@ -698,10 +715,12 @@ class pa_cvolume(Structure): pa_context_get_sink_info_list.argtypes = [POINTER(pa_context), pa_sink_info_cb_t, c_void_p] pa_context_set_sink_volume_by_index = _libraries['libpulse.so.0'].pa_context_set_sink_volume_by_index pa_context_set_sink_volume_by_index.restype = POINTER(pa_operation) -pa_context_set_sink_volume_by_index.argtypes = [POINTER(pa_context), uint32_t, POINTER(pa_cvolume), pa_context_success_cb_t, c_void_p] +pa_context_set_sink_volume_by_index.argtypes = [POINTER(pa_context), uint32_t, POINTER(pa_cvolume), + pa_context_success_cb_t, c_void_p] pa_context_set_sink_volume_by_name = _libraries['libpulse.so.0'].pa_context_set_sink_volume_by_name pa_context_set_sink_volume_by_name.restype = POINTER(pa_operation) -pa_context_set_sink_volume_by_name.argtypes = [POINTER(pa_context), STRING, POINTER(pa_cvolume), pa_context_success_cb_t, c_void_p] +pa_context_set_sink_volume_by_name.argtypes = [POINTER(pa_context), STRING, POINTER(pa_cvolume), + pa_context_success_cb_t, c_void_p] pa_context_set_sink_mute_by_index = _libraries['libpulse.so.0'].pa_context_set_sink_mute_by_index pa_context_set_sink_mute_by_index.restype = POINTER(pa_operation) pa_context_set_sink_mute_by_index.argtypes = [POINTER(pa_context), uint32_t, c_int, pa_context_success_cb_t, c_void_p] @@ -721,71 +740,73 @@ class pa_cvolume(Structure): pa_context_set_sink_port_by_name.restype = POINTER(pa_operation) pa_context_set_sink_port_by_name.argtypes = [POINTER(pa_context), STRING, STRING, pa_context_success_cb_t, c_void_p] + class pa_source_port_info(Structure): pass pa_source_port_info._fields_ = [ - ( - 'name', STRING), - ( - 'description', STRING), - ( - 'priority', uint32_t)] + ( + 'name', STRING), + ( + 'description', STRING), + ( + 'priority', uint32_t)] + class pa_source_info(Structure): pass pa_source_info._fields_ = [ - ( - 'name', STRING), - ( - 'index', uint32_t), - ( - 'description', STRING), - ( - 'sample_spec', pa_sample_spec), - ( - 'channel_map', pa_channel_map), - ( - 'owner_module', uint32_t), - ( - 'volume', pa_cvolume), - ( - 'mute', c_int), - ( - 'monitor_of_sink', uint32_t), - ( - 'monitor_of_sink_name', STRING), - ( - 'latency', pa_usec_t), - ( - 'driver', STRING), - ( - 'flags', pa_source_flags_t), - ( - 'proplist', POINTER(pa_proplist)), - ( - 'configured_latency', pa_usec_t), - ( - 'base_volume', pa_volume_t), - ( - 'state', pa_source_state_t), - ( - 'n_volume_steps', uint32_t), - ( - 'card', uint32_t), - ( - 'n_ports', uint32_t), - ( - 'ports', POINTER(POINTER(pa_source_port_info))), - ( - 'active_port', POINTER(pa_source_port_info)), - ( - 'n_formats', uint8_t), - ( - 'formats', POINTER(POINTER(pa_format_info)))] + ( + 'name', STRING), + ( + 'index', uint32_t), + ( + 'description', STRING), + ( + 'sample_spec', pa_sample_spec), + ( + 'channel_map', pa_channel_map), + ( + 'owner_module', uint32_t), + ( + 'volume', pa_cvolume), + ( + 'mute', c_int), + ( + 'monitor_of_sink', uint32_t), + ( + 'monitor_of_sink_name', STRING), + ( + 'latency', pa_usec_t), + ( + 'driver', STRING), + ( + 'flags', pa_source_flags_t), + ( + 'proplist', POINTER(pa_proplist)), + ( + 'configured_latency', pa_usec_t), + ( + 'base_volume', pa_volume_t), + ( + 'state', pa_source_state_t), + ( + 'n_volume_steps', uint32_t), + ( + 'card', uint32_t), + ( + 'n_ports', uint32_t), + ( + 'ports', POINTER(POINTER(pa_source_port_info))), + ( + 'active_port', POINTER(pa_source_port_info)), + ( + 'n_formats', uint8_t), + ( + 'formats', POINTER(POINTER(pa_format_info)))] pa_source_info_cb_t = CFUNCTYPE(None, POINTER(pa_context), POINTER(pa_source_info), c_int, c_void_p) pa_context_get_source_info_by_name = _libraries['libpulse.so.0'].pa_context_get_source_info_by_name pa_context_get_source_info_by_name.restype = POINTER(pa_operation) @@ -798,10 +819,12 @@ class pa_source_info(Structure): pa_context_get_source_info_list.argtypes = [POINTER(pa_context), pa_source_info_cb_t, c_void_p] pa_context_set_source_volume_by_index = _libraries['libpulse.so.0'].pa_context_set_source_volume_by_index pa_context_set_source_volume_by_index.restype = POINTER(pa_operation) -pa_context_set_source_volume_by_index.argtypes = [POINTER(pa_context), uint32_t, POINTER(pa_cvolume), pa_context_success_cb_t, c_void_p] +pa_context_set_source_volume_by_index.argtypes = [POINTER(pa_context), uint32_t, POINTER(pa_cvolume), + pa_context_success_cb_t, c_void_p] pa_context_set_source_volume_by_name = _libraries['libpulse.so.0'].pa_context_set_source_volume_by_name pa_context_set_source_volume_by_name.restype = POINTER(pa_operation) -pa_context_set_source_volume_by_name.argtypes = [POINTER(pa_context), STRING, POINTER(pa_cvolume), pa_context_success_cb_t, c_void_p] +pa_context_set_source_volume_by_name.argtypes = [POINTER(pa_context), STRING, POINTER(pa_cvolume), + pa_context_success_cb_t, c_void_p] pa_context_set_source_mute_by_index = _libraries['libpulse.so.0'].pa_context_set_source_mute_by_index pa_context_set_source_mute_by_index.restype = POINTER(pa_operation) pa_context_set_source_mute_by_index.argtypes = [POINTER(pa_context), uint32_t, c_int, pa_context_success_cb_t, c_void_p] @@ -816,56 +839,59 @@ class pa_source_info(Structure): pa_context_suspend_source_by_index.argtypes = [POINTER(pa_context), uint32_t, c_int, pa_context_success_cb_t, c_void_p] pa_context_set_source_port_by_index = _libraries['libpulse.so.0'].pa_context_set_source_port_by_index pa_context_set_source_port_by_index.restype = POINTER(pa_operation) -pa_context_set_source_port_by_index.argtypes = [POINTER(pa_context), uint32_t, STRING, pa_context_success_cb_t, c_void_p] +pa_context_set_source_port_by_index.argtypes = [POINTER(pa_context), uint32_t, STRING, pa_context_success_cb_t, + c_void_p] pa_context_set_source_port_by_name = _libraries['libpulse.so.0'].pa_context_set_source_port_by_name pa_context_set_source_port_by_name.restype = POINTER(pa_operation) pa_context_set_source_port_by_name.argtypes = [POINTER(pa_context), STRING, STRING, pa_context_success_cb_t, c_void_p] + class pa_server_info(Structure): pass pa_server_info._fields_ = [ - ( - 'user_name', STRING), - ( - 'host_name', STRING), - ( - 'server_version', STRING), - ( - 'server_name', STRING), - ( - 'sample_spec', pa_sample_spec), - ( - 'default_sink_name', STRING), - ( - 'default_source_name', STRING), - ( - 'cookie', uint32_t), - ( - 'channel_map', pa_channel_map)] + ( + 'user_name', STRING), + ( + 'host_name', STRING), + ( + 'server_version', STRING), + ( + 'server_name', STRING), + ( + 'sample_spec', pa_sample_spec), + ( + 'default_sink_name', STRING), + ( + 'default_source_name', STRING), + ( + 'cookie', uint32_t), + ( + 'channel_map', pa_channel_map)] pa_server_info_cb_t = CFUNCTYPE(None, POINTER(pa_context), POINTER(pa_server_info), c_void_p) pa_context_get_server_info = _libraries['libpulse.so.0'].pa_context_get_server_info pa_context_get_server_info.restype = POINTER(pa_operation) pa_context_get_server_info.argtypes = [POINTER(pa_context), pa_server_info_cb_t, c_void_p] + class pa_module_info(Structure): pass pa_module_info._fields_ = [ - ( - 'index', uint32_t), - ( - 'name', STRING), - ( - 'argument', STRING), - ( - 'n_used', uint32_t), - ( - 'auto_unload', c_int), - ( - 'proplist', POINTER(pa_proplist))] + ( + 'index', uint32_t), + ( + 'name', STRING), + ( + 'argument', STRING), + ( + 'n_used', uint32_t), + ( + 'auto_unload', c_int), + ( + 'proplist', POINTER(pa_proplist))] pa_module_info_cb_t = CFUNCTYPE(None, POINTER(pa_context), POINTER(pa_module_info), c_int, c_void_p) pa_context_get_module_info = _libraries['libpulse.so.0'].pa_context_get_module_info pa_context_get_module_info.restype = POINTER(pa_operation) @@ -881,21 +907,22 @@ class pa_module_info(Structure): pa_context_unload_module.restype = POINTER(pa_operation) pa_context_unload_module.argtypes = [POINTER(pa_context), uint32_t, pa_context_success_cb_t, c_void_p] + class pa_client_info(Structure): pass pa_client_info._fields_ = [ - ( - 'index', uint32_t), - ( - 'name', STRING), - ( - 'owner_module', uint32_t), - ( - 'driver', STRING), - ( - 'proplist', POINTER(pa_proplist))] + ( + 'index', uint32_t), + ( + 'name', STRING), + ( + 'owner_module', uint32_t), + ( + 'driver', STRING), + ( + 'proplist', POINTER(pa_proplist))] pa_client_info_cb_t = CFUNCTYPE(None, POINTER(pa_context), POINTER(pa_client_info), c_int, c_void_p) pa_context_get_client_info = _libraries['libpulse.so.0'].pa_context_get_client_info pa_context_get_client_info.restype = POINTER(pa_operation) @@ -907,43 +934,45 @@ class pa_client_info(Structure): pa_context_kill_client.restype = POINTER(pa_operation) pa_context_kill_client.argtypes = [POINTER(pa_context), uint32_t, pa_context_success_cb_t, c_void_p] + class pa_card_profile_info(Structure): pass pa_card_profile_info._fields_ = [ - ( - 'name', STRING), - ( - 'description', STRING), - ( - 'n_sinks', uint32_t), - ( - 'n_sources', uint32_t), - ( - 'priority', uint32_t)] + ( + 'name', STRING), + ( + 'description', STRING), + ( + 'n_sinks', uint32_t), + ( + 'n_sources', uint32_t), + ( + 'priority', uint32_t)] + class pa_card_info(Structure): pass pa_card_info._fields_ = [ - ( - 'index', uint32_t), - ( - 'name', STRING), - ( - 'owner_module', uint32_t), - ( - 'driver', STRING), - ( - 'n_profiles', uint32_t), - ( - 'profiles', POINTER(pa_card_profile_info)), - ( - 'active_profile', POINTER(pa_card_profile_info)), - ( - 'proplist', POINTER(pa_proplist))] + ( + 'index', uint32_t), + ( + 'name', STRING), + ( + 'owner_module', uint32_t), + ( + 'driver', STRING), + ( + 'n_profiles', uint32_t), + ( + 'profiles', POINTER(pa_card_profile_info)), + ( + 'active_profile', POINTER(pa_card_profile_info)), + ( + 'proplist', POINTER(pa_proplist))] pa_card_info_cb_t = CFUNCTYPE(None, POINTER(pa_context), POINTER(pa_card_info), c_int, c_void_p) pa_context_get_card_info_by_index = _libraries['libpulse.so.0'].pa_context_get_card_info_by_index pa_context_get_card_info_by_index.restype = POINTER(pa_operation) @@ -956,52 +985,54 @@ class pa_card_info(Structure): pa_context_get_card_info_list.argtypes = [POINTER(pa_context), pa_card_info_cb_t, c_void_p] pa_context_set_card_profile_by_index = _libraries['libpulse.so.0'].pa_context_set_card_profile_by_index pa_context_set_card_profile_by_index.restype = POINTER(pa_operation) -pa_context_set_card_profile_by_index.argtypes = [POINTER(pa_context), uint32_t, STRING, pa_context_success_cb_t, c_void_p] +pa_context_set_card_profile_by_index.argtypes = [POINTER(pa_context), uint32_t, STRING, pa_context_success_cb_t, + c_void_p] pa_context_set_card_profile_by_name = _libraries['libpulse.so.0'].pa_context_set_card_profile_by_name pa_context_set_card_profile_by_name.restype = POINTER(pa_operation) pa_context_set_card_profile_by_name.argtypes = [POINTER(pa_context), STRING, STRING, pa_context_success_cb_t, c_void_p] + class pa_sink_input_info(Structure): pass pa_sink_input_info._fields_ = [ - ( - 'index', uint32_t), - ( - 'name', STRING), - ( - 'owner_module', uint32_t), - ( - 'client', uint32_t), - ( - 'sink', uint32_t), - ( - 'sample_spec', pa_sample_spec), - ( - 'channel_map', pa_channel_map), - ( - 'volume', pa_cvolume), - ( - 'buffer_usec', pa_usec_t), - ( - 'sink_usec', pa_usec_t), - ( - 'resample_method', STRING), - ( - 'driver', STRING), - ( - 'mute', c_int), - ( - 'proplist', POINTER(pa_proplist)), - ( - 'corked', c_int), - ( - 'has_volume', c_int), - ( - 'volume_writable', c_int), - ( - 'format', POINTER(pa_format_info))] + ( + 'index', uint32_t), + ( + 'name', STRING), + ( + 'owner_module', uint32_t), + ( + 'client', uint32_t), + ( + 'sink', uint32_t), + ( + 'sample_spec', pa_sample_spec), + ( + 'channel_map', pa_channel_map), + ( + 'volume', pa_cvolume), + ( + 'buffer_usec', pa_usec_t), + ( + 'sink_usec', pa_usec_t), + ( + 'resample_method', STRING), + ( + 'driver', STRING), + ( + 'mute', c_int), + ( + 'proplist', POINTER(pa_proplist)), + ( + 'corked', c_int), + ( + 'has_volume', c_int), + ( + 'volume_writable', c_int), + ( + 'format', POINTER(pa_format_info))] pa_sink_input_info_cb_t = CFUNCTYPE(None, POINTER(pa_context), POINTER(pa_sink_input_info), c_int, c_void_p) pa_context_get_sink_input_info = _libraries['libpulse.so.0'].pa_context_get_sink_input_info pa_context_get_sink_input_info.restype = POINTER(pa_operation) @@ -1014,10 +1045,12 @@ class pa_sink_input_info(Structure): pa_context_move_sink_input_by_name.argtypes = [POINTER(pa_context), uint32_t, STRING, pa_context_success_cb_t, c_void_p] pa_context_move_sink_input_by_index = _libraries['libpulse.so.0'].pa_context_move_sink_input_by_index pa_context_move_sink_input_by_index.restype = POINTER(pa_operation) -pa_context_move_sink_input_by_index.argtypes = [POINTER(pa_context), uint32_t, uint32_t, pa_context_success_cb_t, c_void_p] +pa_context_move_sink_input_by_index.argtypes = [POINTER(pa_context), uint32_t, uint32_t, pa_context_success_cb_t, + c_void_p] pa_context_set_sink_input_volume = _libraries['libpulse.so.0'].pa_context_set_sink_input_volume pa_context_set_sink_input_volume.restype = POINTER(pa_operation) -pa_context_set_sink_input_volume.argtypes = [POINTER(pa_context), uint32_t, POINTER(pa_cvolume), pa_context_success_cb_t, c_void_p] +pa_context_set_sink_input_volume.argtypes = [POINTER(pa_context), uint32_t, POINTER(pa_cvolume), + pa_context_success_cb_t, c_void_p] pa_context_set_sink_input_mute = _libraries['libpulse.so.0'].pa_context_set_sink_input_mute pa_context_set_sink_input_mute.restype = POINTER(pa_operation) pa_context_set_sink_input_mute.argtypes = [POINTER(pa_context), uint32_t, c_int, pa_context_success_cb_t, c_void_p] @@ -1025,47 +1058,48 @@ class pa_sink_input_info(Structure): pa_context_kill_sink_input.restype = POINTER(pa_operation) pa_context_kill_sink_input.argtypes = [POINTER(pa_context), uint32_t, pa_context_success_cb_t, c_void_p] + class pa_source_output_info(Structure): pass pa_source_output_info._fields_ = [ - ( - 'index', uint32_t), - ( - 'name', STRING), - ( - 'owner_module', uint32_t), - ( - 'client', uint32_t), - ( - 'source', uint32_t), - ( - 'sample_spec', pa_sample_spec), - ( - 'channel_map', pa_channel_map), - ( - 'buffer_usec', pa_usec_t), - ( - 'source_usec', pa_usec_t), - ( - 'resample_method', STRING), - ( - 'driver', STRING), - ( - 'proplist', POINTER(pa_proplist)), - ( - 'corked', c_int), - ( - 'volume', pa_cvolume), - ( - 'mute', c_int), - ( - 'has_volume', c_int), - ( - 'volume_writable', c_int), - ( - 'format', POINTER(pa_format_info))] + ( + 'index', uint32_t), + ( + 'name', STRING), + ( + 'owner_module', uint32_t), + ( + 'client', uint32_t), + ( + 'source', uint32_t), + ( + 'sample_spec', pa_sample_spec), + ( + 'channel_map', pa_channel_map), + ( + 'buffer_usec', pa_usec_t), + ( + 'source_usec', pa_usec_t), + ( + 'resample_method', STRING), + ( + 'driver', STRING), + ( + 'proplist', POINTER(pa_proplist)), + ( + 'corked', c_int), + ( + 'volume', pa_cvolume), + ( + 'mute', c_int), + ( + 'has_volume', c_int), + ( + 'volume_writable', c_int), + ( + 'format', POINTER(pa_format_info))] pa_source_output_info_cb_t = CFUNCTYPE(None, POINTER(pa_context), POINTER(pa_source_output_info), c_int, c_void_p) pa_context_get_source_output_info = _libraries['libpulse.so.0'].pa_context_get_source_output_info pa_context_get_source_output_info.restype = POINTER(pa_operation) @@ -1075,13 +1109,16 @@ class pa_source_output_info(Structure): pa_context_get_source_output_info_list.argtypes = [POINTER(pa_context), pa_source_output_info_cb_t, c_void_p] pa_context_move_source_output_by_name = _libraries['libpulse.so.0'].pa_context_move_source_output_by_name pa_context_move_source_output_by_name.restype = POINTER(pa_operation) -pa_context_move_source_output_by_name.argtypes = [POINTER(pa_context), uint32_t, STRING, pa_context_success_cb_t, c_void_p] +pa_context_move_source_output_by_name.argtypes = [POINTER(pa_context), uint32_t, STRING, pa_context_success_cb_t, + c_void_p] pa_context_move_source_output_by_index = _libraries['libpulse.so.0'].pa_context_move_source_output_by_index pa_context_move_source_output_by_index.restype = POINTER(pa_operation) -pa_context_move_source_output_by_index.argtypes = [POINTER(pa_context), uint32_t, uint32_t, pa_context_success_cb_t, c_void_p] +pa_context_move_source_output_by_index.argtypes = [POINTER(pa_context), uint32_t, uint32_t, pa_context_success_cb_t, + c_void_p] pa_context_set_source_output_volume = _libraries['libpulse.so.0'].pa_context_set_source_output_volume pa_context_set_source_output_volume.restype = POINTER(pa_operation) -pa_context_set_source_output_volume.argtypes = [POINTER(pa_context), uint32_t, POINTER(pa_cvolume), pa_context_success_cb_t, c_void_p] +pa_context_set_source_output_volume.argtypes = [POINTER(pa_context), uint32_t, POINTER(pa_cvolume), + pa_context_success_cb_t, c_void_p] pa_context_set_source_output_mute = _libraries['libpulse.so.0'].pa_context_set_source_output_mute pa_context_set_source_output_mute.restype = POINTER(pa_operation) pa_context_set_source_output_mute.argtypes = [POINTER(pa_context), uint32_t, c_int, pa_context_success_cb_t, c_void_p] @@ -1089,51 +1126,53 @@ class pa_source_output_info(Structure): pa_context_kill_source_output.restype = POINTER(pa_operation) pa_context_kill_source_output.argtypes = [POINTER(pa_context), uint32_t, pa_context_success_cb_t, c_void_p] + class pa_stat_info(Structure): pass pa_stat_info._fields_ = [ - ( - 'memblock_total', uint32_t), - ( - 'memblock_total_size', uint32_t), - ( - 'memblock_allocated', uint32_t), - ( - 'memblock_allocated_size', uint32_t), - ( - 'scache_size', uint32_t)] + ( + 'memblock_total', uint32_t), + ( + 'memblock_total_size', uint32_t), + ( + 'memblock_allocated', uint32_t), + ( + 'memblock_allocated_size', uint32_t), + ( + 'scache_size', uint32_t)] pa_stat_info_cb_t = CFUNCTYPE(None, POINTER(pa_context), POINTER(pa_stat_info), c_void_p) pa_context_stat = _libraries['libpulse.so.0'].pa_context_stat pa_context_stat.restype = POINTER(pa_operation) pa_context_stat.argtypes = [POINTER(pa_context), pa_stat_info_cb_t, c_void_p] + class pa_sample_info(Structure): pass pa_sample_info._fields_ = [ - ( - 'index', uint32_t), - ( - 'name', STRING), - ( - 'volume', pa_cvolume), - ( - 'sample_spec', pa_sample_spec), - ( - 'channel_map', pa_channel_map), - ( - 'duration', pa_usec_t), - ( - 'bytes', uint32_t), - ( - 'lazy', c_int), - ( - 'filename', STRING), - ( - 'proplist', POINTER(pa_proplist))] + ( + 'index', uint32_t), + ( + 'name', STRING), + ( + 'volume', pa_cvolume), + ( + 'sample_spec', pa_sample_spec), + ( + 'channel_map', pa_channel_map), + ( + 'duration', pa_usec_t), + ( + 'bytes', uint32_t), + ( + 'lazy', c_int), + ( + 'filename', STRING), + ( + 'proplist', POINTER(pa_proplist))] pa_sample_info_cb_t = CFUNCTYPE(None, POINTER(pa_context), POINTER(pa_sample_info), c_int, c_void_p) pa_context_get_sample_info_by_name = _libraries['libpulse.so.0'].pa_context_get_sample_info_by_name pa_context_get_sample_info_by_name.restype = POINTER(pa_operation) @@ -1147,25 +1186,27 @@ class pa_sample_info(Structure): pa_autoload_type = c_int pa_autoload_type_t = pa_autoload_type + class pa_autoload_info(Structure): pass pa_autoload_info._fields_ = [ - ( - 'index', uint32_t), - ( - 'name', STRING), - ( - 'type', pa_autoload_type_t), - ( - 'module', STRING), - ( - 'argument', STRING)] + ( + 'index', uint32_t), + ( + 'name', STRING), + ( + 'type', pa_autoload_type_t), + ( + 'module', STRING), + ( + 'argument', STRING)] pa_autoload_info_cb_t = CFUNCTYPE(None, POINTER(pa_context), POINTER(pa_autoload_info), c_int, c_void_p) pa_context_get_autoload_info_by_name = _libraries['libpulse.so.0'].pa_context_get_autoload_info_by_name pa_context_get_autoload_info_by_name.restype = POINTER(pa_operation) -pa_context_get_autoload_info_by_name.argtypes = [POINTER(pa_context), STRING, pa_autoload_type_t, pa_autoload_info_cb_t, c_void_p] +pa_context_get_autoload_info_by_name.argtypes = [POINTER(pa_context), STRING, pa_autoload_type_t, pa_autoload_info_cb_t, + c_void_p] pa_context_get_autoload_info_by_index = _libraries['libpulse.so.0'].pa_context_get_autoload_info_by_index pa_context_get_autoload_info_by_index.restype = POINTER(pa_operation) pa_context_get_autoload_info_by_index.argtypes = [POINTER(pa_context), uint32_t, pa_autoload_info_cb_t, c_void_p] @@ -1174,16 +1215,19 @@ class pa_autoload_info(Structure): pa_context_get_autoload_info_list.argtypes = [POINTER(pa_context), pa_autoload_info_cb_t, c_void_p] pa_context_add_autoload = _libraries['libpulse.so.0'].pa_context_add_autoload pa_context_add_autoload.restype = POINTER(pa_operation) -pa_context_add_autoload.argtypes = [POINTER(pa_context), STRING, pa_autoload_type_t, STRING, STRING, pa_context_index_cb_t, c_void_p] +pa_context_add_autoload.argtypes = [POINTER(pa_context), STRING, pa_autoload_type_t, STRING, STRING, + pa_context_index_cb_t, c_void_p] pa_context_remove_autoload_by_name = _libraries['libpulse.so.0'].pa_context_remove_autoload_by_name pa_context_remove_autoload_by_name.restype = POINTER(pa_operation) -pa_context_remove_autoload_by_name.argtypes = [POINTER(pa_context), STRING, pa_autoload_type_t, pa_context_success_cb_t, c_void_p] +pa_context_remove_autoload_by_name.argtypes = [POINTER(pa_context), STRING, pa_autoload_type_t, pa_context_success_cb_t, + c_void_p] pa_context_remove_autoload_by_index = _libraries['libpulse.so.0'].pa_context_remove_autoload_by_index pa_context_remove_autoload_by_index.restype = POINTER(pa_operation) pa_context_remove_autoload_by_index.argtypes = [POINTER(pa_context), uint32_t, pa_context_success_cb_t, c_void_p] pa_io_event_flags = c_int pa_io_event_flags_t = pa_io_event_flags + class pa_io_event(Structure): pass @@ -1194,6 +1238,7 @@ class pa_io_event(Structure): pa_time_event._fields_ = [] pa_time_event_destroy_cb_t = CFUNCTYPE(None, POINTER(pa_mainloop_api), POINTER(pa_time_event), c_void_p) + class pa_defer_event(Structure): pass @@ -1202,37 +1247,42 @@ class pa_defer_event(Structure): pa_defer_event_cb_t = CFUNCTYPE(None, POINTER(pa_mainloop_api), POINTER(pa_defer_event), c_void_p) pa_defer_event_destroy_cb_t = CFUNCTYPE(None, POINTER(pa_mainloop_api), POINTER(pa_defer_event), c_void_p) pa_mainloop_api._fields_ = [ - ( - 'userdata', c_void_p), - ( - 'io_new', CFUNCTYPE(POINTER(pa_io_event), POINTER(pa_mainloop_api), c_int, pa_io_event_flags_t, pa_io_event_cb_t, c_void_p)), - ( - 'io_enable', CFUNCTYPE(None, POINTER(pa_io_event), pa_io_event_flags_t)), - ( - 'io_free', CFUNCTYPE(None, POINTER(pa_io_event))), - ( - 'io_set_destroy', CFUNCTYPE(None, POINTER(pa_io_event), pa_io_event_destroy_cb_t)), - ( - 'time_new', CFUNCTYPE(POINTER(pa_time_event), POINTER(pa_mainloop_api), POINTER(timeval), pa_time_event_cb_t, c_void_p)), - ( - 'time_restart', CFUNCTYPE(None, POINTER(pa_time_event), POINTER(timeval))), - ( - 'time_free', CFUNCTYPE(None, POINTER(pa_time_event))), - ( - 'time_set_destroy', CFUNCTYPE(None, POINTER(pa_time_event), pa_time_event_destroy_cb_t)), - ( - 'defer_new', CFUNCTYPE(POINTER(pa_defer_event), POINTER(pa_mainloop_api), pa_defer_event_cb_t, c_void_p)), - ( - 'defer_enable', CFUNCTYPE(None, POINTER(pa_defer_event), c_int)), - ( - 'defer_free', CFUNCTYPE(None, POINTER(pa_defer_event))), - ( - 'defer_set_destroy', CFUNCTYPE(None, POINTER(pa_defer_event), pa_defer_event_destroy_cb_t)), - ( - 'quit', CFUNCTYPE(None, POINTER(pa_mainloop_api), c_int))] + ( + 'userdata', c_void_p), + ( + 'io_new', + CFUNCTYPE(POINTER(pa_io_event), POINTER(pa_mainloop_api), c_int, pa_io_event_flags_t, pa_io_event_cb_t, + c_void_p)), + ( + 'io_enable', CFUNCTYPE(None, POINTER(pa_io_event), pa_io_event_flags_t)), + ( + 'io_free', CFUNCTYPE(None, POINTER(pa_io_event))), + ( + 'io_set_destroy', CFUNCTYPE(None, POINTER(pa_io_event), pa_io_event_destroy_cb_t)), + ( + 'time_new', + CFUNCTYPE(POINTER(pa_time_event), POINTER(pa_mainloop_api), POINTER(timeval), pa_time_event_cb_t, c_void_p)), + ( + 'time_restart', CFUNCTYPE(None, POINTER(pa_time_event), POINTER(timeval))), + ( + 'time_free', CFUNCTYPE(None, POINTER(pa_time_event))), + ( + 'time_set_destroy', CFUNCTYPE(None, POINTER(pa_time_event), pa_time_event_destroy_cb_t)), + ( + 'defer_new', CFUNCTYPE(POINTER(pa_defer_event), POINTER(pa_mainloop_api), pa_defer_event_cb_t, c_void_p)), + ( + 'defer_enable', CFUNCTYPE(None, POINTER(pa_defer_event), c_int)), + ( + 'defer_free', CFUNCTYPE(None, POINTER(pa_defer_event))), + ( + 'defer_set_destroy', CFUNCTYPE(None, POINTER(pa_defer_event), pa_defer_event_destroy_cb_t)), + ( + 'quit', CFUNCTYPE(None, POINTER(pa_mainloop_api), c_int))] pa_mainloop_api_once = _libraries['libpulse.so.0'].pa_mainloop_api_once pa_mainloop_api_once.restype = None -pa_mainloop_api_once.argtypes = [POINTER(pa_mainloop_api), CFUNCTYPE(None, POINTER(pa_mainloop_api), c_void_p), c_void_p] +pa_mainloop_api_once.argtypes = [POINTER(pa_mainloop_api), CFUNCTYPE(None, POINTER(pa_mainloop_api), c_void_p), + c_void_p] + class pa_signal_event(Structure): pass @@ -1257,6 +1307,7 @@ class pa_signal_event(Structure): pa_signal_set_destroy.restype = None pa_signal_set_destroy.argtypes = [POINTER(pa_signal_event), pa_signal_destroy_cb_t] + class pa_mainloop(Structure): pass @@ -1296,6 +1347,7 @@ class pa_mainloop(Structure): pa_mainloop_wakeup.restype = None pa_mainloop_wakeup.argtypes = [POINTER(pa_mainloop)] + class pollfd(Structure): pass @@ -1428,6 +1480,7 @@ class pollfd(Structure): pa_sample_format_is_be.argtypes = [pa_sample_format_t] pa_context_play_sample_cb_t = CFUNCTYPE(None, POINTER(pa_context), uint32_t, c_void_p) + class pa_stream(Structure): pass @@ -1446,7 +1499,8 @@ class pa_stream(Structure): pa_context_play_sample.argtypes = [POINTER(pa_context), STRING, STRING, pa_volume_t, pa_context_success_cb_t, c_void_p] pa_context_play_sample_with_proplist = _libraries['libpulse.so.0'].pa_context_play_sample_with_proplist pa_context_play_sample_with_proplist.restype = POINTER(pa_operation) -pa_context_play_sample_with_proplist.argtypes = [POINTER(pa_context), STRING, STRING, pa_volume_t, POINTER(pa_proplist), pa_context_play_sample_cb_t, c_void_p] +pa_context_play_sample_with_proplist.argtypes = [POINTER(pa_context), STRING, STRING, pa_volume_t, POINTER(pa_proplist), + pa_context_play_sample_cb_t, c_void_p] pa_stream._fields_ = [] pa_stream_success_cb_t = CFUNCTYPE(None, POINTER(pa_stream), c_int, c_void_p) pa_stream_request_cb_t = CFUNCTYPE(None, POINTER(pa_stream), size_t, c_void_p) @@ -1457,10 +1511,12 @@ class pa_stream(Structure): pa_stream_new.argtypes = [POINTER(pa_context), STRING, POINTER(pa_sample_spec), POINTER(pa_channel_map)] pa_stream_new_with_proplist = _libraries['libpulse.so.0'].pa_stream_new_with_proplist pa_stream_new_with_proplist.restype = POINTER(pa_stream) -pa_stream_new_with_proplist.argtypes = [POINTER(pa_context), STRING, POINTER(pa_sample_spec), POINTER(pa_channel_map), POINTER(pa_proplist)] +pa_stream_new_with_proplist.argtypes = [POINTER(pa_context), STRING, POINTER(pa_sample_spec), POINTER(pa_channel_map), + POINTER(pa_proplist)] pa_stream_new_extended = _libraries['libpulse.so.0'].pa_stream_new_extended pa_stream_new_extended.restype = POINTER(pa_stream) -pa_stream_new_extended.argtypes = [POINTER(pa_context), STRING, POINTER(POINTER(pa_format_info)), c_uint, POINTER(pa_proplist)] +pa_stream_new_extended.argtypes = [POINTER(pa_context), STRING, POINTER(POINTER(pa_format_info)), c_uint, + POINTER(pa_proplist)] pa_stream_unref = _libraries['libpulse.so.0'].pa_stream_unref pa_stream_unref.restype = None pa_stream_unref.argtypes = [POINTER(pa_stream)] @@ -1490,7 +1546,8 @@ class pa_stream(Structure): pa_stream_is_corked.argtypes = [POINTER(pa_stream)] pa_stream_connect_playback = _libraries['libpulse.so.0'].pa_stream_connect_playback pa_stream_connect_playback.restype = c_int -pa_stream_connect_playback.argtypes = [POINTER(pa_stream), STRING, POINTER(pa_buffer_attr), pa_stream_flags_t, POINTER(pa_cvolume), POINTER(pa_stream)] +pa_stream_connect_playback.argtypes = [POINTER(pa_stream), STRING, POINTER(pa_buffer_attr), pa_stream_flags_t, + POINTER(pa_cvolume), POINTER(pa_stream)] pa_stream_connect_record = _libraries['libpulse.so.0'].pa_stream_connect_record pa_stream_connect_record.restype = c_int pa_stream_connect_record.argtypes = [POINTER(pa_stream), STRING, POINTER(pa_buffer_attr), pa_stream_flags_t] @@ -1604,7 +1661,8 @@ class pa_stream(Structure): pa_stream_update_sample_rate.argtypes = [POINTER(pa_stream), uint32_t, pa_stream_success_cb_t, c_void_p] pa_stream_proplist_update = _libraries['libpulse.so.0'].pa_stream_proplist_update pa_stream_proplist_update.restype = POINTER(pa_operation) -pa_stream_proplist_update.argtypes = [POINTER(pa_stream), pa_update_mode_t, POINTER(pa_proplist), pa_stream_success_cb_t, c_void_p] +pa_stream_proplist_update.argtypes = [POINTER(pa_stream), pa_update_mode_t, POINTER(pa_proplist), + pa_stream_success_cb_t, c_void_p] pa_stream_proplist_remove = _libraries['libpulse.so.0'].pa_stream_proplist_remove pa_stream_proplist_remove.restype = POINTER(pa_operation) pa_stream_proplist_remove.argtypes = [POINTER(pa_stream), POINTER(STRING), pa_stream_success_cb_t, c_void_p] @@ -1622,6 +1680,7 @@ class pa_stream(Structure): pa_context_set_subscribe_callback.restype = None pa_context_set_subscribe_callback.argtypes = [POINTER(pa_context), pa_context_subscribe_cb_t, c_void_p] + class pa_threaded_mainloop(Structure): pass @@ -1978,421 +2037,421 @@ class pa_threaded_mainloop(Structure): PA_PROP_MEDIA_LANGUAGE = 'media.language' pollfd._fields_ = [] __all__ = [ - 'pa_context_set_name', - 'pa_context_get_source_info_by_index', - 'pa_time_event_destroy_cb_t', 'PA_IO_EVENT_HANGUP', - 'pa_client_info', 'pa_context_set_sink_volume_by_name', - 'pa_stream_request_cb_t', 'PA_PROP_MEDIA_ROLE', - 'PA_STREAM_UPLOAD', 'PA_SUBSCRIPTION_MASK_SOURCE', - 'PA_PROP_DEVICE_API', 'pa_context_get_protocol_version', - 'pa_channel_map_def_t', - 'pa_context_set_card_profile_by_name', - 'pa_context_get_server_info', 'pa_stream_set_buffer_attr', - 'pa_context_get_sample_info_by_index', 'uint8_t', - 'pa_get_host_name', 'pa_bytes_to_usec', 'pa_free_cb_t', - 'pa_format_info_set_channel_map', - 'pa_context_get_client_info_list', - 'pa_threaded_mainloop_in_thread', 'pa_xfree', - 'pa_proplist_iterate', - 'PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE', 'PA_VOLUME_MUTED', - 'pa_context_move_sink_input_by_index', - 'pa_context_suspend_sink_by_name', 'PA_CONTEXT_NOFAIL', - 'PA_PROP_DEVICE_CLASS', 'pa_encoding_t', - 'pa_stream_set_name', 'PA_PROP_FILTER_SUPPRESS', - 'pa_stream_set_event_callback', 'pa_channel_map_valid', - 'PA_CHANNEL_POSITION_SUBWOOFER', 'pa_signal_destroy_cb_t', - 'pa_channel_position_from_string', '__time_t', - 'pa_seek_mode', 'PA_SUBSCRIPTION_MASK_CLIENT', - 'pa_context_set_sink_volume_by_index', - 'pa_context_get_module_info', 'pa_sample_spec_init', - 'PA_RATE_MAX', 'pa_channel_position_mask_t', - 'PA_SINK_LATENCY', 'PA_PROP_MEDIA_ICON', 'PA_USEC_INVALID', - 'pa_cvolume_set_fade', - 'pa_context_remove_autoload_by_name', - 'pa_mainloop_get_retval', - 'pa_format_info_set_prop_string_array', 'PA_SINK_UNLINKED', - 'pa_subscription_event_type_t', 'PA_ERR_TIMEOUT', - 'PA_PROP_APPLICATION_PROCESS_ID', - 'pa_context_get_source_output_info_list', 'pa_sample_spec', - 'pa_context_play_sample_with_proplist', - 'PA_ENCODING_DTS_IEC61937', 'PA_ERR_NOTSUPPORTED', - 'pa_stream_get_channel_map', 'pa_channel_map_parse', - 'pa_channel_map_equal', 'PA_CHANNEL_POSITION_MAX', - 'pa_cvolume_remap', 'PA_STREAM_AUTO_TIMING_UPDATE', - 'PA_STREAM_PASSTHROUGH', 'PA_PROP_DEVICE_STRING', - 'pa_context_get_autoload_info_by_index', - 'pa_format_info_is_compatible', - 'pa_context_play_sample_cb_t', 'pa_proplist_size', - 'pa_xstrdup', 'pa_stream_get_timing_info', - 'pa_cvolume_get_position', 'PA_CHANNEL_POSITION_AUX18', - 'PA_CHANNEL_POSITION_AUX19', 'pa_signal_init', - 'PA_CHANNEL_POSITION_AUX10', 'PA_CHANNEL_POSITION_AUX11', - 'PA_CHANNEL_POSITION_AUX12', 'PA_CHANNEL_POSITION_AUX13', - 'PA_CHANNEL_POSITION_AUX14', 'PA_CHANNEL_POSITION_AUX15', - 'PA_CHANNEL_POSITION_AUX16', 'PA_CHANNEL_POSITION_AUX17', - 'pa_stream_set_moved_callback', 'pa_stream_trigger', - 'pa_timeval_age', 'PA_SAMPLE_U8', 'PA_SINK_HARDWARE', - 'pa_stream_get_device_index', 'pa_cvolume_max', - 'PA_PROP_EVENT_ID', 'PA_NSEC_PER_USEC', - 'pa_format_info_set_rate', 'pa_stream_state_t', - 'PA_BYTES_SNPRINT_MAX', 'pa_proplist_from_string', - 'PA_CHANNEL_POSITION_INVALID', 'PA_ERR_INTERNAL', - 'PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER', - 'pa_cvolume_avg', 'pa_stream_state', - 'PA_PROP_WINDOW_X11_XID', 'PA_CONTEXT_UNCONNECTED', - 'PA_SUBSCRIPTION_EVENT_MODULE', 'PA_ERR_TOOLARGE', - 'PA_CHANNEL_MAP_ALSA', 'PA_STREAM_FIX_FORMAT', - 'PA_SOURCE_HARDWARE', 'PA_CHANNEL_POSITION_CENTER', - 'PA_PROP_WINDOW_X11_MONITOR', - 'pa_context_set_source_volume_by_index', - 'PA_PROP_MEDIA_FILENAME', 'PA_SINK_DECIBEL_VOLUME', - 'pa_operation_ref', 'pa_format_info_copy', - 'pa_channel_position_t', 'pa_sample_format_t', - 'pa_stream_flush', 'PA_PROP_FORMAT_SAMPLE_FORMAT', - 'PA_SEEK_ABSOLUTE', 'PA_PROP_MEDIA_TITLE', - 'PA_SAMPLE_SPEC_SNPRINT_MAX', 'PA_SOURCE_INVALID_STATE', - 'pa_stream_set_write_callback', 'PA_SOURCE_LATENCY', - 'PA_CHANNELS_MAX', 'PA_CONTEXT_NOAUTOSPAWN', - 'pa_cvolume_set_position', 'pa_sample_info', - 'pa_subscription_mask_t', 'PA_SUBSCRIPTION_EVENT_SOURCE', - 'pa_io_event_flags', 'pa_context_errno', - 'PA_CONTEXT_READY', 'PA_SAMPLE_S24BE', - 'pa_threaded_mainloop_wait', 'pa_stream_connect_record', - 'pa_context_remove_autoload_by_index', - 'PA_SEEK_RELATIVE_END', 'pa_timing_info', - 'pa_path_get_filename', 'pa_stream_get_buffer_attr', - 'PA_STREAM_EVENT_REQUEST_UNCORK', 'pa_defer_event', - 'pa_get_binary_name', 'pa_channel_map_can_balance', - 'PA_API_VERSION', 'pa_stream_set_buffer_attr_callback', - 'PA_CHANNEL_MAP_OSS', 'pa_format_info_is_pcm', - 'pa_context_get_server_protocol_version', - 'pa_sample_format_is_be', 'PA_SUBSCRIPTION_EVENT_CLIENT', - 'pa_stream_ref', 'PA_SOURCE_HW_VOLUME_CTRL', - 'PA_PROP_MEDIA_COPYRIGHT', 'pollfd', 'PA_ERR_ACCESS', - 'PA_CHANNEL_POSITION_TOP_FRONT_RIGHT', - 'pa_defer_event_destroy_cb_t', 'pa_strerror', - 'pa_channel_map_snprint', 'PA_STREAM_FIX_RATE', - 'pa_context_drain', 'pa_stream_direction_t', - 'PA_PROP_DEVICE_VENDOR_NAME', - 'PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE', - 'PA_PROP_APPLICATION_PROCESS_HOST', - 'pa_stream_get_format_info', 'PA_PROP_APPLICATION_NAME', - 'pa_signal_new', 'PA_SAMPLE_S24_32BE', 'PA_SOURCE_NETWORK', - 'PA_SUBSCRIPTION_EVENT_FACILITY_MASK', - 'pa_mainloop_wakeup', 'pa_xstrndup', 'PA_SEEK_RELATIVE', - 'pa_module_info', 'pa_encoding_to_string', 'PA_ERR_IO', - 'pa_stream_flags_t', 'pa_timeval_sub', 'pa_timeval_add', - 'PA_CHANNEL_POSITION_TOP_REAR_CENTER', - 'PA_CONTEXT_CONNECTING', 'pa_context_add_autoload', - 'pa_sw_cvolume_divide', - 'pa_context_set_source_mute_by_name', - 'PA_SUBSCRIPTION_MASK_AUTOLOAD', 'pa_stream_cancel_write', - 'PA_SINK_HW_MUTE_CTRL', 'PA_CHANNEL_POSITION_AUX21', - 'PA_CHANNEL_POSITION_AUX20', 'PA_CHANNEL_POSITION_AUX23', - 'PA_CHANNEL_POSITION_AUX22', 'PA_CHANNEL_POSITION_AUX25', - 'PA_UPDATE_MERGE', 'PA_CHANNEL_POSITION_AUX27', - 'PA_SOURCE_DYNAMIC_LATENCY', 'PA_CHANNEL_POSITION_AUX29', - 'PA_CHANNEL_POSITION_AUX28', - 'pa_stream_set_started_callback', 'PA_SINK_FLAT_VOLUME', - 'size_t', 'pa_context_flags', 'pa_utf8_to_locale', - 'pa_proplist_sets', 'pa_proplist_setp', - 'PA_ERR_CONNECTIONTERMINATED', 'pa_format_info_free', - 'PA_PROP_WINDOW_ICON', 'pa_operation_cancel', - 'PA_CHANNEL_MAP_SNPRINT_MAX', 'PA_DEVICE_TYPE_SINK', - 'PA_CHANNEL_POSITION_TOP_FRONT_CENTER', - 'pa_format_info_from_string', 'pa_proplist_setf', - 'pa_cvolume_set', 'pa_bytes_per_second', - 'PA_PROP_DEVICE_PROFILE_DESCRIPTION', 'pa_stream', - 'PA_ERR_COMMAND', 'PA_SUBSCRIPTION_MASK_SINK_INPUT', - 'pa_channel_map_to_pretty_name', 'pa_card_info', - 'PA_CONTEXT_SETTING_NAME', 'PA_IO_EVENT_OUTPUT', - 'PA_PROP_FORMAT_CHANNEL_MAP', - 'pa_context_set_card_profile_by_index', - 'PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER', - 'pa_sample_info_cb_t', 'pa_source_state', - 'pa_channel_map_init_mono', 'pa_stream_readable_size', - 'PA_PROP_WINDOW_WIDTH', 'pa_stream_set_suspended_callback', - 'pa_cvolume_scale_mask', 'pa_stream_get_underflow_index', - 'pa_stream_begin_write', 'pa_stream_get_time', - 'pa_cvolume', 'pa_context_set_state_callback', - 'pa_sw_cvolume_multiply', 'PA_CHANNEL_POSITION_REAR_LEFT', - 'PA_ERR_EXIST', 'pa_threaded_mainloop_lock', 'pa_io_event', - 'PA_VOLUME_NORM', 'pa_proplist_unset_many', - 'PA_SAMPLE_MAX', 'PA_SOURCE_DECIBEL_VOLUME', - 'PA_PROP_WINDOW_Y', 'PA_PROP_WINDOW_X', - 'pa_stream_get_state', 'pa_frame_size', - 'pa_sample_size_of_format', 'PA_SAMPLE_FLOAT32LE', - 'PA_STREAM_FIX_CHANNELS', 'PA_CONTEXT_NOFLAGS', - 'PA_STREAM_EARLY_REQUESTS', 'pa_update_mode_t', - 'pa_proplist_unset', 'PA_ERR_PROTOCOL', - 'PA_PROP_MODULE_AUTHOR', 'PA_SOURCE_HW_MUTE_CTRL', - 'pa_context_set_subscribe_callback', - 'PA_PROP_MODULE_VERSION', 'PA_ENCODING_ANY', - 'pa_context_set_default_sink', 'PA_SAMPLE_S24_32LE', - 'pa_context_get_client_info', 'PA_ENCODING_PCM', - 'pa_stream_notify_cb_t', 'pa_context_index_cb_t', - 'pa_cvolume_merge', 'PA_ENCODING_MAX', 'pa_signal_done', - 'pa_threaded_mainloop_new', 'PA_PROP_DEVICE_ICON', - 'pa_channel_map_init_extend', 'PA_SUBSCRIPTION_MASK_SINK', - 'pa_context_set_sink_mute_by_name', 'pa_sample_spec_equal', - 'pa_mainloop_api_once', 'pa_threaded_mainloop_stop', - 'pa_timeval_cmp', 'pa_source_flags_t', 'pa_sink_flags', - 'pa_io_event_cb_t', 'pa_mainloop_get_api', - 'PA_CHANNEL_MAP_DEF_MAX', 'pa_usec_to_bytes', - 'PA_ERR_VERSION', 'pa_stream_prebuf', 'PA_IO_EVENT_NULL', - 'PA_OPERATION_RUNNING', 'PA_CHANNEL_POSITION_LEFT', - 'pa_cvolume_min', 'PA_CHANNEL_POSITION_RIGHT', - 'PA_SINK_INVALID_STATE', 'PA_SUBSCRIPTION_EVENT_SINK', - 'pa_io_event_flags_t', '__suseconds_t', - 'pa_channel_map_init_stereo', 'PA_CHANNEL_MAP_AUX', - 'pa_threaded_mainloop_unlock', 'PA_SINK_RUNNING', - 'pa_source_flags', 'pa_stream_proplist_remove', - 'pa_get_library_version', 'PA_SINK_NETWORK', - 'pa_stream_event_cb_t', 'PA_ENCODING_MPEG_IEC61937', - 'PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT', 'pa_source_state_t', - 'pa_xmalloc0', 'PA_UPDATE_SET', - 'pa_stream_update_timing_info', - 'PA_SUBSCRIPTION_EVENT_REMOVE', 'pa_stat_info', - 'PA_CONTEXT_AUTHORIZING', 'pa_proplist_new', - 'PA_SOURCE_INIT', 'pa_mainloop', 'PA_USEC_PER_SEC', - 'pa_stream_writable_size', 'PA_PROP_EVENT_MOUSE_HPOS', - 'PA_SUBSCRIPTION_MASK_CARD', - 'pa_context_set_sink_port_by_name', - 'pa_sw_cvolume_snprint_dB', - 'PA_SUBSCRIPTION_MASK_SAMPLE_CACHE', 'PA_PROP_FILTER_WANT', - 'PA_STREAM_INTERPOLATE_TIMING', - 'pa_context_set_sink_input_volume', - 'pa_stream_proplist_update', 'pa_volume_snprint', - 'pa_context_get_sink_info_by_name', 'uint64_t', - 'PA_CVOLUME_SNPRINT_MAX', 'pa_spawn_api', - 'PA_CHANNEL_POSITION_TOP_FRONT_LEFT', - 'pa_context_set_sink_input_mute', 'PA_USEC_MAX', - 'PA_CHANNEL_POSITION_TOP_CENTER', 'pa_get_home_dir', - 'pa_operation_unref', 'PA_ERR_BADSTATE', 'pa_mainloop_run', - 'pa_mainloop_iterate', 'PA_SUBSCRIPTION_MASK_NULL', - 'pa_cvolume_inc_clamp', 'PA_PROP_MODULE_USAGE', - 'pa_device_type', 'pa_sample_format_is_le', 'pa_xmalloc', - 'PA_ERR_MODINITFAILED', 'timeval', - 'PA_PROP_WINDOW_ICON_NAME', 'pa_sample_spec_snprint', - 'PA_MSEC_PER_SEC', 'pa_stream_get_sample_spec', - 'PA_STREAM_START_UNMUTED', 'PA_STREAM_TERMINATED', - 'pa_context_get_card_info_list', 'pa_cvolume_scale', - 'pa_proplist', 'pa_cvolume_init', - 'pa_stream_set_read_callback', 'pa_server_info', - 'PA_PROP_APPLICATION_ICON_NAME', 'PA_SAMPLE_ALAW', - 'PA_SUBSCRIPTION_MASK_MODULE', 'PA_STREAM_FAILED', - 'pa_sw_volume_divide', 'pa_stream_finish_upload', - 'PA_PROP_EVENT_DESCRIPTION', 'pa_sw_volume_from_dB', - 'pa_format_info_set_prop_int_array', 'PA_ERR_AUTHKEY', - 'PA_SUBSCRIPTION_EVENT_NEW', 'PA_STREAM_EVENT_FORMAT_LOST', - 'PA_SUBSCRIPTION_EVENT_SINK_INPUT', - 'PA_PROP_FORMAT_CHANNELS', 'PA_PROP_MEDIA_LANGUAGE', - 'pa_source_output_info', 'pa_context_state_t', - 'PA_PROP_APPLICATION_ICON', - 'PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND', - 'PA_PROP_WINDOW_DESKTOP', 'pa_io_event_destroy_cb_t', - 'PA_ERR_MAX', 'pa_proplist_to_string', - 'PA_CHANNEL_POSITION_SIDE_RIGHT', 'pa_context_stat', - 'pa_locale_to_utf8', 'pa_context_set_source_port_by_index', - 'pa_stream_set_latency_update_callback', - 'PA_PROP_WINDOW_VPOS', 'pa_operation_state_t', - 'PA_CHANNEL_POSITION_AUX24', 'pa_context_get_state', - 'PA_ERR_FORKED', 'pa_source_info', - 'PA_CHANNEL_POSITION_AUX26', 'PA_ERR_CONNECTIONREFUSED', - 'PA_CHANNEL_POSITION_FRONT_RIGHT', 'pa_sample_size', - 'PA_PROP_DEVICE_DESCRIPTION', 'pa_msleep', - 'PA_USEC_PER_MSEC', 'pa_context_get_sink_info_list', - 'PA_CHANNEL_POSITION_AUX30', 'PA_CHANNEL_POSITION_AUX31', - 'PA_SAMPLE_INVALID', 'PA_SAMPLE_ULAW', 'pa_usec_t', - 'pa_autoload_info_cb_t', 'pa_gettimeofday', - 'pa_card_info_cb_t', 'PA_STREAM_ADJUST_LATENCY', - 'PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE', - 'pa_cvolume_equal', 'pa_parse_sample_format', - 'PA_IO_EVENT_ERROR', 'pa_context_set_sink_port_by_index', - 'PA_DEVICE_TYPE_SOURCE', 'pa_threaded_mainloop_get_api', - 'pa_bytes_snprint', 'pa_context_event_cb_t', - 'pa_cvolume_valid', 'pa_context_rttime_restart', - 'PA_PROP_EVENT_MOUSE_VPOS', 'pa_mainloop_poll', - 'PA_STREAM_NO_REMAP_CHANNELS', 'pa_mainloop_free', - 'PA_SINK_SUSPENDED', 'pa_threaded_mainloop_start', - 'pa_format_info_set_sample_format', - 'pa_format_info_set_prop_int', 'PA_PROP_MEDIA_ICON_NAME', - 'pa_autoload_type', 'pa_threaded_mainloop', - 'PA_SINK_DYNAMIC_LATENCY', 'pa_context_kill_client', - 'pa_sink_state', 'pa_stream_write', 'pa_sink_port_info', - 'pa_mainloop_new', 'pa_context_get_source_info_by_name', - 'PA_STREAM_NO_REMIX_CHANNELS', 'pa_context_remove_sample', - 'PA_MAJOR', 'PA_STREAM_FAIL_ON_SUSPEND', - 'pa_context_get_tile_size', 'pa_stream_set_state_callback', - 'PA_PROP_APPLICATION_PROCESS_SESSION_ID', - 'pa_client_info_cb_t', 'pa_stream_connect_playback', - 'pa_context_unref', 'pa_format_info_set_prop_int_range', - 'pa_context_new_with_proplist', 'PA_PROP_DEVICE_BUS', - 'PA_SINK_SET_FORMATS', 'pa_stream_new_extended', - 'PA_CHANNEL_POSITION_TOP_REAR_LEFT', - 'PA_SUBSCRIPTION_EVENT_AUTOLOAD', - 'PA_CHANNEL_POSITION_FRONT_CENTER', - 'PA_SEEK_RELATIVE_ON_READ', 'pa_channel_position', - 'pa_mainloop_api', 'pa_proplist_gets', - 'pa_context_set_default_source', 'PA_CHANNEL_POSITION_LFE', - 'pa_sample_format', 'pa_sw_cvolume_divide_scalar', - 'pa_cvolume_min_mask', 'PA_STREAM_PEAK_DETECT', - 'PA_IO_EVENT_INPUT', 'PA_STREAM_VARIABLE_RATE', - 'PA_ERR_NODATA', 'PA_DECIBEL_MININFTY', - 'PA_PROP_WINDOW_NAME', - 'pa_channel_position_to_pretty_string', - 'pa_stream_is_corked', 'pa_context_get_sink_input_info', - 'pa_sw_volume_snprint_dB', - 'pa_context_move_source_output_by_name', - 'pa_stream_get_device_name', 'pa_operation_state', - 'pa_channel_map_mask', 'pa_stream_disconnect', - 'PA_PROP_DEVICE_FORM_FACTOR', - 'PA_PROP_APPLICATION_PROCESS_MACHINE_ID', - 'pa_cvolume_set_balance', - 'PA_PROP_APPLICATION_PROCESS_USER', 'pa_get_user_name', - 'PA_STREAM_EVENT_REQUEST_CORK', - 'pa_proplist_to_string_sep', 'PA_STREAM_START_MUTED', - 'PA_SOURCE_NOFLAGS', 'pa_threaded_mainloop_accept', - 'PA_SAMPLE_S32LE', 'pa_context_notify_cb_t', - 'pa_context_set_source_mute_by_index', 'PA_SOURCE_IDLE', - 'pa_context_suspend_source_by_index', - 'PA_PROP_MEDIA_SOFTWARE', 'PA_PROP_WINDOW_ID', - 'PA_PROP_WINDOW_HPOS', 'pa_context_play_sample', - 'pa_channel_map_to_name', - 'pa_context_get_module_info_list', 'pa_operation', - 'PA_STREAM_RECORD', 'PA_AUTOLOAD_SOURCE', - 'pa_context_get_card_info_by_name', - 'PA_PROP_DEVICE_ACCESS_MODE', 'pa_context_subscribe', - 'PA_AUTOLOAD_SINK', 'pa_context_get_source_info_list', - 'PA_MINOR', 'pa_timeval_diff', 'PA_SOURCE_RUNNING', - 'pa_server_info_cb_t', 'pa_context_ref', - 'pa_sw_cvolume_multiply_scalar', - 'PA_SW_CVOLUME_SNPRINT_DB_MAX', 'PA_VOLUME_SNPRINT_MAX', - 'pa_time_event_cb_t', 'pa_stream_get_latency', - 'pa_xmemdup', 'PA_CHANNEL_POSITION_MONO', - 'PA_CHANNEL_MAP_DEFAULT', 'PA_OPERATION_DONE', - 'pa_mainloop_dispatch', 'pa_proplist_set', 'PA_SINK_INIT', - 'pa_cvolume_max_mask', 'PA_STREAM_NODIRECTION', - 'PA_PROP_DEVICE_SERIAL', 'pa_autoload_info', - 'PA_PROP_APPLICATION_VERSION', - 'pa_context_kill_sink_input', 'PA_PROP_WINDOW_X11_DISPLAY', - 'pa_sink_info_cb_t', 'pa_channel_map_superset', - 'PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT', - 'pa_card_profile_info', 'pa_context_get_sample_info_list', - 'PA_MICRO', 'PA_PROP_DEVICE_VENDOR_ID', - 'pa_subscription_mask', 'PA_STREAM_DONT_MOVE', - 'pa_threaded_mainloop_free', 'PA_SAMPLE_S16BE', - 'pa_stream_connect_upload', 'PA_FORMAT_INFO_SNPRINT_MAX', - 'PA_ERR_KILLED', 'pa_context_get_source_output_info', - 'pa_stat_info_cb_t', 'pa_ascii_filter', - 'pa_context_get_autoload_info_list', - 'PA_ENCODING_AC3_IEC61937', 'PA_STREAM_PLAYBACK', - 'pa_format_info_set_channels', 'PA_PROP_FILTER_APPLY', - 'pa_sw_volume_to_dB', 'pa_format_info', 'pa_sink_state_t', - 'uint32_t', 'PA_SW_VOLUME_SNPRINT_DB_MAX', 'pa_volume_t', - 'PA_STREAM_UNCONNECTED', 'PA_CHANNEL_MAP_WAVEEX', - 'pa_stream_cork', 'pa_channel_map_init', - 'PA_ENCODING_EAC3_IEC61937', 'pa_stream_new_with_proplist', - 'PA_STREAM_NOFLAGS', 'pa_stream_success_cb_t', - 'PA_STREAM_NOT_MONOTONIC', 'PA_PROP_DEVICE_MASTER_DEVICE', - 'pa_stream_drain', 'PA_SINK_IDLE', 'pa_context_new', - 'pa_context_suspend_sink_by_index', 'pa_cvolume_dec', - 'PA_CONTEXT_TERMINATED', 'pa_context_rttime_new', - 'pa_module_info_cb_t', - 'PA_CHANNEL_POSITION_TOP_REAR_RIGHT', 'PA_NSEC_PER_MSEC', - 'pa_stream_peek', 'PA_PROP_MEDIA_NAME', - 'pa_channel_map_can_fade', 'PA_CONTEXT_FAILED', - 'pa_context_set_sink_mute_by_index', 'pa_sink_info', - 'pa_context_set_source_output_volume', - 'pa_sample_spec_valid', 'pa_operation_get_state', - 'PA_PROP_APPLICATION_PROCESS_BINARY', - 'pa_context_proplist_remove', - 'pa_context_move_source_output_by_index', - 'pa_timeval_load', 'pa_get_fqdn', 'pa_stream_unref', - 'pa_stream_set_monitor_stream', - 'PA_CHANNEL_POSITION_FRONT_LEFT', 'pa_mainloop_quit', - 'pa_channel_map_init_auto', 'pa_cvolume_inc', - 'PA_PROP_DEVICE_PRODUCT_ID', 'pa_cvolume_get_balance', - 'PA_PROTOCOL_VERSION', 'pa_source_info_cb_t', - 'pa_context_get_index', 'pa_signal_free', - 'PA_PROP_DEVICE_BUS_PATH', 'pa_cvolume_compatible', - 'pa_encoding', 'PA_NSEC_PER_SEC', - 'PA_SUBSCRIPTION_MASK_SERVER', 'pa_cvolume_get_fade', - 'pa_context', 'PA_PROP_EVENT_MOUSE_BUTTON', - 'pa_utf8_filter', 'pa_stream_update_sample_rate', - 'PA_PROP_DEVICE_PROFILE_NAME', 'pa_sw_volume_multiply', - 'pa_cvolume_snprint', 'pa_format_info_new', - 'pa_stream_flags', 'PA_CHANNEL_POSITION_AUX2', - 'PA_CHANNEL_POSITION_AUX3', 'PA_CHANNEL_POSITION_AUX0', - 'PA_SAMPLE_S16LE', 'PA_CHANNEL_POSITION_AUX6', - 'PA_STREAM_RELATIVE_VOLUME', 'PA_CHANNEL_POSITION_AUX4', - 'PA_CHANNEL_POSITION_AUX5', 'pa_xrealloc', - 'PA_CHANNEL_POSITION_AUX8', 'PA_CHANNEL_POSITION_AUX9', - 'PA_PROP_WINDOW_X11_SCREEN', 'PA_SOURCE_SUSPENDED', - 'pa_defer_event_cb_t', 'pa_threaded_mainloop_signal', - 'PA_STREAM_START_CORKED', 'pa_time_event', - 'PA_CHANNEL_MAP_AIFF', 'PA_PROP_APPLICATION_LANGUAGE', - 'PA_ERR_NOENTITY', 'PA_CHANNEL_POSITION_REAR_RIGHT', - 'pa_stream_get_context', 'pa_sw_volume_to_linear', - 'pa_source_output_info_cb_t', - 'pa_format_info_set_prop_string', 'pa_proplist_clear', - 'pa_context_get_server', 'pa_stream_set_overflow_callback', - 'PA_ERR_BUSY', 'pa_cvolume_compatible_with_channel_map', - 'PA_PROP_MEDIA_ARTIST', 'pa_utf8_valid', - 'pa_proplist_free', 'pa_stream_set_underflow_callback', - 'pa_channel_map', 'pa_update_mode', - 'PA_PROP_APPLICATION_ID', 'PA_UPDATE_REPLACE', - 'pa_stream_is_suspended', 'PA_SAMPLE_S24LE', - 'PA_ENCODING_INVALID', 'pa_context_get_card_info_by_index', - 'pa_proplist_equal', 'pa_stream_get_index', - 'pa_context_get_sample_info_by_name', - 'PA_SINK_HW_VOLUME_CTRL', 'PA_OPERATION_CANCELLED', - 'pa_context_get_sink_input_info_list', - 'pa_threaded_mainloop_get_retval', 'PA_SAMPLE_S32BE', - 'pa_proplist_copy', 'pa_context_proplist_update', - 'PA_INVALID_INDEX', 'PA_SAMPLE_FLOAT32BE', - 'pa_context_get_sink_info_by_index', 'pa_proplist_update', - 'PA_ERR_UNKNOWN', 'pa_stream_drop', 'pa_signal_cb_t', - 'pa_context_set_source_volume_by_name', - 'pa_context_subscribe_cb_t', 'pa_source_port_info', - 'pa_cvolume_channels_equal_to', 'PA_SINK_NOFLAGS', - 'PA_CHANNEL_POSITION_SIDE_LEFT', 'pa_device_type_t', - 'PA_SUBSCRIPTION_EVENT_CHANGE', 'PA_OK', - 'pa_channel_position_to_string', 'pa_context_load_module', - 'pa_context_connect', 'pa_autoload_type_t', - 'PA_SUBSCRIPTION_EVENT_CARD', - 'PA_CHANNEL_POSITION_REAR_CENTER', 'PA_ERR_INVALID', - 'pa_channel_map_def', 'pa_proplist_get', - 'PA_PROP_FORMAT_RATE', 'pa_context_flags_t', - 'PA_ERR_NOEXTENSION', 'pa_signal_set_destroy', - 'pa_poll_func', 'pa_context_set_source_output_mute', - 'pa_timeval_store', 'PA_SUBSCRIPTION_EVENT_TYPE_MASK', - 'pa_proplist_isempty', 'pa_cvolume_avg_mask', - 'pa_context_exit_daemon', - 'pa_context_suspend_source_by_name', - 'pa_context_set_event_callback', 'PA_ERR_NOTIMPLEMENTED', - 'PA_PROP_EVENT_MOUSE_X', 'PA_PROP_EVENT_MOUSE_Y', - 'pa_subscription_event_type', - 'pa_context_move_sink_input_by_name', 'int64_t', - 'pa_mainloop_set_poll_func', 'PA_SOURCE_FLAT_VOLUME', - 'PA_ERR_OBSOLETE', 'pa_mainloop_prepare', - 'PA_PROP_MODULE_DESCRIPTION', 'pa_context_is_pending', - 'PA_STREAM_CREATING', 'PA_PROP_DEVICE_PRODUCT_NAME', - 'pa_context_get_autoload_info_by_name', 'pa_context_state', - 'pa_ascii_valid', 'pa_context_disconnect', - 'pa_channel_map_compatible', - 'PA_SUBSCRIPTION_EVENT_SERVER', 'pa_stream_direction', - 'PA_SOURCE_UNLINKED', 'pa_sink_flags_t', 'pa_seek_mode_t', - 'pa_context_set_source_port_by_name', - 'pa_context_is_local', 'PA_PROP_DEVICE_INTENDED_ROLES', - 'pa_context_kill_source_output', 'pa_stream_new', - 'PA_SUBSCRIPTION_MASK_ALL', 'pa_proplist_contains', - 'PA_ERR_INVALIDSERVER', 'pa_stream_get_monitor_stream', - 'PA_PROP_DEVICE_ICON_NAME', 'PA_CHANNEL_POSITION_AUX1', - 'pa_sink_input_info_cb_t', 'pa_channel_map_has_position', - 'PA_STREAM_READY', 'pa_sw_volume_from_linear', - 'PA_CHANNEL_POSITION_AUX7', 'pa_context_unload_module', - 'PA_PROP_WINDOW_HEIGHT', 'pa_format_info_valid', - 'pa_signal_event', 'pa_sink_input_info', - 'pa_sample_format_to_string', 'pa_format_info_snprint', - 'pa_context_success_cb_t', 'pa_buffer_attr'] + 'pa_context_set_name', + 'pa_context_get_source_info_by_index', + 'pa_time_event_destroy_cb_t', 'PA_IO_EVENT_HANGUP', + 'pa_client_info', 'pa_context_set_sink_volume_by_name', + 'pa_stream_request_cb_t', 'PA_PROP_MEDIA_ROLE', + 'PA_STREAM_UPLOAD', 'PA_SUBSCRIPTION_MASK_SOURCE', + 'PA_PROP_DEVICE_API', 'pa_context_get_protocol_version', + 'pa_channel_map_def_t', + 'pa_context_set_card_profile_by_name', + 'pa_context_get_server_info', 'pa_stream_set_buffer_attr', + 'pa_context_get_sample_info_by_index', 'uint8_t', + 'pa_get_host_name', 'pa_bytes_to_usec', 'pa_free_cb_t', + 'pa_format_info_set_channel_map', + 'pa_context_get_client_info_list', + 'pa_threaded_mainloop_in_thread', 'pa_xfree', + 'pa_proplist_iterate', + 'PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE', 'PA_VOLUME_MUTED', + 'pa_context_move_sink_input_by_index', + 'pa_context_suspend_sink_by_name', 'PA_CONTEXT_NOFAIL', + 'PA_PROP_DEVICE_CLASS', 'pa_encoding_t', + 'pa_stream_set_name', 'PA_PROP_FILTER_SUPPRESS', + 'pa_stream_set_event_callback', 'pa_channel_map_valid', + 'PA_CHANNEL_POSITION_SUBWOOFER', 'pa_signal_destroy_cb_t', + 'pa_channel_position_from_string', '__time_t', + 'pa_seek_mode', 'PA_SUBSCRIPTION_MASK_CLIENT', + 'pa_context_set_sink_volume_by_index', + 'pa_context_get_module_info', 'pa_sample_spec_init', + 'PA_RATE_MAX', 'pa_channel_position_mask_t', + 'PA_SINK_LATENCY', 'PA_PROP_MEDIA_ICON', 'PA_USEC_INVALID', + 'pa_cvolume_set_fade', + 'pa_context_remove_autoload_by_name', + 'pa_mainloop_get_retval', + 'pa_format_info_set_prop_string_array', 'PA_SINK_UNLINKED', + 'pa_subscription_event_type_t', 'PA_ERR_TIMEOUT', + 'PA_PROP_APPLICATION_PROCESS_ID', + 'pa_context_get_source_output_info_list', 'pa_sample_spec', + 'pa_context_play_sample_with_proplist', + 'PA_ENCODING_DTS_IEC61937', 'PA_ERR_NOTSUPPORTED', + 'pa_stream_get_channel_map', 'pa_channel_map_parse', + 'pa_channel_map_equal', 'PA_CHANNEL_POSITION_MAX', + 'pa_cvolume_remap', 'PA_STREAM_AUTO_TIMING_UPDATE', + 'PA_STREAM_PASSTHROUGH', 'PA_PROP_DEVICE_STRING', + 'pa_context_get_autoload_info_by_index', + 'pa_format_info_is_compatible', + 'pa_context_play_sample_cb_t', 'pa_proplist_size', + 'pa_xstrdup', 'pa_stream_get_timing_info', + 'pa_cvolume_get_position', 'PA_CHANNEL_POSITION_AUX18', + 'PA_CHANNEL_POSITION_AUX19', 'pa_signal_init', + 'PA_CHANNEL_POSITION_AUX10', 'PA_CHANNEL_POSITION_AUX11', + 'PA_CHANNEL_POSITION_AUX12', 'PA_CHANNEL_POSITION_AUX13', + 'PA_CHANNEL_POSITION_AUX14', 'PA_CHANNEL_POSITION_AUX15', + 'PA_CHANNEL_POSITION_AUX16', 'PA_CHANNEL_POSITION_AUX17', + 'pa_stream_set_moved_callback', 'pa_stream_trigger', + 'pa_timeval_age', 'PA_SAMPLE_U8', 'PA_SINK_HARDWARE', + 'pa_stream_get_device_index', 'pa_cvolume_max', + 'PA_PROP_EVENT_ID', 'PA_NSEC_PER_USEC', + 'pa_format_info_set_rate', 'pa_stream_state_t', + 'PA_BYTES_SNPRINT_MAX', 'pa_proplist_from_string', + 'PA_CHANNEL_POSITION_INVALID', 'PA_ERR_INTERNAL', + 'PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER', + 'pa_cvolume_avg', 'pa_stream_state', + 'PA_PROP_WINDOW_X11_XID', 'PA_CONTEXT_UNCONNECTED', + 'PA_SUBSCRIPTION_EVENT_MODULE', 'PA_ERR_TOOLARGE', + 'PA_CHANNEL_MAP_ALSA', 'PA_STREAM_FIX_FORMAT', + 'PA_SOURCE_HARDWARE', 'PA_CHANNEL_POSITION_CENTER', + 'PA_PROP_WINDOW_X11_MONITOR', + 'pa_context_set_source_volume_by_index', + 'PA_PROP_MEDIA_FILENAME', 'PA_SINK_DECIBEL_VOLUME', + 'pa_operation_ref', 'pa_format_info_copy', + 'pa_channel_position_t', 'pa_sample_format_t', + 'pa_stream_flush', 'PA_PROP_FORMAT_SAMPLE_FORMAT', + 'PA_SEEK_ABSOLUTE', 'PA_PROP_MEDIA_TITLE', + 'PA_SAMPLE_SPEC_SNPRINT_MAX', 'PA_SOURCE_INVALID_STATE', + 'pa_stream_set_write_callback', 'PA_SOURCE_LATENCY', + 'PA_CHANNELS_MAX', 'PA_CONTEXT_NOAUTOSPAWN', + 'pa_cvolume_set_position', 'pa_sample_info', + 'pa_subscription_mask_t', 'PA_SUBSCRIPTION_EVENT_SOURCE', + 'pa_io_event_flags', 'pa_context_errno', + 'PA_CONTEXT_READY', 'PA_SAMPLE_S24BE', + 'pa_threaded_mainloop_wait', 'pa_stream_connect_record', + 'pa_context_remove_autoload_by_index', + 'PA_SEEK_RELATIVE_END', 'pa_timing_info', + 'pa_path_get_filename', 'pa_stream_get_buffer_attr', + 'PA_STREAM_EVENT_REQUEST_UNCORK', 'pa_defer_event', + 'pa_get_binary_name', 'pa_channel_map_can_balance', + 'PA_API_VERSION', 'pa_stream_set_buffer_attr_callback', + 'PA_CHANNEL_MAP_OSS', 'pa_format_info_is_pcm', + 'pa_context_get_server_protocol_version', + 'pa_sample_format_is_be', 'PA_SUBSCRIPTION_EVENT_CLIENT', + 'pa_stream_ref', 'PA_SOURCE_HW_VOLUME_CTRL', + 'PA_PROP_MEDIA_COPYRIGHT', 'pollfd', 'PA_ERR_ACCESS', + 'PA_CHANNEL_POSITION_TOP_FRONT_RIGHT', + 'pa_defer_event_destroy_cb_t', 'pa_strerror', + 'pa_channel_map_snprint', 'PA_STREAM_FIX_RATE', + 'pa_context_drain', 'pa_stream_direction_t', + 'PA_PROP_DEVICE_VENDOR_NAME', + 'PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE', + 'PA_PROP_APPLICATION_PROCESS_HOST', + 'pa_stream_get_format_info', 'PA_PROP_APPLICATION_NAME', + 'pa_signal_new', 'PA_SAMPLE_S24_32BE', 'PA_SOURCE_NETWORK', + 'PA_SUBSCRIPTION_EVENT_FACILITY_MASK', + 'pa_mainloop_wakeup', 'pa_xstrndup', 'PA_SEEK_RELATIVE', + 'pa_module_info', 'pa_encoding_to_string', 'PA_ERR_IO', + 'pa_stream_flags_t', 'pa_timeval_sub', 'pa_timeval_add', + 'PA_CHANNEL_POSITION_TOP_REAR_CENTER', + 'PA_CONTEXT_CONNECTING', 'pa_context_add_autoload', + 'pa_sw_cvolume_divide', + 'pa_context_set_source_mute_by_name', + 'PA_SUBSCRIPTION_MASK_AUTOLOAD', 'pa_stream_cancel_write', + 'PA_SINK_HW_MUTE_CTRL', 'PA_CHANNEL_POSITION_AUX21', + 'PA_CHANNEL_POSITION_AUX20', 'PA_CHANNEL_POSITION_AUX23', + 'PA_CHANNEL_POSITION_AUX22', 'PA_CHANNEL_POSITION_AUX25', + 'PA_UPDATE_MERGE', 'PA_CHANNEL_POSITION_AUX27', + 'PA_SOURCE_DYNAMIC_LATENCY', 'PA_CHANNEL_POSITION_AUX29', + 'PA_CHANNEL_POSITION_AUX28', + 'pa_stream_set_started_callback', 'PA_SINK_FLAT_VOLUME', + 'size_t', 'pa_context_flags', 'pa_utf8_to_locale', + 'pa_proplist_sets', 'pa_proplist_setp', + 'PA_ERR_CONNECTIONTERMINATED', 'pa_format_info_free', + 'PA_PROP_WINDOW_ICON', 'pa_operation_cancel', + 'PA_CHANNEL_MAP_SNPRINT_MAX', 'PA_DEVICE_TYPE_SINK', + 'PA_CHANNEL_POSITION_TOP_FRONT_CENTER', + 'pa_format_info_from_string', 'pa_proplist_setf', + 'pa_cvolume_set', 'pa_bytes_per_second', + 'PA_PROP_DEVICE_PROFILE_DESCRIPTION', 'pa_stream', + 'PA_ERR_COMMAND', 'PA_SUBSCRIPTION_MASK_SINK_INPUT', + 'pa_channel_map_to_pretty_name', 'pa_card_info', + 'PA_CONTEXT_SETTING_NAME', 'PA_IO_EVENT_OUTPUT', + 'PA_PROP_FORMAT_CHANNEL_MAP', + 'pa_context_set_card_profile_by_index', + 'PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER', + 'pa_sample_info_cb_t', 'pa_source_state', + 'pa_channel_map_init_mono', 'pa_stream_readable_size', + 'PA_PROP_WINDOW_WIDTH', 'pa_stream_set_suspended_callback', + 'pa_cvolume_scale_mask', 'pa_stream_get_underflow_index', + 'pa_stream_begin_write', 'pa_stream_get_time', + 'pa_cvolume', 'pa_context_set_state_callback', + 'pa_sw_cvolume_multiply', 'PA_CHANNEL_POSITION_REAR_LEFT', + 'PA_ERR_EXIST', 'pa_threaded_mainloop_lock', 'pa_io_event', + 'PA_VOLUME_NORM', 'pa_proplist_unset_many', + 'PA_SAMPLE_MAX', 'PA_SOURCE_DECIBEL_VOLUME', + 'PA_PROP_WINDOW_Y', 'PA_PROP_WINDOW_X', + 'pa_stream_get_state', 'pa_frame_size', + 'pa_sample_size_of_format', 'PA_SAMPLE_FLOAT32LE', + 'PA_STREAM_FIX_CHANNELS', 'PA_CONTEXT_NOFLAGS', + 'PA_STREAM_EARLY_REQUESTS', 'pa_update_mode_t', + 'pa_proplist_unset', 'PA_ERR_PROTOCOL', + 'PA_PROP_MODULE_AUTHOR', 'PA_SOURCE_HW_MUTE_CTRL', + 'pa_context_set_subscribe_callback', + 'PA_PROP_MODULE_VERSION', 'PA_ENCODING_ANY', + 'pa_context_set_default_sink', 'PA_SAMPLE_S24_32LE', + 'pa_context_get_client_info', 'PA_ENCODING_PCM', + 'pa_stream_notify_cb_t', 'pa_context_index_cb_t', + 'pa_cvolume_merge', 'PA_ENCODING_MAX', 'pa_signal_done', + 'pa_threaded_mainloop_new', 'PA_PROP_DEVICE_ICON', + 'pa_channel_map_init_extend', 'PA_SUBSCRIPTION_MASK_SINK', + 'pa_context_set_sink_mute_by_name', 'pa_sample_spec_equal', + 'pa_mainloop_api_once', 'pa_threaded_mainloop_stop', + 'pa_timeval_cmp', 'pa_source_flags_t', 'pa_sink_flags', + 'pa_io_event_cb_t', 'pa_mainloop_get_api', + 'PA_CHANNEL_MAP_DEF_MAX', 'pa_usec_to_bytes', + 'PA_ERR_VERSION', 'pa_stream_prebuf', 'PA_IO_EVENT_NULL', + 'PA_OPERATION_RUNNING', 'PA_CHANNEL_POSITION_LEFT', + 'pa_cvolume_min', 'PA_CHANNEL_POSITION_RIGHT', + 'PA_SINK_INVALID_STATE', 'PA_SUBSCRIPTION_EVENT_SINK', + 'pa_io_event_flags_t', '__suseconds_t', + 'pa_channel_map_init_stereo', 'PA_CHANNEL_MAP_AUX', + 'pa_threaded_mainloop_unlock', 'PA_SINK_RUNNING', + 'pa_source_flags', 'pa_stream_proplist_remove', + 'pa_get_library_version', 'PA_SINK_NETWORK', + 'pa_stream_event_cb_t', 'PA_ENCODING_MPEG_IEC61937', + 'PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT', 'pa_source_state_t', + 'pa_xmalloc0', 'PA_UPDATE_SET', + 'pa_stream_update_timing_info', + 'PA_SUBSCRIPTION_EVENT_REMOVE', 'pa_stat_info', + 'PA_CONTEXT_AUTHORIZING', 'pa_proplist_new', + 'PA_SOURCE_INIT', 'pa_mainloop', 'PA_USEC_PER_SEC', + 'pa_stream_writable_size', 'PA_PROP_EVENT_MOUSE_HPOS', + 'PA_SUBSCRIPTION_MASK_CARD', + 'pa_context_set_sink_port_by_name', + 'pa_sw_cvolume_snprint_dB', + 'PA_SUBSCRIPTION_MASK_SAMPLE_CACHE', 'PA_PROP_FILTER_WANT', + 'PA_STREAM_INTERPOLATE_TIMING', + 'pa_context_set_sink_input_volume', + 'pa_stream_proplist_update', 'pa_volume_snprint', + 'pa_context_get_sink_info_by_name', 'uint64_t', + 'PA_CVOLUME_SNPRINT_MAX', 'pa_spawn_api', + 'PA_CHANNEL_POSITION_TOP_FRONT_LEFT', + 'pa_context_set_sink_input_mute', 'PA_USEC_MAX', + 'PA_CHANNEL_POSITION_TOP_CENTER', 'pa_get_home_dir', + 'pa_operation_unref', 'PA_ERR_BADSTATE', 'pa_mainloop_run', + 'pa_mainloop_iterate', 'PA_SUBSCRIPTION_MASK_NULL', + 'pa_cvolume_inc_clamp', 'PA_PROP_MODULE_USAGE', + 'pa_device_type', 'pa_sample_format_is_le', 'pa_xmalloc', + 'PA_ERR_MODINITFAILED', 'timeval', + 'PA_PROP_WINDOW_ICON_NAME', 'pa_sample_spec_snprint', + 'PA_MSEC_PER_SEC', 'pa_stream_get_sample_spec', + 'PA_STREAM_START_UNMUTED', 'PA_STREAM_TERMINATED', + 'pa_context_get_card_info_list', 'pa_cvolume_scale', + 'pa_proplist', 'pa_cvolume_init', + 'pa_stream_set_read_callback', 'pa_server_info', + 'PA_PROP_APPLICATION_ICON_NAME', 'PA_SAMPLE_ALAW', + 'PA_SUBSCRIPTION_MASK_MODULE', 'PA_STREAM_FAILED', + 'pa_sw_volume_divide', 'pa_stream_finish_upload', + 'PA_PROP_EVENT_DESCRIPTION', 'pa_sw_volume_from_dB', + 'pa_format_info_set_prop_int_array', 'PA_ERR_AUTHKEY', + 'PA_SUBSCRIPTION_EVENT_NEW', 'PA_STREAM_EVENT_FORMAT_LOST', + 'PA_SUBSCRIPTION_EVENT_SINK_INPUT', + 'PA_PROP_FORMAT_CHANNELS', 'PA_PROP_MEDIA_LANGUAGE', + 'pa_source_output_info', 'pa_context_state_t', + 'PA_PROP_APPLICATION_ICON', + 'PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND', + 'PA_PROP_WINDOW_DESKTOP', 'pa_io_event_destroy_cb_t', + 'PA_ERR_MAX', 'pa_proplist_to_string', + 'PA_CHANNEL_POSITION_SIDE_RIGHT', 'pa_context_stat', + 'pa_locale_to_utf8', 'pa_context_set_source_port_by_index', + 'pa_stream_set_latency_update_callback', + 'PA_PROP_WINDOW_VPOS', 'pa_operation_state_t', + 'PA_CHANNEL_POSITION_AUX24', 'pa_context_get_state', + 'PA_ERR_FORKED', 'pa_source_info', + 'PA_CHANNEL_POSITION_AUX26', 'PA_ERR_CONNECTIONREFUSED', + 'PA_CHANNEL_POSITION_FRONT_RIGHT', 'pa_sample_size', + 'PA_PROP_DEVICE_DESCRIPTION', 'pa_msleep', + 'PA_USEC_PER_MSEC', 'pa_context_get_sink_info_list', + 'PA_CHANNEL_POSITION_AUX30', 'PA_CHANNEL_POSITION_AUX31', + 'PA_SAMPLE_INVALID', 'PA_SAMPLE_ULAW', 'pa_usec_t', + 'pa_autoload_info_cb_t', 'pa_gettimeofday', + 'pa_card_info_cb_t', 'PA_STREAM_ADJUST_LATENCY', + 'PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE', + 'pa_cvolume_equal', 'pa_parse_sample_format', + 'PA_IO_EVENT_ERROR', 'pa_context_set_sink_port_by_index', + 'PA_DEVICE_TYPE_SOURCE', 'pa_threaded_mainloop_get_api', + 'pa_bytes_snprint', 'pa_context_event_cb_t', + 'pa_cvolume_valid', 'pa_context_rttime_restart', + 'PA_PROP_EVENT_MOUSE_VPOS', 'pa_mainloop_poll', + 'PA_STREAM_NO_REMAP_CHANNELS', 'pa_mainloop_free', + 'PA_SINK_SUSPENDED', 'pa_threaded_mainloop_start', + 'pa_format_info_set_sample_format', + 'pa_format_info_set_prop_int', 'PA_PROP_MEDIA_ICON_NAME', + 'pa_autoload_type', 'pa_threaded_mainloop', + 'PA_SINK_DYNAMIC_LATENCY', 'pa_context_kill_client', + 'pa_sink_state', 'pa_stream_write', 'pa_sink_port_info', + 'pa_mainloop_new', 'pa_context_get_source_info_by_name', + 'PA_STREAM_NO_REMIX_CHANNELS', 'pa_context_remove_sample', + 'PA_MAJOR', 'PA_STREAM_FAIL_ON_SUSPEND', + 'pa_context_get_tile_size', 'pa_stream_set_state_callback', + 'PA_PROP_APPLICATION_PROCESS_SESSION_ID', + 'pa_client_info_cb_t', 'pa_stream_connect_playback', + 'pa_context_unref', 'pa_format_info_set_prop_int_range', + 'pa_context_new_with_proplist', 'PA_PROP_DEVICE_BUS', + 'PA_SINK_SET_FORMATS', 'pa_stream_new_extended', + 'PA_CHANNEL_POSITION_TOP_REAR_LEFT', + 'PA_SUBSCRIPTION_EVENT_AUTOLOAD', + 'PA_CHANNEL_POSITION_FRONT_CENTER', + 'PA_SEEK_RELATIVE_ON_READ', 'pa_channel_position', + 'pa_mainloop_api', 'pa_proplist_gets', + 'pa_context_set_default_source', 'PA_CHANNEL_POSITION_LFE', + 'pa_sample_format', 'pa_sw_cvolume_divide_scalar', + 'pa_cvolume_min_mask', 'PA_STREAM_PEAK_DETECT', + 'PA_IO_EVENT_INPUT', 'PA_STREAM_VARIABLE_RATE', + 'PA_ERR_NODATA', 'PA_DECIBEL_MININFTY', + 'PA_PROP_WINDOW_NAME', + 'pa_channel_position_to_pretty_string', + 'pa_stream_is_corked', 'pa_context_get_sink_input_info', + 'pa_sw_volume_snprint_dB', + 'pa_context_move_source_output_by_name', + 'pa_stream_get_device_name', 'pa_operation_state', + 'pa_channel_map_mask', 'pa_stream_disconnect', + 'PA_PROP_DEVICE_FORM_FACTOR', + 'PA_PROP_APPLICATION_PROCESS_MACHINE_ID', + 'pa_cvolume_set_balance', + 'PA_PROP_APPLICATION_PROCESS_USER', 'pa_get_user_name', + 'PA_STREAM_EVENT_REQUEST_CORK', + 'pa_proplist_to_string_sep', 'PA_STREAM_START_MUTED', + 'PA_SOURCE_NOFLAGS', 'pa_threaded_mainloop_accept', + 'PA_SAMPLE_S32LE', 'pa_context_notify_cb_t', + 'pa_context_set_source_mute_by_index', 'PA_SOURCE_IDLE', + 'pa_context_suspend_source_by_index', + 'PA_PROP_MEDIA_SOFTWARE', 'PA_PROP_WINDOW_ID', + 'PA_PROP_WINDOW_HPOS', 'pa_context_play_sample', + 'pa_channel_map_to_name', + 'pa_context_get_module_info_list', 'pa_operation', + 'PA_STREAM_RECORD', 'PA_AUTOLOAD_SOURCE', + 'pa_context_get_card_info_by_name', + 'PA_PROP_DEVICE_ACCESS_MODE', 'pa_context_subscribe', + 'PA_AUTOLOAD_SINK', 'pa_context_get_source_info_list', + 'PA_MINOR', 'pa_timeval_diff', 'PA_SOURCE_RUNNING', + 'pa_server_info_cb_t', 'pa_context_ref', + 'pa_sw_cvolume_multiply_scalar', + 'PA_SW_CVOLUME_SNPRINT_DB_MAX', 'PA_VOLUME_SNPRINT_MAX', + 'pa_time_event_cb_t', 'pa_stream_get_latency', + 'pa_xmemdup', 'PA_CHANNEL_POSITION_MONO', + 'PA_CHANNEL_MAP_DEFAULT', 'PA_OPERATION_DONE', + 'pa_mainloop_dispatch', 'pa_proplist_set', 'PA_SINK_INIT', + 'pa_cvolume_max_mask', 'PA_STREAM_NODIRECTION', + 'PA_PROP_DEVICE_SERIAL', 'pa_autoload_info', + 'PA_PROP_APPLICATION_VERSION', + 'pa_context_kill_sink_input', 'PA_PROP_WINDOW_X11_DISPLAY', + 'pa_sink_info_cb_t', 'pa_channel_map_superset', + 'PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT', + 'pa_card_profile_info', 'pa_context_get_sample_info_list', + 'PA_MICRO', 'PA_PROP_DEVICE_VENDOR_ID', + 'pa_subscription_mask', 'PA_STREAM_DONT_MOVE', + 'pa_threaded_mainloop_free', 'PA_SAMPLE_S16BE', + 'pa_stream_connect_upload', 'PA_FORMAT_INFO_SNPRINT_MAX', + 'PA_ERR_KILLED', 'pa_context_get_source_output_info', + 'pa_stat_info_cb_t', 'pa_ascii_filter', + 'pa_context_get_autoload_info_list', + 'PA_ENCODING_AC3_IEC61937', 'PA_STREAM_PLAYBACK', + 'pa_format_info_set_channels', 'PA_PROP_FILTER_APPLY', + 'pa_sw_volume_to_dB', 'pa_format_info', 'pa_sink_state_t', + 'uint32_t', 'PA_SW_VOLUME_SNPRINT_DB_MAX', 'pa_volume_t', + 'PA_STREAM_UNCONNECTED', 'PA_CHANNEL_MAP_WAVEEX', + 'pa_stream_cork', 'pa_channel_map_init', + 'PA_ENCODING_EAC3_IEC61937', 'pa_stream_new_with_proplist', + 'PA_STREAM_NOFLAGS', 'pa_stream_success_cb_t', + 'PA_STREAM_NOT_MONOTONIC', 'PA_PROP_DEVICE_MASTER_DEVICE', + 'pa_stream_drain', 'PA_SINK_IDLE', 'pa_context_new', + 'pa_context_suspend_sink_by_index', 'pa_cvolume_dec', + 'PA_CONTEXT_TERMINATED', 'pa_context_rttime_new', + 'pa_module_info_cb_t', + 'PA_CHANNEL_POSITION_TOP_REAR_RIGHT', 'PA_NSEC_PER_MSEC', + 'pa_stream_peek', 'PA_PROP_MEDIA_NAME', + 'pa_channel_map_can_fade', 'PA_CONTEXT_FAILED', + 'pa_context_set_sink_mute_by_index', 'pa_sink_info', + 'pa_context_set_source_output_volume', + 'pa_sample_spec_valid', 'pa_operation_get_state', + 'PA_PROP_APPLICATION_PROCESS_BINARY', + 'pa_context_proplist_remove', + 'pa_context_move_source_output_by_index', + 'pa_timeval_load', 'pa_get_fqdn', 'pa_stream_unref', + 'pa_stream_set_monitor_stream', + 'PA_CHANNEL_POSITION_FRONT_LEFT', 'pa_mainloop_quit', + 'pa_channel_map_init_auto', 'pa_cvolume_inc', + 'PA_PROP_DEVICE_PRODUCT_ID', 'pa_cvolume_get_balance', + 'PA_PROTOCOL_VERSION', 'pa_source_info_cb_t', + 'pa_context_get_index', 'pa_signal_free', + 'PA_PROP_DEVICE_BUS_PATH', 'pa_cvolume_compatible', + 'pa_encoding', 'PA_NSEC_PER_SEC', + 'PA_SUBSCRIPTION_MASK_SERVER', 'pa_cvolume_get_fade', + 'pa_context', 'PA_PROP_EVENT_MOUSE_BUTTON', + 'pa_utf8_filter', 'pa_stream_update_sample_rate', + 'PA_PROP_DEVICE_PROFILE_NAME', 'pa_sw_volume_multiply', + 'pa_cvolume_snprint', 'pa_format_info_new', + 'pa_stream_flags', 'PA_CHANNEL_POSITION_AUX2', + 'PA_CHANNEL_POSITION_AUX3', 'PA_CHANNEL_POSITION_AUX0', + 'PA_SAMPLE_S16LE', 'PA_CHANNEL_POSITION_AUX6', + 'PA_STREAM_RELATIVE_VOLUME', 'PA_CHANNEL_POSITION_AUX4', + 'PA_CHANNEL_POSITION_AUX5', 'pa_xrealloc', + 'PA_CHANNEL_POSITION_AUX8', 'PA_CHANNEL_POSITION_AUX9', + 'PA_PROP_WINDOW_X11_SCREEN', 'PA_SOURCE_SUSPENDED', + 'pa_defer_event_cb_t', 'pa_threaded_mainloop_signal', + 'PA_STREAM_START_CORKED', 'pa_time_event', + 'PA_CHANNEL_MAP_AIFF', 'PA_PROP_APPLICATION_LANGUAGE', + 'PA_ERR_NOENTITY', 'PA_CHANNEL_POSITION_REAR_RIGHT', + 'pa_stream_get_context', 'pa_sw_volume_to_linear', + 'pa_source_output_info_cb_t', + 'pa_format_info_set_prop_string', 'pa_proplist_clear', + 'pa_context_get_server', 'pa_stream_set_overflow_callback', + 'PA_ERR_BUSY', 'pa_cvolume_compatible_with_channel_map', + 'PA_PROP_MEDIA_ARTIST', 'pa_utf8_valid', + 'pa_proplist_free', 'pa_stream_set_underflow_callback', + 'pa_channel_map', 'pa_update_mode', + 'PA_PROP_APPLICATION_ID', 'PA_UPDATE_REPLACE', + 'pa_stream_is_suspended', 'PA_SAMPLE_S24LE', + 'PA_ENCODING_INVALID', 'pa_context_get_card_info_by_index', + 'pa_proplist_equal', 'pa_stream_get_index', + 'pa_context_get_sample_info_by_name', + 'PA_SINK_HW_VOLUME_CTRL', 'PA_OPERATION_CANCELLED', + 'pa_context_get_sink_input_info_list', + 'pa_threaded_mainloop_get_retval', 'PA_SAMPLE_S32BE', + 'pa_proplist_copy', 'pa_context_proplist_update', + 'PA_INVALID_INDEX', 'PA_SAMPLE_FLOAT32BE', + 'pa_context_get_sink_info_by_index', 'pa_proplist_update', + 'PA_ERR_UNKNOWN', 'pa_stream_drop', 'pa_signal_cb_t', + 'pa_context_set_source_volume_by_name', + 'pa_context_subscribe_cb_t', 'pa_source_port_info', + 'pa_cvolume_channels_equal_to', 'PA_SINK_NOFLAGS', + 'PA_CHANNEL_POSITION_SIDE_LEFT', 'pa_device_type_t', + 'PA_SUBSCRIPTION_EVENT_CHANGE', 'PA_OK', + 'pa_channel_position_to_string', 'pa_context_load_module', + 'pa_context_connect', 'pa_autoload_type_t', + 'PA_SUBSCRIPTION_EVENT_CARD', + 'PA_CHANNEL_POSITION_REAR_CENTER', 'PA_ERR_INVALID', + 'pa_channel_map_def', 'pa_proplist_get', + 'PA_PROP_FORMAT_RATE', 'pa_context_flags_t', + 'PA_ERR_NOEXTENSION', 'pa_signal_set_destroy', + 'pa_poll_func', 'pa_context_set_source_output_mute', + 'pa_timeval_store', 'PA_SUBSCRIPTION_EVENT_TYPE_MASK', + 'pa_proplist_isempty', 'pa_cvolume_avg_mask', + 'pa_context_exit_daemon', + 'pa_context_suspend_source_by_name', + 'pa_context_set_event_callback', 'PA_ERR_NOTIMPLEMENTED', + 'PA_PROP_EVENT_MOUSE_X', 'PA_PROP_EVENT_MOUSE_Y', + 'pa_subscription_event_type', + 'pa_context_move_sink_input_by_name', 'int64_t', + 'pa_mainloop_set_poll_func', 'PA_SOURCE_FLAT_VOLUME', + 'PA_ERR_OBSOLETE', 'pa_mainloop_prepare', + 'PA_PROP_MODULE_DESCRIPTION', 'pa_context_is_pending', + 'PA_STREAM_CREATING', 'PA_PROP_DEVICE_PRODUCT_NAME', + 'pa_context_get_autoload_info_by_name', 'pa_context_state', + 'pa_ascii_valid', 'pa_context_disconnect', + 'pa_channel_map_compatible', + 'PA_SUBSCRIPTION_EVENT_SERVER', 'pa_stream_direction', + 'PA_SOURCE_UNLINKED', 'pa_sink_flags_t', 'pa_seek_mode_t', + 'pa_context_set_source_port_by_name', + 'pa_context_is_local', 'PA_PROP_DEVICE_INTENDED_ROLES', + 'pa_context_kill_source_output', 'pa_stream_new', + 'PA_SUBSCRIPTION_MASK_ALL', 'pa_proplist_contains', + 'PA_ERR_INVALIDSERVER', 'pa_stream_get_monitor_stream', + 'PA_PROP_DEVICE_ICON_NAME', 'PA_CHANNEL_POSITION_AUX1', + 'pa_sink_input_info_cb_t', 'pa_channel_map_has_position', + 'PA_STREAM_READY', 'pa_sw_volume_from_linear', + 'PA_CHANNEL_POSITION_AUX7', 'pa_context_unload_module', + 'PA_PROP_WINDOW_HEIGHT', 'pa_format_info_valid', + 'pa_signal_event', 'pa_sink_input_info', + 'pa_sample_format_to_string', 'pa_format_info_snprint', + 'pa_context_success_cb_t', 'pa_buffer_attr'] diff --git a/kuri_api/src/kuri_api/utils/pulse_utils/pulse_mon.py b/kuri_api/src/kuri_api/utils/pulse_utils/pulse_mon.py index 247da3c..872302c 100644 --- a/kuri_api/src/kuri_api/utils/pulse_utils/pulse_mon.py +++ b/kuri_api/src/kuri_api/utils/pulse_utils/pulse_mon.py @@ -1,10 +1,15 @@ -import sys, time -from threading import RLock +import sys +import time from ctypes import POINTER, c_void_p, c_ulong, cast, c_short -import pulse_lib, logging +from threading import RLock + +import logging +import pulse_lib + logger = logging.getLogger(__name__) DEFAULT_SOURCE = 'alsa_output.default.monitor' + class PeakMonitor(object): DEFAULT_WINDOW_RATE = 40 DEFAULT_CHANNELS = 5 @@ -130,10 +135,8 @@ def main(args): if __name__ == '__main__': - def my_logger(x): print x - logger.info = my_logger main(sys.argv) diff --git a/kuri_api/src/kuri_api/utils/pulse_utils/pulse_simple_lib.py b/kuri_api/src/kuri_api/utils/pulse_utils/pulse_simple_lib.py index 2b7c360..a60dffc 100644 --- a/kuri_api/src/kuri_api/utils/pulse_utils/pulse_simple_lib.py +++ b/kuri_api/src/kuri_api/utils/pulse_utils/pulse_simple_lib.py @@ -1,30 +1,34 @@ +import ctypes +import logging from ctypes import byref, c_int, c_uint32, c_uint8, Structure -import ctypes, logging + logger = logging.getLogger(__name__) pa_simple = ctypes.cdll.LoadLibrary('libpulse-simple.so.0') -class struct_pa_sample_spec(Structure): + +class StructPASampleSpec(Structure): __slots__ = [ - 'format', - 'rate', - 'channels'] - - -struct_pa_sample_spec._fields_ = [ - ( - 'format', c_int), - ( - 'rate', c_uint32), - ( - 'channels', c_uint8)] -pa_sample_spec = struct_pa_sample_spec + 'format', + 'rate', + 'channels'] + + +StructPASampleSpec._fields_ = [ + ( + 'format', c_int), + ( + 'rate', c_uint32), + ( + 'channels', c_uint8)] +pa_sample_spec = StructPASampleSpec PA_SAMPLE_S16LE = 3 DEFAULT_CHANNELS = 2 DEFAULT_SAMPLE_RATE = 48000 PA_STREAM_PLAYBACK = 1 + def get_sample_spec(rate=None, channels=None, sample_format=None): - spec_format = struct_pa_sample_spec() + spec_format = StructPASampleSpec() spec_format.rate = rate or DEFAULT_SAMPLE_RATE spec_format.channels = channels or DEFAULT_CHANNELS spec_format.format = sample_format or c_int(PA_SAMPLE_S16LE) @@ -33,9 +37,10 @@ def get_sample_spec(rate=None, channels=None, sample_format=None): def make_playback_stream(name, stream_format): error = c_int(0) - stream = pa_simple.pa_simple_new(None, name, PA_STREAM_PLAYBACK, None, 'playback', byref(stream_format), None, None, byref(error)) + stream = pa_simple.pa_simple_new(None, name, PA_STREAM_PLAYBACK, None, 'playback', byref(stream_format), None, None, + byref(error)) if not stream: - logger.error(('Could not create pulse audio stream: {0}!').format(pa_simple.strerror(byref(error)))) + logger.error('Could not create pulse audio stream: {0}!'.format(pa_simple.strerror(byref(error)))) return stream @@ -49,7 +54,7 @@ def write(stream, buf): error = c_int(0) status = pa_simple.pa_simple_write(stream, buf, len(buf), error) if status < 0: - logger.error(('Could not write to the stream: {0}!').format(pa_simple.strerror(byref(error)))) + logger.error('Could not write to the stream: {0}!'.format(pa_simple.strerror(byref(error)))) if status < 0: return False return True @@ -59,7 +64,7 @@ def drain(stream): error = c_int(0) status = pa_simple.pa_simple_drain(stream, error) if status < 0: - logger.error(('Could not drain the stream: {0}!').format(pa_simple.strerror(byref(error)))) + logger.error('Could not drain the stream: {0}!'.format(pa_simple.strerror(byref(error)))) if status < 0: return False return True diff --git a/kuri_api/src/kuri_api/utils/rate.py b/kuri_api/src/kuri_api/utils/rate.py index cde74fb..a9781c2 100644 --- a/kuri_api/src/kuri_api/utils/rate.py +++ b/kuri_api/src/kuri_api/utils/rate.py @@ -1,9 +1,10 @@ import time + class Rate(object): """ Convenience class for sleeping in a loop at a specified rate. - + Copied over from rospy, modified to not use rostime as that requires master to be running, and init_node to have been called. -Hai Nguyen """ @@ -47,7 +48,7 @@ def sleep(self, f=None): Attempt sleep at the specified rate. sleep() takes into account the time elapsed since the last successful sleep(). - + @param f: float -> val, function that does the actual sleeping. If None, use time.sleep. """ diff --git a/kuri_api/src/kuri_api/utils/ros.py b/kuri_api/src/kuri_api/utils/ros.py index 6d12f84..c778b02 100644 --- a/kuri_api/src/kuri_api/utils/ros.py +++ b/kuri_api/src/kuri_api/utils/ros.py @@ -1,11 +1,17 @@ """ Helpers for dealing with ROS. """ -import logging, genpy, rospy, timer, traceback +import genpy +import logging +import rospy +import timer +import traceback from threading import Lock + logger = logging.getLogger(__name__) DEFAULT_SERVICE_WAIT_RATE = 0.1 + def async_wait_for_servers(svrs, done_cb=None): """ Wait for servers asynchronously. @@ -28,7 +34,7 @@ def _runner(): def wait_for_servers(svrs, timeout=None): if not isinstance(svrs, list): svrs = [ - svrs] + svrs] for svr in svrs: try: svr.wait_for_service(timeout=timeout) @@ -42,7 +48,7 @@ def wait_for_servers(svrs, timeout=None): def wait_for_topics(topics, timeout=None, poll=0.1): if not isinstance(topics, list): topics = [ - topics] + topics] expires_at = rospy.get_time() + timeout if timeout else None for topics in topics: while topics.get_num_connections() == 0 and (expires_at is None or rospy.get_time() < expires_at): @@ -109,15 +115,15 @@ def __call__(self, *args, **kwargs): for i in range(self.RETRIES): try: return self._service_proxy(*args, **kwargs) - except rospy.service.ServiceException as rospy.ServiceException: + except rospy.service.ServiceException as _: name = '' if hasattr(self._service_proxy, 'resolved_name'): name = self._service_proxy.resolved_name if not self._mute_failures: - logger.warn(('Failed to call {}').format(name)) + logger.warn('Failed to call {}'.format(name)) return except Exception: logger.error(traceback.format_exc()) self._create_service() - return \ No newline at end of file + return diff --git a/kuri_api/src/kuri_api/utils/social.py b/kuri_api/src/kuri_api/utils/social.py index 8b564d7..32f191e 100644 --- a/kuri_api/src/kuri_api/utils/social.py +++ b/kuri_api/src/kuri_api/utils/social.py @@ -1,5 +1,6 @@ import random from math import radians + MIN_ADULT_TILT = radians(40) * -1 MAX_ADULT_TILT = radians(25) * -1 MIN_CHILD_TILT = radians(27) * -1 @@ -7,6 +8,7 @@ MIN_NAV_TILT = radians(40) * -1 MAX_NAV_TILT = radians(5) * -1 + def random_photo_tilt(): """ Calculates a random head tilt appropriate for a photo. @@ -36,19 +38,19 @@ def random_turn(): :return: angle in radians to turn """ seed = random.random() - TURN_90_THRESH = 0.45 - TURN_45_THRESH = 0.25 - TURN_135_THRESH = 0.18 + turn_90_thresh = 0.45 + turn_45_thresh = 0.25 + turn_135_thresh = 0.18 turn_direction = random.choice([-1, 1]) - if seed < TURN_90_THRESH: + if seed < turn_90_thresh: turn_angle = 90 else: - if seed < TURN_90_THRESH + TURN_45_THRESH: + if seed < turn_90_thresh + turn_45_thresh: turn_angle = 45 else: - if seed < TURN_90_THRESH + TURN_45_THRESH + TURN_135_THRESH: + if seed < turn_90_thresh + turn_45_thresh + turn_135_thresh: turn_angle = 135 else: turn_angle = 180 turn_direction = 1 - return radians(turn_angle * turn_direction) \ No newline at end of file + return radians(turn_angle * turn_direction) diff --git a/kuri_api/src/kuri_api/utils/timeouts.py b/kuri_api/src/kuri_api/utils/timeouts.py index e7f7520..63b20f3 100644 --- a/kuri_api/src/kuri_api/utils/timeouts.py +++ b/kuri_api/src/kuri_api/utils/timeouts.py @@ -1,6 +1,10 @@ -import logging, threading, rospy +import logging +import rospy +import threading + logger = logging.getLogger(__name__) + class Timeout(threading.Thread): """ Cancel able timeout thread (not available in rospy) @@ -63,16 +67,16 @@ def __init__(self, interface, duration, callback): """ self._timeout = EventTimeout(duration=duration, timeout_cb=callback) self._events = [ - interface.sensors.kidnapped_event, - interface.sensors.pickup_event, - interface.sensors.putdown_event, - interface.touch.touch_event, - interface.power.docked_event, - interface.nav_client.nav_event, - interface.wheels_mux.teleop.move_event, - interface.head_ctl.move_event, - interface.comm_interface.command_event, - interface.voice.wake_event] + interface.sensors.kidnapped_event, + interface.sensors.pickup_event, + interface.sensors.putdown_event, + interface.touch.touch_event, + interface.power.docked_event, + interface.nav_client.nav_event, + interface.wheels_mux.teleop.move_event, + interface.head_ctl.move_event, + interface.comm_interface.command_event, + interface.voice.wake_event] for event in self._events: event.connect(self._reset_timeout) @@ -83,4 +87,4 @@ def shutdown(self): for event in self._events: event.disconnect(self._reset_timeout) - self._timeout.shutdown() \ No newline at end of file + self._timeout.shutdown() diff --git a/kuri_api/src/kuri_api/vision.py b/kuri_api/src/kuri_api/vision.py index 6cea14a..23ec243 100644 --- a/kuri_api/src/kuri_api/vision.py +++ b/kuri_api/src/kuri_api/vision.py @@ -1,21 +1,23 @@ -import rospy -from copy import deepcopy -from collections import Counter +import Queue import threading -from vision_msgs.srv import VisionActiveModules, VisionActiveModulesRequest, VisionCmds, VisionCmdsRequest, VisionQuery, \ - VisionQueryRequest -from vision_msgs.msg import VisionCmdMsg, FrameResults, ImageClustering -from std_msgs.msg import Header +from collections import Counter +from collections import deque +from copy import deepcopy +from threading import Thread + +import logging +import numpy as np +import rospy from mayfield_msgs.msg import KeyValue -from robot_api.utils.event import Event from robot_api.utils import ros -from threading import Thread -import threading -import Queue -from collections import deque -from .vision_utils.visual_features import VisualFeatures +from robot_api.utils.event import Event +from std_msgs.msg import Header +from vision_msgs.msg import VisionCmdMsg, FrameResults, ImageClustering +from vision_msgs.srv import VisionActiveModules, VisionActiveModulesRequest, VisionCmds, VisionCmdsRequest, VisionQuery, \ + VisionQueryRequest + from .vision_utils.utils import cast_nan -import numpy as np, logging +from .vision_utils.visual_features import VisualFeatures logger = logging.getLogger(__name__) @@ -426,7 +428,7 @@ def moment_pre_check(self, thresholds, good_subject=False, similar_subject=False check['max_similar_ok'] = cluster_size <= thresholds['max_similar'] check['success'] = check['score_ok'] and check['brightness_ok'] and check['sharpness_ok'] and check[ 'bad_cluster_ok'] and check['max_similar_ok'] and not similar_subject and ( - check['excitement_ok'] or good_subject) + check['excitement_ok'] or good_subject) check['log_str'] = ('success,{}|').format(check['success']) + ('score,{},{}|').format(score, check['score_ok']) + ( 'brightness,{},{}|').format(brightness, check['brightness_ok']) + ( @@ -707,4 +709,4 @@ def score(self): sc = self.vf.calc.get_f_val(['score', 'value'], self.results()['data']) if np.isnan(sc): sc = 0 - return sc \ No newline at end of file + return sc diff --git a/kuri_api/src/kuri_api/vision_utils/utils.py b/kuri_api/src/kuri_api/vision_utils/utils.py index 2306126..77ebbb8 100644 --- a/kuri_api/src/kuri_api/vision_utils/utils.py +++ b/kuri_api/src/kuri_api/vision_utils/utils.py @@ -1,6 +1,9 @@ -import numpy as np, operator from functools import reduce +import numpy as np +import operator + + def cast_nan(item, cast_to): try: if np.isnan(item): diff --git a/kuri_api/src/kuri_api/vision_utils/visual_features.py b/kuri_api/src/kuri_api/vision_utils/visual_features.py index 99813a7..f77e213 100644 --- a/kuri_api/src/kuri_api/vision_utils/visual_features.py +++ b/kuri_api/src/kuri_api/vision_utils/visual_features.py @@ -1,11 +1,15 @@ +import logging +from collections import OrderedDict from copy import deepcopy -from vision_msgs.msg import Face, ClassifiedObject + import numpy as np -from collections import OrderedDict +from vision_msgs.msg import Face, ClassifiedObject + from .utils import cast_nan, get_key_ref_by_path, set_key_by_path -import logging + logger = logging.getLogger(__name__) + class VisualFeatures: def __init__(self, fsps=None, msps=None, features=None): @@ -16,14 +20,14 @@ def __init__(self, fsps=None, msps=None, features=None): class Config(): """ Generate configs and empty data structures for frame and moment feats - + configs are nested dicts of features -> indices in the data structure the data structure is a numpy array of values to allow more efficient calculation of statistics. - + If you wish to alter a config or data structure, use the get_* methods as these will return a copy rather than a reference. - + data can be rendered into the config dict using render """ @@ -34,8 +38,8 @@ def __init__(self, fsps=None, msps=None, features=None): :param features: list of features and stat patterns upon them :returns (frame conf, frame data, moment conf, moment data) """ - self.fsps = fsps or {'sv': {'labels': ('value', ), 'indices': (1, )}, - 'mi': {'labels': ('count', 'mean', 'variance'), 'indices': (0, 1, 2)}} + self.fsps = fsps or {'sv': {'labels': ('value',), 'indices': (1,)}, + 'mi': {'labels': ('count', 'mean', 'variance'), 'indices': (0, 1, 2)}} frame_stat_len = 0 for _fps_k, _fsp_v in self.fsps.iteritems(): _t = np.max(_fsp_v['indices']) + 1 @@ -50,16 +54,16 @@ def __init__(self, fsps=None, msps=None, features=None): moment_stat_len = _t self.features = features or [ - (('det', 'face', 'extent'), 'mi', 'mv', 'face_detector'), - (('det', 'face', 'comp'), 'mi', 'mv', 'face_detector'), - (('det', 'cat', 'extent'), 'mi', 'mv', 'object_detector'), - (('det', 'dog', 'extent'), 'mi', 'mv', 'object_detector'), - (('det', 'person', 'extent'), 'mi', 'mv', 'object_detector'), - (('excitement',), 'sv', 'mv', 'object_detector'), - (('brightness',), 'sv', 'mv', 'image_quality'), - (('sharpness',), 'sv', 'mv', 'image_quality'), - (('score',), 'sv', 'mv', '')] - self.feat_modules = list(set([ f[3] for f in self.features ])) + (('det', 'face', 'extent'), 'mi', 'mv', 'face_detector'), + (('det', 'face', 'comp'), 'mi', 'mv', 'face_detector'), + (('det', 'cat', 'extent'), 'mi', 'mv', 'object_detector'), + (('det', 'dog', 'extent'), 'mi', 'mv', 'object_detector'), + (('det', 'person', 'extent'), 'mi', 'mv', 'object_detector'), + (('excitement',), 'sv', 'mv', 'object_detector'), + (('brightness',), 'sv', 'mv', 'image_quality'), + (('sharpness',), 'sv', 'mv', 'image_quality'), + (('score',), 'sv', 'mv', '')] + self.feat_modules = list(set([f[3] for f in self.features])) feat_len = len(self.features) self.fmods = OrderedDict() for index, f in enumerate(self.features): @@ -82,8 +86,8 @@ def __init__(self, fsps=None, msps=None, features=None): _fsp = self.fsps[_feat[1]] for _fsp_index, _fsp_label in enumerate(_fsp['labels']): _cur_loc[_fsp_label] = ( - _feat_index, - _fsp['indices'][_fsp_index]) + _feat_index, + _fsp['indices'][_fsp_index]) self.mf_data = np.zeros((feat_len, moment_stat_len)) self.mf_data.fill(np.nan) @@ -103,7 +107,7 @@ def __init__(self, fsps=None, msps=None, features=None): for _fsp_index, _fsp_label in enumerate(_fsp['labels']): _s_index = _fsp['indices'][_fsp_index] + _msp_index * frame_stat_len _cur_loc[_msp_label][_fsp_label] = (_feat_index, - _s_index) + _s_index) def get_ff_ind(self, key_path): return get_key_ref_by_path(self.ff, key_path) @@ -121,14 +125,13 @@ class Calc(): """ Logic and methods for calculating features. Uses config to decide calculations to perform and population into the data structure - TODO(Joe): Better placement for params """ OBJECTS_HEIGHT_SCALER = 1.0 / 300.0 OBJECTS_WIDTH_SCALER = 1.0 / 300.0 OBJECTS_SCALER = OBJECTS_HEIGHT_SCALER * OBJECTS_WIDTH_SCALER POINTS_OF_INTEREST = [ - (0.5, 0.5), (0.33, 0.33), (0.66, 0.33)] + (0.5, 0.5), (0.33, 0.33), (0.66, 0.33)] def __init__(self, config): self.config = config @@ -137,19 +140,18 @@ def comp(self, item): """ Composition, currently minimum distance to a point of interest, currently upper law of thirds and center point. - TODO(Joe): Add presence along edge measure """ poi = self.POINTS_OF_INTEREST coords = () if isinstance(item, Face): coords = ( - item.center.x, item.center.y) + item.center.x, item.center.y) else: if isinstance(item, ClassifiedObject): coords = ( - (item.roi.x_offset + item.roi.width / 2.0) * self.OBJECTS_WIDTH_SCALER, - (item.roi.y_offset + item.roi.height / 2.0) * self.OBJECTS_HEIGHT_SCALER) + (item.roi.x_offset + item.roi.width / 2.0) * self.OBJECTS_WIDTH_SCALER, + (item.roi.y_offset + item.roi.height / 2.0) * self.OBJECTS_HEIGHT_SCALER) return np.min(np.linalg.norm(np.subtract(poi, coords), axis=1)) def extent(self, item): @@ -160,12 +162,12 @@ def extent(self, item): def det_face(self, ff, op): fun = getattr(self, op) - return [ fun(face) for face in ff['msg'].faces.faces ] + return [fun(face) for face in ff['msg'].faces.faces] def _det_obj(self, ff, op, oc): fun = getattr(self, op) - return [ fun(o) for o in ff['msg'].objects.positive_detections.objects if o.object_class == oc - ] + return [fun(o) for o in ff['msg'].objects.positive_detections.objects if o.object_class == oc + ] def det_cat(self, ff, op): return self._det_obj(ff, op, 'cat') @@ -196,8 +198,8 @@ def score(self, ff): excitement = self.get_f_val(['excitement', 'value'], ff['data']) or 0.0 sharpness = self.get_f_val(['sharpness', 'value'], ff['data']) or 0.0 return np.nansum([face_extent * face_count, - sharpness / 4.0, - excitement / 20.0]) + sharpness / 4.0, + excitement / 20.0]) def get_f_val(self, key_path, data): k = get_key_ref_by_path(self.config.ff, key_path) @@ -209,9 +211,7 @@ def get_f_val(self, key_path, data): def f_stats(self, feature, fsps_def): """ Generate stats for frame feature - Must follow pattern in config.fsps - TODO(Joe): Set length and organize stats from fsps_def """ if fsps_def == 'mi': @@ -249,21 +249,21 @@ def featurize_frame(self, msg): def gen_moment_data(self, ffs, m_start, m_stop): """ Integration of frame results for whole moment representation - + Generates values for "area" of results ~(value X time) - + Timeline: - + |_[__|____|_|__|__|___|____|_|____|___]__| - + | Featurized frame (run through vision, not the moment video) [ ] Moment video first and last frame timestamps - + We pad a result before and after the moment. - + m_start must be between ffs[0], ffs[1], m_stop must be between ffs[-2], ffs[-1] - + :param ffs: Featurized frames to integrate. (oldest to newest) :param m_start: time stamp of first frame in moment :param m_stop: time stamp of last frame in moment @@ -277,18 +277,18 @@ def weight_time(m_start, m_stop, ff_times): r""" Weight time based on mid point between frame and adjacent frames. - + |___.____|______.______|____.____|_._| \___________/\__________/\_____/ - + | featurized frame . mid point between frames \_/ time area assigned to contained frame - + Generate time weights for featurized frames. Assumes 1 ff_time before and after moment Must be at least 5 featurized frames - + :param m_start float epoch timestamp of first frame in moment :param m_stop float epoch timestamp of last frame in moment :param ff_times list of float epoch times for detected frames @@ -321,14 +321,13 @@ def weight_time(m_start, m_stop, ff_times): def moment_stats(ffs): """ Generate moment level statistics for frame level features - Use weight_time for time weighted stats (mean, variance...) - + :param ffs: Featurized frames :returns: Moment level statistics data array """ - frames_data = np.array([ ff['data'] for ff in ffs ]) - frame_times = [ ff['msg'].header.stamp.to_sec() for ff in ffs ] + frames_data = np.array([ff['data'] for ff in ffs]) + frame_times = [ff['msg'].header.stamp.to_sec() for ff in ffs] frames_time_weights = weight_time(m_start, m_stop, frame_times) frame_features = np.nansum(frames_data, axis=2) frame_features_mask = np.isfinite(frame_features) @@ -343,7 +342,7 @@ def moment_stats(ffs): demeaned_weighted_sum_of_frames = np.nansum(demeaned_weighted_frames, axis=0) time_weighted_variance_features = demeaned_weighted_sum_of_frames / feature_weight_sums mv_feature_stats = np.concatenate((time_weighted_mean_features, - time_weighted_variance_features), axis=1) + time_weighted_variance_features), axis=1) return mv_feature_stats mf_data = moment_stats(ffs) @@ -372,7 +371,7 @@ def render_f_result(self, result, cast_nan_to_none=False): def render(self, conf, data, cast_nan_to_none=False): """ Render a feature config nested dict with data - + :param conf: conf produced by gen_visual_features_config() :param data: data struct produced by gen_visual_features_config() """ @@ -392,4 +391,4 @@ def populate_config(output, d, key_path): return populate_config(output, output, []) - return output \ No newline at end of file + return output diff --git a/kuri_api/src/kuri_api/voice.py b/kuri_api/src/kuri_api/voice.py index 3665a0e..5f731c4 100644 --- a/kuri_api/src/kuri_api/voice.py +++ b/kuri_api/src/kuri_api/voice.py @@ -1,5 +1,6 @@ import pyttsx + class Voice(object): def __init__(self): self.engine = pyttsx.init() diff --git a/kuri_api/src/kuri_api/volume.py b/kuri_api/src/kuri_api/volume.py index 8ffaaab..b052793 100644 --- a/kuri_api/src/kuri_api/volume.py +++ b/kuri_api/src/kuri_api/volume.py @@ -1,10 +1,14 @@ -import os.path, rospy +import logging +import os.path +import rospy + from kuri_api.msg import Volume as VolMsg from std_msgs.msg import Bool, Empty -import logging + sounds_path = '/opt/gizmo/share/assets/sounds' logger = logging.getLogger(__name__) + class Volume(object): """ A thin wrapper that is in charge of delegating requested volume @@ -57,4 +61,4 @@ def _play_volume_beep(self, level): beep = os.path.join(sounds_path, 'Volume.wav') if level >= 100: beep = os.path.join(sounds_path, 'S97_VOLUME_CHANGE_MAX.wav') - self._sound_src.play(beep) \ No newline at end of file + self._sound_src.play(beep) diff --git a/kuri_audio/CMakeLists.txt b/kuri_audio/CMakeLists.txt index 8fe2cf4..51c81a1 100644 --- a/kuri_audio/CMakeLists.txt +++ b/kuri_audio/CMakeLists.txt @@ -7,12 +7,14 @@ add_compile_options(-std=c++11) find_package(catkin REQUIRED COMPONENTS - + rospy ) catkin_package( CATKIN_DEPENDS + ) -include_directories(${catkin_INCLUDE_DIRS}) +catkin_install_python(PROGRAMS scripts/audio_voice_delegate + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) diff --git a/kuri_camera/CMakeLists.txt b/kuri_camera/CMakeLists.txt index 5d8d081..82c70ca 100644 --- a/kuri_camera/CMakeLists.txt +++ b/kuri_camera/CMakeLists.txt @@ -10,11 +10,13 @@ find_package(OpenCV REQUIRED) find_package(catkin REQUIRED COMPONENTS + compressed_image_transport cv_bridge + dynamic_reconfigure image_transport madmux - compressed_image_transport - dynamic_reconfigure + roscpp + sensor_msgs ) catkin_package( @@ -22,6 +24,7 @@ catkin_package( CATKIN_DEPENDS cv_bridge image_transport + roscpp sensor_msgs compressed_image_transport dynamic_reconfigure @@ -69,8 +72,21 @@ if (libmadmux) add_executable(kuri_camera_publisher src/kuri_camera_publisher.cpp) add_dependencies(kuri_camera_publisher KuriCamera_gencfg) target_link_libraries(kuri_camera_publisher ${catkin_LIBRARIES} ${libmadmux}) + + install(TARGETS kuri_camera_publisher + ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}) + else() message(WARNING "Did not find libmadmux. Skipping kuri_camera_publisher") message(WARNING "libmadmux path: ") message(WARNING ${libmadmux}) endif() + + +catkin_install_python(PROGRAMS scripts/kuri_camera_publisher.py scripts/save_image.py + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) + +install(DIRECTORY include/${PROJECT_NAME}/ + DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}) diff --git a/kuri_camera/include/h264_decoder.h b/kuri_camera/include/kuri_camera/h264_decoder.h similarity index 100% rename from kuri_camera/include/h264_decoder.h rename to kuri_camera/include/kuri_camera/h264_decoder.h diff --git a/kuri_camera/package.xml b/kuri_camera/package.xml index c77aa04..20032ad 100644 --- a/kuri_camera/package.xml +++ b/kuri_camera/package.xml @@ -7,7 +7,7 @@ Nick Walker - None + MIT catkin diff --git a/kuri_camera/scripts/kuri_camera_publisher.py b/kuri_camera/scripts/kuri_camera_publisher.py index ae416e5..3fbd26a 100755 --- a/kuri_camera/scripts/kuri_camera_publisher.py +++ b/kuri_camera/scripts/kuri_camera_publisher.py @@ -1,11 +1,12 @@ #!/usr/bin/env python -import madmux import threading + import cv2 +import madmux import numpy as np -from sensor_msgs.msg import Image, CompressedImage -from cv_bridge import CvBridge, CvBridgeError import rospy +from cv_bridge import CvBridge +from sensor_msgs.msg import Image, CompressedImage rospy.init_node("kuri_camera_publisher") @@ -25,28 +26,31 @@ publisher = rospy.Publisher(base_topic, Image, queue_size=1) image = None + + def stream_cb(data): - global image - try: - stamp = rospy.get_rostime() - # Make sure the previous message was sent before we take in the new one - image_published.wait() - image_published.clear() - - # Read the bytes as a jpeg image - data = np.fromstring(data, np.uint8) - decoded = cv2.imdecode(data, cv2.CV_LOAD_IMAGE_COLOR) - - # Convert the decoded image to a ROS message - if use_compression: - image = bridge.cv2_to_compressed_imgmsg(decoded) - else: - image = bridge.cv2_to_imgmsg(decoded, "rgb8") - - image.header.stamp = stamp - image_received.set() - except Exception as e: - print(e) + global image + try: + stamp = rospy.get_rostime() + # Make sure the previous message was sent before we take in the new one + image_published.wait() + image_published.clear() + + # Read the bytes as a jpeg image + data = np.fromstring(data, np.uint8) + decoded = cv2.imdecode(data, cv2.CV_LOAD_IMAGE_COLOR) + + # Convert the decoded image to a ROS message + if use_compression: + image = bridge.cv2_to_compressed_imgmsg(decoded) + else: + image = bridge.cv2_to_imgmsg(decoded, "rgb8") + + image.header.stamp = stamp + image_received.set() + except Exception as e: + print(e) + # The MJPEG channel s = madmux.Stream("/var/run/madmux/ch3.sock") @@ -57,7 +61,7 @@ def stream_cb(data): image_published.set() while not rospy.is_shutdown(): if publisher.get_num_connections() == 0: - rospy.loginfo_throttle(10,"Waiting for subscribers...") + rospy.loginfo_throttle(10, "Waiting for subscribers...") poll_subscribers.sleep() continue diff --git a/kuri_camera/scripts/save_image.py b/kuri_camera/scripts/save_image.py index 8ae8b4f..ba72158 100755 --- a/kuri_camera/scripts/save_image.py +++ b/kuri_camera/scripts/save_image.py @@ -1,8 +1,9 @@ #!/usr/bin/env python # From https://github.com/KuriRobot/Kuri-Documentation/blob/master/reference/ros-packages/madmux.md -import madmux import threading +import madmux + done = threading.Event() @@ -11,6 +12,7 @@ def cb(data): f.write(data) done.set() + s = madmux.Stream("/var/run/madmux/ch3.sock") s.register_cb(cb) done.wait() diff --git a/kuri_camera/src/h264_decoder_node.cpp b/kuri_camera/src/h264_decoder_node.cpp index b10f893..1a13fee 100644 --- a/kuri_camera/src/h264_decoder_node.cpp +++ b/kuri_camera/src/h264_decoder_node.cpp @@ -1,5 +1,5 @@ #include "ros/ros.h" -#include "h264_decoder.h" +#include #include #include #include diff --git a/kuri_gazebo/CMakeLists.txt b/kuri_gazebo/CMakeLists.txt index 81b82f5..bd461e7 100644 --- a/kuri_gazebo/CMakeLists.txt +++ b/kuri_gazebo/CMakeLists.txt @@ -1,22 +1,20 @@ cmake_minimum_required(VERSION 2.8.3) project(kuri_gazebo) -## Compile as C++11, supported in ROS Kinetic and newer + add_compile_options(-std=c++11) -## Find catkin macros and libraries -## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) -## is used, also find other catkin packages find_package(catkin REQUIRED COMPONENTS angles + control_toolbox gazebo_ros_control - hardware_interface + hardware_interface + joint_limits_interface ) find_package(gazebo REQUIRED) -list(APPEND CMAKE_CXX_FLAGS "${GAZEBO_CXX_FLAGS}") catkin_package( INCLUDE_DIRS include @@ -26,12 +24,10 @@ catkin_package( gazebo_ros_control joint_limits_interface hardware_interface -# DEPENDS system_lib ) include_directories(include ${catkin_INCLUDE_DIRS} ${GAZEBO_INCLUDE_DIRS}) -link_directories(${GAZEBO_LIBRARY_DIRS}) add_library(${PROJECT_NAME} src/kuri_hardware_gazebo.cpp) target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${GAZEBO_LIBRARIES}) @@ -48,4 +44,4 @@ install(DIRECTORY include/ FILES_MATCHING PATTERN "*.h" ) install (FILES kuri_gazebo_plugins.xml - DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) \ No newline at end of file + DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) diff --git a/kuri_gazebo/package.xml b/kuri_gazebo/package.xml index 8db51dd..5619aad 100644 --- a/kuri_gazebo/package.xml +++ b/kuri_gazebo/package.xml @@ -4,16 +4,11 @@ 0.1.0 The kuri_gazebo package - - - Nick Walker - - - - TODO + + MIT catkin @@ -23,9 +18,19 @@ hardware_interface joint_limits_interface gazebo_ros_control + + + gazebo + gizmo_description + robot_state_publisher + kuri_audio + kuri_navigation + controller_manager + topic_tools + xacro + gazebo_ros - diff --git a/kuri_launch/CMakeLists.txt b/kuri_launch/CMakeLists.txt index 832d29f..0e0404d 100644 --- a/kuri_launch/CMakeLists.txt +++ b/kuri_launch/CMakeLists.txt @@ -5,10 +5,6 @@ find_package(catkin REQUIRED) catkin_add_env_hooks(${PROJECT_NAME} SHELLS sh DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/env-hooks) -include_directories( -# include -# ${catkin_INCLUDE_DIRS} -) catkin_package( ) diff --git a/kuri_launch/package.xml b/kuri_launch/package.xml index 241d9e7..b263128 100644 --- a/kuri_launch/package.xml +++ b/kuri_launch/package.xml @@ -10,11 +10,11 @@ catkin - message_generation - actionlib - actionlib_msgs - message_runtime madmux + kuri_api + kuri_camera + kuri_navigation + mobile_base_driver diff --git a/kuri_navigation/CMakeLists.txt b/kuri_navigation/CMakeLists.txt index c31036c..09dae40 100644 --- a/kuri_navigation/CMakeLists.txt +++ b/kuri_navigation/CMakeLists.txt @@ -16,4 +16,5 @@ catkin_package( ) -include_directories(${catkin_INCLUDE_DIRS}) +catkin_install_python(PROGRAMS scripts/mapping_controller scripts/may_nav_controller scripts/safety_controller + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) diff --git a/kuri_navigation/package.xml b/kuri_navigation/package.xml index 6e73ca8..a223852 100644 --- a/kuri_navigation/package.xml +++ b/kuri_navigation/package.xml @@ -9,7 +9,14 @@ None + amcl + dynamic_reconfigure + gmapping + map_server + move_base + catkin + diff --git a/kuri_navigation/scripts/mapping_controller b/kuri_navigation/scripts/mapping_controller index 50c47e9..f8899b2 100755 --- a/kuri_navigation/scripts/mapping_controller +++ b/kuri_navigation/scripts/mapping_controller @@ -1,10 +1,10 @@ #!/usr/bin/env python -import rospy +import sys import kuri_navigation +import rospy -import sys if __name__ == '__main__': rospy.init_node('mapping_controller') diff --git a/kuri_navigation/scripts/may_nav_controller b/kuri_navigation/scripts/may_nav_controller index d1412c1..185f5d6 100755 --- a/kuri_navigation/scripts/may_nav_controller +++ b/kuri_navigation/scripts/may_nav_controller @@ -1,9 +1,7 @@ #!/usr/bin/env python -import sys - -import rospy import kuri_navigation +import rospy if __name__ == '__main__': diff --git a/kuri_navigation/scripts/safety_controller b/kuri_navigation/scripts/safety_controller index 63be675..0502c06 100755 --- a/kuri_navigation/scripts/safety_controller +++ b/kuri_navigation/scripts/safety_controller @@ -1,8 +1,7 @@ #!/usr/bin/env python -import rospy - import kuri_navigation +import rospy if __name__ == '__main__': diff --git a/kuri_navigation/setup.py b/kuri_navigation/setup.py index 1bd2620..e079bfc 100644 --- a/kuri_navigation/setup.py +++ b/kuri_navigation/setup.py @@ -1,4 +1,4 @@ -## ! DO NOT MANUALLY INVOKE THIS setup.py, USE CATKIN INSTEAD +# DO NOT MANUALLY INVOKE THIS setup.py, USE CATKIN INSTEAD from distutils.core import setup from catkin_pkg.python_setup import generate_distutils_setup @@ -9,4 +9,4 @@ package_dir={'': 'src'}, ) -setup(**setup_args) \ No newline at end of file +setup(**setup_args) diff --git a/kuri_navigation/src/kuri_navigation/__init__.py b/kuri_navigation/src/kuri_navigation/__init__.py index 0e6cc7e..3f8ea3c 100644 --- a/kuri_navigation/src/kuri_navigation/__init__.py +++ b/kuri_navigation/src/kuri_navigation/__init__.py @@ -1,4 +1,4 @@ -from .oort_map_manager import OortMapManager from .mapping_controller import MappingController -from .safety_controller import SafetyController from .may_nav_controller import MayNavController +from .oort_map_manager import OortMapManager +from .safety_controller import SafetyController diff --git a/kuri_navigation/src/kuri_navigation/localization_manager.py b/kuri_navigation/src/kuri_navigation/localization_manager.py index bc4a3fd..444d5aa 100644 --- a/kuri_navigation/src/kuri_navigation/localization_manager.py +++ b/kuri_navigation/src/kuri_navigation/localization_manager.py @@ -4,9 +4,8 @@ import nav_msgs import rospy import std_srvs -from nav_msgs.srv import SetMapRequest - from kuri_navigation.pose_utils import _pose_to_posecov, se2_to_pose +from nav_msgs.srv import SetMapRequest class LocalizationManager: @@ -47,4 +46,4 @@ def start_localization(self): ] ) - self._relocalization_pub.publish(hset) \ No newline at end of file + self._relocalization_pub.publish(hset) diff --git a/kuri_navigation/src/kuri_navigation/mapping_controller.py b/kuri_navigation/src/kuri_navigation/mapping_controller.py index e58e757..030a163 100644 --- a/kuri_navigation/src/kuri_navigation/mapping_controller.py +++ b/kuri_navigation/src/kuri_navigation/mapping_controller.py @@ -1,13 +1,12 @@ -import rospy import signal -import sys import mayfield_msgs.msg import mayfield_utils import mobile_base - -from kuri_navigation.oort_map_manager import OortMapManager +import rospy from kuri_api.power import PowerMonitor +from kuri_navigation.oort_map_manager import OortMapManager + class MappingController: ''' @@ -50,20 +49,19 @@ def __init__(self, map_name): # joints self._joint_states = mobile_base.JointStates() - self._power_monitor = None # Created when we start to run self._map_manager = OortMapManager() - - # catch ctrl-c and signal the main thread that we should save the map + + # catch ctrl-c and signal the main thread that we should save the map # and quit def signal_handler(sig, frame): self._mapping_complete = True + signal.signal(signal.SIGINT, signal_handler) self._mapping_complete = False self.map_name = map_name self._start_mapping() - def run(self): # Indicate to the world that we're running and ready to go: @@ -72,8 +70,8 @@ def run(self): ) self._power_monitor = PowerMonitor() - #self._power_monitor.docked_event.connect(self._dock_changed_cb) - #self._power_monitor.undocked_event.connect(self._dock_changed_cb) + # self._power_monitor.docked_event.connect(self._dock_changed_cb) + # self._power_monitor.undocked_event.connect(self._dock_changed_cb) # _start_mapping and _stop_mapping are called from ROS callbacks # once _stop mapping runs, it will set self._mapping_complete @@ -94,7 +92,6 @@ def run(self): rospy.sleep(0.5) except rospy.exceptions.ROSInterruptException: return - def shutdown(self): self._joint_states.shutdown() @@ -104,7 +101,6 @@ def shutdown(self): self._map_manager.shutdown() - def _start_mapping(self): map_path = self._map_manager.start_mapping(self.map_name) @@ -118,7 +114,7 @@ def _start_mapping(self): def _stop_mapping(self): # Notifying OORT that we're docked will give it a hint about how to do # the final loop closure - #self._map_manager.notify_docked() + # self._map_manager.notify_docked() # Telling OORT to finish off the map is time consuming. We'll do that # from the main thread self._mapping_complete = True diff --git a/kuri_navigation/src/kuri_navigation/may_nav_controller.py b/kuri_navigation/src/kuri_navigation/may_nav_controller.py index bf7bb65..6bb94d0 100644 --- a/kuri_navigation/src/kuri_navigation/may_nav_controller.py +++ b/kuri_navigation/src/kuri_navigation/may_nav_controller.py @@ -1,13 +1,8 @@ import os.path -import rospy -from tf.transformations import euler_from_quaternion - import mayfield_msgs.msg import mayfield_utils - -import geometry_msgs.msg - +import rospy from kuri_api.power import PowerMonitor from kuri_navigation.localization_manager import LocalizationManager @@ -37,7 +32,6 @@ def __init__(self): self._localization_manager = LocalizationManager() self._power_monitor = None # Created when we start to run - def run(self): ''' Look in the home directory to see if there's a simlink to an active @@ -47,7 +41,7 @@ def run(self): self._localization_manager.start_localization() # Assume that on start-up we're on or near the dock. It's as good # a guess as any. . . - #self._map_manager.localize_on_dock() + # self._map_manager.localize_on_dock() self._power_monitor = PowerMonitor() self._power_monitor.docked_event.connect(self._dock_changed_cb) self._power_monitor.undocked_event.connect(self._dock_changed_cb) @@ -79,6 +73,6 @@ def _dock_changed_cb(self, msg): To help AMCL, relocalize to the dock whenever we're on it ''' if msg == 'docked': - #TODO: Make dock pose a ros param so we can do something like this without OORT - #self._map_manager.localize_on_dock() + # TODO: Make dock pose a ros param so we can do something like this without OORT + # self._map_manager.localize_on_dock() pass diff --git a/kuri_navigation/src/kuri_navigation/oort_map_manager.py b/kuri_navigation/src/kuri_navigation/oort_map_manager.py index a87fd49..a24bfa7 100644 --- a/kuri_navigation/src/kuri_navigation/oort_map_manager.py +++ b/kuri_navigation/src/kuri_navigation/oort_map_manager.py @@ -4,23 +4,19 @@ import subprocess import rospy -from tf.transformations import euler_from_quaternion, quaternion_from_euler import amcl.msg -import geometry_msgs.msg import nav_msgs.msg -from nav_msgs.srv import SetMap, SetMapRequest import std_srvs.srv import oort_msgs.srv import mayfield_utils -from kuri_navigation.pose_utils import _pose_to_posecov, se2_to_pose +from kuri_navigation.pose_utils import _pose_to_posecov, se2_to_pose, pose_to_se2 class OortMapManager: - - onMapGrew = mayfield_utils.Event() + on_map_grew = mayfield_utils.Event() def __init__(self): @@ -225,4 +221,4 @@ def _map_cb(self, msg): if map_size - self._map_size > 1: self._map_size = map_size - self.onMapGrew(map_size) + self.on_map_grew(map_size) diff --git a/kuri_navigation/src/kuri_navigation/pose_utils.py b/kuri_navigation/src/kuri_navigation/pose_utils.py index 77523fe..9469775 100644 --- a/kuri_navigation/src/kuri_navigation/pose_utils.py +++ b/kuri_navigation/src/kuri_navigation/pose_utils.py @@ -32,7 +32,7 @@ def _cov_list(x, y, t): 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, t*t] + 0, 0, 0, 0, 0, t * t] def _pose_to_posecov(pose, cov_params): @@ -43,4 +43,4 @@ def _pose_to_posecov(pose, cov_params): ps = geometry_msgs.msg.PoseWithCovariance() ps.pose = pose ps.covariance = _cov_list(*cov_params) - return ps \ No newline at end of file + return ps diff --git a/kuri_navigation/src/kuri_navigation/safety_controller.py b/kuri_navigation/src/kuri_navigation/safety_controller.py index 335f669..58a265d 100644 --- a/kuri_navigation/src/kuri_navigation/safety_controller.py +++ b/kuri_navigation/src/kuri_navigation/safety_controller.py @@ -1,15 +1,13 @@ import threading import geometry_msgs.msg -import rospy - import mayfield_msgs.msg import mayfield_utils import mobile_base +import rospy class SafetyController: - # A set of the safety events we're equipped to handle. # It's just bumpers so we don't need to deal with compexities # like "What happens if a front bump and a rear cliff triggers @@ -35,8 +33,8 @@ def __init__(self): # Override the safety controller for all events that we don't # handle so they'll be ignored by the hardware self.UNHANDLED_EVENTS = ( - self._safety_client.safety_statuses() # All statuses - - self.HANDLED_EVENTS # Minus the ones we handle + self._safety_client.safety_statuses() # All statuses + - self.HANDLED_EVENTS # Minus the ones we handle ) self._safety_client.safety_override(self.UNHANDLED_EVENTS) diff --git a/kuri_person_tracking/CMakeLists.txt b/kuri_person_tracking/CMakeLists.txt index a27b430..a7d35ce 100644 --- a/kuri_person_tracking/CMakeLists.txt +++ b/kuri_person_tracking/CMakeLists.txt @@ -1,12 +1,7 @@ cmake_minimum_required(VERSION 2.8.3) project(kuri_person_tracking) -## Compile as C++11, supported in ROS Kinetic and newer -# add_compile_options(-std=c++11) -## Find catkin macros and libraries -## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) -## is used, also find other catkin packages find_package(catkin REQUIRED COMPONENTS roscpp rospy @@ -14,195 +9,25 @@ find_package(catkin REQUIRED COMPONENTS message_generation ) -## System dependencies are found with CMake's conventions -# find_package(Boost REQUIRED COMPONENTS system) - -## Uncomment this if the package has a setup.py. This macro ensures -## modules and global scripts declared therein get installed -## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html -# catkin_python_setup() - -################################################ -## Declare ROS messages, services and actions ## -################################################ - -## To declare and build messages, services or actions from within this -## package, follow these steps: -## * Let MSG_DEP_SET be the set of packages whose message types you use in -## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). -## * In the file package.xml: -## * add a build_depend tag for "message_generation" -## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET -## * If MSG_DEP_SET isn't empty the following dependency has been pulled in -## but can be declared for certainty nonetheless: -## * add a exec_depend tag for "message_runtime" -## * In this file (CMakeLists.txt): -## * add "message_generation" and every package in MSG_DEP_SET to -## find_package(catkin REQUIRED COMPONENTS ...) -## * add "message_runtime" and every package in MSG_DEP_SET to -## catkin_package(CATKIN_DEPENDS ...) -## * uncomment the add_*_files sections below as needed -## and list every .msg/.srv/.action file to be processed -## * uncomment the generate_messages entry below -## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) - -## Generate messages in the 'msg' folder add_message_files( FILES BoundingBox.msg BoundingBoxes.msg ) -## Generate services in the 'srv' folder -# add_service_files( -# FILES -# Service1.srv -# Service2.srv -# ) - -## Generate actions in the 'action' folder -# add_action_files( -# FILES -# Action1.action -# Action2.action -# ) - -## Generate added messages and services with any dependencies listed here generate_messages( DEPENDENCIES - std_msgs # Or other packages containing msgs + std_msgs ) -################################################ -## Declare ROS dynamic reconfigure parameters ## -################################################ - -## To declare and build dynamic reconfigure parameters within this -## package, follow these steps: -## * In the file package.xml: -## * add a build_depend and a exec_depend tag for "dynamic_reconfigure" -## * In this file (CMakeLists.txt): -## * add "dynamic_reconfigure" to -## find_package(catkin REQUIRED COMPONENTS ...) -## * uncomment the "generate_dynamic_reconfigure_options" section below -## and list every .cfg file to be processed - -## Generate dynamic reconfigure parameters in the 'cfg' folder -# generate_dynamic_reconfigure_options( -# cfg/DynReconf1.cfg -# cfg/DynReconf2.cfg -# ) - -################################### -## catkin specific configuration ## -################################### -## The catkin_package macro generates cmake config files for your package -## Declare things to be passed to dependent projects -## INCLUDE_DIRS: uncomment this if your package contains header files -## LIBRARIES: libraries you create in this project that dependent projects also need -## CATKIN_DEPENDS: catkin_packages dependent projects also need -## DEPENDS: system dependencies of this project that dependent projects also need catkin_package( -# INCLUDE_DIRS include -# LIBRARIES kuri_person_tracking - CATKIN_DEPENDS message_runtime -# CATKIN_DEPENDS darknet_ros -# DEPENDS system_lib -) - -########### -## Build ## -########### - -## Specify additional locations of header files -## Your package locations should be listed before other locations -include_directories( -# include - ${catkin_INCLUDE_DIRS} + CATKIN_DEPENDS message_runtime roscpp std_msgs ) -## Declare a C++ library -# add_library(${PROJECT_NAME} -# src/${PROJECT_NAME}/kuri_person_tracking.cpp -# ) - -## Add cmake target dependencies of the library -## as an example, code may need to be generated before libraries -## either from message generation or dynamic reconfigure -# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Declare a C++ executable -## With catkin_make all packages are built within a single CMake context -## The recommended prefix ensures that target names across packages don't collide -# add_executable(${PROJECT_NAME}_node src/kuri_person_tracking_node.cpp) - -## Rename C++ executable without prefix -## The above recommended prefix causes long target names, the following renames the -## target back to the shorter version for ease of user use -## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" -# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") - -## Add cmake target dependencies of the executable -## same as for the library above -# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Specify libraries to link a library or executable target against -# target_link_libraries(${PROJECT_NAME}_node -# ${catkin_LIBRARIES} -# ) - -############# -## Install ## -############# - -# all install targets should use catkin DESTINATION variables -# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html - -## Mark executable scripts (Python etc.) for installation -## in contrast to setup.py, you can choose the destination -# catkin_install_python(PROGRAMS -# scripts/my_python_script -# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) - -## Mark executables for installation -## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html -# install(TARGETS ${PROJECT_NAME}_node -# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) - -## Mark libraries for installation -## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html -# install(TARGETS ${PROJECT_NAME} -# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} -# ) - -## Mark cpp header files for installation -# install(DIRECTORY include/${PROJECT_NAME}/ -# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} -# FILES_MATCHING PATTERN "*.h" -# PATTERN ".svn" EXCLUDE -# ) - -## Mark other files for installation (e.g. launch and bag files, etc.) -# install(FILES -# # myfile1 -# # myfile2 -# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} -# ) - -############# -## Testing ## -############# -## Add gtest based cpp test target and link libraries -# catkin_add_gtest(${PROJECT_NAME}-test test/test_kuri_person_tracking.cpp) -# if(TARGET ${PROJECT_NAME}-test) -# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) -# endif() +catkin_install_python(PROGRAMS scripts/person_detection.py scripts/move_towards.py + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) -## Add folders to be run by python nosetests -# catkin_add_nosetests(test) +install(PROGRAMS scripts/download_yolo.bash + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}/scripts) diff --git a/kuri_person_tracking/package.xml b/kuri_person_tracking/package.xml index 6074293..74ca43b 100644 --- a/kuri_person_tracking/package.xml +++ b/kuri_person_tracking/package.xml @@ -4,60 +4,21 @@ 0.0.0 The person_tracking package - - - nikitaf - - - - TODO + MIT - actionlib - control_msgs roscpp rospy - trajectory_msgs - - - - - - - - - - - - - - - - - - - - - - + std_msgs message_generation - - - - - + message_runtime - - - - + catkin - - diff --git a/kuri_person_tracking/scripts/kuri_params.py b/kuri_person_tracking/scripts/kuri_params.py index 6344c1f..cd3e3ee 100644 --- a/kuri_person_tracking/scripts/kuri_params.py +++ b/kuri_person_tracking/scripts/kuri_params.py @@ -16,4 +16,4 @@ def _get_camera_parameters(): print("Getting camera parameters") CAMERA_INFO_WIDTH = rospy.get_param('image_width') - CAMERA_INFO_HEIGHT = rospy.get_param('image_height') \ No newline at end of file + CAMERA_INFO_HEIGHT = rospy.get_param('image_height') diff --git a/kuri_person_tracking/scripts/move_towards.py b/kuri_person_tracking/scripts/move_towards.py index d3739e5..d96e1a2 100755 --- a/kuri_person_tracking/scripts/move_towards.py +++ b/kuri_person_tracking/scripts/move_towards.py @@ -1,15 +1,12 @@ #!/usr/bin/env python import rospy -import math -from statistics import mean import random import time from collections import deque import numpy as np -from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint -from sensor_msgs.msg import JointState, LaserScan +from sensor_msgs.msg import LaserScan from geometry_msgs.msg import Twist from kuri_person_tracking.msg import BoundingBoxes @@ -25,10 +22,10 @@ SCAN_TOPIC = rospy.get_param('subscribers/scan/topic', '/scan') SCAN_QSIZE = rospy.get_param('subscribers/scan/queue_size', 1) -VELOCITY_TOPIC = rospy.get_param('publishers/velocity/topic', '/mobile_base/commands/velocity') # 'kuri_navigation_command_velocity' +VELOCITY_TOPIC = rospy.get_param('publishers/velocity/topic', + '/mobile_base/commands/velocity') # 'kuri_navigation_command_velocity' VELOCITY_QSIZE = rospy.get_param('publishers/velocity/queue_size', 1) - CENTER_PICKING_STYLE = 2 _center_picking_styles = [ 'mean', @@ -36,7 +33,7 @@ 'highest_probability', ] -bounding_box_persistance = 1 # the number of secs to keep a bounding box center before re-scanning +bounding_box_persistance = 1 # the number of secs to keep a bounding box center before re-scanning # set by pick_center() center = None @@ -44,9 +41,12 @@ latest_positions = None scan_density = None +pending_update = None + scan_window = deque() scan_timestamps_window = deque() -SCAN_LIFESPAN = 1 # in secs +SCAN_LIFESPAN = 1 # in secs + def main(): """ Tracks a person if one is in view @@ -65,32 +65,32 @@ def main(): base_publisher = rospy.Publisher(VELOCITY_TOPIC, Twist, queue_size=VELOCITY_QSIZE) # Subscribe to the person bounding boxes - bb_sub = rospy.Subscriber(BOUNDING_BOXES_TOPIC, BoundingBoxes, bounding_boxes_callback, queue_size=BOUNDING_BOXES_QSIZE) + _ = rospy.Subscriber(BOUNDING_BOXES_TOPIC, BoundingBoxes, bounding_boxes_callback, + queue_size=BOUNDING_BOXES_QSIZE) # Subscribe to the scans - scan_sub = rospy.Subscriber(SCAN_TOPIC, LaserScan, scan_callback, queue_size=SCAN_QSIZE) + _ = rospy.Subscriber(SCAN_TOPIC, LaserScan, scan_callback, queue_size=SCAN_QSIZE) # Rate in Hz rate = rospy.Rate(2) state = "idle" - available_states = ["idle", "following", "waiting"] + # available_states = ["idle", "following", "waiting"] idle_animation_velocities = [-0.4, 0.4] num_cycles_remaining_for_idle_animation = 0 following_start = None - sig_following_duration = 3.0 # secs + sig_following_duration = 3.0 # secs waiting_start = None - waiting_duration = 5.0 # secs - + waiting_duration = 5.0 # secs while not rospy.is_shutdown(): # print(state) if state == "idle": # idle animation if num_cycles_remaining_for_idle_animation == 0: - num_cycles_remaining_for_idle_animation = random.randint(6, 16) # 3 - 8 secs at a rate of of 2Hz + num_cycles_remaining_for_idle_animation = random.randint(6, 16) # 3 - 8 secs at a rate of of 2Hz idle_ang_z = random.choice(idle_animation_velocities) publish_base_cmd(base_publisher, 0.0, idle_ang_z) @@ -166,17 +166,17 @@ def joint_states_callback(data): def scan_callback(data): global scan_window, scan_timestamps_window - range_max = data.range_max + # range_max = data.range_max ranges = data.ranges scan_window.append(ranges) - original_len = len(ranges) + # original_len = len(ranges) timestamp = rospy.Time(secs=data.header.stamp.secs, nsecs=data.header.stamp.nsecs) scan_timestamps_window.append(timestamp) # check if oldest scan is expired - if (timestamp.to_sec() - scan_timestamps_window[0].to_sec() > SCAN_LIFESPAN): + if timestamp.to_sec() - scan_timestamps_window[0].to_sec() > SCAN_LIFESPAN: scan_window.popleft() scan_timestamps_window.popleft() @@ -188,18 +188,17 @@ def close_enough(): return False scan_window_arr = np.array(scan_window) - scan_window_arr[scan_window_arr == float('inf')] = float('nan') # filter infs + scan_window_arr[scan_window_arr == float('inf')] = float('nan') # filter infs num_scan_points = scan_window_arr.shape[1] - scan_window_arr = scan_window_arr[: , num_scan_points // 3 : num_scan_points // 3 * 2] # take front third of scan - + scan_window_arr = scan_window_arr[:, num_scan_points // 3: num_scan_points // 3 * 2] # take front third of scan scan_mean = np.nanmean(scan_window_arr, axis=0) - scan_mean = scan_mean[~ np.isnan(scan_mean)] # filter nans + scan_mean = scan_mean[~ np.isnan(scan_mean)] # filter nans scan_mean_mean = np.mean(scan_mean) - return scan_mean_mean < 1.0 # 1.0 # 2.0 + return scan_mean_mean < 1.0 # 1.0 # 2.0 def get_center(bounding_box): @@ -260,7 +259,7 @@ def pixels_to_rotation(px_x, px_y): coordinates are from the bottom left corner of the image, with x along the horizontal axis and y the vertical. """ - return (px_x - 0.5) + return px_x - 0.5 def _wait_for_time(): diff --git a/kuri_person_tracking/scripts/person_detection.py b/kuri_person_tracking/scripts/person_detection.py index e25813f..4915378 100755 --- a/kuri_person_tracking/scripts/person_detection.py +++ b/kuri_person_tracking/scripts/person_detection.py @@ -1,16 +1,14 @@ #!/usr/bin/env python -import numpy as np -import imutils -import cv2 +import os import threading import time +import cv2 +import numpy as np import rospy -from sensor_msgs.msg import CompressedImage from kuri_person_tracking.msg import BoundingBox, BoundingBoxes - -import os +from sensor_msgs.msg import CompressedImage DISPLAY = rospy.get_param('person_detection/image_display', False) @@ -43,6 +41,7 @@ image_data = None image_lock = threading.Lock() + def main(): init_yolo() init_ros() @@ -50,7 +49,7 @@ def main(): def init_yolo(): global net, output_layers, classes, COLORS - net = cv2.dnn.readNet(os.path.join(NET_CFG_DIR, 'yolov3-tiny.weights'), \ + net = cv2.dnn.readNet(os.path.join(NET_CFG_DIR, 'yolov3-tiny.weights'), os.path.join(NET_CFG_DIR, 'yolov3-tiny.cfg')) layer_names = net.getLayerNames() @@ -61,7 +60,7 @@ def init_yolo(): classes = [line.strip() for line in f.readlines()] COLORS = np.random.randint(0, 255, size=(len(classes), 3), - dtype="uint8") + dtype="uint8") def init_ros(): @@ -101,7 +100,6 @@ def process_image_loop(): image_lock.release() if data is not None: - start_time = time.time() # uncompress compressed image image = cv2.imdecode(np.fromstring(data.data, np.uint8), 1) @@ -131,7 +129,7 @@ def process_image_loop(): cv2.rectangle(image, (x, y), (x + w, y + h), color, 2) text = "{}: {:.4f}".format(classes[class_ids[i]], confidences[i]) cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, - 0.5, color, 2) + 0.5, color, 2) # show the output image if DISPLAY: @@ -190,10 +188,10 @@ def publish_bounding_box(rects, width, height): for xmin, ymin, xmax, ymax, confidence in rects: bb = BoundingBox() - bb.xmin = xmin/width - bb.ymin = ymin/height - bb.xmax = xmax/width - bb.ymax = ymax/height + bb.xmin = xmin / width + bb.ymin = ymin / height + bb.xmax = xmax / width + bb.ymax = ymax / height bb.probability = confidence boxes.append(bb) @@ -202,7 +200,6 @@ def publish_bounding_box(rects, width, height): bb_publisher.publish(bbs) - def _wait_for_time(): """ Wait for rospy to spool up """ diff --git a/kuri_person_tracking/scripts/position_head.py b/kuri_person_tracking/scripts/position_head.py index 5062df8..139b002 100644 --- a/kuri_person_tracking/scripts/position_head.py +++ b/kuri_person_tracking/scripts/position_head.py @@ -20,7 +20,7 @@ def main(): def position_head(): """ Opens Kuri's eyes and raises head """ - + eyes_pub = rospy.Publisher(EYELIDS_TOPIC, JointTrajectory, queue_size=10) head_pub = rospy.Publisher(HEAD_TOPIC, JointTrajectory, queue_size=1) @@ -41,10 +41,9 @@ def publish_eye_pos(eye_publisher, val): traj.points = [p] eye_publisher.publish(traj) - -def publish_head_pos(head_publisher, pan, tilt): +def publish_head_pos(head_publisher, pan, tilt): traj = JointTrajectory() traj.joint_names = ["head_1_joint", "head_2_joint"] p = JointTrajectoryPoint() @@ -63,4 +62,4 @@ def wait_for_time(): if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/kuri_slack_bot/CMakeLists.txt b/kuri_slack_bot/CMakeLists.txt index 989e12c..5b6dd93 100644 --- a/kuri_slack_bot/CMakeLists.txt +++ b/kuri_slack_bot/CMakeLists.txt @@ -1,202 +1,11 @@ cmake_minimum_required(VERSION 2.8.3) project(kuri_slack_bot) -## Compile as C++11, supported in ROS Kinetic and newer -# add_compile_options(-std=c++11) -## Find catkin macros and libraries -## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) -## is used, also find other catkin packages find_package(catkin REQUIRED) -## System dependencies are found with CMake's conventions -# find_package(Boost REQUIRED COMPONENTS system) - - -## Uncomment this if the package has a setup.py. This macro ensures -## modules and global scripts declared therein get installed -## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html -# catkin_python_setup() - -################################################ -## Declare ROS messages, services and actions ## -################################################ - -## To declare and build messages, services or actions from within this -## package, follow these steps: -## * Let MSG_DEP_SET be the set of packages whose message types you use in -## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). -## * In the file package.xml: -## * add a build_depend tag for "message_generation" -## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET -## * If MSG_DEP_SET isn't empty the following dependency has been pulled in -## but can be declared for certainty nonetheless: -## * add a exec_depend tag for "message_runtime" -## * In this file (CMakeLists.txt): -## * add "message_generation" and every package in MSG_DEP_SET to -## find_package(catkin REQUIRED COMPONENTS ...) -## * add "message_runtime" and every package in MSG_DEP_SET to -## catkin_package(CATKIN_DEPENDS ...) -## * uncomment the add_*_files sections below as needed -## and list every .msg/.srv/.action file to be processed -## * uncomment the generate_messages entry below -## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) - -## Generate messages in the 'msg' folder -# add_message_files( -# FILES -# Message1.msg -# Message2.msg -# ) - -## Generate services in the 'srv' folder -# add_service_files( -# FILES -# Service1.srv -# Service2.srv -# ) - -## Generate actions in the 'action' folder -# add_action_files( -# FILES -# Action1.action -# Action2.action -# ) - -## Generate added messages and services with any dependencies listed here -# generate_messages( -# DEPENDENCIES -# std_msgs # Or other packages containing msgs -# ) - -################################################ -## Declare ROS dynamic reconfigure parameters ## -################################################ - -## To declare and build dynamic reconfigure parameters within this -## package, follow these steps: -## * In the file package.xml: -## * add a build_depend and a exec_depend tag for "dynamic_reconfigure" -## * In this file (CMakeLists.txt): -## * add "dynamic_reconfigure" to -## find_package(catkin REQUIRED COMPONENTS ...) -## * uncomment the "generate_dynamic_reconfigure_options" section below -## and list every .cfg file to be processed - -## Generate dynamic reconfigure parameters in the 'cfg' folder -# generate_dynamic_reconfigure_options( -# cfg/DynReconf1.cfg -# cfg/DynReconf2.cfg -# ) - -################################### -## catkin specific configuration ## -################################### -## The catkin_package macro generates cmake config files for your package -## Declare things to be passed to dependent projects -## INCLUDE_DIRS: uncomment this if your package contains header files -## LIBRARIES: libraries you create in this project that dependent projects also need -## CATKIN_DEPENDS: catkin_packages dependent projects also need -## DEPENDS: system dependencies of this project that dependent projects also need catkin_package( -# INCLUDE_DIRS include -# LIBRARIES kuri_slack_bot -# CATKIN_DEPENDS other_catkin_pkg -# DEPENDS system_lib -) - -########### -## Build ## -########### - -## Specify additional locations of header files -## Your package locations should be listed before other locations -include_directories( -# include -# ${catkin_INCLUDE_DIRS} ) -## Declare a C++ library -# add_library(${PROJECT_NAME} -# src/${PROJECT_NAME}/kuri_slack_bot.cpp -# ) - -## Add cmake target dependencies of the library -## as an example, code may need to be generated before libraries -## either from message generation or dynamic reconfigure -# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Declare a C++ executable -## With catkin_make all packages are built within a single CMake context -## The recommended prefix ensures that target names across packages don't collide -# add_executable(${PROJECT_NAME}_node src/kuri_slack_bot_node.cpp) - -## Rename C++ executable without prefix -## The above recommended prefix causes long target names, the following renames the -## target back to the shorter version for ease of user use -## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" -# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") - -## Add cmake target dependencies of the executable -## same as for the library above -# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Specify libraries to link a library or executable target against -# target_link_libraries(${PROJECT_NAME}_node -# ${catkin_LIBRARIES} -# ) - -############# -## Install ## -############# - -# all install targets should use catkin DESTINATION variables -# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html - -## Mark executable scripts (Python etc.) for installation -## in contrast to setup.py, you can choose the destination -# catkin_install_python(PROGRAMS -# scripts/my_python_script -# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) - -## Mark executables for installation -## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html -# install(TARGETS ${PROJECT_NAME}_node -# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) - -## Mark libraries for installation -## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html -# install(TARGETS ${PROJECT_NAME} -# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} -# ) - -## Mark cpp header files for installation -# install(DIRECTORY include/${PROJECT_NAME}/ -# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} -# FILES_MATCHING PATTERN "*.h" -# PATTERN ".svn" EXCLUDE -# ) - -## Mark other files for installation (e.g. launch and bag files, etc.) -# install(FILES -# # myfile1 -# # myfile2 -# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} -# ) - -############# -## Testing ## -############# - -## Add gtest based cpp test target and link libraries -# catkin_add_gtest(${PROJECT_NAME}-test test/test_kuri_slack_bot.cpp) -# if(TARGET ${PROJECT_NAME}-test) -# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) -# endif() - -## Add folders to be run by python nosetests -# catkin_add_nosetests(test) +catkin_install_python(PROGRAMS dummy_publisher.py + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) diff --git a/kuri_slack_bot/app.py b/kuri_slack_bot/app.py index 18b832f..5dc6423 100644 --- a/kuri_slack_bot/app.py +++ b/kuri_slack_bot/app.py @@ -1,8 +1,5 @@ -import os import logging -LOGGER = logging.getLogger("default logger") -LOGGER.setLevel(logging.DEBUG) -LOGGER.addHandler(logging.StreamHandler()) +import os from flask import Flask from slack import WebClient @@ -10,11 +7,14 @@ from slack.errors import SlackApiError from slack_bot import SlackBot -import time import threading import rospy from std_msgs.msg import Float64 +LOGGER = logging.getLogger("default logger") +LOGGER.setLevel(logging.DEBUG) +LOGGER.addHandler(logging.StreamHandler()) + # Based in part on Slack's onboarding tutorial https://github.com/slackapi/python-slackclient/blob/master/tutorial/ # Initialize a Flask app to host the events adapter @@ -27,7 +27,6 @@ slack_web_client = WebClient(token=os.environ['SLACK_BOT_TOKEN']) - def welcome_message(channel: str, user_id: str = None): slack_bot = SlackBot(channel) @@ -44,9 +43,10 @@ def welcome_message(channel: str, user_id: str = None): # _____not used but left in for the time being_____ # slack_bot.timestamp = response["ts"] -def teleop_message(channel: str, user_id: str=None): + +def teleop_message(channel: str, user_id: str = None): slack_bot = SlackBot(channel) - + # Get the onboarding message payload message = slack_bot.get_teleop_payload() @@ -56,7 +56,7 @@ def teleop_message(channel: str, user_id: str=None): def dummy_cb(msg): print("got message") - if msg.data > 0.5: + if msg.data > 0.5: response = slack_web_client.conversations_list(types="public_channel") for channel in response.get("channels"): try: @@ -66,7 +66,7 @@ def dummy_cb(msg): LOGGER.debug(e) -#____________________________ EVENT CALLBACKS ____________________________ +# ____________________________ EVENT CALLBACKS ____________________________ # ================ Team Join Event =============== # # When the user first joins a team, the type of the event will be 'team_join'. @@ -103,7 +103,6 @@ def message(payload): user_id = event.get("user") text = event.get("text") - if text: if text.lower() == "start": return welcome_message(user_id, channel_id) @@ -111,17 +110,18 @@ def message(payload): return teleop_message(user_id, channel_id) - if __name__ == "__main__": # Dummy subscriber print("Starting subscriber") rospy.init_node('flask_app_sub') + def tmp(): rospy.Subscriber('dummy_topic', Float64, dummy_cb) + + threading.Thread(target=tmp, daemon=True).start() - + threading.Thread(target=app.run, kwargs={"port": 3000}, daemon=True).start() - + rospy.spin() - diff --git a/kuri_slack_bot/dummy_publisher.py b/kuri_slack_bot/dummy_publisher.py index 6b5d663..59d8f57 100755 --- a/kuri_slack_bot/dummy_publisher.py +++ b/kuri_slack_bot/dummy_publisher.py @@ -1,13 +1,16 @@ #! /usr/bin/python +import random as rand + import rospy from std_msgs.msg import Float64 -import random as rand + def wait_for_time(): while rospy.Time().now().to_sec() == 0: pass + def main(): """ Publishes a random float every few seconds. Purely for testing the slack bot's ability to post messages when requested by Kuri over ROS @@ -25,4 +28,4 @@ def main(): if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/kuri_slack_bot/package.xml b/kuri_slack_bot/package.xml index df8ecde..945b3eb 100644 --- a/kuri_slack_bot/package.xml +++ b/kuri_slack_bot/package.xml @@ -4,56 +4,16 @@ 0.0.0 The kuri_slack_bot package - - - nikitaf - - - - TODO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + MIT + catkin - - + diff --git a/kuri_slack_bot/slack_bot.py b/kuri_slack_bot/slack_bot.py index c54999d..6bb6035 100644 --- a/kuri_slack_bot/slack_bot.py +++ b/kuri_slack_bot/slack_bot.py @@ -1,5 +1,6 @@ import os + class SlackBot: """Constructs help-request message""" @@ -18,7 +19,8 @@ class SlackBot: "text": { "type": "mrkdwn", "text": ( - "Kuri needs your help! Click to view a teleop interface..." + "Kuri needs your help! Click to view a teleop interface..." ), }, } @@ -31,7 +33,7 @@ def __init__(self, channel=None): self.username = "kuribot" self.icon_emoji = ":robot_face:" self.timestamp = "" - + def get_welcome_payload(self): return { "ts": self.timestamp, diff --git a/kuri_teleop/CMakeLists.txt b/kuri_teleop/CMakeLists.txt index 1a3a371..57da76e 100644 --- a/kuri_teleop/CMakeLists.txt +++ b/kuri_teleop/CMakeLists.txt @@ -3,7 +3,7 @@ add_compile_options(-std=c++11) project(kuri_teleop) find_package( - catkin REQUIRED + catkin REQUIRED COMPONENTS roscpp rospy std_msgs @@ -12,12 +12,13 @@ find_package( control_msgs joy actionlib + actionlib_msgs tf ) catkin_package( INCLUDE_DIRS include - CATKIN_DEPENDS roscpp rospy std_msgs geometry_msgs trajectory_msgs control_msgs joy actionlib tf + CATKIN_DEPENDS roscpp rospy std_msgs geometry_msgs trajectory_msgs control_msgs joy actionlib actionlib_msgs tf ) catkin_add_env_hooks(${PROJECT_NAME} SHELLS sh DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/env-hooks) @@ -32,3 +33,16 @@ target_link_libraries(joystick_teleop ${catkin_LIBRARIES}) add_executable(display_heading_arrow src/display_heading_arrow.cpp) target_link_libraries(display_heading_arrow ${catkin_LIBRARIES}) + + +install(TARGETS joystick_teleop display_heading_arrow + ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}) + +catkin_install_python(PROGRAMS scripts/keyboard_teleop + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) + + +install(DIRECTORY include/${PROJECT_NAME}/ + DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}) diff --git a/kuri_teleop/include/joystick_teleop.h b/kuri_teleop/include/kuri_teleop/joystick_teleop.h similarity index 100% rename from kuri_teleop/include/joystick_teleop.h rename to kuri_teleop/include/kuri_teleop/joystick_teleop.h diff --git a/kuri_teleop/package.xml b/kuri_teleop/package.xml index 110d971..570356c 100644 --- a/kuri_teleop/package.xml +++ b/kuri_teleop/package.xml @@ -5,7 +5,7 @@ 0.0.0 A teleoperation package for Kuri Amal Nanavati - None + MIT catkin diff --git a/kuri_teleop/src/joystick_teleop.cpp b/kuri_teleop/src/joystick_teleop.cpp index 31bc01f..bfbf446 100644 --- a/kuri_teleop/src/joystick_teleop.cpp +++ b/kuri_teleop/src/joystick_teleop.cpp @@ -1,4 +1,4 @@ -#include "joystick_teleop.h" +#include JoystickTeleop::JoystickTeleop() : head_action_srv("head_controller/follow_joint_trajectory"), diff --git a/kuri_web_teleop/CMakeLists.txt b/kuri_web_teleop/CMakeLists.txt index bb2e160..4a368c8 100644 --- a/kuri_web_teleop/CMakeLists.txt +++ b/kuri_web_teleop/CMakeLists.txt @@ -1,17 +1,13 @@ cmake_minimum_required(VERSION 2.8.3) project(kuri_web_teleop) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(OpenCV_DIR /usr/share/OpenCV/) -## Compile as C++11, supported in ROS Kinetic and newer + add_compile_options(-std=c++11) -## Find catkin macros and libraries -## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) -## is used, also find other catkin packages find_package( - catkin REQUIRED - OpenCV REQUIRED + catkin REQUIRED COMPONENTS cv_bridge roscpp roslib @@ -26,187 +22,24 @@ find_package( compressed_image_transport image_geometry tf + web_video_server ) -## System dependencies are found with CMake's conventions -# find_package(Boost REQUIRED COMPONENTS system) - - -## Uncomment this if the package has a setup.py. This macro ensures -## modules and global scripts declared therein get installed -## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html -# catkin_python_setup() - -################################################ -## Declare ROS messages, services and actions ## -################################################ - -## To declare and build messages, services or actions from within this -## package, follow these steps: -## * Let MSG_DEP_SET be the set of packages whose message types you use in -## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). -## * In the file package.xml: -## * add a build_depend tag for "message_generation" -## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET -## * If MSG_DEP_SET isn't empty the following dependency has been pulled in -## but can be declared for certainty nonetheless: -## * add a exec_depend tag for "message_runtime" -## * In this file (CMakeLists.txt): -## * add "message_generation" and every package in MSG_DEP_SET to -## find_package(catkin REQUIRED COMPONENTS ...) -## * add "message_runtime" and every package in MSG_DEP_SET to -## catkin_package(CATKIN_DEPENDS ...) -## * uncomment the add_*_files sections below as needed -## and list every .msg/.srv/.action file to be processed -## * uncomment the generate_messages entry below -## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) - -## Generate messages in the 'msg' folder -# add_message_files( -# FILES -# Message1.msg -# Message2.msg -# ) - -## Generate services in the 'srv' folder -# add_service_files( -# FILES -# Service1.srv -# Service2.srv -# ) - -## Generate actions in the 'action' folder -# add_action_files( -# FILES -# Action1.action -# Action2.action -# ) - -## Generate added messages and services with any dependencies listed here -# generate_messages( -# DEPENDENCIES -# std_msgs # Or other packages containing msgs -# ) - -################################################ -## Declare ROS dynamic reconfigure parameters ## -################################################ - -## To declare and build dynamic reconfigure parameters within this -## package, follow these steps: -## * In the file package.xml: -## * add a build_depend and a exec_depend tag for "dynamic_reconfigure" -## * In this file (CMakeLists.txt): -## * add "dynamic_reconfigure" to -## find_package(catkin REQUIRED COMPONENTS ...) -## * uncomment the "generate_dynamic_reconfigure_options" section below -## and list every .cfg file to be processed - -## Generate dynamic reconfigure parameters in the 'cfg' folder -# generate_dynamic_reconfigure_options( -# cfg/DynReconf1.cfg -# cfg/DynReconf2.cfg -# ) - -################################### -## catkin specific configuration ## -################################### -## The catkin_package macro generates cmake config files for your package -## Declare things to be passed to dependent projects -## INCLUDE_DIRS: uncomment this if your package contains header files -## LIBRARIES: libraries you create in this project that dependent projects also need -## CATKIN_DEPENDS: catkin_packages dependent projects also need -## DEPENDS: system dependencies of this project that dependent projects also need catkin_package( -# INCLUDE_DIRS include -# LIBRARIES kuri_web_teleop -# CATKIN_DEPENDS other_catkin_pkg -# DEPENDS system_lib -) - -########### -## Build ## -########### - -## Specify additional locations of header files -## Your package locations should be listed before other locations -include_directories( - # include - ${catkin_INCLUDE_DIRS} + CATKIN_DEPENDS + mobile_base_driver + tf ) -## Declare a C++ library -# add_library(${PROJECT_NAME} -# src/${PROJECT_NAME}/kuri_web_teleop.cpp -# ) -## Add cmake target dependencies of the library -## as an example, code may need to be generated before libraries -## either from message generation or dynamic reconfigure -# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) +include_directories(${catkin_INCLUDE_DIRS}) -## Declare a C++ executable -## With catkin_make all packages are built within a single CMake context -## The recommended prefix ensures that target names across packages don't collide add_executable(add_image_overlay src/add_image_overlay.cpp) -## Rename C++ executable without prefix -## The above recommended prefix causes long target names, the following renames the -## target back to the shorter version for ease of user use -## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" -# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") - -## Add cmake target dependencies of the executable -## same as for the library above -# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Specify libraries to link a library or executable target against target_link_libraries(add_image_overlay ${catkin_LIBRARIES} ${OpenCV_LIBRARIES}) -############# -## Install ## -############# - -# all install targets should use catkin DESTINATION variables -# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html - -## Mark executable scripts (Python etc.) for installation -## in contrast to setup.py, you can choose the destination -# install(PROGRAMS -# scripts/my_python_script -# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) - -## Mark executables and/or libraries for installation -# install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node -# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) - -## Mark cpp header files for installation -# install(DIRECTORY include/${PROJECT_NAME}/ -# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} -# FILES_MATCHING PATTERN "*.h" -# PATTERN ".svn" EXCLUDE -# ) - -## Mark other files for installation (e.g. launch and bag files, etc.) -# install(FILES -# # myfile1 -# # myfile2 -# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} -# ) - -############# -## Testing ## -############# - -## Add gtest based cpp test target and link libraries -# catkin_add_gtest(${PROJECT_NAME}-test test/test_kuri_web_teleop.cpp) -# if(TARGET ${PROJECT_NAME}-test) -# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) -# endif() -## Add folders to be run by python nosetests -# catkin_add_nosetests(test) +install(TARGETS add_image_overlay + ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}) diff --git a/kuri_web_teleop/package.xml b/kuri_web_teleop/package.xml index 13019e6..d5b2078 100644 --- a/kuri_web_teleop/package.xml +++ b/kuri_web_teleop/package.xml @@ -4,61 +4,35 @@ 0.0.0 The web_teleop package - - - nikita - - - - TODO + MIT mobile_base_driver compressed_image_transport - web_video_server image_geometry tf - - - - + actionlib + cv_bridge + geometry_msgs + image_transport + joy + roscpp + roslib + rospy + std_msgs + trajectory_msgs + web_video_server + + kuri_camera + rosbridge_server + web_video_server - - - - - - - - - - - - - - - - - - - - - - - - - - catkin - - - - diff --git a/madmux/CMakeLists.txt b/madmux/CMakeLists.txt index a761e8e..c81fbcb 100644 --- a/madmux/CMakeLists.txt +++ b/madmux/CMakeLists.txt @@ -6,3 +6,6 @@ find_package(catkin REQUIRED) catkin_package( INCLUDE_DIRS include ) + +install(DIRECTORY include/ + DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}) \ No newline at end of file diff --git a/may_nav_msgs/CMakeLists.txt b/may_nav_msgs/CMakeLists.txt index c2e1fe3..7d4c873 100644 --- a/may_nav_msgs/CMakeLists.txt +++ b/may_nav_msgs/CMakeLists.txt @@ -42,7 +42,10 @@ generate_messages( catkin_package( CATKIN_DEPENDS + actionlib_msgs + geometry_msgs + message_runtime + nav_msgs std_msgs ) -include_directories(${catkin_INCLUDE_DIRS}) diff --git a/mayfield_msgs/CMakeLists.txt b/mayfield_msgs/CMakeLists.txt index 2bd7a53..d983b25 100644 --- a/mayfield_msgs/CMakeLists.txt +++ b/mayfield_msgs/CMakeLists.txt @@ -31,7 +31,7 @@ generate_messages( catkin_package( CATKIN_DEPENDS + message_runtime std_msgs ) -include_directories(${catkin_INCLUDE_DIRS}) diff --git a/mayfield_msgs/package.xml b/mayfield_msgs/package.xml index d601609..6725695 100644 --- a/mayfield_msgs/package.xml +++ b/mayfield_msgs/package.xml @@ -19,12 +19,6 @@ std_msgs - - - - - - diff --git a/mobile_base_driver/CMakeLists.txt b/mobile_base_driver/CMakeLists.txt index efebdf6..d7b3b42 100644 --- a/mobile_base_driver/CMakeLists.txt +++ b/mobile_base_driver/CMakeLists.txt @@ -41,5 +41,5 @@ generate_messages( std_msgs ) -catkin_package() +catkin_package(CATKIN_DEPENDS actionlib_msgs message_runtime std_msgs) diff --git a/mobile_base_driver/package.xml b/mobile_base_driver/package.xml index d3a2204..b60eb47 100644 --- a/mobile_base_driver/package.xml +++ b/mobile_base_driver/package.xml @@ -1,4 +1,4 @@ - + mobile_base_driver 14.3.1 @@ -11,7 +11,14 @@ catkin - xacro + xacro + + message_generation + actionlib_msgs + std_msgs + roscpp + rospy + message_runtime roslib diff --git a/vision_msgs/CMakeLists.txt b/vision_msgs/CMakeLists.txt index 2acf508..6b5123f 100644 --- a/vision_msgs/CMakeLists.txt +++ b/vision_msgs/CMakeLists.txt @@ -11,6 +11,7 @@ find_package(catkin REQUIRED mayfield_msgs message_generation sensor_msgs + std_msgs ) add_message_files( @@ -45,6 +46,8 @@ generate_messages( catkin_package( CATKIN_DEPENDS geometry_msgs + mayfield_msgs + message_runtime sensor_msgs std_msgs mayfield_msgs diff --git a/vision_msgs/package.xml b/vision_msgs/package.xml index 175d321..621d8ef 100644 --- a/vision_msgs/package.xml +++ b/vision_msgs/package.xml @@ -1,5 +1,5 @@ - + vision_msgs 1.0.0 Messages used by the mayfield vision_bridge package @@ -9,13 +9,12 @@ catkin - std_msgs - geometry_msgs - sensor_msgs - mayfield_msgs + std_msgs + geometry_msgs + sensor_msgs + mayfield_msgs - std_msgs - geometry_msgs - sensor_msgs - mayfield_msgs + + message_generation + message_runtime