Compare commits

...
Author SHA1 Message Date
David Lechner 784c7ec5fc jedi: v1.9.0
Update pybricks package for next beta.
2023-05-16 15:43:09 -05:00
David Lechner 9e2bac457a github/workflows/publish-ide-docs: poetry install --only=doc
We don't need to install other dependencies to build the docs.
2023-05-16 15:39:14 -05:00
David Lechner 61d18ebe6f @pybricks/ide-docs v2.9.0 2023-05-16 15:33:45 -05:00
David Lechner ff0b767e3e v3.3.0a5 2023-05-16 15:27:22 -05:00
David Lechner 3274cef849 pybricks.common: Add new BLE class.
This adds a new BLE class that is used for connectionless broadcasting/
observing on hubs with built-in Bluetooth Low Energy.

Also see https://github.com/pybricks/pybricks-micropython/pull/158.
2023-05-16 14:46:53 -05:00
David Lechner b4ff3af36d pyproject: split lint and doc dependencies
This allows a subset of dependencies to be installed if needed and
allows sharing requirements with readthedocs.
2023-05-10 14:35:08 -05:00
David Lechner 8e5891d9e8 all: spelling
Misc spelling fixes.
2023-05-10 14:16:15 -05:00
David Lechner 7de67852f7 vscode: change to ms-python.black-formatter
Microsoft is breaking out various Python tools into separate extensions.
2023-05-10 13:43:49 -05:00
David Lechner 31d3a117d6 doc/main/conf: update copyright year 2023-04-21 17:39:28 -05:00
David Lechner 263fe3a1cb npm/jedi: v1.8.0 2023-04-21 17:31:17 -05:00
David Lechner db8de447d5 jedi: v1.8.0 2023-04-21 17:26:38 -05:00
David Lechner 46d6189eb1 jedi: update pybricks package version
also bump python requirement since Pyodide is now using Python 3.11.
2023-04-21 17:24:47 -05:00
David Lechner 2278c7bcda @pybricks/ide-docs v2.8.0 2023-04-21 17:10:51 -05:00
David Lechner 4da3618428 v3.3.0b4 2023-04-21 17:00:18 -05:00
Laurens Valk 5bc11b185d pybricks.tools: Add versionchanged note. 2023-04-21 14:07:46 +02:00
Laurens Valk be9f99d41b pybricks.tools: Add category headings. 2023-04-21 13:59:16 +02:00
Laurens Valk 870aae83c0 pybricks.tools: Document cross product. 2023-04-21 13:39:08 +02:00
Laurens Valk 9cde749e8a pybricks.geometry: Drop module.
See https://github.com/pybricks/pybricks-micropython/pull/160
2023-04-21 13:33:19 +02:00
Laurens Valk 8bca5eb6e4 pybricks.robotics: Add GyroDriveBase. 2023-04-21 10:42:30 +02:00
Laurens Valk 95a12a7386 pybricks.robotics: Drop note suggesting to flip motors.
This will still work, but it is asking for trouble when including the gyro.

So it is probably better not to mention this at all.
2023-04-21 10:42:30 +02:00
Laurens Valk d6c78f1f39 pybricks.robotics: Drop note restricting when to change settings. 2023-04-21 10:42:30 +02:00
Laurens Valk 98f2bb27fe pybricks.robotics.DriveBase: Drop positive direction.
This reverts commit e4650cb1c9.

This is not needed for gyro support, so it is better to remove it
before it is ever released.
2023-04-21 10:42:30 +02:00
Laurens Valk fdbd078388 pybricks._common.IMU: Heading is clockwise positive.
This is not a breaking change because heading() was never implemented until now.
2023-04-21 10:42:30 +02:00
Laurens Valk ccd2b46819 pybricks.robotics.DriveBase: Revert gyro use via init.
This reverts commit dadaab6f61.

We will introduce a separate class instead.
2023-04-21 10:42:30 +02:00
Laurens Valk c0cb05dd74 pybricks.robotics.DriveBase: Document use of gyro. 2023-04-21 10:42:30 +02:00
Laurens Valk b183e1420a pybricks.pupdevices.Motor: Document speed time window. 2023-04-21 10:42:30 +02:00
Laurens Valk b311c54261 pybricks._common.IMU: Change settings setter. 2023-04-21 10:42:30 +02:00
Laurens Valk bb37b94f5e pybricks._common.IMU: Add imu status. 2023-04-21 10:42:30 +02:00
Laurens Valk 5b25606afa pybricks._common.IMU: Add rotation and orientation.
Also update implementation status for heading and reset_heading.
2023-04-21 10:42:30 +02:00
Laurens Valk 8172d11ef6 urandom: Fix formula in getrandbits. 2023-03-28 08:50:00 +02:00
Laurens Valk c415296b71 pybricks._common.Motor: Document profile.
Fixes https://github.com/pybricks/support/issues/966
2023-03-20 15:12:36 +01:00
Laurens Valk e4650cb1c9 pybricks.robotics.DriveBase: Document positive direction.
Fixes https://github.com/pybricks/support/issues/992
2023-03-20 14:22:25 +01:00
Laurens Valk 91154a394c pybricks.robotics.DriveBase: Clarify settings method.
Fixes https://github.com/pybricks/support/issues/882
2023-03-20 14:00:42 +01:00
David Lechner 3c36010c04 pybricks.ev3devices: Fix Gyro direction parameter name.
The actual implemented name is `direction`, not `positive_direction`.

Fixes: https://github.com/pybricks/support/issues/509
2023-03-20 13:56:16 +01:00
Laurens Valk a553df3b03 pybricks.iodevices.PUPDevice: Add device class as comments. 2023-02-23 16:31:38 +01:00
Hans Willemen dbd1cc8dc9 pybricks.iodevices.PUPDevice: Add more devices.
Added:
- non-uart DCMotors  (Medium and Train)
- non-uart Light
- SPIKE 3x3 Color Matrix
- SPIKE Small Angular Motor
2023-02-23 16:31:38 +01:00
Laurens Valk b40c3989aa pybricks.common.Motor: Add Model() class instance.
This is mainly used to debug the motor model, and to quickly select the
feedback parameters. This is useful when adding or configuring new motor
types.

Reading the estimated speed can also be useful in advanced applications
where the user builds their own PID controller.

We may choose to hide this method from the documentation before the
release.
2023-02-09 10:25:15 +01:00
Laurens Valk 13612bdb1a README: Fix D002 Trailing whitespace. 2023-02-09 10:25:10 +01:00
kai-morich 031e905e12 README: document stub usage in vs code
Fixes: pybricks/support#937
2023-02-07 15:37:15 -06:00
Laurens Valk 428bca79ab pybricks.common.Control: Document deadzone. 2023-02-02 14:45:34 +01:00
Laurens Valk 0e8b6cfd97 doc/main/cad/devices: Generate motor model. 2023-02-02 14:44:50 +01:00
David Lechner eea8ff0924 examples/ev3/bluetooth: remove 3rd party dependency
Since Python 3.10, RFCOMM sockets are available in Python on Windows
so we no longer need 3rd party code.

Fixes: pybricks/support#902
2023-01-06 14:17:29 -06:00
David Lechner 8c673ab280 github: update actions/checkout to v3
This fixes deprecation warnings about node v12.
2022-12-28 16:16:01 -06:00
David Lechner 73477169ae npm/jedi: v1.7.0
Update pybricks_jedi package to v1.7.0 and bump version for release.
2022-12-28 16:13:28 -06:00
David Lechner 5ccc60c177 jedi/pyproject: v1.7.0 2022-12-28 16:09:37 -06:00
David Lechner 93c4fcc884 jedi: add update_user_modules() function
This function will be used to fix import completion of user module
names in Pybricks Code.

Issue: https://github.com/pybricks/support/issues/759
2022-12-28 16:06:47 -06:00
David Lechner aa72605e99 jedi: fix code completion for local _*
This fixes code completion for identifier names starting with "_" in
the local ("__main__") file.
2022-12-28 15:33:33 -06:00
David Lechner 8ee725722f jedi: fix completion of builtin types
Completions for `x.` where `x` is an instance of a builtin type was
broken because of filtering on the `builtins` modules. This extends
the filtering to allow attributes available on common builtin types
in Pybricks MicroPython.
2022-12-28 15:33:33 -06:00
David Lechner 236bda5f31 ubuiltins.round: Fix example.
The example did not have proper line breaks between statements.

