Skip to content
Merged
Show file tree
Hide file tree
Changes from 250 commits
Commits
Show all changes
295 commits
Select commit Hold shift + click to select a range
c546a1c
Remove API warnings
virtuald Apr 16, 2018
3e0951f
Upgrade to use the realistic tankmodel for physics
virtuald Apr 20, 2018
939b958
Add drivetrain characterization
virtuald Apr 30, 2018
fcdb7a6
Update examples to use new drivetrain model
virtuald Apr 30, 2018
4991a87
Merge pull request #17 from robotpy/tankmodel
virtuald May 1, 2018
47dcacc
Do multivariate linear regression
virtuald May 2, 2018
b31384c
Cleanup plotting, deal with empty data without crashing
virtuald May 2, 2018
f3516dc
Move drivetrain characterization code to https://github.com/robotpy/r…
virtuald May 5, 2018
6f70478
Update test list
virtuald May 6, 2018
49b7336
Add pint to travis requirements
virtuald May 6, 2018
bdd6f4a
Split NavX tests out
virtuald Jun 8, 2018
98c6daf
Change examples to use the new NavX package
virtuald Jun 8, 2018
d41243b
Add python 3.7 testing for travis
virtuald Nov 21, 2018
30baa82
Merge pull request #19 from robotpy/py37
virtuald Nov 26, 2018
0ef58c6
Reformat examples using black
virtuald Nov 10, 2018
581ae1e
Merge pull request #18 from robotpy/black
virtuald Dec 2, 2018
66c8f11
Add Shuffleboard example
auscompgeek Jan 28, 2019
0605fb2
shuffleboard: Fix copyright year
auscompgeek Jan 29, 2019
dcfad95
Merge pull request #21 from robotpy/sb-copyright
virtuald Feb 5, 2019
832168a
Remove Python 3.5 and add 3.8 to CI
M1sterShad0w Oct 18, 2019
3fc4ca5
Update magicbot examples to use variable annotation syntax
M1sterShad0w Oct 18, 2019
04b5930
Update magicbot autonomous examples to use variable annotation syntax
M1sterShad0w Oct 18, 2019
c4cb69b
Update magicbot constant examples to use variable annotation syntax
M1sterShad0w Oct 18, 2019
fd9a75a
Merge pull request #26 from M-Shadow/master
virtuald Oct 18, 2019
129c8aa
Start fixing examples for new libraries
CrispyBacon1999 Jan 11, 2020
7a9914a
Add game data example
CrispyBacon1999 Jan 11, 2020
67d06b7
Format using black
CrispyBacon1999 Jan 11, 2020
086520a
Add game-data to tests
CrispyBacon1999 Jan 11, 2020
db233a1
Add wpilib.drive import
CrispyBacon1999 Jan 13, 2020
4f2e26a
Add wpilib.drive import
CrispyBacon1999 Jan 13, 2020
f35965f
Change joystick to port 0 so it's the first port
CrispyBacon1999 Jan 13, 2020
f9c5134
Switch to IterativeRobot instead of SampleRobot
CrispyBacon1999 Jan 13, 2020
5d65ef3
Switch to IterativeRobot
CrispyBacon1999 Jan 13, 2020
9e5f5cd
Format using black
CrispyBacon1999 Jan 13, 2020
7495218
Switch to IterativeRobot
CrispyBacon1999 Jan 13, 2020
ac719e9
Change to DifferentialDrive (instead of RobotDrive)
CrispyBacon1999 Jan 13, 2020
7f8f1c2
Switch to joystick port 0 and use Talon instead of Jaguar
CrispyBacon1999 Jan 13, 2020
69d1c2f
Switch to TimedRobot instead of IterativeRobot
CrispyBacon1999 Jan 15, 2020
208bf6b
Switch to TimedRobot instead of IterativeRobot
CrispyBacon1999 Jan 15, 2020
b2f0e4c
Missed a couple
CrispyBacon1999 Jan 15, 2020
7be9d54
Merge pull request #27 from CrispyBacon1999/master
virtuald Jan 17, 2020
fe380a0
Merge pull request #1 from robotpy/master
MrRSquared Jan 17, 2020
da23ad2
Update more to timedrobot
CrispyBacon1999 Jan 27, 2020
703cef2
Removed iterative, as TimedRobot is the new version
CrispyBacon1999 Jan 27, 2020
72b8f23
Merge branch 'master' of https://github.com/CrispyBacon1999/examples
CrispyBacon1999 Jan 27, 2020
39626d8
Merge branch 'master' into master
CrispyBacon1999 Jan 27, 2020
97eb84a
Merge pull request #29 from CrispyBacon1999/master
virtuald Jan 28, 2020
c30e751
Merge pull request #2 from robotpy/master
MrRSquared Feb 7, 2020
c3e6363
Update Navx to 2020
lekofraggle Feb 7, 2020
edc18b0
Added Xbox Mecanum Drive Example
lekofraggle Feb 7, 2020
bac77f9
Removed wpilib.drive.drive method to update for 2020 codebase.
lekofraggle Feb 7, 2020
e4c016e
Added TimedRobot to Stateful-Auto and more states to avoid timeouts
MrRSquared Feb 8, 2020
a390611
Made recommended changes and ran through Black.
MrRSquared Feb 8, 2020
bce0bb2
Merge pull request #30 from Oscats/master
virtuald Feb 9, 2020
7ccf6b9
Update physics example for 2020
virtuald Feb 14, 2020
b527d17
Merge pull request #3 from robotpy/master
MrRSquared Feb 14, 2020
d53034b
Changed robot_drive in auto.
MrRSquared Feb 14, 2020
f95c180
Merge pull request #31 from Oscats/master
virtuald Feb 14, 2020
31ea843
Delete pyfrc_test.py
virtuald Feb 22, 2020
5fd7503
Update stateful-autonomous to use new methods
auscompgeek Feb 27, 2020
e598bfd
Merge pull request #32 from robotpy/auto-chooser-split
virtuald Feb 27, 2020
ea10ef9
Update physics examples for 2020
virtuald Feb 29, 2020
8ecdd14
Merge pull request #33 from robotpy/pyfrc-2020
virtuald Mar 3, 2020
1317b0a
Fix navx-rotate-to-angle example
virtuald Mar 3, 2020
1772d5a
Rewrote CrispyBacon1999's robotopy-examples, excluding the directory …
benjiboy50fonz Aug 30, 2020
9a8d0c6
Running tests on all the desired files.
benjiboy50fonz Aug 30, 2020
71a713b
Modified the git ignore to exclude my libraries.
benjiboy50fonz Aug 30, 2020
6602179
Modified the travis config.
benjiboy50fonz Aug 30, 2020
b2e9e10
A
benjiboy50fonz Sep 1, 2020
b0d8ad4
Merge pull request #36 from benjiboy50fonz/master
virtuald Sep 4, 2020
81839a6
Format with black
virtuald Jan 22, 2021
237384d
Update physics example for 2021
virtuald Jan 22, 2021
b85bae9
Move command v1 examples to a single directory
virtuald Feb 6, 2021
178ba73
Add commands v2 example
virtuald Feb 6, 2021
2c2fd14
Fix commandsv2 example
TheTripleV Feb 8, 2021
da397d4
Merge pull request #41 from TheTripleV/main
virtuald Feb 8, 2021
61889ab
move to github actions (#42)
TheTripleV Feb 8, 2021
e58631f
Changed gearsbot and physics-camsim to TimedRobot rather than Iterati…
benjiboy50fonz Jan 29, 2021
b0ef158
Finished up the physics-camsim example after a little debugging.
benjiboy50fonz Feb 7, 2021
40aac9d
Reformatted all of these with Black.
benjiboy50fonz Feb 7, 2021
50ee847
Reformatted and tried to debug my sim. I think it's just on my end, s…
benjiboy50fonz Feb 7, 2021
8e19b0b
Final touches to the camsim; it appears to be working now.
benjiboy50fonz Feb 8, 2021
4536f05
Merge pull request #40 from benjiboy50fonz/master
virtuald Feb 9, 2021
7a300cc
Wrote RamseteCommand Example (#43)
benjiboy50fonz Feb 20, 2021
56d7d7d
Make robot.py executable
virtuald Feb 20, 2021
097f78d
Add ROMI example (#44)
virtuald Feb 22, 2021
c3d230d
Remove nonsense from example
virtuald Jan 13, 2022
c7dd2a0
Update black formatting
virtuald Jan 24, 2022
0a8dec0
Remove old commands examples
virtuald Jan 24, 2022
8305845
Fix hatchbot example
virtuald Jan 24, 2022
3627899
Fix ramsete example
virtuald Jan 24, 2022
fdbc13b
Update romi example to use vendordep library
virtuald Feb 14, 2022
6edee9a
Remove config.json, not used anymore
virtuald Feb 19, 2022
1b56c32
Add simgui stuff to .gitignore
virtuald Feb 19, 2022
7966377
Fix game-data example for 2022
virtuald Feb 20, 2022
b18e6a7
Fix mecanum API
virtuald Feb 20, 2022
6faa7c2
Remove obsolete pathfinder example
virtuald Feb 20, 2022
8891dc6
Upgrade physics to use objects from robot
virtuald Feb 23, 2022
bf8af7e
Fix old wpilib.controller imports
virtuald Feb 23, 2022
5514d89
Fix timed robot tests
virtuald Feb 23, 2022
77212a6
Add arm simulation example
virtuald Mar 6, 2022
2030128
Update .gitignore
virtuald Mar 6, 2022
01d5abc
Update license
virtuald Mar 6, 2022
84cf1b1
Add elevator example
virtuald Mar 6, 2022
eda0d45
Fix usage of pytest.approx
virtuald Mar 6, 2022
4c41644
Fix navx examples
virtuald Mar 6, 2022
4931daf
Fix run_tests
virtuald Mar 6, 2022
3e58ced
Remove navx examples, update README
virtuald Mar 6, 2022
8fdfd8b
Fix camsim example rotation
virtuald Apr 12, 2022
5d91e6b
Enable tests again
virtuald Apr 27, 2022
ff8e533
Merge pull request #48 from robotpy/enable-tests
virtuald Apr 27, 2022
7484a6d
Update mecanum drive example for consistency with upstream (#50)
BerkeSinanYetkin Sep 4, 2022
6958fd8
Adding Addressabled LED class example (#51)
megarubber Sep 29, 2022
a4cd347
Added mechanism2d example. (#52)
BerkeSinanYetkin Oct 2, 2022
9f2f08f
Added profiled pid elevator example. (#54)
BerkeSinanYetkin Dec 8, 2022
956ba32
Update for 2023-beta
virtuald Nov 13, 2022
5d5a91b
Update docs and tests in preparation for 2023 merge
virtuald Dec 18, 2022
c667663
Fix ramsete example for 2023 updates
virtuald Dec 18, 2022
8eee4d6
Merge pull request #57 from robotpy/2023-beta
virtuald Dec 18, 2022
441100d
Add Frisbeebot example
BerkeSinanYetkin Dec 18, 2022
d58e6f8
Update frisbee-bot example
virtuald Dec 19, 2022
1f8812a
Merge pull request #59 from robotpy/frisbeebot
virtuald Dec 19, 2022
70fe181
Add armbotoffboard example (#53)
megarubber Dec 19, 2022
3d77350
Move armbotoffboard to commands-v2
virtuald Dec 19, 2022
de4ced4
Add elevator trapezoid profile example (#61)
BerkeSinanYetkin Dec 24, 2022
f35f4b3
Add porting guide to help new contributors
virtuald Dec 19, 2022
7292c59
Merge pull request #60 from robotpy/porting-guide
virtuald Dec 24, 2022
2fd215a
Add gyro-drive-commands example (#63)
BerkeSinanYetkin Dec 27, 2022
bc7f1d6
add drivedistanceoffboard example (#64)
BerkeSinanYetkin Dec 31, 2022
8d1fdcf
Add selectcommand example (#62)
megarubber Dec 31, 2022
396b8b7
run_tests: Re-enable magicbot-simple example
auscompgeek Jan 1, 2023
d224fee
run_tests: Re-sort list of examples to test
davo-canva Jan 2, 2023
a0c3e26
Fix armbotoffboard arm subsystem (#68)
auscompgeek Jan 3, 2023
82e58d5
Add hatchbot-inlined example (#67)
BerkeSinanYetkin Jan 7, 2023
7710016
Fix shuffleboard example
virtuald Dec 31, 2022
570649b
Bump example requirements
virtuald Jan 7, 2023
5918a78
set inverted of right motor to true
megarubber Jan 31, 2023
89e777c
added elevator trapezoid profile example
BerkeSinanYetkin Dec 20, 2022
45aaa64
Run black 23.1.0
auscompgeek Feb 1, 2023
f800499
Update getting-started (#72)
BerkeSinanYetkin Feb 5, 2023
4b225a4
Add armbot example (#70)
megarubber Feb 6, 2023
d6fd6ec
Run black formatter
virtuald Feb 6, 2023
0b63364
Fix mecanum example to match wpilib example
virtuald Feb 8, 2023
4eb0b17
Fix cmd.run* usage
virtuald Feb 12, 2023
0009933
Update cscore-intermediate-vision example
virtuald Mar 15, 2023
1c39a74
armbot: Run black
auscompgeek Aug 5, 2023
b42a36d
Re-enable stateful-autonomous test (#76)
auscompgeek Aug 5, 2023
5701762
Add beta note
virtuald Nov 5, 2023
142e26c
Update examples for 2024
virtuald Nov 5, 2023
d61f7aa
Merge pull request #78 from robotpy/2024-beta
virtuald Dec 1, 2023
6c60e2c
Added relay example.
mbardoe Dec 2, 2023
02ee733
comments in greater alignment with the comments in allwpilib examples
mbardoe Dec 2, 2023
fd5e680
Editted out the variable that saved joystick channel for greater alig…
mbardoe Dec 3, 2023
7f59bda
added relay to run_tests.sh
mbardoe Dec 3, 2023
07344bf
Merge pull request #80 from mbardoeChoate/relay
virtuald Dec 3, 2023
045256e
Add PotentiometerPID example
BerkeSinanYetkin Feb 5, 2023
8705e1b
Merge pull request #73 from qubit-robotics/potantiometerpid
virtuald Dec 3, 2023
4618013
Update arm simulation example
virtuald Dec 3, 2023
aef067f
Merge pull request #81 from robotpy/arm-sim-update
virtuald Dec 3, 2023
1293d23
Added in solenoid/robot.py
mbardoe Dec 3, 2023
316f68e
Merge pull request #82 from mbardoeChoate/solenoid
virtuald Dec 3, 2023
cabf1c4
add CANPDP example
fletch3555 Dec 4, 2023
a5a5d5f
Merge pull request #86 from fletch3555/add_canpdp_example
virtuald Dec 5, 2023
edcb7c5
add arcade-drive-xbox-controller example and update arcade-drive
fletch3555 Dec 3, 2023
a3158c6
add tank-drive-xbox-controller example and update tank-drive
fletch3555 Dec 3, 2023
31db31f
Merge pull request #83 from fletch3555/add_arcade-drive-xbox-controll…
virtuald Dec 5, 2023
359eb42
Merge pull request #84 from fletch3555/add_tank-drive-xbox-controller…
virtuald Dec 5, 2023
346dafb
make directory structure flat
jasondaming Dec 5, 2023
ce50591
Merge pull request #88 from jasondaming/flat
virtuald Dec 6, 2023
b6264d5
Add i2c-communication example (#90)
fletch3555 Dec 9, 2023
a42b8a6
add differential-drive-bot example (#87)
fletch3555 Dec 9, 2023
28ed425
Created Ultrasonic example (#85)
mbardoeChoate Dec 9, 2023
affd090
Add digital-communication example
fletch3555 Dec 7, 2023
d81571c
Add dutycycle-encoder example
fletch3555 Dec 7, 2023
97103b8
Add dutycycle-input example
fletch3555 Dec 7, 2023
c0a3916
Add encoder example
fletch3555 Dec 7, 2023
7555bc3
Add flywheel-bangbang-controller example
fletch3555 Dec 7, 2023
1adbd33
Add gyro-mecanum example
fletch3555 Dec 7, 2023
22e986d
Add hid-rumble example
fletch3555 Dec 7, 2023
ac857df
reformating/updating to match java examples
fletch3555 Dec 7, 2023
1bdc112
formatting
fletch3555 Dec 7, 2023
7e6102a
Remove html comments
fletch3555 Dec 8, 2023
b8af09f
Switch to k-prefix naming convention for constants
fletch3555 Dec 7, 2023
b51d71b
Standardize header to match #93
fletch3555 Dec 7, 2023
4d8f4b0
Add quick-vision and ramsete-controller examples
fletch3555 Dec 13, 2023
bc0dc95
formatting
fletch3555 Dec 17, 2023
cde463c
fixing docstring copy/paste error
fletch3555 Dec 17, 2023
31f0aae
fix styling and copyright header
fletch3555 Dec 17, 2023
4fd5d3e
Move flywheel sim functionality to physics.py
fletch3555 Dec 17, 2023
7f1d55a
Standardize robot.py styling for copyright header (#93)
fletch3555 Dec 18, 2023
ac76856
Merge pull request #91 from fletch3555/low-hanging-fruit
virtuald Dec 19, 2023
0f89dc5
Add mecanum-bot example (#92)
fletch3555 Dec 19, 2023
5260677
Add ultrasonic-pid example (#94)
fletch3555 Dec 20, 2023
4a238b4
rename example project folder names to match java
fletch3555 Dec 20, 2023
d95f49a
Renaming to match case of cpp examples
fletch3555 Dec 20, 2023
e2d8746
Sync ramsete example with java ramsete-command example (#96)
fletch3555 Dec 21, 2023
f02b736
Merge pull request #95 from fletch3555/rename-examples-for-consistency
virtuald Dec 21, 2023
a27cf54
Merge pull request #97 from fletch3555/rename-examples-for-consistency
virtuald Dec 22, 2023
de88a37
Add SwerveBot example (#98)
megarubber Dec 29, 2023
9ab0baa
Add StateSpaceFlywheelSysId example (#99)
megarubber Jan 1, 2024
810dd34
Update CONTRIBUTING.md
Suave101 Jan 4, 2024
bcdee3e
Merge pull request #102 from Suave101/contribution-guide-addition-pro…
virtuald Jan 4, 2024
1e8181c
Add vision testing note to CONTRIBUTING.md (#104)
Suave101 Jan 5, 2024
de5f6fd
Remove wpilib.run for 2024
virtuald Jan 6, 2024
be6c228
Merge pull request #106 from robotpy/remove-wpilib-run
virtuald Jan 6, 2024
3f5efed
[Rebase] add AprilTagVision example (#107)
Suave101 Jan 8, 2024
f337ff9
Add AxisCamera sample (#103)
Suave101 Jan 8, 2024
b120f84
Update AprilTag example error bits
sciencewhiz Jan 15, 2024
296b827
Merge pull request #110 from sciencewhiz/AprilTagErrorBits
virtuald Jan 15, 2024
6c0be2b
Update commands examples
virtuald Jan 24, 2024
04fc00a
Merge pull request #114 from robotpy/update-commands
virtuald Jan 24, 2024
1212497
Add & adapt State-Space examples (#101)
megarubber Jan 24, 2024
c7dbad2
Run black 24.1.0
auscompgeek Jan 26, 2024
479a450
Update romi reference
virtuald Feb 7, 2024
def7f15
Add ROMI to installed requirements
virtuald Feb 7, 2024
719bfe2
Add SysId example (#111)
LucienMorey Mar 10, 2024
7f67a90
Changed the swervemodule getPosition function to use encoder distance
BrysonSmith15 Dec 4, 2024
3208492
Merge pull request #121 from BrysonSmith15/swerve_example_position
virtuald Dec 4, 2024
6ea4b47
ci: Update to macOS 14
auscompgeek Dec 30, 2024
14b73a9
ci: Switch to macOS 13 for 2024
auscompgeek Jan 3, 2025
1992b05
ci: Pin numpy to 1.x for 2024
auscompgeek Jan 3, 2025
b352b49
Add pre-commit config
auscompgeek Dec 30, 2024
49f9314
Disable StateSpaceArm and StateSpaceElevator
auscompgeek Jan 3, 2025
a8da66d
Update for 2025
auscompgeek Jan 3, 2025
67d2a71
Merge pull request #124 from robotpy/2025
auscompgeek Jan 4, 2025
a432288
MagicbotSimple: Add magicbot.feedback usage
auscompgeek Jan 3, 2025
f64f366
Merge pull request #123 from robotpy/magicbot-feedback
virtuald Jan 4, 2025
33ac31a
Remove Deprecated Axis Camera Example (#126)
Suave101 Jan 5, 2025
4c3917a
Revert "Remove Deprecated Axis Camera Example (#126)"
auscompgeek Jan 5, 2025
be7d23e
Convert AxisCamera example to generic HTTP camera
auscompgeek Jan 5, 2025
09a2964
Merge pull request #128 from robotpy/revert-126-RemoveAxisCamera
auscompgeek Jan 6, 2025
486df72
Add XrpReference example
virtuald Apr 20, 2024
cd16f66
Merge pull request #118 from robotpy/xrp
virtuald Jan 24, 2025
4b0cea0
Update README to be year-agnostic
virtuald Jan 24, 2025
14d7ffc
Merge pull request #122 from robotpy/pre-commit
auscompgeek Jan 27, 2025
b2d1165
Allow manually starting CI
auscompgeek Feb 9, 2025
dd04fd6
Update examples using MotorControllerGroup (#130)
LED-esma Apr 24, 2025
ce32e53
Update example
LED-esma May 6, 2025
875acc3
Merge pull request #131 from LED-esma/physics_update
virtuald May 6, 2025
e2127a4
Update GitHub Actions
auscompgeek Aug 19, 2025
e7a0d1c
ci: Run on 2027 branch
auscompgeek Aug 19, 2025
d5929ba
Update ROMI/XRP examples to use run-romi/run-xrp
virtuald Dec 28, 2025
d626515
Merge pull request #134 from robotpy/run-romi-xrp
virtuald Dec 29, 2025
d88ac48
Import https://github.com/robotpy/examples
virtuald Jan 17, 2026
8b22c50
Remove examples not present in allwpilib
virtuald Jan 5, 2026
c7b6911
Remove examples standalone repo files
virtuald Jan 5, 2026
75097bb
Add new examples
virtuald Jan 5, 2026
178e904
Add test-examples to rdev and run examples tests in CI
virtuald Jan 5, 2026
8fcdbdc
Update examples for 2027
virtuald Jan 5, 2026
e8d6201
Mark opmode test as xfail for now
virtuald Jan 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/dist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,10 @@ jobs:
run: |
python -m devtools ci install-test-pure-wheels

- name: Test examples
run: |
python -m devtools test-examples

- name: Ensure all headers are accounted for
run: |
python -m devtools ci scan-headers
Expand Down
2 changes: 2 additions & 0 deletions devtools/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from .ctx import Context
from . import ci
from . import examples
from . import update_pyproject


Expand Down Expand Up @@ -34,6 +35,7 @@ def main(ctx: click.Context, verbose: bool):


main.add_command(ci.ci)
main.add_command(examples.test_examples)
main.add_command(update_pyproject.update_pyproject)


Expand Down
105 changes: 105 additions & 0 deletions devtools/examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import dataclasses
import os
import pathlib
import subprocess
import sys
import typing as T

import click
import tomlkit

from .util import parse_input, run_cmd


def _validate_example_list(root: pathlib.Path, expected_dirs: T.Sequence[str]) -> None:
expected = sorted(f"{name}/robot.py" for name in expected_dirs)
actual = sorted(p.relative_to(root).as_posix() for p in root.rglob("robot.py"))

if expected == actual:
return

missing = sorted(set(expected) - set(actual))
extra = sorted(set(actual) - set(expected))
for path in missing:
print(f"Missing: {path}")
for path in extra:
print(f"Extra: {path}")

if not os.environ.get("FORCE_ANYWAYS"):
print("ERROR: Not every robot.py file is in the list of tests!")
sys.exit(1)


@dataclasses.dataclass
class ExamplesTests:
base: T.List[str]
ignored: T.List[str]


@dataclasses.dataclass
class ExamplesConfig:
tests: ExamplesTests


def _load_tests_config(config_path: pathlib.Path) -> ExamplesConfig:
try:
data = tomlkit.parse(config_path.read_text(encoding="utf-8"))
except FileNotFoundError:
raise click.ClickException(f"Missing tests config: {config_path}")
except Exception as exc:
raise click.ClickException(f"Invalid tests config: {config_path}: {exc}")

try:
return parse_input(data, ExamplesConfig, config_path)
except Exception as exc:
raise click.ClickException(str(exc))


@click.command(name="test-examples")
@click.argument("test_name", required=False)
@click.option("-x", "--exitfirst", is_flag=True, help="Exit on first failed test.")
def test_examples(test_name: str | None, exitfirst: bool) -> None:
"""Run tests on robot examples."""
root = pathlib.Path(__file__).parent.parent / "examples" / "robot"
config_path = root / "examples.toml"

cfg = _load_tests_config(config_path)
base_tests = cfg.tests.base
ignored_tests = cfg.tests.ignored

every_tests = [*base_tests, *ignored_tests]
_validate_example_list(root, every_tests)

tests_to_run = base_tests
if test_name:
if test_name not in every_tests:
raise click.BadParameter(f"unknown example {test_name}")
tests_to_run = [test_name]

failed_tests = []

for example_name in tests_to_run:
test_dir = root / example_name
print(test_dir.resolve())
try:
run_cmd(
sys.executable,
"-m",
"robotpy",
"test",
"--builtin",
cwd=test_dir,
)
except subprocess.CalledProcessError:
print(f"Test in {test_dir.resolve()} failed")
failed_tests.append(example_name)
if exitfirst:
break

if failed_tests:
print("Failed tests:")
for name in failed_tests:
print(f"- {name}")
sys.exit(1)

print("All tests successful!")
22 changes: 22 additions & 0 deletions examples/robot/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
*.py[ocd]
__pycache__
.coverage
.cache

.vscode/
.deploy_cfg
deploy.json

.project
.pydevproject

pyproject.toml
wpilib_preferences.json

imgui.ini
simgui*.json

opkg_cache
pip_cache

networktables.*
45 changes: 45 additions & 0 deletions examples/robot/AddressableLED/robot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env python3
#
# Copyright (c) FIRST and other WPILib contributors.
# Open Source Software; you can modify and/or share it under the terms of
# the WPILib BSD license file in the root directory of this project.
#

import wpilib
import wpimath.units


class MyRobot(wpilib.TimedRobot):
def __init__(self) -> None:
super().__init__()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we were keeping robotInit for Python, per wpilibsuite/allwpilib#6623 (comment)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well. I definitely forgot about that.


# SmartIO port 1
self.led = wpilib.AddressableLED(1)

# Reuse buffer
# Default to a length of 60
self.ledData = [wpilib.AddressableLED.LEDData() for _ in range(60)]
self.led.setLength(len(self.ledData))

# Set the data
self.led.setData(self.ledData)

# Create an LED pattern that will display a rainbow across
# all hues at maximum saturation and half brightness
self.rainbow = wpilib.LEDPattern.rainbow(255, 128)

# Our LED strip has a density of 120 LEDs per meter
self.kLedSpacing = 1 / 120.0

# Create a new pattern that scrolls the rainbow pattern across the LED strip, moving at a
# speed of 1 meter per second.
self.scrollingRainbow = self.rainbow.scrollAtAbsoluteSpeed(
1,
self.kLedSpacing,
)

def robotPeriodic(self) -> None:
# Update the buffer with the rainbow animation
self.scrollingRainbow.applyTo(self.ledData)
# Set the LEDs
self.led.setData(self.ledData)
26 changes: 26 additions & 0 deletions examples/robot/AprilTagsVision/robot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env python3
#
# Copyright (c) FIRST and other WPILib contributors.
# Open Source Software; you can modify and/or share it under the terms of
# the WPILib BSD license file in the root directory of this project.
#


import wpilib
import wpilib.cameraserver


class MyRobot(wpilib.TimedRobot):
"""
This is a demo program showing the detection of AprilTags. The image is acquired from the USB
camera, then any detected AprilTags are marked up on the image and sent to the dashboard.
Be aware that the performance on this is much worse than a coprocessor solution!
"""

def __init__(self):
super().__init__()
# Your image processing code will be launched via a stub that will set up logging and initialize NetworkTables
# to talk to your robot code.
# https://robotpy.readthedocs.io/en/stable/vision/roborio.html#important-notes

wpilib.CameraServer.launch("vision.py:main")
152 changes: 152 additions & 0 deletions examples/robot/AprilTagsVision/vision.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#
# Copyright (c) FIRST and other WPILib contributors.
# Open Source Software; you can modify and/or share it under the terms of
# the WPILib BSD license file in the root directory of this project.
#


import ntcore
import robotpy_apriltag
from cscore import CameraServer

import cv2
import numpy as np


#
# This code will work both on a RoboRIO and on other platforms. The exact mechanism
# to run it differs depending on whether you’re on a RoboRIO or a coprocessor
#
# https://robotpy.readthedocs.io/en/stable/vision/code.html


def main():
detector = robotpy_apriltag.AprilTagDetector()

# look for tag36h11, correct 1 error bit (hamming distance 1)
# hamming 1 allocates 781KB, 2 allocates 27.4 MB, 3 allocates 932 MB
# max of 1 recommended for RoboRIO 1, while hamming 2 is feasible on the RoboRIO 2
detector.addFamily("tag36h11", 1)

# Set up Pose Estimator - parameters are for a Microsoft Lifecam HD-3000
# (https://www.chiefdelphi.com/t/wpilib-apriltagdetector-sample-code/421411/21)
poseEstConfig = robotpy_apriltag.AprilTagPoseEstimator.Config(
0.1651,
699.3778103158814,
677.7161226393544,
345.6059345433618,
207.12741326228522,
)
estimator = robotpy_apriltag.AprilTagPoseEstimator(poseEstConfig)

# Get the UsbCamera from CameraServer
camera = CameraServer.startAutomaticCapture()

# Set the resolution
camera.setResolution(640, 480)

# Get a CvSink. This will capture Mats from the camera
cvSink = CameraServer.getVideo()

# Set up a CvSource. This will send images back to the Dashboard
outputStream = CameraServer.putVideo("Detected", 640, 480)

# Mats are very memory expensive. Let's reuse these.
mat = np.zeros((480, 640, 3), dtype=np.uint8)
grayMat = np.zeros(shape=(480, 640), dtype=np.uint8)

# Instantiate once
tags = []
outlineColor = (0, 255, 0)
crossColor = (0, 0, 255)

# Output the list to Network Tables
tagsTable = ntcore.NetworkTableInstance.getDefault().getTable("apriltags")
pubTags = tagsTable.getIntegerArrayTopic("tags").publish()

try:
while True:
# Tell the CvSink to grab a frame from the camera and put it
# in the source mat. If there is an error notify the output.
if cvSink.grabFrame(mat) == 0:
# Send the output frame the error
outputStream.notifyError(cvSink.getError())

# Skip the rest of the current iteration
continue

cv2.cvtColor(mat, cv2.COLOR_RGB2GRAY, dst=grayMat)

detections = detector.detect(grayMat)

# have not seen any tags yet
tags.clear()

for detection in detections:
# remember we saw this tag
tags.append(detection.getId())

# draw lines around the tag
for i in range(4):
j = (i + 1) % 4
point1 = (
int(detection.getCorner(i).x),
int(detection.getCorner(i).y),
)
point2 = (
int(detection.getCorner(j).x),
int(detection.getCorner(j).y),
)
mat = cv2.line(mat, point1, point2, outlineColor, 2)

# mark the center of the tag
cx = int(detection.getCenter().x)
cy = int(detection.getCenter().y)
ll = 10
mat = cv2.line(
mat,
(cx - ll, cy),
(cx + ll, cy),
crossColor,
2,
)
mat = cv2.line(
mat,
(cx, cy - ll),
(cx, cy + ll),
crossColor,
2,
)

# identify the tag
mat = cv2.putText(
mat,
str(detection.getId()),
(cx + ll, cy),
cv2.FONT_HERSHEY_SIMPLEX,
1,
crossColor,
3,
)

# determine pose
pose = estimator.estimate(detection)

# put pose into dashboard
rot = pose.rotation()
tagsTable.getEntry(f"pose_{detection.getId()}").setDoubleArray(
[pose.X(), pose.Y(), pose.Z(), rot.X(), rot.Y(), rot.Z()]
)

# put list of tags onto dashboard
pubTags.set(tags)

# Give output stream a new image to display
outputStream.putFrame(mat)
finally:
pubTags.close()
detector.close()

# The camera code will be killed when the robot.py program exits. If you wish to perform cleanup,
# you should register an atexit handler. The child process will NOT be launched when running the robot code in
# simulation or unit testing mode
Loading