From 0d430b027b9027a3f93ba8e37c5f9f8777fb532d Mon Sep 17 00:00:00 2001 From: Yoshi-0921 Date: Mon, 24 Jan 2022 12:49:33 +0900 Subject: [PATCH 1/7] controller added --- main.py | 10 ++- toio_API/characteristics/motor_control.py | 4 +- toio_API/scenarios/__init__.py | 14 ++- toio_API/scenarios/examples/__init__.py | 11 ++- toio_API/scenarios/examples/control_toio.py | 98 +++++++++++++++++++++ toio_API/utils/toio.py | 23 ++++- 6 files changed, 149 insertions(+), 11 deletions(-) create mode 100644 toio_API/scenarios/examples/control_toio.py diff --git a/main.py b/main.py index de4d0f2..d41014a 100644 --- a/main.py +++ b/main.py @@ -1,11 +1,13 @@ -# -*- coding: utf-8 -*- - import asyncio from toio_API.scenarios import make_scenario from toio_API.utils.general import create_toios, discover_toios + if __name__ == "__main__": toio_addresses = asyncio.run(discover_toios()) - toios = create_toios(toio_addresses=toio_addresses, toio_names=["Yoshi", "Moto"]) - scenario = make_scenario(scenario_name="spin", toios=toios) + toios = create_toios( + toio_addresses=toio_addresses + ) + scenario = make_scenario(scenario_name="control", toios=toios) + scenario.run() diff --git a/toio_API/characteristics/motor_control.py b/toio_API/characteristics/motor_control.py index 428a468..709e74a 100644 --- a/toio_API/characteristics/motor_control.py +++ b/toio_API/characteristics/motor_control.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - from typing import Dict, List from bleak import BleakClient @@ -233,7 +231,7 @@ async def acceleration_control( - The acceleration should be [0, 255] and 0 is for constant speed. - Defaults to 5. rotation_speed (int, optional): Rotationalal speed of toio. - - Set it in [0, 65535] and the unit is degrees/sec. + - Set it in [0, 65535] and the unit is degrees/sec. - Defaults to 15. rotation_direction (int, optional): Rotationalal direction of toio. - Set 0 for veering clockwise. diff --git a/toio_API/scenarios/__init__.py b/toio_API/scenarios/__init__.py index ebbf2c9..a35e625 100644 --- a/toio_API/scenarios/__init__.py +++ b/toio_API/scenarios/__init__.py @@ -5,7 +5,15 @@ from toio_API.utils.logging import initialize_logging from toio_API.utils.toio import Toio -from .examples import BallChase, Chase, CollisionAvoidance, RunSpin, Spin, AimDests +from .examples import ( + BallChase, + Chase, + CollisionAvoidance, + RunSpin, + Spin, + AimDests, + JoyControl, +) from .customs import Custom1, Custom2, Custom3 logger = initialize_logging(__name__) @@ -18,6 +26,7 @@ "collision_avoidance", "run_spin", "spin", + "control", ] @@ -40,6 +49,9 @@ def make_scenario(scenario_name: str = "spin", toios: List[Toio] = None): elif scenario_name == "spin": scenario = Spin(toios=toios) + elif scenario_name == "control": + scenario = JoyControl(toios=toios) + elif scenario_name == "custom_1": scenario = Custom1(toios=toios) diff --git a/toio_API/scenarios/examples/__init__.py b/toio_API/scenarios/examples/__init__.py index 44044b1..84394d8 100644 --- a/toio_API/scenarios/examples/__init__.py +++ b/toio_API/scenarios/examples/__init__.py @@ -6,5 +6,14 @@ from .collision_avoidance import CollisionAvoidance from .run_spin import RunSpin from .spin import Spin +from .control_toio import JoyControl -__all__ = ["AimDests", "BallChase", "Chase", "CollisionAvoidance", "RunSpin", "Spin"] +__all__ = [ + "AimDests", + "BallChase", + "Chase", + "CollisionAvoidance", + "RunSpin", + "Spin", + "JoyControl", +] diff --git a/toio_API/scenarios/examples/control_toio.py b/toio_API/scenarios/examples/control_toio.py new file mode 100644 index 0000000..0e5b3e5 --- /dev/null +++ b/toio_API/scenarios/examples/control_toio.py @@ -0,0 +1,98 @@ +import asyncio +import random +from typing import List + +import pygame +from toio_API.scenarios.abstract_scenario import AbstractSenario +from toio_API.utils.toio import Toio + + +class JoyControl(AbstractSenario): + def __init__(self, toios: List[Toio]) -> None: + super().__init__(toios) + self.initialize_controller() + + def initialize_controller(self): + pygame.init() + pygame.joystick.init() + + joy = pygame.joystick.Joystick(0) + self.num_axes = joy.get_numaxes() + self.num_buttons = joy.get_numbuttons() + + async def _main(self, **kwargs): + while True: + axes_status, button_status = await self.press_button() + await asyncio.gather( + *[ + self.__control(toio, axes_status[toio_id], button_status[toio_id]) + for toio_id, toio in enumerate(self.toios) + ] + ) + await asyncio.sleep(0.01) + + async def __control(self, toio: Toio, axes_status, button_status): + if button_status[0]: # Select button + await toio.sound.play(sound_effect=0) + elif button_status[1]: # Left stick + await toio.sound.play(sound_effect=1) + elif button_status[2]: # Right stick + await toio.sound.play(sound_effect=2) + elif button_status[3]: # Start button + await toio.sound.play(sound_effect=3) + elif button_status[4]: # Up button + await toio.sound.play(sound_effect=4) + elif button_status[5]: # Right button + await toio.sound.play(sound_effect=5) + elif button_status[6]: # Down button + await toio.sound.play(sound_effect=6) + elif button_status[7]: # Left button + await toio.sound.play(sound_effect=7) + elif button_status[8]: # L2 button + await toio.sound.play(sound_effect=8) + elif button_status[9]: # R2 button + await toio.sound.play(sound_effect=9) + elif button_status[10]: # L1 button + await toio.sound.play(sound_effect=10) + elif button_status[11]: # R1 button + await toio.sound.play(sound_effect=random.randint(0, 10)) + + elif button_status[12]: # △ button + toio.forward_speed = 150 + await toio.lamp.turn_on(time=15, red=255, green=0, blue=0) + await toio.sound.play(sound_effect=1) + + elif button_status[13]: # ○ button + await toio.motor.control( + left_speed=toio.forward_speed + int(min(-0.5, axes_status[0]) * 50), + right_speed=toio.forward_speed - int(max(0.5, axes_status[0]) * 50), + ) + + elif button_status[14]: # × button + toio.forward_speed = 100 + await toio.motor.control( + left_speed=toio.back_speed - int(min(-0.5, axes_status[0]) * 50), + right_speed=toio.back_speed + int(max(0.5, axes_status[0]) * 50), + ) + + elif button_status[15]: # □ button + toio.forward_speed = 50 + await toio.lamp.turn_on(time=15, red=0, green=0, blue=255) + await toio.sound.play(sound_effect=10) + + elif button_status[16]: + await toio.sound.play(sound_effect=random.randint(0, 10)) + + else: + await toio.motor.control(left_speed=0, right_speed=0) + + async def press_button(self): + joys = [pygame.joystick.Joystick(i) for i in range(pygame.joystick.get_count())] + axes_status = [[joy.get_axis(i) for i in range(self.num_axes)] for joy in joys] + button_status = [ + [joy.get_button(i) for i in range(self.num_buttons)] for joy in joys + ] + + await asyncio.sleep(0.01) + + return axes_status, button_status diff --git a/toio_API/utils/toio.py b/toio_API/utils/toio.py index d35b591..2358b33 100644 --- a/toio_API/utils/toio.py +++ b/toio_API/utils/toio.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - from bleak import BleakClient from toio_API.characteristics import ( Battery, @@ -39,6 +37,9 @@ def __init__(self, address: str = None, name: str = None) -> None: self.__battery = Battery(name=self.__name, client=self.__client) self.__configuration = Configuration(name=self.__name, client=self.__client) + self.__forward_speed = 100 + self.__back_speed = -100 + @property def address(self) -> str: return self.__address @@ -86,3 +87,21 @@ def battery(self) -> Battery: @property def configuration(self) -> Configuration: return self.__configuration + + @property + def forward_speed(self) -> int: + return self.__forward_speed + + @property + def back_speed(self) -> int: + return self.__back_speed + + @forward_speed.setter + def forward_speed(self, forward_speed: int): + assert 0 < forward_speed + self.__forward_speed = forward_speed + + @back_speed.setter + def back_speed(self, back_speed: int): + assert back_speed < 0 + self.__back_speed = back_speed From 70466578ed8d740c005f81cea9fac739a2ea1ec2 Mon Sep 17 00:00:00 2001 From: Yoshi-0921 Date: Mon, 24 Jan 2022 13:21:26 +0900 Subject: [PATCH 2/7] docstring done --- gui_main.py | 5 ++++- main.py | 6 +++++- toio_API/characteristics/abstract_characteristic.py | 5 ++++- toio_API/characteristics/battery_information.py | 5 ++++- toio_API/characteristics/button_information.py | 5 ++++- toio_API/characteristics/configuration.py | 5 ++++- toio_API/characteristics/id_information.py | 5 ++++- toio_API/characteristics/light_control.py | 5 ++++- toio_API/characteristics/motor_control.py | 5 +++++ toio_API/characteristics/sensor_information.py | 5 ++++- toio_API/characteristics/sound_control.py | 5 ++++- toio_API/scenarios/abstract_scenario.py | 7 +++++-- toio_API/scenarios/examples/__init__.py | 2 -- toio_API/scenarios/examples/aim_dests.py | 9 ++++++--- toio_API/scenarios/examples/ball_chase.py | 9 ++++++--- toio_API/scenarios/examples/chase.py | 9 ++++++--- toio_API/scenarios/examples/collision_avoidance.py | 9 ++++++--- toio_API/scenarios/examples/control_toio.py | 11 +++++++++-- toio_API/scenarios/examples/run_spin.py | 9 ++++++--- toio_API/scenarios/examples/spin.py | 9 ++++++--- toio_API/utils/general.py | 5 ++++- toio_API/utils/logging.py | 5 ++++- toio_API/utils/state.py | 8 ++++++-- toio_API/utils/tkinter_setup.py | 5 +++++ toio_API/utils/toio.py | 7 ++++++- 25 files changed, 121 insertions(+), 39 deletions(-) diff --git a/gui_main.py b/gui_main.py index 5a91bac..08822b4 100644 --- a/gui_main.py +++ b/gui_main.py @@ -1,4 +1,7 @@ -# -*- coding: utf-8 -*- +"""Source code for the GUI main entry. + +Author: Yoshinari Motokawa +""" from toio_API.utils.tkinter_setup import toioDefaultWindow diff --git a/main.py b/main.py index d41014a..6612d07 100644 --- a/main.py +++ b/main.py @@ -1,9 +1,13 @@ +"""Source code for the main entry. + +Author: Yoshinari Motokawa +""" + import asyncio from toio_API.scenarios import make_scenario from toio_API.utils.general import create_toios, discover_toios - if __name__ == "__main__": toio_addresses = asyncio.run(discover_toios()) toios = create_toios( diff --git a/toio_API/characteristics/abstract_characteristic.py b/toio_API/characteristics/abstract_characteristic.py index 5fd3895..50e7517 100644 --- a/toio_API/characteristics/abstract_characteristic.py +++ b/toio_API/characteristics/abstract_characteristic.py @@ -1,4 +1,7 @@ -# -*- coding: utf-8 -*- +"""Source code for the abstract characteristic class. + +Author: Yoshinari Motokawa +""" from abc import ABC from typing import Dict diff --git a/toio_API/characteristics/battery_information.py b/toio_API/characteristics/battery_information.py index e89568d..9275f90 100644 --- a/toio_API/characteristics/battery_information.py +++ b/toio_API/characteristics/battery_information.py @@ -1,4 +1,7 @@ -# -*- coding: utf-8 -*- +"""Source code for the Battery characteristic class. + +Author: Yoshinari Motokawa +""" from typing import Dict diff --git a/toio_API/characteristics/button_information.py b/toio_API/characteristics/button_information.py index 644a9c6..3c53edb 100644 --- a/toio_API/characteristics/button_information.py +++ b/toio_API/characteristics/button_information.py @@ -1,4 +1,7 @@ -# -*- coding: utf-8 -*- +"""Source code for the Button characteristic class. + +Author: Yoshinari Motokawa +""" from typing import Dict diff --git a/toio_API/characteristics/configuration.py b/toio_API/characteristics/configuration.py index be30489..dac68f1 100644 --- a/toio_API/characteristics/configuration.py +++ b/toio_API/characteristics/configuration.py @@ -1,4 +1,7 @@ -# -*- coding: utf-8 -*- +"""Source code for the Configuration characteristic class. + +Author: Yoshinari Motokawa +""" from typing import Dict diff --git a/toio_API/characteristics/id_information.py b/toio_API/characteristics/id_information.py index bfe7c22..2d85512 100644 --- a/toio_API/characteristics/id_information.py +++ b/toio_API/characteristics/id_information.py @@ -1,4 +1,7 @@ -# -*- coding: utf-8 -*- +"""Source code for the Reader characteristic class. + +Author: Yoshinari Motokawa +""" from typing import Dict diff --git a/toio_API/characteristics/light_control.py b/toio_API/characteristics/light_control.py index 1aa4b99..4765aeb 100644 --- a/toio_API/characteristics/light_control.py +++ b/toio_API/characteristics/light_control.py @@ -1,4 +1,7 @@ -# -*- coding: utf-8 -*- +"""Source code for the Lamp characteristic class. + +Author: Yoshinari Motokawa +""" from typing import List diff --git a/toio_API/characteristics/motor_control.py b/toio_API/characteristics/motor_control.py index 709e74a..72b67b2 100644 --- a/toio_API/characteristics/motor_control.py +++ b/toio_API/characteristics/motor_control.py @@ -1,3 +1,8 @@ +"""Source code for the Motor characteristic class. + +Author: Yoshinari Motokawa +""" + from typing import Dict, List from bleak import BleakClient diff --git a/toio_API/characteristics/sensor_information.py b/toio_API/characteristics/sensor_information.py index 0626ede..de5c7c7 100644 --- a/toio_API/characteristics/sensor_information.py +++ b/toio_API/characteristics/sensor_information.py @@ -1,4 +1,7 @@ -# -*- coding: utf-8 -*- +"""Source code for the MotionSensor characteristic class. + +Author: Yoshinari Motokawa +""" from typing import Dict diff --git a/toio_API/characteristics/sound_control.py b/toio_API/characteristics/sound_control.py index d76e2c0..d73e6a7 100644 --- a/toio_API/characteristics/sound_control.py +++ b/toio_API/characteristics/sound_control.py @@ -1,4 +1,7 @@ -# -*- coding: utf-8 -*- +"""Source code for the Sound characteristic class. + +Author: Yoshinari Motokawa +""" from typing import List diff --git a/toio_API/scenarios/abstract_scenario.py b/toio_API/scenarios/abstract_scenario.py index 7e77b6c..c9fd2e0 100644 --- a/toio_API/scenarios/abstract_scenario.py +++ b/toio_API/scenarios/abstract_scenario.py @@ -1,4 +1,7 @@ -# -*- coding: utf-8 -*- +"""Source code for the abstract scenario class. + +Author: Yoshinari Motokawa +""" import asyncio from abc import ABC, abstractmethod @@ -8,7 +11,7 @@ from toio_API.utils.toio import Toio -class AbstractSenario(ABC): +class AbstractScenario(ABC): def __init__(self, toios: List[Toio]) -> None: self.__toios = toios self.__num_toios = len(self.__toios) diff --git a/toio_API/scenarios/examples/__init__.py b/toio_API/scenarios/examples/__init__.py index 84394d8..8e0d485 100644 --- a/toio_API/scenarios/examples/__init__.py +++ b/toio_API/scenarios/examples/__init__.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - from .aim_dests import AimDests from .ball_chase import BallChase from .chase import Chase diff --git a/toio_API/scenarios/examples/aim_dests.py b/toio_API/scenarios/examples/aim_dests.py index 5e3187d..f28f63e 100644 --- a/toio_API/scenarios/examples/aim_dests.py +++ b/toio_API/scenarios/examples/aim_dests.py @@ -1,8 +1,11 @@ -# -*- coding: utf-8 -*- +"""Source code for the AimDests scenario class. + +Author: Yoshinari Motokawa +""" import asyncio import math -from toio_API.scenarios.abstract_scenario import AbstractSenario +from toio_API.scenarios.abstract_scenario import AbstractScenario from toio_API.utils.general import read_information from toio_API.utils.toio import Toio from copy import deepcopy @@ -11,7 +14,7 @@ IMAGE_WIDTH = 600 -class AimDests(AbstractSenario): +class AimDests(AbstractScenario): async def _main(self, **kwargs): print(kwargs["converted_ovals"]) self.dests = [ diff --git a/toio_API/scenarios/examples/ball_chase.py b/toio_API/scenarios/examples/ball_chase.py index 221c9a1..cd1f449 100644 --- a/toio_API/scenarios/examples/ball_chase.py +++ b/toio_API/scenarios/examples/ball_chase.py @@ -1,15 +1,18 @@ -# -*- coding: utf-8 -*- +"""Source code for the BallChase scenario class. + +Author: Yoshinari Motokawa +""" import asyncio import cv2 from toio_API.camera.ball import convert_ball_position, get_ball_center -from toio_API.scenarios.abstract_scenario import AbstractSenario +from toio_API.scenarios.abstract_scenario import AbstractScenario from toio_API.utils.general import read_information from toio_API.utils.toio import Toio import math -class BallChase(AbstractSenario): +class BallChase(AbstractScenario): async def _main(self, **kwargs): capture = cv2.VideoCapture(1) diff --git a/toio_API/scenarios/examples/chase.py b/toio_API/scenarios/examples/chase.py index 691646b..c40d6d7 100644 --- a/toio_API/scenarios/examples/chase.py +++ b/toio_API/scenarios/examples/chase.py @@ -1,13 +1,16 @@ -# -*- coding: utf-8 -*- +"""Source code for the Chase scenario class. + +Author: Yoshinari Motokawa +""" import asyncio -from toio_API.scenarios.abstract_scenario import AbstractSenario +from toio_API.scenarios.abstract_scenario import AbstractScenario from toio_API.utils.general import read_information from toio_API.utils.toio import Toio -class Chase(AbstractSenario): +class Chase(AbstractScenario): async def _main(self, **kwargs): while not kwargs["run"].is_set(): response = await read_information(self.toios) diff --git a/toio_API/scenarios/examples/collision_avoidance.py b/toio_API/scenarios/examples/collision_avoidance.py index 409024d..cdba53d 100644 --- a/toio_API/scenarios/examples/collision_avoidance.py +++ b/toio_API/scenarios/examples/collision_avoidance.py @@ -1,14 +1,17 @@ -# -*- coding: utf-8 -*- +"""Source code for the CollisionAvoidance scenario class. + +Author: Yoshinari Motokawa +""" import asyncio import math -from toio_API.scenarios.abstract_scenario import AbstractSenario +from toio_API.scenarios.abstract_scenario import AbstractScenario from toio_API.utils.general import read_information from toio_API.utils.toio import Toio -class CollisionAvoidance(AbstractSenario): +class CollisionAvoidance(AbstractScenario): async def _main(self, **kwargs): while not kwargs["run"].is_set(): response = await read_information(self.toios) diff --git a/toio_API/scenarios/examples/control_toio.py b/toio_API/scenarios/examples/control_toio.py index 0e5b3e5..448f970 100644 --- a/toio_API/scenarios/examples/control_toio.py +++ b/toio_API/scenarios/examples/control_toio.py @@ -1,13 +1,20 @@ +"""Source code for the JoyControl scenario class. +Users can asynchronously control toio cubes by multiple joystick controllers. +Currently, only DUALSHOCK3 (PS3 controller) is supported. + +Author: Yoshinari Motokawa +""" + import asyncio import random from typing import List import pygame -from toio_API.scenarios.abstract_scenario import AbstractSenario +from toio_API.scenarios.abstract_scenario import AbstractScenario from toio_API.utils.toio import Toio -class JoyControl(AbstractSenario): +class JoyControl(AbstractScenario): def __init__(self, toios: List[Toio]) -> None: super().__init__(toios) self.initialize_controller() diff --git a/toio_API/scenarios/examples/run_spin.py b/toio_API/scenarios/examples/run_spin.py index f2be36a..5394704 100644 --- a/toio_API/scenarios/examples/run_spin.py +++ b/toio_API/scenarios/examples/run_spin.py @@ -1,12 +1,15 @@ -# -*- coding: utf-8 -*- +"""Source code for the RunSpin scenario class. + +Author: Yoshinari Motokawa +""" import asyncio -from toio_API.scenarios.abstract_scenario import AbstractSenario +from toio_API.scenarios.abstract_scenario import AbstractScenario from toio_API.utils.toio import Toio -class RunSpin(AbstractSenario): +class RunSpin(AbstractScenario): async def _main(self, **kwargs): await asyncio.gather(*[self.__run_spin(toio) for toio in self.toios]) diff --git a/toio_API/scenarios/examples/spin.py b/toio_API/scenarios/examples/spin.py index fc2d774..77f0189 100644 --- a/toio_API/scenarios/examples/spin.py +++ b/toio_API/scenarios/examples/spin.py @@ -1,11 +1,14 @@ -# -*- coding: utf-8 -*- +"""Source code for the Spin scenario class. + +Author: Yoshinari Motokawa +""" import asyncio -from toio_API.scenarios.abstract_scenario import AbstractSenario +from toio_API.scenarios.abstract_scenario import AbstractScenario -class Spin(AbstractSenario): +class Spin(AbstractScenario): async def _main(self, **kwargs): while not kwargs["run"].is_set(): await asyncio.gather(*[toio.motor.control() for toio in self.toios]) diff --git a/toio_API/utils/general.py b/toio_API/utils/general.py index 22b6992..70c81c9 100644 --- a/toio_API/utils/general.py +++ b/toio_API/utils/general.py @@ -1,4 +1,7 @@ -# -*- coding: utf-8 -*- +"""Source code for the utility methods. + +Author: Yoshinari Motokawa +""" from typing import Dict, List diff --git a/toio_API/utils/logging.py b/toio_API/utils/logging.py index de27163..fa9c0b6 100644 --- a/toio_API/utils/logging.py +++ b/toio_API/utils/logging.py @@ -1,4 +1,7 @@ -# -*- coding: utf-8 -*- +"""Source code for the logger. + +Author: Yoshinari Motokawa +""" from logging import DEBUG, Formatter, Logger, StreamHandler, getLogger diff --git a/toio_API/utils/state.py b/toio_API/utils/state.py index 4a29e19..89e52a5 100644 --- a/toio_API/utils/state.py +++ b/toio_API/utils/state.py @@ -1,7 +1,10 @@ -# -*- coding: utf-8 -*- +"""Source code for the State object class. +Author: Yoshinari Motokawa +""" -class State: + +class State(object): """State to represent the property of characteristics. Args: @@ -23,6 +26,7 @@ def __init__( notify: bool = False, ): self.__write = write + self.__write_without_response = write_without_response self.__read = read self.__notify = notify diff --git a/toio_API/utils/tkinter_setup.py b/toio_API/utils/tkinter_setup.py index b51d577..b4c589a 100644 --- a/toio_API/utils/tkinter_setup.py +++ b/toio_API/utils/tkinter_setup.py @@ -1,3 +1,8 @@ +"""Source code for the tkinter windows of gui_main. + +Author: Yoshinari Motokawa +""" + import asyncio import threading import tkinter diff --git a/toio_API/utils/toio.py b/toio_API/utils/toio.py index 2358b33..23fd29d 100644 --- a/toio_API/utils/toio.py +++ b/toio_API/utils/toio.py @@ -1,3 +1,8 @@ +"""Source code for the Toio object class. + +Author: Yoshinari Motokawa +""" + from bleak import BleakClient from toio_API.characteristics import ( Battery, @@ -12,7 +17,7 @@ ) -class Toio: +class Toio(object): """The toio cube to control. For more information, please refer to https://toio.github.io/toio-spec/docs/ble_communication_overview. From 70da2ff0e8a1fe658d657971e4ab42a5bace47d0 Mon Sep 17 00:00:00 2001 From: Yoshi-0921 Date: Mon, 24 Jan 2022 13:29:45 +0900 Subject: [PATCH 3/7] deleted customs --- toio_API/characteristics/__init__.py | 3 +-- toio_API/scenarios/__init__.py | 23 ++--------------------- toio_API/scenarios/customs/__init__.py | 7 ------- toio_API/scenarios/customs/custom1.py | 8 -------- toio_API/scenarios/customs/custom2.py | 8 -------- toio_API/scenarios/customs/custom3.py | 8 -------- 6 files changed, 3 insertions(+), 54 deletions(-) delete mode 100644 toio_API/scenarios/customs/__init__.py delete mode 100644 toio_API/scenarios/customs/custom1.py delete mode 100644 toio_API/scenarios/customs/custom2.py delete mode 100644 toio_API/scenarios/customs/custom3.py diff --git a/toio_API/characteristics/__init__.py b/toio_API/characteristics/__init__.py index 5b4b9bd..52fd92b 100644 --- a/toio_API/characteristics/__init__.py +++ b/toio_API/characteristics/__init__.py @@ -4,8 +4,7 @@ from .id_information import Reader from .light_control import Lamp from .motor_control import Motor -from .sensor_information import MotionSensor -from .sensor_information import MagneticSensor +from .sensor_information import MagneticSensor, MotionSensor from .sound_control import Sound __all__ = [ diff --git a/toio_API/scenarios/__init__.py b/toio_API/scenarios/__init__.py index a35e625..a22f22b 100644 --- a/toio_API/scenarios/__init__.py +++ b/toio_API/scenarios/__init__.py @@ -1,20 +1,10 @@ -# -*- coding: utf-8 -*- - from typing import List from toio_API.utils.logging import initialize_logging from toio_API.utils.toio import Toio -from .examples import ( - BallChase, - Chase, - CollisionAvoidance, - RunSpin, - Spin, - AimDests, - JoyControl, -) -from .customs import Custom1, Custom2, Custom3 +from .examples import (AimDests, BallChase, Chase, CollisionAvoidance, + JoyControl, RunSpin, Spin) logger = initialize_logging(__name__) @@ -52,15 +42,6 @@ def make_scenario(scenario_name: str = "spin", toios: List[Toio] = None): elif scenario_name == "control": scenario = JoyControl(toios=toios) - elif scenario_name == "custom_1": - scenario = Custom1(toios=toios) - - elif scenario_name == "custom_2": - scenario = Custom2(toios=toios) - - elif scenario_name == "custom_3": - scenario = Custom3(toios=toios) - else: logger.warn(f"Invalid scenario name is given. scenario_name: {scenario_name}") diff --git a/toio_API/scenarios/customs/__init__.py b/toio_API/scenarios/customs/__init__.py deleted file mode 100644 index a391c3a..0000000 --- a/toio_API/scenarios/customs/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# -*- coding: utf-8 -*- - -from .custom1 import Custom1 -from .custom2 import Custom2 -from .custom3 import Custom3 - -__all__ = ["Custom1", "Custom2", "Custom3"] diff --git a/toio_API/scenarios/customs/custom1.py b/toio_API/scenarios/customs/custom1.py deleted file mode 100644 index 20e1deb..0000000 --- a/toio_API/scenarios/customs/custom1.py +++ /dev/null @@ -1,8 +0,0 @@ -# -*- coding: utf-8 -*- - -from toio_API.scenarios.abstract_scenario import AbstractSenario - - -class Custom1(AbstractSenario): - async def _main(self): - raise NotImplementedError() diff --git a/toio_API/scenarios/customs/custom2.py b/toio_API/scenarios/customs/custom2.py deleted file mode 100644 index da4b828..0000000 --- a/toio_API/scenarios/customs/custom2.py +++ /dev/null @@ -1,8 +0,0 @@ -# -*- coding: utf-8 -*- - -from toio_API.scenarios.abstract_scenario import AbstractSenario - - -class Custom2(AbstractSenario): - async def _main(self): - raise NotImplementedError() diff --git a/toio_API/scenarios/customs/custom3.py b/toio_API/scenarios/customs/custom3.py deleted file mode 100644 index a847119..0000000 --- a/toio_API/scenarios/customs/custom3.py +++ /dev/null @@ -1,8 +0,0 @@ -# -*- coding: utf-8 -*- - -from toio_API.scenarios.abstract_scenario import AbstractSenario - - -class Custom3(AbstractSenario): - async def _main(self): - raise NotImplementedError() From 270b38c4492e66d83ca21ef4bb1b87080876d6d3 Mon Sep 17 00:00:00 2001 From: Yoshi-0921 Date: Mon, 24 Jan 2022 13:33:46 +0900 Subject: [PATCH 4/7] renamed to JoyStickControl --- main.py | 2 +- toio_API/scenarios/__init__.py | 6 +++--- toio_API/scenarios/examples/__init__.py | 4 ++-- .../examples/{control_toio.py => joy_stick_toio.py} | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) rename toio_API/scenarios/examples/{control_toio.py => joy_stick_toio.py} (97%) diff --git a/main.py b/main.py index 6612d07..c0d6cc9 100644 --- a/main.py +++ b/main.py @@ -13,5 +13,5 @@ toios = create_toios( toio_addresses=toio_addresses ) - scenario = make_scenario(scenario_name="control", toios=toios) + scenario = make_scenario(scenario_name="joy_stick", toios=toios) scenario.run() diff --git a/toio_API/scenarios/__init__.py b/toio_API/scenarios/__init__.py index a22f22b..fda8803 100644 --- a/toio_API/scenarios/__init__.py +++ b/toio_API/scenarios/__init__.py @@ -4,7 +4,7 @@ from toio_API.utils.toio import Toio from .examples import (AimDests, BallChase, Chase, CollisionAvoidance, - JoyControl, RunSpin, Spin) + JoyStickControl, RunSpin, Spin) logger = initialize_logging(__name__) @@ -39,8 +39,8 @@ def make_scenario(scenario_name: str = "spin", toios: List[Toio] = None): elif scenario_name == "spin": scenario = Spin(toios=toios) - elif scenario_name == "control": - scenario = JoyControl(toios=toios) + elif scenario_name == "joy_stick": + scenario = JoyStickControl(toios=toios) else: logger.warn(f"Invalid scenario name is given. scenario_name: {scenario_name}") diff --git a/toio_API/scenarios/examples/__init__.py b/toio_API/scenarios/examples/__init__.py index 8e0d485..e7ace8c 100644 --- a/toio_API/scenarios/examples/__init__.py +++ b/toio_API/scenarios/examples/__init__.py @@ -4,7 +4,7 @@ from .collision_avoidance import CollisionAvoidance from .run_spin import RunSpin from .spin import Spin -from .control_toio import JoyControl +from .joy_stick_toio import JoyStickControl __all__ = [ "AimDests", @@ -13,5 +13,5 @@ "CollisionAvoidance", "RunSpin", "Spin", - "JoyControl", + "JoyStickControl", ] diff --git a/toio_API/scenarios/examples/control_toio.py b/toio_API/scenarios/examples/joy_stick_toio.py similarity index 97% rename from toio_API/scenarios/examples/control_toio.py rename to toio_API/scenarios/examples/joy_stick_toio.py index 448f970..298a8b6 100644 --- a/toio_API/scenarios/examples/control_toio.py +++ b/toio_API/scenarios/examples/joy_stick_toio.py @@ -1,4 +1,4 @@ -"""Source code for the JoyControl scenario class. +"""Source code for the JoyStickControl scenario class. Users can asynchronously control toio cubes by multiple joystick controllers. Currently, only DUALSHOCK3 (PS3 controller) is supported. @@ -14,7 +14,7 @@ from toio_API.utils.toio import Toio -class JoyControl(AbstractScenario): +class JoyStickControl(AbstractScenario): def __init__(self, toios: List[Toio]) -> None: super().__init__(toios) self.initialize_controller() From c497172583180868ba5841a27168a53720cc08fe Mon Sep 17 00:00:00 2001 From: Yoshi-0921 Date: Mon, 24 Jan 2022 13:41:23 +0900 Subject: [PATCH 5/7] updated README --- README.md | 35 ++++++++++++++--------------------- main.py | 1 + 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 506de4f..6a4fd2c 100644 --- a/README.md +++ b/README.md @@ -12,19 +12,18 @@ AboutHow To UseExamples • - CustomsCommunityLicense

