Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
6ad8e29
distance new functon
LuckyzxV Jan 21, 2026
c2abee4
corrections of the distance function
LuckyzxV Jan 21, 2026
ad5ff6c
Drivetrain fixed
damesrm Jan 24, 2026
bb4475e
Some adjustments
damesrm Jan 30, 2026
040b64e
PId 2.0 (now it's working)
damesrm Jan 31, 2026
27e8797
chore(pyproject): edit commands2 path
megarubber Jan 31, 2026
6020cfa
Merge remote-tracking branch 'drivetrain-fix' into 'Feature/joystick'
megarubber Jan 31, 2026
1f55592
feat: add PID constants and calculate motor angle using hall sensor p…
damesrm Jan 31, 2026
d6faaa5
style: remove unnecessary tabspaces
megarubber Jan 31, 2026
cdc08ba
Merge remote-tracking branch 'Feature/Intake' into 'Feature/joystick'
megarubber Jan 31, 2026
471cce2
feat: create track ball intake methods
megarubber Jan 31, 2026
de9d682
fix: rearrage all drivetrain & joystick methods
megarubber Jan 31, 2026
1a1659b
Some fixes
damesrm Feb 2, 2026
fec2635
Intake without pid (the real inatke)
damesrm Feb 2, 2026
2d40280
Simplify intake code
damesrm Feb 2, 2026
dfb34a4
Drop balls feature on intake
LuckyzxV Feb 3, 2026
c9b171d
Merge remote-tracking branch 'Feature/Intake' into 'Feature/joystick'
megarubber Feb 3, 2026
0da3fd3
return with intake enabled
megarubber Feb 3, 2026
d3e5745
fix(genericjoystick): remame button bindings keys and return of funct…
megarubber Feb 3, 2026
74cdb2b
Limelight camera
LuckyzxV Feb 4, 2026
177eb8e
chore: add limelight dependency
megarubber Feb 5, 2026
28056d2
Merge remote-tracking branch 'origin/Feature/apriltag' into 'Feature/…
megarubber Feb 5, 2026
1f62680
wip: test alternative (through bore) encoder and display it
megarubber Feb 7, 2026
7e19b9a
wip: limelight camera
megarubber Feb 7, 2026
3b28c3d
feat: add system to tuning shooter feedforward
megarubber Feb 7, 2026
8a4f088
refactor: remove socket observer from limelight logging code
megarubber Feb 7, 2026
fcc95c9
style: change filename
megarubber Feb 8, 2026
61fbe32
refactor: remove pathplanner example to a simple test with trajectory…
megarubber Feb 8, 2026
290290b
refactor: set conversion and constants for autonomous and sparkmax mo…
megarubber Feb 8, 2026
94bf27f
fix: remove unnecessary constants and object instantiation
megarubber Feb 8, 2026
fe9080e
fix(ci): rewrite the entire bash script for robotpy tests
megarubber Feb 8, 2026
580d8a8
refactor: adapt old ramsete command example to LTV unicycle example
megarubber Feb 9, 2026
101d6d9
refactor: remove unnecessary imports
megarubber Feb 9, 2026
97884ec
refactor: separate feedforward object from base auto command
megarubber Feb 10, 2026
b858e7f
style: remove ramsete references
megarubber Feb 10, 2026
0e45d57
refactor: remove photonvision camera dependency
megarubber Feb 10, 2026
d5ba547
chore: add requirements file
megarubber Feb 10, 2026
aaf717c
style: run black
megarubber Feb 10, 2026
2ce3d7d
refactor: abstract both limelight and photonvision cameras
megarubber Feb 10, 2026
2be40e2
refactor: separate shooter from turret subsystem
megarubber Feb 10, 2026
61fc527
style: remove unnecessary imports
megarubber Feb 10, 2026
33ee4c1
style: run black
megarubber Feb 10, 2026
39c8777
LimeLight test
LuckyzxV Feb 12, 2026
b647b2e
Function corrections, know the turretAling function it's working
LuckyzxV Feb 13, 2026
74ad4e2
some additions
LuckyzxV Feb 13, 2026
bcfb111
style: rewrite imports
megarubber Feb 13, 2026
5464bbc
refactor: add pivot system based on 2022 everybot
megarubber Feb 13, 2026
663bd88
refactor: update feedforward/feedback constants
megarubber Feb 14, 2026
46c084a
refactor: parametrize pivot intake time with smart dashboard
megarubber Feb 14, 2026
60bee29
minor: separate limelight camera host name
megarubber Feb 14, 2026
3ca34f9
refactor: reimplement pathplanner configs
megarubber Feb 14, 2026
05ed3fe
refactor(drivetrain): use setSetpoint instead of setReference on spar…
megarubber Feb 14, 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
43 changes: 43 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
name: dist

on:
pull_request:
push:
branches:
- main
- '2027'
tags:
- '*'
workflow_dispatch:

jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: pre-commit/action@v3.0.1

test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: ["ubuntu-22.04", "macos-14", "windows-2022"]
python_version:
- '3.10'
- '3.11'
- '3.12'
- '3.13'
- '3.14'

steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python_version }}
- name: Install deps
run: |
pip install 'robotpy[commands2,navx,pykit,pathplannerlib,ctre,rev]<2027,>=2026.1.1' numpy pytest photonlibpy limelightlib-python
- name: Run tests
run: bash run_tests.sh
shell: bash
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
# Vim temporarily files
*.swp

