Skip to content

Commit b2d0024

Browse files
authored
Merge pull request #74 from sciencewhiz/AddTests
Add testing for examples
2 parents 384ca50 + 8566962 commit b2d0024

File tree

21 files changed

+341
-111
lines changed

21 files changed

+341
-111
lines changed

.github/workflows/dist.yml

+11
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,14 @@ jobs:
2222
WPI_ARTIFACTORY_USERNAME: ${{ secrets.WPI_ARTIFACTORY_USERNAME }}
2323
WPI_ARTIFACTORY_TOKEN: ${{ secrets.WPI_ARTIFACTORY_TOKEN }}
2424
PYPI_API_TOKEN: ${{ secrets.PYPI_PASSWORD }}
25+
26+
check-example-headers:
27+
runs-on: ubuntu-latest
28+
steps:
29+
- uses: actions/checkout@v4
30+
- uses: actions/setup-python@v4
31+
with:
32+
python-version: 3.12
33+
- name: Check header
34+
run: python examples/check_header.py
35+
shell: bash

examples/can-arcade-drive/robot.py

+53-27
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
# ----------------------------------------------------------------------------
2-
# Copyright (c) 2017-2018 FIRST. All Rights Reserved.
3-
# Open Source Software - may be modified and shared by FRC teams. The code
4-
# must be accompanied by the FIRST BSD license file in the root directory of
5-
# the project.
6-
# ----------------------------------------------------------------------------
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) FIRST and other WPILib contributors.
4+
# Open Source Software; you can modify and/or share it under the terms of
5+
# the WPILib BSD license file in the root directory of this project.
6+
#
77

88
import rev
99
import wpilib
@@ -25,34 +25,60 @@ def robotInit(self):
2525
#
2626
# The example below initializes four brushless motors with CAN IDs
2727
# 1, 2, 3, 4. Change these parameters to match your setup
28-
self.leftLeadMotor = rev.CANSparkMax(1, rev.CANSparkMax.MotorType.kBrushless)
29-
self.rightLeadMotor = rev.CANSparkMax(3, rev.CANSparkMax.MotorType.kBrushless)
30-
self.leftFollowMotor = rev.CANSparkMax(2, rev.CANSparkMax.MotorType.kBrushless)
31-
self.rightFollowMotor = rev.CANSparkMax(4, rev.CANSparkMax.MotorType.kBrushless)
28+
self.leftLeadMotor = rev.SparkMax(1, rev.SparkMax.MotorType.kBrushless)
29+
self.rightLeadMotor = rev.SparkMax(3, rev.SparkMax.MotorType.kBrushless)
30+
self.leftFollowMotor = rev.SparkMax(2, rev.SparkMax.MotorType.kBrushless)
31+
self.rightFollowMotor = rev.SparkMax(4, rev.SparkMax.MotorType.kBrushless)
3232

3333
# Passing in the lead motors into DifferentialDrive allows any
3434
# commmands sent to the lead motors to be sent to the follower motors.
3535
self.driveTrain = DifferentialDrive(self.leftLeadMotor, self.rightLeadMotor)
3636
self.joystick = wpilib.Joystick(0)
3737