Also add an additional example using f-strings.
2022-12-28 14:09:18 -06:00
David Lechner 36ee3bd9ef pyproject: v3.2.0 2022-12-20 15:46:44 -06:00
David Lechner 16a0621e03 @pybricks/ide-docs v2.7.0 2022-12-20 11:05:36 -06:00
Laurens Valk 7c4c5439a4 pyproject: v3.2.0c2 2022-12-20 16:08:48 +01:00
David Lechner f7314bc1bc npm/images: v1.3.0
Bump version for release to npm.
2022-12-19 11:16:57 -06:00
David Lechner f14bbc3a36 npm/images: add DFU Windows driver images
This will be used in Pybricks Code for Windows driver installation
instructions.
2022-12-19 11:15:37 -06:00
Laurens Valk 44c6191b2f doc/main/diagrams_source: Add labels to DFU screenshots. 2022-12-19 10:55:20 -06:00
Laurens Valk 829b0ab97a doc/main/diagrams_source: Draft DFU screenshots. 2022-12-19 10:55:20 -06:00
Laurens Valk 1c5e390e13 doc/main/index: Clarify categories.
This is more descriptive than just repeating the module name.
2022-12-16 22:30:09 +01:00
David Lechner 98e7d814b1 npm/jedi/build: update @pybricks/jedi package version to v1.6.0
Update version for release to npm.
2022-12-09 15:28:11 -06:00
David Lechner 0117e50599 npm/jedi/build: update pybricks-jedi Python package to v1.6.0 2022-12-09 15:26:57 -06:00
122 changed files with 4710 additions and 1317 deletions
+3 -11
View File
@@ -6,7 +6,7 @@ name: Build Python package and docs
on:
push:
tags-ignore:
- "*"
- '**'
pull_request:
paths:
- doc/**
@@ -20,19 +20,11 @@ on:
jobs:
build:
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: [3.8, 3.9]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install poetry
+5 -5
View File
@@ -7,17 +7,17 @@ on:
jobs:
publish_ide_docs:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Ubuntu packages
run: |
sudo apt-get update
sudo apt-get install -y dvisvgm preview-latex-style texlive texlive-fonts-extra texlive-latex-extra
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Set up Python 3.8
uses: actions/setup-python@v1
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Install dependencies
@@ -25,8 +25,8 @@ jobs:
pip install poetry
poetry run python -m pip install --upgrade pip
poetry run python -m pip install --upgrade setuptools
poetry install
- uses: actions/setup-node@v1
poetry install --only=doc
- uses: actions/setup-node@v3
with:
node-version: '14.x'
registry-url: 'https://registry.npmjs.org'
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
publish_jedi:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
# Setup .npmrc file to publish to npm
- uses: actions/setup-node@v3
with:
+26
View File
@@ -0,0 +1,26 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
build:
os: "ubuntu-22.04"
tools:
python: "3.10"
jobs:
post_create_environment:
- pip install poetry
- poetry config virtualenvs.create false
post_install:
- poetry install --only=doc
# Build documentation in the doc/main/ directory with Sphinx
sphinx:
configuration: doc/main/conf.py
fail_on_warning: true
# Optionally build your docs in additional formats such as PDF
formats:
- pdf
+2 -1
View File
@@ -4,7 +4,8 @@
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"ms-python.python"
"ms-python.python",
"ms-python.black-formatter"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
+2 -2
View File
@@ -4,14 +4,14 @@
},
"python.defaultInterpreterPath": ".venv/bin/python",
"python.autoComplete.extraPaths": ["jedi/src"],
"python.formatting.provider": "black",
"python.formatting.provider": "none",
"python.linting.pylintEnabled": false,
"python.linting.flake8Enabled": true,
"python.linting.pycodestyleEnabled": false,
"python.linting.enabled": true,
"[python]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "ms-python.python"
"editor.defaultFormatter": "ms-python.black-formatter"
},
"python.languageServer": "Pylance",
"python.testing.pytestArgs": [
+29
View File
@@ -4,6 +4,35 @@
## Unreleased
## 3.3.0b5 - 2023-05-16
### Added
- Documented new `hub.ble` methods.
## 3.3.0b4 - 2023-04-21
### Added
- Documented `integral_deadzone` in `Control.pid()`.
- Documented `Motor.model`. This can be used to view the estimated motor
state and change its settings.
- Added `rotation`, `orientation`, `ready`, `stationary` and `settings` methods
to `IMU` class.
- Added `GyroDriveBase` class to `pybricks.robotics`.
### Changed
- Change implementation status of `IMU.heading` and `IMU.reset_heading`. They
are now implemented, with some limitations as noted in a note box.
- Moved `Matrix` and `vector` from `pybricks.geometry` to `pybricks.tools`.
- Moved `Axis` from `pybricks.geometry` to `pybricks.parameters`.
### Removed
- Removed `pybricks.geometry` module.
## 3.2.0 - 2022-12-20
### Changed
- Changed module TOC headings to make it easier to find things.
## 3.2.0c1 - 2022-12-09
### Changed
+5
View File
@@ -12,6 +12,11 @@ used to generate the `official documentation`_.
See the `contributor's guide <CONTRIBUTING.md>`_ for acceptable changes and
instructions to build the documentation locally.
You can use the API stubs in this repository for syntax highlighting and code
completion when programming the EV3 with VS Code. To enable, remove the
``"python.languageServer"="None"`` line in the ``.vscode/settings.json`` file
generated by the *LEGO® MINDSTORMS® EV3 MicroPython* extension.
For general discussion, please visit the `support`_ issue tracker.
.. _Pybricks package: pybricks
+2 -1
View File
@@ -321,10 +321,11 @@ def on_missing_reference(
app.builder, node["refdoc"], "signaltypes", "numbers", contnode
)
# References with special characters can't exist, so we have to supress
# References with special characters can't exist, so we have to suppress
# warnings when Sphinx tries to cross reference units like deg/s. For
# consistency, we also treat units without special characters this way.
for unit in [
"dBm",
"deg",
"deg/s",
"deg/s²",
+4 -5
View File
@@ -10,7 +10,6 @@ FEATURES_SMALL = set()
# Medium feature set.
FEATURES_MEDIUM = FEATURES_SMALL | {
"pybricks-geometry",
"pybricks-common-control",
"pybricks-iodevices",
"stm32-extra",
@@ -24,10 +23,10 @@ FEATURES_LARGE = FEATURES_MEDIUM | set()
HUB_FEATURES = {
"movehub": {"movehub"} | FEATURES_SMALL,
"cityhub": {"cityhub"} | FEATURES_MEDIUM,
"technichub": {"technichub"} | FEATURES_MEDIUM,
"primehub": {"primehub", "inventorhub", "light-matrix"} | FEATURES_LARGE,
"inventorhub": {"primehub", "inventorhub", "light-matrix"} | FEATURES_LARGE,
"essentialhub": {"essentialhub"} | FEATURES_LARGE,
"technichub": {"technichub", "gyro"} | FEATURES_MEDIUM,
"primehub": {"primehub", "inventorhub", "light-matrix", "gyro"} | FEATURES_LARGE,
"inventorhub": {"primehub", "inventorhub", "light-matrix", "gyro"} | FEATURES_LARGE,
"essentialhub": {"essentialhub", "gyro"} | FEATURES_LARGE,
}
+1169 -6
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -8,7 +8,7 @@ import sys
# General information about the project.
project = "pybricks"
copyright = "2018-2021 The Pybricks Authors"
copyright = "2018-2023 The Pybricks Authors"
author = ""
_TITLE = "Pybricks Modules and Examples"
@@ -29,7 +29,7 @@ if os.environ.get("READTHEDOCS", None) == "True":
# HACK: this allows Number type alias to be imported by Sphinx
os.environ["SPHINX_BUILD"] = "True"
# Addtional configuration of the IDE docs
# Additional configuration of the IDE docs
if "ide" in tags.tags: # noqa F821
_DISCLAIMER = ""
html_show_copyright = False
@@ -45,7 +45,7 @@ if "ide" in tags.tags: # noqa F821
exec(open(os.path.abspath("../common/conf.py")).read())
# Addtional configuration of the IDE docs
# Additional configuration of the IDE docs
if "ide" in tags.tags: # noqa F821
extensions.remove("sphinx.ext.mathjax") # noqa F821
Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

@@ -0,0 +1,224 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_1_open_device_manager.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6">
<marker
style="overflow:visible;"
id="marker3510"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow2Mend"
inkscape:isstock="true">
<path
transform="scale(0.6) rotate(180) translate(0,0)"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
style="stroke:context-stroke;fill-rule:evenodd;fill:context-stroke;stroke-width:0.62500000;stroke-linejoin:round;"
id="path3508" />
</marker>
<marker
style="overflow:visible;"
id="marker3500"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Mend"
inkscape:isstock="true">
<path
transform="scale(0.4) rotate(180) translate(10,0)"
style="fill-rule:evenodd;fill:context-stroke;stroke:context-stroke;stroke-width:1.0pt;"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path3498" />
</marker>
<marker
style="overflow:visible;"
id="marker3216"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow2Mend"
inkscape:isstock="true">
<path
transform="scale(0.6) rotate(180) translate(0,0)"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
style="stroke:context-stroke;fill-rule:evenodd;fill:context-stroke;stroke-width:0.62500000;stroke-linejoin:round;"
id="path3214" />
</marker>
<marker
style="overflow:visible;"
id="marker3206"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Mend"
inkscape:isstock="true">
<path
transform="scale(0.4) rotate(180) translate(10,0)"
style="fill-rule:evenodd;fill:context-stroke;stroke:context-stroke;stroke-width:1.0pt;"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path3204" />
</marker>
<marker
style="overflow:visible;"
id="Arrow2Mend"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow2Mend"
inkscape:isstock="true">
<path
transform="scale(0.6) rotate(180) translate(0,0)"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
style="stroke:context-stroke;fill-rule:evenodd;fill:context-stroke;stroke-width:0.62500000;stroke-linejoin:round;"
id="path1221" />
</marker>
<marker
style="overflow:visible;"
id="marker1668"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Lend"
inkscape:isstock="true">
<path
transform="scale(0.8) rotate(180) translate(12.5,0)"
style="fill-rule:evenodd;fill:context-stroke;stroke:context-stroke;stroke-width:1.0pt;"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path1666" />
</marker>
<marker
style="overflow:visible;"
id="marker1658"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Lend"
inkscape:isstock="true">
<path
transform="scale(0.8) rotate(180) translate(12.5,0)"
style="fill-rule:evenodd;fill:context-stroke;stroke:context-stroke;stroke-width:1.0pt;"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path1656" />
</marker>
<marker
style="overflow:visible;"
id="marker1648"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Send"
inkscape:isstock="true">
<path
transform="scale(0.2) rotate(180) translate(6,0)"
style="fill-rule:evenodd;fill:context-stroke;stroke:context-stroke;stroke-width:1.0pt;"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path1646" />
</marker>
<marker
style="overflow:visible;"
id="Arrow1Mend"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Mend"
inkscape:isstock="true">
<path
transform="scale(0.4) rotate(180) translate(10,0)"
style="fill-rule:evenodd;fill:context-stroke;stroke:context-stroke;stroke-width:1.0pt;"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path1203" />
</marker>
<marker
style="overflow:visible;"
id="Arrow1Send"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Send"
inkscape:isstock="true">
<path
transform="scale(0.2) rotate(180) translate(6,0)"
style="fill-rule:evenodd;fill:context-stroke;stroke:context-stroke;stroke-width:1.0pt;"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path1209" />
</marker>
<marker
style="overflow:visible;"
id="Arrow1Lend"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Lend"
inkscape:isstock="true">
<path
transform="scale(0.8) rotate(180) translate(12.5,0)"
style="fill-rule:evenodd;fill:context-stroke;stroke:context-stroke;stroke-width:1.0pt;"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path1197" />
</marker>
<marker
style="overflow:visible;"
id="Arrow2Lend"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow2Lend"
inkscape:isstock="true">
<path
transform="scale(1.1) rotate(180) translate(1,0)"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
style="stroke:context-stroke;fill-rule:evenodd;fill:context-stroke;stroke-width:0.62500000;stroke-linejoin:round;"
id="path1215" />
</marker>
</defs>
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.9044027"
inkscape:cx="133.37515"
inkscape:cy="178.79622"
inkscape:window-width="1856"
inkscape:window-height="1136"
inkscape:window-x="64"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_1_open_device_manager.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4543"
width="282"
height="42"
x="6.4999995"
y="152.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_2_large_hub_open_properties.png"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6">
<marker
style="overflow:visible;"
id="Arrow1Mend"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Mend"
inkscape:isstock="true">
<path
transform="scale(0.4) rotate(180) translate(10,0)"
style="fill-rule:evenodd;fill:context-stroke;stroke:context-stroke;stroke-width:1.0pt;"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path4580" />
</marker>
</defs>
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.3235797"
inkscape:cx="382.29658"
inkscape:cy="262.92334"
inkscape:window-width="1920"
inkscape:window-height="1163"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_2_large_hub_open_properties.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4543"
width="245"
height="39"
x="339.5"
y="438.5" />
<path
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 362.36628,258.14936 -44.35771,68.2069"
id="path868"
sodipodi:nodetypes="cc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_2_small_hub_open_properties.png"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6">
<marker
style="overflow:visible;"
id="Arrow1Mend"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Mend"
inkscape:isstock="true">
<path
transform="scale(0.4) rotate(180) translate(10,0)"
style="fill-rule:evenodd;fill:context-stroke;stroke:context-stroke;stroke-width:1.0pt;"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path4580" />
</marker>
</defs>
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.3235797"
inkscape:cx="382.29658"
inkscape:cy="262.92334"
inkscape:window-width="1920"
inkscape:window-height="1163"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_2_small_hub_open_properties.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4543"
width="245"
height="39"
x="339.5"
y="438.5" />
<path
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 362.36628,258.14936 -44.35771,68.2069"
id="path868"
sodipodi:nodetypes="cc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_3_large_hub_properties.png"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="0.92648239"
inkscape:cx="365.9001"
inkscape:cy="415.01059"
inkscape:window-width="1856"
inkscape:window-height="1136"
inkscape:window-x="64"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_3_large_hub_properties.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4543"
width="150"
height="42"
x="374.5"
y="357.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_3_small_hub_properties.png"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="0.92648239"
inkscape:cx="365.9001"
inkscape:cy="415.01059"
inkscape:window-width="1856"
inkscape:window-height="1136"
inkscape:window-x="64"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_3_small_hub_properties.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4543"
width="150"
height="42"
x="374.5"
y="357.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_4_large_hub_update_driver.png"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.1227623"
inkscape:cx="315.29381"
inkscape:cy="468.93274"
inkscape:window-width="1856"
inkscape:window-height="1136"
inkscape:window-x="64"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_4_large_hub_update_driver.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5.00001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4543"
width="497.99997"
height="99.999992"
x="53.5"
y="255.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_4_small_hub_update_driver.png"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.1227623"
inkscape:cx="315.29381"
inkscape:cy="468.93274"
inkscape:window-width="1856"
inkscape:window-height="1136"
inkscape:window-x="64"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_4_small_hub_update_driver.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5.00001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4543"
width="497.99997"
height="99.999992"
x="53.5"
y="255.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_5_large_hub_update_driver_pick.png"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.3593536"
inkscape:cx="302.34958"
inkscape:cy="207.08371"
inkscape:window-width="1856"
inkscape:window-height="1136"
inkscape:window-x="64"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_5_large_hub_update_driver_pick.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5.00001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4543"
width="535"
height="102.99999"
x="49.500004"
y="300.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_5_small_hub_update_driver_pick.png"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.3593536"
inkscape:cx="302.34958"
inkscape:cy="207.08371"
inkscape:window-width="1856"
inkscape:window-height="1136"
inkscape:window-x="64"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_5_small_hub_update_driver_pick.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5.00001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4543"
width="535"
height="102.99999"
x="49.500004"
y="300.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_6_large_hub_update_driver_select_type.png"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.1381411"
inkscape:cx="345.29989"
inkscape:cy="387.91324"
inkscape:window-width="1856"
inkscape:window-height="1136"
inkscape:window-x="64"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_6_large_hub_update_driver_select_type.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4543"
width="245"
height="22"
x="65.5"
y="289.5" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect835"
width="85"
height="32"
x="473.49997"
y="446.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_6_small_hub_update_driver_select_type.png"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.1381411"
inkscape:cx="345.29989"
inkscape:cy="387.91324"
inkscape:window-width="1856"
inkscape:window-height="1136"
inkscape:window-x="64"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_6_small_hub_update_driver_select_type.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4543"
width="245"
height="22"
x="65.5"
y="289.5" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect835"
width="85"
height="32"
x="473.49997"
y="446.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_7_large_hub_update_driver_select_driver.png"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.0044967"
inkscape:cx="222.00173"
inkscape:cy="433.55047"
inkscape:window-width="1856"
inkscape:window-height="1136"
inkscape:window-x="64"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_7_large_hub_update_driver_select_driver.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4543"
width="97"
height="25"
x="68.5"
y="297.5" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect835"
width="108"
height="25"
x="274.76102"
y="316.04642" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect835-3"
width="85"
height="32"
x="473.5"
y="446.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_7_small_hub_update_driver_select_driver.png"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.0044967"
inkscape:cx="222.00173"
inkscape:cy="433.55047"
inkscape:window-width="1856"
inkscape:window-height="1136"
inkscape:window-x="64"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_7_small_hub_update_driver_select_driver.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4543"
width="97"
height="25"
x="68.5"
y="297.5" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect835"
width="108"
height="25"
x="274.76102"
y="316.04642" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect835-3"
width="85"
height="32"
x="473.5"
y="446.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_8_update_driver_warning.png"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.0295191"
inkscape:cx="484.6923"
inkscape:cy="365.70471"
inkscape:window-width="1856"
inkscape:window-height="1136"
inkscape:window-x="64"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_8_update_driver_warning.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect835"
width="85"
height="32"
x="363.5"
y="298.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_9_large_hub_update_driver_done.png"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.374761"
inkscape:cx="336.78581"
inkscape:cy="261.5"
inkscape:window-width="1856"
inkscape:window-height="1136"
inkscape:window-x="64"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_9_large_hub_update_driver_done.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect835-3"
width="85"
height="32"
x="555.5"
y="446.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="673"
height="523"
viewBox="0 0 673 523"
sodipodi:docname="dfu_windows_9_small_hub_update_driver_done.png"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
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">
<defs
id="defs6" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.374761"
inkscape:cx="336.78581"
inkscape:cy="261.5"
inkscape:window-width="1856"
inkscape:window-height="1136"
inkscape:window-x="64"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="673"
height="523"
preserveAspectRatio="none"
xlink:href="dfu_windows_9_small_hub_update_driver_done.png"
id="image10" />
<rect
style="fill:none;stroke:#ce4e00;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect835-3"
width="85"
height="32"
x="555.5"
y="446.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

+2 -2
View File
@@ -20,12 +20,12 @@ Motors
.. rubric:: Measuring
.. automethod:: pybricks.ev3devices.Motor.speed
.. automethod:: pybricks.ev3devices.Motor.angle
.. automethod:: pybricks.ev3devices.Motor.reset_angle
.. automethod:: pybricks.ev3devices.Motor.speed
.. automethod:: pybricks.ev3devices.Motor.load
.. automethod:: pybricks.ev3devices.Motor.stalled
-51
View File
@@ -1,51 +0,0 @@
.. pybricks-requirements:: stm32-float
:mod:`geometry <pybricks.geometry>` -- Geometry and algebra
============================================================
.. module:: pybricks.geometry
.. autoclass:: pybricks.geometry.Matrix
:no-members:
.. autoattribute:: pybricks.geometry::Matrix.T
.. autoattribute:: pybricks.geometry::Matrix.shape
.. autofunction:: pybricks.geometry.vector
.. autoclass:: pybricks.geometry.Axis
:no-members:
.. _robotframe:
Reference frames
-----------------------
The Pybricks module and this documentation use the following conventions:
- X: Positive means forward. Negative means backward.
- Y: Positive means to the left. Negative means to the right.
- Z: Positive means upward. Negative means downward.
To make sure that all hub measurements (such as acceleration) have the correct
value and sign, you can specify how the hub is mounted in your creation. This
adjust the measurements so that it is easy to see how your *robot* is moving,
rather than how the *hub* is moving.
For example, the hub may be mounted upside down in your design. If you
configure the settings as shown in :numref:`fig_imuexamples`, the hub
measurements will be adjusted accordingly. This way, a positive acceleration
value in the X direction means that your *robot* accelerates forward, even
though the *hub* accelerates backward.
.. _fig_imuexamples:
.. figure:: ../main/diagrams/imuexamples.png
:width: 100 %
How to configure the ``top_side`` and ``front_side`` settings for three
different robot designs. The same technique can be applied to other hubs
and other creations, by noting which way the top and
front :class:`Side <Side>` of the hub are pointing. The example
on the left is the default configuration.
+22
View File
@@ -19,6 +19,17 @@ City Hub
.. automethod:: pybricks.hubs::CityHub.light.animate
.. rubric:: Using connectionless Bluetooth messaging
``ble.broadcast()`` does not work on ``CityHub`` due to a bug in the
Bluetooth chip firmware.
.. automethod:: pybricks.hubs::CityHub.ble.observe
.. automethod:: pybricks.hubs::CityHub.ble.signal_strength
.. automethod:: pybricks.hubs::CityHub.ble.version
.. rubric:: Using the battery
.. automethod:: pybricks.hubs::CityHub.battery.voltage
@@ -70,6 +81,17 @@ Creating light animations
.. literalinclude::
../../../examples/pup/hub_common/build/light_animate_cityhub.py
Bluetooth examples
------------------
Observing data from other hubs
******************************
.. literalinclude::
../../../examples/pup/hub_common/build/ble_observe_cityhub.py
Button and system examples
----------------------------------
+37
View File
@@ -25,6 +25,10 @@ Essential Hub
.. rubric:: Using the IMU
.. automethod:: pybricks.hubs::EssentialHub.imu.ready
.. automethod:: pybricks.hubs::EssentialHub.imu.stationary
.. automethod:: pybricks.hubs::EssentialHub.imu.up
.. automethod:: pybricks.hubs::EssentialHub.imu.tilt
@@ -37,6 +41,22 @@ Essential Hub
.. automethod:: pybricks.hubs::EssentialHub.imu.reset_heading
.. automethod:: pybricks.hubs::EssentialHub.imu.rotation
.. automethod:: pybricks.hubs::EssentialHub.imu.orientation
.. automethod:: pybricks.hubs::EssentialHub.imu.settings
.. rubric:: Using connectionless Bluetooth messaging
.. automethod:: pybricks.hubs::EssentialHub.ble.broadcast
.. automethod:: pybricks.hubs::EssentialHub.ble.observe
.. automethod:: pybricks.hubs::EssentialHub.ble.signal_strength
.. automethod:: pybricks.hubs::EssentialHub.ble.version
.. rubric:: Using the battery
.. automethod:: pybricks.hubs::EssentialHub.battery.voltage
@@ -126,6 +146,23 @@ 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
----------------------------------
+2 -2
View File
@@ -1,7 +1,7 @@
.. pybricks-requirements::
:mod:`hubs <pybricks.hubs>` -- Programmable hubs
================================================
:mod:`hubs <pybricks.hubs>` -- Built-in hub functions
=====================================================
.. module:: pybricks.hubs
+27
View File
@@ -31,6 +31,16 @@ Move Hub
Changed acceleration units from m/s² to mm/s².
.. rubric:: Using connectionless Bluetooth messaging
.. automethod:: pybricks.hubs::MoveHub.ble.broadcast
.. automethod:: pybricks.hubs::MoveHub.ble.observe
.. automethod:: pybricks.hubs::MoveHub.ble.signal_strength
.. automethod:: pybricks.hubs::MoveHub.ble.version
.. rubric:: Using the battery
.. automethod:: pybricks.hubs::MoveHub.battery.voltage
@@ -85,6 +95,23 @@ 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
----------------------------------
+37
View File
@@ -59,6 +59,10 @@ Prime Hub / Inventor Hub
.. rubric:: Using the IMU
.. automethod:: pybricks.hubs::PrimeHub.imu.ready
.. automethod:: pybricks.hubs::PrimeHub.imu.stationary
.. automethod:: pybricks.hubs::PrimeHub.imu.up
.. automethod:: pybricks.hubs::PrimeHub.imu.tilt
@@ -71,6 +75,12 @@ Prime Hub / Inventor Hub
.. automethod:: pybricks.hubs::PrimeHub.imu.reset_heading
.. automethod:: pybricks.hubs::PrimeHub.imu.rotation
.. automethod:: pybricks.hubs::PrimeHub.imu.orientation
.. automethod:: pybricks.hubs::PrimeHub.imu.settings
.. rubric:: Using the speaker
.. automethod:: pybricks.hubs::PrimeHub.speaker.volume
@@ -79,6 +89,16 @@ Prime Hub / Inventor Hub
.. automethod:: pybricks.hubs::PrimeHub.speaker.play_notes
.. rubric:: Using connectionless Bluetooth messaging
.. automethod:: pybricks.hubs::PrimeHub.ble.broadcast
.. automethod:: pybricks.hubs::PrimeHub.ble.observe
.. automethod:: pybricks.hubs::PrimeHub.ble.signal_strength
.. automethod:: pybricks.hubs::PrimeHub.ble.version
.. rubric:: Using the battery
.. automethod:: pybricks.hubs::PrimeHub.battery.voltage
@@ -237,6 +257,23 @@ 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
----------------------------------
+37
View File
@@ -21,6 +21,10 @@ Technic Hub
.. rubric:: Using the IMU
.. automethod:: pybricks.hubs::TechnicHub.imu.ready
.. automethod:: pybricks.hubs::TechnicHub.imu.stationary
.. automethod:: pybricks.hubs::TechnicHub.imu.up
.. automethod:: pybricks.hubs::TechnicHub.imu.tilt
@@ -33,6 +37,22 @@ Technic Hub
.. automethod:: pybricks.hubs::TechnicHub.imu.reset_heading
.. automethod:: pybricks.hubs::TechnicHub.imu.rotation
.. automethod:: pybricks.hubs::TechnicHub.imu.orientation
.. automethod:: pybricks.hubs::TechnicHub.imu.settings
.. rubric:: Using connectionless Bluetooth messaging
.. automethod:: pybricks.hubs::TechnicHub.ble.broadcast
.. automethod:: pybricks.hubs::TechnicHub.ble.observe
.. automethod:: pybricks.hubs::TechnicHub.ble.signal_strength
.. automethod:: pybricks.hubs::TechnicHub.ble.version
.. rubric:: Using the battery
.. automethod:: pybricks.hubs::TechnicHub.battery.voltage
@@ -118,6 +138,23 @@ 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
----------------------------------
-1
View File
@@ -60,7 +60,6 @@ above to reveal this menu.
parameters/index
tools/index
robotics
geometry
signaltypes
.. toctree::
+2 -2
View File
@@ -1,6 +1,6 @@
.. pybricks-requirements:: pybricks-iodevices
:mod:`iodevices <pybricks.iodevices>` -- Generic I/O devices
:mod:`iodevices <pybricks.iodevices>` -- Custom devices
============================================================
.. module:: pybricks.iodevices
@@ -12,7 +12,7 @@
pupdevice
lwp3device
This module has classes for generic input/output devices.
This module has classes for generic and custom input/output devices.
.. pybricks-classlink:: PUPDevice
+1 -1
View File
@@ -38,7 +38,7 @@ Powers and logarithms
.. autofunction:: umath.sqrt
Trigonomety
Trigonometry
-------------------------------
.. autodata:: umath.pi
+7
View File
@@ -0,0 +1,7 @@
.. pybricks-requirements:: stm32-float
Axis
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: pybricks.parameters.Axis
:no-members:
+3
View File
@@ -10,6 +10,7 @@
:maxdepth: 1
:hidden:
axis
button
color
direction
@@ -18,6 +19,8 @@
side
stop
.. pybricks-classlink:: Axis
.. pybricks-classlink:: Button
.. pybricks-classlink:: Color
+2 -2
View File
@@ -1,7 +1,7 @@
.. pybricks-requirements::
:mod:`pupdevices <pybricks.pupdevices>` -- Powered Up devices
=============================================================
:mod:`pupdevices <pybricks.pupdevices>` -- Motors, sensors, lights
==================================================================
.. automodule:: pybricks.pupdevices
:no-members:
+10 -2
View File
@@ -18,12 +18,12 @@ Motors with rotation sensors
.. rubric:: Measuring
.. automethod:: pybricks.pupdevices.Motor.speed
.. automethod:: pybricks.pupdevices.Motor.angle
.. automethod:: pybricks.pupdevices.Motor.reset_angle
.. automethod:: pybricks.pupdevices.Motor.speed
.. automethod:: pybricks.pupdevices.Motor.load
.. automethod:: pybricks.pupdevices.Motor.stalled
@@ -93,6 +93,14 @@ Motors with rotation sensors
The :meth:`done`, :meth:`stalled` and :meth:`load` methods have been
moved.
.. pybricks-requirements:: pybricks-common-control
.. automethod:: pybricks.pupdevices.Motor.model.state
.. pybricks-requirements:: pybricks-common-control
.. automethod:: pybricks.pupdevices.Motor.model.settings
Initialization examples
-----------------------
+39 -7
View File
@@ -1,11 +1,10 @@
.. pybricks-requirements::
:mod:`robotics <pybricks.robotics>` -- Robotics
======================================================
:mod:`robotics <pybricks.robotics>` -- Robotics and drive bases
===============================================================
.. automodule:: pybricks.robotics
:no-members:
.. pybricks-requirements::
.. autoclass:: pybricks.robotics.DriveBase
:no-members:
@@ -103,9 +102,6 @@
the default speed and acceleration for straight maneuvers and turns.
Use the following attributes to adjust more advanced control settings.
You can only change the settings while the robot is stopped. This is
either before you begin driving or after you call :meth:`.stop`.
.. autoattribute:: pybricks.robotics.DriveBase.distance_control
:annotation:
@@ -116,11 +112,47 @@
The :meth:`done` and :meth:`stalled` methods have been moved.
.. pybricks-requirements:: gyro
.. class:: GyroDriveBase
This class works just like the :class:`DriveBase`, but it uses the hub's
built-in gyroscope to drive straight and turn more accurately.
If your hub is not mounted flat in your robot, make sure to specify
the ``top_side`` and ``front_side`` parameters when you initialize the
:class:`PrimeHub() <pybricks.hubs.PrimeHub>`,
:class:`InventorHub() <pybricks.hubs.PrimeHub>`,
:class:`EssentialHub() <pybricks.hubs.EssentialHub>`, or
:class:`TechnicHub() <pybricks.hubs.TechnicHub>`. This way your robot
knows which rotation to measure when turning.
The gyro in each hub is a bit different, which can cause it to be a few
degrees off for big turns, or many small turns in the same
direction. For example, you may need to use
:meth:`turn(357) <pybricks.robotics.DriveBase.turn>` or
:meth:`turn(362) <pybricks.robotics.DriveBase.turn>`
on your robot to make a full turn.
By default, this class tries to maintain the robot's position after a move
completes. This means the wheels will spin if you pick the robot up, in an
effort to maintain its heading angle. To avoid this, you can choose
``then=Stop.COAST`` in your last
:meth:`straight <pybricks.robotics.DriveBase.straight>`,
:meth:`turn <pybricks.robotics.DriveBase.turn>`, or
:meth:`curve <pybricks.robotics.DriveBase.curve>` command.
Examples
-------------------
Driving straight and turning in place
**********************************************
The following program shows the basics of driving and turning.
To use the built-in gyro, just replace the two occurrences of
:class:`DriveBase` with :class:`GyroDriveBase`.
.. literalinclude::
../../examples/pup/robotics/drivebase_basics.py
+34 -1
View File
@@ -248,7 +248,7 @@ For example, you can choose the frequency of a beep to change the pitch.
temperature: °C
---------------
Temperature is measured in degrees Celcius (°C). To convert to degrees
Temperature is measured in degrees Celsius (°C). To convert to degrees
Fahrenheit (°F) or Kelvin (K), you can use the following conversion formulas:
:math:`^{\circ}\kern1pt\!F =\kern1pt^{\circ}\kern1pt\!C \cdot \frac{9}{5} + 32`.
@@ -260,3 +260,36 @@ Fahrenheit (°F) or Kelvin (K), you can use the following conversion formulas:
hue: deg
--------------
Hue of a color (0-359 degrees).
.. _robotframe:
Reference frames
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Pybricks module and this documentation use the following conventions:
- X: Positive means forward. Negative means backward.
- Y: Positive means to the left. Negative means to the right.
- Z: Positive means upward. Negative means downward.
To make sure that all hub measurements (such as acceleration) have the correct
value and sign, you can specify how the hub is mounted in your creation. This
adjust the measurements so that it is easy to see how your *robot* is moving,
rather than how the *hub* is moving.
For example, the hub may be mounted upside down in your design. If you
configure the settings as shown in :numref:`fig_imuexamples`, the hub
measurements will be adjusted accordingly. This way, a positive acceleration
value in the X direction means that your *robot* accelerates forward, even
though the *hub* accelerates backward.
.. _fig_imuexamples:
.. figure:: ../main/diagrams/imuexamples.png
:width: 100 %
How to configure the ``top_side`` and ``front_side`` settings for three
different robot designs. The same technique can be applied to other hubs
and other creations, by noting which way the top and
front :class:`Side <Side>` of the hub are pointing. The example
on the left is the default configuration.
+24
View File
@@ -6,6 +6,9 @@
.. automodule:: pybricks.tools
:no-members:
Timing tools
---------------
.. autofunction:: wait
.. autoclass:: pybricks.tools.StopWatch
@@ -19,3 +22,24 @@
.. automethod:: pybricks.tools.StopWatch.reset
Linear algebra tools
--------------------
.. versionchanged:: 3.3
These tools were previously located in the ``pybricks.geometry`` module.
.. pybricks-requirements:: stm32-float
.. autoclass:: pybricks.tools.Matrix
:no-members:
.. autoattribute:: pybricks.tools::Matrix.T
.. autoattribute:: pybricks.tools::Matrix.shape
.. pybricks-requirements:: stm32-float
.. autofunction:: pybricks.tools.vector
.. autofunction:: pybricks.tools.cross
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env python3
from pybricks.messaging import BluetoothMailboxServer, TextMailbox
# This demo makes your PC talk to an EV3 over Bluetooth.
#
# This is identical to the EV3 server example in ../bluetooth_server
#
# The only difference is that it runs in Python3 on your computer, thanks to
# the Python3 implementation of the messaging module that is included here.
# As far as the EV3 is concerned, it thinks it just talks to an EV3 client.
#
# So, the EV3 client example needs no further modifications. The connection
# procedure is also the same as documented in the messaging module docs:
# https://docs.pybricks.com/en/latest/messaging.html
server = BluetoothMailboxServer()
mbox = TextMailbox("greeting", server)
# The server must be started before the client!
print("waiting for connection...")
server.wait_for_connection()
print("connected!")
# In this program, the server waits for the client to send the first message
# and then sends a reply.
mbox.wait()
print(mbox.read())
mbox.send("hello to you!")
+16 -56
View File
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: MIT
# Copyright (C) 2020 The Pybricks Authors
# Copyright (C) 2020,2023 The Pybricks Authors
"""
:class:`RFCOMMServer` can be used to communicate with other Bluetooth RFCOMM
@@ -10,29 +10,13 @@ remain a strict subset of that implementation when it comes to low-level
implementation details.
"""
from bluetooth import BluetoothSocket, RFCOMM
from socket import socket, AF_BLUETOOTH, BTPROTO_RFCOMM, SOCK_STREAM
from socketserver import ThreadingMixIn
BDADDR_ANY = ""
def str2ba(string, ba):
"""Convert string to Bluetooth address"""
for i, v in enumerate(string.split(":")):
ba.b[5 - i] = int(v, 16)
def ba2str(ba):
"""Convert Bluetooth address to string"""
string = []
for b in ba.b:
string.append("{:02X}".format(b))
string.reverse()
return ":".join(string).upper()
class RFCOMMServer:
"""Object that simplifies setting up an RFCOMM socket server.
"""
Object that simplifies setting up an RFCOMM socket server.
This is based on the ``socketserver.SocketServer`` class in the Python
standard library.
@@ -44,10 +28,10 @@ class RFCOMMServer:
self.server_address = server_address
self.RequestHandlerClass = RequestHandlerClass
self.socket = BluetoothSocket(RFCOMM)
self.socket = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)
try:
self.socket.bind((server_address[0], server_address[1]))
self.socket.bind(server_address)
# self.server_address = self.socket.getsockname()
self.socket.listen(self.request_queue_size)
except Exception:
@@ -83,50 +67,22 @@ class RFCOMMServer:
self.socket.close()
class StreamRequestHandler:
"""Class that handles incoming requests.
This is based on ``socketserver.StreamRequestHandler`` from the Python
standard library.
"""
def __init__(self, request, client_address, server):
self.request = request
self.client_address = client_address
self.server = server
self.setup()
try:
self.handle()
finally:
self.finish()
def setup(self):
self.wfile = self.request
self.rfile = self.request
def handle(self):
pass
def finish(self):
pass
class ThreadingRFCOMMServer(ThreadingMixIn, RFCOMMServer):
"""Version of :class:`RFCOMMServer` that handles connections in a new
thread.
"""
Version of :class:`RFCOMMServer` that handles connections in a new thread.
"""
pass
daemon_threads = True
class RFCOMMClient:
def __init__(self, client_address, RequestHandlerClass):
self.client_address = client_address
self.RequestHandlerClass = RequestHandlerClass
self.socket = BluetoothSocket(RFCOMM)
self.socket = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)
def handle_request(self):
self.socket.connect((self.client_address[0], self.client_address[1]))
self.socket.connect(self.client_address)
try:
self.process_request(self.socket, self.client_address)
except Exception:
@@ -145,4 +101,8 @@ class RFCOMMClient:
class ThreadingRFCOMMClient(ThreadingMixIn, RFCOMMClient):
pass
"""
Version of :class:`RFCOMMClient` that handles connections in a new thread.
"""
daemon_threads = True
+11 -14
View File
@@ -1,16 +1,13 @@
# SPDX-License-Identifier: MIT
# Copyright (C) 2020 The Pybricks Authors
# Copyright (C) 2020,2023 The Pybricks Authors
from _thread import allocate_lock
from errno import ECONNRESET
from struct import pack, unpack
from socket import BDADDR_ANY
from socketserver import StreamRequestHandler
from threading import Lock
from .bluetooth import (
BDADDR_ANY,
ThreadingRFCOMMServer,
ThreadingRFCOMMClient,
StreamRequestHandler,
)
from .bluetooth import ThreadingRFCOMMServer, ThreadingRFCOMMClient
def resolve(brick):
@@ -151,7 +148,7 @@ class MailboxHandler(StreamRequestHandler):
self.server._clients[self.client_address[0]] = self.request
while True:
try:
buf = self.rfile.recv(2)
buf = self.rfile.read(2)
if len(buf) == 0:
break
except OSError as ex:
@@ -160,7 +157,7 @@ class MailboxHandler(StreamRequestHandler):
break
raise
(size,) = unpack("<H", buf)
buf = self.rfile.recv(size)
buf = self.rfile.read(size)
msg_count, cmd_type, cmd, name_size = unpack("<HBBB", buf[0:5])
if cmd_type != SYSTEM_COMMAND_NO_REPLY:
raise ValueError("Bad message type")
@@ -180,7 +177,7 @@ class MailboxHandler(StreamRequestHandler):
class MailboxHandlerMixIn:
def __init__(self):
# protects against concurrent access of other attributes
self._lock = allocate_lock()
self._lock = Lock()
# map of mailbox name to raw data
self._mailboxes = {}
# map of device name/address to object with send() method
@@ -247,7 +244,7 @@ class MailboxHandlerMixIn:
def wait_for_mailbox_update(self, mbox):
"""Waits until ``mbox`` receives a value."""
lock = allocate_lock()
lock = Lock()
lock.acquire()
with self._lock:
self._updates[mbox] = lock
@@ -264,7 +261,7 @@ class BluetoothMailboxServer(MailboxHandlerMixIn, ThreadingRFCOMMServer):
EV3.
The remote EV3 can either be running MicroPython or the standard EV3
firmare.
firmware.
"""
super().__init__()
super(ThreadingRFCOMMServer, self).__init__(
@@ -307,7 +304,7 @@ class BluetoothMailboxClient(MailboxHandlerMixIn):
remote EV3s.
The remote EV3s can either be running MicroPython or the standard EV3
firmare.
firmware.
"""
def __enter__(self):
+1 -1
View File
@@ -36,7 +36,7 @@ def scale(val, src, dst):
# Create a loop to react to events
# This loop reacte to all main PS4 button and stick events. I have left out
# This loop reacts to all main PS4 button and stick events. I have left out
# buttons like share and options, but can easily be added in by referring
# to the table at: https://github.com/codeadamca/python-connect-ps4
+24
View File
@@ -0,0 +1,24 @@
# 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
# Initialize the hub.
hub = ThisHub(broadcast_channel=1)
# Initialize the motors.
left_motor = Motor(Port.A)
right_motor = Motor(Port.B)
while True:
# Read the motor angles to be sent to the other hub.
left_angle = left_motor.angle()
right_angle = right_motor.angle()
# Set the broadcast data and start broadcasting if not already doing so.
hub.ble.broadcast(left_angle, right_angle)
# Broadcasts are only sent every 100 milliseconds, so there is no reason
# to call the broadcast() method more often than that.
wait(100)
+39
View File
@@ -0,0 +1,39 @@
# ThisHub = MoveHub CityHub TechnicHub PrimeHub EssentialHub
from pybricks.hubs import ThisHub
from pybricks.pupdevices import Motor
from pybricks.parameters import Color, Port
from pybricks.tools import wait
# Initialize the hub.
hub = ThisHub(observe_channels=[1])
# Initialize the motors.
left_motor = Motor(Port.A)
right_motor = Motor(Port.B)
while True:
# Receive broadcast from the other hub.
data = hub.ble.observe(1)
if data is None:
# No data has been received in the last 1 second.
hub.light.on(Color.RED)
else:
# 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
# other hub.
left_angle = data[0]
right_angle = data[1]
# Make the motors on this hub mirror the position of the
# motors on the other hub.
left_motor.track_target(left_angle)
right_motor.track_target(right_angle)
# Broadcasts are only sent every 100 milliseconds, so there is
# no reason to call the observe() method more often than that.
wait(100)
+1 -1
View File
@@ -1,7 +1,7 @@
# ThisHub = TechnicHub PrimeHub EssentialHub
from pybricks.hubs import ThisHub
from pybricks.tools import wait
from pybricks.geometry import Axis
from pybricks.parameters import Axis
# Initialize the hub.
hub = ThisHub()
+1 -1
View File
@@ -1,7 +1,7 @@
# ThisHub = TechnicHub PrimeHub EssentialHub
from pybricks.hubs import ThisHub
from pybricks.tools import wait
from pybricks.geometry import Axis
from pybricks.parameters import Axis
# Initialize the hub. In this case, specify that the hub is mounted with the
# top side facing forward and the front side facing to the right.
+1 -2
View File
@@ -1,6 +1,5 @@
from pybricks.hubs import PrimeHub
from pybricks.tools import wait
from pybricks.geometry import Matrix
from pybricks.tools import wait, Matrix
# Initialize the hub.
hub = PrimeHub()
+21 -6
View File
@@ -4,19 +4,34 @@ from uerrno import ENODEV
# Dictionary of device identifiers along with their name.
device_names = {
34: "Wedo 2.0 Tilt Sensor",
35: "Wedo 2.0 Infrared Sensor",
37: "BOOST Color Distance Sensor",
# pybricks.pupdevices.DCMotor
1: "Wedo 2.0 Medium Motor",
2: "Powered Up Train Motor",
# pybricks.pupdevices.Light
8: "Powered Up Light",
# pybricks.pupdevices.Motor
38: "BOOST Interactive Motor",
46: "Technic Large Motor",
47: "Technic Extra Large Motor",
48: "SPIKE Medium Angular Motor",
49: "SPIKE Large Angular Motor",
61: "SPIKE Color Sensor",
62: "SPIKE Ultrasonic Sensor",
63: "SPIKE Force Sensor",
65: "SPIKE Small Angular Motor",
75: "Technic Medium Angular Motor",
76: "Technic Large Angular Motor",
# pybricks.pupdevices.TiltSensor
34: "Wedo 2.0 Tilt Sensor",
# pybricks.pupdevices.InfraredSensor
35: "Wedo 2.0 Infrared Motion Sensor",
# pybricks.pupdevices.ColorDistanceSensor
37: "BOOST Color Distance Sensor",
# pybricks.pupdevices.ColorSensor
61: "SPIKE Color Sensor",
# pybricks.pupdevices.UltrasonicSensor
62: "SPIKE Ultrasonic Sensor",
# pybricks.pupdevices.ForceSensor
63: "SPIKE Force Sensor",
# pybricks.pupdevices.ColorLightMatrix
64: "SPIKE 3x3 Color Light Matrix",
}
# Make a list of known ports.
+2 -2
View File
@@ -14,10 +14,10 @@ drive_base = DriveBase(left_motor, right_motor, wheel_diameter=56, axle_track=11
# Drive forward by 500mm (half a meter).
drive_base.straight(500)
# Turn around clockwise (180 degrees)
# Turn around clockwise by 180 degrees.
drive_base.turn(180)
# Drive forward again to drive back.
# Drive forward again to get back to the start.
drive_base.straight(500)
# Turn around counterclockwise.
+19
View File
@@ -4,6 +4,25 @@
## Unreleased
## 1.9.0 - 2023-05-16
### Changed
- Updated `pybricks` package to v3.3.0b5.
## 1.8.0 - 2023-04-21
### Changed
- Updated `pybricks` package to v3.3.0b4.
## 1.7.0 - 2022-12-28
### Added
- Added `update_user_modules()` function for filtering on user modules.
### Fixed
- Fixed code completion for builtin types.
- Fixed code completion for names starting with `_`.
## 1.6.0 - 2022-12-09
### Changed
+267 -267
View File
@@ -1,3 +1,5 @@
# This file is automatically @generated by Poetry and should not be changed by hand.
[[package]]
name = "attrs"
version = "22.1.0"
@@ -5,6 +7,10 @@ description = "Classes Without Boilerplate"
category = "dev"
optional = false
python-versions = ">=3.5"
files = [
{file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"},
{file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"},
]
[package.extras]
dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"]
@@ -19,252 +25,7 @@ description = "The uncompromising code formatter."
category = "dev"
optional = false
python-versions = ">=3.7"
[package.dependencies]
click = ">=8.0.0"
mypy-extensions = ">=0.4.3"
pathspec = ">=0.9.0"
platformdirs = ">=2"
tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""}
[package.extras]
colorama = ["colorama (>=0.4.3)"]
d = ["aiohttp (>=3.7.4)"]
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "click"
version = "8.1.3"
description = "Composable command line interface toolkit"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
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"
[[package]]
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"
[[package]]
name = "exceptiongroup"
version = "1.0.4"
description = "Backport of PEP 654 (exception groups)"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.extras]
test = ["pytest (>=6)"]
[[package]]
name = "flake8"
version = "4.0.1"
description = "the modular source code checker: pep8 pyflakes and co"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
mccabe = ">=0.6.0,<0.7.0"
pycodestyle = ">=2.8.0,<2.9.0"
pyflakes = ">=2.4.0,<2.5.0"
[[package]]
name = "iniconfig"
version = "1.1.1"
description = "iniconfig: brain-dead simple config-ini parsing"
category = "dev"
optional = false
python-versions = "*"
[[package]]
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"
[package.dependencies]
parso = ">=0.8.0,<0.9.0"
[package.extras]
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"]
[[package]]
name = "mccabe"
version = "0.6.1"
description = "McCabe checker, plugin for flake8"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "mypy-extensions"
version = "0.4.3"
description = "Experimental type system extensions for programs checked with the mypy typechecker."
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "packaging"
version = "21.3"
description = "Core utilities for Python packages"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
[[package]]
name = "parso"
version = "0.8.3"
description = "A Python Parser"
category = "main"
optional = false
python-versions = ">=3.6"
[package.extras]
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
testing = ["docopt", "pytest (<6.0.0)"]
[[package]]
name = "pathspec"
version = "0.10.2"
description = "Utility library for gitignore style pattern matching of file paths."
category = "dev"
optional = false
python-versions = ">=3.7"
[[package]]
name = "platformdirs"
version = "2.5.4"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "dev"
optional = false
python-versions = ">=3.7"
[package.extras]
docs = ["furo (>=2022.9.29)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.4)"]
test = ["appdirs (==1.4.4)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
[[package]]
name = "pluggy"
version = "1.0.0"
description = "plugin and hook calling mechanisms for python"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.extras]
dev = ["pre-commit", "tox"]
testing = ["pytest", "pytest-benchmark"]
[[package]]
name = "pybricks"
version = "3.2.0c1"
description = "Documentation and user-API stubs for Pybricks MicroPython"
category = "main"
optional = false
python-versions = "^3.8"
develop = true
[package.source]
type = "directory"
url = ".."
[[package]]
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.*"
[[package]]
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.*"
[[package]]
name = "pyparsing"
version = "3.0.9"
description = "pyparsing module - Classes and methods to define and execute parsing grammars"
category = "dev"
optional = false
python-versions = ">=3.6.8"
[package.extras]
diagrams = ["jinja2", "railroad-diagrams"]
[[package]]
name = "pytest"
version = "7.2.0"
description = "pytest: simple powerful testing with Python"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.dependencies]
attrs = ">=19.2.0"
colorama = {version = "*", markers = "sys_platform == \"win32\""}
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
iniconfig = "*"
packaging = "*"
pluggy = ">=0.12,<2.0"
tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
[package.extras]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"]
[[package]]
name = "tomli"
version = "2.0.1"
description = "A lil' TOML parser"
category = "dev"
optional = false
python-versions = ">=3.7"
[[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"
[metadata]
lock-version = "1.1"
python-versions = ">= 3.10, < 3.11"
content-hash = "971c6d0dddd9bb8e33a942e2360905a7d80a1a9d33015c0defc08345df5c1019"
[metadata.files]
attrs = [
{file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"},
{file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"},
]
black = [
files = [
{file = "black-22.10.0-1fixedarch-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:5cc42ca67989e9c3cf859e84c2bf014f6633db63d1cbdf8fdb666dcd9e77e3fa"},
{file = "black-22.10.0-1fixedarch-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:5d8f74030e67087b219b032aa33a919fae8806d49c867846bfacde57f43972ef"},
{file = "black-22.10.0-1fixedarch-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:197df8509263b0b8614e1df1756b1dd41be6738eed2ba9e9769f3880c2b9d7b6"},
@@ -287,84 +48,323 @@ black = [
{file = "black-22.10.0-py3-none-any.whl", hash = "sha256:c957b2b4ea88587b46cf49d1dc17681c1e672864fd7af32fc1e9664d572b3458"},
{file = "black-22.10.0.tar.gz", hash = "sha256:f513588da599943e0cde4e32cc9879e825d58720d6557062d1098c5ad80080e1"},
]
click = [
[package.dependencies]
click = ">=8.0.0"
mypy-extensions = ">=0.4.3"
pathspec = ">=0.9.0"
platformdirs = ">=2"
tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""}
[package.extras]
colorama = ["colorama (>=0.4.3)"]
d = ["aiohttp (>=3.7.4)"]
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "click"
version = "8.1.3"
description = "Composable command line interface toolkit"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
{file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
]
colorama = [
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
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 = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
]
docstring-parser = [
[[package]]
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 = [
{file = "docstring_parser-0.14.1-py3-none-any.whl", hash = "sha256:14ac6ec1f1ba6905c4d8cb90fd0bc55394f5678183752c90e44812bf28d7a515"},
{file = "docstring_parser-0.14.1.tar.gz", hash = "sha256:2c77522e31b7c88b1ab457a1f3c9ae38947ad719732260ba77ee8a3deb58622a"},
]
exceptiongroup = [
[[package]]
name = "exceptiongroup"
version = "1.0.4"
description = "Backport of PEP 654 (exception groups)"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "exceptiongroup-1.0.4-py3-none-any.whl", hash = "sha256:542adf9dea4055530d6e1279602fa5cb11dab2395fa650b8674eaec35fc4a828"},
{file = "exceptiongroup-1.0.4.tar.gz", hash = "sha256:bd14967b79cd9bdb54d97323216f8fdf533e278df937aa2a90089e7d6e06e5ec"},
]
flake8 = [
[package.extras]
test = ["pytest (>=6)"]
[[package]]
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 = [
{file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"},
{file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"},
]
iniconfig = [
[package.dependencies]
mccabe = ">=0.6.0,<0.7.0"
pycodestyle = ">=2.8.0,<2.9.0"
pyflakes = ">=2.4.0,<2.5.0"
[[package]]
name = "iniconfig"
version = "1.1.1"
description = "iniconfig: brain-dead simple config-ini parsing"
category = "dev"
optional = false
python-versions = "*"
files = [
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
]
jedi = [
[[package]]
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 = [
{file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"},
{file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"},
]
mccabe = [
[package.dependencies]
parso = ">=0.8.0,<0.9.0"
[package.extras]
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"]
[[package]]
name = "mccabe"
version = "0.6.1"
description = "McCabe checker, plugin for flake8"
category = "dev"
optional = false
python-versions = "*"
files = [
{file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
]
mypy-extensions = [
[[package]]
name = "mypy-extensions"
version = "0.4.3"
description = "Experimental type system extensions for programs checked with the mypy typechecker."
category = "dev"
optional = false
python-versions = "*"
files = [
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
]
packaging = [
[[package]]
name = "packaging"
version = "21.3"
description = "Core utilities for Python packages"
category = "dev"
optional = false
python-versions = ">=3.6"
files = [
{file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
]
parso = [
[package.dependencies]
pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
[[package]]
name = "parso"
version = "0.8.3"
description = "A Python Parser"
category = "main"
optional = false
python-versions = ">=3.6"
files = [
{file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"},
{file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"},
]
pathspec = [
[package.extras]
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
testing = ["docopt", "pytest (<6.0.0)"]
[[package]]
name = "pathspec"
version = "0.10.2"
description = "Utility library for gitignore style pattern matching of file paths."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "pathspec-0.10.2-py3-none-any.whl", hash = "sha256:88c2606f2c1e818b978540f73ecc908e13999c6c3a383daf3705652ae79807a5"},
{file = "pathspec-0.10.2.tar.gz", hash = "sha256:8f6bf73e5758fd365ef5d58ce09ac7c27d2833a8d7da51712eac6e27e35141b0"},
]
platformdirs = [
[[package]]
name = "platformdirs"
version = "2.5.4"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "platformdirs-2.5.4-py3-none-any.whl", hash = "sha256:af0276409f9a02373d540bf8480021a048711d572745aef4b7842dad245eba10"},
{file = "platformdirs-2.5.4.tar.gz", hash = "sha256:1006647646d80f16130f052404c6b901e80ee4ed6bef6792e1f238a8969106f7"},
]
pluggy = [
[package.extras]
docs = ["furo (>=2022.9.29)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.4)"]
test = ["appdirs (==1.4.4)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
[[package]]
name = "pluggy"
version = "1.0.0"
description = "plugin and hook calling mechanisms for python"
category = "dev"
optional = false
python-versions = ">=3.6"
files = [
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
]
pybricks = []
pycodestyle = [
[package.extras]
dev = ["pre-commit", "tox"]
testing = ["pytest", "pytest-benchmark"]
[[package]]
name = "pybricks"
version = "3.3.0a5"
description = "Documentation and user-API stubs for Pybricks MicroPython"
category = "main"
optional = false
python-versions = "^3.8"
files = []
develop = true
[package.source]
type = "directory"
url = ".."
[[package]]
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 = [
{file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"},
{file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"},
]
pyflakes = [
[[package]]
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 = [
{file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"},
{file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"},
]
pyparsing = [
[[package]]
name = "pyparsing"
version = "3.0.9"
description = "pyparsing module - Classes and methods to define and execute parsing grammars"
category = "dev"
optional = false
python-versions = ">=3.6.8"
files = [
{file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
{file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
]
pytest = [
[package.extras]
diagrams = ["jinja2", "railroad-diagrams"]
[[package]]
name = "pytest"
version = "7.2.0"
description = "pytest: simple powerful testing with Python"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "pytest-7.2.0-py3-none-any.whl", hash = "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71"},
{file = "pytest-7.2.0.tar.gz", hash = "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59"},
]
tomli = [
[package.dependencies]
attrs = ">=19.2.0"
colorama = {version = "*", markers = "sys_platform == \"win32\""}
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
iniconfig = "*"
packaging = "*"
pluggy = ">=0.12,<2.0"
tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
[package.extras]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"]
[[package]]
name = "tomli"
version = "2.0.1"
description = "A lil' TOML parser"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
typing-extensions = [
[[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 = [
{file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"},
{file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"},
]
[metadata]
lock-version = "2.0"
python-versions = ">= 3.10, < 3.12"
content-hash = "25da309474c7393923efe8ea98d47ed5759f373fdf8f4c71f6ccdc76c5f21882"
+3 -3
View File
@@ -1,13 +1,13 @@
[tool.poetry]
name = "pybricks_jedi"
version = "1.6.0"
version = "1.9.0"
description = "Code completion for Pybricks."
authors = ["The Pybricks Authors <team@pybricks.com>"]
license = "MIT"
[tool.poetry.dependencies]
python = ">= 3.10, < 3.11"
pybricks = "3.2.0c1"
python = ">= 3.10, < 3.12"
pybricks = "3.3.0a5"
jedi = "0.18.1"
typing-extensions = "4.2.0"
docstring-parser = "0.14.1"
+171 -90
View File
@@ -2,6 +2,7 @@ import io
import json
import re
from enum import IntEnum
from typing import Iterable
import docstring_parser
import jedi
@@ -12,7 +13,6 @@ from typing_extensions import NotRequired, TypedDict
PYBRICKS_CODE_PACKAGES = {
"micropython",
"pybricks",
"pybricks.geometry",
"pybricks.hubs",
"pybricks.iodevices",
"pybricks.parameters",
@@ -31,90 +31,153 @@ PYBRICKS_CODE_PACKAGES = {
# Subset of Python builtins included in Pybricks MicroPython.
PYBRICKS_BUILTINS = {
"abs",
"all",
"any",
"ArithmeticError",
"AssertionError",
"AttributeError",
"BaseException",
"bin",
"bool",
"bytearray",
"bytes",
"callable",
"chr",
"classmethod",
"complex",
"dict",
"dir",
"divmod",
"enumerate",
"EOFError",
"eval",
"Exception",
"exec",
"float",
"GeneratorExit",
"getattr",
"globals",
"hasattr",
"hash",
"help",
"hex",
"id",
"ImportError",
"IndentationError",
"IndexError",
"input",
"int",
"isinstance",
"issubclass",
"iter",
"KeyboardInterrupt",
"KeyError",
"len",
"list",
"locals",
"LookupError",
"map",
"max",
"MemoryError",
"min",
"NameError",
"next",
"NotImplementedError",
"object",
"oct",
"ord",
"OSError",
"OverflowError",
"pow",
"print",
"range",
"repr",
"reversed",
"round",
"RuntimeError",
"set",
"setattr",
"slice",
"sorted",
"staticmethod",
"StopIteration",
"str",
"sum",
"super",
"SyntaxError",
"SystemExit",
"tuple",
"type",
"TypeError",
"ValueError",
"ZeroDivisionError",
"zip",
"builtins.abs",
"builtins.all",
"builtins.any",
"builtins.ArithmeticError",
"builtins.AssertionError",
"builtins.AttributeError",
"builtins.BaseException",
"builtins.bin",
"builtins.bool",
"builtins.bytearray",
"builtins.bytes",
"builtins.callable",
"builtins.chr",
"builtins.classmethod",
"builtins.complex",
"builtins.dict",
"builtins.dir",
"builtins.divmod",
"builtins.enumerate",
"builtins.EOFError",
"builtins.eval",
"builtins.Exception",
"builtins.exec",
"builtins.float",
"builtins.GeneratorExit",
"builtins.getattr",
"builtins.globals",
"builtins.hasattr",
"builtins.hash",
"builtins.help",
"builtins.hex",
"builtins.id",
"builtins.ImportError",
"builtins.IndentationError",
"builtins.IndexError",
"builtins.input",
"builtins.int",
"builtins.isinstance",
"builtins.issubclass",
"builtins.iter",
"builtins.KeyboardInterrupt",
"builtins.KeyError",
"builtins.len",
"builtins.list",
"builtins.locals",
"builtins.LookupError",
"builtins.map",
"builtins.max",
"builtins.MemoryError",
"builtins.min",
"builtins.NameError",
"builtins.next",
"builtins.NotImplementedError",
"builtins.object",
"builtins.oct",
"builtins.ord",
"builtins.OSError",
"builtins.OverflowError",
"builtins.pow",
"builtins.print",
"builtins.range",
"builtins.repr",
"builtins.reversed",
"builtins.round",
"builtins.RuntimeError",
"builtins.set",
"builtins.setattr",
"builtins.slice",
"builtins.sorted",
"builtins.staticmethod",
"builtins.StopIteration",
"builtins.str",
"builtins.sum",
"builtins.super",
"builtins.SyntaxError",
"builtins.SystemExit",
"builtins.tuple",
"builtins.type",
"builtins.TypeError",
"builtins.ValueError",
"builtins.ZeroDivisionError",
"builtins.zip",
"builtins.bytearray.append",
"builtins.bytearray.extend",
"builtins.dict.clear",
"builtins.dict.copy",
"builtins.dict.fromkeys",
"builtins.dict.get",
"builtins.dict.items",
"builtins.dict.keys",
"builtins.dict.pop",
"builtins.dict.popitem",
"builtins.dict.setdefault",
"builtins.dict.update",
"builtins.dict.values",
"builtins.int.from_bytes",
"builtins.int.to_bytes",
"builtins.list.append",
"builtins.list.clear",
"builtins.list.copy",
"builtins.list.count",
"builtins.list.extend",
"builtins.list.index",
"builtins.list.insert",
"builtins.list.pop",
"builtins.list.remove",
"builtins.list.reverse",
"builtins.list.sort",
"builtins.str.count",
"builtins.str.endswith",
"builtins.str.find",
"builtins.str.format",
"builtins.str.index",
"builtins.str.isalpha",
"builtins.str.isdigit",
"builtins.str.islower",
"builtins.str.isspace",
"builtins.str.isupper",
"builtins.str.join",
"builtins.str.lower",
"builtins.str.lstrip",
"builtins.str.replace",
"builtins.str.rfind",
"builtins.str.rindex",
"builtins.str.rsplit",
"builtins.str.rstrip",
"builtins.str.split",
"builtins.str.startswith",
"builtins.str.strip",
"builtins.str.upper",
"builtins.tuple.count",
"builtins.tuple.index",
}
PYBRICKS_BUILTINS_NO_FULLNAME = {"items", "values"}
PYBRICKS_TYPING = {
"typing.MutableSequence.append",
"typing.MutableSequence.extend",
"typing.MutableMapping.pop",
"typing.Mapping.get",
}
MICROPY_NOT_SUPPORTED_DUNDER = {"__doc__", "__package__"}
user_modules = set()
# Types from monaco editor
@@ -243,10 +306,14 @@ class SignatureHelp(TypedDict):
def _is_pybricks(c: Completion) -> bool:
# filter all "private" names (leading underscore)
if (isinstance(c.name, str)) and c.name.startswith("_"):
return False
if c.name is not None:
if c.name.startswith("_") and c.module_name != "__main__":
return False
if isinstance(c.full_name, str):
if c.name in MICROPY_NOT_SUPPORTED_DUNDER:
return False
if c.full_name is not None:
# this catches things like `from __future__ import annotations`
if c.full_name.startswith("_") and c.module_name != "__main__":
return False
@@ -256,16 +323,19 @@ def _is_pybricks(c: Completion) -> bool:
return False
# filter out typing types
if c.full_name.startswith("typing."):
if c.full_name.startswith("typing.") and c.full_name not in PYBRICKS_TYPING:
return False
# filter out packages/modules that are not included in Pybricks firmware
if c.type == "module" or c.type == "namespace":
return c.full_name in PYBRICKS_CODE_PACKAGES
return c.full_name in PYBRICKS_CODE_PACKAGES or c.full_name in user_modules
# filter subset of builtins
if c.module_name == "builtins" and c.type != "keyword":
return c.name in PYBRICKS_BUILTINS
if c.full_name is None:
return c.name in PYBRICKS_BUILTINS_NO_FULLNAME
return c.full_name in PYBRICKS_BUILTINS
# this is a type alias, not a real type
if c.full_name == "pybricks.parameters.Number":
@@ -418,7 +488,6 @@ def initialize():
"pybricks._common",
"pybricks.ev3dev",
"pybricks.ev3dev.speaker",
"pybricks.geometry",
"pybricks.hubs",
"pybricks.iodevices",
"pybricks.parameters",
@@ -473,3 +542,15 @@ def get_signatures(code: str, line: int, column: int) -> str:
"""
signatures = jedi.Script(code).get_signatures(line, column - 1)
return json.dumps(_map_signatures(signatures))
def update_user_modules(names: Iterable[str]) -> None:
"""
Updates the set of user module names used for filtering.
Args:
names:
An iterable of module names.
"""
user_modules.clear()
user_modules.update(names)
+143
View File
@@ -7,6 +7,9 @@ Tests for correct code completion of builtins.
import json
import pytest
from pybricks_jedi import CompletionItem, complete
@@ -123,4 +126,144 @@ def test_empty_code():
"yield",
"ZeroDivisionError",
"zip",
"__name__",
]
FUNCTION_PARAMS = [
pytest.param(
"''.",
[
"count",
"endswith",
"find",
"format",
"index",
"isalpha",
"isdigit",
"islower",
"isspace",
"isupper",
"join",
"lower",
"lstrip",
"replace",
"rfind",
"rindex",
"rsplit",
"rstrip",
"split",
"startswith",
"strip",
"upper",
],
),
pytest.param(
"str().",
[
"count",
"endswith",
"find",
"format",
"index",
"isalpha",
"isdigit",
"islower",
"isspace",
"isupper",
"join",
"lower",
"lstrip",
"replace",
"rfind",
"rindex",
"rsplit",
"rstrip",
"split",
"startswith",
"strip",
"upper",
],
),
pytest.param("(0).", ["from_bytes", "to_bytes"]),
pytest.param("int().", ["from_bytes", "to_bytes"]),
pytest.param(
"{}.",
[
"clear",
"copy",
"fromkeys",
"get",
"items",
"keys",
"pop",
"popitem",
"setdefault",
"update",
"values",
],
),
pytest.param(
"dict().",
[
"clear",
"copy",
"fromkeys",
"get",
"items",
"keys",
"pop",
"popitem",
"setdefault",
"update",
"values",
],
),
pytest.param(
"[].",
[
"append",
"clear",
"copy",
"count",
"extend",
"index",
"insert",
"pop",
"remove",
"reverse",
"sort",
],
),
pytest.param(
"list().",
[
"append",
"clear",
"copy",
"count",
"extend",
"index",
"insert",
"pop",
"remove",
"reverse",
"sort",
],
),
pytest.param("().", ["count", "index"]),
pytest.param("tuple().", ["count", "index"]),
pytest.param("bytearray().", ["append", "extend"]),
pytest.param("bytes().", []),
pytest.param("b''.", []),
pytest.param("float().", []),
pytest.param("(0.0).", []),
pytest.param("complex().", []),
pytest.param("type().", []),
]
@pytest.mark.parametrize("code,attributes", FUNCTION_PARAMS)
def test_get_completion_for_builtins(code: str, attributes: list[str]):
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == attributes
+1
View File
@@ -33,6 +33,7 @@ def test_hub_dot():
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"battery",
"ble",
"button",
"light",
"system",
@@ -33,6 +33,7 @@ def test_hub_dot():
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"battery",
"ble",
"button",
"charger",
"imu",
@@ -79,7 +80,12 @@ def test_hub_dot_imu_dot():
"acceleration",
"angular_velocity",
"heading",
"orientation",
"ready",
"reset_heading",
"rotation",
"settings",
"stationary",
"tilt",
"up",
]
+34 -16
View File
@@ -6,7 +6,9 @@ Tests for correct code completion of import statements.
"""
import json
from pybricks_jedi import CompletionItem, complete
import pytest
from pybricks_jedi import CompletionItem, complete, update_user_modules
def test_from():
@@ -27,11 +29,36 @@ def test_from():
]
@pytest.fixture
def user_modules():
update_user_modules(["jedi", "pytest"])
yield
update_user_modules([])
def test_from_with_user_modules(user_modules):
code = "from "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"jedi",
"micropython",
"pybricks",
"pytest",
"uerrno",
"uio",
"ujson",
"umath",
"urandom",
"uselect",
"ustruct",
"usys",
]
def test_from_pybricks_import():
code = "from pybricks import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"geometry",
"hubs",
"iodevices",
"parameters",
@@ -46,7 +73,6 @@ def test_from_pybricks_dot():
code = "from pybricks."
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"geometry",
"hubs",
"iodevices",
"parameters",
@@ -56,16 +82,6 @@ def test_from_pybricks_dot():
]
def test_from_pybricks_geometry_import():
code = "from pybricks.geometry import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"Axis",
"Matrix",
"vector",
]
def test_from_pybricks_hubs_import():
code = "from pybricks.hubs import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
@@ -99,6 +115,7 @@ def test_from_pybricks_parameters_import():
code = "from pybricks.parameters import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"Axis",
"Button",
"Color",
"Direction",
@@ -131,17 +148,18 @@ def test_from_pybricks_pupdevices_import():
def test_from_pybricks_robotics_import():
code = "from pybricks.robotics import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"DriveBase",
]
assert [c["insertText"] for c in completions] == ["DriveBase", "GyroDriveBase"]
def test_from_pybricks_tools_import():
code = "from pybricks.tools import "
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
assert [c["insertText"] for c in completions] == [
"cross",
"DataLog",
"Matrix",
"StopWatch",
"vector",
"wait",
]
+32
View File
@@ -0,0 +1,32 @@
import json
from pybricks_jedi import CompletionItem, complete
def test_get_completion_for_private_globals():
code = """
_X = 0
_
"""
completions: list[CompletionItem] = json.loads(complete(code, 4, 2))
assert [c["insertText"] for c in completions] == ["_X", "__name__"]
def test_get_completion_for_private_attributes():
code = """
class X:
def __init__(self):
self.public = 0
self._protected = 0
self.__private = 0
x = X()
x.
"""
completions: list[CompletionItem] = json.loads(complete(code, 10, 3))
assert [c["insertText"] for c in completions] == [
"public",
"_protected",
"__init__",
]
+1
View File
@@ -33,6 +33,7 @@ def test_hub_dot():
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
assert [c["insertText"] for c in completions] == [
"battery",
"ble",
"button",
"imu",
"light",
+6
View File
@@ -33,6 +33,7 @@ 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",
@@ -97,7 +98,12 @@ def test_hub_dot_imu_dot():
"acceleration",
"angular_velocity",
"heading",
"orientation",
"ready",
"reset_heading",
"rotation",
"settings",
"stationary",
"tilt",
"up",
]

Some files were not shown because too many files have changed in this diff Show More