# WPILib default config
tests/
.wpilib/

# WPILib default simulator
simgui-ds.json

# CTRE Simulator
ctre_sim

Expand Down
Empty file added autonomous/__init__.py
Empty file.
34 changes: 34 additions & 0 deletions autonomous/basicauto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import constants
from commands2 import Command
from wpimath.controller import LTVUnicycleController
from drivetrain import Drivetrain
from wpimath.trajectory import TrajectoryConfig, TrajectoryGenerator
from wpimath.geometry import Pose2d, Rotation2d, Translation2d


class BasicAuto(Command):
def __init__(self, drivetrain: Drivetrain) -> None:
super().__init__()
self.trajectory = TrajectoryGenerator.generateTrajectory(
Pose2d(0, 0, Rotation2d(0)),
[Translation2d(1, 1), Translation2d(2, -1)],
Pose2d(3, 0, Rotation2d(0)),
TrajectoryConfig(0.5, 0.5)
)
self.reference = self.trajectory.sample(3)
self.controller = LTVUnicycleController(0.020)

self.drivetrain = drivetrain
self.addRequirements(drivetrain)

def execute(self) -> None:
adjustedSpeeds = self.controller.calculate(
self.drivetrain.getPose(), self.reference
)

wheelSpeeds = constants.kDrivetrainKinematics.toWheelSpeeds(adjustedSpeeds)

self.drivetrain.driveWithWheelSpeeds(wheelSpeeds)

def end(self, interrupted: bool) -> None:
self.drivetrain.stop()
58 changes: 29 additions & 29 deletions buttons.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@
"pov-down": 180,
"pov-left": 270,
"pov-right": 90,
"left-x-axis": 0,
"left-y-axis": 1,
"right-x-axis": 2,
"right-y-axis": 5,
"left-trigger-axis": 3,
"right-trigger-axis": 4
"left-x-stick": 0,
"left-y-stick": 1,
"right-x-stick": 2,
"right-y-stick": 5,
"left-trigger-axis": 3,
"right-trigger-axis": 4,
}

#Generic dualshock4
# Generic dualshock4

g_ps4_controller = {
"square": 4,
Expand All @@ -49,12 +49,12 @@
"pov-down": 180,
"pov-left": 270,
"pov-right": 90,
"left-x-axis": 0,
"left-y-axis": 1,
"right-x-axis": 2,
"right-y-axis": 3,
"left-trigger-axis": 2,
"right-trigger-axis": 3
"left-x-stick": 0,
"left-y-stick": 1,
"right-x-stick": 2,
"right-y-stick": 3,
"left-trigger-axis": 2,
"right-trigger-axis": 3,
}

# Generic Nintendo Switch Pro Controller
Expand All @@ -81,32 +81,32 @@
"rb": 6,
"back": 7,
"start": 8,
"press_left_stick": 9,
"press_right_stick": 10,
"press-left-stick": 9,
"press-right-stick": 10,
"pov-up": 0,
"pov-down": 180,
"pov-left": 270,
"pov-right": 90,
"left-x-stick": 0,
"left-y-stick": 1,
"left-trigger-axis": 2,
"right-trigger-axis": 3,
"left-trigger-axis": 2,
"right-trigger-axis": 3,
"right-y-stick": 5,
"right-x-stick": 4,
}