38-
# The RestoreFactoryDefaults method can be used to reset the
39-
# configuration parameters in the SPARK MAX to their factory default
40-
# state. If no argument is passed, these parameters will not persist
41-
# between power cycles
42-
self.leftLeadMotor.restoreFactoryDefaults()
43-
self.rightLeadMotor.restoreFactoryDefaults()
44-
self.leftFollowMotor.restoreFactoryDefaults()
45-
self.rightFollowMotor.restoreFactoryDefaults()
46-
47-
# In CAN mode, one SPARK MAX can be configured to follow another. This
48-
# is done by calling the follow() method on the SPARK MAX you want to
49-
# configure as a follower, and by passing as a parameter the SPARK MAX
50-
# you want to configure as a leader.
38+
# Create new SPARK MAX configuration objects. These will store the
39+
# configuration parameters for the SPARK MAXes that we will set below.
40+
self.globalConfig = rev.SparkMaxConfig()
41+
self.rightLeaderConfig = rev.SparkMaxConfig()
42+
self.leftFollowerConfig = rev.SparkMaxConfig()
43+
self.rightFollowerConfig = rev.SparkMaxConfig()
44+
45+
# Apply the global config and invert since it is on the opposite side
46+
self.rightLeaderConfig.apply(self.globalConfig).inverted(True)
47+
48+
# Apply the global config and set the leader SPARK for follower mode
49+
self.leftFollowerConfig.apply(self.globalConfig).follow(self.leftLeadMotor)
50+
51+
# Apply the global config and set the leader SPARK for follower mode
52+
self.rightFollowerConfig.apply(self.globalConfig).follow(self.rightLeadMotor)
53+
54+
# Apply the configuration to the SPARKs.
55+
#
56+
# kResetSafeParameters is used to get the SPARK MAX to a known state. This
57+
# is useful in case the SPARK MAX is replaced.
5158
#
52-
# This is shown in the example below, where one motor on each side of
53-
# our drive train is configured to follow a lead motor.
54-
self.leftFollowMotor.follow(self.leftLeadMotor)
55-
self.rightFollowMotor.follow(self.rightLeadMotor)
59+
# kPersistParameters is used to ensure the configuration is not lost when
60+
# the SPARK MAX loses power. This is useful for power cycles that may occur
61+
# mid-operation.
62+
self.leftLeadMotor.configure(
63+
self.globalConfig,
64+
rev.SparkBase.ResetMode.kResetSafeParameters,
65+
rev.SparkBase.PersistMode.kPersistParameters,
66+
)
67+
self.leftFollowMotor.configure(
68+
self.leftFollowerConfig,
69+
rev.SparkBase.ResetMode.kResetSafeParameters,
70+
rev.SparkBase.PersistMode.kPersistParameters,
71+
)
72+
self.rightLeadMotor.configure(
73+
self.rightLeaderConfig,
74+
rev.SparkBase.ResetMode.kResetSafeParameters,
75+
rev.SparkBase.PersistMode.kPersistParameters,
76+
)
77+
self.rightFollowMotor.configure(
78+
self.rightFollowerConfig,
79+
rev.SparkBase.ResetMode.kResetSafeParameters,
80+
rev.SparkBase.PersistMode.kPersistParameters,
81+
)
5682

5783
def teleopPeriodic(self):
5884
# Drive with arcade style

examples/can-tank-drive/robot.py

+22-15
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
# ----------------------------------------------------------------------------
2-
# Copyright (c) 2017-2018 FIRST. All Rights Reserved.
3-
# Open Source Software - may be modified and shared by FRC teams. The code
4-
# must be accompanied by the FIRST BSD license file in the root directory of
5-
# the project.
6-
# ----------------------------------------------------------------------------
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) FIRST and other WPILib contributors.
4+
# Open Source Software; you can modify and/or share it under the terms of
5+
# the WPILib BSD license file in the root directory of this project.
6+
#
77

88
import rev
99
import wpilib
@@ -25,15 +25,22 @@ def robotInit(self):
2525
#
2626
# The example below initializes two brushless motors with CAN IDs
2727
# 1 and 2. Change these parameters to match your setup
28-
self.leftMotor = rev.CANSparkMax(1, rev.CANSparkMax.MotorType.kBrushless)
29-
self.rightMotor = rev.CANSparkMax(2, rev.CANSparkMax.MotorType.kBrushless)
30-
31-
# The RestoreFactoryDefaults method can be used to reset the
32-
# configuration parameters in the SPARK MAX to their factory default
33-
# state. If no argument is passed, these parameters will not persist
34-
# between power cycles
35-
self.leftMotor.restoreFactoryDefaults()
36-
self.rightMotor.restoreFactoryDefaults()
28+
self.leftMotor = rev.SparkMax(1, rev.SparkMax.MotorType.kBrushless)
29+
self.rightMotor = rev.SparkMax(2, rev.SparkMax.MotorType.kBrushless)
30+
31+
# Configure for factory defaults and invert right side motor
32+
self.globalConfig = rev.SparkMaxConfig()
33+
self.rightConfig = self.globalConfig.inverted(True)
34+
self.leftMotor.configure(
35+
self.globalConfig,
36+
rev.SparkBase.ResetMode.kResetSafeParameters,
37+
rev.SparkBase.PersistMode.kPersistParameters,
38+
)
39+
self.rightMotor.configure(
40+
self.rightConfig,
41+
rev.SparkBase.ResetMode.kResetSafeParameters,
42+
rev.SparkBase.PersistMode.kPersistParameters,
43+
)
3744

