-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
645 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# | ||
# 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 typing | ||
import commands2 | ||
from subsystems.drivetrain import Drivetrain | ||
|
||
|
||
class ArcadeDrive(commands2.Command): | ||
def __init__( | ||
self, | ||
drive: Drivetrain, | ||
xaxisSpeedSupplier: typing.Callable[[], float], | ||
zaxisRotateSupplier: typing.Callable[[], float], | ||
) -> None: | ||
"""Creates a new ArcadeDrive. This command will drive your robot according to the speed supplier | ||
lambdas. This command does not terminate. | ||
:param drivetrain: The drivetrain subsystem on which this command will run | ||
:param xaxisSpeedSupplier: Callable supplier of forward/backward speed | ||
:param zaxisRotateSupplier: Callable supplier of rotational speed | ||
""" | ||
super().__init__() | ||
|
||
self.drive = drive | ||
self.xaxisSpeedSupplier = xaxisSpeedSupplier | ||
self.zaxisRotateSupplier = zaxisRotateSupplier | ||
|
||
self.addRequirements(self.drive) | ||
|
||
def execute(self) -> None: | ||
self.drive.arcadeDrive(self.xaxisSpeedSupplier(), self.zaxisRotateSupplier()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# | ||
# 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 commands2 | ||
|
||
from commands.drivedistance import DriveDistance | ||
from commands.turndegrees import TurnDegrees | ||
from subsystems.drivetrain import Drivetrain | ||
|
||
|
||
class AutonomousDistance(commands2.SequentialCommandGroup): | ||
def __init__(self, drive: Drivetrain) -> None: | ||
"""Creates a new Autonomous Drive based on distance. This will drive out for a specified distance, | ||
turn around and drive back. | ||
:param drivetrain: The drivetrain subsystem on which this command will run | ||
""" | ||
super().__init__() | ||
|
||
self.addCommands( | ||
DriveDistance(-0.5, 10, drive), | ||
TurnDegrees(-0.5, 180, drive), | ||
DriveDistance(-0.5, 10, drive), | ||
TurnDegrees(0.5, 180, drive), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# | ||
# 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 commands2 | ||
|
||
from commands.drivetime import DriveTime | ||
from commands.turntime import TurnTime | ||
from subsystems.drivetrain import Drivetrain | ||
|
||
|
||
class AutonomousTime(commands2.SequentialCommandGroup): | ||
def __init__(self, drive: Drivetrain) -> None: | ||
"""Creates a new Autonomous Drive based on time. This will drive out for a period of time, turn | ||
around for time (equivalent to time to turn around) and drive forward again. This should mimic | ||
driving out, turning around and driving back. | ||
:param drivetrain: The drive subsystem on which this command will run | ||
""" | ||
super().__init__() | ||
|
||
self.addCommands( | ||
DriveTime(-0.6, 2.0, drive), | ||
TurnTime(-0.5, 1.3, drive), | ||
DriveTime(-0.6, 2.0, drive), | ||
TurnTime(0.5, 1.3, drive), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# | ||
# 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 commands2 | ||
|
||
from subsystems.drivetrain import Drivetrain | ||
|
||
|
||
class DriveDistance(commands2.Command): | ||
def __init__(self, speed: float, inches: float, drive: Drivetrain) -> None: | ||
"""Creates a new DriveDistance. This command will drive your your robot for a desired distance at | ||
a desired speed. | ||
:param speed: The speed at which the robot will drive | ||
:param inches: The number of inches the robot will drive | ||
:param drive: The drivetrain subsystem on which this command will run | ||
""" | ||
super().__init__() | ||
|
||
self.distance = inches | ||
self.speed = speed | ||
self.drive = drive | ||
self.addRequirements(drive) | ||
|
||
def initialize(self) -> None: | ||
"""Called when the command is initially scheduled.""" | ||
self.drive.arcadeDrive(0, 0) | ||
self.drive.resetEncoders() | ||
|
||
def execute(self) -> None: | ||
"""Called every time the scheduler runs while the command is scheduled.""" | ||
self.drive.arcadeDrive(self.speed, 0) | ||
|
||
def end(self, interrupted: bool) -> None: | ||
"""Called once the command ends or is interrupted.""" | ||
self.drive.arcadeDrive(0, 0) | ||
|
||
def isFinished(self) -> bool: | ||
"""Returns true when the command should end.""" | ||
# Compare distance travelled from start to desired distance | ||
return abs(self.drive.getAverageDistanceInch()) >= self.distance |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# | ||
# 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 commands2 | ||
import wpilib | ||
|
||
from subsystems.drivetrain import Drivetrain | ||
|
||
|
||
class DriveTime(commands2.Command): | ||
"""Creates a new DriveTime. This command will drive your robot for a desired speed and time.""" | ||
|
||
def __init__(self, speed: float, time: float, drive: Drivetrain) -> None: | ||
"""Creates a new DriveTime. This command will drive your robot for a desired speed and time. | ||
:param speed: The speed which the robot will drive. Negative is in reverse. | ||
:param time: How much time to drive in seconds | ||
:param drive: The drivetrain subsystem on which this command will run | ||
""" | ||
super().__init__() | ||
|
||
self.speed = speed | ||
self.duration = time | ||
self.drive = drive | ||
self.addRequirements(drive) | ||
|
||
self.startTime = 0.0 | ||
|
||
def initialize(self) -> None: | ||
"""Called when the command is initially scheduled.""" | ||
self.startTime = wpilib.Timer.getFPGATimestamp() | ||
self.drive.arcadeDrive(0, 0) | ||
|
||
def execute(self) -> None: | ||
"""Called every time the scheduler runs while the command is scheduled.""" | ||
self.drive.arcadeDrive(self.speed, 0) | ||
|
||
def end(self, interrupted: bool) -> None: | ||
"""Called once the command ends or is interrupted.""" | ||
self.drive.arcadeDrive(0, 0) | ||
|
||
def isFinished(self) -> bool: | ||
"""Returns true when the command should end""" | ||
return wpilib.Timer.getFPGATimestamp() - self.startTime >= self.duration |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# | ||
# 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 math | ||
import commands2 | ||
|
||
from subsystems.drivetrain import Drivetrain | ||
|
||
|
||
class TurnDegrees(commands2.Command): | ||
def __init__(self, speed: float, degrees: float, drive: Drivetrain) -> None: | ||
"""Creates a new TurnDegrees. This command will turn your robot for a desired rotation (in | ||
degrees) and rotational speed. | ||
:param speed: The speed which the robot will drive. Negative is in reverse. | ||
:param degrees: Degrees to turn. Leverages encoders to compare distance. | ||
:param drive: The drive subsystem on which this command will run | ||
""" | ||
super().__init__() | ||
|
||
self.degrees = degrees | ||
self.speed = speed | ||
self.drive = drive | ||
self.addRequirements(drive) | ||
|
||
def initialize(self) -> None: | ||
"""Called when the command is initially scheduled.""" | ||
# Set motors to stop, read encoder values for starting point | ||
self.drive.arcadeDrive(0, 0) | ||
self.drive.resetEncoders() | ||
|
||
def execute(self) -> None: | ||
"""Called every time the scheduler runs while the command is scheduled.""" | ||
self.drive.arcadeDrive(0, self.speed) | ||
|
||
def end(self, interrupted: bool) -> None: | ||
"""Called once the command ends or is interrupted.""" | ||
self.drive.arcadeDrive(0, 0) | ||
|
||
def isFinished(self) -> bool: | ||
"""Returns true when the command should end.""" | ||
|
||
# Need to convert distance travelled to degrees. The Standard | ||
# XRP Chassis found here, https://www.sparkfun.com/products/22230, | ||
# has a wheel placement diameter (163 mm) - width of the wheel (8 mm) = 155 mm | ||
# or 6.102 inches. We then take into consideration the width of the tires. | ||
inchPerDegree = math.pi * 6.102 / 360 | ||
|
||
# Compare distance travelled from start to distance based on degree turn | ||
return self._getAverageTurningDistance() >= inchPerDegree * self.degrees | ||
|
||
def _getAverageTurningDistance(self) -> float: | ||
leftDistance = abs(self.drive.getLeftDistanceInch()) | ||
rightDistance = abs(self.drive.getRightDistanceInch()) | ||
return (leftDistance + rightDistance) / 2.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# | ||
# 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 commands2 | ||
import wpilib | ||
|
||
from subsystems.drivetrain import Drivetrain | ||
|
||
|
||
class TurnTime(commands2.Command): | ||
"""Creates a new TurnTime command. This command will turn your robot for a | ||
desired rotational speed and time. | ||
""" | ||
|
||
def __init__(self, speed: float, time: float, drive: Drivetrain) -> None: | ||
"""Creates a new TurnTime. | ||
:param speed: The speed which the robot will turn. Negative is in reverse. | ||
:param time: How much time to turn in seconds | ||
:param drive: The drive subsystem on which this command will run | ||
""" | ||
super().__init__() | ||
|
||
self.rotationalSpeed = speed | ||
self.duration = time | ||
self.drive = drive | ||
self.addRequirements(drive) | ||
|
||
self.startTime = 0.0 | ||
|
||
def initialize(self) -> None: | ||
"""Called when the command is initially scheduled.""" | ||
self.startTime = wpilib.Timer.getFPGATimestamp() | ||
self.drive.arcadeDrive(0, 0) | ||
|
||
def execute(self) -> None: | ||
"""Called every time the scheduler runs while the command is scheduled.""" | ||
self.drive.arcadeDrive(0, self.rotationalSpeed) | ||
|
||
def end(self, interrupted: bool) -> None: | ||
"""Called once the command ends or is interrupted.""" | ||
self.drive.arcadeDrive(0, 0) | ||
|
||
def isFinished(self) -> bool: | ||
"""Returns true when the command should end""" | ||
return wpilib.Timer.getFPGATimestamp() - self.startTime >= self.duration |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#!/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. | ||
# | ||
|
||
# | ||
# Example that shows how to connect to a XRP from RobotPy | ||
# | ||
# Requirements | ||
# ------------ | ||
# | ||
# You must have the robotpy-xrp package installed. This is best done via: | ||
# | ||
# # Windows | ||
# py -3 -m pip install robotpy[commands2,sim,xrp] | ||
# | ||
# # Linux/macOS | ||
# pip3 install robotpy[commands2,sim,xrp] | ||
# | ||
# Run the program | ||
# --------------- | ||
# | ||
# To run the program you will need to explicitly use the XRP option: | ||
# | ||
# # Windows | ||
# py -3 robotpy sim --xrp | ||
# | ||
# # Linux/macOS | ||
# python robotpy sim --xrp | ||
# | ||
# By default the WPILib simulation GUI will be displayed. To disable the display | ||
# you can add the --nogui option | ||
# | ||
|
||
import os | ||
import typing | ||
|
||
import wpilib | ||
import commands2 | ||
|
||
from robotcontainer import RobotContainer | ||
|
||
# If your ROMI isn't at the default address, set that here | ||
os.environ["HALSIMXRP_HOST"] = "192.168.42.1" | ||
os.environ["HALSIMXRP_PORT"] = "3540" | ||
|
||
|
||
class MyRobot(commands2.TimedCommandRobot): | ||
""" | ||
Command v2 robots are encouraged to inherit from TimedCommandRobot, which | ||
has an implementation of robotPeriodic which runs the scheduler for you | ||
""" | ||
|
||
autonomousCommand: typing.Optional[commands2.Command] = None | ||
|
||
def robotInit(self) -> None: | ||
""" | ||
This function is run when the robot is first started up and should be used for any | ||
initialization code. | ||
""" | ||
|
||
# Instantiate our RobotContainer. This will perform all our button bindings, and put our | ||
# autonomous chooser on the dashboard. | ||
self.container = RobotContainer() | ||
|
||
def disabledInit(self) -> None: | ||
"""This function is called once each time the robot enters Disabled mode.""" | ||
|
||
def disabledPeriodic(self) -> None: | ||
"""This function is called periodically when disabled""" | ||
|
||
def autonomousInit(self) -> None: | ||
"""This autonomous runs the autonomous command selected by your RobotContainer class.""" | ||
self.autonomousCommand = self.container.getAutonomousCommand() | ||
|
||
if self.autonomousCommand: | ||
self.autonomousCommand.schedule() | ||
|
||
def autonomousPeriodic(self) -> None: | ||
"""This function is called periodically during autonomous""" | ||
|
||
def teleopInit(self) -> None: | ||
# This makes sure that the autonomous stops running when | ||
# teleop starts running. If you want the autonomous to | ||
# continue until interrupted by another command, remove | ||
# this line or comment it out. | ||
if self.autonomousCommand: | ||
self.autonomousCommand.cancel() | ||
|
||
def teleopPeriodic(self) -> None: | ||
"""This function is called periodically during operator control""" | ||
|
||
def testInit(self) -> None: | ||
# Cancels all running commands at the start of test mode | ||
commands2.CommandScheduler.getInstance().cancelAll() |
Oops, something went wrong.