Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port Commands to Pure Python #26

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from 13 commits
Commits
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
7 changes: 1 addition & 6 deletions .github/workflows/dist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,9 @@ on:

jobs:
ci:
uses: robotpy/build-actions/.github/workflows/package-ci.yml@v2023
uses: robotpy/build-actions/.github/workflows/package-pure.yml@v2024-alpha
with:
enable_sphinx_check: false
secrets:
SSH_USER: ${{ secrets.SSH_USER }}
SSH_KEY: ${{ secrets.SSH_KEY }}
SSH_PASSPHRASE: ${{ secrets.SSH_PASSPHRASE }}
META_REPO_ACCESS_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
RTD_TOKEN: ${{ secrets.RTD_TOKEN }}
RTD_WEBHOOK: ${{ secrets.RTD_WEBHOOK }}
PYPI_API_TOKEN: ${{ secrets.PYPI_PASSWORD }}
135 changes: 63 additions & 72 deletions commands2/__init__.py
Original file line number Diff line number Diff line change
@@ -1,96 +1,87 @@
from . import _init_impl

from .version import version as __version__

# autogenerated by 'robotpy-build create-imports commands2 commands2._impl'
from ._impl import (
Command,
CommandBase,
CommandGroupBase,
CommandScheduler,
ConditionalCommand,
FunctionalCommand,
InstantCommand,
MecanumControllerCommand,
NotifierCommand,
PIDCommand,
PIDSubsystem,
ParallelCommandGroup,
ParallelDeadlineGroup,
ParallelRaceGroup,
PerpetualCommand,
PrintCommand,
ProfiledPIDCommand,
ProfiledPIDSubsystem,
ProxyScheduleCommand,
RamseteCommand,
RepeatCommand,
RunCommand,
ScheduleCommand,
SelectCommand,
SequentialCommandGroup,
StartEndCommand,
Subsystem,
SubsystemBase,
Swerve2ControllerCommand,
Swerve3ControllerCommand,
Swerve4ControllerCommand,
Swerve6ControllerCommand,
TimedCommandRobot,
TrapezoidProfileCommand,
TrapezoidProfileCommandRadians,
TrapezoidProfileSubsystem,
TrapezoidProfileSubsystemRadians,
Trigger,
WaitCommand,
WaitUntilCommand,
# button,
# cmd,
requirementsDisjoint,
from . import button
from .command import Command, InterruptionBehavior
from .commandfactories import (
TheTripleV marked this conversation as resolved.
Show resolved Hide resolved
deadline,
either,
none,
parallel,
print_,
race,
repeatingSequence,
run,
runEnd,
runOnce,
select,
sequence,
startEnd,
waitSeconds,
waitUntil,
)
from .commandgroup import CommandGroup, IllegalCommandUse
from .commandscheduler import CommandScheduler
from .conditionalcommand import ConditionalCommand
from .functionalcommand import FunctionalCommand
from .instantcommand import InstantCommand
from .notifiercommand import NotifierCommand
from .parallelcommandgroup import ParallelCommandGroup
from .paralleldeadlinegroup import ParallelDeadlineGroup
from .parallelracegroup import ParallelRaceGroup
from .perpetualcommand import PerpetualCommand
from .printcommand import PrintCommand
from .proxycommand import ProxyCommand
from .proxyschedulecommand import ProxyScheduleCommand
from .repeatcommand import RepeatCommand
from .runcommand import RunCommand
from .schedulecommand import ScheduleCommand
from .selectcommand import SelectCommand
from .sequentialcommandgroup import SequentialCommandGroup
from .startendcommand import StartEndCommand
from .subsystem import Subsystem
from .waitcommand import WaitCommand
from .waituntilcommand import WaitUntilCommand
from .wrappercommand import WrapperCommand

__all__ = [
"button",
TheTripleV marked this conversation as resolved.
Show resolved Hide resolved
"Command",
"CommandBase",
"CommandGroupBase",
"CommandGroup",
"CommandScheduler",
"ConditionalCommand",
"SelectCommand",
"FunctionalCommand",
"IllegalCommandUse",
"InstantCommand",
"MecanumControllerCommand",
"InterruptionBehavior",
"NotifierCommand",
"PIDCommand",
"PIDSubsystem",
"ParallelCommandGroup",
"ParallelDeadlineGroup",
"ParallelRaceGroup",
"PerpetualCommand",
"PrintCommand",
"ProfiledPIDCommand",
"ProfiledPIDSubsystem",
"ProxyCommand",
"ProxyScheduleCommand",
"RamseteCommand",
"RepeatCommand",
"RunCommand",
"ScheduleCommand",
"SelectCommand",
"SequentialCommandGroup",
"StartEndCommand",
"Subsystem",
"SubsystemBase",
"Swerve2ControllerCommand",
"Swerve3ControllerCommand",
"Swerve4ControllerCommand",
"Swerve6ControllerCommand",
"TimedCommandRobot",
TheTripleV marked this conversation as resolved.
Show resolved Hide resolved
"TrapezoidProfileCommand",
"TrapezoidProfileCommandRadians",
"TrapezoidProfileSubsystem",
"TrapezoidProfileSubsystemRadians",
"Trigger",
"WaitCommand",
"WaitUntilCommand",
# "button",
# "cmd",
"requirementsDisjoint",
"WrapperCommand",
"none",
"runOnce",
"run",
"startEnd",
"runEnd",
"print_",
"waitSeconds",
"waitUntil",
"either",
"select",
"sequence",
"repeatingSequence",
"parallel",
"race",
"deadline",
TheTripleV marked this conversation as resolved.
Show resolved Hide resolved
]
21 changes: 9 additions & 12 deletions commands2/button/__init__.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
# autogenerated by 'robotpy-build create-imports commands2.button commands2._impl.button'
from .._impl.button import (
Button,
CommandGenericHID,
CommandJoystick,
CommandPS4Controller,
CommandXboxController,
JoystickButton,
NetworkButton,
POVButton,
)
from .commandgenerichid import CommandGenericHID
from .commandjoystick import CommandJoystick
from .commandps4controller import CommandPS4Controller
from .commandxboxcontroller import CommandXboxController
from .joystickbutton import JoystickButton
from .networkbutton import NetworkButton
from .povbutton import POVButton
from .trigger import Trigger

__all__ = [
"Button",
"Trigger",
"CommandGenericHID",
"CommandJoystick",
"CommandPS4Controller",
Expand Down
190 changes: 190 additions & 0 deletions commands2/button/commandgenerichid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
from typing import Optional

from wpilib.event import EventLoop
from wpilib.interfaces import GenericHID

from ..commandscheduler import CommandScheduler
from .trigger import Trigger


class CommandGenericHID:
"""
A version of GenericHID with Trigger factories for command-based.
"""

def __init__(self, port: int):
"""
Construct an instance of a device.

:param port: The port on the Driver Station that the device is plugged into.
"""
self._hid = GenericHID(port)

def getHID(self) -> GenericHID:
"""
Get the underlying GenericHID object.
"""
return self._hid

def button(self, button: int, loop: Optional[EventLoop] = None) -> Trigger:
"""
Constructs an event instance around this button's digital signal.

:param button: The button index
:param loop: the event loop instance to attache the event to.
"""
if loop is None:
loop = CommandScheduler().getDefaultButtonLoop()
TheTripleV marked this conversation as resolved.
Show resolved Hide resolved
return Trigger(loop, lambda: self._hid.getRawButtonPressed(button))

def pov(
self, angle: int, *, pov: int = 0, loop: Optional[EventLoop] = None
) -> Trigger:
"""
Constructs a Trigger instance based around this angle of a POV on the HID.

The POV angles start at 0 in the up direction, and increase clockwise (e.g. right is 90,
upper-left is 315).

:param angle: POV angle in degrees, or -1 for the center / not pressed.
:param pov: index of the POV to read (starting at 0). Defaults to 0.
:param loop: the event loop instance to attach the event to. Defaults to {@link
CommandScheduler#getDefaultButtonLoop() the default command scheduler button loop}.
:returns: a Trigger instance based around this angle of a POV on the HID.
"""
if loop is None:
loop = CommandScheduler().getDefaultButtonLoop()
return Trigger(loop, lambda: self._hid.getPOV(pov) == angle)

def povUp(self) -> Trigger:
"""
Constructs a Trigger instance based around the 0 degree angle (up) of the default (index 0) POV
on the HID, attached to {@link CommandScheduler#getDefaultButtonLoop() the default command
scheduler button loop}.

:returns: a Trigger instance based around the 0 degree angle of a POV on the HID.
"""
return self.pov(0)

def povUpRight(self) -> Trigger:
"""
Constructs a Trigger instance based around the 45 degree angle (right up) of the default (index
0) POV on the HID, attached to {@link CommandScheduler#getDefaultButtonLoop() the default
command scheduler button loop}.

:returns: a Trigger instance based around the 45 degree angle of a POV on the HID.
"""
return self.pov(45)

def povRight(self) -> Trigger:
"""
Constructs a Trigger instance based around the 90 degree angle (right) of the default (index 0)
POV on the HID, attached to {@link CommandScheduler#getDefaultButtonLoop() the default command
scheduler button loop}.

:returns: a Trigger instance based around the 90 degree angle of a POV on the HID.
"""
return self.pov(90)

def povDownRight(self) -> Trigger:
"""
Constructs a Trigger instance based around the 135 degree angle (right down) of the default
(index 0) POV on the HID, attached to {@link CommandScheduler#getDefaultButtonLoop() the
default command scheduler button loop}.

:returns: a Trigger instance based around the 135 degree angle of a POV on the HID.
"""
return self.pov(135)

def povDown(self) -> Trigger:
"""
Constructs a Trigger instance based around the 180 degree angle (down) of the default (index 0)
POV on the HID, attached to {@link CommandScheduler#getDefaultButtonLoop() the default command
scheduler button loop}.

:returns: a Trigger instance based around the 180 degree angle of a POV on the HID.
"""
return self.pov(180)

def povDownLeft(self) -> Trigger:
"""
Constructs a Trigger instance based around the 225 degree angle (down left) of the default
(index 0) POV on the HID, attached to {@link CommandScheduler#getDefaultButtonLoop() the
default command scheduler button loop}.

:returns: a Trigger instance based around the 225 degree angle of a POV on the HID.
"""
return self.pov(225)

def povLeft(self) -> Trigger:
"""
Constructs a Trigger instance based around the 270 degree angle (left) of the default (index 0)
POV on the HID, attached to {@link CommandScheduler#getDefaultButtonLoop() the default command
scheduler button loop}.

:returns: a Trigger instance based around the 270 degree angle of a POV on the HID.
"""
return self.pov(270)

def povUpLeft(self) -> Trigger:
"""
Constructs a Trigger instance based around the 315 degree angle (left up) of the default (index
0) POV on the HID, attached to {@link CommandScheduler#getDefaultButtonLoop() the default
command scheduler button loop}.

:returns: a Trigger instance based around the 315 degree angle of a POV on the HID.
"""
return self.pov(315)

def povCenter(self) -> Trigger:
"""
Constructs a Trigger instance based around the center (not pressed) position of the default
(index 0) POV on the HID, attached to {@link CommandScheduler#getDefaultButtonLoop() the
default command scheduler button loop}.

:returns: a Trigger instance based around the center position of a POV on the HID.
"""
return self.pov(-1)

def axisLessThan(
self, axis: int, threshold: float, loop: Optional[EventLoop] = None
) -> Trigger:
"""
Constructs a Trigger instance that is true when the axis value is less than {@code threshold},
attached to the given loop.

:param axis: The axis to read, starting at 0
:param threshold: The value below which this trigger should return true.
:param loop: the event loop instance to attach the trigger to
:returns: a Trigger instance that is true when the axis value is less than the provided
threshold.
"""
if loop is None:
loop = CommandScheduler().getDefaultButtonLoop()
return Trigger(loop, lambda: self._hid.getRawAxis(axis) < threshold)

def axisGreaterThan(
self, axis: int, threshold: float, loop: Optional[EventLoop] = None
) -> Trigger:
"""
Constructs a Trigger instance that is true when the axis value is greater than {@code
threshold}, attached to the given loop.

:param axis: The axis to read, starting at 0
:param threshold: The value above which this trigger should return true.
:param loop: the event loop instance to attach the trigger to.
:returns: a Trigger instance that is true when the axis value is greater than the provided
threshold.
"""
if loop is None:
loop = CommandScheduler().getDefaultButtonLoop()
return Trigger(loop, lambda: self._hid.getRawAxis(axis) > threshold)

def getRawAxis(self, axis: int) -> float:
"""
Get the value of the axis.

:param axis: The axis to read, starting at 0.
:returns: The value of the axis.
"""
return self._hid.getRawAxis(axis)
Loading