3845
self.driveTrain = DifferentialDrive(self.leftMotor, self.rightMotor)
3946
self.l_stick = wpilib.Joystick(0)

examples/check_header.py

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) FIRST and other WPILib contributors.
4+
# Open Source Software; you can modify and/or share it under the terms of
5+
# the WPILib BSD license file in the root directory of this project.
6+
#
7+
8+
from pathlib import Path
9+
10+
11+
def check_file_content(file_path):
12+
with open(file_path, "r") as file:
13+
lines = file.readlines()
14+
15+
if file.name.endswith("robot.py"):
16+
expected_lines = [
17+
"#!/usr/bin/env python3\n",
18+
"#\n",
19+
"# Copyright (c) FIRST and other WPILib contributors.\n",
20+
"# Open Source Software; you can modify and/or share it under the terms of\n",
21+
"# the WPILib BSD license file in the root directory of this project.\n",
22+
"#\n",
23+
"\n",
24+
]
25+
else:
26+
expected_lines = [
27+
"#\n",
28+
"# Copyright (c) FIRST and other WPILib contributors.\n",
29+
"# Open Source Software; you can modify and/or share it under the terms of\n",
30+
"# the WPILib BSD license file in the root directory of this project.\n",
31+
"#\n",
32+
"\n",
33+
]
34+
35+
if lines[: len(expected_lines)] != expected_lines:
36+
print(
37+
"\n".join(
38+
[
39+
f"{file_path}",
40+
"ERROR: File must start with the following lines",
41+
"------------------------------",
42+
"".join(expected_lines[:-1]),
43+
"------------------------------",
44+
"Found:",
45+
"".join(lines[: len(expected_lines)]),
46+
"------------------------------",
47+
]
48+
)
49+
)
50+
51+
return False
52+
return True
53+
54+
55+
def main():
56+
current_directory = Path(__file__).parent
57+
python_files = [
58+
x
59+
for x in current_directory.glob("./**/*.py")
60+
if not x.parent == current_directory and x.stat().st_size != 0
61+
]
62+
63+
non_compliant_files = [
64+
file for file in python_files if not check_file_content(file)
65+
]
66+
67+
non_compliant_files.sort()
68+
69+
if non_compliant_files:
70+
print("Non-compliant files:")
71+
for file in non_compliant_files:
72+
print(f"- {file}")
73+
exit(1) # Exit with an error code
74+
else:
75+
print("All files are compliant.")
76+
77+
78+
if __name__ == "__main__":
79+
main()

examples/color_match/robot.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#!/usr/bin/env python3
2-
3-
# Copyright (c) 2017-2018 FIRST. All Rights Reserved.
4-
# Open Source Software - may be modified and shared by FRC teams. The code
5-
# must be accompanied by the FIRST BSD license file in the root directory of
6-
# the project.
2+
#
3+
# Copyright (c) FIRST and other WPILib contributors.
4+
# Open Source Software; you can modify and/or share it under the terms of
5+
# the WPILib BSD license file in the root directory of this project.
6+
#
77

88
import wpilib
99
from rev import ColorSensorV3, ColorMatch

examples/get-set-params/robot.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
# ----------------------------------------------------------------------------
2-
# Copyright (c) 2017-2018 FIRST. All Rights Reserved.
3-
# Open Source Software - may be modified and shared by FRC teams. The code
4-
# must be accompanied by the FIRST BSD license file in the root directory of
5-
# the project.
6-
# ----------------------------------------------------------------------------
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) FIRST and other WPILib contributors.
4+
# Open Source Software; you can modify and/or share it under the terms of
5+
# the WPILib BSD license file in the root directory of this project.
6+
#
77

88
import rev
99
import wpilib

examples/getting-started/robot.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ def robotInit(self):
1616
This function is called upon program startup and
1717
should be used for any initialization code.
1818
"""
19-
self.leftDrive = rev.CANSparkMax(1, rev.CANSparkMax.MotorType.kBrushless)
20-
self.rightDrive = rev.CANSparkMax(2, rev.CANSparkMax.MotorType.kBrushless)
19+
self.leftDrive = rev.SparkMax(1, rev.SparkMax.MotorType.kBrushless)
20+
self.rightDrive = rev.SparkMax(2, rev.SparkMax.MotorType.kBrushless)
2121
self.robotDrive = wpilib.drive.DifferentialDrive(
2222
self.leftDrive, self.rightDrive
2323
)

0 commit comments

Comments
 (0)