## About -This is unofficial toio control API for python users. Suitable to handle asynchronous operations using several toio cubes. +This is unofficial toio control API for python users. Suitable to handle asynchronous operations using several toio cubes. これはtoio好きのtoio好きによるtoio好きのための非公式APIです。Pythonで複数のtoioキューブを非同期制御したい方向けのライブラリです。 ## How To Use -基本的に`$ python main.py`または`$ python gui_main.py`で実行できます。toioの行動パターンは実装した「シナリオ」に基づいており、例として以下の4つのシナリオを用意しています。 +基本的に`$ python main.py`または`$ python gui_main.py`で実行できます。toioキューブの行動パターンは実装した「シナリオ」に基づいており、例として以下の4つのシナリオを用意しています。

spin • @@ -33,7 +32,7 @@ This is unofficial toio control API for python users. Suitable to handle asynchr collision_avoidance

-`main.py`では`make_scenario(scenario_name='spin', ...)`がデフォルトで設定されていますが、その他のシナリオでtoioを制御したい場合は該当するシナリオ名に変更してください。 +`main.py`では`make_scenario(scenario_name='spin', ...)`がデフォルトで設定されていますが、その他のシナリオでtoioキューブを制御したい場合は該当するシナリオ名に変更してください。 ```py # main.py @@ -45,15 +44,15 @@ from toio_API.utils.general import create_toios, discover_toios if __name__ == '__main__': toio_addresses = asyncio.run(discover_toios()) - toios = create_toios(toio_addresses=toio_addresses, toio_names=['Yoshi', 'Moto']) + toios = create_toios(toio_addresses=toio_addresses) scenario = make_scenario(scenario_name='spin', toios=toios) scenario.run() ``` #### その他 -- `asyncio.run(discover_toios())`: 接続可能なtoioを見つけます。発見できた場合、そのtoioのBLE_addressがリスト型で返されます。 -- `create_toios(toio_addresses)`: 見つけたtoioのBLE_addresを基にtoio制御クラスを作成します。引数に名前も設定できます。 -- `make_scenario(toios)`: toioの行動パターンを決めるシナリオを作成します。この時、自動的にtoioとのBLE通信が開始されます。 +- `asyncio.run(discover_toios())`: 接続可能なtoioキューブを見つけます。発見できた場合、そのtoioキューブのBLE_addressがリスト型で返されます。 +- `create_toios(toio_addresses)`: 見つけたtoioキューブのBLE_addresを基にtoio制御クラスを作成します。引数に名前`(toio_names)`も設定できます。 +- `make_scenario(toios)`: toioの行動パターンを決めるシナリオを作成します。この時、自動的にtoioキューブとのBLE通信が開始されます。 - `scenario.run()`: 作成したシナリオを実行します。  `gui_main.py`を実行すると以下のようなGUIがが出力されます。左下のバーより任意のシナリオを選択して`Run toio`を押してください。 @@ -61,7 +60,7 @@ if __name__ == '__main__': ## Examples -4つのシナリオの実装コードです。たったの数行のコードでtoioを簡単に制御できます。 +4つのシナリオの実装コードです。たったの数行のコードでtoioキューブを簡単に制御できます。 ### Spin toioがグルグルとその場で回転して、5秒後に停止します。 @@ -79,7 +78,7 @@ class Spin(AbstractSenario): [Demo video clip](https://youtu.be/rINq-bm9uKI) ### Run and Spin -toioが1秒間走り、その後1秒間スピンします。 +toioキューブが1秒間走り、その後1秒間スピンします。 ```py # scenarios/examples/run_spin.py @@ -98,7 +97,7 @@ class RunSpin(AbstractSenario): [Demo video clip](https://youtu.be/3fU0nKxnZRQ) ### Chase -2体以上のtoioが必要です。1体のtoioに目掛けてその他のtoioが追いかけます。 +2体以上のtoioキューブが必要です。1体のtoioキューブに目掛けてその他のtoioキューブが追いかけます。 ```py # scenarios/examples/chase.py @@ -124,7 +123,7 @@ class Chase(AbstractSenario): [Demo video clip](https://youtu.be/juGjJ5iSx_k) ### Collision Avoidance -2体のtoioが必要です。toioを互いの正面に向き合わせて実行します。初めに直進しますが、近づいたら衝突回避行動をします。 +2体のtoioキューブが必要です。toioキューブを互いの正面に向き合わせて実行します。初めに直進しますが、近づいたら衝突回避行動をします。 ```py # scenarios/examples/collision_avoidance.py @@ -149,13 +148,7 @@ class CollisionAvoidance(AbstractSenario): [Demo video clip](https://youtu.be/1LJGxODB4vM) -## Customs -自分のオリジナルコードでtoioを制御する場合、`scenarios/customs/`に用意したカスタムシナリオにコーディングしてください(Custom1 ~ Custom3まで実装できます)。完成したら`main.py`でシナリオ名を'custom1'に変更して実行してみましょう! -``` -# scenarios/customs/custom1.py - -class Custom1(AbstractSenario): - async def _main(self): - raise NotImplementedError() -``` +## Joy Stick Control +複数台のPS3コントローラーでtoioキューブを非同期で操作することができます。 +

