mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-19 00:41:41 +00:00
[python] Fixup python examples / build (#2509)
## Description This fixes up and renables the python examples builds. Main fixes - Test shell script just straight up didn't do what it was intended to do - Replace analog imus (and half refactored sims) with OnboardIMU - Fixes swerve velocities function signature - "regenerates" the default robotpy test ## Meta Merge checklist: - [x] Pull Request title is [short, imperative summary](https://cbea.ms/git-commit/) of proposed changes - [x] The description documents the _what_ and _why_, including events that led to this PR - [ ] If this PR changes behavior or adds a feature, user documentation is updated - [ ] If this PR touches photon-serde, all messages have been regenerated and hashes have not changed unexpectedly - [ ] If this PR touches configuration, this is backwards compatible with all settings going back to the previous seasons's last release (seasons end after champs ends) - [ ] If this PR touches pipeline settings or anything related to data exchange, the frontend typing is updated - [ ] If this PR addresses a bug, a regression test for it is added - [ ] If this PR adds a dependency, the license has been checked for compatibility and steps taken to follow it --------- Co-authored-by: Matt Morley <matthew.morley.ca@gmail.com> Co-authored-by: David Vo <auscompgeek@users.noreply.github.com>
This commit is contained in:
79
.github/workflows/python.yml
vendored
79
.github/workflows/python.yml
vendored
@@ -78,55 +78,54 @@ jobs:
|
|||||||
- name: Run mypy type checking
|
- name: Run mypy type checking
|
||||||
run: mypy --show-column-numbers --config-file photon-lib/py/pyproject.toml photon-lib
|
run: mypy --show-column-numbers --config-file photon-lib/py/pyproject.toml photon-lib
|
||||||
|
|
||||||
# build-python-examples:
|
build-python-examples:
|
||||||
# needs: build-py
|
needs: build-py
|
||||||
# strategy:
|
strategy:
|
||||||
# matrix:
|
matrix:
|
||||||
# os: [ubuntu-24.04, windows-2022, macos-14]
|
os: [ubuntu-24.04, windows-2022, macos-14]
|
||||||
# runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
# steps:
|
steps:
|
||||||
|
|
||||||
# - name: Checkout code
|
- name: Checkout code
|
||||||
# uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
# with:
|
with:
|
||||||
# fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
# - name: Set up Python
|
- name: Set up Python
|
||||||
# uses: actions/setup-python@v6
|
uses: actions/setup-python@v6
|
||||||
# with:
|
with:
|
||||||
# python-version: 3.14
|
python-version: 3.14
|
||||||
|
|
||||||
# - name: Install dependencies
|
- name: Install dependencies
|
||||||
# run: |
|
run: |
|
||||||
# python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
# python -m pip install mypy
|
python -m pip install mypy
|
||||||
|
|
||||||
# - name: Download artifacts
|
- name: Download artifacts
|
||||||
# uses: actions/download-artifact@v8
|
uses: actions/download-artifact@v8
|
||||||
# with:
|
with:
|
||||||
# name: dist
|
name: dist
|
||||||
# path: ./photon-lib/py/dist/
|
path: ./photon-lib/py/dist/
|
||||||
|
|
||||||
# - name: Install PhotonLibPy package
|
- name: Install PhotonLibPy package
|
||||||
# working-directory: ./photon-lib/py
|
working-directory: ./photon-lib/py
|
||||||
# shell: bash
|
shell: bash
|
||||||
# run: |
|
run: |
|
||||||
# pip install --no-cache-dir dist/*.whl
|
pip install --no-cache-dir dist/*.whl
|
||||||
|
|
||||||
# - name: Build Python examples
|
- name: Build Python examples
|
||||||
# working-directory: photonlib-python-examples
|
working-directory: photonlib-python-examples
|
||||||
# shell: bash
|
shell: bash
|
||||||
# run: |
|
run: |
|
||||||
# for folder in */;
|
for folder in */;
|
||||||
# do
|
do
|
||||||
# echo $folder
|
echo $folder
|
||||||
# ./run.sh $folder
|
./test.sh $folder
|
||||||
# done
|
done
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
# TODO: BRING BACK PYTHON EXAMPLES
|
needs: [test-py, build-python-examples]
|
||||||
needs: [test-py]
|
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
# Only upload on tags
|
# Only upload on tags
|
||||||
if: startsWith(github.ref, 'refs/tags/v')
|
if: startsWith(github.ref, 'refs/tags/v')
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ class Drivetrain:
|
|||||||
self.debugField = wpilib.Field2d()
|
self.debugField = wpilib.Field2d()
|
||||||
wpilib.SmartDashboard.putData("Drivetrain Debug", self.debugField)
|
wpilib.SmartDashboard.putData("Drivetrain Debug", self.debugField)
|
||||||
|
|
||||||
self.gyro = wpilib.AnalogGyro(0)
|
self.gyro = wpilib.OnboardIMU(wpilib.OnboardIMU.MountOrientation.FLAT)
|
||||||
self.simGyro = wpilib.simulation.OnboardIMUSim(self.gyro)
|
self.simGyro = wpilib.simulation.OnboardIMUSim()
|
||||||
self._yaw = 0.0
|
self._yaw = 0.0
|
||||||
|
|
||||||
self.kinematics = wpimath.SwerveDrive4Kinematics(
|
self.kinematics = wpimath.SwerveDrive4Kinematics(
|
||||||
@@ -77,7 +77,7 @@ class Drivetrain:
|
|||||||
|
|
||||||
self.targetChassisVelocities = wpimath.ChassisVelocities()
|
self.targetChassisVelocities = wpimath.ChassisVelocities()
|
||||||
|
|
||||||
self.gyro.reset()
|
self.gyro.resetYaw()
|
||||||
|
|
||||||
def drive(
|
def drive(
|
||||||
self,
|
self,
|
||||||
@@ -126,13 +126,20 @@ class Drivetrain:
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
def getModuleVelocities(self) -> list[wpimath.SwerveModuleVelocity]:
|
def getModuleVelocities(
|
||||||
return [
|
self,
|
||||||
|
) -> tuple[
|
||||||
|
wpimath.SwerveModuleVelocity,
|
||||||
|
wpimath.SwerveModuleVelocity,
|
||||||
|
wpimath.SwerveModuleVelocity,
|
||||||
|
wpimath.SwerveModuleVelocity,
|
||||||
|
]:
|
||||||
|
return (
|
||||||
self.frontLeft.getVelocity(),
|
self.frontLeft.getVelocity(),
|
||||||
self.frontRight.getVelocity(),
|
self.frontRight.getVelocity(),
|
||||||
self.backLeft.getVelocity(),
|
self.backLeft.getVelocity(),
|
||||||
self.backRight.getVelocity(),
|
self.backRight.getVelocity(),
|
||||||
]
|
)
|
||||||
|
|
||||||
def getModulePoses(self) -> list[wpimath.Pose2d]:
|
def getModulePoses(self) -> list[wpimath.Pose2d]:
|
||||||
p = self.odometry.getPose()
|
p = self.odometry.getPose()
|
||||||
@@ -197,6 +204,6 @@ class Drivetrain:
|
|||||||
self.backLeft.simulationPeriodic()
|
self.backLeft.simulationPeriodic()
|
||||||
self.backRight.simulationPeriodic()
|
self.backRight.simulationPeriodic()
|
||||||
rate = -1.0 * self.getChassisVelocities().omega_dps
|
rate = -1.0 * self.getChassisVelocities().omega_dps
|
||||||
self.simGyro.setRate(rate)
|
self.simGyro.setGyroRateZ(rate)
|
||||||
self._yaw += rate * 0.02
|
self._yaw += rate * 0.02
|
||||||
self.simGyro.setYaw(self._yaw)
|
self.simGyro.setYaw(math.radians(self._yaw))
|
||||||
|
|||||||
@@ -92,6 +92,6 @@ class MyRobot(wpilib.TimedRobot):
|
|||||||
|
|
||||||
self.swerve.drive(xSpeed, ySpeed, rot, True, self.getPeriod())
|
self.swerve.drive(xSpeed, ySpeed, rot, True, self.getPeriod())
|
||||||
|
|
||||||
def _simulationPeriodic(self) -> None:
|
def simulationPeriodic(self) -> None:
|
||||||
self.swerve.simulationPeriodic()
|
self.swerve.simulationPeriodic()
|
||||||
return super()._simulationPeriodic()
|
return super().simulationPeriodic()
|
||||||
|
|||||||
@@ -95,12 +95,16 @@ class SwerveModule:
|
|||||||
# Simulation Support
|
# Simulation Support
|
||||||
self.simDriveEncoder = wpilib.simulation.EncoderSim(self.driveEncoder)
|
self.simDriveEncoder = wpilib.simulation.EncoderSim(self.driveEncoder)
|
||||||
self.simTurningEncoder = wpilib.simulation.EncoderSim(self.turningEncoder)
|
self.simTurningEncoder = wpilib.simulation.EncoderSim(self.turningEncoder)
|
||||||
self.simDrivingMotor = wpilib.simulation.PWMSim(driveMotorChannel)
|
self.simDrivingMotor = wpilib.simulation.PWMMotorControllerSim(
|
||||||
self.simTurningMotor = wpilib.simulation.PWMSim(turningMotorChannel)
|
driveMotorChannel
|
||||||
|
)
|
||||||
|
self.simTurningMotor = wpilib.simulation.PWMMotorControllerSim(
|
||||||
|
turningMotorChannel
|
||||||
|
)
|
||||||
self.simDrivingMotorFilter = wpimath.LinearFilter.singlePoleIIR(0.1, 0.02)
|
self.simDrivingMotorFilter = wpimath.LinearFilter.singlePoleIIR(0.1, 0.02)
|
||||||
self.simTurningMotorFilter = wpimath.LinearFilter.singlePoleIIR(0.0001, 0.02)
|
self.simTurningMotorFilter = wpimath.LinearFilter.singlePoleIIR(0.0001, 0.02)
|
||||||
self.simTurningEncoderPos = 0
|
self.simTurningEncoderPos = 0.0
|
||||||
self.simDrivingEncoderPos = 0
|
self.simDrivingEncoderPos = 0.0
|
||||||
|
|
||||||
def getVelocity(self) -> wpimath.SwerveModuleVelocity:
|
def getVelocity(self) -> wpimath.SwerveModuleVelocity:
|
||||||
"""Returns the current state of the module.
|
"""Returns the current state of the module.
|
||||||
@@ -188,10 +192,12 @@ class SwerveModule:
|
|||||||
|
|
||||||
def simulationPeriodic(self) -> None:
|
def simulationPeriodic(self) -> None:
|
||||||
driveVoltage = (
|
driveVoltage = (
|
||||||
self.simDrivingMotor.getSpeed() * wpilib.RobotController.getBatteryVoltage()
|
self.simDrivingMotor.getThrottle()
|
||||||
|
* wpilib.RobotController.getBatteryVoltage()
|
||||||
)
|
)
|
||||||
turnVoltage = (
|
turnVoltage = (
|
||||||
self.simTurningMotor.getSpeed() * wpilib.RobotController.getBatteryVoltage()
|
self.simTurningMotor.getThrottle()
|
||||||
|
* wpilib.RobotController.getBatteryVoltage()
|
||||||
)
|
)
|
||||||
driveSpdRaw = (
|
driveSpdRaw = (
|
||||||
driveVoltage / 12.0 * self.driveFeedforward.maxAchievableVelocity(12.0, 0)
|
driveVoltage / 12.0 * self.driveFeedforward.maxAchievableVelocity(12.0, 0)
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
"""
|
|
||||||
This test module imports tests that come with pyfrc, and can be used
|
|
||||||
to test basic functionality of just about any robot.
|
|
||||||
"""
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
"""
|
||||||
|
This test module imports tests that come with wpilib, and can be used
|
||||||
|
to test basic functionality of just about any robot.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from wpilib.testing.robot_tests import * # noqa
|
||||||
@@ -53,8 +53,8 @@ class Drivetrain:
|
|||||||
self.debugField = wpilib.Field2d()
|
self.debugField = wpilib.Field2d()
|
||||||
wpilib.SmartDashboard.putData("Drivetrain Debug", self.debugField)
|
wpilib.SmartDashboard.putData("Drivetrain Debug", self.debugField)
|
||||||
|
|
||||||
self.gyro = wpilib.AnalogGyro(0)
|
self.gyro = wpilib.OnboardIMU(wpilib.OnboardIMU.MountOrientation.FLAT)
|
||||||
self.simGyro = wpilib.simulation.OnboardIMUSim(self.gyro)
|
self.simGyro = wpilib.simulation.OnboardIMUSim()
|
||||||
self._yaw = 0.0
|
self._yaw = 0.0
|
||||||
|
|
||||||
self.kinematics = wpimath.SwerveDrive4Kinematics(
|
self.kinematics = wpimath.SwerveDrive4Kinematics(
|
||||||
@@ -77,7 +77,7 @@ class Drivetrain:
|
|||||||
|
|
||||||
self.targetChassisVelocities = wpimath.ChassisVelocities()
|
self.targetChassisVelocities = wpimath.ChassisVelocities()
|
||||||
|
|
||||||
self.gyro.reset()
|
self.gyro.resetYaw()
|
||||||
|
|
||||||
def drive(
|
def drive(
|
||||||
self,
|
self,
|
||||||
@@ -126,13 +126,20 @@ class Drivetrain:
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
def getModuleVelocities(self) -> list[wpimath.SwerveModuleVelocity]:
|
def getModuleVelocities(
|
||||||
return [
|
self,
|
||||||
|
) -> tuple[
|
||||||
|
wpimath.SwerveModuleVelocity,
|
||||||
|
wpimath.SwerveModuleVelocity,
|
||||||
|
wpimath.SwerveModuleVelocity,
|
||||||
|
wpimath.SwerveModuleVelocity,
|
||||||
|
]:
|
||||||
|
return (
|
||||||
self.frontLeft.getVelocity(),
|
self.frontLeft.getVelocity(),
|
||||||
self.frontRight.getVelocity(),
|
self.frontRight.getVelocity(),
|
||||||
self.backLeft.getVelocity(),
|
self.backLeft.getVelocity(),
|
||||||
self.backRight.getVelocity(),
|
self.backRight.getVelocity(),
|
||||||
]
|
)
|
||||||
|
|
||||||
def getModulePoses(self) -> list[wpimath.Pose2d]:
|
def getModulePoses(self) -> list[wpimath.Pose2d]:
|
||||||
p = self.odometry.getPose()
|
p = self.odometry.getPose()
|
||||||
@@ -197,6 +204,6 @@ class Drivetrain:
|
|||||||
self.backLeft.simulationPeriodic()
|
self.backLeft.simulationPeriodic()
|
||||||
self.backRight.simulationPeriodic()
|
self.backRight.simulationPeriodic()
|
||||||
rate = -1.0 * self.getChassisVelocities().omega_dps
|
rate = -1.0 * self.getChassisVelocities().omega_dps
|
||||||
self.simGyro.setRate(rate)
|
self.simGyro.setGyroRateZ(rate)
|
||||||
self._yaw += rate * 0.02
|
self._yaw += rate * 0.02
|
||||||
self.simGyro.setYaw(self._yaw)
|
self.simGyro.setYaw(math.radians(self._yaw))
|
||||||
|
|||||||
@@ -69,6 +69,6 @@ class MyRobot(wpilib.TimedRobot):
|
|||||||
|
|
||||||
self.swerve.drive(xSpeed, ySpeed, rot, True, self.getPeriod())
|
self.swerve.drive(xSpeed, ySpeed, rot, True, self.getPeriod())
|
||||||
|
|
||||||
def _simulationPeriodic(self) -> None:
|
def simulationPeriodic(self) -> None:
|
||||||
self.swerve.simulationPeriodic()
|
self.swerve.simulationPeriodic()
|
||||||
return super()._simulationPeriodic()
|
return super().simulationPeriodic()
|
||||||
|
|||||||
@@ -95,12 +95,16 @@ class SwerveModule:
|
|||||||
# Simulation Support
|
# Simulation Support
|
||||||
self.simDriveEncoder = wpilib.simulation.EncoderSim(self.driveEncoder)
|
self.simDriveEncoder = wpilib.simulation.EncoderSim(self.driveEncoder)
|
||||||
self.simTurningEncoder = wpilib.simulation.EncoderSim(self.turningEncoder)
|
self.simTurningEncoder = wpilib.simulation.EncoderSim(self.turningEncoder)
|
||||||
self.simDrivingMotor = wpilib.simulation.PWMSim(driveMotorChannel)
|
self.simDrivingMotor = wpilib.simulation.PWMMotorControllerSim(
|
||||||
self.simTurningMotor = wpilib.simulation.PWMSim(turningMotorChannel)
|
driveMotorChannel
|
||||||
|
)
|
||||||
|
self.simTurningMotor = wpilib.simulation.PWMMotorControllerSim(
|
||||||
|
turningMotorChannel
|
||||||
|
)
|
||||||
self.simDrivingMotorFilter = wpimath.LinearFilter.singlePoleIIR(0.1, 0.02)
|
self.simDrivingMotorFilter = wpimath.LinearFilter.singlePoleIIR(0.1, 0.02)
|
||||||
self.simTurningMotorFilter = wpimath.LinearFilter.singlePoleIIR(0.0001, 0.02)
|
self.simTurningMotorFilter = wpimath.LinearFilter.singlePoleIIR(0.0001, 0.02)
|
||||||
self.simTurningEncoderPos = 0
|
self.simTurningEncoderPos = 0.0
|
||||||
self.simDrivingEncoderPos = 0
|
self.simDrivingEncoderPos = 0.0
|
||||||
|
|
||||||
def getVelocity(self) -> wpimath.SwerveModuleVelocity:
|
def getVelocity(self) -> wpimath.SwerveModuleVelocity:
|
||||||
"""Returns the current state of the module.
|
"""Returns the current state of the module.
|
||||||
@@ -188,10 +192,12 @@ class SwerveModule:
|
|||||||
|
|
||||||
def simulationPeriodic(self) -> None:
|
def simulationPeriodic(self) -> None:
|
||||||
driveVoltage = (
|
driveVoltage = (
|
||||||
self.simDrivingMotor.getSpeed() * wpilib.RobotController.getBatteryVoltage()
|
self.simDrivingMotor.getThrottle()
|
||||||
|
* wpilib.RobotController.getBatteryVoltage()
|
||||||
)
|
)
|
||||||
turnVoltage = (
|
turnVoltage = (
|
||||||
self.simTurningMotor.getSpeed() * wpilib.RobotController.getBatteryVoltage()
|
self.simTurningMotor.getThrottle()
|
||||||
|
* wpilib.RobotController.getBatteryVoltage()
|
||||||
)
|
)
|
||||||
driveSpdRaw = (
|
driveSpdRaw = (
|
||||||
driveVoltage / 12.0 * self.driveFeedforward.maxAchievableVelocity(12.0, 0)
|
driveVoltage / 12.0 * self.driveFeedforward.maxAchievableVelocity(12.0, 0)
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
"""
|
|
||||||
This test module imports tests that come with pyfrc, and can be used
|
|
||||||
to test basic functionality of just about any robot.
|
|
||||||
"""
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
"""
|
||||||
|
This test module imports tests that come with wpilib, and can be used
|
||||||
|
to test basic functionality of just about any robot.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from wpilib.testing.robot_tests import * # noqa
|
||||||
@@ -58,8 +58,8 @@ class Drivetrain:
|
|||||||
self.debugField = wpilib.Field2d()
|
self.debugField = wpilib.Field2d()
|
||||||
wpilib.SmartDashboard.putData("Drivetrain Debug", self.debugField)
|
wpilib.SmartDashboard.putData("Drivetrain Debug", self.debugField)
|
||||||
|
|
||||||
self.gyro = wpilib.AnalogGyro(0)
|
self.gyro = wpilib.OnboardIMU(wpilib.OnboardIMU.MountOrientation.FLAT)
|
||||||
self.simGyro = wpilib.simulation.OnboardIMUSim(self.gyro)
|
self.simGyro = wpilib.simulation.OnboardIMUSim()
|
||||||
self._yaw = 0.0
|
self._yaw = 0.0
|
||||||
|
|
||||||
self.kinematics = wpimath.SwerveDrive4Kinematics(
|
self.kinematics = wpimath.SwerveDrive4Kinematics(
|
||||||
@@ -78,11 +78,12 @@ class Drivetrain:
|
|||||||
self.backLeft.getPosition(),
|
self.backLeft.getPosition(),
|
||||||
self.backRight.getPosition(),
|
self.backRight.getPosition(),
|
||||||
),
|
),
|
||||||
|
wpimath.Pose2d(),
|
||||||
)
|
)
|
||||||
|
|
||||||
self.targetChassisVelocities = wpimath.ChassisVelocities()
|
self.targetChassisVelocities = wpimath.ChassisVelocities()
|
||||||
|
|
||||||
self.gyro.reset()
|
self.gyro.resetYaw()
|
||||||
|
|
||||||
def drive(
|
def drive(
|
||||||
self,
|
self,
|
||||||
@@ -121,7 +122,7 @@ class Drivetrain:
|
|||||||
|
|
||||||
def updateOdometry(self) -> None:
|
def updateOdometry(self) -> None:
|
||||||
"""Updates the field relative position of the robot."""
|
"""Updates the field relative position of the robot."""
|
||||||
self.odometry.update(
|
self.poseEst.update(
|
||||||
self.gyro.getRotation2d(),
|
self.gyro.getRotation2d(),
|
||||||
(
|
(
|
||||||
self.frontLeft.getPosition(),
|
self.frontLeft.getPosition(),
|
||||||
@@ -132,7 +133,7 @@ class Drivetrain:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def addVisionPoseEstimate(self, pose: wpimath.Pose3d, timestamp: float) -> None:
|
def addVisionPoseEstimate(self, pose: wpimath.Pose3d, timestamp: float) -> None:
|
||||||
self.poseEst.addVisionMeasurement(pose, timestamp)
|
self.poseEst.addVisionMeasurement(pose.toPose2d(), timestamp)
|
||||||
|
|
||||||
def resetPose(self) -> None:
|
def resetPose(self) -> None:
|
||||||
self.poseEst.resetPosition(
|
self.poseEst.resetPosition(
|
||||||
@@ -146,13 +147,20 @@ class Drivetrain:
|
|||||||
kInitialPose,
|
kInitialPose,
|
||||||
)
|
)
|
||||||
|
|
||||||
def getModuleVelocities(self) -> list[wpimath.SwerveModuleVelocity]:
|
def getModuleVelocities(
|
||||||
return [
|
self,
|
||||||
|
) -> tuple[
|
||||||
|
wpimath.SwerveModuleVelocity,
|
||||||
|
wpimath.SwerveModuleVelocity,
|
||||||
|
wpimath.SwerveModuleVelocity,
|
||||||
|
wpimath.SwerveModuleVelocity,
|
||||||
|
]:
|
||||||
|
return (
|
||||||
self.frontLeft.getVelocity(),
|
self.frontLeft.getVelocity(),
|
||||||
self.frontRight.getVelocity(),
|
self.frontRight.getVelocity(),
|
||||||
self.backLeft.getVelocity(),
|
self.backLeft.getVelocity(),
|
||||||
self.backRight.getVelocity(),
|
self.backRight.getVelocity(),
|
||||||
]
|
)
|
||||||
|
|
||||||
def getModulePoses(self) -> list[wpimath.Pose2d]:
|
def getModulePoses(self) -> list[wpimath.Pose2d]:
|
||||||
p = self.poseEst.getEstimatedPosition()
|
p = self.poseEst.getEstimatedPosition()
|
||||||
@@ -181,7 +189,7 @@ class Drivetrain:
|
|||||||
def log(self):
|
def log(self):
|
||||||
table = "Drive/"
|
table = "Drive/"
|
||||||
|
|
||||||
pose = self.odometry.getPose()
|
pose = self.poseEst.getEstimatedPosition()
|
||||||
wpilib.SmartDashboard.putNumber(table + "X", pose.X())
|
wpilib.SmartDashboard.putNumber(table + "X", pose.X())
|
||||||
wpilib.SmartDashboard.putNumber(table + "Y", pose.Y())
|
wpilib.SmartDashboard.putNumber(table + "Y", pose.Y())
|
||||||
wpilib.SmartDashboard.putNumber(table + "Heading", pose.rotation().degrees())
|
wpilib.SmartDashboard.putNumber(table + "Heading", pose.rotation().degrees())
|
||||||
@@ -208,7 +216,7 @@ class Drivetrain:
|
|||||||
self.backLeft.log()
|
self.backLeft.log()
|
||||||
self.backRight.log()
|
self.backRight.log()
|
||||||
|
|
||||||
self.debugField.getRobotObject().setPose(self.odometry.getPose())
|
self.debugField.getRobotObject().setPose(self.poseEst.getEstimatedPosition())
|
||||||
self.debugField.getObject("SwerveModules").setPoses(self.getModulePoses())
|
self.debugField.getObject("SwerveModules").setPoses(self.getModulePoses())
|
||||||
|
|
||||||
def simulationPeriodic(self):
|
def simulationPeriodic(self):
|
||||||
@@ -217,6 +225,6 @@ class Drivetrain:
|
|||||||
self.backLeft.simulationPeriodic()
|
self.backLeft.simulationPeriodic()
|
||||||
self.backRight.simulationPeriodic()
|
self.backRight.simulationPeriodic()
|
||||||
rate = -1.0 * self.getChassisVelocities().omega_dps
|
rate = -1.0 * self.getChassisVelocities().omega_dps
|
||||||
self.simGyro.setRate(rate)
|
self.simGyro.setGyroRateZ(rate)
|
||||||
self._yaw += rate * 0.02
|
self._yaw += rate * 0.02
|
||||||
self.simGyro.setYaw(self._yaw)
|
self.simGyro.setYaw(math.radians(self._yaw))
|
||||||
|
|||||||
@@ -55,9 +55,10 @@ class MyRobot(wpilib.TimedRobot):
|
|||||||
if camEstPose is None:
|
if camEstPose is None:
|
||||||
camEstPose = self.camPoseEst.estimateLowestAmbiguityPose(result)
|
camEstPose = self.camPoseEst.estimateLowestAmbiguityPose(result)
|
||||||
|
|
||||||
self.swerve.addVisionPoseEstimate(
|
if camEstPose:
|
||||||
camEstPose.estimatedPose, camEstPose.timestampSeconds
|
self.swerve.addVisionPoseEstimate(
|
||||||
)
|
camEstPose.estimatedPose, camEstPose.timestampSeconds
|
||||||
|
)
|
||||||
|
|
||||||
self.swerve.updateOdometry()
|
self.swerve.updateOdometry()
|
||||||
self.swerve.log()
|
self.swerve.log()
|
||||||
@@ -69,6 +70,6 @@ class MyRobot(wpilib.TimedRobot):
|
|||||||
|
|
||||||
self.swerve.drive(xSpeed, ySpeed, rot, True, self.getPeriod())
|
self.swerve.drive(xSpeed, ySpeed, rot, True, self.getPeriod())
|
||||||
|
|
||||||
def _simulationPeriodic(self) -> None:
|
def simulationPeriodic(self) -> None:
|
||||||
self.swerve.simulationPeriodic()
|
self.swerve.simulationPeriodic()
|
||||||
return super()._simulationPeriodic()
|
return super().simulationPeriodic()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Speeds ###################################################################################
|
###################################################################################
|
||||||
# MIT License
|
# MIT License
|
||||||
#
|
#
|
||||||
# Copyright (c) PhotonVision
|
# Copyright (c) PhotonVision
|
||||||
@@ -95,12 +95,16 @@ class SwerveModule:
|
|||||||
# Simulation Support
|
# Simulation Support
|
||||||
self.simDriveEncoder = wpilib.simulation.EncoderSim(self.driveEncoder)
|
self.simDriveEncoder = wpilib.simulation.EncoderSim(self.driveEncoder)
|
||||||
self.simTurningEncoder = wpilib.simulation.EncoderSim(self.turningEncoder)
|
self.simTurningEncoder = wpilib.simulation.EncoderSim(self.turningEncoder)
|
||||||
self.simDrivingMotor = wpilib.simulation.PWMSim(driveMotorChannel)
|
self.simDrivingMotor = wpilib.simulation.PWMMotorControllerSim(
|
||||||
self.simTurningMotor = wpilib.simulation.PWMSim(turningMotorChannel)
|
driveMotorChannel
|
||||||
|
)
|
||||||
|
self.simTurningMotor = wpilib.simulation.PWMMotorControllerSim(
|
||||||
|
turningMotorChannel
|
||||||
|
)
|
||||||
self.simDrivingMotorFilter = wpimath.LinearFilter.singlePoleIIR(0.1, 0.02)
|
self.simDrivingMotorFilter = wpimath.LinearFilter.singlePoleIIR(0.1, 0.02)
|
||||||
self.simTurningMotorFilter = wpimath.LinearFilter.singlePoleIIR(0.0001, 0.02)
|
self.simTurningMotorFilter = wpimath.LinearFilter.singlePoleIIR(0.0001, 0.02)
|
||||||
self.simTurningEncoderPos = 0
|
self.simTurningEncoderPos = 0.0
|
||||||
self.simDrivingEncoderPos = 0
|
self.simDrivingEncoderPos = 0.0
|
||||||
|
|
||||||
def getVelocity(self) -> wpimath.SwerveModuleVelocity:
|
def getVelocity(self) -> wpimath.SwerveModuleVelocity:
|
||||||
"""Returns the current state of the module.
|
"""Returns the current state of the module.
|
||||||
@@ -155,6 +159,10 @@ class SwerveModule:
|
|||||||
self.turningEncoder.getDistance(), self.desiredVelocity.angle.radians()
|
self.turningEncoder.getDistance(), self.desiredVelocity.angle.radians()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
turnFeedforward = self.turnFeedforward.calculate(
|
||||||
|
self.turningPIDController.getSetpoint()
|
||||||
|
)
|
||||||
|
|
||||||
self.driveMotor.setVoltage(driveOutput + driveFeedforward)
|
self.driveMotor.setVoltage(driveOutput + driveFeedforward)
|
||||||
self.turningMotor.setVoltage(turnOutput + turnFeedforward)
|
self.turningMotor.setVoltage(turnOutput + turnFeedforward)
|
||||||
|
|
||||||
@@ -188,10 +196,12 @@ class SwerveModule:
|
|||||||
|
|
||||||
def simulationPeriodic(self) -> None:
|
def simulationPeriodic(self) -> None:
|
||||||
driveVoltage = (
|
driveVoltage = (
|
||||||
self.simDrivingMotor.getSpeed() * wpilib.RobotController.getBatteryVoltage()
|
self.simDrivingMotor.getThrottle()
|
||||||
|
* wpilib.RobotController.getBatteryVoltage()
|
||||||
)
|
)
|
||||||
turnVoltage = (
|
turnVoltage = (
|
||||||
self.simTurningMotor.getSpeed() * wpilib.RobotController.getBatteryVoltage()
|
self.simTurningMotor.getThrottle()
|
||||||
|
* wpilib.RobotController.getBatteryVoltage()
|
||||||
)
|
)
|
||||||
driveSpdRaw = (
|
driveSpdRaw = (
|
||||||
driveVoltage / 12.0 * self.driveFeedforward.maxAchievableVelocity(12.0, 0)
|
driveVoltage / 12.0 * self.driveFeedforward.maxAchievableVelocity(12.0, 0)
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
"""
|
|
||||||
This test module imports tests that come with pyfrc, and can be used
|
|
||||||
to test basic functionality of just about any robot.
|
|
||||||
"""
|
|
||||||
6
photonlib-python-examples/poseest/tests/robot_test.py
Normal file
6
photonlib-python-examples/poseest/tests/robot_test.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
"""
|
||||||
|
This test module imports tests that come with wpilib, and can be used
|
||||||
|
to test basic functionality of just about any robot.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from wpilib.testing.robot_tests import * # noqa
|
||||||
@@ -11,4 +11,4 @@ cd $1
|
|||||||
|
|
||||||
# Run the example
|
# Run the example
|
||||||
mypy --show-column-numbers --config-file ../../photon-lib/py/pyproject.toml .
|
mypy --show-column-numbers --config-file ../../photon-lib/py/pyproject.toml .
|
||||||
python3 robot.py sim
|
python3 -m robotpy sim
|
||||||
|
|||||||
14
photonlib-python-examples/test.sh
Executable file
14
photonlib-python-examples/test.sh
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
set -e
|
||||||
|
# Check if the first argument is provided
|
||||||
|
if [ $# -eq 0 ]
|
||||||
|
then
|
||||||
|
echo "Error: No example-to-run provided."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Move to the right example folder
|
||||||
|
cd $1
|
||||||
|
|
||||||
|
# Run the example
|
||||||
|
mypy --show-column-numbers --config-file ../../photon-lib/py/pyproject.toml .
|
||||||
|
python3 -m robotpy test
|
||||||
Reference in New Issue
Block a user