pybricks 3.2.0rc2__tar.gz → 3.3.0a5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/PKG-INFO +6 -1
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/README.rst +5 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/pyproject.toml +4 -2
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/pybricks/_common.py +266 -22
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/pybricks/ev3devices.py +2 -4
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/pybricks/hubs.py +100 -9
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/pybricks/parameters.py +15 -1
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/pybricks/pupdevices.py +8 -3
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/pybricks/robotics.py +18 -9
- pybricks-3.3.0a5/src/pybricks/tools.py +227 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/urandom/__init__.py +1 -1
- pybricks-3.2.0rc2/setup.py +0 -50
- pybricks-3.2.0rc2/src/pybricks/geometry.py +0 -132
- pybricks-3.2.0rc2/src/pybricks/tools.py +0 -102
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/LICENSE +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/micropython/__init__.py +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/micropython/py.typed +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/pybricks/__init__.py +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/pybricks/ev3dev/_speaker.py +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/pybricks/iodevices.py +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/pybricks/media/__init__.py +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/pybricks/media/ev3dev.py +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/pybricks/media/py.typed +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/pybricks/messaging.py +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/pybricks/nxtdevices.py +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/pybricks/py.typed +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/uerrno/__init__.py +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/uerrno/py.typed +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/uio/__init__.py +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/uio/py.typed +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/ujson/__init__.py +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/umath/__init__.py +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/umath/py.typed +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/urandom/py.typed +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/uselect/__init__.py +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/uselect/py.typed +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/ustruct/__init__.py +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/usys/__init__.py +0 -0
- {pybricks-3.2.0rc2 → pybricks-3.3.0a5}/src/usys/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pybricks
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.0a5
|
|
4
4
|
Summary: Documentation and user-API stubs for Pybricks MicroPython
|
|
5
5
|
Home-page: https://pybricks.com
|
|
6
6
|
License: MIT
|
|
@@ -35,6 +35,11 @@ used to generate the `official documentation`_.
|
|
|
35
35
|
See the `contributor's guide <CONTRIBUTING.md>`_ for acceptable changes and
|
|
36
36
|
instructions to build the documentation locally.
|
|
37
37
|
|
|
38
|
+
You can use the API stubs in this repository for syntax highlighting and code
|
|
39
|
+
completion when programming the EV3 with VS Code. To enable, remove the
|
|
40
|
+
``"python.languageServer"="None"`` line in the ``.vscode/settings.json`` file
|
|
41
|
+
generated by the *LEGO® MINDSTORMS® EV3 MicroPython* extension.
|
|
42
|
+
|
|
38
43
|
For general discussion, please visit the `support`_ issue tracker.
|
|
39
44
|
|
|
40
45
|
.. _Pybricks package: pybricks
|
|
@@ -12,6 +12,11 @@ used to generate the `official documentation`_.
|
|
|
12
12
|
See the `contributor's guide <CONTRIBUTING.md>`_ for acceptable changes and
|
|
13
13
|
instructions to build the documentation locally.
|
|
14
14
|
|
|
15
|
+
You can use the API stubs in this repository for syntax highlighting and code
|
|
16
|
+
completion when programming the EV3 with VS Code. To enable, remove the
|
|
17
|
+
``"python.languageServer"="None"`` line in the ``.vscode/settings.json`` file
|
|
18
|
+
generated by the *LEGO® MINDSTORMS® EV3 MicroPython* extension.
|
|
19
|
+
|
|
15
20
|
For general discussion, please visit the `support`_ issue tracker.
|
|
16
21
|
|
|
17
22
|
.. _Pybricks package: pybricks
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "pybricks"
|
|
3
|
-
version = "3.
|
|
3
|
+
version = "3.3.0a5"
|
|
4
4
|
description = "Documentation and user-API stubs for Pybricks MicroPython"
|
|
5
5
|
authors = ["The Pybricks Authors <dev@pybricks.com>"]
|
|
6
6
|
maintainers = ["Laurens Valk <laurens@pybricks.com>", "David Lechner <david@pybricks.com>" ]
|
|
@@ -29,10 +29,12 @@ packages = [
|
|
|
29
29
|
[tool.poetry.dependencies]
|
|
30
30
|
python = "^3.8"
|
|
31
31
|
|
|
32
|
-
[tool.poetry.
|
|
32
|
+
[tool.poetry.group.lint.dependencies]
|
|
33
33
|
black = "^22.3.0"
|
|
34
34
|
doc8 = "^0.8.1"
|
|
35
35
|
flake8 = "^4.0"
|
|
36
|
+
|
|
37
|
+
[tool.poetry.group.doc.dependencies]
|
|
36
38
|
Sphinx = { git = "https://github.com/pybricks/sphinx.git", rev = "b00124cb" }
|
|
37
39
|
sphinx-rtd-theme = "^1.0.0"
|
|
38
40
|
toml = "^0.10.0"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
|
2
|
-
# Copyright (c) 2018-
|
|
2
|
+
# Copyright (c) 2018-2023 The Pybricks Authors
|
|
3
3
|
|
|
4
4
|
"""Generic cross-platform module for typical devices like lights, displays,
|
|
5
5
|
speakers, and batteries."""
|
|
@@ -8,8 +8,8 @@ from __future__ import annotations
|
|
|
8
8
|
|
|
9
9
|
from typing import Union, Iterable, overload, Optional, Tuple, Collection, TYPE_CHECKING
|
|
10
10
|
|
|
11
|
-
from .
|
|
12
|
-
from .parameters import Direction, Stop, Button, Port, Color, Side
|
|
11
|
+
from .tools import Matrix
|
|
12
|
+
from .parameters import Axis, Direction, Stop, Button, Port, Color, Side
|
|
13
13
|
|
|
14
14
|
if TYPE_CHECKING:
|
|
15
15
|
from .parameters import Number
|
|
@@ -219,18 +219,18 @@ class Control:
|
|
|
219
219
|
kp: Optional[Number] = None,
|
|
220
220
|
ki: Optional[Number] = None,
|
|
221
221
|
kd: Optional[Number] = None,
|
|
222
|
-
|
|
222
|
+
integral_deadzone: Optional[Number] = None,
|
|
223
223
|
integral_rate: Optional[Number] = None,
|
|
224
224
|
) -> None:
|
|
225
225
|
...
|
|
226
226
|
|
|
227
227
|
@overload
|
|
228
|
-
def pid(self) -> Tuple[int, int, int,
|
|
228
|
+
def pid(self) -> Tuple[int, int, int, int, int]:
|
|
229
229
|
...
|
|
230
230
|
|
|
231
231
|
def pid(self, *args):
|
|
232
|
-
"""pid(kp, ki, kd,
|
|
233
|
-
pid() -> Tuple[int, int, int,
|
|
232
|
+
"""pid(kp, ki, kd, integral_deadzone, integral_rate)
|
|
233
|
+
pid() -> Tuple[int, int, int, int, int]
|
|
234
234
|
|
|
235
235
|
Gets or sets the PID values for position and speed control.
|
|
236
236
|
|
|
@@ -245,7 +245,8 @@ class Control:
|
|
|
245
245
|
kd (int): Derivative position (or proportional speed) control
|
|
246
246
|
constant. It is the feedback torque per
|
|
247
247
|
unit of speed: µNm/(deg/s).
|
|
248
|
-
|
|
248
|
+
integral_deadzone (Number, deg or Number, mm): Zone around the
|
|
249
|
+
target where the error integral does not accumulate errors.
|
|
249
250
|
integral_rate (Number, deg/s or Number, mm/s): Maximum rate at
|
|
250
251
|
which the error integral is allowed to grow.
|
|
251
252
|
"""
|
|
@@ -303,6 +304,52 @@ class Control:
|
|
|
303
304
|
"""
|
|
304
305
|
|
|
305
306
|
|
|
307
|
+
class Model:
|
|
308
|
+
"""Class to interact with motor state observer and settings."""
|
|
309
|
+
|
|
310
|
+
def state(self) -> Tuple[float, float, float, bool]:
|
|
311
|
+
"""state() -> Tuple[float, float, float, bool]
|
|
312
|
+
|
|
313
|
+
Gets the estimated angle, speed, current, and stall state of the motor,
|
|
314
|
+
using a simulation model that mimics the real motor.
|
|
315
|
+
These estimates are updated faster than the real measurements,
|
|
316
|
+
which can be useful when building your own PID controllers.
|
|
317
|
+
|
|
318
|
+
For most applications it is better to used the *measured*
|
|
319
|
+
:meth:`angle <pybricks.pupdevices.Motor.angle>`,
|
|
320
|
+
:meth:`speed <pybricks.pupdevices.Motor.speed>`,
|
|
321
|
+
:meth:`load <pybricks.pupdevices.Motor.load>`, and
|
|
322
|
+
:meth:`stall <pybricks.pupdevices.Motor.stalled>` state instead.
|
|
323
|
+
|
|
324
|
+
Returns:
|
|
325
|
+
Tuple with the estimated angle (deg), speed (deg/s), current (mA),
|
|
326
|
+
and stall state (``True`` or ``False``).
|
|
327
|
+
"""
|
|
328
|
+
|
|
329
|
+
@overload
|
|
330
|
+
def settings(self, values: tuple) -> None:
|
|
331
|
+
...
|
|
332
|
+
|
|
333
|
+
@overload
|
|
334
|
+
def settings(self) -> tuple:
|
|
335
|
+
...
|
|
336
|
+
|
|
337
|
+
def settings(self, speed, time):
|
|
338
|
+
"""settings(values)
|
|
339
|
+
settings() -> Tuple
|
|
340
|
+
|
|
341
|
+
Gets or sets model settings as a tuple of integers. If no arguments are
|
|
342
|
+
given, this will return the current values. This method is mainly used
|
|
343
|
+
to debug the motor model class. Changing these settings should not be
|
|
344
|
+
needed in user programs.
|
|
345
|
+
|
|
346
|
+
.. _model settings: https://docs.pybricks.com/projects/pbio/en/latest/struct__pbio__observer__settings__t.html
|
|
347
|
+
|
|
348
|
+
Arguments:
|
|
349
|
+
values (Tuple): Tuple with `model settings`_.
|
|
350
|
+
"""
|
|
351
|
+
|
|
352
|
+
|
|
306
353
|
class Motor(DCMotor):
|
|
307
354
|
"""Generic class to control motors with built-in rotation sensors."""
|
|
308
355
|
|
|
@@ -312,14 +359,18 @@ class Motor(DCMotor):
|
|
|
312
359
|
``control`` attribute of the motor. See :ref:`control` for an overview
|
|
313
360
|
of available methods."""
|
|
314
361
|
|
|
362
|
+
model = Model()
|
|
363
|
+
"""Model representing the observer that estimates the motor state."""
|
|
364
|
+
|
|
315
365
|
def __init__(
|
|
316
366
|
self,
|
|
317
367
|
port: Port,
|
|
318
368
|
positive_direction: Direction = Direction.CLOCKWISE,
|
|
319
369
|
gears: Optional[Union[Collection[int], Collection[Collection[int]]]] = None,
|
|
320
370
|
reset_angle: bool = True,
|
|
371
|
+
profile: Number = None,
|
|
321
372
|
):
|
|
322
|
-
"""__init__(port, positive_direction=Direction.CLOCKWISE, gears=None, reset_angle=True)
|
|
373
|
+
"""__init__(port, positive_direction=Direction.CLOCKWISE, gears=None, reset_angle=True, profile=None)
|
|
323
374
|
|
|
324
375
|
Arguments:
|
|
325
376
|
port (Port): Port to which the motor is connected.
|
|
@@ -336,12 +387,16 @@ class Motor(DCMotor):
|
|
|
336
387
|
When you specify a gear train, all motor commands and settings
|
|
337
388
|
are automatically adjusted to account for the resulting gear
|
|
338
389
|
ratio. The motor direction remains unchanged by this.
|
|
339
|
-
reset_angle(bool):
|
|
390
|
+
reset_angle (bool):
|
|
340
391
|
Choose ``True`` to reset the rotation sensor value to the
|
|
341
392
|
absolute marker angle (between -180 and 179).
|
|
342
393
|
Choose ``False`` to keep the
|
|
343
394
|
current value, so your program knows where it left off last
|
|
344
395
|
time.
|
|
396
|
+
profile (Number, deg): Precision profile. A lower value
|
|
397
|
+
means more precise movement; a larger value means
|
|
398
|
+
smoother movement. If no value is given, a suitable profile for
|
|
399
|
+
this motor type will be selected automatically.
|
|
345
400
|
"""
|
|
346
401
|
|
|
347
402
|
def angle(self) -> int:
|
|
@@ -353,11 +408,19 @@ class Motor(DCMotor):
|
|
|
353
408
|
Motor angle.
|
|
354
409
|
"""
|
|
355
410
|
|
|
356
|
-
def speed(self) -> int:
|
|
357
|
-
"""speed() -> int: deg/s
|
|
411
|
+
def speed(self, window: Number = 100) -> int:
|
|
412
|
+
"""speed(window=100) -> int: deg/s
|
|
358
413
|
|
|
359
414
|
Gets the speed of the motor.
|
|
360
415
|
|
|
416
|
+
The speed is measured as the change in the motor angle during the
|
|
417
|
+
given time window. A short window makes the speed value more
|
|
418
|
+
responsive to motor movement, but less steady. A long window makes the
|
|
419
|
+
speed value less responsive, but more steady.
|
|
420
|
+
|
|
421
|
+
Arguments:
|
|
422
|
+
window (Number, ms): The time window used to determine the speed.
|
|
423
|
+
|
|
361
424
|
Returns:
|
|
362
425
|
Motor speed.
|
|
363
426
|
|
|
@@ -731,7 +794,7 @@ class LightMatrix:
|
|
|
731
794
|
|
|
732
795
|
Arguments:
|
|
733
796
|
matrices (iter): Sequence of
|
|
734
|
-
:class:`Matrix <pybricks.
|
|
797
|
+
:class:`Matrix <pybricks.tools.Matrix>` of intensities.
|
|
735
798
|
interval (Number, ms): Time to display each image in the list.
|
|
736
799
|
"""
|
|
737
800
|
|
|
@@ -928,22 +991,94 @@ class Accelerometer(SimpleAccelerometer):
|
|
|
928
991
|
along the x-axis.
|
|
929
992
|
|
|
930
993
|
Returns:
|
|
931
|
-
Tuple of pitch and roll angles.
|
|
994
|
+
Tuple of pitch and roll angles in degrees.
|
|
932
995
|
"""
|
|
933
996
|
|
|
934
997
|
|
|
935
998
|
class IMU(Accelerometer):
|
|
999
|
+
def ready(self) -> bool:
|
|
1000
|
+
"""ready() -> bool
|
|
1001
|
+
|
|
1002
|
+
Checks if the device is calibrated and ready for use.
|
|
1003
|
+
|
|
1004
|
+
This becomes ``True`` when the robot has been sitting stationary for a
|
|
1005
|
+
few seconds, which allows the device to re-calibrate. It is ``False``
|
|
1006
|
+
if the hub has just been started, or if it hasn't had a chance to
|
|
1007
|
+
calibrate for more than 10 minutes.
|
|
1008
|
+
|
|
1009
|
+
Returns:
|
|
1010
|
+
``True`` if it is ready for use, ``False`` if not.
|
|
1011
|
+
"""
|
|
1012
|
+
|
|
1013
|
+
def stationary(self) -> bool:
|
|
1014
|
+
"""stationary() -> bool
|
|
1015
|
+
|
|
1016
|
+
Checks if the device is currently stationary (not moving).
|
|
1017
|
+
|
|
1018
|
+
Returns:
|
|
1019
|
+
``True`` if stationary for at least a second, ``False`` if it is
|
|
1020
|
+
moving.
|
|
1021
|
+
"""
|
|
1022
|
+
|
|
1023
|
+
@overload
|
|
1024
|
+
def settings(
|
|
1025
|
+
self,
|
|
1026
|
+
angular_velocity_threshold: float = None,
|
|
1027
|
+
acceleration_threshold: float = None,
|
|
1028
|
+
) -> None:
|
|
1029
|
+
...
|
|
1030
|
+
|
|
1031
|
+
@overload
|
|
1032
|
+
def settings(self) -> Tuple[float, float]:
|
|
1033
|
+
...
|
|
1034
|
+
|
|
1035
|
+
def settings(self, *args):
|
|
1036
|
+
"""
|
|
1037
|
+
settings(angular_velocity_threshold, acceleration_threshold)
|
|
1038
|
+
settings() -> Tuple[float, float]
|
|
1039
|
+
|
|
1040
|
+
Configures the IMU settings. If no arguments are given,
|
|
1041
|
+
this returns the current values.
|
|
1042
|
+
|
|
1043
|
+
The ``angular_velocity_threshold`` and ``acceleration_threshold``
|
|
1044
|
+
define when the hub is considered stationary. If all
|
|
1045
|
+
measurements stay below these thresholds for one second, the IMU
|
|
1046
|
+
will recalibrate itself.
|
|
1047
|
+
|
|
1048
|
+
In a noisy room with high ambient vibrations (such as a
|
|
1049
|
+
competition hall), it is recommended to increase the thresholds
|
|
1050
|
+
slightly to give your robot the chance to calibrate.
|
|
1051
|
+
To verify that your settings are working as expected, test that
|
|
1052
|
+
the ``stationary()`` method gives ``False`` if your robot is moving,
|
|
1053
|
+
and ``True`` if it is sitting still for at least a second.
|
|
1054
|
+
|
|
1055
|
+
Arguments:
|
|
1056
|
+
angular_velocity_threshold (Number, deg/s): The threshold for
|
|
1057
|
+
angular velocity. The default value is 1.5 deg/s.
|
|
1058
|
+
acceleration_threshold (Number, mm/s²): The threshold for angular
|
|
1059
|
+
velocity. The default value is 250 mm/s².
|
|
1060
|
+
"""
|
|
1061
|
+
|
|
936
1062
|
def heading(self) -> float:
|
|
937
1063
|
"""heading() -> float: deg
|
|
938
1064
|
|
|
939
|
-
Gets the heading angle
|
|
940
|
-
|
|
941
|
-
frame <robotframe>`, prior to applying any tilt rotation.
|
|
1065
|
+
Gets the heading angle of your robot. A positive value means a
|
|
1066
|
+
clockwise turn.
|
|
942
1067
|
|
|
943
|
-
|
|
944
|
-
|
|
1068
|
+
The heading is 0 when your program starts. The value continues to grow
|
|
1069
|
+
even as the robot turns more than 180 degrees. It does not wrap around
|
|
1070
|
+
to -180 like it does in some apps.
|
|
945
1071
|
|
|
946
|
-
|
|
1072
|
+
|
|
1073
|
+
.. note:: *For now, this method only keeps track of the heading while
|
|
1074
|
+
the robot is on a flat surface.*
|
|
1075
|
+
|
|
1076
|
+
This means that the value is
|
|
1077
|
+
no longer correct if you lift it from the table. To solve
|
|
1078
|
+
this, you can call ``reset_heading`` to reset the heading to
|
|
1079
|
+
a known value *after* you put it back down. For example, you
|
|
1080
|
+
could align your robot with the side of the competition table
|
|
1081
|
+
and reset the heading 90 degrees as the new starting point.
|
|
947
1082
|
|
|
948
1083
|
Returns:
|
|
949
1084
|
Heading angle relative to starting orientation.
|
|
@@ -955,8 +1090,6 @@ class IMU(Accelerometer):
|
|
|
955
1090
|
|
|
956
1091
|
Resets the accumulated heading angle of the robot.
|
|
957
1092
|
|
|
958
|
-
.. note:: This method is not yet implemented.
|
|
959
|
-
|
|
960
1093
|
Arguments:
|
|
961
1094
|
angle (Number, deg): Value to which the heading should be reset.
|
|
962
1095
|
"""
|
|
@@ -985,6 +1118,41 @@ class IMU(Accelerometer):
|
|
|
985
1118
|
this returns a vector of accelerations along all axes.
|
|
986
1119
|
"""
|
|
987
1120
|
|
|
1121
|
+
def rotation(self, axis: Axis) -> float:
|
|
1122
|
+
"""
|
|
1123
|
+
rotation(axis) -> float: deg
|
|
1124
|
+
|
|
1125
|
+
Gets the rotation of the device along a given axis in
|
|
1126
|
+
the :ref:`robot reference frame <robotframe>`.
|
|
1127
|
+
|
|
1128
|
+
This value is useful if your robot *only* rotates along the requested
|
|
1129
|
+
axis. For general three-dimensional motion, use the
|
|
1130
|
+
``orientation()`` method instead.
|
|
1131
|
+
|
|
1132
|
+
The value starts counting from ``0`` when you initialize this class.
|
|
1133
|
+
|
|
1134
|
+
Arguments:
|
|
1135
|
+
axis (Axis): Axis along which the rotation should be measured.
|
|
1136
|
+
Returns:
|
|
1137
|
+
The rotation angle.
|
|
1138
|
+
"""
|
|
1139
|
+
|
|
1140
|
+
def orientation(self) -> Matrix:
|
|
1141
|
+
"""
|
|
1142
|
+
orientation() -> Matrix
|
|
1143
|
+
|
|
1144
|
+
Gets the three-dimensional orientation of the robot in
|
|
1145
|
+
the :ref:`robot reference frame <robotframe>`.
|
|
1146
|
+
|
|
1147
|
+
It returns a rotation matrix whose columns represent the ``X``, ``Y``,
|
|
1148
|
+
and ``Z`` axis of the robot.
|
|
1149
|
+
|
|
1150
|
+
.. note:: This method is not yet implemented.
|
|
1151
|
+
|
|
1152
|
+
Returns:
|
|
1153
|
+
The rotation matrix.
|
|
1154
|
+
"""
|
|
1155
|
+
|
|
988
1156
|
|
|
989
1157
|
class CommonColorSensor:
|
|
990
1158
|
"""Generic color sensor that supports Pybricks color calibration."""
|
|
@@ -1117,3 +1285,79 @@ class AmbientColorSensor(CommonColorSensor):
|
|
|
1117
1285
|
Measured color. The color is described by a hue (0--359), a
|
|
1118
1286
|
saturation (0--100), and a brightness value (0--100).
|
|
1119
1287
|
"""
|
|
1288
|
+
|
|
1289
|
+
|
|
1290
|
+
class BLE:
|
|
1291
|
+
"""
|
|
1292
|
+
Bluetooth Low Energy.
|
|
1293
|
+
|
|
1294
|
+
.. versionadded:: 3.3
|
|
1295
|
+
"""
|
|
1296
|
+
|
|
1297
|
+
def broadcast(self, *args: Union[None, bool, int, float, str, bytes]) -> None:
|
|
1298
|
+
"""broadcast(data0, data1, ...)
|
|
1299
|
+
|
|
1300
|
+
Starts broadcasting the given data values.
|
|
1301
|
+
|
|
1302
|
+
Each value can be any of ``int``, ``float``, ``str`, ``bytes``,
|
|
1303
|
+
``None``, ``True``, or ``False``. The data is broadcasted on the
|
|
1304
|
+
*broadcast_channel* you selected when initializing the hub.
|
|
1305
|
+
|
|
1306
|
+
The total data size is quite limited (26 bytes). ``None``, ``True`` and
|
|
1307
|
+
``False`` take 1 byte each. ``float`` takes 5 bytes. ``int`` takes 2 to
|
|
1308
|
+
5 bytes depending on how big the number is. ``str`` and ``bytes`` take
|
|
1309
|
+
the number of bytes in the object plus one extra byte.
|
|
1310
|
+
|
|
1311
|
+
Params:
|
|
1312
|
+
args: Zero or more values to be broadcast.
|
|
1313
|
+
|
|
1314
|
+
|
|
1315
|
+
|
|
1316
|
+
.. versionadded:: 3.3
|
|
1317
|
+
"""
|
|
1318
|
+
|
|
1319
|
+
def observe(
|
|
1320
|
+
self, channel: int
|
|
1321
|
+
) -> Optional[Tuple[Union[None, bool, int, float, str, bytes], ...]]:
|
|
1322
|
+
"""observe(channel) -> tuple | None
|
|
1323
|
+
|
|
1324
|
+
Retrieves the last observed data for a given channel.
|
|
1325
|
+
|
|
1326
|
+
Args:
|
|
1327
|
+
channel (int): The channel to observe (0 to 255).
|
|
1328
|
+
|
|
1329
|
+
Returns:
|
|
1330
|
+
A tuple of the received data or ``None`` if no recent data is
|
|
1331
|
+
available.
|
|
1332
|
+
|
|
1333
|
+
.. tip:: Receiving data is more reliable when the hub is not connected
|
|
1334
|
+
to a computer or other devices at the same time.
|
|
1335
|
+
|
|
1336
|
+
.. versionadded:: 3.3
|
|
1337
|
+
"""
|
|
1338
|
+
|
|
1339
|
+
def signal_strength(self, channel: int) -> int:
|
|
1340
|
+
"""signal_strength(channel) -> int: dBm
|
|
1341
|
+
|
|
1342
|
+
Gets the average signal strength in dBm for the given channel.
|
|
1343
|
+
|
|
1344
|
+
This is useful for detecting how near the broadcasting device is. A close
|
|
1345
|
+
device may have a signal strength around -40 dBm while a far away device
|
|
1346
|
+
might have a signal strength around -70 dBm.
|
|
1347
|
+
|
|
1348
|
+
Args:
|
|
1349
|
+
channel (int): The channel number (0 to 255).
|
|
1350
|
+
|
|
1351
|
+
Returns:
|
|
1352
|
+
The signal strength or ``-128`` if there is no recent observed data.
|
|
1353
|
+
|
|
1354
|
+
.. versionadded:: 3.3
|
|
1355
|
+
"""
|
|
1356
|
+
|
|
1357
|
+
def version(self) -> str:
|
|
1358
|
+
"""version() -> str
|
|
1359
|
+
|
|
1360
|
+
Gets the firmware version from the Bluetooth chip.
|
|
1361
|
+
|
|
1362
|
+
.. versionadded:: 3.3
|
|
1363
|
+
"""
|
|
@@ -168,14 +168,12 @@ class InfraredSensor:
|
|
|
168
168
|
class GyroSensor:
|
|
169
169
|
"""LEGO® MINDSTORMS® EV3 Gyro Sensor."""
|
|
170
170
|
|
|
171
|
-
def __init__(
|
|
172
|
-
self, port: _Port, positive_direction: _Direction = _Direction.CLOCKWISE
|
|
173
|
-
):
|
|
171
|
+
def __init__(self, port: _Port, direction: _Direction = _Direction.CLOCKWISE):
|
|
174
172
|
"""GyroSensor(port)
|
|
175
173
|
|
|
176
174
|
Arguments:
|
|
177
175
|
port (Port): Port to which the sensor is connected.
|
|
178
|
-
|
|
176
|
+
direction (Direction):
|
|
179
177
|
Positive rotation direction when looking at the red dot on top
|
|
180
178
|
of the sensor.
|
|
181
179
|
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
|
2
|
-
# Copyright (c) 2018-
|
|
2
|
+
# Copyright (c) 2018-2023 The Pybricks Authors
|
|
3
3
|
|
|
4
4
|
"""LEGO® Programmable Hubs."""
|
|
5
|
+
|
|
6
|
+
from typing import Sequence
|
|
7
|
+
|
|
5
8
|
from . import _common
|
|
6
9
|
from .ev3dev import _speaker
|
|
7
|
-
from .geometry import Axis
|
|
8
10
|
from .media.ev3dev import Image as _Image
|
|
9
|
-
from .parameters import Button as _Button
|
|
11
|
+
from .parameters import Button as _Button, Axis
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
class EV3Brick:
|
|
@@ -39,6 +41,25 @@ class MoveHub:
|
|
|
39
41
|
imu = _common.SimpleAccelerometer()
|
|
40
42
|
system = _common.System()
|
|
41
43
|
button = _common.Keypad([_Button.CENTER])
|
|
44
|
+
ble = _common.BLE()
|
|
45
|
+
|
|
46
|
+
def __init__(
|
|
47
|
+
self, broadcast_channel: int = 0, observe_channels: Sequence[int] = []
|
|
48
|
+
):
|
|
49
|
+
"""MoveHub(broadcast_channel=0, observe_channels=[])
|
|
50
|
+
|
|
51
|
+
Arguments:
|
|
52
|
+
broadcast_channel:
|
|
53
|
+
A value from 0 to 255 indicating which channel ``hub.ble.broadcast()``
|
|
54
|
+
will use. Default is channel 0.
|
|
55
|
+
observe_channels:
|
|
56
|
+
A list of channels to listen to when ``hub.ble.observe()`` is
|
|
57
|
+
called. Listening to more channels requires more memory.
|
|
58
|
+
Default is an empty list (no channels).
|
|
59
|
+
|
|
60
|
+
.. versionchanged:: 3.3
|
|
61
|
+
Added *broadcast_channel* and *observe_channels* arguments.
|
|
62
|
+
"""
|
|
42
63
|
|
|
43
64
|
|
|
44
65
|
class CityHub:
|
|
@@ -50,6 +71,25 @@ class CityHub:
|
|
|
50
71
|
light = _common.ColorLight()
|
|
51
72
|
system = _common.System()
|
|
52
73
|
button = _common.Keypad([_Button.CENTER])
|
|
74
|
+
ble = _common.BLE()
|
|
75
|
+
|
|
76
|
+
def __init__(
|
|
77
|
+
self, broadcast_channel: int = 0, observe_channels: Sequence[int] = []
|
|
78
|
+
):
|
|
79
|
+
"""CityHub(broadcast_channel=0, observe_channels=[])
|
|
80
|
+
|
|
81
|
+
Arguments:
|
|
82
|
+
broadcast_channel:
|
|
83
|
+
A value from 0 to 255 indicating which channel ``hub.ble.broadcast()``
|
|
84
|
+
will use. Default is channel 0.
|
|
85
|
+
observe_channels:
|
|
86
|
+
A list of channels to listen to when ``hub.ble.observe()`` is
|
|
87
|
+
called. Listening to more channels requires more memory.
|
|
88
|
+
Default is an empty list (no channels).
|
|
89
|
+
|
|
90
|
+
.. versionchanged:: 3.3
|
|
91
|
+
Added *broadcast_channel* and *observe_channels* arguments.
|
|
92
|
+
"""
|
|
53
93
|
|
|
54
94
|
|
|
55
95
|
class TechnicHub:
|
|
@@ -62,9 +102,16 @@ class TechnicHub:
|
|
|
62
102
|
imu = _common.IMU()
|
|
63
103
|
system = _common.System()
|
|
64
104
|
button = _common.Keypad([_Button.CENTER])
|
|
105
|
+
ble = _common.BLE()
|
|
65
106
|
|
|
66
|
-
def __init__(
|
|
67
|
-
|
|
107
|
+
def __init__(
|
|
108
|
+
self,
|
|
109
|
+
top_side: Axis = Axis.Z,
|
|
110
|
+
front_side: Axis = Axis.X,
|
|
111
|
+
broadcast_channel: int = 0,
|
|
112
|
+
observe_channels: Sequence[int] = [],
|
|
113
|
+
):
|
|
114
|
+
"""TechnicHub(top_side=Axis.Z, front_side=Axis.X, broadcast_channel=0, observe_channels=[])
|
|
68
115
|
|
|
69
116
|
Initializes the hub. Optionally, specify how the hub is
|
|
70
117
|
:ref:`placed in your design <robotframe>` by saying in which
|
|
@@ -76,6 +123,16 @@ class TechnicHub:
|
|
|
76
123
|
the hub.
|
|
77
124
|
front_side (Axis): The axis that passes through the *front side* of
|
|
78
125
|
the hub.
|
|
126
|
+
broadcast_channel:
|
|
127
|
+
A value from 0 to 255 indicating which channel ``hub.ble.broadcast()``
|
|
128
|
+
will use. Default is channel 0.
|
|
129
|
+
observe_channels:
|
|
130
|
+
A list of channels to listen to when ``hub.ble.observe()`` is
|
|
131
|
+
called. Listening to more channels requires more memory.
|
|
132
|
+
Default is an empty list (no channels).
|
|
133
|
+
|
|
134
|
+
.. versionchanged:: 3.3
|
|
135
|
+
Added *broadcast_channel* and *observe_channels* arguments.
|
|
79
136
|
"""
|
|
80
137
|
|
|
81
138
|
|
|
@@ -90,9 +147,16 @@ class EssentialHub:
|
|
|
90
147
|
light = _common.ColorLight()
|
|
91
148
|
imu = _common.IMU()
|
|
92
149
|
system = _common.System()
|
|
150
|
+
ble = _common.BLE()
|
|
93
151
|
|
|
94
|
-
def __init__(
|
|
95
|
-
|
|
152
|
+
def __init__(
|
|
153
|
+
self,
|
|
154
|
+
top_side: Axis = Axis.Z,
|
|
155
|
+
front_side: Axis = Axis.X,
|
|
156
|
+
broadcast_channel: int = 0,
|
|
157
|
+
observe_channels: Sequence[int] = [],
|
|
158
|
+
):
|
|
159
|
+
"""EssentialHub(top_side=Axis.Z, front_side=Axis.X, broadcast_channel=0, observe_channels=[])
|
|
96
160
|
|
|
97
161
|
Initializes the hub. Optionally, specify how the hub is
|
|
98
162
|
:ref:`placed in your design <robotframe>` by saying in which
|
|
@@ -104,6 +168,16 @@ class EssentialHub:
|
|
|
104
168
|
the hub.
|
|
105
169
|
front_side (Axis): The axis that passes through the *front side* of
|
|
106
170
|
the hub.
|
|
171
|
+
broadcast_channel:
|
|
172
|
+
A value from 0 to 255 indicating which channel ``hub.ble.broadcast()``
|
|
173
|
+
will use. Default is channel 0.
|
|
174
|
+
observe_channels:
|
|
175
|
+
A list of channels to listen to when ``hub.ble.observe()`` is
|
|
176
|
+
called. Listening to more channels requires more memory.
|
|
177
|
+
Default is an empty list (no channels).
|
|
178
|
+
|
|
179
|
+
.. versionchanged:: 3.3
|
|
180
|
+
Added *broadcast_channel* and *observe_channels* arguments.
|
|
107
181
|
"""
|
|
108
182
|
pass
|
|
109
183
|
|
|
@@ -128,9 +202,16 @@ class PrimeHub:
|
|
|
128
202
|
speaker = _common.Speaker()
|
|
129
203
|
imu = _common.IMU()
|
|
130
204
|
system = _common.System()
|
|
205
|
+
ble = _common.BLE()
|
|
131
206
|
|
|
132
|
-
def __init__(
|
|
133
|
-
|
|
207
|
+
def __init__(
|
|
208
|
+
self,
|
|
209
|
+
top_side: Axis = Axis.Z,
|
|
210
|
+
front_side: Axis = Axis.X,
|
|
211
|
+
broadcast_channel: int = 0,
|
|
212
|
+
observe_channels: Sequence[int] = [],
|
|
213
|
+
):
|
|
214
|
+
"""PrimeHub(top_side=Axis.Z, front_side=Axis.X, broadcast_channel=0, observe_channels=[])
|
|
134
215
|
|
|
135
216
|
Initializes the hub. Optionally, specify how the hub is
|
|
136
217
|
:ref:`placed in your design <robotframe>` by saying in which
|
|
@@ -142,6 +223,16 @@ class PrimeHub:
|
|
|
142
223
|
the hub.
|
|
143
224
|
front_side (Axis): The axis that passes through the *front side* of
|
|
144
225
|
the hub.
|
|
226
|
+
broadcast_channel:
|
|
227
|
+
A value from 0 to 255 indicating which channel ``hub.ble.broadcast()``
|
|
228
|
+
will use. Default is channel 0.
|
|
229
|
+
observe_channels:
|
|
230
|
+
A list of channels to listen to when ``hub.ble.observe()`` is
|
|
231
|
+
called. Listening to more channels requires more memory.
|
|
232
|
+
Default is an empty list (no channels).
|
|
233
|
+
|
|
234
|
+
.. versionchanged:: 3.3
|
|
235
|
+
Added *broadcast_channel* and *observe_channels* arguments.
|
|
145
236
|
"""
|
|
146
237
|
|
|
147
238
|
|
|
@@ -9,7 +9,7 @@ from enum import Enum
|
|
|
9
9
|
from typing import Union, TYPE_CHECKING
|
|
10
10
|
import os
|
|
11
11
|
|
|
12
|
-
from .
|
|
12
|
+
from .tools import Matrix as _Matrix, vector as _vector
|
|
13
13
|
|
|
14
14
|
if TYPE_CHECKING or os.environ.get("SPHINX_BUILD") == "True":
|
|
15
15
|
Number = Union[int, float]
|
|
@@ -57,6 +57,20 @@ class _PybricksEnum(Enum, metaclass=_PybricksEnumMeta):
|
|
|
57
57
|
return str(self)
|
|
58
58
|
|
|
59
59
|
|
|
60
|
+
class Axis:
|
|
61
|
+
"""Unit axes of a coordinate system.
|
|
62
|
+
|
|
63
|
+
.. data:: X = vector(1, 0, 0)
|
|
64
|
+
.. data:: Y = vector(0, 1, 0)
|
|
65
|
+
.. data:: Z = vector(0, 0, 1)
|
|
66
|
+
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
X: _Matrix = _vector(1, 0, 0)
|
|
70
|
+
Y: _Matrix = _vector(0, 1, 0)
|
|
71
|
+
Z: _Matrix = _vector(0, 0, 1)
|
|
72
|
+
|
|
73
|
+
|
|
60
74
|
class Color:
|
|
61
75
|
"""Light or surface color."""
|
|
62
76
|
|