GUI

\ No newline at end of file diff --git a/main.py b/main.py index c0d6cc9..7bee66a 100644 --- a/main.py +++ b/main.py @@ -14,4 +14,5 @@ toio_addresses=toio_addresses ) scenario = make_scenario(scenario_name="joy_stick", toios=toios) + scenario.run() From 42099ec22dfaaf888ae0b981e38bfb23872dc89b Mon Sep 17 00:00:00 2001 From: Yoshi-0921 Date: Mon, 24 Jan 2022 13:49:11 +0900 Subject: [PATCH 6/7] updated README --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6a4fd2c..c3ed64e 100644 --- a/README.md +++ b/README.md @@ -150,5 +150,7 @@ class CollisionAvoidance(AbstractSenario): ## Joy Stick Control -複数台のPS3コントローラーでtoioキューブを非同期で操作することができます。 -

GUI

\ No newline at end of file +複数台のPS3コントローラーでtoioキューブを非同期操作することができます。 +- まず、通常のBluetooth通信でマシンとPS3コントローラーを接続します。 +- `scenario_name='joy_stick'`と設定し、`main.py`を実行します。 +

GUI

From c90a23fd4270fbdccd4fe3a1631a06a592329748 Mon Sep 17 00:00:00 2001 From: Yoshi-0921 Date: Wed, 26 Jan 2022 16:33:21 +0900 Subject: [PATCH 7/7] WIP --- toio_API/scenarios/examples/joy_stick_toio.py | 63 ++++++++++++++++++- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/toio_API/scenarios/examples/joy_stick_toio.py b/toio_API/scenarios/examples/joy_stick_toio.py index 298a8b6..48eafbe 100644 --- a/toio_API/scenarios/examples/joy_stick_toio.py +++ b/toio_API/scenarios/examples/joy_stick_toio.py @@ -10,6 +10,18 @@ from typing import List import pygame +from pygame.locals import * +import sys + +SCREEN_SIZE = (600, 425) # 画面サイズ (横/縦) +MAT_HEIGHT = 216 +MAT_WIDTH = 304 +MAT_HEIGHT_MIN = 142 +MAT_WIDTH_MIN = 98 +pygame.display.set_caption("window test") # Windowタイトルの設定 +X_CENTER = int(SCREEN_SIZE[0] / 2) +Y_CENTER = int(SCREEN_SIZE[1] / 2) + from toio_API.scenarios.abstract_scenario import AbstractScenario from toio_API.utils.toio import Toio @@ -27,9 +39,19 @@ def initialize_controller(self): self.num_axes = joy.get_numaxes() self.num_buttons = joy.get_numbuttons() + self.screen = pygame.display.set_mode(SCREEN_SIZE) # SCREEN_SIZEの画面を作成 + mat_image = pygame.image.load("figs/normal_mat.png") + self.mat_image = pygame.transform.scale(mat_image, SCREEN_SIZE) + bullet_image = pygame.image.load("figs/bullet.jpeg") + self.bullet_image = pygame.transform.scale(bullet_image, (50, 10)) + self.bullets = [] + async def _main(self, **kwargs): while True: + await self.print_screen() + axes_status, button_status = await self.press_button() + await asyncio.gather( *[ self.__control(toio, axes_status[toio_id], button_status[toio_id]) @@ -60,13 +82,15 @@ async def __control(self, toio: Toio, axes_status, button_status): elif button_status[9]: # R2 button await toio.sound.play(sound_effect=9) elif button_status[10]: # L1 button + self.bullets = [] await toio.sound.play(sound_effect=10) elif button_status[11]: # R1 button + self.bullets.append(self.bullet_image) await toio.sound.play(sound_effect=random.randint(0, 10)) elif button_status[12]: # △ button toio.forward_speed = 150 - await toio.lamp.turn_on(time=15, red=255, green=0, blue=0) + await toio.lamp.turn_on(time=1, red=255, green=0, blue=0) await toio.sound.play(sound_effect=1) elif button_status[13]: # ○ button @@ -84,7 +108,7 @@ async def __control(self, toio: Toio, axes_status, button_status): elif button_status[15]: # □ button toio.forward_speed = 50 - await toio.lamp.turn_on(time=15, red=0, green=0, blue=255) + await toio.lamp.turn_on(time=1, red=0, green=0, blue=255) await toio.sound.play(sound_effect=10) elif button_status[16]: @@ -103,3 +127,38 @@ async def press_button(self): await asyncio.sleep(0.01) return axes_status, button_status + + async def print_screen(self): + joy = pygame.joystick.Joystick(0) + self.screen.fill((0, 0, 0)) # 画面を黒色で塗りつぶす + # self.screen.blit(self.mat_image, (0, 0)) + for bullet_image in self.bullets: + self.screen.blit(bullet_image, (random.randint(0, SCREEN_SIZE[0]), random.randint(0, SCREEN_SIZE[1]))) + # イベント処理 + for event in pygame.event.get(): # ×ボタンによる終了 + if event.type == QUIT: # 終了イベント + sys.exit() + + # ジョイスティック(アナログバー左スティック)状態の取得 + circle_x = int( + (joy.get_axis(0) + 1) * X_CENTER + ) # joystick(横軸)の方向キーはは-1~1の範囲で取得できる + circle_y = int( + (joy.get_axis(1) + 1) * Y_CENTER + ) # joystick(縦軸)の方向キーはは-1~1の範囲で取得できる + + # 描画範囲の上下限チェック + if circle_x < 0: + circle_x = 0 + elif circle_x > SCREEN_SIZE[0]: + circle_x = SCREEN_SIZE[0] + + if circle_y < 0: + circle_y = 0 + elif circle_y > SCREEN_SIZE[1]: + circle_y = SCREEN_SIZE[1] + + pygame.draw.circle(self.screen, (255, 0, 0), (circle_x, circle_y), 10) + pygame.display.update() + + await asyncio.sleep(0.01)