diff --git a/Baby Bot 4/.gitignore b/.gitignore similarity index 93% rename from Baby Bot 4/.gitignore rename to .gitignore index cdbfbfa..5528d4f 100644 --- a/Baby Bot 4/.gitignore +++ b/.gitignore @@ -1,178 +1,178 @@ -# This gitignore has been specially created by the WPILib team. -# If you remove items from this file, intellisense might break. - -### C++ ### -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - -### Java ### -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -### Linux ### -*~ - -# temporary files which can be created if a process still has a handle open of a deleted file -.fuse_hidden* - -# KDE directory preferences -.directory - -# Linux trash folder which might appear on any partition or disk -.Trash-* - -# .nfs files are created when an open file is removed but is still being accessed -.nfs* - -### macOS ### -# General -.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -### VisualStudioCode ### -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json - -### Windows ### -# Windows thumbnail cache files -Thumbs.db -ehthumbs.db -ehthumbs_vista.db - -# Dump file -*.stackdump - -# Folder config file -[Dd]esktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msix -*.msm -*.msp - -# Windows shortcuts -*.lnk - -### Gradle ### -.gradle -/build/ - -# Ignore Gradle GUI config -gradle-app.setting - -# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) -!gradle-wrapper.jar - -# Cache of project -.gradletasknamecache - -# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 -# gradle/wrapper/gradle-wrapper.properties - -# # VS Code Specific Java Settings -# DO NOT REMOVE .classpath and .project -.classpath -.project -.settings/ -bin/ - -# IntelliJ -*.iml -*.ipr -*.iws -.idea/ -out/ - -# Fleet -.fleet - -# Simulation GUI and other tools window save file -*-window.json - -# Simulation data log directory -logs/ - -# Folder that has CTRE Phoenix Sim device config storage -ctre_sim/ +# This gitignore has been specially created by the WPILib team. +# If you remove items from this file, intellisense might break. + +### C++ ### +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +### Java ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### Gradle ### +.gradle +/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +# # VS Code Specific Java Settings +# DO NOT REMOVE .classpath and .project +.classpath +.project +.settings/ +bin/ + +# IntelliJ +*.iml +*.ipr +*.iws +.idea/ +out/ + +# Fleet +.fleet + +# Simulation GUI and other tools window save file +*-window.json + +# Simulation data log directory +logs/ + +# Folder that has CTRE Phoenix Sim device config storage +ctre_sim/ diff --git a/Baby Bot 4/.vscode/launch.json b/.vscode/launch.json similarity index 95% rename from Baby Bot 4/.vscode/launch.json rename to .vscode/launch.json index 5b804e8..c9c9713 100644 --- a/Baby Bot 4/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,21 +1,21 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - - { - "type": "wpilib", - "name": "WPILib Desktop Debug", - "request": "launch", - "desktop": true, - }, - { - "type": "wpilib", - "name": "WPILib roboRIO Debug", - "request": "launch", - "desktop": false, - } - ] -} +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "type": "wpilib", + "name": "WPILib Desktop Debug", + "request": "launch", + "desktop": true, + }, + { + "type": "wpilib", + "name": "WPILib roboRIO Debug", + "request": "launch", + "desktop": false, + } + ] +} diff --git a/Baby Bot 4/.vscode/settings.json b/.vscode/settings.json similarity index 96% rename from Baby Bot 4/.vscode/settings.json rename to .vscode/settings.json index 8be11f2..4ed293b 100644 --- a/Baby Bot 4/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,29 +1,29 @@ -{ - "java.configuration.updateBuildConfiguration": "automatic", - "java.server.launchMode": "Standard", - "files.exclude": { - "**/.git": true, - "**/.svn": true, - "**/.hg": true, - "**/CVS": true, - "**/.DS_Store": true, - "bin/": true, - "**/.classpath": true, - "**/.project": true, - "**/.settings": true, - "**/.factorypath": true, - "**/*~": true - }, - "java.test.config": [ - { - "name": "WPIlibUnitTests", - "workingDirectory": "${workspaceFolder}/build/jni/release", - "vmargs": [ "-Djava.library.path=${workspaceFolder}/build/jni/release" ], - "env": { - "LD_LIBRARY_PATH": "${workspaceFolder}/build/jni/release" , - "DYLD_LIBRARY_PATH": "${workspaceFolder}/build/jni/release" - } - }, - ], - "java.test.defaultConfig": "WPIlibUnitTests" -} +{ + "java.configuration.updateBuildConfiguration": "automatic", + "java.server.launchMode": "Standard", + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "bin/": true, + "**/.classpath": true, + "**/.project": true, + "**/.settings": true, + "**/.factorypath": true, + "**/*~": true + }, + "java.test.config": [ + { + "name": "WPIlibUnitTests", + "workingDirectory": "${workspaceFolder}/build/jni/release", + "vmargs": [ "-Djava.library.path=${workspaceFolder}/build/jni/release" ], + "env": { + "LD_LIBRARY_PATH": "${workspaceFolder}/build/jni/release" , + "DYLD_LIBRARY_PATH": "${workspaceFolder}/build/jni/release" + } + }, + ], + "java.test.defaultConfig": "WPIlibUnitTests" +} diff --git a/Baby Bot 4/.wpilib/wpilib_preferences.json b/.wpilib/wpilib_preferences.json similarity index 100% rename from Baby Bot 4/.wpilib/wpilib_preferences.json rename to .wpilib/wpilib_preferences.json diff --git a/Baby Bot 4/src/main/java/frc/robot/commands/Autos.java b/Baby Bot 4/src/main/java/frc/robot/commands/Autos.java deleted file mode 100644 index 5d1ed0c..0000000 --- a/Baby Bot 4/src/main/java/frc/robot/commands/Autos.java +++ /dev/null @@ -1,18 +0,0 @@ -// 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. - -package frc.robot.commands; - -import frc.robot.subsystems.DrivebaseS; -import edu.wpi.first.wpilibj2.command.Command; -import edu.wpi.first.wpilibj2.command.Commands; - -public final class Autos { - /** Example static factory for an autonomous command. */ - - - private Autos() { - throw new UnsupportedOperationException("This is a utility class!"); - } -} diff --git a/Baby Bot 4/src/main/java/frc/robot/commands/ExampleCommand.java b/Baby Bot 4/src/main/java/frc/robot/commands/ExampleCommand.java deleted file mode 100644 index 343590f..0000000 --- a/Baby Bot 4/src/main/java/frc/robot/commands/ExampleCommand.java +++ /dev/null @@ -1,43 +0,0 @@ -// 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. - -package frc.robot.commands; - -import frc.robot.subsystems.DrivebaseS; -import edu.wpi.first.wpilibj2.command.Command; - -/** An example command that uses an example subsystem. */ -public class ExampleCommand extends Command { - @SuppressWarnings({"PMD.UnusedPrivateField", "PMD.SingularField"}) - private final DrivebaseS m_subsystem; - - /** - * Creates a new ExampleCommand. - * - * @param subsystem The subsystem used by this command. - */ - public ExampleCommand(DrivebaseS subsystem) { - m_subsystem = subsystem; - // Use addRequirements() here to declare subsystem dependencies. - addRequirements(subsystem); - } - - // Called when the command is initially scheduled. - @Override - public void initialize() {} - - // Called every time the scheduler runs while the command is scheduled. - @Override - public void execute() {} - - // Called once the command ends or is interrupted. - @Override - public void end(boolean interrupted) {} - - // Returns true when the command should end. - @Override - public boolean isFinished() { - return false; - } -} diff --git a/Baby Bot 4/src/main/java/frc/robot/subsystems/DrivebaseS.java b/Baby Bot 4/src/main/java/frc/robot/subsystems/DrivebaseS.java deleted file mode 100644 index 21415e3..0000000 --- a/Baby Bot 4/src/main/java/frc/robot/subsystems/DrivebaseS.java +++ /dev/null @@ -1,134 +0,0 @@ -// 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. - -package frc.robot.subsystems; - -import com.revrobotics.CANSparkLowLevel.MotorType; - -import java.util.function.Supplier; - -import frc.robot.Constants.DriveConstants; - -import com.revrobotics.CANSparkMax; - -import java.util.Timer; -import java.util.TimerTask; - -import edu.wpi.first.math.geometry.Translation2d; -import edu.wpi.first.math.kinematics.ChassisSpeeds; -import edu.wpi.first.math.kinematics.MecanumDriveKinematics; -import edu.wpi.first.math.kinematics.MecanumDriveWheelSpeeds; -import edu.wpi.first.math.util.Units; -import edu.wpi.first.wpilibj2.command.Command; -import edu.wpi.first.wpilibj2.command.Commands; -import edu.wpi.first.wpilibj2.command.SubsystemBase; -import edu.wpi.first.wpilibj2.command.button.Trigger; - - - -public class DrivebaseS extends SubsystemBase { - - public int maxBoosts = 2; - public int timesBoosted = 1; - public int boostTimeSeconds = 5; - - private CANSparkMax motorFL = new CANSparkMax(5, MotorType.kBrushless); - private CANSparkMax motorBR = new CANSparkMax(4, MotorType.kBrushless); - private CANSparkMax motorBL = new CANSparkMax(3, MotorType.kBrushless); - private CANSparkMax motorFR = new CANSparkMax(2, MotorType.kBrushless); - - private double slowSpeed = 2.8; - private double fastSpeed = 7.1; - - private double SpeedMultiplier = slowSpeed; - - -private MecanumDriveKinematics kinematics = new MecanumDriveKinematics( - new Translation2d( - Units.inchesToMeters(7.5), - Units.inchesToMeters(6.5) - ), - new Translation2d( - Units.inchesToMeters(7.5), - Units.inchesToMeters(-6.5) - ), - new Translation2d( - Units.inchesToMeters(-7.5), - Units.inchesToMeters(6.5) - ), - new Translation2d( - Units.inchesToMeters(-7.5), - Units.inchesToMeters(-6.5))); - - /** Creates a new ExampleSubsystem. */ - public DrivebaseS() { - motorBL.setSmartCurrentLimit(DriveConstants.CURRENT_LIMIT); - motorFL.setSmartCurrentLimit(DriveConstants.CURRENT_LIMIT); - motorBR.setSmartCurrentLimit(DriveConstants.CURRENT_LIMIT); - motorBR.setSmartCurrentLimit(DriveConstants.CURRENT_LIMIT); - - } - - - public void drive (ChassisSpeeds Speeds) { - MecanumDriveWheelSpeeds wheels = kinematics.toWheelSpeeds(Speeds); - motorFL.setVoltage(SpeedMultiplier * wheels.frontLeftMetersPerSecond); - motorFR.setVoltage(SpeedMultiplier * wheels.frontRightMetersPerSecond); - motorBL.setVoltage(SpeedMultiplier * wheels.rearLeftMetersPerSecond); - motorBR.setVoltage(SpeedMultiplier * wheels.rearRightMetersPerSecond); - } - - public Command driveC (Supplier Speeds) { - return run(()->drive(Speeds.get())); - } - - @Override - public void periodic() { - // This method will be called once per scheduler run - } - - @Override - public void simulationPeriodic() { - // This method will be called once per scheduler run during simulation - - } - public final Trigger trg_canBoost = new Trigger(()->(SpeedMultiplier != fastSpeed && timesBoosted < maxBoosts)); - public Command ToggleFastC() { - return Commands.sequence( - Commands.runOnce(()-> { - SpeedMultiplier = fastSpeed; - }), - Commands.waitSeconds(boostTimeSeconds), - Commands.runOnce(()-> { - ++timesBoosted; - SpeedMultiplier = slowSpeed;}) - ); - - } - - public void ToggleSpeed() { - if (SpeedMultiplier == slowSpeed){ - SpeedMultiplier = fastSpeed; - } - else{ - SpeedMultiplier = slowSpeed; - } - } - - - public void ResetBoost() { - timesBoosted = 0; - } - - public Command ResetBoostC () { - return runOnce(this::ResetBoost); - } - -} - - - - - - diff --git a/Baby Bot 4/src/main/java/frc/robot/subsystems/pneumatics/Pnuematics2S.java b/Baby Bot 4/src/main/java/frc/robot/subsystems/pneumatics/Pnuematics2S.java deleted file mode 100644 index 25a5612..0000000 --- a/Baby Bot 4/src/main/java/frc/robot/subsystems/pneumatics/Pnuematics2S.java +++ /dev/null @@ -1,55 +0,0 @@ - -// 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. - -package frc.robot.subsystems.pneumatics; - -import edu.wpi.first.wpilibj.Solenoid; -import edu.wpi.first.wpilibj.PneumaticsModuleType; -import edu.wpi.first.wpilibj2.command.Command; -import edu.wpi.first.wpilibj2.command.Commands; -import edu.wpi.first.wpilibj2.command.InstantCommand; -import edu.wpi.first.wpilibj2.command.SubsystemBase; -import frc.robot.Constants; - -public class Pnuematics2S extends SubsystemBase { - public class Constants{ - } - - private final Solenoid m_solenoid2Solenoid = new Solenoid(PneumaticsModuleType.REVPH,2); - private boolean isExtended = false; - - /** Creates a new PnueamticsS. */ - public Pnuematics2S() { - - } - - public void extend(){ - isExtended = true; - m_solenoid2Solenoid.set(true); - - } - - public void retract(){ - isExtended = false; - m_solenoid2Solenoid.set(false); - } - - public Command extendC(){ - return run(this::extend); - } - - public Command retractC(){ - return run(this::retract); - } - public void toggle(){ - m_solenoid2Solenoid.toggle(); - } - - public Command toggleC() { - return runOnce(this::toggle); - } - - -} diff --git a/Baby Bot 4/src/main/java/frc/robot/subsystems/pneumatics/Pnuematics3S.java b/Baby Bot 4/src/main/java/frc/robot/subsystems/pneumatics/Pnuematics3S.java deleted file mode 100644 index e8ec3ea..0000000 --- a/Baby Bot 4/src/main/java/frc/robot/subsystems/pneumatics/Pnuematics3S.java +++ /dev/null @@ -1,55 +0,0 @@ - -// 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. - -package frc.robot.subsystems.pneumatics; - -import edu.wpi.first.wpilibj.Solenoid; -import edu.wpi.first.wpilibj.PneumaticsModuleType; -import edu.wpi.first.wpilibj2.command.Command; -import edu.wpi.first.wpilibj2.command.Commands; -import edu.wpi.first.wpilibj2.command.InstantCommand; -import edu.wpi.first.wpilibj2.command.SubsystemBase; -import frc.robot.Constants; - -public class Pnuematics3S extends SubsystemBase { - public class Constants{ - } - - private final Solenoid m_solenoid3Solenoid = new Solenoid(PneumaticsModuleType.REVPH,4); - private boolean isExtended = false; - - /** Creates a new PnueamticsS. */ - public Pnuematics3S() { - - } - - public void extend(){ - isExtended = true; - m_solenoid3Solenoid.set(true); - - } - - public void retract(){ - isExtended = false; - m_solenoid3Solenoid.set(false); - } - - public Command extendC(){ - return run(this::extend); - } - - public Command retractC(){ - return run(this::retract); - } - public void toggle(){ - m_solenoid3Solenoid.toggle(); - } - - public Command toggleC() { - return runOnce(this::toggle); - } - - -} diff --git a/README.md b/README.md new file mode 100644 index 0000000..19fe3a4 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +This branch demonstrates a development process for the 2024 water games sprayer robot. + +The first step is defining the capabilities of the robot, then breaking that down into system requirements. + +See Requirements.md for this first step. \ No newline at end of file diff --git a/Requirements.md b/Requirements.md new file mode 100644 index 0000000..d1548ca --- /dev/null +++ b/Requirements.md @@ -0,0 +1,97 @@ +# USER NEEDS +NOMAD needs a system with the following constraints: + +> This document intentionally avoids discussing driver control hardware or mapping to driver inputs. +Consider that a separate system that interfaces with this one, and has its own requirements. + +## H. HARDWARE TO BE USED +The system has the following hardware configured: +> This list only describes the hardware that is to be controlled by the robot code. + +1. 4 wheels, arranged in two parallel sets of 2 wheels, the "left side" and the "right side". No wheels are mechanically coupled to other wheels. + - A wheel's "forward" is defined as the direction that would cause the robot to move forward. +1. 4 NEO motors and Spark Maxes, each individually geared one of four wheels +1. At least one solenoid. + 1. Each solenoid is plumbed to spray water out of one nozzle (1 solenoid:1 nozzle) + 2. Each solenoid is connected to a distinct channel on a REV PCM. (1 solenoid:1 channel) + 3. Each solenoid channel can be set ON to spray water or OFF to not spray water. + +## I. Inputs + +The system shall have the following inputs. +1. The enabled/disabled state of the system +1. Speed Axis: A number controlling forward-backward driving. It is a range of -1 (reverse) to 0 (no fwd/backward movement) to 1 (forward). +1. Turn Axis: A number controlling drive turning. It is a range of -1 (turn CW) to 0 (no turning) to 1 (turn CCW). +1. Boost Button: A boolean triggering boost behavior as described in section B. +1. Sprayer Buttons: A boolean for each solenoid that is to be controlled. + +## B. System Behaviors + +The system shall have the following behaviors. + +### Boost +#### Two Speeds +The system shall define a base top speed and a boost top speed in meters per second. + +#### Fast Mode +When in Fast Mode, the system's top speed for forward-backward movement shall be equal to the boost top speed. + +#### Normal Speed +When not in Fast Mode, the system's top speed for forward-backward movement shall be equal to the base top speed + +#### Default is Not Fast Mode +When the system becomes enabled, the system shall not be in Fast Mode. + +#### Exit Fast Mode on disable +When the system becomes disabled, the system shall exit Fast Mode if it is in Fast Mode. + +#### Boost Period +The system shall have a Boost Period behavior, which enters Fast Mode for a constant length of time, then exits Fast Mode when that time is elapsed. + +#### Boost is Only Usage of Fast Mode +The system shall not allow Fast Mode to be entered except through the Boost Period behavior. + +#### Boost Period Cancellation +The system shall *not* provide a way to exit Fast Mode except for disable or the elapsing of the Boost Period. + +#### Limited Boost Periods +The system shall permit Boost Period to be entered only a limited number of times (the Max Boosts) between Boost Resets. + +#### Cannot Enter Boost during Boost Period +Attempts to enter Boost Period while the system is already in the Boost Period have no effect on system top speed or the number of Boost Periods remaining. + + +### Drive +#### Straight +When the system is enabled, Turn Axis == 0 and Speed Axis != 0, the system shall drive straight at a speed in meters per second according to the value of Speed Axis times the current top speed. Driving straight is defined as the left and right side wheels moving in the same direction at the same speed. + +#### Turn In Place +When the system is enabled, Turn Axis != 0 and Speed Axis = 0, the system shall turn in place at a speed according to the value of Turn Axis. Turning in place is defined as the left and right side wheels moving in opposite directions at the same speed. + +#### FWD/BACK + Turn +When the system is enabled, Turn Axis != 0 and Speed Axis != 0, the system shall move according to the combined Turn Axis and Speed Axis. Exact mapping of this combination is an implementation detail subject to later refinement. + +### Sprayer +For each sprayer installed on the system: + +#### Spraying only when Button and Enabled +The sprayer shall be set to ON if and only if the corresponding Sprayer Button is true and the system is enabled. Otherwise it shall be set to OFF. + +## D. Development Constraints +### Java WPILIB +The system shall be implemented in WPILib Java. + +### Units +The system shall be implemented using unit-aware coding practices, but not using WPILib's Measure feature for unit values. + +## A. Architecture + +### Command-based +The system shall use the command-based architecture. + +### Constants +Constant values shall be stored as static values in appropriate Constants classes. + +### Code Reuse +Code duplication should be avoided where possible (i.e. in the use of multiple sprayers with similar behavior) + diff --git a/Baby Bot 4/WPILib-License.md b/WPILib-License.md similarity index 98% rename from Baby Bot 4/WPILib-License.md rename to WPILib-License.md index e7cd597..645e542 100644 --- a/Baby Bot 4/WPILib-License.md +++ b/WPILib-License.md @@ -1,24 +1,24 @@ -Copyright (c) 2009-2024 FIRST and other WPILib contributors -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of FIRST, WPILib, nor the names of other WPILib - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY FIRST AND OTHER WPILIB CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Copyright (c) 2009-2024 FIRST and other WPILib contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of FIRST, WPILib, nor the names of other WPILib + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY FIRST AND OTHER WPILIB CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Baby Bot 4/build.gradle b/build.gradle similarity index 97% rename from Baby Bot 4/build.gradle rename to build.gradle index aed9e2a..b63c234 100644 --- a/Baby Bot 4/build.gradle +++ b/build.gradle @@ -1,101 +1,101 @@ -plugins { - id "java" - id "edu.wpi.first.GradleRIO" version "2024.3.1" -} - -java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 -} - -def ROBOT_MAIN_CLASS = "frc.robot.Main" - -// Define my targets (RoboRIO) and artifacts (deployable files) -// This is added by GradleRIO's backing project DeployUtils. -deploy { - targets { - roborio(getTargetTypeClass('RoboRIO')) { - // Team number is loaded either from the .wpilib/wpilib_preferences.json - // or from command line. If not found an exception will be thrown. - // You can use getTeamOrDefault(team) instead of getTeamNumber if you - // want to store a team number in this file. - team = project.frc.getTeamNumber() - debug = project.frc.getDebugOrDefault(false) - - artifacts { - // First part is artifact name, 2nd is artifact type - // getTargetTypeClass is a shortcut to get the class type using a string - - frcJava(getArtifactTypeClass('FRCJavaArtifact')) { - } - - // Static files artifact - frcStaticFileDeploy(getArtifactTypeClass('FileTreeArtifact')) { - files = project.fileTree('src/main/deploy') - directory = '/home/lvuser/deploy' - } - } - } - } -} - -def deployArtifact = deploy.targets.roborio.artifacts.frcJava - -// Set to true to use debug for JNI. -wpi.java.debugJni = false - -// Set this to true to enable desktop support. -def includeDesktopSupport = false - -// Defining my dependencies. In this case, WPILib (+ friends), and vendor libraries. -// Also defines JUnit 5. -dependencies { - implementation wpi.java.deps.wpilib() - implementation wpi.java.vendor.java() - - roborioDebug wpi.java.deps.wpilibJniDebug(wpi.platforms.roborio) - roborioDebug wpi.java.vendor.jniDebug(wpi.platforms.roborio) - - roborioRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.roborio) - roborioRelease wpi.java.vendor.jniRelease(wpi.platforms.roborio) - - nativeDebug wpi.java.deps.wpilibJniDebug(wpi.platforms.desktop) - nativeDebug wpi.java.vendor.jniDebug(wpi.platforms.desktop) - simulationDebug wpi.sim.enableDebug() - - nativeRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.desktop) - nativeRelease wpi.java.vendor.jniRelease(wpi.platforms.desktop) - simulationRelease wpi.sim.enableRelease() - - testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' -} - -test { - useJUnitPlatform() - systemProperty 'junit.jupiter.extensions.autodetection.enabled', 'true' -} - -// Simulation configuration (e.g. environment variables). -wpi.sim.addGui().defaultEnabled = true -wpi.sim.addDriverstation() - -// Setting up my Jar File. In this case, adding all libraries into the main jar ('fat jar') -// in order to make them all available at runtime. Also adding the manifest so WPILib -// knows where to look for our Robot Class. -jar { - from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } - from sourceSets.main.allSource - manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) - duplicatesStrategy = DuplicatesStrategy.INCLUDE -} - -// Configure jar and deploy tasks -deployArtifact.jarTask = jar -wpi.java.configureExecutableTasks(jar) -wpi.java.configureTestTasks(test) - -// Configure string concat to always inline compile -tasks.withType(JavaCompile) { - options.compilerArgs.add '-XDstringConcat=inline' -} +plugins { + id "java" + id "edu.wpi.first.GradleRIO" version "2024.3.1" +} + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + +def ROBOT_MAIN_CLASS = "frc.robot.Main" + +// Define my targets (RoboRIO) and artifacts (deployable files) +// This is added by GradleRIO's backing project DeployUtils. +deploy { + targets { + roborio(getTargetTypeClass('RoboRIO')) { + // Team number is loaded either from the .wpilib/wpilib_preferences.json + // or from command line. If not found an exception will be thrown. + // You can use getTeamOrDefault(team) instead of getTeamNumber if you + // want to store a team number in this file. + team = project.frc.getTeamNumber() + debug = project.frc.getDebugOrDefault(false) + + artifacts { + // First part is artifact name, 2nd is artifact type + // getTargetTypeClass is a shortcut to get the class type using a string + + frcJava(getArtifactTypeClass('FRCJavaArtifact')) { + } + + // Static files artifact + frcStaticFileDeploy(getArtifactTypeClass('FileTreeArtifact')) { + files = project.fileTree('src/main/deploy') + directory = '/home/lvuser/deploy' + } + } + } + } +} + +def deployArtifact = deploy.targets.roborio.artifacts.frcJava + +// Set to true to use debug for JNI. +wpi.java.debugJni = false + +// Set this to true to enable desktop support. +def includeDesktopSupport = false + +// Defining my dependencies. In this case, WPILib (+ friends), and vendor libraries. +// Also defines JUnit 5. +dependencies { + implementation wpi.java.deps.wpilib() + implementation wpi.java.vendor.java() + + roborioDebug wpi.java.deps.wpilibJniDebug(wpi.platforms.roborio) + roborioDebug wpi.java.vendor.jniDebug(wpi.platforms.roborio) + + roborioRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.roborio) + roborioRelease wpi.java.vendor.jniRelease(wpi.platforms.roborio) + + nativeDebug wpi.java.deps.wpilibJniDebug(wpi.platforms.desktop) + nativeDebug wpi.java.vendor.jniDebug(wpi.platforms.desktop) + simulationDebug wpi.sim.enableDebug() + + nativeRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.desktop) + nativeRelease wpi.java.vendor.jniRelease(wpi.platforms.desktop) + simulationRelease wpi.sim.enableRelease() + + testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' +} + +test { + useJUnitPlatform() + systemProperty 'junit.jupiter.extensions.autodetection.enabled', 'true' +} + +// Simulation configuration (e.g. environment variables). +wpi.sim.addGui().defaultEnabled = true +wpi.sim.addDriverstation() + +// Setting up my Jar File. In this case, adding all libraries into the main jar ('fat jar') +// in order to make them all available at runtime. Also adding the manifest so WPILib +// knows where to look for our Robot Class. +jar { + from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } + from sourceSets.main.allSource + manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) + duplicatesStrategy = DuplicatesStrategy.INCLUDE +} + +// Configure jar and deploy tasks +deployArtifact.jarTask = jar +wpi.java.configureExecutableTasks(jar) +wpi.java.configureTestTasks(test) + +// Configure string concat to always inline compile +tasks.withType(JavaCompile) { + options.compilerArgs.add '-XDstringConcat=inline' +} diff --git a/Baby Bot 4/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from Baby Bot 4/gradle/wrapper/gradle-wrapper.jar rename to gradle/wrapper/gradle-wrapper.jar diff --git a/Baby Bot 4/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties similarity index 97% rename from Baby Bot 4/gradle/wrapper/gradle-wrapper.properties rename to gradle/wrapper/gradle-wrapper.properties index 7015f6b..5e82d67 100644 --- a/Baby Bot 4/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=permwrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=permwrapper/dists +distributionBase=GRADLE_USER_HOME +distributionPath=permwrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=permwrapper/dists diff --git a/Baby Bot 4/gradlew b/gradlew old mode 100755 new mode 100644 similarity index 100% rename from Baby Bot 4/gradlew rename to gradlew diff --git a/Baby Bot 4/gradlew.bat b/gradlew.bat similarity index 96% rename from Baby Bot 4/gradlew.bat rename to gradlew.bat index 6689b85..93e3f59 100644 --- a/Baby Bot 4/gradlew.bat +++ b/gradlew.bat @@ -1,92 +1,92 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/Baby Bot 4/networktables.json b/networktables.json similarity index 100% rename from Baby Bot 4/networktables.json rename to networktables.json diff --git a/Baby Bot 4/settings.gradle b/settings.gradle similarity index 97% rename from Baby Bot 4/settings.gradle rename to settings.gradle index 3e30f84..d94f73c 100644 --- a/Baby Bot 4/settings.gradle +++ b/settings.gradle @@ -1,30 +1,30 @@ -import org.gradle.internal.os.OperatingSystem - -pluginManagement { - repositories { - mavenLocal() - gradlePluginPortal() - String frcYear = '2024' - File frcHome - if (OperatingSystem.current().isWindows()) { - String publicFolder = System.getenv('PUBLIC') - if (publicFolder == null) { - publicFolder = "C:\\Users\\Public" - } - def homeRoot = new File(publicFolder, "wpilib") - frcHome = new File(homeRoot, frcYear) - } else { - def userFolder = System.getProperty("user.home") - def homeRoot = new File(userFolder, "wpilib") - frcHome = new File(homeRoot, frcYear) - } - def frcHomeMaven = new File(frcHome, 'maven') - maven { - name 'frcHome' - url frcHomeMaven - } - } -} - -Properties props = System.getProperties(); -props.setProperty("org.gradle.internal.native.headers.unresolved.dependencies.ignore", "true"); +import org.gradle.internal.os.OperatingSystem + +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + String frcYear = '2024' + File frcHome + if (OperatingSystem.current().isWindows()) { + String publicFolder = System.getenv('PUBLIC') + if (publicFolder == null) { + publicFolder = "C:\\Users\\Public" + } + def homeRoot = new File(publicFolder, "wpilib") + frcHome = new File(homeRoot, frcYear) + } else { + def userFolder = System.getProperty("user.home") + def homeRoot = new File(userFolder, "wpilib") + frcHome = new File(homeRoot, frcYear) + } + def frcHomeMaven = new File(frcHome, 'maven') + maven { + name 'frcHome' + url frcHomeMaven + } + } +} + +Properties props = System.getProperties(); +props.setProperty("org.gradle.internal.native.headers.unresolved.dependencies.ignore", "true"); diff --git a/Baby Bot 4/simgui-ds.json b/simgui-ds.json similarity index 100% rename from Baby Bot 4/simgui-ds.json rename to simgui-ds.json diff --git a/Baby Bot 4/simgui.json b/simgui.json similarity index 100% rename from Baby Bot 4/simgui.json rename to simgui.json diff --git a/Baby Bot 4/src/main/deploy/example.txt b/src/main/deploy/example.txt similarity index 100% rename from Baby Bot 4/src/main/deploy/example.txt rename to src/main/deploy/example.txt diff --git a/src/main/java/frc/robot/BoostTracker.java b/src/main/java/frc/robot/BoostTracker.java new file mode 100644 index 0000000..a0a2a52 --- /dev/null +++ b/src/main/java/frc/robot/BoostTracker.java @@ -0,0 +1,48 @@ +package frc.robot; + +import edu.wpi.first.wpilibj2.command.Command; +import edu.wpi.first.wpilibj2.command.button.Trigger; +import static edu.wpi.first.wpilibj2.command.Commands.*; +import static frc.robot.BoostTracker.BoostConstants.*; + +public class BoostTracker { + public class BoostConstants { + public static final int MAX_BOOSTS = 2; + + public static final int BOOST_TIME = 5; + + private static final double SLOW_SPEED_MPS = 2.8; + private static final double FAST_SPEED_MPS = 7.1; + } + + public int timesBoosted = 0; + public boolean inBoostMode = false; + public final Trigger trg_canBoost = new Trigger(() -> (!inBoostMode && (timesBoosted < MAX_BOOSTS))); + + public Command startBoostC() { + return sequence( + runOnce(() -> { + inBoostMode = true; + }), + waitSeconds(BOOST_TIME)) + .finallyDo((interrupt) -> { + if (!interrupt) { + ++timesBoosted; + } + inBoostMode = false; + }); + + } + + public void resetBoost() { + timesBoosted = 0; + } + + public Command resetBoostC() { + return runOnce(this::resetBoost); + } + + public double getTopSpeed() { + return inBoostMode ? FAST_SPEED_MPS : SLOW_SPEED_MPS; + } +} \ No newline at end of file diff --git a/Baby Bot 4/src/main/java/frc/robot/Constants.java b/src/main/java/frc/robot/Constants.java similarity index 83% rename from Baby Bot 4/src/main/java/frc/robot/Constants.java rename to src/main/java/frc/robot/Constants.java index 189288e..2b60706 100644 --- a/Baby Bot 4/src/main/java/frc/robot/Constants.java +++ b/src/main/java/frc/robot/Constants.java @@ -18,7 +18,9 @@ public static class OperatorConstants { public static final int kOperatorControllerPort = 1; } - public static class DriveConstants { - public static final int CURRENT_LIMIT = 50; + public static class SprayerConstants { + public static final int CHANNEL_30 = 3; + public static final int CHANNEL_45 = 2; + public static final int CHANNEL_60 = 4; } } diff --git a/Baby Bot 4/src/main/java/frc/robot/Main.java b/src/main/java/frc/robot/Main.java similarity index 100% rename from Baby Bot 4/src/main/java/frc/robot/Main.java rename to src/main/java/frc/robot/Main.java diff --git a/Baby Bot 4/src/main/java/frc/robot/Robot.java b/src/main/java/frc/robot/Robot.java similarity index 93% rename from Baby Bot 4/src/main/java/frc/robot/Robot.java rename to src/main/java/frc/robot/Robot.java index 3bf4250..7a86b90 100644 --- a/Baby Bot 4/src/main/java/frc/robot/Robot.java +++ b/src/main/java/frc/robot/Robot.java @@ -4,13 +4,7 @@ package frc.robot; -import com.revrobotics.CANSparkMax; -import com.revrobotics.CANSparkBase.ControlType; -import com.revrobotics.CANSparkLowLevel.MotorType; -import com.revrobotics.jni.CANSparkMaxJNI; - import edu.wpi.first.wpilibj.TimedRobot; -import edu.wpi.first.wpilibj.motorcontrol.Spark; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.CommandScheduler; @@ -88,8 +82,6 @@ public void teleopInit() { if (m_autonomousCommand != null) { m_autonomousCommand.cancel(); } - m_robotContainer.onEnabled(); - } diff --git a/Baby Bot 4/src/main/java/frc/robot/RobotContainer.java b/src/main/java/frc/robot/RobotContainer.java similarity index 62% rename from Baby Bot 4/src/main/java/frc/robot/RobotContainer.java rename to src/main/java/frc/robot/RobotContainer.java index f5d3570..f1ab53e 100644 --- a/Baby Bot 4/src/main/java/frc/robot/RobotContainer.java +++ b/src/main/java/frc/robot/RobotContainer.java @@ -4,14 +4,10 @@ package frc.robot; -import frc.robot.Constants.OperatorConstants; -import frc.robot.commands.Autos; -import frc.robot.commands.ExampleCommand; +import static frc.robot.Constants.*; import frc.robot.subsystems.DrivebaseS; -import frc.robot.subsystems.pneumatics.PnuematicsS; -import frc.robot.subsystems.pneumatics.Pnuematics2S; -import frc.robot.subsystems.pneumatics.Pnuematics3S; +import frc.robot.subsystems.SprayerS; import edu.wpi.first.math.MathUtil; import edu.wpi.first.math.kinematics.ChassisSpeeds; import edu.wpi.first.wpilibj2.command.Command; @@ -28,13 +24,12 @@ */ public class RobotContainer { // The robot's subsystems and commands are defined here... + private final BoostTracker m_boostTracker = new BoostTracker(); private final DrivebaseS m_drivebaseS = new DrivebaseS(); - private final PnuematicsS m_pneumatics = new PnuematicsS(); - private final Pnuematics2S m_pneumatics2 = new Pnuematics2S(); - private final Pnuematics3S m_pneumatics3 = new Pnuematics3S(); + private final SprayerS m_sprayer30S = new SprayerS(SprayerConstants.CHANNEL_30); + //private final SprayerS m_sprayer45S = new SprayerS(SprayerConstants.CHANNEL_45); + private final SprayerS m_sprayer60S = new SprayerS(SprayerConstants.CHANNEL_60); - - // Replace with CommandPS4Controller or CommandJoystick if needed private final CommandXboxController m_driverController = new CommandXboxController(OperatorConstants.kDriverControllerPort); private final CommandXboxController m_operatorController = @@ -61,30 +56,17 @@ public RobotContainer() { private void configureBindings() { m_drivebaseS.setDefaultCommand(m_drivebaseS.driveC(()->{ return new ChassisSpeeds( - MathUtil.applyDeadband (-m_driverController.getLeftY(), 0.2), + MathUtil.applyDeadband (-m_driverController.getLeftY(), 0.2) * m_boostTracker.getTopSpeed(), 0.0, - MathUtil.applyDeadband((m_driverController.getLeftX() * 2), 0.2)); + MathUtil.applyDeadband((m_driverController.getLeftX()), 0.2) * 2); })); - //two controllers - m_operatorController.a().onTrue(m_pneumatics.extendC()).onFalse(m_pneumatics.retractC()); - m_operatorController.x().onTrue(m_pneumatics2.extendC()).onFalse(m_pneumatics2.retractC()); - m_operatorController.y().onTrue(m_pneumatics3.extendC()).onFalse(m_pneumatics3.retractC()); - - m_operatorController.b().and(m_drivebaseS.trg_canBoost).onTrue(m_drivebaseS.ToggleFastC()); - - // m_operatorController.y().onTrue(m_drivebaseS.ResetBoostC()); - - /* - //one controllers - m_driverController.a().onTrue(m_pneumatics.extendC()).onFalse(m_pneumatics.retractC()); - m_driverController.x().onTrue(m_pneumatics2.extendC()).onFalse(m_pneumatics2.retractC()); + m_operatorController.x().whileTrue(m_sprayer30S.sprayStopC()); + m_operatorController.y().whileTrue(m_sprayer60S.sprayStopC()); - m_driverController.b().and(m_drivebaseS.trg_canBoost).onTrue(m_drivebaseS.ToggleFastC()); - m_driverController.y().onTrue(m_drivebaseS.ResetBoostC()); - */ + m_operatorController.b().and(m_boostTracker.trg_canBoost).onTrue(m_boostTracker.startBoostC()); - RobotModeTriggers.disabled().onFalse(m_drivebaseS.ResetBoostC()); + RobotModeTriggers.disabled().onFalse(m_boostTracker.resetBoostC()); } /** @@ -96,9 +78,4 @@ public Command getAutonomousCommand() { // An example command will be run in autonomous return Commands.none(); } - - public void onEnabled() { - - } - } diff --git a/src/main/java/frc/robot/subsystems/DrivebaseS.java b/src/main/java/frc/robot/subsystems/DrivebaseS.java new file mode 100644 index 0000000..bb03683 --- /dev/null +++ b/src/main/java/frc/robot/subsystems/DrivebaseS.java @@ -0,0 +1,66 @@ +// 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. + +package frc.robot.subsystems; + +import com.revrobotics.CANSparkLowLevel.MotorType; + +import java.util.function.Supplier; + +import com.revrobotics.CANSparkMax; + +import edu.wpi.first.math.geometry.Translation2d; +import edu.wpi.first.math.kinematics.ChassisSpeeds; +import edu.wpi.first.math.kinematics.MecanumDriveKinematics; +import edu.wpi.first.math.kinematics.MecanumDriveWheelSpeeds; +import edu.wpi.first.math.util.Units; +import edu.wpi.first.wpilibj2.command.Command; +import edu.wpi.first.wpilibj2.command.SubsystemBase; +import static frc.robot.subsystems.DrivebaseS.DriveConstants.*; + +public class DrivebaseS extends SubsystemBase { + + public static class DriveConstants { + public static final int CURRENT_LIMIT = 50; + public static final double K_V = 2.0; // V/(m/s) + public static final double HALF_LENGTH = Units.inchesToMeters(7.5); + public static final double HALF_WIDTH = Units.inchesToMeters(6.5); + public static final int CAN_ID_FL = 5; + public static final int CAN_ID_BR = 4; + public static final int CAN_ID_BL = 3; + public static final int CAN_ID_FR = 2; + } + private CANSparkMax motorFL = new CANSparkMax(CAN_ID_FL, MotorType.kBrushless); + private CANSparkMax motorBR = new CANSparkMax(CAN_ID_BR, MotorType.kBrushless); + private CANSparkMax motorBL = new CANSparkMax(CAN_ID_BL, MotorType.kBrushless); + private CANSparkMax motorFR = new CANSparkMax(CAN_ID_FR, MotorType.kBrushless); + + private MecanumDriveKinematics kinematics = new MecanumDriveKinematics( + new Translation2d(+HALF_LENGTH, +HALF_WIDTH), + new Translation2d(+HALF_LENGTH, -HALF_WIDTH), + new Translation2d(-HALF_LENGTH, +HALF_WIDTH), + new Translation2d(-HALF_LENGTH, -HALF_WIDTH) + ); + + /** Creates a new ExampleSubsystem. */ + public DrivebaseS() { + motorBL.setSmartCurrentLimit(CURRENT_LIMIT); + motorFL.setSmartCurrentLimit(CURRENT_LIMIT); + motorBR.setSmartCurrentLimit(CURRENT_LIMIT); + motorBR.setSmartCurrentLimit(CURRENT_LIMIT); + + } + + public void drive(ChassisSpeeds Speeds) { + MecanumDriveWheelSpeeds wheels = kinematics.toWheelSpeeds(Speeds); + motorFL.setVoltage(K_V * wheels.frontLeftMetersPerSecond); + motorFR.setVoltage(K_V * wheels.frontRightMetersPerSecond); + motorBL.setVoltage(K_V * wheels.rearLeftMetersPerSecond); + motorBR.setVoltage(K_V * wheels.rearRightMetersPerSecond); + } + + public Command driveC(Supplier Speeds) { + return run(() -> drive(Speeds.get())); + } +} diff --git a/Baby Bot 4/src/main/java/frc/robot/subsystems/pneumatics/PnuematicsS.java b/src/main/java/frc/robot/subsystems/SprayerS.java similarity index 52% rename from Baby Bot 4/src/main/java/frc/robot/subsystems/pneumatics/PnuematicsS.java rename to src/main/java/frc/robot/subsystems/SprayerS.java index ada94a9..72a01d5 100644 --- a/Baby Bot 4/src/main/java/frc/robot/subsystems/pneumatics/PnuematicsS.java +++ b/src/main/java/frc/robot/subsystems/SprayerS.java @@ -2,7 +2,7 @@ // 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. -package frc.robot.subsystems.pneumatics; +package frc.robot.subsystems; import edu.wpi.first.wpilibj.Solenoid; import edu.wpi.first.wpilibj.PneumaticsModuleType; @@ -12,43 +12,37 @@ import edu.wpi.first.wpilibj2.command.SubsystemBase; import frc.robot.Constants; -public class PnuematicsS extends SubsystemBase { - public class Constants{ - } +public class SprayerS extends SubsystemBase { - private final Solenoid m_solenoid = new Solenoid(PneumaticsModuleType.REVPH,3); - private boolean isExtended = false; + // don't construct this before the SprayerS constructor. + private final Solenoid m_solenoid; /** Creates a new PnueamticsS. */ - public PnuematicsS() { - + public SprayerS(int channel) { + m_solenoid = new Solenoid(PneumaticsModuleType.REVPH, channel); } - public void extend(){ - isExtended = true; + public void spray(){ m_solenoid.set(true); - } - public void retract(){ - isExtended = false; + public void stop(){ m_solenoid.set(false); } - public Command extendC(){ - return run(this::extend); + public Command sprayC(){ + return runOnce(this::spray); } - public Command retractC(){ - return run(this::retract); - } - public void toggle(){ - m_solenoid.toggle(); + public Command stopC(){ + return runOnce(this::stop); } - public Command toggleC() { - return runOnce(this::toggle); + public Command sprayStopC() { + return startEnd(this::spray, this::stop); } +// toggles are unnecessary for our usage + } diff --git a/Baby Bot 4/src/main/java/frc/robot/util/InputAxis.java b/src/main/java/frc/robot/util/InputAxis.java similarity index 96% rename from Baby Bot 4/src/main/java/frc/robot/util/InputAxis.java rename to src/main/java/frc/robot/util/InputAxis.java index 3529a42..33b626f 100644 --- a/Baby Bot 4/src/main/java/frc/robot/util/InputAxis.java +++ b/src/main/java/frc/robot/util/InputAxis.java @@ -1,80 +1,80 @@ -package frc.robot.util; - -import edu.wpi.first.math.MathUtil; -import frc.robot.util.drive.AsymmetricSlewRateLimiter; -import java.util.function.DoubleSupplier; - -/** An extension of DoubleSupplier designed for pre-processing driver controller axis inputs. */ -public class InputAxis implements DoubleSupplier { - DoubleSupplier m_supplier; - double deadband = 0; - AsymmetricSlewRateLimiter limiter = - new AsymmetricSlewRateLimiter(Double.MAX_VALUE, Double.MAX_VALUE); - boolean square; - double multiplier = 1; - - double outputValue; - String name; - - public InputAxis(String name, DoubleSupplier supplier) { - this.name = name; - m_supplier = supplier; - } - - // @Override - // public String configureLogName() { - // return name; - // } - - private double inputValue() { - return m_supplier.getAsDouble(); - } - - public InputAxis withSlewRate(double forward, double back) { - limiter = new AsymmetricSlewRateLimiter(forward, back); - return this; - } - - public InputAxis withSlewRate(double rate) { - limiter = new AsymmetricSlewRateLimiter(rate); - return this; - } - - public InputAxis withDeadband(double deadband) { - this.deadband = deadband; - return this; - } - - public InputAxis withSquaring(boolean square) { - this.square = square; - return this; - } - - public InputAxis withInvert(boolean invert) { - this.multiplier = Math.abs(this.multiplier) * (invert ? -1 : 1); - return this; - } - - public void resetSlewRate() { - double value = m_supplier.getAsDouble(); - value *= multiplier; - value = MathUtil.applyDeadband(value, deadband); - if (this.square) { - value = Math.copySign(value * value, value); - } - limiter.reset(value); - } - - @Override - public double getAsDouble() { - double value = m_supplier.getAsDouble(); - value *= multiplier; - value = MathUtil.applyDeadband(value, deadband); - if (this.square) { - value = Math.copySign(value * value, value); - } - value = limiter.calculate(value); - outputValue = value; - return value; - } -} +package frc.robot.util; + +import edu.wpi.first.math.MathUtil; +import frc.robot.util.drive.AsymmetricSlewRateLimiter; +import java.util.function.DoubleSupplier; + +/** An extension of DoubleSupplier designed for pre-processing driver controller axis inputs. */ +public class InputAxis implements DoubleSupplier { + DoubleSupplier m_supplier; + double deadband = 0; + AsymmetricSlewRateLimiter limiter = + new AsymmetricSlewRateLimiter(Double.MAX_VALUE, Double.MAX_VALUE); + boolean square; + double multiplier = 1; + + double outputValue; + String name; + + public InputAxis(String name, DoubleSupplier supplier) { + this.name = name; + m_supplier = supplier; + } + + // @Override + // public String configureLogName() { + // return name; + // } + + private double inputValue() { + return m_supplier.getAsDouble(); + } + + public InputAxis withSlewRate(double forward, double back) { + limiter = new AsymmetricSlewRateLimiter(forward, back); + return this; + } + + public InputAxis withSlewRate(double rate) { + limiter = new AsymmetricSlewRateLimiter(rate); + return this; + } + + public InputAxis withDeadband(double deadband) { + this.deadband = deadband; + return this; + } + + public InputAxis withSquaring(boolean square) { + this.square = square; + return this; + } + + public InputAxis withInvert(boolean invert) { + this.multiplier = Math.abs(this.multiplier) * (invert ? -1 : 1); + return this; + } + + public void resetSlewRate() { + double value = m_supplier.getAsDouble(); + value *= multiplier; + value = MathUtil.applyDeadband(value, deadband); + if (this.square) { + value = Math.copySign(value * value, value); + } + limiter.reset(value); + } + + @Override + public double getAsDouble() { + double value = m_supplier.getAsDouble(); + value *= multiplier; + value = MathUtil.applyDeadband(value, deadband); + if (this.square) { + value = Math.copySign(value * value, value); + } + value = limiter.calculate(value); + outputValue = value; + return value; + } +} diff --git a/Baby Bot 4/src/main/java/frc/robot/util/drive/AsymmetricSlewRateLimiter.java b/src/main/java/frc/robot/util/drive/AsymmetricSlewRateLimiter.java similarity index 97% rename from Baby Bot 4/src/main/java/frc/robot/util/drive/AsymmetricSlewRateLimiter.java rename to src/main/java/frc/robot/util/drive/AsymmetricSlewRateLimiter.java index 457a1d8..fa2bd29 100644 --- a/Baby Bot 4/src/main/java/frc/robot/util/drive/AsymmetricSlewRateLimiter.java +++ b/src/main/java/frc/robot/util/drive/AsymmetricSlewRateLimiter.java @@ -1,106 +1,106 @@ -// 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. - -package frc.robot.util.drive; - -import edu.wpi.first.math.MathSharedStore; -import edu.wpi.first.math.MathUtil; - -/** - * A class that limits the rate of change of an input value. Useful for implementing voltage, - * setpoint, and/or output ramps. A slew-rate limit is most appropriate when the quantity being - * controlled is a velocity or a voltage; when controlling a position, consider using a {@link - * edu.wpi.first.math.trajectory.TrapezoidProfile} instead. - */ -public class AsymmetricSlewRateLimiter { - private final double m_positiveMagnitudeRateLimit; - private final double m_negativeMagnitudeRateLimit; - private double m_prevVal; - private double m_prevTime; - - /** - * Creates a new SlewRateLimiter with the given positive and negative rate limits and initial - * value. - * - * @param positiveMagnitudeRateLimit The rate-of-change limit in the positive direction, in units - * per second. This is expected to be positive. - * @param negativeMagnitudeRateLimit The rate-of-change limit in the negative direction, in units - * per second. This is expected to be negative. - * @param initialValue The initial value of the input. - */ - public AsymmetricSlewRateLimiter( - double positiveMagnitudeRateLimit, double negativeMagnitudeRateLimit, double initialValue) { - m_positiveMagnitudeRateLimit = positiveMagnitudeRateLimit; - m_negativeMagnitudeRateLimit = negativeMagnitudeRateLimit; - m_prevVal = initialValue; - m_prevTime = MathSharedStore.getTimestamp(); - } - - public AsymmetricSlewRateLimiter( - double positiveMagnitudeRateLimit, double negativeMagnitudeRateLimit) { - m_positiveMagnitudeRateLimit = positiveMagnitudeRateLimit; - m_negativeMagnitudeRateLimit = negativeMagnitudeRateLimit; - m_prevVal = 0; - m_prevTime = MathSharedStore.getTimestamp(); - } - - /** - * Creates a new SlewRateLimiter with the given positive rate limit and negative rate limit of - * -rateLimit and initial value. - * - * @param rateLimit The rate-of-change limit, in units per second. - * @param initalValue The initial value of the input. - * @deprecated Use SlewRateLimiter(double positiveRateLimit, double negativeRateLimit, double - * initalValue) instead. - */ - - /** - * Creates a new SlewRateLimiter with the given positive rate limit and negative rate limit of - * -rateLimit. - * - * @param rateLimit The rate-of-change limit, in units per second. - */ - public AsymmetricSlewRateLimiter(double rateLimit) { - this(rateLimit, rateLimit, 0); - } - - /** - * Filters the input to limit its slew rate. - * - * @param input The input value whose slew rate is to be limited. - * @return The filtered value, which will not change faster than the slew rate. - */ - public double calculate(double input) { - double currentTime = MathSharedStore.getTimestamp(); - double elapsedTime = currentTime - m_prevTime; - double distanceToCover = input - m_prevVal; - // if decreasing while still positive, or increasing while still negative - if (Math.signum(m_prevVal) == -Math.signum(distanceToCover)) { - m_prevVal += - MathUtil.clamp( - input - m_prevVal, - -Math.abs(m_negativeMagnitudeRateLimit) * elapsedTime, - Math.abs(m_negativeMagnitudeRateLimit) * elapsedTime); - } else { - m_prevVal += - MathUtil.clamp( - input - m_prevVal, - -Math.abs(m_positiveMagnitudeRateLimit) * elapsedTime, - Math.abs(m_positiveMagnitudeRateLimit) * elapsedTime); - } - - m_prevTime = currentTime; - return m_prevVal; - } - - /** - * Resets the slew rate limiter to the specified value; ignores the rate limit when doing so. - * - * @param value The value to reset to. - */ - public void reset(double value) { - m_prevVal = value; - m_prevTime = MathSharedStore.getTimestamp(); - } -} +// 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. + +package frc.robot.util.drive; + +import edu.wpi.first.math.MathSharedStore; +import edu.wpi.first.math.MathUtil; + +/** + * A class that limits the rate of change of an input value. Useful for implementing voltage, + * setpoint, and/or output ramps. A slew-rate limit is most appropriate when the quantity being + * controlled is a velocity or a voltage; when controlling a position, consider using a {@link + * edu.wpi.first.math.trajectory.TrapezoidProfile} instead. + */ +public class AsymmetricSlewRateLimiter { + private final double m_positiveMagnitudeRateLimit; + private final double m_negativeMagnitudeRateLimit; + private double m_prevVal; + private double m_prevTime; + + /** + * Creates a new SlewRateLimiter with the given positive and negative rate limits and initial + * value. + * + * @param positiveMagnitudeRateLimit The rate-of-change limit in the positive direction, in units + * per second. This is expected to be positive. + * @param negativeMagnitudeRateLimit The rate-of-change limit in the negative direction, in units + * per second. This is expected to be negative. + * @param initialValue The initial value of the input. + */ + public AsymmetricSlewRateLimiter( + double positiveMagnitudeRateLimit, double negativeMagnitudeRateLimit, double initialValue) { + m_positiveMagnitudeRateLimit = positiveMagnitudeRateLimit; + m_negativeMagnitudeRateLimit = negativeMagnitudeRateLimit; + m_prevVal = initialValue; + m_prevTime = MathSharedStore.getTimestamp(); + } + + public AsymmetricSlewRateLimiter( + double positiveMagnitudeRateLimit, double negativeMagnitudeRateLimit) { + m_positiveMagnitudeRateLimit = positiveMagnitudeRateLimit; + m_negativeMagnitudeRateLimit = negativeMagnitudeRateLimit; + m_prevVal = 0; + m_prevTime = MathSharedStore.getTimestamp(); + } + + /** + * Creates a new SlewRateLimiter with the given positive rate limit and negative rate limit of + * -rateLimit and initial value. + * + * @param rateLimit The rate-of-change limit, in units per second. + * @param initalValue The initial value of the input. + * @deprecated Use SlewRateLimiter(double positiveRateLimit, double negativeRateLimit, double + * initalValue) instead. + */ + + /** + * Creates a new SlewRateLimiter with the given positive rate limit and negative rate limit of + * -rateLimit. + * + * @param rateLimit The rate-of-change limit, in units per second. + */ + public AsymmetricSlewRateLimiter(double rateLimit) { + this(rateLimit, rateLimit, 0); + } + + /** + * Filters the input to limit its slew rate. + * + * @param input The input value whose slew rate is to be limited. + * @return The filtered value, which will not change faster than the slew rate. + */ + public double calculate(double input) { + double currentTime = MathSharedStore.getTimestamp(); + double elapsedTime = currentTime - m_prevTime; + double distanceToCover = input - m_prevVal; + // if decreasing while still positive, or increasing while still negative + if (Math.signum(m_prevVal) == -Math.signum(distanceToCover)) { + m_prevVal += + MathUtil.clamp( + input - m_prevVal, + -Math.abs(m_negativeMagnitudeRateLimit) * elapsedTime, + Math.abs(m_negativeMagnitudeRateLimit) * elapsedTime); + } else { + m_prevVal += + MathUtil.clamp( + input - m_prevVal, + -Math.abs(m_positiveMagnitudeRateLimit) * elapsedTime, + Math.abs(m_positiveMagnitudeRateLimit) * elapsedTime); + } + + m_prevTime = currentTime; + return m_prevVal; + } + + /** + * Resets the slew rate limiter to the specified value; ignores the rate limit when doing so. + * + * @param value The value to reset to. + */ + public void reset(double value) { + m_prevVal = value; + m_prevTime = MathSharedStore.getTimestamp(); + } +} diff --git a/Baby Bot 4/vendordeps/REVLib.json b/vendordeps/REVLib.json similarity index 100% rename from Baby Bot 4/vendordeps/REVLib.json rename to vendordeps/REVLib.json diff --git a/Baby Bot 4/vendordeps/WPILibNewCommands.json b/vendordeps/WPILibNewCommands.json similarity index 100% rename from Baby Bot 4/vendordeps/WPILibNewCommands.json rename to vendordeps/WPILibNewCommands.json