# Generic steering wheel controller (generic Xbox 360 controller)
steering_wheel = {
"turn-axis": 0,
"a" : 3,
"b" : 2,
"y" : 1,
"x" : 4,
"lb" : 5,
"rb" : 6,
"rt" : 8,
"lt" : 7,
"r3" : 12,
"l3" : 11,
"back" : 9,
}
"a": 3,
"b": 2,
"y": 1,
"x": 4,
"lb": 5,
"rb": 6,
"rt": 8,
"lt": 7,
"r3": 12,
"l3": 11,
"back": 9,
}
134 changes: 91 additions & 43 deletions camera.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,91 @@
from photonlibpy import PhotonCamera
import wpimath.units
import constants
from typing import Optional, Tuple
from utils import Utils

from photonlibpy.targeting.photonTrackedTarget import PhotonTrackedTarget

class AprilTagCamera(PhotonCamera):
def __init__(self, camera: str) -> None:
self.camera = PhotonCamera(camera)

def getBestTarget(self) -> Optional[PhotonTrackedTarget]:
result = self.camera.getLatestResult()
if result.hasTargets():
target = result.getBestTarget()
return target
return None

def getYaw(self, tag: int) -> float:
results = self.camera.getAllUnreadResults()
if len(results) > 0:
result = results[-1]
for target in result.getTargets():
if target.getFiducialId() == tag:
return target.getYaw()
return -1

def getYawWithRange(self, tag: int) -> Tuple[float, float]:
results = self.camera.getAllUnreadResults()
target_range = 0
if len(results) > 0:
result = results[-1]
for target in result.getTargets():
if target.getFiducialId() == tag:
target_range = Utils.calculateDistanceToTargetMeters(
constants.kCameraHeightMeters,
constants.kTargetHeightMeters,
constants.kCameraPitchRadians,
wpimath.units.degreesToRadians(target.getPitch())
)
return target.getYaw(), target_range
return -1, -1
import constants
from photonlibpy import PhotonCamera
from typing import Optional, Tuple
from utils import Utils
from abc import ABC, abstractmethod
from limelight import Limelight
from limelightresults import parse_results
from wpinet import PortForwarder
from photonlibpy.targeting.photonTrackedTarget import PhotonTrackedTarget
from wpimath.units import degreesToRadians
from wpilib import RobotBase

class Camera(ABC):
@abstractmethod
def getYawFromTag(self, tag: int) -> float:
pass

@abstractmethod
def getYawAndRangeFromTag(self, tag: int) -> Tuple[float, float]:
pass


class PhotonVisionCamera(Camera):
def __init__(self, camera: str) -> None:
self.camera = PhotonCamera(camera)

def getBestTarget(self) -> Optional[PhotonTrackedTarget]:
result = self.camera.getLatestResult()
if result.hasTargets():
target = result.getBestTarget()
return target
return None

def getYawFromTag(self, tag: int) -> float:
results = self.camera.getAllUnreadResults()
if len(results) > 0:
result = results[-1]
for target in result.getTargets():
if target.getFiducialId() == tag:
return target.getYaw()
return -1

def getYawAndRangeFromTag(self, tag: int) -> Tuple[float, float]:
results = self.camera.getAllUnreadResults()
target_range = 0
if len(results) > 0:
result = results[-1]
for target in result.getTargets():
if target.getFiducialId() == tag:
target_range = Utils.calculateDistanceToTargetMeters(
constants.kCameraHeightMeters,
constants.kTargetHeightMeters,
constants.kCameraPitchRadians,
degreesToRadians(target.getPitch()),
)
return target.getYaw(), target_range
return -1, -1


class LimelightCamera(Camera):
def __init__(self, camera: str) -> None:
self.limelight = None

if not RobotBase.isSimulation():
self.limelight = Limelight(camera)
self.limelight.pipeline_switch(0)

PortForwarder.getInstance().add(*constants.kLimelightPortForwarder)

def getYawFromTag(self, tag: int) -> float:
if self.limelight is None:
return -1

result = self.limelight.get_results()
parsed_result = parse_results(result)

for target in parsed_result.fiducialResults:
if target.fiducial_id == tag:
return target.target_x_degrees # yaw

return -1

def getYawAndRangeFromTag(self, tag: int) -> Tuple[float, float]:
return 0, 0

class Pixy2(Camera):
pass


class DriverCamera(Camera):
pass
3 changes: 2 additions & 1 deletion climber.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import phoenix6
import phoenix5


class Climber:
def __init__(self):
self.left_motor = phoenix5.WPI_VictorSPX(1)
Expand All @@ -16,4 +17,4 @@ def stop(self):
self.climber.set(0)

def down(self):
self.climber.set(-1)
self.climber.set(-1)
Loading
Loading