psc-sr-robot3 2026.0.3.18__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- psc_sr_robot3-2026.0.3.18/.flake8 +14 -0
- psc_sr_robot3-2026.0.3.18/.github/dependabot.yml +34 -0
- psc_sr_robot3-2026.0.3.18/.github/workflows/test_build.yml +87 -0
- psc_sr_robot3-2026.0.3.18/.gitignore +135 -0
- psc_sr_robot3-2026.0.3.18/LICENSE +22 -0
- psc_sr_robot3-2026.0.3.18/Makefile +33 -0
- psc_sr_robot3-2026.0.3.18/PKG-INFO +195 -0
- psc_sr_robot3-2026.0.3.18/README.md +135 -0
- psc_sr_robot3-2026.0.3.18/firmware/arduino-fw/arduino-fw.ino +230 -0
- psc_sr_robot3-2026.0.3.18/psc_sr_robot3.egg-info/PKG-INFO +195 -0
- psc_sr_robot3-2026.0.3.18/psc_sr_robot3.egg-info/SOURCES.txt +86 -0
- psc_sr_robot3-2026.0.3.18/psc_sr_robot3.egg-info/dependency_links.txt +1 -0
- psc_sr_robot3-2026.0.3.18/psc_sr_robot3.egg-info/requires.txt +23 -0
- psc_sr_robot3-2026.0.3.18/psc_sr_robot3.egg-info/scm_file_list.json +82 -0
- psc_sr_robot3-2026.0.3.18/psc_sr_robot3.egg-info/scm_version.json +8 -0
- psc_sr_robot3-2026.0.3.18/psc_sr_robot3.egg-info/top_level.txt +1 -0
- psc_sr_robot3-2026.0.3.18/pyproject.toml +88 -0
- psc_sr_robot3-2026.0.3.18/setup.cfg +4 -0
- psc_sr_robot3-2026.0.3.18/sr/__init__.py +0 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/__init__.py +71 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/_version.py +24 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/arduino.py +734 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/astoria.py +303 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/battery.py +136 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/brain.py +405 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/bus_servo.py +446 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/buzzer.py +81 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/calibrations/__init__.py +4 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/camera.py +411 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/exceptions.py +55 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/game_specific.py +11 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/gamepad.py +714 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/i2c.py +687 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/kch.py +420 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/leds.py +87 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/logging.py +110 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/marker.py +157 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/motor_board.py +343 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/mqtt.py +223 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/pin_motors.py +238 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/power_board.py +578 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/py.typed +1 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/raw_serial.py +225 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/robot.py +630 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/serial_wrapper.py +262 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/servo_board.py +382 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/simulator/__init__.py +0 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/simulator/camera.py +78 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/simulator/time_server.py +94 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/timeout.py +85 -0
- psc_sr_robot3-2026.0.3.18/sr/robot3/utils.py +299 -0
- psc_sr_robot3-2026.0.3.18/stubs/RPi/GPIO.pyi +43 -0
- psc_sr_robot3-2026.0.3.18/stubs/RPi/__init__.pyi +0 -0
- psc_sr_robot3-2026.0.3.18/tests/__init__.py +1 -0
- psc_sr_robot3-2026.0.3.18/tests/conftest.py +97 -0
- psc_sr_robot3-2026.0.3.18/tests/test_arduino.py +355 -0
- psc_sr_robot3-2026.0.3.18/tests/test_battery.py +125 -0
- psc_sr_robot3-2026.0.3.18/tests/test_bus_servo.py +207 -0
- psc_sr_robot3-2026.0.3.18/tests/test_buzzer_pi.py +148 -0
- psc_sr_robot3-2026.0.3.18/tests/test_camera.py +180 -0
- psc_sr_robot3-2026.0.3.18/tests/test_data/bad/metadata.json +1 -0
- psc_sr_robot3-2026.0.3.18/tests/test_data/empty/.gitkeep +0 -0
- psc_sr_robot3-2026.0.3.18/tests/test_data/marker_detections.json +38 -0
- psc_sr_robot3-2026.0.3.18/tests/test_data/marker_locations.csv +37 -0
- psc_sr_robot3-2026.0.3.18/tests/test_data/missing_key/metadata.json +3 -0
- psc_sr_robot3-2026.0.3.18/tests/test_data/nested/valid/metadata.json +4 -0
- psc_sr_robot3-2026.0.3.18/tests/test_data/not_object/metadata.json +4 -0
- psc_sr_robot3-2026.0.3.18/tests/test_data/timeout_scripts/catch-base-exception.py +10 -0
- psc_sr_robot3-2026.0.3.18/tests/test_data/timeout_scripts/catch-exception.py +10 -0
- psc_sr_robot3-2026.0.3.18/tests/test_data/timeout_scripts/hot-loop.py +7 -0
- psc_sr_robot3-2026.0.3.18/tests/test_data/timeout_scripts/sleep.py +6 -0
- psc_sr_robot3-2026.0.3.18/tests/test_data/timeout_scripts/try-finally.py +11 -0
- psc_sr_robot3-2026.0.3.18/tests/test_data/timeout_scripts_extra/early-exit.py +3 -0
- psc_sr_robot3-2026.0.3.18/tests/test_data/timeout_scripts_extra/exception.py +5 -0
- psc_sr_robot3-2026.0.3.18/tests/test_data/valid/metadata.json +4 -0
- psc_sr_robot3-2026.0.3.18/tests/test_gamepad.py +336 -0
- psc_sr_robot3-2026.0.3.18/tests/test_i2c.py +762 -0
- psc_sr_robot3-2026.0.3.18/tests/test_leds.py +93 -0
- psc_sr_robot3-2026.0.3.18/tests/test_logging.py +42 -0
- psc_sr_robot3-2026.0.3.18/tests/test_markers.py +103 -0
- psc_sr_robot3-2026.0.3.18/tests/test_motor_board.py +294 -0
- psc_sr_robot3-2026.0.3.18/tests/test_pin_motors.py +250 -0
- psc_sr_robot3-2026.0.3.18/tests/test_power_board.py +425 -0
- psc_sr_robot3-2026.0.3.18/tests/test_raw_serial.py +151 -0
- psc_sr_robot3-2026.0.3.18/tests/test_serial_wrapper.py +173 -0
- psc_sr_robot3-2026.0.3.18/tests/test_servo_board.py +312 -0
- psc_sr_robot3-2026.0.3.18/tests/test_sr_robot.py +289 -0
- psc_sr_robot3-2026.0.3.18/tests/test_timeout.py +99 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[flake8]
|
|
2
|
+
max_line_length = 95
|
|
3
|
+
ignore =
|
|
4
|
+
# Don't require imperative mood docstrings.
|
|
5
|
+
D401,
|
|
6
|
+
# Ignore docstrings on magic methods
|
|
7
|
+
D105,
|
|
8
|
+
# Ignore docstrings on init methods
|
|
9
|
+
D107,
|
|
10
|
+
# Allow line breaks before and after a binary operator
|
|
11
|
+
W503, W504,
|
|
12
|
+
# Ignore TODO comments
|
|
13
|
+
T000,
|
|
14
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: pip
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: daily
|
|
7
|
+
open-pull-requests-limit: 10
|
|
8
|
+
ignore:
|
|
9
|
+
- dependency-name: sphinx
|
|
10
|
+
versions:
|
|
11
|
+
- 3.4.3
|
|
12
|
+
- 3.5.0
|
|
13
|
+
- 3.5.1
|
|
14
|
+
- 3.5.2
|
|
15
|
+
- 3.5.3
|
|
16
|
+
- dependency-name: flake8
|
|
17
|
+
versions:
|
|
18
|
+
- 3.8.4
|
|
19
|
+
- 3.9.0
|
|
20
|
+
- dependency-name: pytest
|
|
21
|
+
versions:
|
|
22
|
+
- 6.2.2
|
|
23
|
+
- dependency-name: sphinx-rtd-theme
|
|
24
|
+
versions:
|
|
25
|
+
- 0.5.1
|
|
26
|
+
- dependency-name: isort
|
|
27
|
+
versions:
|
|
28
|
+
- 5.7.0
|
|
29
|
+
- dependency-name: flake8-comprehensions
|
|
30
|
+
versions:
|
|
31
|
+
- 3.3.1
|
|
32
|
+
- dependency-name: rope
|
|
33
|
+
versions:
|
|
34
|
+
- 0.18.0
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
name: Lint & build
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
strategy:
|
|
10
|
+
fail-fast: false
|
|
11
|
+
matrix:
|
|
12
|
+
os: [ubuntu-latest]
|
|
13
|
+
py_version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
|
14
|
+
include:
|
|
15
|
+
- os: windows-latest
|
|
16
|
+
py_version: "3.9"
|
|
17
|
+
- os: windows-latest
|
|
18
|
+
py_version: "3.13"
|
|
19
|
+
- os: macos-latest
|
|
20
|
+
py_version: "3.9"
|
|
21
|
+
- os: macos-latest
|
|
22
|
+
py_version: "3.13"
|
|
23
|
+
runs-on: ${{ matrix.os }}
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
with:
|
|
27
|
+
fetch-depth: 0
|
|
28
|
+
- name: Set up Python
|
|
29
|
+
uses: actions/setup-python@v5
|
|
30
|
+
with:
|
|
31
|
+
python-version: ${{ matrix.py_version }}
|
|
32
|
+
- name: Install dependencies
|
|
33
|
+
run: |
|
|
34
|
+
python -m pip install --upgrade pip
|
|
35
|
+
python -m pip install .[dev,vision]
|
|
36
|
+
- name: Lint
|
|
37
|
+
run: |
|
|
38
|
+
make lint
|
|
39
|
+
- name: Isort
|
|
40
|
+
run: |
|
|
41
|
+
make isort-check
|
|
42
|
+
- name: Typecheck
|
|
43
|
+
run: |
|
|
44
|
+
make type
|
|
45
|
+
- name: Run tests
|
|
46
|
+
run: |
|
|
47
|
+
make test
|
|
48
|
+
|
|
49
|
+
build:
|
|
50
|
+
permissions:
|
|
51
|
+
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
needs: test
|
|
54
|
+
# PyPI's trusted publisher for psc-sr-robot3 names this environment
|
|
55
|
+
environment:
|
|
56
|
+
name: pypi
|
|
57
|
+
url: https://pypi.org/p/psc-sr-robot3
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@v4
|
|
60
|
+
with:
|
|
61
|
+
fetch-depth: 0
|
|
62
|
+
- name: Set up Python 3.10
|
|
63
|
+
uses: actions/setup-python@v5
|
|
64
|
+
with:
|
|
65
|
+
python-version: "3.10"
|
|
66
|
+
- name: Install dependencies
|
|
67
|
+
run: |
|
|
68
|
+
python -m pip install --upgrade pip build
|
|
69
|
+
# Install package to generate version info
|
|
70
|
+
python -m pip install .
|
|
71
|
+
- name: Build package
|
|
72
|
+
run: |
|
|
73
|
+
make build
|
|
74
|
+
- name: Save built package
|
|
75
|
+
uses: actions/upload-artifact@v4
|
|
76
|
+
with:
|
|
77
|
+
name: package
|
|
78
|
+
path: |
|
|
79
|
+
dist
|
|
80
|
+
- name: Check the package
|
|
81
|
+
run: |
|
|
82
|
+
python -m pip install twine
|
|
83
|
+
python -m twine check --strict dist/*
|
|
84
|
+
- name: Publish to PyPi
|
|
85
|
+
# Version tags only, such as 2026.0.3.18
|
|
86
|
+
if: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, '20') }}
|
|
87
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
pip-wheel-metadata/
|
|
24
|
+
share/python-wheels/
|
|
25
|
+
*.egg-info/
|
|
26
|
+
.installed.cfg
|
|
27
|
+
*.egg
|
|
28
|
+
MANIFEST
|
|
29
|
+
|
|
30
|
+
# PyInstaller
|
|
31
|
+
# Usually these files are written by a python script from a template
|
|
32
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
33
|
+
*.manifest
|
|
34
|
+
*.spec
|
|
35
|
+
|
|
36
|
+
# Installer logs
|
|
37
|
+
pip-log.txt
|
|
38
|
+
pip-delete-this-directory.txt
|
|
39
|
+
|
|
40
|
+
# Unit test / coverage reports
|
|
41
|
+
htmlcov/
|
|
42
|
+
.tox/
|
|
43
|
+
.nox/
|
|
44
|
+
.coverage
|
|
45
|
+
.coverage.*
|
|
46
|
+
.cache
|
|
47
|
+
nosetests.xml
|
|
48
|
+
coverage.xml
|
|
49
|
+
*.cover
|
|
50
|
+
*.py,cover
|
|
51
|
+
.hypothesis/
|
|
52
|
+
.pytest_cache/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
target/
|
|
76
|
+
|
|
77
|
+
# Jupyter Notebook
|
|
78
|
+
.ipynb_checkpoints
|
|
79
|
+
|
|
80
|
+
# IPython
|
|
81
|
+
profile_default/
|
|
82
|
+
ipython_config.py
|
|
83
|
+
|
|
84
|
+
# pyenv
|
|
85
|
+
.python-version
|
|
86
|
+
|
|
87
|
+
# pipenv
|
|
88
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
89
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
90
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
91
|
+
# install all needed dependencies.
|
|
92
|
+
#Pipfile.lock
|
|
93
|
+
|
|
94
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
95
|
+
__pypackages__/
|
|
96
|
+
|
|
97
|
+
# Celery stuff
|
|
98
|
+
celerybeat-schedule
|
|
99
|
+
celerybeat.pid
|
|
100
|
+
|
|
101
|
+
# SageMath parsed files
|
|
102
|
+
*.sage.py
|
|
103
|
+
|
|
104
|
+
# Environments
|
|
105
|
+
.env
|
|
106
|
+
.venv
|
|
107
|
+
env/
|
|
108
|
+
venv/
|
|
109
|
+
ENV/
|
|
110
|
+
env.bak/
|
|
111
|
+
venv.bak/
|
|
112
|
+
|
|
113
|
+
# Spyder project settings
|
|
114
|
+
.spyderproject
|
|
115
|
+
.spyproject
|
|
116
|
+
|
|
117
|
+
# Rope project settings
|
|
118
|
+
.ropeproject
|
|
119
|
+
|
|
120
|
+
# mkdocs documentation
|
|
121
|
+
/site
|
|
122
|
+
|
|
123
|
+
# mypy
|
|
124
|
+
.mypy_cache/
|
|
125
|
+
.dmypy.json
|
|
126
|
+
dmypy.json
|
|
127
|
+
|
|
128
|
+
# Pyre type checker
|
|
129
|
+
.pyre/
|
|
130
|
+
|
|
131
|
+
_version.py
|
|
132
|
+
|
|
133
|
+
# macOS metadata
|
|
134
|
+
.DS_Store
|
|
135
|
+
**/.DS_Store
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019-21 Dan Trickey
|
|
4
|
+
Copyright (c) 2023 SourceBots
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
.PHONY: lint type test test-html isort isort-check build upload
|
|
2
|
+
|
|
3
|
+
PYMODULE:=sr/robot3
|
|
4
|
+
TESTS:=tests
|
|
5
|
+
|
|
6
|
+
all: lint isort-check type test
|
|
7
|
+
|
|
8
|
+
lint:
|
|
9
|
+
flake8 $(PYMODULE)
|
|
10
|
+
|
|
11
|
+
type:
|
|
12
|
+
mypy $(PYMODULE)
|
|
13
|
+
|
|
14
|
+
test:
|
|
15
|
+
pytest --cov=$(PYMODULE) --cov-report=term --cov-report=xml $(TESTS)
|
|
16
|
+
|
|
17
|
+
test-html:
|
|
18
|
+
pytest --cov=$(PYMODULE) --cov-report=html $(TESTS)
|
|
19
|
+
|
|
20
|
+
isort-check:
|
|
21
|
+
python -m isort --check $(PYMODULE)
|
|
22
|
+
|
|
23
|
+
isort:
|
|
24
|
+
python -m isort $(PYMODULE)
|
|
25
|
+
|
|
26
|
+
build:
|
|
27
|
+
python -m build
|
|
28
|
+
|
|
29
|
+
upload:
|
|
30
|
+
twine upload dist/*
|
|
31
|
+
|
|
32
|
+
clean:
|
|
33
|
+
rm -rf dist/* build/*
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: psc-sr-robot3
|
|
3
|
+
Version: 2026.0.3.18
|
|
4
|
+
Summary: PSC Robotics' version of the Student Robotics API for Python 3
|
|
5
|
+
Author: PSC Robotics
|
|
6
|
+
Author-email: Student Robotics <kit-team@studentrobotics.org>
|
|
7
|
+
License: MIT License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2019-21 Dan Trickey
|
|
10
|
+
Copyright (c) 2023 SourceBots
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
29
|
+
|
|
30
|
+
Project-URL: Repository, https://github.com/PSC-Robotics/Custom-SR-Library
|
|
31
|
+
Project-URL: Homepage, https://psc-robotics.uk
|
|
32
|
+
Project-URL: Documentation, https://docs.psc-robotics.uk
|
|
33
|
+
Project-URL: Student Robotics sr-robot3, https://github.com/srobo/sr-robot
|
|
34
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
35
|
+
Classifier: Operating System :: OS Independent
|
|
36
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
37
|
+
Classifier: Typing :: Typed
|
|
38
|
+
Classifier: Topic :: Education
|
|
39
|
+
Requires-Python: >=3.9
|
|
40
|
+
Description-Content-Type: text/markdown
|
|
41
|
+
License-File: LICENSE
|
|
42
|
+
Requires-Dist: pyserial<4,>=3
|
|
43
|
+
Requires-Dist: april_vision==3.0.0
|
|
44
|
+
Requires-Dist: paho-mqtt<3,>=2
|
|
45
|
+
Requires-Dist: pydantic<2,>=1.9.1
|
|
46
|
+
Requires-Dist: typing-extensions; python_version < "3.10"
|
|
47
|
+
Requires-Dist: tomli<3,>=2.0.1; python_version < "3.11"
|
|
48
|
+
Provides-Extra: dev
|
|
49
|
+
Requires-Dist: flake8; extra == "dev"
|
|
50
|
+
Requires-Dist: isort; extra == "dev"
|
|
51
|
+
Requires-Dist: mypy<2,>=1.7; extra == "dev"
|
|
52
|
+
Requires-Dist: build; extra == "dev"
|
|
53
|
+
Requires-Dist: types-pyserial; extra == "dev"
|
|
54
|
+
Requires-Dist: pytest; extra == "dev"
|
|
55
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
56
|
+
Requires-Dist: paho-mqtt<3,>=2; extra == "dev"
|
|
57
|
+
Provides-Extra: vision
|
|
58
|
+
Requires-Dist: opencv-python-headless<5,>=4.10; extra == "vision"
|
|
59
|
+
Dynamic: license-file
|
|
60
|
+
|
|
61
|
+
# psc-sr-robot3
|
|
62
|
+
|
|
63
|
+
[](https://opensource.org/licenses/MIT)
|
|
64
|
+
|
|
65
|
+
`psc-sr-robot3` is PSC Robotics' version of [sr-robot3](https://github.com/srobo/sr-robot),
|
|
66
|
+
the Student Robotics Python API. It adds PSC's brain board: GPIO motors and steppers,
|
|
67
|
+
servo drivers and I2C, the brain board LED and battery sensor, the buzzer and gamepads.
|
|
68
|
+
See the [PSC Robotics docs](https://docs.psc-robotics.uk).
|
|
69
|
+
|
|
70
|
+
Your code imports it as `sr.robot3`, the same as Student Robotics' library, so the two
|
|
71
|
+
can't be installed together. The PSC Robotics OS image already has it installed; install
|
|
72
|
+
it on a computer to get code completion and type checking while you write robot code.
|
|
73
|
+
|
|
74
|
+
## Installation
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install psc-sr-robot3
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
To include OpenCV, for the camera:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pip install "psc-sr-robot3[vision]"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Versions are Student Robotics' base version followed by PSC's own release number:
|
|
87
|
+
2026.0.3.18 is PSC release 18 of sr-robot3 2026.0.3.
|
|
88
|
+
|
|
89
|
+
## Usage
|
|
90
|
+
|
|
91
|
+
The main entry point for the API is the `Robot` class.
|
|
92
|
+
Instantiating this class will automatically detect and connect to any supported SR v4 boards connected to the device.
|
|
93
|
+
All SR boards are optional; connected boards are initialized and exposed as usual. By default, the `Robot` class waits for a start signal before continuing. When a power board is present, its start button is used; without one, the start signal can come from Astoria.
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
|
|
97
|
+
from sr.robot3 import Robot
|
|
98
|
+
|
|
99
|
+
r = Robot()
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
To disable the waiting for the start button, you can pass `wait_for_start=False` to the constructor.
|
|
104
|
+
The `wait_for_start` method needs to be called before the metadata is available.
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
|
|
108
|
+
from sr.robot3 import Robot
|
|
109
|
+
|
|
110
|
+
r = Robot(wait_for_start=False)
|
|
111
|
+
|
|
112
|
+
# Setup in here
|
|
113
|
+
|
|
114
|
+
r.wait_start()
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
An Arduino running firmware version 4 or later can drive a step/direction
|
|
119
|
+
stepper driver with `arduino.stepper_move(step_pin, direction_pin, steps)`. The
|
|
120
|
+
call blocks until the requested pulses are emitted; pass `direction=False` to
|
|
121
|
+
drive DIR low, and use `step_delay_us` to set the low interval between pulses.
|
|
122
|
+
Moves are limited to 350 ms per command so they fit within the serial timeout.
|
|
123
|
+
This API does not provide acceleration or track motor position.
|
|
124
|
+
|
|
125
|
+
### Buzzer
|
|
126
|
+
|
|
127
|
+
`robot.buzzer.buzz(frequency, duration, blocking=False)` plays a tone on the
|
|
128
|
+
buzzer connected to the brain board, like the Student Robotics power board's
|
|
129
|
+
`piezo.buzz()`. `Note` values such as `Note.A6` can be used for the frequency.
|
|
130
|
+
A new tone replaces the one playing. Tones are played by the robot's status
|
|
131
|
+
service, which also beeps when code is waiting for the start button, when start
|
|
132
|
+
is pressed, and with fast short beeps when code crashes.
|
|
133
|
+
|
|
134
|
+
### Steppers on the brain board's GPIO pins
|
|
135
|
+
|
|
136
|
+
`robot.brain.stepper_move(step_pin, direction_pin, steps)` drives a
|
|
137
|
+
step/direction stepper driver wired to the Pi's GPIO header, using BCM GPIO
|
|
138
|
+
numbers. It takes the same arguments as `arduino.stepper_move`, but has no
|
|
139
|
+
350 ms limit: `steps` can be up to 1000000 and `step_delay_us` from 50 to
|
|
140
|
+
1000000. Timing is done in software, so step timing can vary slightly. GPIO 5,
|
|
141
|
+
13 and 18 are used by the robot and can't be used.
|
|
142
|
+
|
|
143
|
+
### Multiple cameras
|
|
144
|
+
|
|
145
|
+
Every connected camera with a calibration is available in `robot.cameras`.
|
|
146
|
+
`robot.camera` still works when exactly one camera is connected.
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from sr.robot3 import Robot
|
|
150
|
+
|
|
151
|
+
r = Robot()
|
|
152
|
+
|
|
153
|
+
for camera_id, camera in r.cameras.items():
|
|
154
|
+
print(camera_id, camera.see())
|
|
155
|
+
|
|
156
|
+
front = r.cameras["A1B2C3D4"]
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Cameras are keyed by their USB serial number. Cameras with no serial number,
|
|
160
|
+
a generic placeholder serial or a serial shared with another connected camera
|
|
161
|
+
are keyed by the USB port they are plugged into, such as `usb-1-1.2`. Keep
|
|
162
|
+
those cameras in the same ports so their names stay the same. The camera
|
|
163
|
+
calibration dialog in the robot web UI shows the name of each connected camera.
|
|
164
|
+
Cameras of the same model share one calibration.
|
|
165
|
+
|
|
166
|
+
### Camera calibrations
|
|
167
|
+
|
|
168
|
+
The bundled Logitech calibrations are used automatically and are read-only in
|
|
169
|
+
the camera calibration dialog. Custom calibration directories can be added to the code
|
|
170
|
+
USB root with either `camera-calibrations.toml`:
|
|
171
|
+
|
|
172
|
+
```toml
|
|
173
|
+
calibrations = ["camera-calibrations"]
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
or `camera-calibrations.json`:
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{"calibrations": ["camera-calibrations"]}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Place the AprilVision calibration XML files in the listed directory. Paths are
|
|
183
|
+
relative to the manifest and must remain on the code USB. Only cameras matching
|
|
184
|
+
a loaded calibration are added to `Robot.cameras`.
|
|
185
|
+
|
|
186
|
+
## Developer Notes
|
|
187
|
+
|
|
188
|
+
There are a number of considerations that have been made in the design of this API.
|
|
189
|
+
Some of these may not be immediately obvious, so they are documented below.
|
|
190
|
+
|
|
191
|
+
- The API is designed to raise exceptions for incorrect actions, such as trying to modify the output dictionary or assign a value directly to the motor object.
|
|
192
|
+
- `MappingProxyType` is used to prevent the user from adding, removing or overwriting keys in any parts of the API that return a dictionary.
|
|
193
|
+
- `tuple` is used to prevent the user from adding, removing or overwriting items in any parts of the API that would return a list.
|
|
194
|
+
- `__slots__` is used to prevent the user from adding, removing or overwriting attributes in any parts of the API.
|
|
195
|
+
- `sr.robot3.serial_wrapper.SerialWrapper` handles automatic reconnection to the serial port if the connection is lost and impleents 3 retries on any serial operation before raising a `BoardDisconnectionError`.
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# psc-sr-robot3
|
|
2
|
+
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
|
|
5
|
+
`psc-sr-robot3` is PSC Robotics' version of [sr-robot3](https://github.com/srobo/sr-robot),
|
|
6
|
+
the Student Robotics Python API. It adds PSC's brain board: GPIO motors and steppers,
|
|
7
|
+
servo drivers and I2C, the brain board LED and battery sensor, the buzzer and gamepads.
|
|
8
|
+
See the [PSC Robotics docs](https://docs.psc-robotics.uk).
|
|
9
|
+
|
|
10
|
+
Your code imports it as `sr.robot3`, the same as Student Robotics' library, so the two
|
|
11
|
+
can't be installed together. The PSC Robotics OS image already has it installed; install
|
|
12
|
+
it on a computer to get code completion and type checking while you write robot code.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install psc-sr-robot3
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
To include OpenCV, for the camera:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install "psc-sr-robot3[vision]"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Versions are Student Robotics' base version followed by PSC's own release number:
|
|
27
|
+
2026.0.3.18 is PSC release 18 of sr-robot3 2026.0.3.
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
The main entry point for the API is the `Robot` class.
|
|
32
|
+
Instantiating this class will automatically detect and connect to any supported SR v4 boards connected to the device.
|
|
33
|
+
All SR boards are optional; connected boards are initialized and exposed as usual. By default, the `Robot` class waits for a start signal before continuing. When a power board is present, its start button is used; without one, the start signal can come from Astoria.
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
|
|
37
|
+
from sr.robot3 import Robot
|
|
38
|
+
|
|
39
|
+
r = Robot()
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
To disable the waiting for the start button, you can pass `wait_for_start=False` to the constructor.
|
|
44
|
+
The `wait_for_start` method needs to be called before the metadata is available.
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
|
|
48
|
+
from sr.robot3 import Robot
|
|
49
|
+
|
|
50
|
+
r = Robot(wait_for_start=False)
|
|
51
|
+
|
|
52
|
+
# Setup in here
|
|
53
|
+
|
|
54
|
+
r.wait_start()
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
An Arduino running firmware version 4 or later can drive a step/direction
|
|
59
|
+
stepper driver with `arduino.stepper_move(step_pin, direction_pin, steps)`. The
|
|
60
|
+
call blocks until the requested pulses are emitted; pass `direction=False` to
|
|
61
|
+
drive DIR low, and use `step_delay_us` to set the low interval between pulses.
|
|
62
|
+
Moves are limited to 350 ms per command so they fit within the serial timeout.
|
|
63
|
+
This API does not provide acceleration or track motor position.
|
|
64
|
+
|
|
65
|
+
### Buzzer
|
|
66
|
+
|
|
67
|
+
`robot.buzzer.buzz(frequency, duration, blocking=False)` plays a tone on the
|
|
68
|
+
buzzer connected to the brain board, like the Student Robotics power board's
|
|
69
|
+
`piezo.buzz()`. `Note` values such as `Note.A6` can be used for the frequency.
|
|
70
|
+
A new tone replaces the one playing. Tones are played by the robot's status
|
|
71
|
+
service, which also beeps when code is waiting for the start button, when start
|
|
72
|
+
is pressed, and with fast short beeps when code crashes.
|
|
73
|
+
|
|
74
|
+
### Steppers on the brain board's GPIO pins
|
|
75
|
+
|
|
76
|
+
`robot.brain.stepper_move(step_pin, direction_pin, steps)` drives a
|
|
77
|
+
step/direction stepper driver wired to the Pi's GPIO header, using BCM GPIO
|
|
78
|
+
numbers. It takes the same arguments as `arduino.stepper_move`, but has no
|
|
79
|
+
350 ms limit: `steps` can be up to 1000000 and `step_delay_us` from 50 to
|
|
80
|
+
1000000. Timing is done in software, so step timing can vary slightly. GPIO 5,
|
|
81
|
+
13 and 18 are used by the robot and can't be used.
|
|
82
|
+
|
|
83
|
+
### Multiple cameras
|
|
84
|
+
|
|
85
|
+
Every connected camera with a calibration is available in `robot.cameras`.
|
|
86
|
+
`robot.camera` still works when exactly one camera is connected.
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from sr.robot3 import Robot
|
|
90
|
+
|
|
91
|
+
r = Robot()
|
|
92
|
+
|
|
93
|
+
for camera_id, camera in r.cameras.items():
|
|
94
|
+
print(camera_id, camera.see())
|
|
95
|
+
|
|
96
|
+
front = r.cameras["A1B2C3D4"]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Cameras are keyed by their USB serial number. Cameras with no serial number,
|
|
100
|
+
a generic placeholder serial or a serial shared with another connected camera
|
|
101
|
+
are keyed by the USB port they are plugged into, such as `usb-1-1.2`. Keep
|
|
102
|
+
those cameras in the same ports so their names stay the same. The camera
|
|
103
|
+
calibration dialog in the robot web UI shows the name of each connected camera.
|
|
104
|
+
Cameras of the same model share one calibration.
|
|
105
|
+
|
|
106
|
+
### Camera calibrations
|
|
107
|
+
|
|
108
|
+
The bundled Logitech calibrations are used automatically and are read-only in
|
|
109
|
+
the camera calibration dialog. Custom calibration directories can be added to the code
|
|
110
|
+
USB root with either `camera-calibrations.toml`:
|
|
111
|
+
|
|
112
|
+
```toml
|
|
113
|
+
calibrations = ["camera-calibrations"]
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
or `camera-calibrations.json`:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{"calibrations": ["camera-calibrations"]}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Place the AprilVision calibration XML files in the listed directory. Paths are
|
|
123
|
+
relative to the manifest and must remain on the code USB. Only cameras matching
|
|
124
|
+
a loaded calibration are added to `Robot.cameras`.
|
|
125
|
+
|
|
126
|
+
## Developer Notes
|
|
127
|
+
|
|
128
|
+
There are a number of considerations that have been made in the design of this API.
|
|
129
|
+
Some of these may not be immediately obvious, so they are documented below.
|
|
130
|
+
|
|
131
|
+
- The API is designed to raise exceptions for incorrect actions, such as trying to modify the output dictionary or assign a value directly to the motor object.
|
|
132
|
+
- `MappingProxyType` is used to prevent the user from adding, removing or overwriting keys in any parts of the API that return a dictionary.
|
|
133
|
+
- `tuple` is used to prevent the user from adding, removing or overwriting items in any parts of the API that would return a list.
|
|
134
|
+
- `__slots__` is used to prevent the user from adding, removing or overwriting attributes in any parts of the API.
|
|
135
|
+
- `sr.robot3.serial_wrapper.SerialWrapper` handles automatic reconnection to the serial port if the connection is lost and impleents 3 retries on any serial operation before raising a `BoardDisconnectionError`.
|