mirror of
https://github.com/pybricks/pybricks-api.git
synced 2026-09-11 17:14:41 +00:00
Compare commits
33
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16d5ba64d2 | ||
|
|
d8802ace7d | ||
|
|
acb5206349 | ||
|
|
6686fce3c3 | ||
|
|
7d27fbb5d8 | ||
|
|
a0e98ba75f | ||
|
|
1b69e42b6b | ||
|
|
47a3d664c2 | ||
|
|
e6cb436c47 | ||
|
|
a8d74720b6 | ||
|
|
54b4e39360 | ||
|
|
1f8f0f777a | ||
|
|
45b9b89d11 | ||
|
|
e0f48b178b | ||
|
|
8ed5a489b9 | ||
|
|
a2ba8e4dcd | ||
|
|
7900f03574 | ||
|
|
7014f46441 | ||
|
|
7411a246c9 | ||
|
|
3bc2f35e3e | ||
|
|
61578b5547 | ||
|
|
c615ccf986 | ||
|
|
32f974e7e5 | ||
|
|
0efcfd4a36 | ||
|
|
356f6ffdba | ||
|
|
4967b96ddd | ||
|
|
116368e4c7 | ||
|
|
5b56249d8c | ||
|
|
04fb7e3e19 | ||
|
|
5814a73bb1 | ||
|
|
ed3059b47b | ||
|
|
2a98264144 | ||
|
|
6083b17d9a |
Vendored
-1
@@ -24,7 +24,6 @@ EV3
|
||||
ev3brick
|
||||
ev3dev
|
||||
ev3devices
|
||||
Ev3devSensor
|
||||
fb
|
||||
Franca
|
||||
func
|
||||
|
||||
+17
-1
@@ -4,7 +4,23 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
## 3.6.b5 - 2024-04-11
|
||||
### Fixed
|
||||
|
||||
- Fixed `DriveBase.angle` reporting an incorrect return type.
|
||||
|
||||
## 3.6.1 - 2025-05-01
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed missing `hub.system.info` method on some hubs.
|
||||
|
||||
## 3.6.0 - 2025-03-11
|
||||
|
||||
### Changed
|
||||
|
||||
- Update API for firmware 3.6.0. See upstream changelog for details.
|
||||
|
||||
## 3.6.0b5 - 2025-02-26
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@@ -254,12 +254,6 @@ latex_documents = [
|
||||
exclude_patterns = [
|
||||
"ev3devices.rst",
|
||||
"hubs/ev3brick.rst",
|
||||
"iodevices/analogsensor.rst",
|
||||
"iodevices/dcmotor.rst",
|
||||
"iodevices/ev3devsensor.rst",
|
||||
"iodevices/i2cdevice.rst",
|
||||
"iodevices/lumpdevice.rst",
|
||||
"iodevices/uartdevice.rst",
|
||||
"media.rst",
|
||||
"messaging.rst",
|
||||
"nxtdevices.rst",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import xml.etree.ElementTree as ET
|
||||
from docutils.parsers.rst import Directive, directives
|
||||
from docutils.parsers.rst import Directive
|
||||
from docutils import nodes
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@@ -18,14 +18,23 @@ FEATURES_MEDIUM = FEATURES_SMALL | {
|
||||
}
|
||||
|
||||
# Large feature set.
|
||||
FEATURES_LARGE = FEATURES_MEDIUM | set()
|
||||
FEATURES_LARGE = FEATURES_MEDIUM | {
|
||||
"ble-extra", # Extra features such as pairing or multiple connections.
|
||||
}
|
||||
|
||||
# Features per hub.
|
||||
HUB_FEATURES = {
|
||||
"movehub": {"movehub"} | FEATURES_SMALL,
|
||||
"cityhub": {"cityhub"} | FEATURES_MEDIUM,
|
||||
"technichub": {"technichub", "gyro", "xbox-controller"} | FEATURES_MEDIUM,
|
||||
"primehub": {"primehub", "inventorhub", "light-matrix", "gyro", "xbox-controller"}
|
||||
"movehub": {"movehub", "pup"} | FEATURES_SMALL,
|
||||
"cityhub": {"cityhub", "pup"} | FEATURES_MEDIUM,
|
||||
"technichub": {"technichub", "gyro", "xbox-controller", "pup"} | FEATURES_MEDIUM,
|
||||
"primehub": {
|
||||
"primehub",
|
||||
"inventorhub",
|
||||
"light-matrix",
|
||||
"gyro",
|
||||
"xbox-controller",
|
||||
"pup",
|
||||
}
|
||||
| FEATURES_LARGE,
|
||||
"inventorhub": {
|
||||
"primehub",
|
||||
@@ -33,9 +42,10 @@ HUB_FEATURES = {
|
||||
"light-matrix",
|
||||
"gyro",
|
||||
"xbox-controller",
|
||||
"pup",
|
||||
}
|
||||
| FEATURES_LARGE,
|
||||
"essentialhub": {"essentialhub", "gyro", "xbox-controller"} | FEATURES_LARGE,
|
||||
"essentialhub": {"essentialhub", "gyro", "xbox-controller", "pup"} | FEATURES_LARGE,
|
||||
}
|
||||
|
||||
|
||||
@@ -94,9 +104,7 @@ class PybricksRequirementsStaticDirective(Directive):
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
""".format(
|
||||
compat_row
|
||||
)
|
||||
""".format(compat_row)
|
||||
|
||||
# Return the node.
|
||||
node = nodes.raw("", html, format="html")
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 126 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
width="525"
|
||||
height="525"
|
||||
viewBox="0 0 525 525"
|
||||
sodipodi:docname="icon_ev3hub.svg"
|
||||
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||
inkscape:export-filename="../diagrams/icon_ev3hub.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata
|
||||
id="metadata8">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs6">
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath860">
|
||||
<rect
|
||||
style="fill:#6ab0de;fill-opacity:1;stroke:#6ab0de;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect862"
|
||||
width="589.10107"
|
||||
height="96.333336"
|
||||
x="235.33333"
|
||||
y="-236.00002" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath1040">
|
||||
<rect
|
||||
style="fill:#1e1e1e;fill-opacity:1;stroke:none;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect1042"
|
||||
width="128.5101"
|
||||
height="19.934668"
|
||||
x="827.15656"
|
||||
y="74.666672" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#fcfcfc"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1163"
|
||||
id="namedview4"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.9950413"
|
||||
inkscape:cx="301.49502"
|
||||
inkscape:cy="344.70931"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2"
|
||||
inkscape:snap-global="false"
|
||||
inkscape:pagecheckerboard="0" />
|
||||
<image
|
||||
width="525"
|
||||
height="468.02328"
|
||||
preserveAspectRatio="none"
|
||||
xlink:href="../cad/output/ev3device-ev3.png"
|
||||
id="image834"
|
||||
x="0"
|
||||
y="26.384924" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
width="525"
|
||||
height="525"
|
||||
viewBox="0 0 525 525"
|
||||
sodipodi:docname="icon_nxthub.svg"
|
||||
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||
inkscape:export-filename="../diagrams/icon_nxthub.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata
|
||||
id="metadata8">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs6">
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath860">
|
||||
<rect
|
||||
style="fill:#6ab0de;fill-opacity:1;stroke:#6ab0de;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect862"
|
||||
width="589.10107"
|
||||
height="96.333336"
|
||||
x="235.33333"
|
||||
y="-236.00002" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath1040">
|
||||
<rect
|
||||
style="fill:#1e1e1e;fill-opacity:1;stroke:none;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect1042"
|
||||
width="128.5101"
|
||||
height="19.934668"
|
||||
x="827.15656"
|
||||
y="74.666672" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#fcfcfc"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1163"
|
||||
id="namedview4"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.9950413"
|
||||
inkscape:cx="301.49502"
|
||||
inkscape:cy="344.70931"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2"
|
||||
inkscape:snap-global="false"
|
||||
inkscape:pagecheckerboard="false" />
|
||||
<image
|
||||
width="525"
|
||||
height="447.39801"
|
||||
preserveAspectRatio="none"
|
||||
xlink:href="../cad/output/nxtdevice-nxt.png"
|
||||
id="image960"
|
||||
x="0"
|
||||
y="34.809708" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -26,20 +26,6 @@ City Hub
|
||||
|
||||
.. automethod:: pybricks.hubs::CityHub.light.animate
|
||||
|
||||
.. rubric:: Using connectionless Bluetooth messaging
|
||||
|
||||
.. blockimg:: pybricks_blockBleBroadcast_CityHub
|
||||
|
||||
.. automethod:: pybricks.hubs::CityHub.ble.broadcast
|
||||
|
||||
.. blockimg:: pybricks_blockBleObserve_CityHub
|
||||
|
||||
.. automethod:: pybricks.hubs::CityHub.ble.observe
|
||||
|
||||
.. automethod:: pybricks.hubs::CityHub.ble.signal_strength
|
||||
|
||||
.. automethod:: pybricks.hubs::CityHub.ble.version
|
||||
|
||||
.. rubric:: Using the battery
|
||||
|
||||
.. blockimg:: pybricks_blockBatteryMeasure_CityHub_battery.voltage
|
||||
@@ -56,10 +42,12 @@ City Hub
|
||||
|
||||
.. automethod:: pybricks.hubs::CityHub.buttons.pressed
|
||||
|
||||
.. automethod:: pybricks.hubs::CityHub.system.info
|
||||
|
||||
.. blockimg:: pybricks_blockHubStopButton_CityHub
|
||||
|
||||
.. blockimg:: pybricks_blockHubStopButton_CityHub_none
|
||||
|
||||
|
||||
.. automethod:: pybricks.hubs::CityHub.system.set_stop_button
|
||||
|
||||
.. automethod:: pybricks.hubs::CityHub.system.storage
|
||||
@@ -102,23 +90,6 @@ Creating light animations
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/light_animate_cityhub.py
|
||||
|
||||
|
||||
Bluetooth examples
|
||||
------------------
|
||||
|
||||
Broadcasting data to other hubs
|
||||
*******************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/ble_broadcast_cityhub.py
|
||||
|
||||
Observing data from other hubs
|
||||
******************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/ble_observe_cityhub.py
|
||||
|
||||
|
||||
Button and system examples
|
||||
----------------------------------
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ Essential Hub
|
||||
.. blockimg:: pybricks_blockHubStopButton_EssentialHub
|
||||
|
||||
.. blockimg:: pybricks_blockHubStopButton_EssentialHub_none
|
||||
|
||||
|
||||
.. automethod:: pybricks.hubs::EssentialHub.system.set_stop_button
|
||||
|
||||
.. rubric:: Using the IMU
|
||||
@@ -63,7 +63,7 @@ Essential Hub
|
||||
.. blockimg:: pybricks_blockTilt_EssentialHub_imu.tilt.pitch
|
||||
|
||||
.. blockimg:: pybricks_blockTilt_EssentialHub_imu.tilt.roll
|
||||
|
||||
|
||||
.. automethod:: pybricks.hubs::EssentialHub.imu.tilt
|
||||
|
||||
.. blockimg:: pybricks_blockImuAcceleration_EssentialHub
|
||||
@@ -89,27 +89,13 @@ Essential Hub
|
||||
.. automethod:: pybricks.hubs::EssentialHub.imu.orientation
|
||||
|
||||
.. blockimg:: pybricks_blockImuConfigure_EssentialHub_imu.settings_heading_correction
|
||||
|
||||
|
||||
.. blockimg:: pybricks_blockImuConfigure_EssentialHub_imu.settings_angular_velocity_threshold
|
||||
|
||||
|
||||
.. blockimg:: pybricks_blockImuConfigure_EssentialHub_imu.settings_acceleration_threshold
|
||||
|
||||
|
||||
.. automethod:: pybricks.hubs::EssentialHub.imu.settings
|
||||
|
||||
.. rubric:: Using connectionless Bluetooth messaging
|
||||
|
||||
.. blockimg:: pybricks_blockBleBroadcast_EssentialHub
|
||||
|
||||
.. automethod:: pybricks.hubs::EssentialHub.ble.broadcast
|
||||
|
||||
.. blockimg:: pybricks_blockBleObserve_EssentialHub
|
||||
|
||||
.. automethod:: pybricks.hubs::EssentialHub.ble.observe
|
||||
|
||||
.. automethod:: pybricks.hubs::EssentialHub.ble.signal_strength
|
||||
|
||||
.. automethod:: pybricks.hubs::EssentialHub.ble.version
|
||||
|
||||
.. rubric:: Using the battery
|
||||
|
||||
.. blockimg:: pybricks_blockBatteryMeasure_EssentialHub_battery.voltage
|
||||
@@ -204,23 +190,6 @@ Reading acceleration and angular velocity on one axis
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/imu_read_scalar_essentialhub.py
|
||||
|
||||
|
||||
Bluetooth examples
|
||||
------------------
|
||||
|
||||
Broadcasting data to other hubs
|
||||
*******************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/ble_broadcast_essentialhub.py
|
||||
|
||||
Observing data from other hubs
|
||||
******************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/ble_observe_essentialhub.py
|
||||
|
||||
|
||||
System examples
|
||||
----------------------------------
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ Move Hub
|
||||
.. blockimg:: pybricks_blockTilt_MoveHub_imu.tilt.pitch
|
||||
|
||||
.. blockimg:: pybricks_blockTilt_MoveHub_imu.tilt.roll
|
||||
|
||||
|
||||
.. automethod:: pybricks.hubs::MoveHub.imu.tilt
|
||||
|
||||
.. blockimg:: pybricks_blockImuAcceleration_MoveHub
|
||||
@@ -49,20 +49,6 @@ Move Hub
|
||||
|
||||
Changed acceleration units from m/s² to mm/s².
|
||||
|
||||
.. rubric:: Using connectionless Bluetooth messaging
|
||||
|
||||
.. blockimg:: pybricks_blockBleBroadcast_PrimeHub
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.ble.broadcast
|
||||
|
||||
.. blockimg:: pybricks_blockBleObserve_PrimeHub
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.ble.observe
|
||||
|
||||
.. automethod:: pybricks.hubs::MoveHub.ble.signal_strength
|
||||
|
||||
.. automethod:: pybricks.hubs::MoveHub.ble.version
|
||||
|
||||
.. rubric:: Using the battery
|
||||
|
||||
.. blockimg:: pybricks_blockBatteryMeasure_MoveHub_battery.voltage
|
||||
@@ -79,10 +65,12 @@ Move Hub
|
||||
|
||||
.. automethod:: pybricks.hubs::MoveHub.buttons.pressed
|
||||
|
||||
.. automethod:: pybricks.hubs::MoveHub.system.info
|
||||
|
||||
.. blockimg:: pybricks_blockHubStopButton_MoveHub
|
||||
|
||||
.. blockimg:: pybricks_blockHubStopButton_MoveHub_none
|
||||
|
||||
|
||||
.. automethod:: pybricks.hubs::MoveHub.system.set_stop_button
|
||||
|
||||
.. automethod:: pybricks.hubs::MoveHub.system.storage
|
||||
@@ -127,23 +115,6 @@ Reading acceleration
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_movehub/imu_read_acceleration.py
|
||||
|
||||
|
||||
Bluetooth examples
|
||||
------------------
|
||||
|
||||
Broadcasting data to other hubs
|
||||
*******************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/ble_broadcast_movehub.py
|
||||
|
||||
Observing data from other hubs
|
||||
******************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/ble_observe_movehub.py
|
||||
|
||||
|
||||
Button and system examples
|
||||
----------------------------------
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ Prime Hub / Inventor Hub
|
||||
.. blockimg:: pybricks_blockHubStopButton_PrimeHub
|
||||
|
||||
.. blockimg:: pybricks_blockHubStopButton_PrimeHub_none
|
||||
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.system.set_stop_button
|
||||
|
||||
.. rubric:: Using the IMU
|
||||
@@ -109,7 +109,7 @@ Prime Hub / Inventor Hub
|
||||
.. blockimg:: pybricks_blockTilt_PrimeHub_imu.tilt.pitch
|
||||
|
||||
.. blockimg:: pybricks_blockTilt_PrimeHub_imu.tilt.roll
|
||||
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.imu.tilt
|
||||
|
||||
.. blockimg:: pybricks_blockImuAcceleration_PrimeHub
|
||||
@@ -135,11 +135,11 @@ Prime Hub / Inventor Hub
|
||||
.. automethod:: pybricks.hubs::PrimeHub.imu.orientation
|
||||
|
||||
.. blockimg:: pybricks_blockImuConfigure_PrimeHub_imu.settings_heading_correction
|
||||
|
||||
|
||||
.. blockimg:: pybricks_blockImuConfigure_PrimeHub_imu.settings_angular_velocity_threshold
|
||||
|
||||
|
||||
.. blockimg:: pybricks_blockImuConfigure_PrimeHub_imu.settings_acceleration_threshold
|
||||
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.imu.settings
|
||||
|
||||
.. rubric:: Using the speaker
|
||||
@@ -150,20 +150,6 @@ Prime Hub / Inventor Hub
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.speaker.play_notes
|
||||
|
||||
.. rubric:: Using connectionless Bluetooth messaging
|
||||
|
||||
.. blockimg:: pybricks_blockBleBroadcast_PrimeHub
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.ble.broadcast
|
||||
|
||||
.. blockimg:: pybricks_blockBleObserve_PrimeHub
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.ble.observe
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.ble.signal_strength
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.ble.version
|
||||
|
||||
.. rubric:: Using the battery
|
||||
|
||||
.. blockimg:: pybricks_blockBatteryMeasure_PrimeHub_battery.voltage
|
||||
@@ -329,23 +315,6 @@ Reading acceleration and angular velocity on one axis
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/imu_read_scalar_primehub.py
|
||||
|
||||
|
||||
Bluetooth examples
|
||||
------------------
|
||||
|
||||
Broadcasting data to other hubs
|
||||
*******************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/ble_broadcast_primehub.py
|
||||
|
||||
Observing data from other hubs
|
||||
******************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/ble_observe_primehub.py
|
||||
|
||||
|
||||
System examples
|
||||
----------------------------------
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ Technic Hub
|
||||
.. blockimg:: pybricks_blockTilt_TechnicHub_imu.tilt.pitch
|
||||
|
||||
.. blockimg:: pybricks_blockTilt_TechnicHub_imu.tilt.roll
|
||||
|
||||
|
||||
.. automethod:: pybricks.hubs::TechnicHub.imu.tilt
|
||||
|
||||
.. blockimg:: pybricks_blockImuAcceleration_TechnicHub
|
||||
@@ -77,27 +77,13 @@ Technic Hub
|
||||
.. automethod:: pybricks.hubs::TechnicHub.imu.orientation
|
||||
|
||||
.. blockimg:: pybricks_blockImuConfigure_TechnicHub_imu.settings_heading_correction
|
||||
|
||||
|
||||
.. blockimg:: pybricks_blockImuConfigure_TechnicHub_imu.settings_angular_velocity_threshold
|
||||
|
||||
|
||||
.. blockimg:: pybricks_blockImuConfigure_TechnicHub_imu.settings_acceleration_threshold
|
||||
|
||||
|
||||
.. automethod:: pybricks.hubs::TechnicHub.imu.settings
|
||||
|
||||
.. rubric:: Using connectionless Bluetooth messaging
|
||||
|
||||
.. blockimg:: pybricks_blockBleBroadcast_TechnicHub
|
||||
|
||||
.. automethod:: pybricks.hubs::TechnicHub.ble.broadcast
|
||||
|
||||
.. blockimg:: pybricks_blockBleObserve_TechnicHub
|
||||
|
||||
.. automethod:: pybricks.hubs::TechnicHub.ble.observe
|
||||
|
||||
.. automethod:: pybricks.hubs::TechnicHub.ble.signal_strength
|
||||
|
||||
.. automethod:: pybricks.hubs::TechnicHub.ble.version
|
||||
|
||||
.. rubric:: Using the battery
|
||||
|
||||
.. blockimg:: pybricks_blockBatteryMeasure_TechnicHub_battery.voltage
|
||||
@@ -114,10 +100,12 @@ Technic Hub
|
||||
|
||||
.. automethod:: pybricks.hubs::TechnicHub.buttons.pressed
|
||||
|
||||
.. automethod:: pybricks.hubs::TechnicHub.system.info
|
||||
|
||||
.. blockimg:: pybricks_blockHubStopButton_TechnicHub
|
||||
|
||||
.. blockimg:: pybricks_blockHubStopButton_TechnicHub_none
|
||||
|
||||
|
||||
.. automethod:: pybricks.hubs::TechnicHub.system.set_stop_button
|
||||
|
||||
.. automethod:: pybricks.hubs::TechnicHub.system.storage
|
||||
@@ -193,23 +181,6 @@ Reading acceleration and angular velocity on one axis
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/imu_read_scalar_technichub.py
|
||||
|
||||
|
||||
Bluetooth examples
|
||||
------------------
|
||||
|
||||
Broadcasting data to other hubs
|
||||
*******************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/ble_broadcast_technichub.py
|
||||
|
||||
Observing data from other hubs
|
||||
******************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/ble_observe_technichub.py
|
||||
|
||||
|
||||
Button and system examples
|
||||
----------------------------------
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ above to reveal this menu.
|
||||
parameters/index
|
||||
tools/index
|
||||
robotics
|
||||
messaging/index
|
||||
signaltypes
|
||||
|
||||
.. toctree::
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
EV3 Analog Sensor
|
||||
.. pybricks-requirements:: pybricks-iodevices ev3
|
||||
|
||||
Analog Sensor
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. note::
|
||||
|
||||
This class is only available on EV3.
|
||||
|
||||
.. figure:: ../../main/cad/output/iodevice-rj12brown.png
|
||||
:width: 25 %
|
||||
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
EV3 DC Motor
|
||||
DC Motor
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. note::
|
||||
This class is specifically for EV3 and NXT. This lets you drive motors that
|
||||
are not automatically detected as motors. This includes RCX motors and Power
|
||||
Function motors that are connected via the official converter cables. Note:
|
||||
Applying motor power to custom electronics may damage the hub or the device.
|
||||
|
||||
This class is specifically for on EV3. For Powered Up DC Motors, just use
|
||||
the :class:`DCMotor <pybricks.pupdevices.DCMotor>` class.
|
||||
For Powered Up DC Motors, just use
|
||||
the :class:`DCMotor <pybricks.pupdevices.DCMotor>` class instead, which will
|
||||
automatically detect the motor and use the correct and safe settings.
|
||||
|
||||
.. figure:: ../../main/cad/output/iodevice-dcmotor.png
|
||||
:width: 40 %
|
||||
@@ -16,5 +20,8 @@ EV3 DC Motor
|
||||
.. automethod:: pybricks.iodevices.DCMotor.dc
|
||||
:noindex:
|
||||
|
||||
.. automethod:: pybricks.iodevices.DCMotor.brake
|
||||
:noindex:
|
||||
|
||||
.. automethod:: pybricks.iodevices.DCMotor.stop
|
||||
:noindex:
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
Ev3dev sensors
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. note::
|
||||
|
||||
This class is only available on EV3.
|
||||
|
||||
.. figure:: ../../main/cad/output/iodevice-rj12pcbbox.png
|
||||
:width: 30 %
|
||||
|
||||
EV3 MicroPython is built on top of ev3dev, which means that a sensor
|
||||
may be supported even if it is not listed in this documentation. If so, you can
|
||||
use it with the ``Ev3devSensor`` class. This is easier and faster than using
|
||||
the custom device classes given above.
|
||||
|
||||
To check whether you can use the ``Ev3devSensor`` class:
|
||||
|
||||
* Plug the sensor into your EV3 Brick.
|
||||
* Go to the main menu of the EV3 Brick.
|
||||
* Select `Device Browser` and then `Sensors`.
|
||||
* If your sensor shows up, you can use it.
|
||||
|
||||
Now select your sensor from the menu and choose `set mode`. This shows all
|
||||
available modes for this sensor. You can use these mode names as the ``mode``
|
||||
setting below.
|
||||
|
||||
To learn more about compatible devices and what each mode does,
|
||||
visit the `ev3dev sensors`_ page.
|
||||
|
||||
.. autoclass:: pybricks.iodevices.Ev3devSensor
|
||||
:no-members:
|
||||
|
||||
.. autoattribute:: pybricks.iodevices.Ev3devSensor.sensor_index
|
||||
:annotation:
|
||||
|
||||
.. autoattribute:: pybricks.iodevices.Ev3devSensor.port_index
|
||||
:annotation:
|
||||
|
||||
.. automethod:: pybricks.iodevices.Ev3devSensor.read
|
||||
|
||||
**Example: Reading values with the Ev3devSensor class**
|
||||
|
||||
In this example we use the LEGO MINDSTORMS EV3 Color Sensor with the raw
|
||||
RGB mode. This gives uncalibrated red, green, and blue reflection values.
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/ev3/ev3devsensor/main.py
|
||||
|
||||
**Example: Extending the Ev3devSensor class**
|
||||
|
||||
This example shows how to extend the ``Ev3devSensor`` class by accessing
|
||||
additional features found in the Linux system folder for this device.
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/ev3/ev3devsensor/class_example.py
|
||||
|
||||
.. _ev3dev sensors: http://docs.ev3dev.org/projects/lego-linux-drivers/en/ev3dev-stretch/sensors.html
|
||||
.. _Mode name: http://docs.ev3dev.org/projects/lego-linux-drivers/en/ev3dev-stretch/sensor_data.html
|
||||
.. _lego-sensor: http://docs.ev3dev.org/projects/lego-linux-drivers/en/ev3dev-stretch/sensors.html#the-lego-sensor-subsytem
|
||||
.. _lego-port: http://docs.ev3dev.org/projects/lego-linux-drivers/en/ev3dev-stretch/ports.html#the-lego-port-subsystem
|
||||
@@ -1,14 +1,8 @@
|
||||
Generic I2C Device
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. note::
|
||||
|
||||
This class is **only supported on the EV3** at this time. It could be added
|
||||
to Powered Up hubs in a future release. If you'd like to see this happen, be
|
||||
sure to ask us on our `support page`_.
|
||||
|
||||
.. _support page: https://github.com/pybricks/support/issues/
|
||||
|
||||
EV3 and NXT support connecting generic I2C devices to the hub.
|
||||
See :doc:`pinout here <uartdevice>`.
|
||||
|
||||
.. figure:: ../../main/cad/output/iodevice-rj12cyan.png
|
||||
:width: 25 %
|
||||
|
||||
@@ -1,25 +1,39 @@
|
||||
.. pybricks-requirements:: pybricks-iodevices
|
||||
|
||||
:mod:`iodevices <pybricks.iodevices>` -- Custom devices
|
||||
============================================================
|
||||
|
||||
.. module:: pybricks.iodevices
|
||||
|
||||
This module has classes for generic and custom input/output devices.
|
||||
|
||||
Wireless devices
|
||||
----------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:hidden:
|
||||
|
||||
pupdevice
|
||||
lwp3device
|
||||
xboxcontroller
|
||||
|
||||
This module has classes for generic and custom input/output devices.
|
||||
.. pybricks-requirements:: pybricks-iodevices
|
||||
|
||||
.. pybricks-classlink:: PUPDevice
|
||||
.. pybricks-classlink:: XboxController
|
||||
|
||||
.. figure:: ../../main/cad/output/iodevice-pupdevice.png
|
||||
:width: 50 %
|
||||
:target: pupdevice.html
|
||||
.. figure:: ../../main/diagrams_source/xboxcontroller.png
|
||||
:width: 40 %
|
||||
:target: xboxcontroller.html
|
||||
|
||||
LEGO protocol devices
|
||||
---------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:hidden:
|
||||
|
||||
lwp3device
|
||||
lumpdevice
|
||||
pupdevice
|
||||
|
||||
.. pybricks-requirements:: pybricks-iodevices
|
||||
|
||||
.. pybricks-classlink:: LWP3Device
|
||||
|
||||
@@ -27,8 +41,68 @@ This module has classes for generic and custom input/output devices.
|
||||
:width: 80 %
|
||||
:target: lwp3device.html
|
||||
|
||||
.. pybricks-classlink:: XboxController
|
||||
.. pybricks-requirements:: ev3 pybricks-iodevices
|
||||
|
||||
.. figure:: ../../main/diagrams_source/xboxcontroller.png
|
||||
.. pybricks-classlink:: LUMPDevice
|
||||
|
||||
.. figure:: ../../main/cad/output/iodevice-rj12green.png
|
||||
:width: 20 %
|
||||
:target: lumpdevice.html
|
||||
|
||||
.. pybricks-requirements:: pybricks-iodevices
|
||||
|
||||
.. pybricks-classlink:: PUPDevice
|
||||
|
||||
.. figure:: ../../main/cad/output/iodevice-pupdevice.png
|
||||
:width: 50 %
|
||||
:target: pupdevice.html
|
||||
|
||||
Generic protocols
|
||||
-----------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:hidden:
|
||||
|
||||
uartdevice
|
||||
i2cdevice
|
||||
analogsensor
|
||||
dcmotor
|
||||
|
||||
.. pybricks-requirements:: pybricks-iodevices
|
||||
|
||||
.. pybricks-classlink:: UARTDevice
|
||||
|
||||
.. |uart-wired| image:: ../../main/cad/output/iodevice-rj12grey.png
|
||||
:width: 20 %
|
||||
:target: uartdevice.html
|
||||
|
||||
.. |uart-wireless| image:: ../../main/cad/output/iodevice-pupdevice.png
|
||||
:width: 50 %
|
||||
:target: uartdevice.html
|
||||
|
||||
|uart-wired| |uart-wireless|
|
||||
|
||||
.. pybricks-requirements:: ev3 pybricks-iodevices
|
||||
|
||||
.. pybricks-classlink:: I2CDevice
|
||||
|
||||
.. figure:: ../../main/cad/output/iodevice-rj12cyan.png
|
||||
:width: 20 %
|
||||
:target: i2cdevice.html
|
||||
|
||||
.. pybricks-requirements:: ev3 pybricks-iodevices
|
||||
|
||||
.. pybricks-classlink:: AnalogSensor
|
||||
|
||||
.. figure:: ../../main/cad/output/iodevice-rj12brown.png
|
||||
:width: 20 %
|
||||
:target: analogsensor.html
|
||||
|
||||
.. pybricks-requirements:: ev3 pybricks-iodevices
|
||||
|
||||
.. pybricks-classlink:: DCMotor
|
||||
|
||||
.. figure:: ../../main/cad/output/iodevice-dcmotor.png
|
||||
:width: 40 %
|
||||
:target: xboxcontroller.html
|
||||
:target: dcmotor.html
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
.. pybricks-requirements:: pybricks-iodevices ev3
|
||||
|
||||
EV3 UART Device
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. note::
|
||||
|
||||
This class is only available on EV3.
|
||||
|
||||
.. figure:: ../../main/cad/output/iodevice-rj12green.png
|
||||
:width: 25 %
|
||||
|
||||
.. autoclass:: pybricks.iodevices.LUMPDevice
|
||||
:no-members:
|
||||
|
||||
@@ -3,11 +3,6 @@
|
||||
LEGO Wireless Protocol v3 device
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. warning::
|
||||
|
||||
This is an experimental class. It has not been well tested and may be
|
||||
changed in future.
|
||||
|
||||
.. figure:: ../../main/cad/output/hub-lwp3.png
|
||||
:width: 80 %
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
@@ -15,6 +15,8 @@ Powered Up Device
|
||||
|
||||
.. automethod:: pybricks.iodevices.PUPDevice.write
|
||||
|
||||
.. automethod:: pybricks.iodevices.PUPDevice.reset
|
||||
|
||||
Examples
|
||||
-------------------
|
||||
|
||||
|
||||
@@ -1,16 +1,47 @@
|
||||
.. pybricks-requirements:: pybricks-iodevices
|
||||
|
||||
Generic UART Device
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. note::
|
||||
Powered Up and EV3 support connecting generic UART devices to the hub. The pinout
|
||||
is shown below. Note the orientation of the connector. For EV3, the internal
|
||||
wire colors match those on the diagram below.
|
||||
|
||||
This class is **only supported on the EV3** at this time. It could be added
|
||||
to Powered Up hubs in a future release. If you'd like to see this happen,
|
||||
be sure to ask us on our `support page`_.
|
||||
.. image:: pinout_numbered.jpg
|
||||
:width: 50 %
|
||||
|
||||
.. _support page: https://github.com/pybricks/support/issues/
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
* - Pin
|
||||
- Powered Up (UART)
|
||||
- EV3 (UART sensor)
|
||||
- EV3 (I2C sensor)
|
||||
* - 1 (white)
|
||||
- Motor Terminal 1
|
||||
- Optional battery power
|
||||
- Optional battery power
|
||||
* - 2 (black)
|
||||
- Motor Terminal 2
|
||||
- N/A
|
||||
- N/A
|
||||
* - 3 (red)
|
||||
- Ground
|
||||
- Ground
|
||||
- Ground
|
||||
* - 4 (green)
|
||||
- VCC (3.3 V)
|
||||
- VCC (5 V)
|
||||
- VCC (5 V)
|
||||
* - 5 (yellow)
|
||||
- Hub TX (Sensor RX) (3.3 V)
|
||||
- Hub TX (Sensor RX) (3.3 V)
|
||||
- SCL (master) (3.3 V)
|
||||
* - 6 (blue)
|
||||
- Hub RX (Sensor TX) (3.3 V)
|
||||
- Hub RX (Sensor TX) (3.3 V)
|
||||
- SDA (master) (3.3 V)
|
||||
|
||||
.. figure:: ../../main/cad/output/iodevice-rj12grey.png
|
||||
:width: 25 %
|
||||
|
||||
.. autoclass:: pybricks.iodevices.UARTDevice
|
||||
|
||||
|
||||
@@ -11,6 +11,12 @@ Xbox Controller
|
||||
.. autoclass:: pybricks.iodevices.XboxController
|
||||
:no-members:
|
||||
|
||||
.. automethod:: pybricks.iodevices::XboxController.connect
|
||||
|
||||
.. automethod:: pybricks.iodevices::XboxController.disconnect
|
||||
|
||||
.. automethod:: pybricks.iodevices::XboxController.name
|
||||
|
||||
.. blockimg:: pybricks_blockButtonIsPressed_XboxController
|
||||
|
||||
.. automethod:: pybricks.iodevices::XboxController.buttons.pressed
|
||||
@@ -30,19 +36,19 @@ Xbox Controller
|
||||
.. blockimg:: pybricks_blockJoystickValue_lj_x
|
||||
|
||||
.. blockimg:: pybricks_blockJoystickValue_lj_y
|
||||
|
||||
|
||||
.. automethod:: pybricks.iodevices::XboxController.joystick_left
|
||||
|
||||
.. blockimg:: pybricks_blockJoystickValue_rj_x
|
||||
|
||||
.. blockimg:: pybricks_blockJoystickValue_rj_y
|
||||
|
||||
|
||||
.. automethod:: pybricks.iodevices::XboxController.joystick_right
|
||||
|
||||
.. blockimg:: pybricks_blockJoystickValue_lt
|
||||
|
||||
.. blockimg:: pybricks_blockJoystickValue_rt
|
||||
|
||||
|
||||
.. automethod:: pybricks.iodevices::XboxController.triggers
|
||||
|
||||
.. blockimg:: pybricks_blockJoystickValue_dpad
|
||||
@@ -56,15 +62,15 @@ Xbox Controller
|
||||
.. blockimg:: pybricks_blockGamepadRumble_default
|
||||
|
||||
.. blockimg:: pybricks_blockGamepadRumble_default_with_list
|
||||
|
||||
|
||||
.. blockimg:: pybricks_blockGamepadRumble_with_options
|
||||
|
||||
|
||||
.. automethod:: pybricks.iodevices::XboxController.rumble
|
||||
|
||||
.. _xbox-controller-pairing:
|
||||
|
||||
Xbox Controller Pairing Instructions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
====================================
|
||||
The first time you use a controller with a hub, you will need to pair
|
||||
them: Turn the controller on and then press and hold the pairing
|
||||
button on the back of the controller for a few seconds. When you release
|
||||
@@ -74,7 +80,7 @@ When pairing and the connection is succesful, the Xbox button will stop
|
||||
flashing and stay on for as long as the program is running.
|
||||
|
||||
Repeat Connections
|
||||
==================
|
||||
------------------
|
||||
|
||||
If you keep using the same controller with the same hub, you can simply
|
||||
turn the controller on the next time and the hub will connect to it
|
||||
@@ -86,7 +92,7 @@ connect to another hub, you will need to pair them again as described
|
||||
above.
|
||||
|
||||
Compatible Controllers
|
||||
============================
|
||||
----------------------
|
||||
|
||||
All Xbox controllers released since 2016 are compatible. This includes the
|
||||
controller from the One S (``1708`` from 2016), the Elite Series 2 (``1797``
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
:mod:`messaging <pybricks.messaging>` -- Send and receive messages
|
||||
==================================================================
|
||||
|
||||
.. automodule:: pybricks.messaging
|
||||
:no-members:
|
||||
|
||||
.. pybricks-requirements:: pup
|
||||
|
||||
.. autoclass:: pybricks.messaging.BLERadio
|
||||
:no-members:
|
||||
|
||||
.. automethod:: pybricks.messaging.BLERadio.broadcast
|
||||
|
||||
.. automethod:: pybricks.messaging.BLERadio.observe
|
||||
|
||||
.. automethod:: pybricks.messaging.BLERadio.signal_strength
|
||||
|
||||
.. automethod:: pybricks.messaging.BLERadio.version
|
||||
|
||||
.. autoclass:: pybricks.messaging.AppData
|
||||
:no-members:
|
||||
|
||||
.. automethod:: pybricks.messaging.AppData.get_bytes
|
||||
|
||||
.. automethod:: pybricks.messaging.AppData.write_bytes
|
||||
|
||||
.. automethod:: pybricks.messaging.AppData.configure
|
||||
|
||||
.. automethod:: pybricks.messaging.AppData.close
|
||||
|
||||
BLERadio examples
|
||||
------------------
|
||||
|
||||
Broadcasting data to other hubs
|
||||
*******************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/ble_broadcast_cityhub.py
|
||||
|
||||
Observing data from other hubs
|
||||
******************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_common/build/ble_observe_cityhub.py
|
||||
@@ -42,7 +42,7 @@ Color Sensor
|
||||
.. blockimg:: pybricks_blockLightOn_colorsensor_on
|
||||
|
||||
.. blockimg:: pybricks_blockLightOn_colorsensor_on_list
|
||||
|
||||
|
||||
.. automethod:: pybricks.pupdevices::ColorSensor.lights.on
|
||||
|
||||
.. blockimg:: pybricks_blockLightOn_colorsensor_off
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
.. pybricks-requirements:: pybricks-iodevices ble-extra
|
||||
|
||||
Duplo Train
|
||||
^^^^^^^^^^^
|
||||
|
||||
.. autoclass:: pybricks.pupdevices.DuploTrain
|
||||
:no-members:
|
||||
|
||||
.. automethod:: pybricks.pupdevices::DuploTrain.connect
|
||||
|
||||
.. automethod:: pybricks.pupdevices::DuploTrain.disconnect
|
||||
|
||||
.. automethod:: pybricks.pupdevices::DuploTrain.name
|
||||
|
||||
.. automethod:: pybricks.pupdevices::DuploTrain.drive
|
||||
|
||||
.. automethod:: pybricks.pupdevices::DuploTrain.headlights
|
||||
|
||||
.. automethod:: pybricks.pupdevices::DuploTrain.sound
|
||||
|
||||
.. automethod:: pybricks.pupdevices::DuploTrain.speed
|
||||
|
||||
.. automethod:: pybricks.pupdevices::DuploTrain.color
|
||||
@@ -22,6 +22,9 @@
|
||||
colorlightmatrix
|
||||
light
|
||||
remote
|
||||
technicmovehub
|
||||
mariohub
|
||||
duplotrain
|
||||
|
||||
.. pybricks-classlink:: DCMotor
|
||||
|
||||
@@ -94,3 +97,15 @@
|
||||
.. figure:: ../../main/cad/output/pupdevice-remote.png
|
||||
:width: 50 %
|
||||
:target: remote.html
|
||||
|
||||
.. pybricks-requirements:: pybricks-iodevices ble-extra
|
||||
|
||||
.. pybricks-classlink:: TechnicMoveHub
|
||||
|
||||
.. pybricks-requirements:: pybricks-iodevices ble-extra
|
||||
|
||||
.. pybricks-classlink:: MarioHub
|
||||
|
||||
.. pybricks-requirements:: pybricks-iodevices ble-extra
|
||||
|
||||
.. pybricks-classlink:: DuploTrain
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
.. pybricks-requirements:: pybricks-iodevices ble-extra
|
||||
|
||||
Mario Hub
|
||||
^^^^^^^^^
|
||||
|
||||
.. autoclass:: pybricks.pupdevices.MarioHub
|
||||
:no-members:
|
||||
|
||||
.. automethod:: pybricks.pupdevices::MarioHub.connect
|
||||
|
||||
.. automethod:: pybricks.pupdevices::MarioHub.disconnect
|
||||
|
||||
.. automethod:: pybricks.pupdevices::MarioHub.color
|
||||
|
||||
.. automethod:: pybricks.pupdevices::MarioHub.hsv
|
||||
|
||||
.. automethod:: pybricks.pupdevices::MarioHub.detectable_colors
|
||||
@@ -105,9 +105,9 @@ Motors with rotation sensors
|
||||
.. blockimg:: pybricks_blockMotorConfigure_motor_max_speed
|
||||
|
||||
.. blockimg:: pybricks_blockMotorConfigure_motor_acceleration
|
||||
|
||||
|
||||
.. blockimg:: pybricks_blockMotorConfigure_motor_max_torque
|
||||
|
||||
|
||||
.. automethod:: pybricks.pupdevices.Motor.control.limits
|
||||
|
||||
.. pybricks-requirements:: pybricks-common-control
|
||||
|
||||
@@ -13,6 +13,8 @@ Remote Control
|
||||
.. autoclass:: pybricks.pupdevices.Remote
|
||||
:no-members:
|
||||
|
||||
.. automethod:: pybricks.pupdevices::Remote.connect
|
||||
|
||||
.. automethod:: pybricks.pupdevices::Remote.name
|
||||
|
||||
.. blockimg:: pybricks_blockLightOnColor_remote_on
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
.. pybricks-requirements:: pybricks-iodevices ble-extra
|
||||
|
||||
Technic Move Hub
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autoclass:: pybricks.pupdevices.TechnicMoveHub
|
||||
:no-members:
|
||||
|
||||
.. automethod:: pybricks.pupdevices::TechnicMoveHub.connect
|
||||
|
||||
.. automethod:: pybricks.pupdevices::TechnicMoveHub.disconnect
|
||||
|
||||
.. automethod:: pybricks.pupdevices::TechnicMoveHub.drive
|
||||
@@ -14,7 +14,7 @@ Tilt Sensor
|
||||
.. blockimg:: pybricks_blockTilt_TiltSensor_imu.tilt.pitch
|
||||
|
||||
.. blockimg:: pybricks_blockTilt_TiltSensor_imu.tilt.roll
|
||||
|
||||
|
||||
.. automethod:: tilt
|
||||
|
||||
Examples
|
||||
|
||||
@@ -25,7 +25,7 @@ Ultrasonic Sensor
|
||||
.. blockimg:: pybricks_blockLightOn_ultrasonicsensor_on
|
||||
|
||||
.. blockimg:: pybricks_blockLightOn_ultrasonicsensor_on_list
|
||||
|
||||
|
||||
.. automethod:: pybricks.pupdevices::UltrasonicSensor.lights.on
|
||||
|
||||
.. blockimg:: pybricks_blockLightOn_ultrasonicsensor_off
|
||||
|
||||
+6
-13
@@ -27,25 +27,16 @@
|
||||
|
||||
.. automethod:: pybricks.robotics.DriveBase.turn
|
||||
|
||||
.. versionchanged:: 3.6
|
||||
|
||||
The ``curve()`` Python method will be replaced by the :meth:`.arc`
|
||||
method. It can still make curves, but it uses different definitions
|
||||
for drive and turn direction. Existing code with ``curve()`` continues
|
||||
to work the same, but you should use :meth:`.arc` for new code.
|
||||
If you use block code, you can pick a new block from the palette to
|
||||
update your code. The old block will still work, but it displays a
|
||||
warning icon to remind you to upgrade. The updated `curve` option uses
|
||||
the direction definitions given below. The new `veer` option lets
|
||||
you drive along a circle by a given distance, which is useful for
|
||||
veering slightly in one direction.
|
||||
|
||||
.. blockimg:: pybricks_blockDriveBaseDrive2_drivebase_drive_arc_angle
|
||||
|
||||
.. blockimg:: pybricks_blockDriveBaseDrive2_drivebase_drive_arc_distance
|
||||
|
||||
.. automethod:: pybricks.robotics.DriveBase.arc
|
||||
|
||||
.. pybricks-requirements:: stm32-float
|
||||
|
||||
.. automethod:: pybricks.robotics.DriveBase.move_by
|
||||
|
||||
.. blockimg:: pybricks_blockDriveBaseConfigure_drivebase_straight_speed
|
||||
|
||||
.. blockimg:: pybricks_blockDriveBaseConfigure_drivebase_straight_acceleration
|
||||
@@ -80,6 +71,8 @@
|
||||
|
||||
.. blockimg:: pybricks_blockDriveBaseStop_hold
|
||||
|
||||
.. automethod:: pybricks.robotics.DriveBase.hold
|
||||
|
||||
.. rubric:: Measuring
|
||||
|
||||
.. blockimg:: pybricks_blockDriveBaseMeasure_drivebase_get_distance
|
||||
|
||||
@@ -10,7 +10,7 @@ ev3 = EV3Brick()
|
||||
device = I2CDevice(Port.S2, 0xD2 >> 1)
|
||||
|
||||
# Recommended for reading
|
||||
(result,) = device.read(reg=0x0F, length=1)
|
||||
result = device.read(reg=0x0F, length=1)
|
||||
|
||||
# Read 1 byte from no particular register:
|
||||
device.read(reg=None, length=1)
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
# ThisHub = MoveHub CityHub TechnicHub PrimeHub EssentialHub
|
||||
from pybricks.hubs import ThisHub
|
||||
from pybricks.pupdevices import Motor
|
||||
from pybricks.parameters import Port
|
||||
from pybricks.tools import wait
|
||||
from pybricks.messaging import BLERadio
|
||||
|
||||
# Initialize the hub.
|
||||
hub = ThisHub(broadcast_channel=1)
|
||||
radio = BLERadio(broadcast_channel=1)
|
||||
|
||||
# Initialize the motors.
|
||||
left_motor = Motor(Port.A)
|
||||
@@ -18,7 +17,7 @@ while True:
|
||||
|
||||
# Set the broadcast data and start broadcasting if not already doing so.
|
||||
data = (left_angle, right_angle)
|
||||
hub.ble.broadcast(data)
|
||||
radio.broadcast(data)
|
||||
|
||||
# Broadcasts are only sent every 100 milliseconds, so there is no reason
|
||||
# to call the broadcast() method more often than that.
|
||||
@@ -1,11 +1,10 @@
|
||||
# ThisHub = MoveHub CityHub TechnicHub PrimeHub EssentialHub
|
||||
from pybricks.hubs import ThisHub
|
||||
from pybricks.pupdevices import Motor
|
||||
from pybricks.parameters import Color, Port
|
||||
from pybricks.parameters import Port
|
||||
from pybricks.tools import wait
|
||||
from pybricks.messaging import BLERadio
|
||||
|
||||
# Initialize the hub.
|
||||
hub = ThisHub(observe_channels=[1])
|
||||
radio = BLERadio(observe_channels=[1])
|
||||
|
||||
# Initialize the motors.
|
||||
left_motor = Motor(Port.A)
|
||||
@@ -14,17 +13,12 @@ right_motor = Motor(Port.B)
|
||||
while True:
|
||||
# Receive broadcast from the other hub.
|
||||
|
||||
data = hub.ble.observe(1)
|
||||
data = radio.observe(1)
|
||||
|
||||
if data is None:
|
||||
# No data has been received in the last 1 second.
|
||||
hub.light.on(Color.RED)
|
||||
else:
|
||||
if data is not None:
|
||||
# Data was received and is less that one second old.
|
||||
hub.light.on(Color.GREEN)
|
||||
|
||||
# *data* contains the same values in the same order
|
||||
# that were passed to hub.ble.broadcast() on the
|
||||
# It contains the same values in the same order
|
||||
# that were passed to radio.broadcast() on the
|
||||
# other hub.
|
||||
left_angle, right_angle = data
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
## 1.17.0 - 2025-02-26
|
||||
|
||||
### Changed
|
||||
- Updated `pybricks` package to v3.5.0b5.
|
||||
|
||||
## 1.16.0 - 2024-04-05
|
||||
|
||||
### Changed
|
||||
|
||||
Generated
+57
-47
@@ -1,10 +1,9 @@
|
||||
# This file is automatically @generated by Poetry and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "black"
|
||||
version = "22.12.0"
|
||||
description = "The uncompromising code formatter."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
@@ -37,14 +36,13 @@ uvloop = ["uvloop (>=0.15.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.1.7"
|
||||
version = "8.1.8"
|
||||
description = "Composable command line interface toolkit"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
|
||||
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
|
||||
{file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"},
|
||||
{file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -54,7 +52,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
description = "Cross-platform colored terminal text."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||
files = [
|
||||
@@ -66,7 +63,6 @@ files = [
|
||||
name = "docstring-parser"
|
||||
version = "0.14.1"
|
||||
description = "Parse Python docstrings in reST, Google and Numpydoc format"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6,<4.0"
|
||||
files = [
|
||||
@@ -76,14 +72,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "exceptiongroup"
|
||||
version = "1.2.0"
|
||||
version = "1.2.2"
|
||||
description = "Backport of PEP 654 (exception groups)"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"},
|
||||
{file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"},
|
||||
{file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
|
||||
{file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@@ -93,7 +88,6 @@ test = ["pytest (>=6)"]
|
||||
name = "flake8"
|
||||
version = "4.0.1"
|
||||
description = "the modular source code checker: pep8 pyflakes and co"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
@@ -110,7 +104,6 @@ pyflakes = ">=2.4.0,<2.5.0"
|
||||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
description = "brain-dead simple config-ini parsing"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
@@ -122,7 +115,6 @@ files = [
|
||||
name = "jedi"
|
||||
version = "0.18.1"
|
||||
description = "An autocompletion tool for Python that can be used for text editors."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
@@ -141,7 +133,6 @@ testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"]
|
||||
name = "mccabe"
|
||||
version = "0.6.1"
|
||||
description = "McCabe checker, plugin for flake8"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
@@ -153,7 +144,6 @@ files = [
|
||||
name = "mypy-extensions"
|
||||
version = "1.0.0"
|
||||
description = "Type system extensions for programs checked with the mypy type checker."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
@@ -163,21 +153,19 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "24.0"
|
||||
version = "24.2"
|
||||
description = "Core utilities for Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"},
|
||||
{file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"},
|
||||
{file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
|
||||
{file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parso"
|
||||
version = "0.8.4"
|
||||
description = "A Python Parser"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
@@ -193,7 +181,6 @@ testing = ["docopt", "pytest"]
|
||||
name = "pathspec"
|
||||
version = "0.12.1"
|
||||
description = "Utility library for gitignore style pattern matching of file paths."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
@@ -203,30 +190,29 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "4.2.0"
|
||||
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||
category = "dev"
|
||||
version = "4.3.6"
|
||||
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"},
|
||||
{file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"},
|
||||
{file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"},
|
||||
{file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"]
|
||||
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"]
|
||||
docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"]
|
||||
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"]
|
||||
type = ["mypy (>=1.11.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"},
|
||||
{file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"},
|
||||
{file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
|
||||
{file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@@ -235,9 +221,8 @@ testing = ["pytest", "pytest-benchmark"]
|
||||
|
||||
[[package]]
|
||||
name = "pybricks"
|
||||
version = "3.5.0b2"
|
||||
version = "3.6.0b5"
|
||||
description = "Documentation and user-API stubs for Pybricks MicroPython"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "^3.8"
|
||||
files = []
|
||||
@@ -251,7 +236,6 @@ url = ".."
|
||||
name = "pycodestyle"
|
||||
version = "2.8.0"
|
||||
description = "Python style guide checker"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
files = [
|
||||
@@ -263,7 +247,6 @@ files = [
|
||||
name = "pyflakes"
|
||||
version = "2.4.0"
|
||||
description = "passive checker of Python programs"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
files = [
|
||||
@@ -275,7 +258,6 @@ files = [
|
||||
name = "pytest"
|
||||
version = "7.4.4"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
@@ -296,21 +278,49 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.0.1"
|
||||
version = "2.2.1"
|
||||
description = "A lil' TOML parser"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
|
||||
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"},
|
||||
{file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"},
|
||||
{file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.2.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.7+"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
@@ -321,4 +331,4 @@ files = [
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">= 3.10, < 3.12"
|
||||
content-hash = "a634c0231937213565b3dff33539075fd544a4261bf8f84e99b294f34ec7edd4"
|
||||
content-hash = "0a796ac6867c41e8cf0ce289beca1cebb4066b622c2c538c11589413dcb579af"
|
||||
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
[tool.poetry]
|
||||
name = "pybricks_jedi"
|
||||
version = "1.16.0"
|
||||
version = "1.17.0"
|
||||
description = "Code completion for Pybricks."
|
||||
authors = ["The Pybricks Authors <team@pybricks.com>"]
|
||||
license = "MIT"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">= 3.10, < 3.12"
|
||||
pybricks = "3.5.0b2"
|
||||
pybricks = "3.6.0b5"
|
||||
jedi = "0.18.1"
|
||||
typing-extensions = "4.2.0"
|
||||
docstring-parser = "0.14.1"
|
||||
|
||||
@@ -15,6 +15,7 @@ PYBRICKS_CODE_PACKAGES = {
|
||||
"pybricks",
|
||||
"pybricks.hubs",
|
||||
"pybricks.iodevices",
|
||||
"pybricks.messaging",
|
||||
"pybricks.parameters",
|
||||
"pybricks.pupdevices",
|
||||
"pybricks.robotics",
|
||||
@@ -490,6 +491,7 @@ def initialize():
|
||||
"pybricks.ev3dev.speaker",
|
||||
"pybricks.hubs",
|
||||
"pybricks.iodevices",
|
||||
"pybricks.messaging",
|
||||
"pybricks.parameters",
|
||||
"pybricks.pupdevices",
|
||||
"pybricks.robotics",
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
Tests for correct code completion of the CityHub class.
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
from pybricks_jedi import CompletionItem, complete
|
||||
|
||||
@@ -33,7 +32,6 @@ def test_hub_dot():
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"battery",
|
||||
"ble",
|
||||
"buttons",
|
||||
"light",
|
||||
"system",
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
Tests for correct code completion of the EssentialHub class.
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
from pybricks_jedi import CompletionItem, complete
|
||||
|
||||
@@ -33,7 +32,6 @@ def test_hub_dot():
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"battery",
|
||||
"ble",
|
||||
"buttons",
|
||||
"charger",
|
||||
"imu",
|
||||
|
||||
@@ -61,6 +61,7 @@ def test_from_pybricks_import():
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"hubs",
|
||||
"iodevices",
|
||||
"messaging",
|
||||
"parameters",
|
||||
"pupdevices",
|
||||
"robotics",
|
||||
@@ -75,6 +76,7 @@ def test_from_pybricks_dot():
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"hubs",
|
||||
"iodevices",
|
||||
"messaging",
|
||||
"parameters",
|
||||
"pupdevices",
|
||||
"robotics",
|
||||
@@ -102,7 +104,6 @@ def test_from_pybricks_iodevices_import():
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"AnalogSensor",
|
||||
"DCMotor",
|
||||
"Ev3devSensor",
|
||||
"I2CDevice",
|
||||
"LUMPDevice",
|
||||
"LWP3Device",
|
||||
@@ -135,12 +136,15 @@ def test_from_pybricks_pupdevices_import():
|
||||
"ColorLightMatrix",
|
||||
"ColorSensor",
|
||||
"DCMotor",
|
||||
"DuploTrain",
|
||||
"ForceSensor",
|
||||
"InfraredSensor",
|
||||
"Light",
|
||||
"MarioHub",
|
||||
"Motor",
|
||||
"PFMotor",
|
||||
"Remote",
|
||||
"TechnicMoveHub",
|
||||
"TiltSensor",
|
||||
"UltrasonicSensor",
|
||||
]
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
Tests for correct code completion of the InventorHub class.
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
from pybricks_jedi import complete, CompletionItem
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 The Pybricks Authors
|
||||
|
||||
"""
|
||||
Tests for correct code completion of the messaging module.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
from pybricks_jedi import CompletionItem, complete
|
||||
|
||||
|
||||
def test_from_pybricks_messaging_import():
|
||||
code = "from pybricks.messaging import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"AppData",
|
||||
"BLERadio",
|
||||
"BluetoothMailboxClient",
|
||||
"BluetoothMailboxServer",
|
||||
"Connection",
|
||||
"LogicMailbox",
|
||||
"Mailbox",
|
||||
"NumericMailbox",
|
||||
"TextMailbox",
|
||||
]
|
||||
|
||||
|
||||
def test_ble_radio_dot():
|
||||
code = "\n".join(
|
||||
[
|
||||
"from pybricks.messaging import BLERadio",
|
||||
"ble = BLERadio()",
|
||||
"ble.",
|
||||
]
|
||||
)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, 5))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"broadcast",
|
||||
"observe",
|
||||
"signal_strength",
|
||||
"version",
|
||||
]
|
||||
|
||||
|
||||
def test_app_data_dot():
|
||||
code = "\n".join(
|
||||
[
|
||||
"from pybricks.messaging import AppData",
|
||||
"app = AppData([(0, 4)])",
|
||||
"app.",
|
||||
]
|
||||
)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, 5))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"close",
|
||||
"configure",
|
||||
"get_bytes",
|
||||
"write_bytes",
|
||||
]
|
||||
@@ -5,7 +5,6 @@
|
||||
Tests for correct code completion of the MoveHub class.
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
from pybricks_jedi import CompletionItem, complete
|
||||
|
||||
@@ -33,7 +32,6 @@ def test_hub_dot():
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"battery",
|
||||
"ble",
|
||||
"buttons",
|
||||
"imu",
|
||||
"light",
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
Tests for correct code completion of the PrimeHub class.
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
from pybricks_jedi import CompletionItem, complete
|
||||
|
||||
@@ -33,7 +32,6 @@ def test_hub_dot():
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"battery",
|
||||
"ble",
|
||||
"buttons",
|
||||
"charger",
|
||||
"display",
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
Tests for correct code completion of the TechnicHub class.
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
from pybricks_jedi import CompletionItem, complete
|
||||
|
||||
@@ -33,7 +32,6 @@ def test_hub_dot():
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"battery",
|
||||
"ble",
|
||||
"buttons",
|
||||
"imu",
|
||||
"light",
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
Tests for correct signatures of the pupdevices.Motor class.
|
||||
"""
|
||||
|
||||
|
||||
from itertools import zip_longest
|
||||
import json
|
||||
|
||||
@@ -86,12 +85,17 @@ CONSTRUCTOR_PARAMS = [
|
||||
pytest.param(
|
||||
"pybricks.hubs",
|
||||
"MoveHub",
|
||||
[["broadcast_channel: int=None", "observe_channels: Sequence[int]=[]"]],
|
||||
[
|
||||
[
|
||||
"top_side: Axis=Axis.Z",
|
||||
"front_side: Axis=Axis.X",
|
||||
]
|
||||
],
|
||||
),
|
||||
pytest.param(
|
||||
"pybricks.hubs",
|
||||
"CityHub",
|
||||
[["broadcast_channel: int=None", "observe_channels: Sequence[int]=[]"]],
|
||||
[[]],
|
||||
),
|
||||
pytest.param(
|
||||
"pybricks.hubs",
|
||||
@@ -100,8 +104,6 @@ CONSTRUCTOR_PARAMS = [
|
||||
[
|
||||
"top_side: Axis=Axis.Z",
|
||||
"front_side: Axis=Axis.X",
|
||||
"broadcast_channel: int=None",
|
||||
"observe_channels: Sequence[int]=[]",
|
||||
]
|
||||
],
|
||||
),
|
||||
@@ -112,8 +114,6 @@ CONSTRUCTOR_PARAMS = [
|
||||
[
|
||||
"top_side: Axis=Axis.Z",
|
||||
"front_side: Axis=Axis.X",
|
||||
"broadcast_channel: int=None",
|
||||
"observe_channels: Sequence[int]=[]",
|
||||
]
|
||||
],
|
||||
),
|
||||
@@ -124,8 +124,6 @@ CONSTRUCTOR_PARAMS = [
|
||||
[
|
||||
"top_side: Axis=Axis.Z",
|
||||
"front_side: Axis=Axis.X",
|
||||
"broadcast_channel: int=None",
|
||||
"observe_channels: Sequence[int]=[]",
|
||||
]
|
||||
],
|
||||
),
|
||||
@@ -170,7 +168,7 @@ CONSTRUCTOR_PARAMS = [
|
||||
pytest.param(
|
||||
"pybricks.pupdevices",
|
||||
"Remote",
|
||||
[["name: Optional[str]=None", "timeout: int=10000"]],
|
||||
[["name: Optional[str]=None", "timeout: int=10000", "connect: bool=True"]],
|
||||
),
|
||||
# TODO: iodevices go here
|
||||
pytest.param(
|
||||
@@ -935,7 +933,7 @@ METHOD_PARAMS = [
|
||||
"pybricks.pupdevices",
|
||||
"Remote",
|
||||
"name",
|
||||
[(["name: str"], "None"), ([], "str")],
|
||||
[(["name: str"], "MaybeAwaitable"), ([], "str")],
|
||||
),
|
||||
pytest.param(
|
||||
"pybricks.pupdevices",
|
||||
@@ -973,7 +971,12 @@ METHOD_PARAMS = [
|
||||
"turn",
|
||||
[
|
||||
(
|
||||
["angle: Number", "then: Stop=Stop.HOLD", "wait: bool=True"],
|
||||
[
|
||||
"angle: Number",
|
||||
"then: Stop=Stop.HOLD",
|
||||
"wait: bool=True",
|
||||
"absolute: bool=False",
|
||||
],
|
||||
"MaybeAwaitable",
|
||||
)
|
||||
],
|
||||
@@ -1002,13 +1005,16 @@ METHOD_PARAMS = [
|
||||
(
|
||||
[
|
||||
"straight_speed: Optional[Number]=None",
|
||||
"straight_acceleration: Optional[Number]=None",
|
||||
"straight_acceleration: Optional[Union[Number, Tuple[Number, Number]]]=None",
|
||||
"turn_rate: Optional[Number]=None",
|
||||
"turn_acceleration: Optional[Number]=None",
|
||||
"turn_acceleration: Optional[Union[Number, Tuple[Number, Number]]]=None",
|
||||
],
|
||||
"None",
|
||||
),
|
||||
([], "Tuple[int, int, int, int]"),
|
||||
(
|
||||
[],
|
||||
"Tuple[int, Union[int, Tuple[int, int]], int, Union[int, Tuple[int, int]]]",
|
||||
),
|
||||
],
|
||||
),
|
||||
pytest.param(
|
||||
@@ -1020,7 +1026,7 @@ METHOD_PARAMS = [
|
||||
pytest.param("pybricks.robotics", "DriveBase", "stop", [([], "None")]),
|
||||
pytest.param("pybricks.robotics", "DriveBase", "brake", [([], "None")]),
|
||||
pytest.param("pybricks.robotics", "DriveBase", "distance", [([], "int")]),
|
||||
pytest.param("pybricks.robotics", "DriveBase", "angle", [([], "int")]),
|
||||
pytest.param("pybricks.robotics", "DriveBase", "angle", [([], "float")]),
|
||||
pytest.param(
|
||||
"pybricks.robotics", "DriveBase", "state", [([], "Tuple[int, int, int, int]")]
|
||||
),
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
<!-- refer to https://keepachangelog.com/en/1.0.0/ for guidance -->
|
||||
|
||||
## 1.4.0 - 2022-12-19
|
||||
|
||||
### Added
|
||||
- Added existing NXT and EV3 hub images to published package.
|
||||
|
||||
## 1.3.0 - 2022-12-19
|
||||
|
||||
### Added
|
||||
|
||||
+2
-2
@@ -9,11 +9,11 @@ BUILD_DIR = (pathlib.Path(__file__).parent / "build").resolve()
|
||||
IMAGE_DIR = (
|
||||
pathlib.Path(__file__).parent.parent.parent / "doc" / "main" / "diagrams"
|
||||
).resolve()
|
||||
HUBS = ["move", "city", "technic", "prime", "essential", "inventor"]
|
||||
HUBS = ["move", "city", "technic", "prime", "essential", "inventor", "ev3", "nxt"]
|
||||
|
||||
package_json = {
|
||||
"name": "@pybricks/images",
|
||||
"version": "1.3.0",
|
||||
"version": "1.4.0",
|
||||
"description": "Distribution of Pybricks images.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
## 1.17.0 - 2025-02-26
|
||||
|
||||
### Changed
|
||||
- Updated `pybricks_jedi` Python package to v1.17.0.
|
||||
|
||||
## 1.16.0 - 2024-04-05
|
||||
|
||||
### Changed
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ BUILD_DIR = (pathlib.Path(__file__).parent / "build").resolve()
|
||||
|
||||
package_json = {
|
||||
"name": "@pybricks/jedi",
|
||||
"version": "1.16.0",
|
||||
"version": "1.17.0",
|
||||
"description": "Binary distribution of pybricks-jedi Python package and dependencies for use with Pyodide.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -38,7 +38,7 @@ subprocess.check_call(
|
||||
"pip",
|
||||
"download",
|
||||
"--only-binary=any",
|
||||
"pybricks-jedi==1.16.0",
|
||||
"pybricks-jedi==1.17.0",
|
||||
],
|
||||
cwd=BUILD_DIR,
|
||||
)
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "pybricks"
|
||||
version = "3.6.0b5"
|
||||
version = "3.6.1"
|
||||
description = "Documentation and user-API stubs for Pybricks MicroPython"
|
||||
authors = ["The Pybricks Authors <team@pybricks.com>"]
|
||||
maintainers = ["Laurens Valk <laurens@pybricks.com>", "David Lechner <david@pybricks.com>" ]
|
||||
|
||||
+19
-106
@@ -40,6 +40,8 @@ if TYPE_CHECKING:
|
||||
|
||||
class MaybeAwaitableColor(Color, Awaitable[Color]): ...
|
||||
|
||||
class MaybeAwaitableBytes(bytes, Awaitable[bytes]): ...
|
||||
|
||||
|
||||
class System:
|
||||
"""System control actions for a hub."""
|
||||
@@ -123,12 +125,15 @@ class System:
|
||||
automatically, like after a firmware update. It is ``2`` if the hub
|
||||
previously crashed due to a watchdog timeout, which indicates a
|
||||
firmware issue.
|
||||
- ``"host_connected_ble"``: Whether the hub is connected to a computer,
|
||||
tablet, or phone via Bluetooth.
|
||||
- ``"host_connected_ble"``: ``True`` if the hub is connected to a
|
||||
computer, tablet, or phone via Bluetooth, and ``False`` otherwise.
|
||||
- ``"host_connected_usb"``: ``True`` if the hub is connected to a computer
|
||||
via USB and activated in the app. ``False`` otherwise.
|
||||
- ``"program_start_type"``: It is ``1`` if the program started
|
||||
automatically when the hub was powered on. It is ``2`` if the program
|
||||
was started with the hub buttons. It is ``3`` if the program was
|
||||
started from your connected computer.
|
||||
- `"program_id"`: Program (slot) number of the currently running program.
|
||||
|
||||
Returns:
|
||||
A dictionary with system info.
|
||||
@@ -136,7 +141,7 @@ class System:
|
||||
.. versionchanged:: 3.6
|
||||
The name and reset reason where previously available as separate
|
||||
methods. Now they are included in the info dictionary. The methods
|
||||
are still available for compatibility.
|
||||
are still available for backwards compatibility.
|
||||
"""
|
||||
|
||||
|
||||
@@ -828,7 +833,7 @@ class LightMatrix:
|
||||
contents remain unchanged.
|
||||
|
||||
Arguments:
|
||||
top (Side): Which side of the light matrix display is "up" in your
|
||||
up (Side): Which side of the light matrix display is "up" in your
|
||||
design. Choose ``Side.TOP``, ``Side.LEFT``, ``Side.RIGHT``,
|
||||
or ``Side.BOTTOM``.
|
||||
"""
|
||||
@@ -1165,7 +1170,7 @@ class IMU:
|
||||
hub consistently reports a different value for a full rotation. For
|
||||
example, your hub might consistently report `357` degrees for every
|
||||
`360` degree turn. You can measure this value
|
||||
with ``hub.imu.rotation(-Axis.Z)`` and enter it as
|
||||
with ``hub.imu.rotation(-Axis.Z, calibrated=False)`` and enter it as
|
||||
the ``heading_correction`` setting. Then, the ``hub.imu.heading()``
|
||||
method will take it into account going forward, correctly scaling it
|
||||
to 360 degrees for a full rotation.
|
||||
@@ -1179,17 +1184,19 @@ class IMU:
|
||||
variations in acceleration below which the hub is considered
|
||||
stationary enough to calibrate. After a reset the value
|
||||
is 2500 mm/s².
|
||||
heading_correction (Number, deg): Number of degrees reported by
|
||||
``imu.rotation(-Axis.Z)`` for one full rotation of your robot.
|
||||
After a reset the value is 360 degrees.
|
||||
heading_correction (Number, deg): Number of degrees
|
||||
reported by for one full rotation of your robot.
|
||||
After a reset the value is 360 degrees. This is applied on top
|
||||
of any scaling that is done by the ``angular_velocity_scale``
|
||||
setting.
|
||||
angular_velocity_bias (tuple, deg/s): Initial bias for angular
|
||||
velocity measurements along x, y, and z immediately after boot.
|
||||
After a reset the value is (0, 0, 0) deg/s.
|
||||
angular_velocity_scale (tuple, deg): Scale adjustment for x, y, and
|
||||
z rotation to account for manufacturing differences. After a reset the
|
||||
value is (360, 360, 360) deg/s. The correct values can be
|
||||
obtained using `hub.imu.rotation(Axis.X, calibrated=False)` and
|
||||
repeating it for each axis.
|
||||
z rotation to account for manufacturing differences. After a
|
||||
reset the value is (360, 360, 360) deg/s. The correct values
|
||||
can be obtained using `hub.imu.rotation(Axis.X, calibrated=False)`
|
||||
and repeating it for each axis.
|
||||
acceleration_correction (tuple, mm/s²): Scale adjustment for x, y,
|
||||
and z gravity magnitude in both directions to account for
|
||||
manufacturing differences. After a reset the
|
||||
@@ -1209,17 +1216,6 @@ class IMU:
|
||||
even as the robot turns more than 180 degrees. It does not wrap around
|
||||
to -180 like it does in some apps.
|
||||
|
||||
|
||||
.. note:: *For now, this method only keeps track of the heading while
|
||||
the robot is on a flat surface.*
|
||||
|
||||
This means that the value is
|
||||
no longer correct if you lift it from the table or turn on
|
||||
a ramp. Try ``hub.imu.heading('3D')`` for a heading value
|
||||
that compensates for this. This will become the default in a
|
||||
future release. If you try it, please let us know on our
|
||||
forums!
|
||||
|
||||
Returns:
|
||||
Heading angle relative to starting orientation.
|
||||
|
||||
@@ -1437,86 +1433,3 @@ class AmbientColorSensor(CommonColorSensor):
|
||||
Measured color. The color is described by a hue (0--359), a
|
||||
saturation (0--100), and a brightness value (0--100).
|
||||
"""
|
||||
|
||||
|
||||
class BLE:
|
||||
"""
|
||||
Bluetooth Low Energy.
|
||||
|
||||
.. versionadded:: 3.3
|
||||
"""
|
||||
|
||||
def broadcast(self, data: Union[bool, int, float, str, bytes]) -> MaybeAwaitable:
|
||||
"""broadcast(data)
|
||||
|
||||
Starts broadcasting the given data on
|
||||
the ``broadcast_channel`` you selected when initializing the hub.
|
||||
|
||||
Data may be of type ``int``, ``float``, ``str``, ``bytes``,
|
||||
``True``, or ``False``. It can also be a list or tuple of these.
|
||||
|
||||
Choose ``None`` to stop broadcasting. This helps improve performance
|
||||
when you don't need the broadcast feature, especially when observing
|
||||
at the same time.
|
||||
|
||||
The total data size is quite limited (26 bytes). ``True`` and
|
||||
``False`` take 1 byte each. ``float`` takes 5 bytes. ``int`` takes 2 to
|
||||
5 bytes depending on how big the number is. ``str`` and ``bytes`` take
|
||||
the number of bytes in the object plus one extra byte.
|
||||
|
||||
When multitasking, only one task can broadcast at a time. To broadcast
|
||||
information from multiple tasks (or block stacks), you could use a
|
||||
dedicated separate task that broadcast new values when one or more
|
||||
variables change.
|
||||
|
||||
Args:
|
||||
data: The value or values to be broadcast.
|
||||
|
||||
.. versionadded:: 3.3
|
||||
"""
|
||||
|
||||
def observe(
|
||||
self, channel: int
|
||||
) -> Optional[Tuple[Union[bool, int, float, str, bytes], ...]]:
|
||||
"""observe(channel) -> bool | int | float | str | bytes | tuple | None
|
||||
|
||||
Retrieves the last observed data for a given channel.
|
||||
|
||||
Receiving data is more reliable when the hub is not connected
|
||||
to a computer or other devices at the same time.
|
||||
|
||||
Args:
|
||||
channel (int): The channel to observe (0 to 255).
|
||||
|
||||
Returns:
|
||||
The received data in the same format as it was sent, or ``None``
|
||||
if no recent data is available.
|
||||
|
||||
.. versionadded:: 3.3
|
||||
"""
|
||||
|
||||
def signal_strength(self, channel: int) -> int:
|
||||
"""signal_strength(channel) -> int: dBm
|
||||
|
||||
Gets the average signal strength in dBm for the given channel.
|
||||
|
||||
This indicates how near the broadcasting device is. Nearby devices
|
||||
may have a signal strength around -40 dBm, while far away devices
|
||||
might have a signal strength around -70 dBm.
|
||||
|
||||
Args:
|
||||
channel (int): The channel number (0 to 255).
|
||||
|
||||
Returns:
|
||||
The signal strength or ``-128`` if there is no recent observed data.
|
||||
|
||||
.. versionadded:: 3.3
|
||||
"""
|
||||
|
||||
def version(self) -> str:
|
||||
"""version() -> str
|
||||
|
||||
Gets the firmware version from the Bluetooth chip.
|
||||
|
||||
.. versionadded:: 3.3
|
||||
"""
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
"""LEGO® MINDSTORMS® EV3 motors and sensors."""
|
||||
|
||||
from typing import Optional, Tuple, List
|
||||
from typing import Optional, Tuple, List, Set
|
||||
|
||||
from . import _common
|
||||
from .parameters import (
|
||||
@@ -57,7 +57,7 @@ class ColorSensor:
|
||||
Returns:
|
||||
``Color.BLACK``, ``Color.BLUE``, ``Color.GREEN``,
|
||||
``Color.YELLOW``, ``Color.RED``, ``Color.WHITE``, ``Color.BROWN``,
|
||||
or ``None`` if no color is detected.
|
||||
or ``Color.NONE`` if no color is detected.
|
||||
|
||||
"""
|
||||
|
||||
@@ -134,8 +134,8 @@ class InfraredSensor:
|
||||
a tuple of (``None``, ``None``) if no remote is detected.
|
||||
"""
|
||||
|
||||
def buttons(self, channel: int) -> List[_Button]:
|
||||
"""buttons(channel) -> List[Button]
|
||||
def buttons(self, channel: int) -> Set[_Button]:
|
||||
"""buttons(channel) -> Set[Button]
|
||||
|
||||
Checks which buttons on the infrared remote are pressed.
|
||||
|
||||
|
||||
+9
-75
@@ -3,8 +3,6 @@
|
||||
|
||||
"""LEGO® Programmable Hubs."""
|
||||
|
||||
from typing import Sequence
|
||||
|
||||
from . import _common
|
||||
from .ev3dev import _speaker
|
||||
from .media.ev3dev import Image as _Image
|
||||
@@ -41,28 +39,19 @@ class MoveHub:
|
||||
imu = _common.SimpleAccelerometer()
|
||||
system = _common.System()
|
||||
buttons = _common.Keypad([_Button.CENTER])
|
||||
ble = _common.BLE()
|
||||
|
||||
def __init__(
|
||||
self, broadcast_channel: int = None, observe_channels: Sequence[int] = []
|
||||
self,
|
||||
top_side: Axis = Axis.Z,
|
||||
front_side: Axis = Axis.X,
|
||||
):
|
||||
"""MoveHub(top_side=Axis.Z, front_side=Axis.X, broadcast_channel=None, observe_channels=[])
|
||||
"""MoveHub(top_side=Axis.Z, front_side=Axis.X)
|
||||
|
||||
Arguments:
|
||||
top_side (Axis): The axis that passes through the *top side* of
|
||||
the hub.
|
||||
front_side (Axis): The axis that passes through the *front side* of
|
||||
the hub.
|
||||
broadcast_channel:
|
||||
Channel number (0 to 255) used to broadcast data.
|
||||
Choose ``None`` when not using broadcasting.
|
||||
observe_channels:
|
||||
A list of channels to listen to when ``hub.ble.observe()`` is
|
||||
called. Listening to more channels requires more memory.
|
||||
Default is an empty list (no channels).
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
Added *broadcast_channel* and *observe_channels* arguments.
|
||||
"""
|
||||
|
||||
|
||||
@@ -75,25 +64,9 @@ class CityHub:
|
||||
light = _common.ColorLight()
|
||||
system = _common.System()
|
||||
buttons = _common.Keypad([_Button.CENTER])
|
||||
ble = _common.BLE()
|
||||
|
||||
def __init__(
|
||||
self, broadcast_channel: int = None, observe_channels: Sequence[int] = []
|
||||
):
|
||||
"""CityHub(broadcast_channel=None, observe_channels=[])
|
||||
|
||||
Arguments:
|
||||
broadcast_channel:
|
||||
Channel number (0 to 255) used to broadcast data.
|
||||
Choose ``None`` when not using broadcasting.
|
||||
observe_channels:
|
||||
A list of channels to listen to when ``hub.ble.observe()`` is
|
||||
called. Listening to more channels requires more memory.
|
||||
Default is an empty list (no channels).
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
Added *broadcast_channel* and *observe_channels* arguments.
|
||||
"""
|
||||
def __init__(self):
|
||||
"""CityHub()"""
|
||||
|
||||
|
||||
class TechnicHub:
|
||||
@@ -106,16 +79,13 @@ class TechnicHub:
|
||||
imu = _common.IMU()
|
||||
system = _common.System()
|
||||
buttons = _common.Keypad([_Button.CENTER])
|
||||
ble = _common.BLE()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
top_side: Axis = Axis.Z,
|
||||
front_side: Axis = Axis.X,
|
||||
broadcast_channel: int = None,
|
||||
observe_channels: Sequence[int] = [],
|
||||
):
|
||||
"""TechnicHub(top_side=Axis.Z, front_side=Axis.X, broadcast_channel=None, observe_channels=[])
|
||||
"""TechnicHub(top_side=Axis.Z, front_side=Axis.X)
|
||||
|
||||
Initializes the hub. Optionally, specify how the hub is
|
||||
:ref:`placed in your design <robotframe>` by saying in which
|
||||
@@ -127,16 +97,6 @@ class TechnicHub:
|
||||
the hub.
|
||||
front_side (Axis): The axis that passes through the *front side* of
|
||||
the hub.
|
||||
broadcast_channel:
|
||||
Channel number (0 to 255) used to broadcast data.
|
||||
Choose ``None`` when not using broadcasting.
|
||||
observe_channels:
|
||||
A list of channels to listen to when ``hub.ble.observe()`` is
|
||||
called. Listening to more channels requires more memory.
|
||||
Default is an empty list (no channels).
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
Added *broadcast_channel* and *observe_channels* arguments.
|
||||
"""
|
||||
|
||||
|
||||
@@ -151,16 +111,13 @@ class EssentialHub:
|
||||
light = _common.ColorLight()
|
||||
imu = _common.IMU()
|
||||
system = _common.System()
|
||||
ble = _common.BLE()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
top_side: Axis = Axis.Z,
|
||||
front_side: Axis = Axis.X,
|
||||
broadcast_channel: int = None,
|
||||
observe_channels: Sequence[int] = [],
|
||||
):
|
||||
"""EssentialHub(top_side=Axis.Z, front_side=Axis.X, broadcast_channel=None, observe_channels=[])
|
||||
"""EssentialHub(top_side=Axis.Z, front_side=Axis.X)
|
||||
|
||||
Initializes the hub. Optionally, specify how the hub is
|
||||
:ref:`placed in your design <robotframe>` by saying in which
|
||||
@@ -172,16 +129,6 @@ class EssentialHub:
|
||||
the hub.
|
||||
front_side (Axis): The axis that passes through the *front side* of
|
||||
the hub.
|
||||
broadcast_channel:
|
||||
Channel number (0 to 255) used to broadcast data.
|
||||
Choose ``None`` when not using broadcasting.
|
||||
observe_channels:
|
||||
A list of channels to listen to when ``hub.ble.observe()`` is
|
||||
called. Listening to more channels requires more memory.
|
||||
Default is an empty list (no channels).
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
Added *broadcast_channel* and *observe_channels* arguments.
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -206,16 +153,13 @@ class PrimeHub:
|
||||
speaker = _common.Speaker()
|
||||
imu = _common.IMU()
|
||||
system = _common.System()
|
||||
ble = _common.BLE()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
top_side: Axis = Axis.Z,
|
||||
front_side: Axis = Axis.X,
|
||||
broadcast_channel: int = None,
|
||||
observe_channels: Sequence[int] = [],
|
||||
):
|
||||
"""PrimeHub(top_side=Axis.Z, front_side=Axis.X, broadcast_channel=None, observe_channels=[])
|
||||
"""PrimeHub(top_side=Axis.Z, front_side=Axis.X)
|
||||
|
||||
Initializes the hub. Optionally, specify how the hub is
|
||||
:ref:`placed in your design <robotframe>` by saying in which
|
||||
@@ -227,16 +171,6 @@ class PrimeHub:
|
||||
the hub.
|
||||
front_side (Axis): The axis that passes through the *front side* of
|
||||
the hub.
|
||||
broadcast_channel:
|
||||
Channel number (0 to 255) used to broadcast data.
|
||||
Choose ``None`` when not using broadcasting.
|
||||
observe_channels:
|
||||
A list of channels to listen to when ``hub.ble.observe()`` is
|
||||
called. Listening to more channels requires more memory.
|
||||
Default is an empty list (no channels).
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
Added *broadcast_channel* and *observe_channels* arguments.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
+356
-114
@@ -5,13 +5,13 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Dict, Tuple, Optional, overload, TYPE_CHECKING
|
||||
from typing import Tuple, Optional, overload, TYPE_CHECKING
|
||||
|
||||
from . import _common
|
||||
from .parameters import Port as _Port
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ._common import MaybeAwaitable, MaybeAwaitableTuple
|
||||
from ._common import MaybeAwaitable, MaybeAwaitableBytes, MaybeAwaitableTuple
|
||||
from .parameters import Number
|
||||
|
||||
|
||||
@@ -25,13 +25,21 @@ class PUPDevice:
|
||||
port (Port): Port to which the device is connected.
|
||||
"""
|
||||
|
||||
def info(self) -> Dict[str, str]:
|
||||
def info(self) -> dict:
|
||||
"""info() -> Dict
|
||||
|
||||
Gets information about the device.
|
||||
|
||||
For passive devices (such as DC motors or lights), returns a
|
||||
dictionary with only the ``id`` key.
|
||||
|
||||
For UART devices, returns a dictionary with an ``id`` key and a
|
||||
``modes`` key. The ``modes`` value is a tuple of tuples, one per
|
||||
mode, each containing the mode name, number of values, and data
|
||||
type.
|
||||
|
||||
Returns:
|
||||
Dictionary with information, such as the device ``id``.
|
||||
Dictionary with device information.
|
||||
"""
|
||||
|
||||
def read(self, mode: int) -> MaybeAwaitableTuple:
|
||||
@@ -39,89 +47,86 @@ class PUPDevice:
|
||||
|
||||
Reads values from a given mode.
|
||||
|
||||
For passive touch sensors, this returns a single boolean value
|
||||
indicating whether the sensor is pressed, regardless of the
|
||||
``mode`` argument.
|
||||
|
||||
Raises an error for other passive devices such as DC motors and
|
||||
lights, which do not support reading.
|
||||
|
||||
Arguments:
|
||||
mode (int): Device mode.
|
||||
|
||||
Returns:
|
||||
Values read from the sensor.
|
||||
Values read from the device.
|
||||
|
||||
Raises:
|
||||
OSError: If the device is a passive device that does not
|
||||
support reading (e.g. a DC motor or light).
|
||||
"""
|
||||
|
||||
def write(self, mode: int, data: Tuple) -> MaybeAwaitable:
|
||||
"""write(mode, data)
|
||||
|
||||
Writes values to the sensor. Only selected sensors and modes support
|
||||
this.
|
||||
Writes values to the device. Only selected UART devices and modes
|
||||
support this.
|
||||
|
||||
Arguments:
|
||||
mode (int): Device mode.
|
||||
data (tuple): Values to be written.
|
||||
data (tuple): Values to be written. The number of values and
|
||||
their types must match what the device expects for the
|
||||
given mode.
|
||||
|
||||
Raises:
|
||||
OSError: If the device is a passive device that does not
|
||||
support writing.
|
||||
ValueError: If the mode is invalid, the mode is not writable,
|
||||
the number of values does not match, or a value is out of
|
||||
range for its data type.
|
||||
"""
|
||||
|
||||
def reset(self) -> None:
|
||||
"""reset()
|
||||
|
||||
Resets the UART device. After this, it should automatically synchronize
|
||||
and be ready for use after a few seconds. This is useful to forcefully
|
||||
re-trigger what such a sensor does when plugged in.
|
||||
|
||||
Raises:
|
||||
OSError: If the device is a passive device that does not
|
||||
support reset.
|
||||
"""
|
||||
|
||||
|
||||
class LUMPDevice:
|
||||
"""Devices using the LEGO UART Messaging Protocol."""
|
||||
class LUMPDevice(PUPDevice):
|
||||
"""Devices using the LEGO UART Messaging Protocol.
|
||||
|
||||
def __init__(self, port: _Port):
|
||||
"""LUMPDevice(port)
|
||||
See the equivalent :class:`PUPDevice() <pybricks.iodevices.PUPDevice>` for
|
||||
a description of available methods.
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the device is connected.
|
||||
"""
|
||||
|
||||
def read(self, mode: int) -> MaybeAwaitableTuple:
|
||||
"""read(mode) -> Tuple
|
||||
|
||||
Reads values from a given mode.
|
||||
|
||||
Arguments:
|
||||
mode (int): Device mode.
|
||||
|
||||
Returns:
|
||||
Values read from the sensor.
|
||||
"""
|
||||
On EV3, this class provides access to UART devices only. You can use other
|
||||
classes to interact with passive devices.
|
||||
"""
|
||||
|
||||
|
||||
class DCMotor(_common.DCMotor):
|
||||
"""DC Motor for LEGO® MINDSTORMS EV3."""
|
||||
|
||||
|
||||
class Ev3devSensor:
|
||||
"""Read values of an ev3dev-compatible sensor."""
|
||||
|
||||
sensor_index: int
|
||||
"""Index of the ev3dev sysfs `lego-sensor`_ class."""
|
||||
|
||||
port_index: int
|
||||
"""Index of the ev3dev sysfs `lego-port`_ class."""
|
||||
|
||||
def __init__(self, port: _Port):
|
||||
"""Ev3devSensor(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the device is connected.
|
||||
"""
|
||||
|
||||
def read(self, mode: str) -> MaybeAwaitableTuple:
|
||||
"""read(mode) -> Tuple
|
||||
|
||||
Reads values at a given mode.
|
||||
|
||||
Arguments:
|
||||
mode (str): `Mode name`_.
|
||||
|
||||
Returns:
|
||||
values read from the sensor.
|
||||
"""
|
||||
|
||||
|
||||
class AnalogSensor:
|
||||
"""Generic or custom analog sensor."""
|
||||
|
||||
def __init__(self, port: _Port):
|
||||
"""AnalogSensor(port)
|
||||
def __init__(self, port: _Port, custom: bool = False):
|
||||
"""AnalogSensor(port, custom=False)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
custom (bool): Set to ``True`` if you are using a custom analog
|
||||
sensor.
|
||||
|
||||
Raises:
|
||||
OSError: If no standard LEGO analog sensor is
|
||||
detected on the port. Only applies if ``custom=False``.
|
||||
"""
|
||||
|
||||
def voltage(self) -> int:
|
||||
@@ -139,10 +144,15 @@ class AnalogSensor:
|
||||
Measures resistance.
|
||||
|
||||
This value is only meaningful if the analog device is a passive load
|
||||
such as a resistor or thermistor.
|
||||
such as a resistor or thermistor. It is calculated assuming a 10 kΩ
|
||||
internal pull-up resistor forming a voltage divider.
|
||||
|
||||
If the circuit is open (no load connected), the maximum integer value
|
||||
is returned.
|
||||
|
||||
Returns:
|
||||
Resistance of the analog device.
|
||||
Resistance of the analog device, or the maximum integer value
|
||||
if the circuit is open.
|
||||
"""
|
||||
|
||||
def active(self) -> None:
|
||||
@@ -171,58 +181,125 @@ class AnalogSensor:
|
||||
|
||||
|
||||
class I2CDevice:
|
||||
"""Generic or custom I2C device."""
|
||||
"""Generic or custom I2C device.
|
||||
|
||||
def __init__(self, port: _Port, address: int):
|
||||
"""I2CDevice(port, address)
|
||||
Note: Use the ``power_pin`` option at your own risk. Applying power to the
|
||||
pins can damage your hub or device if you are not careful. When you use
|
||||
this option, you will be prompted to confirm that you understand the risks.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
port: _Port,
|
||||
address: int,
|
||||
custom: bool = False,
|
||||
power_pin: int = 0,
|
||||
nxt_quirk: bool = False,
|
||||
):
|
||||
"""I2CDevice(port, address, custom=False, power_pin=0, nxt_quirk=False)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the device is connected.
|
||||
address(int): I2C address of the client device. See
|
||||
address (int): I2C address of the client device. See
|
||||
:ref:`I2C Addresses <i2caddress>`.
|
||||
custom (bool): Set to ``True`` if you are using a custom I2C device.
|
||||
power_pin (int): Power requirements for the device. Use
|
||||
``0`` (default) for no power on the pins. On NXT and EV3, use ``1``
|
||||
to apply battery power to pin 1. Other pins are not supported.
|
||||
nxt_quirk (bool): Set to ``True`` for older NXT I2C sensors that
|
||||
need slower compatibility timing to communicate reliably,
|
||||
such as the old NXT Ultrasonic Sensor.
|
||||
"""
|
||||
|
||||
def read(self, reg: Optional[int], length: Optional[int] = 1) -> bytes:
|
||||
"""read(reg, length=1)
|
||||
@overload
|
||||
def read(
|
||||
self, reg: Optional[int] = None, length: int = 1
|
||||
) -> MaybeAwaitableBytes: ...
|
||||
|
||||
Reads bytes, starting at a given register.
|
||||
@overload
|
||||
def read(
|
||||
self, reg: Optional[int] = None, length: int = 1, map: callable = ...
|
||||
) -> MaybeAwaitable: ...
|
||||
|
||||
def read(
|
||||
self, reg: Optional[int] = None, length: int = 1, map=None
|
||||
) -> MaybeAwaitableBytes:
|
||||
"""read(reg=None, length=1) -> bytes
|
||||
read(reg=None, length=1, map=callable) -> Any
|
||||
|
||||
Reads bytes starting at a given register.
|
||||
|
||||
Arguments:
|
||||
reg (int): Register at which to begin
|
||||
reading: 0--255 or 0x00--0xFF.
|
||||
reg (int): Register at which to begin reading: 0--255 or
|
||||
0x00--0xFF. Use ``None`` to read without writing a register
|
||||
address first.
|
||||
length (int): How many bytes to read.
|
||||
map (callable): Optional callable to convert the returned bytes.
|
||||
If given, it is called with the bytes as its argument and its
|
||||
return value is returned instead.
|
||||
|
||||
Returns:
|
||||
Bytes returned from the device.
|
||||
Bytes returned from the device, or the return value of ``map``
|
||||
if a callable was provided.
|
||||
"""
|
||||
|
||||
def write(self, reg: Optional[int], data: Optional[bytes] = None) -> None:
|
||||
"""write(reg, data=None)
|
||||
def write(
|
||||
self, reg: Optional[int] = None, data: Optional[bytes] = None
|
||||
) -> MaybeAwaitable:
|
||||
"""write(reg=None, data=None)
|
||||
|
||||
Writes bytes, starting at a given register.
|
||||
Writes bytes, optionally starting at a given register.
|
||||
|
||||
Arguments:
|
||||
reg (int): Register at which to begin
|
||||
writing: 0--255 or 0x00--0xFF.
|
||||
data (bytes): Bytes to be written.
|
||||
reg (int): Register at which to begin writing: 0--255 or
|
||||
0x00--0xFF. Use ``None`` to write without a register prefix.
|
||||
data (bytes): Bytes to be written. Use ``None`` to write nothing
|
||||
after the register.
|
||||
|
||||
Raises:
|
||||
ValueError: If ``reg`` is given and ``data`` is more than 32 bytes.
|
||||
To write more data, omit the ``reg`` argument and include the
|
||||
register as the first byte of ``data``.
|
||||
"""
|
||||
|
||||
|
||||
class UARTDevice:
|
||||
"""Generic UART device."""
|
||||
"""Generic UART device.
|
||||
|
||||
def __init__(self, port: _Port, baudrate: int, timeout: Optional[int] = None):
|
||||
"""UARTDevice(port, baudrate, timeout=None)
|
||||
Note: Use the ``power_pin`` option at your own risk. Applying power to the
|
||||
pins can damage your hub or device if you are not careful. When you use
|
||||
this option, you will be prompted to confirm that you understand the risks.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
port: _Port,
|
||||
baudrate: int = 115200,
|
||||
timeout: Optional[int] = None,
|
||||
power_pin: int = 0,
|
||||
):
|
||||
"""UARTDevice(port, baudrate=115200, timeout=None, power_pin=0)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the device is connected.
|
||||
port (Port): Port to which the device is connected. On Powered UP
|
||||
hubs, all ports are supported. On EV3, only the sensor ports
|
||||
are supported.
|
||||
baudrate (int): Baudrate of the UART device.
|
||||
timeout (Number, ms): How long to wait
|
||||
during ``read`` before giving up. If you choose ``None``,
|
||||
it will wait forever.
|
||||
timeout (Number, ms): How long to wait during ``read`` and
|
||||
``write`` before giving up. If you choose ``None``, it will
|
||||
wait forever.
|
||||
power_pin (int): Power requirements for the device. Use ``0``
|
||||
(default) for no power on the pins. On Powered UP hubs, use
|
||||
``1`` or ``2`` for pin 1 or 2, respectively. This will apply
|
||||
battery power to the pin, equivalent to powering a motor.
|
||||
On EV3, use ``1`` to apply battery power to pin 1, though only
|
||||
minimal current is available.
|
||||
|
||||
Raises:
|
||||
ValueError: If ``timeout`` is 0 or negative.
|
||||
"""
|
||||
|
||||
def read(self, length: int = 1) -> bytes:
|
||||
def read(self, length: int = 1) -> MaybeAwaitableBytes:
|
||||
"""read(length=1) -> bytes
|
||||
|
||||
Reads a given number of bytes from the buffer.
|
||||
@@ -232,28 +309,38 @@ class UARTDevice:
|
||||
exception is raised.
|
||||
|
||||
Arguments:
|
||||
length (int): How many bytes to read.
|
||||
length (int): How many bytes to read. Must be at least 1.
|
||||
|
||||
Returns:
|
||||
Bytes returned from the device.
|
||||
|
||||
Raises:
|
||||
ValueError: If ``length`` is less than 1.
|
||||
OSError: If the read takes longer than ``timeout``.
|
||||
"""
|
||||
|
||||
def read_all(self) -> bytes:
|
||||
"""read_all() -> bytes
|
||||
|
||||
Reads all bytes from the buffer.
|
||||
Reads all bytes currently in the buffer. Returns immediately without
|
||||
waiting, even if the buffer is empty.
|
||||
|
||||
Returns:
|
||||
Bytes returned from the device.
|
||||
Bytes currently in the buffer, or an empty bytes object if there
|
||||
is nothing to read.
|
||||
"""
|
||||
|
||||
def write(self, data: bytes) -> None:
|
||||
def write(self, data: bytes) -> MaybeAwaitable:
|
||||
"""write(data)
|
||||
|
||||
Writes bytes.
|
||||
Writes bytes to the device.
|
||||
|
||||
Arguments:
|
||||
data (bytes): Bytes to be written.
|
||||
|
||||
Raises:
|
||||
TypeError: If ``data`` is not ``bytes``, ``bytearray``, or ``str``.
|
||||
OSError: If the write takes longer than ``timeout``.
|
||||
"""
|
||||
|
||||
def waiting(self) -> int:
|
||||
@@ -265,23 +352,57 @@ class UARTDevice:
|
||||
Number of bytes in the buffer.
|
||||
"""
|
||||
|
||||
def set_baudrate(self, baudrate: int) -> None:
|
||||
"""set_baudrate(baudrate)
|
||||
|
||||
Changes the baud rate of the UART device.
|
||||
|
||||
Arguments:
|
||||
baudrate (int): Not all values may be supported.
|
||||
|
||||
Raises:
|
||||
ValueError: If ``baudrate`` is less than 1.
|
||||
"""
|
||||
|
||||
def wait_until(self, pattern: bytes) -> MaybeAwaitable:
|
||||
"""wait_until(pattern)
|
||||
|
||||
Waits until a specific byte sequence is received. Bytes that do not
|
||||
match the pattern are discarded.
|
||||
|
||||
Arguments:
|
||||
pattern (bytes): Byte sequence to wait for. Must not be empty.
|
||||
|
||||
Raises:
|
||||
ValueError: If ``pattern`` is empty.
|
||||
OSError: If this method is already in progress.
|
||||
"""
|
||||
|
||||
def clear(self) -> None:
|
||||
"""clear()
|
||||
|
||||
Empties the buffer."""
|
||||
Empties the receive buffer."""
|
||||
|
||||
|
||||
class LWP3Device:
|
||||
"""
|
||||
Connects to a hub running official LEGO firmware using the
|
||||
`LEGO Wireless Protocol v3`_
|
||||
`LEGO Wireless Protocol v3`_.
|
||||
|
||||
.. _`LEGO Wireless Protocol v3`:
|
||||
https://lego.github.io/lego-ble-wireless-protocol-docs/
|
||||
"""
|
||||
|
||||
def __init__(self, hub_kind: int, name: str = None, timeout: int = 10000):
|
||||
"""LWP3Device(hub_kind, name=None, timeout=10000)
|
||||
def __init__(
|
||||
self,
|
||||
hub_kind: int,
|
||||
name: str = None,
|
||||
timeout: int = 10000,
|
||||
pair: bool = False,
|
||||
num_notifications: int = 8,
|
||||
connect: bool = True,
|
||||
):
|
||||
"""LWP3Device(hub_kind, name=None, timeout=10000, pair=False, num_notifications=8, connect=True)
|
||||
|
||||
Arguments:
|
||||
hub_kind (int):
|
||||
@@ -292,12 +413,35 @@ class LWP3Device:
|
||||
timeout (int):
|
||||
The time, in milliseconds, to wait for a connection before
|
||||
raising an exception.
|
||||
pair (bool): Whether to attempt pairing for a secure connection.
|
||||
This is required for some newer hubs.
|
||||
num_notifications (int): Number of incoming messages from the remote
|
||||
hub to store before discarding older messages.
|
||||
connect (bool): Choose ``False`` to skip connecting.
|
||||
``connect()`` can be called later to connect.
|
||||
|
||||
.. versionchanged:: 3.6
|
||||
|
||||
Added ``pair`` parameter.
|
||||
|
||||
.. versionchanged:: 3.7
|
||||
|
||||
Added ``num_notifications`` parameter.
|
||||
|
||||
.. _`hub type identifier`:
|
||||
https://github.com/pybricks/technical-info/blob/master/assigned-numbers.md#hub-type-ids
|
||||
"""
|
||||
|
||||
def connect(self) -> MaybeAwaitable:
|
||||
"""connect()
|
||||
|
||||
Connects to the device. Only needed if you disconnected or initialized
|
||||
with ``connect=False``.
|
||||
|
||||
Raises:
|
||||
OSError: If the connection attempt fails or times out.
|
||||
"""
|
||||
|
||||
@overload
|
||||
def name(self, name: str) -> MaybeAwaitable: ...
|
||||
|
||||
@@ -313,6 +457,9 @@ class LWP3Device:
|
||||
Arguments:
|
||||
name (str): New Bluetooth name of the device. If no name is given,
|
||||
this method returns the current name.
|
||||
|
||||
Raises:
|
||||
OSError: If the device is not connected.
|
||||
"""
|
||||
|
||||
def write(self, buf: bytes) -> MaybeAwaitable:
|
||||
@@ -321,25 +468,36 @@ class LWP3Device:
|
||||
Sends a message to the remote hub.
|
||||
|
||||
Arguments:
|
||||
buf (bytes): The raw binary message to send.
|
||||
buf (bytes): The raw binary message to send. Maximum 20 bytes.
|
||||
|
||||
Raises:
|
||||
ValueError: If the message exceeds 20 bytes.
|
||||
OSError: If the device is not connected or the write fails.
|
||||
"""
|
||||
|
||||
def read(self) -> bytes:
|
||||
"""read() -> bytes
|
||||
def read(self) -> bytes | None:
|
||||
"""read() -> bytes | None
|
||||
|
||||
Retrieves the most recent message received from the remote hub.
|
||||
Retrieves the oldest buffered message received from the remote hub.
|
||||
|
||||
If a message has not been received since the last read, the method will
|
||||
block until a message is received.
|
||||
If all buffered messages have already been read, this returns ``None``.
|
||||
|
||||
Returns:
|
||||
The raw binary message.
|
||||
The oldest raw binary message or ``None`` if there are no more messages.
|
||||
|
||||
.. versionchanged:: 3.7
|
||||
|
||||
Now supports reading multiple buffered messages instead of blocking
|
||||
until one new message was received.
|
||||
"""
|
||||
|
||||
def disconnect(self) -> MaybeAwaitable:
|
||||
"""disconnect()
|
||||
|
||||
Disconnects the remote LWP3Device from the hub.
|
||||
Disconnects the device.
|
||||
|
||||
Raises:
|
||||
OSError: If disconnecting fails.
|
||||
"""
|
||||
|
||||
|
||||
@@ -355,27 +513,95 @@ class XboxController:
|
||||
|
||||
buttons = _common.Keypad([])
|
||||
|
||||
def __init__(self):
|
||||
""""""
|
||||
def __init__(
|
||||
self,
|
||||
joystick_deadzone: int = 10,
|
||||
name: Optional[str] = None,
|
||||
timeout: int = 10000,
|
||||
connect: bool = True,
|
||||
):
|
||||
"""__init__(joystick_deadzone=10, name=None, timeout=10000, connect=True)
|
||||
|
||||
Arguments:
|
||||
joystick_deadzone (Number, %): Joystick deadzone (0 to 100). Values
|
||||
below this threshold in both axes will be reported as 0 to
|
||||
prevent stick drift.
|
||||
name (str): The Bluetooth name of the Xbox controller to connect to,
|
||||
or ``None`` to connect to any available controller.
|
||||
timeout (Number, ms): How long to wait for a connection before
|
||||
giving up. Choose ``None`` to wait indefinitely.
|
||||
connect (bool): Choose ``False`` to skip connecting to the controller.
|
||||
``connect()`` can be called later to connect.
|
||||
"""
|
||||
|
||||
def connect(self) -> MaybeAwaitable:
|
||||
"""connect()
|
||||
|
||||
Connects to the Xbox controller. Only needed if you disconnected or
|
||||
initialized the controller with ``connect=False``.
|
||||
"""
|
||||
|
||||
def disconnect(self) -> MaybeAwaitable:
|
||||
"""disconnect()
|
||||
|
||||
Disconnects the Xbox controller.
|
||||
"""
|
||||
|
||||
def name(self) -> str:
|
||||
"""name() -> str
|
||||
|
||||
Gets the Bluetooth name of the connected controller.
|
||||
|
||||
Returns:
|
||||
Bluetooth name of the controller.
|
||||
|
||||
Raises:
|
||||
OSError: If the controller is not connected.
|
||||
"""
|
||||
|
||||
def state(self) -> Tuple:
|
||||
"""state() -> Tuple
|
||||
|
||||
Gets all raw controller input values as a single tuple. This gives
|
||||
access to values not exposed by the other methods.
|
||||
|
||||
The joystick axes (x, y, z, rz) are centered at 0. The trigger axes
|
||||
are raw 10-bit values (0-1023).
|
||||
|
||||
Returns:
|
||||
Tuple of ``(x, y, z, rz, left_trigger, right_trigger, dpad,
|
||||
buttons, upload, profile, trigger_switches, paddles)``.
|
||||
|
||||
Raises:
|
||||
OSError: If the controller is not connected.
|
||||
"""
|
||||
|
||||
def joystick_left(self) -> Tuple[int, int]:
|
||||
"""joystick_left() -> Tuple
|
||||
|
||||
Gets the left joystick position as percentages between -100%
|
||||
and 100%. The center position is (0, 0).
|
||||
and 100%. The center position is (0, 0). A square deadzone is applied:
|
||||
if both axes are within the deadzone, both are reported as 0.
|
||||
|
||||
Returns:
|
||||
Tuple of X (horizontal) and Y (vertical) position.
|
||||
|
||||
Raises:
|
||||
OSError: If the controller is not connected.
|
||||
"""
|
||||
|
||||
def joystick_right(self) -> Tuple[int, int]:
|
||||
"""joystick_right() -> Tuple
|
||||
|
||||
Gets the right joystick position as percentages between -100%
|
||||
and 100%. The center position is (0, 0).
|
||||
and 100%. The center position is (0, 0). A square deadzone is applied:
|
||||
if both axes are within the deadzone, both are reported as 0.
|
||||
|
||||
Returns:
|
||||
Tuple of X (horizontal) and Y (vertical) position.
|
||||
|
||||
Raises:
|
||||
OSError: If the controller is not connected.
|
||||
"""
|
||||
|
||||
def triggers(self) -> Tuple[int, int]:
|
||||
@@ -386,6 +612,9 @@ class XboxController:
|
||||
|
||||
Returns:
|
||||
Tuple of left and right trigger positions.
|
||||
|
||||
Raises:
|
||||
OSError: If the controller is not connected.
|
||||
"""
|
||||
|
||||
def dpad(self) -> int:
|
||||
@@ -402,6 +631,9 @@ class XboxController:
|
||||
|
||||
Returns:
|
||||
Direction-pad position, indicating a direction.
|
||||
|
||||
Raises:
|
||||
OSError: If the controller is not connected.
|
||||
"""
|
||||
|
||||
def profile(self) -> int:
|
||||
@@ -412,6 +644,9 @@ class XboxController:
|
||||
|
||||
Returns:
|
||||
Profile number.
|
||||
|
||||
Raises:
|
||||
OSError: If the controller is not connected.
|
||||
"""
|
||||
|
||||
def rumble(
|
||||
@@ -426,27 +661,34 @@ class XboxController:
|
||||
Makes the builtin actuators rumble, creating force feedback.
|
||||
|
||||
If you give a single ``power`` value, the left and right main actuators
|
||||
will both rumble with that power. For more fine-grained control, set
|
||||
``power`` as a tuple of four values, which control the left main
|
||||
actuator, right main actuator, left trigger actuator, and the right
|
||||
trigger actuator, respectively. For example, ``power=(0, 0, 100, 0)``
|
||||
makes the left trigger rumble at full power.
|
||||
will both rumble with that power while the trigger actuators stay off.
|
||||
For more fine-grained control, set ``power`` as a tuple of four values,
|
||||
which control the left main actuator, right main actuator, left trigger
|
||||
actuator, and the right trigger actuator, respectively. For example,
|
||||
``power=(0, 0, 100, 0)`` makes the left trigger rumble at full power.
|
||||
|
||||
The rumble runs in the background while your program continues. To
|
||||
make your program wait, just pause the program for a matching duration.
|
||||
For one rumble, this equals ``duration``. For multiple rumbles, this
|
||||
equals ``count * (duration + delay)``.
|
||||
|
||||
This method does nothing if all actuator powers are zero, if
|
||||
``duration`` is zero, or if ``count`` is less than 1.
|
||||
|
||||
Arguments:
|
||||
power (Number, % or tuple): Rumble power.
|
||||
duration (Number, ms): Rumble duration.
|
||||
count (int): Rumble count.
|
||||
delay (Number, ms): Delay before each rumble. Only if ``count > 1``.
|
||||
power (Number, % or tuple): Rumble power. A single value applies
|
||||
to both main actuators (0-100%). A tuple applies individually
|
||||
to (left handle, right handle, left trigger, right trigger).
|
||||
duration (Number, ms): Duration of each rumble. Capped at 2500 ms.
|
||||
count (int): Number of rumbles (0-100).
|
||||
delay (Number, ms): Delay before each rumble. Only used if
|
||||
``count > 1``. Capped at 2500 ms.
|
||||
"""
|
||||
|
||||
|
||||
# hide from jedi
|
||||
if TYPE_CHECKING:
|
||||
del MaybeAwaitable
|
||||
del MaybeAwaitableBytes
|
||||
del MaybeAwaitableTuple
|
||||
del Number
|
||||
|
||||
+241
-9
@@ -1,29 +1,170 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2018-2020 The Pybricks Authors
|
||||
# Copyright (c) 2018-2026 The Pybricks Authors
|
||||
|
||||
"""
|
||||
Classes to exchange messages between EV3 bricks.
|
||||
Classes to send and receive messages from another device.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import abstractmethod, TypeVar, Optional, Callable, Generic
|
||||
|
||||
from typing import (
|
||||
abstractmethod,
|
||||
Callable,
|
||||
Generic,
|
||||
Iterable,
|
||||
List,
|
||||
Optional,
|
||||
overload,
|
||||
Sequence,
|
||||
Tuple,
|
||||
TYPE_CHECKING,
|
||||
TypeVar,
|
||||
Union,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ._common import (
|
||||
MaybeAwaitable,
|
||||
)
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
class BLERadio:
|
||||
"""
|
||||
Send and receive messages without a connection using Bluetooth Low Energy.
|
||||
|
||||
.. versionadded:: 4.0
|
||||
|
||||
This used to be part of each hub class.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
broadcast_channel: Optional[int] = None,
|
||||
observe_channels: Sequence[int] = [],
|
||||
):
|
||||
"""BLERadio(broadcast_channel=None, observe_channels=[])
|
||||
|
||||
Arguments:
|
||||
broadcast_channel:
|
||||
Channel number (0 to 255) used to broadcast data.
|
||||
Choose ``None`` when not using broadcasting.
|
||||
observe_channels:
|
||||
A list of channels to listen to when ``hub.ble.observe()`` is
|
||||
called. Listening to more channels requires more memory.
|
||||
Default is an empty list (no channels).
|
||||
"""
|
||||
|
||||
@overload
|
||||
def broadcast(self, data: None) -> MaybeAwaitable: ...
|
||||
|
||||
@overload
|
||||
def broadcast(
|
||||
self, data: Iterable[Union[bool, int, float, str, bytes]]
|
||||
) -> MaybeAwaitable: ...
|
||||
|
||||
@overload
|
||||
def broadcast(
|
||||
self, data: Union[bool, int, float, str, bytes]
|
||||
) -> MaybeAwaitable: ...
|
||||
|
||||
def broadcast(self, data: object) -> MaybeAwaitable:
|
||||
"""broadcast(data)
|
||||
|
||||
Starts broadcasting the given data on the previously selected
|
||||
``broadcast_channel``.
|
||||
|
||||
Data may be of type ``int``, ``float``, ``str``, ``bytes``,
|
||||
``True``, or ``False``. It can also be a list or tuple of these.
|
||||
|
||||
Choose ``None`` to stop broadcasting. This helps improve performance
|
||||
when you don't need the broadcast feature, especially when observing
|
||||
at the same time.
|
||||
|
||||
The total data size is quite limited (26 bytes). ``True`` and
|
||||
``False`` take 1 byte each. ``float`` takes 5 bytes. ``int`` takes 2 to
|
||||
5 bytes depending on how big the number is. ``str`` and ``bytes`` take
|
||||
the number of bytes in the object plus one extra byte.
|
||||
|
||||
When multitasking, only one task can broadcast at a time. To broadcast
|
||||
information from multiple tasks (or block stacks), you could use a
|
||||
dedicated separate task that broadcast new values when one or more
|
||||
variables change.
|
||||
|
||||
Args:
|
||||
data: The value or values to be broadcast.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If no ``broadcast_channel`` was configured.
|
||||
ValueError: If the encoded data exceeds 26 bytes.
|
||||
TypeError: If ``data`` contains a value that is not ``bool``,
|
||||
``int``, ``float``, ``str``, or ``bytes``.
|
||||
"""
|
||||
|
||||
def observe(self, channel: int) -> Optional[
|
||||
Union[
|
||||
Tuple[Union[bool, int, float, str, bytes], ...],
|
||||
Union[bool, int, float, str, bytes],
|
||||
]
|
||||
]:
|
||||
"""observe(channel) -> bool | int | float | str | bytes | tuple | None
|
||||
|
||||
Retrieves the last observed data for a given channel.
|
||||
|
||||
Receiving data is more reliable when the hub is not connected
|
||||
to a computer or other devices at the same time.
|
||||
|
||||
Args:
|
||||
channel (int): The channel to observe. Must be one of the channels
|
||||
given to ``observe_channels`` when creating this object.
|
||||
|
||||
Returns:
|
||||
The received data in the same format as it was sent, or ``None``
|
||||
if no data has been received within the last second.
|
||||
|
||||
Raises:
|
||||
ValueError: If ``channel`` was not in ``observe_channels``.
|
||||
"""
|
||||
|
||||
def signal_strength(self, channel: int) -> int:
|
||||
"""signal_strength(channel) -> int: dBm
|
||||
|
||||
Gets the average signal strength in dBm for the given channel.
|
||||
|
||||
This indicates how near the broadcasting device is. Nearby devices
|
||||
may have a signal strength around -40 dBm, while far away devices
|
||||
might have a signal strength around -70 dBm.
|
||||
|
||||
Args:
|
||||
channel (int): The channel number. Must be one of the channels
|
||||
given to ``observe_channels`` when creating this object.
|
||||
|
||||
Returns:
|
||||
The signal strength, or ``-128`` if no data has been received
|
||||
within the last second.
|
||||
|
||||
Raises:
|
||||
ValueError: If ``channel`` was not in ``observe_channels``.
|
||||
"""
|
||||
|
||||
def version(self) -> str:
|
||||
"""version() -> str
|
||||
|
||||
Gets the firmware version from the Bluetooth chip.
|
||||
"""
|
||||
|
||||
|
||||
class Connection:
|
||||
@abstractmethod
|
||||
def read_from_mailbox(self, name: str) -> bytes:
|
||||
...
|
||||
def read_from_mailbox(self, name: str) -> bytes: ...
|
||||
|
||||
@abstractmethod
|
||||
def send_to_mailbox(self, name: str, data: bytes) -> None:
|
||||
...
|
||||
def send_to_mailbox(self, name: str, data: bytes) -> None: ...
|
||||
|
||||
@abstractmethod
|
||||
def wait_for_mailbox_update(self, name: str) -> None:
|
||||
...
|
||||
def wait_for_mailbox_update(self, name: str) -> None: ...
|
||||
|
||||
|
||||
class Mailbox(Generic[T]):
|
||||
@@ -231,3 +372,94 @@ class BluetoothMailboxClient:
|
||||
"""close()
|
||||
|
||||
Closes all connections."""
|
||||
|
||||
|
||||
class AppData:
|
||||
"""
|
||||
Exchange raw data with the Pybricks Code host application over USB or
|
||||
Bluetooth. This is used by the smart sensor features like the vision
|
||||
processors.
|
||||
|
||||
Each processor has on emode and produces a fixed amount of data. These are
|
||||
continuously sent to the hub as they change. The user code can read these
|
||||
buffered values at any time without blocking. All values are initially zero.
|
||||
|
||||
From the hub's perspective, writing back to the host is an awaitable operation.
|
||||
Can be used to configure modes and mode settings.
|
||||
|
||||
Only one instance may exist at a time. Must be created during program
|
||||
initialization. After that, all methods may be used while multi-tasking.
|
||||
"""
|
||||
|
||||
def __init__(self, modes: List[Tuple[int, int]]):
|
||||
"""AppData(modes)
|
||||
|
||||
Arguments:
|
||||
modes:
|
||||
A list of ``(mode, size)`` tuples, where ``mode`` is a mode
|
||||
number (0 to 255) and ``size`` is the number of bytes to
|
||||
allocate for that mode's receive buffer. Mode numbers must be
|
||||
unique. The list is sorted by mode number automatically.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If an ``AppData`` instance already exists.
|
||||
TypeError: If ``modes`` is not a list, or if any element is not a
|
||||
``(mode, size)`` tuple with a mode value of 0 to 255.
|
||||
ValueError: If any mode number appears more than once.
|
||||
"""
|
||||
|
||||
def get_bytes(self, mode: int, index: Optional[int] = None) -> Union[bytes, int]:
|
||||
"""get_bytes(mode, index=None) -> bytes | int
|
||||
|
||||
Gets data received from the host for the given mode.
|
||||
|
||||
Args:
|
||||
mode (int): The mode number to read.
|
||||
index (int): If given, returns the single byte at this position
|
||||
within the mode's buffer as an integer. Otherwise returns
|
||||
the entire mode buffer as ``bytes``.
|
||||
|
||||
Returns:
|
||||
All received bytes for the mode, or a single byte as an integer
|
||||
if ``index`` is given.
|
||||
|
||||
Raises:
|
||||
ValueError: If ``mode`` was not configured, or if ``index`` is
|
||||
out of range.
|
||||
"""
|
||||
|
||||
def write_bytes(self, data: bytes) -> MaybeAwaitable:
|
||||
"""write_bytes(data)
|
||||
|
||||
Sends raw bytes to the host application.
|
||||
|
||||
Args:
|
||||
data (bytes): The data to send.
|
||||
"""
|
||||
|
||||
def configure(self, mode: int, parameter: int, value: bytes) -> MaybeAwaitable:
|
||||
"""configure(mode, parameter, value)
|
||||
|
||||
Sends a configuration command to the host for the given mode.
|
||||
|
||||
This is a wrapper around :meth:`write_bytes`. It prepends a
|
||||
``[0x01, mode, parameter]`` header to configure mode settings.
|
||||
|
||||
Args:
|
||||
mode (int): The mode number to configure.
|
||||
parameter (int): The parameter identifier within the mode.
|
||||
value (bytes): The configuration value to send.
|
||||
"""
|
||||
|
||||
def close(self) -> None:
|
||||
"""close()
|
||||
|
||||
Deactivates the data callback and releases the receive buffer.
|
||||
|
||||
This is also called automatically when the object is garbage collected.
|
||||
"""
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
del MaybeAwaitable
|
||||
del T
|
||||
|
||||
@@ -112,6 +112,13 @@ class Color:
|
||||
The brightness value.
|
||||
"""
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
if key not in ("h", "s", "v"):
|
||||
raise AttributeError("Can't modify unknown attribute: " + key)
|
||||
if hasattr(self, key): # immutable after __init__
|
||||
raise AttributeError("Can't modify immutable attribute: " + key)
|
||||
super().__setattr__(key, value)
|
||||
|
||||
def __iter__(self):
|
||||
"""Allows unpacking of the Color instance into h, s, and v."""
|
||||
return iter((self.h, self.s, self.v))
|
||||
@@ -119,11 +126,12 @@ class Color:
|
||||
def __repr__(self):
|
||||
return "Color(h={}, s={}, v={})".format(self.h, self.s, self.v)
|
||||
|
||||
def __eq__(self, other: Color) -> bool: ...
|
||||
def __eq__(self, other: Color) -> bool:
|
||||
return self.h == other.h and self.s == other.s and self.v == other.v
|
||||
|
||||
def __mul__(self, scale: float) -> Color:
|
||||
v = max(0, min(self.v * scale, 100))
|
||||
return Color(self.h, self.s, int(v), self.name)
|
||||
return Color(self.h, self.s, int(v))
|
||||
|
||||
def __rmul__(self, scale: float) -> Color:
|
||||
return self.__mul__(scale)
|
||||
@@ -134,6 +142,12 @@ class Color:
|
||||
def __floordiv__(self, scale: int) -> Color:
|
||||
return self.__mul__(1 / scale)
|
||||
|
||||
def __lshift__(self, shift: int) -> Color:
|
||||
return self.__rshift__(-shift)
|
||||
|
||||
def __rshift__(self, shift: int) -> Color:
|
||||
return Color((self.h + shift) % 360, self.s, self.v)
|
||||
|
||||
|
||||
Color.NONE = Color(0, 0, 0)
|
||||
Color.BLACK = Color(0, 0, 10)
|
||||
|
||||
+221
-23
@@ -5,9 +5,10 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Collection, Optional, Union, overload
|
||||
from typing import TYPE_CHECKING, Collection, Optional, Union
|
||||
|
||||
from . import _common
|
||||
from .iodevices import LWP3Device
|
||||
from .parameters import Button, Color, Direction
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -98,7 +99,7 @@ class Motor(_common.Motor):
|
||||
"""
|
||||
|
||||
|
||||
class Remote:
|
||||
class Remote(LWP3Device):
|
||||
"""LEGO® Powered Up Bluetooth Remote Control."""
|
||||
|
||||
light = _common.ExternalColorLight()
|
||||
@@ -115,42 +116,238 @@ class Remote:
|
||||
)
|
||||
address: Union[str, None]
|
||||
|
||||
def __init__(self, name: Optional[str] = None, timeout: int = 10000):
|
||||
"""Remote(name=None, timeout=10000)
|
||||
|
||||
When you instantiate this class, the hub will search for a remote
|
||||
and connect automatically.
|
||||
|
||||
The remote must be on and ready for a connection, as indicated by a
|
||||
white blinking light.
|
||||
def __init__(
|
||||
self,
|
||||
name: Optional[str] = None,
|
||||
timeout: int = 10000,
|
||||
connect: bool = True,
|
||||
):
|
||||
"""Remote(name=None, timeout=10000, connect=True)
|
||||
|
||||
Arguments:
|
||||
name (str): Bluetooth name of the remote. If no name is given,
|
||||
the hub connects to the first remote that it finds.
|
||||
timeout (Number, ms): How long to search for the remote.
|
||||
Choose ``None`` to wait indefinitely.
|
||||
connect (bool): Choose ``False`` to skip connecting.
|
||||
``connect()`` can be called later to connect.
|
||||
|
||||
Raises:
|
||||
OSError: If the connection attempt fails or times out.
|
||||
"""
|
||||
|
||||
@overload
|
||||
def name(self, name: str) -> None: ...
|
||||
|
||||
@overload
|
||||
def name(self) -> str: ...
|
||||
class TechnicMoveHub(LWP3Device):
|
||||
"""LEGO® Technic Move Hub (set 42176, 42214, 42239).
|
||||
|
||||
def name(self, *args):
|
||||
"""name(name)
|
||||
name() -> str
|
||||
This newer hub is found in the latest Technic Control+ sets. It requires
|
||||
a special password to update the firmware, so Pybricks cannot be installed
|
||||
on it. However, you can connect a supported hub running Pybricks to it
|
||||
and control its motors that way.
|
||||
"""
|
||||
|
||||
Sets or gets the Bluetooth name of the remote.
|
||||
def __init__(
|
||||
self,
|
||||
name: Optional[str] = None,
|
||||
timeout: int = 10000,
|
||||
connect: bool = True,
|
||||
):
|
||||
"""TechnicMoveHub(name=None, timeout=10000, connect=True)
|
||||
|
||||
Arguments:
|
||||
name (str): New Bluetooth name of the remote. If no name is given,
|
||||
this method returns the current name.
|
||||
name (str): Bluetooth name of the hub. If no name is given,
|
||||
the hub connects to the first Technic Move Hub it finds.
|
||||
timeout (Number, ms): How long to search for the hub.
|
||||
Choose ``None`` to wait indefinitely.
|
||||
connect (bool): Choose ``False`` to skip connecting.
|
||||
``connect()`` can be called later to connect.
|
||||
|
||||
Raises:
|
||||
OSError: If the connection attempt fails or times out.
|
||||
"""
|
||||
|
||||
def disconnect(self) -> MaybeAwaitable:
|
||||
"""disconnect()
|
||||
def drive(self, speed: int, steering: int) -> MaybeAwaitable:
|
||||
"""drive(speed, steering)
|
||||
|
||||
Disconnects the remote from the hub.
|
||||
Drives the hub's motor outputs at the given speed and steering.
|
||||
|
||||
Arguments:
|
||||
speed (int): Drive speed as a percentage (-100 to 100).
|
||||
steering (int): Steering as a percentage (-100 to 100). Positive
|
||||
values steer right. Values exceeding ±97 are clamped to ±97
|
||||
to avoid pushing against the mechanical constraint.
|
||||
|
||||
Raises:
|
||||
OSError: If the hub is not connected.
|
||||
"""
|
||||
|
||||
|
||||
class MarioHub(LWP3Device):
|
||||
"""LEGO® Super Mario hub (sets 71360, 71387, 71441 and similar).
|
||||
|
||||
Connect a supported hub running Pybricks to a LEGO Mario, Luigi, or Peach
|
||||
figure and reads its color sensor.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: Optional[str] = None,
|
||||
timeout: int = 10000,
|
||||
connect: bool = True,
|
||||
):
|
||||
"""MarioHub(name=None, timeout=10000, connect=True)
|
||||
|
||||
Arguments:
|
||||
name (str): Bluetooth name of the hub. If no name is given,
|
||||
the hub connects to the first Mario hub it finds.
|
||||
timeout (Number, ms): How long to search for the hub.
|
||||
Choose ``None`` to wait indefinitely.
|
||||
connect (bool): Choose ``False`` to skip connecting.
|
||||
``connect()`` can be called later to connect.
|
||||
|
||||
Raises:
|
||||
OSError: If the connection attempt fails or times out.
|
||||
"""
|
||||
|
||||
def color(self) -> Color:
|
||||
"""color() -> Color
|
||||
|
||||
Reads the color detected by the color sensor from the latest received
|
||||
notification.
|
||||
|
||||
Returns:
|
||||
Detected color.
|
||||
|
||||
Raises:
|
||||
OSError: If the hub is not connected.
|
||||
"""
|
||||
|
||||
def hsv(self) -> Color:
|
||||
"""hsv() -> Color
|
||||
|
||||
Reads the hue, saturation, and brightness of the color detected by the
|
||||
color sensor from the latest received notification, as a
|
||||
:class:`Color <.parameters.Color>` object.
|
||||
|
||||
Returns:
|
||||
Measured color.
|
||||
|
||||
Raises:
|
||||
OSError: If the hub is not connected.
|
||||
"""
|
||||
|
||||
def detectable_colors(self, colors: Collection[Color] = None) -> None:
|
||||
"""detectable_colors(colors)
|
||||
|
||||
Configures the list of colors that :meth:`color` may return.
|
||||
|
||||
Only the colors in this list will be returned. This helps reduce
|
||||
false positives when you only care about a specific subset of colors.
|
||||
|
||||
Arguments:
|
||||
colors (list): List of :class:`Color <.parameters.Color>` objects
|
||||
to detect, or ``None`` to restore the default list.
|
||||
"""
|
||||
|
||||
|
||||
class DuploTrain(LWP3Device):
|
||||
"""LEGO® Duplo Train hub (sets 10874, 10875, 10427, 10428 similar).
|
||||
|
||||
The Duplo Hub cannot be updated, so you cannot install Pybricks on it.
|
||||
However, you can connect a supported hub running Pybricks to the Duplo Hub
|
||||
and control the train that way.
|
||||
|
||||
You can you control the motor, sound, and headlights, and read the speed
|
||||
and color sensors.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: Optional[str] = None,
|
||||
timeout: int = 10000,
|
||||
connect: bool = True,
|
||||
):
|
||||
"""DuploTrain(name=None, timeout=10000, connect=True)
|
||||
|
||||
Arguments:
|
||||
name (str): Bluetooth name of the hub. If no name is given,
|
||||
the hub connects to the first Duplo Train hub it finds.
|
||||
timeout (Number, ms): How long to search for the hub.
|
||||
Choose ``None`` to wait indefinitely.
|
||||
connect (bool): Choose ``False`` to skip connecting.
|
||||
``connect()`` can be called later to connect.
|
||||
|
||||
Raises:
|
||||
OSError: If the connection attempt fails or times out.
|
||||
"""
|
||||
|
||||
def drive(self, speed: int) -> MaybeAwaitable:
|
||||
"""drive(speed)
|
||||
|
||||
Drives the train motor at the given speed.
|
||||
|
||||
Arguments:
|
||||
speed (int): Speed as a percentage (-100 to 100). Negative values
|
||||
drive in reverse.
|
||||
|
||||
Raises:
|
||||
OSError: If the hub is not connected.
|
||||
"""
|
||||
|
||||
def headlights(self, color: Color) -> MaybeAwaitable:
|
||||
"""headlights(color)
|
||||
|
||||
Sets the color of the train headlights. Not all colors are supported,
|
||||
so the hub will choose the closest color it can produce.
|
||||
|
||||
Arguments:
|
||||
color (Color): Color of the headlights.
|
||||
|
||||
Raises:
|
||||
OSError: If the hub is not connected.
|
||||
"""
|
||||
|
||||
def sound(self, sound: str) -> MaybeAwaitable:
|
||||
"""sound(sound)
|
||||
|
||||
Plays one of the built-in train sounds.
|
||||
|
||||
For the newer (dark blue) train, we have not yet figured out the right
|
||||
sound codes. Please open a discussion or pull request if you know how
|
||||
to do it. Thanks!
|
||||
|
||||
Arguments:
|
||||
sound (str): Name of the sound to play. Choose from
|
||||
``"brake"``, ``"depart"``, ``"water"``, ``"horn"``,
|
||||
or ``"steam"``.
|
||||
|
||||
Raises:
|
||||
OSError: If the hub is not connected.
|
||||
"""
|
||||
|
||||
def speed(self) -> int:
|
||||
"""speed() -> int: %
|
||||
|
||||
Reads the train speed from the latest received notification.
|
||||
|
||||
Returns:
|
||||
Speed as a percentage (-100 to 100).
|
||||
|
||||
Raises:
|
||||
OSError: If the hub is not connected.
|
||||
"""
|
||||
|
||||
def color(self) -> Color:
|
||||
"""color() -> Color
|
||||
|
||||
Reads the color detected by the color sensor from the latest received
|
||||
notification.
|
||||
|
||||
Returns:
|
||||
Detected color.
|
||||
|
||||
Raises:
|
||||
OSError: If the hub is not connected.
|
||||
"""
|
||||
|
||||
|
||||
@@ -461,6 +658,7 @@ if TYPE_CHECKING:
|
||||
del Button
|
||||
del Color
|
||||
del Direction
|
||||
del LWP3Device
|
||||
del MaybeAwaitable
|
||||
del MaybeAwaitableBool
|
||||
del MaybeAwaitableFloat
|
||||
|
||||
+67
-16
@@ -5,7 +5,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Tuple, Optional, overload, TYPE_CHECKING
|
||||
from typing import Tuple, Union, Optional, overload, TYPE_CHECKING
|
||||
|
||||
from . import _common
|
||||
from .parameters import Stop
|
||||
@@ -92,6 +92,12 @@ class DriveBase:
|
||||
Stops the robot by passively braking the motors.
|
||||
"""
|
||||
|
||||
def hold(self) -> None:
|
||||
"""hold()
|
||||
|
||||
Stops the robot and actively holds it in place.
|
||||
"""
|
||||
|
||||
def distance(self) -> int:
|
||||
"""distance() -> int: mm
|
||||
|
||||
@@ -101,11 +107,15 @@ class DriveBase:
|
||||
Driven distance since last reset.
|
||||
"""
|
||||
|
||||
def angle(self) -> int:
|
||||
"""angle() -> int: deg
|
||||
def angle(self) -> float:
|
||||
"""angle() -> float: deg
|
||||
|
||||
Gets the estimated rotation angle of the drive base.
|
||||
|
||||
When the gyro is used for this drive base, this gives the gyro angle.
|
||||
Otherwise, it gives the estimated angle estimated from the motor
|
||||
displacement.
|
||||
|
||||
Returns:
|
||||
Accumulated angle since last reset.
|
||||
"""
|
||||
@@ -115,6 +125,10 @@ class DriveBase:
|
||||
|
||||
Gets the state of the robot.
|
||||
|
||||
As with the :meth:`.angle` methods, the reported angle and turn rate
|
||||
are those of the gyro if the gyro is used. Otherwise they are
|
||||
estimated from the motor displacement.
|
||||
|
||||
Returns:
|
||||
Tuple of distance, drive speed, angle, and turn rate of the robot.
|
||||
"""
|
||||
@@ -129,26 +143,29 @@ class DriveBase:
|
||||
calling this method will `also` set the gyro to the given angle.
|
||||
|
||||
Arguments:
|
||||
distance (Number, mm): Speed of the robot.
|
||||
angle (Number, deg): Heading angle of the robot.
|
||||
distance (Number, mm): New value of the driven distance.
|
||||
angle (Number, deg): New heading angle of the robot.
|
||||
"""
|
||||
|
||||
@overload
|
||||
def settings(
|
||||
self,
|
||||
straight_speed: Optional[Number] = None,
|
||||
straight_acceleration: Optional[Number] = None,
|
||||
straight_acceleration: Optional[Union[Number, Tuple[Number, Number]]] = None,
|
||||
turn_rate: Optional[Number] = None,
|
||||
turn_acceleration: Optional[Number] = None,
|
||||
turn_acceleration: Optional[Union[Number, Tuple[Number, Number]]] = None,
|
||||
) -> None: ...
|
||||
|
||||
@overload
|
||||
def settings(self) -> Tuple[int, int, int, int]: ...
|
||||
def settings(
|
||||
self,
|
||||
) -> Tuple[int, Union[int, Tuple[int, int]], int, Union[int, Tuple[int, int]]]: ...
|
||||
|
||||
def settings(self, *args):
|
||||
"""
|
||||
settings(straight_speed, straight_acceleration, turn_rate, turn_acceleration)
|
||||
settings() -> Tuple[int, int, int, int]
|
||||
settings() -> Tuple[int, Tuple[int, int], int, Tuple[int, int]]
|
||||
|
||||
Configures the drive base speed and acceleration.
|
||||
|
||||
@@ -161,15 +178,22 @@ class DriveBase:
|
||||
The speed values given here do not apply to the :meth:`.drive` method,
|
||||
since you provide your own speed values as arguments in that method.
|
||||
|
||||
Speed and rate values are treated as absolute; negative values are
|
||||
converted to positive automatically.
|
||||
|
||||
Arguments:
|
||||
straight_speed (Number, mm/s): Straight-line speed of the robot.
|
||||
straight_acceleration (Number, mm/s²): Straight-line
|
||||
acceleration and deceleration of the robot. Provide a tuple with
|
||||
two values to set acceleration and deceleration separately.
|
||||
straight_acceleration (Number or Tuple[Number, Number], mm/s²):
|
||||
Straight-line acceleration and deceleration of the robot.
|
||||
Provide a single value to use the same acceleration and
|
||||
deceleration. Provide a tuple with two values to set them
|
||||
separately.
|
||||
turn_rate (Number, deg/s): Turn rate of the robot.
|
||||
turn_acceleration (Number, deg/s²): Angular acceleration and
|
||||
deceleration of the robot. Provide a tuple with
|
||||
two values to set acceleration and deceleration separately.
|
||||
turn_acceleration (Number or Tuple[Number, Number], deg/s²):
|
||||
Angular acceleration and deceleration of the robot.
|
||||
Provide a single value to use the same acceleration and
|
||||
deceleration. Provide a tuple with two values to set them
|
||||
separately.
|
||||
"""
|
||||
|
||||
def straight(
|
||||
@@ -187,9 +211,13 @@ class DriveBase:
|
||||
"""
|
||||
|
||||
def turn(
|
||||
self, angle: Number, then: Stop = Stop.HOLD, wait: bool = True
|
||||
self,
|
||||
angle: Number,
|
||||
then: Stop = Stop.HOLD,
|
||||
wait: bool = True,
|
||||
absolute: bool = False,
|
||||
) -> MaybeAwaitable:
|
||||
"""turn(angle, then=Stop.HOLD, wait=True)
|
||||
"""turn(angle, then=Stop.HOLD, wait=True, absolute=False)
|
||||
|
||||
Turns in place by a given angle and then stops.
|
||||
|
||||
@@ -198,6 +226,9 @@ class DriveBase:
|
||||
then (Stop): What to do after coming to a standstill.
|
||||
wait (bool): Wait for the maneuver to complete before continuing
|
||||
with the rest of the program.
|
||||
absolute (bool): If ``False`` (default), the robot turns _by_ the
|
||||
given angle relative to its current heading. If ``True``,
|
||||
the robot turns to the given absolute heading angle.
|
||||
"""
|
||||
|
||||
def arc(
|
||||
@@ -270,6 +301,26 @@ class DriveBase:
|
||||
``True`` if the drive base is stalled, ``False`` if not.
|
||||
"""
|
||||
|
||||
def move_by(self, dx: Number, dy: Number, then: Stop = Stop.HOLD) -> MaybeAwaitable:
|
||||
"""move_by(dx, dy, then=Stop.HOLD)
|
||||
|
||||
Moves the robot by an amount given as X-and-Y coordinates on the robot
|
||||
drive area. The X-axis is what was forward when the program started.
|
||||
The Y-axis is 90° left of that. You can reset this by resetting the heading.
|
||||
|
||||
The robot first turns to the required heading and then drives the
|
||||
straight-line distance. Because the heading target is absolute, the
|
||||
result is independent of the robot's current heading.
|
||||
|
||||
Arguments:
|
||||
dx (Number, mm): X-distance on the drive area.
|
||||
dy (Number, mm): Y-distance on the drive area.
|
||||
then (Stop): What to do after coming to a standstill.
|
||||
|
||||
Raises:
|
||||
ValueError: If one of the distances is more than 30 m.
|
||||
"""
|
||||
|
||||
def use_gyro(self, use_gyro: bool) -> None:
|
||||
"""use_gyro(use_gyro)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user