From 5917bc428bbb603bb2bb19e5c4082d9d42e6b543 Mon Sep 17 00:00:00 2001 From: Collin McIntyre Date: Mon, 23 Feb 2026 00:17:06 -0600 Subject: [PATCH 1/9] started wip dashboard layout --- Dashboard.txt | 73 +++ src/main/deploy/elastic-layout.json | 858 ++++++++++++++++++++++++++++ src/main/java/frc/robot/Autos.java | 74 +++ src/main/java/frc/robot/Robot.java | 5 + 4 files changed, 1010 insertions(+) create mode 100644 Dashboard.txt create mode 100644 src/main/deploy/elastic-layout.json diff --git a/Dashboard.txt b/Dashboard.txt new file mode 100644 index 0000000..f08bcc4 --- /dev/null +++ b/Dashboard.txt @@ -0,0 +1,73 @@ +Autonomous Tab + Field + Display robot starting location + Display selected autonomous path + Auto Delay Chooser + 0, 1, 2, 3, 4, 5 + Start Position Chooser + Left Trench, Left Bump, Hub, Right Bump, Right Trench + Near Fuel Sources + None, Depot → Outpost, Outpost → Depot, Depot, Outpost + Neutral Zone + Yes, No + Climb + Yes, No + Alerts + Valid combination chosen + +Teleop Tab + Match Time + Period Time + Camera Stream (maybe) + Hub in Turret range + Alerts + +Programmer Tab + PID Controllers + Hood + Turret + Auto driving + X + Y + Z + + Settings + Intake + Forward Voltage + Reverse Voltage + Extension Max Position + Extend Voltage + Retract Voltage + Shooter + Flywheel + Flywheel Tolerance + Pass Velocity + Hood + Min Angle + Max Angle + Shoot Angle + Pass Angle + Tolerance + Turret + Min Angle + Max Angle + Home Angle (leave at 0?) + Tolerance + Pass Angle (if using a constant angle. If targetting, not needed) + Feeder + Feed Voltage + Vision + Max angular rate + Maximum tilt + Climber + L1 Rotation + L3 Rotation + Extension Max Position + Extend Voltage + Retract Voltage + Rotate Voltage + Tolerance + + Commands (set up to only run in test mode) + Run Hood PID + Run Turret PID diff --git a/src/main/deploy/elastic-layout.json b/src/main/deploy/elastic-layout.json new file mode 100644 index 0000000..dce466d --- /dev/null +++ b/src/main/deploy/elastic-layout.json @@ -0,0 +1,858 @@ +{ + "version": 1.0, + "grid_size": 32, + "tabs": [ + { + "name": "Autonomous", + "grid_layout": { + "layouts": [ + { + "title": "List Layout", + "x": 1632.0, + "y": 0.0, + "width": 288.0, + "height": 416.0, + "type": "List Layout", + "properties": { + "label_position": "TOP" + }, + "children": [ + { + "title": "Auto Delay", + "x": 1984.0, + "y": 416.0, + "width": 288.0, + "height": 128.0, + "type": "ComboBox Chooser", + "properties": { + "topic": "/SmartDashboard/Auto Delay", + "period": 0.06, + "sort_options": false + } + }, + { + "title": "Start Position", + "x": 1984.0, + "y": 480.0, + "width": 288.0, + "height": 128.0, + "type": "ComboBox Chooser", + "properties": { + "topic": "/SmartDashboard/Start Position", + "period": 0.06, + "sort_options": false + } + }, + { + "title": "Alliance Fuel Source", + "x": 1952.0, + "y": 256.0, + "width": 288.0, + "height": 128.0, + "type": "ComboBox Chooser", + "properties": { + "topic": "/SmartDashboard/Alliance Fuel Source", + "period": 0.06, + "sort_options": false + } + }, + { + "title": "Neutral Zone", + "x": 1664.0, + "y": 320.0, + "width": 128.0, + "height": 128.0, + "type": "Toggle Switch", + "properties": { + "topic": "/SmartDashboard/Neutral Zone", + "period": 0.06, + "data_type": "boolean" + } + }, + { + "title": "Climb", + "x": 1760.0, + "y": 384.0, + "width": 128.0, + "height": 128.0, + "type": "Toggle Switch", + "properties": { + "topic": "/SmartDashboard/Climb", + "period": 0.06, + "data_type": "boolean" + } + } + ] + } + ], + "containers": [ + { + "title": "Alerts", + "x": 1632.0, + "y": 416.0, + "width": 288.0, + "height": 320.0, + "type": "Alerts", + "properties": { + "topic": "/SmartDashboard/Alerts", + "period": 0.02 + } + }, + { + "title": "Autonomous Mode", + "x": 0.0, + "y": 0.0, + "width": 1632.0, + "height": 736.0, + "type": "Field", + "properties": { + "topic": "/SmartDashboard/Autonomous Mode", + "period": 0.06, + "field_game": "Rebuilt", + "robot_width": 0.85, + "robot_length": 0.85, + "show_other_objects": true, + "show_trajectories": true, + "field_rotation": 0.0, + "robot_color": 4294198070, + "trajectory_color": 4294967295, + "show_robot_outside_widget": true + } + } + ] + } + }, + { + "name": "Teleoperated", + "grid_layout": { + "layouts": [], + "containers": [ + { + "title": "Alerts", + "x": 1344.0, + "y": 0.0, + "width": 576.0, + "height": 736.0, + "type": "Alerts", + "properties": { + "topic": "/SmartDashboard/Alerts", + "period": 0.02 + } + }, + { + "title": "Match Time", + "x": 0.0, + "y": 0.0, + "width": 1344.0, + "height": 736.0, + "type": "Match Time", + "properties": { + "topic": "Dashboard/Robot Values/Match Time", + "period": 0.02, + "data_type": "double", + "time_display_mode": "Minutes and Seconds", + "red_start_time": 15, + "yellow_start_time": 30 + } + } + ] + } + }, + { + "name": "Programmer", + "grid_layout": { + "layouts": [ + { + "title": "Settings", + "x": 1184.0, + "y": 0.0, + "width": 224.0, + "height": 384.0, + "type": "List Layout", + "properties": { + "label_position": "RIGHT" + }, + "children": [ + { + "title": "Max Height", + "x": 0.0, + "y": 0.0, + "width": 128.0, + "height": 128.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator Max Height", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + }, + { + "title": "Hang Height", + "x": 0.0, + "y": 0.0, + "width": 128.0, + "height": 128.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator Hang Height", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + }, + { + "title": "L4 Height", + "x": 0.0, + "y": 0.0, + "width": 128.0, + "height": 128.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator L4 Height", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + }, + { + "title": "L3 Height", + "x": 0.0, + "y": 0.0, + "width": 128.0, + "height": 128.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator L3 Height", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + }, + { + "title": "L2 Height", + "x": 0.0, + "y": 0.0, + "width": 128.0, + "height": 128.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator L2 Height", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + }, + { + "title": "L1 Height", + "x": 0.0, + "y": 0.0, + "width": 128.0, + "height": 128.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator L1 Height", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + }, + { + "title": "Stow Height", + "x": 0.0, + "y": 0.0, + "width": 128.0, + "height": 128.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator Stow Height", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + }, + { + "title": "Min Height", + "x": 0.0, + "y": 0.0, + "width": 128.0, + "height": 128.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator Min Height", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + } + ] + }, + { + "title": "Zero", + "x": 1408.0, + "y": 0.0, + "width": 224.0, + "height": 384.0, + "type": "List Layout", + "properties": { + "label_position": "HIDDEN" + }, + "children": [ + { + "title": "Zero", + "x": 800.0, + "y": 96.0, + "width": 128.0, + "height": 128.0, + "type": "Toggle Switch", + "properties": { + "topic": "Dashboard/Buttons/Elevator Zero Max Height", + "period": 0.02, + "data_type": "boolean" + } + }, + { + "title": "Zero", + "x": 800.0, + "y": 160.0, + "width": 128.0, + "height": 128.0, + "type": "Toggle Switch", + "properties": { + "topic": "Dashboard/Buttons/Elevator Zero Hang Height", + "period": 0.02, + "data_type": "boolean" + } + }, + { + "title": "Zero", + "x": 736.0, + "y": 192.0, + "width": 128.0, + "height": 128.0, + "type": "Toggle Switch", + "properties": { + "topic": "Dashboard/Buttons/Elevator Zero L4 Height", + "period": 0.02, + "data_type": "boolean" + } + }, + { + "title": "Zero", + "x": 736.0, + "y": 224.0, + "width": 128.0, + "height": 128.0, + "type": "Toggle Switch", + "properties": { + "topic": "Dashboard/Buttons/Elevator Zero L3 Height", + "period": 0.02, + "data_type": "boolean" + } + }, + { + "title": "Zero", + "x": 736.0, + "y": 352.0, + "width": 128.0, + "height": 128.0, + "type": "Toggle Switch", + "properties": { + "topic": "Dashboard/Buttons/Elevator Zero L2 Height", + "period": 0.02, + "data_type": "boolean" + } + }, + { + "title": "Zero", + "x": 736.0, + "y": 384.0, + "width": 128.0, + "height": 128.0, + "type": "Toggle Switch", + "properties": { + "topic": "Dashboard/Buttons/Elevator Zero L1 Height", + "period": 0.02, + "data_type": "boolean" + } + }, + { + "title": "Zero", + "x": 736.0, + "y": 448.0, + "width": 128.0, + "height": 128.0, + "type": "Toggle Switch", + "properties": { + "topic": "Dashboard/Buttons/Elevator Zero Stow Height", + "period": 0.02, + "data_type": "boolean" + } + }, + { + "title": "Zero", + "x": 704.0, + "y": 448.0, + "width": 128.0, + "height": 128.0, + "type": "Toggle Switch", + "properties": { + "topic": "Dashboard/Buttons/Elevator Zero Min Height", + "period": 0.02, + "data_type": "boolean" + } + } + ] + }, + { + "title": "Offsets", + "x": 0.0, + "y": 384.0, + "width": 256.0, + "height": 224.0, + "type": "List Layout", + "properties": { + "label_position": "RIGHT" + }, + "children": [ + { + "title": "FL", + "x": 1216.0, + "y": 512.0, + "width": 128.0, + "height": 128.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Drive FL Offset", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + }, + { + "title": "FR", + "x": 1248.0, + "y": 576.0, + "width": 128.0, + "height": 128.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Drive FR Offset", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + }, + { + "title": "BL", + "x": 1184.0, + "y": 608.0, + "width": 128.0, + "height": 128.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Drive BL Offset", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + }, + { + "title": "BR", + "x": 1216.0, + "y": 640.0, + "width": 128.0, + "height": 128.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Drive BR Offset", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + } + ] + }, + { + "title": "Zero", + "x": 256.0, + "y": 384.0, + "width": 128.0, + "height": 224.0, + "type": "List Layout", + "properties": { + "label_position": "HIDDEN" + }, + "children": [ + { + "title": "Zero", + "x": 288.0, + "y": 480.0, + "width": 128.0, + "height": 128.0, + "type": "Toggle Switch", + "properties": { + "topic": "Dashboard/Buttons/Drive Zero FL Offset", + "period": 0.02, + "data_type": "boolean" + } + }, + { + "title": "Zero", + "x": 288.0, + "y": 480.0, + "width": 128.0, + "height": 128.0, + "type": "Toggle Switch", + "properties": { + "topic": "Dashboard/Buttons/Drive Zero FR Offset", + "period": 0.02, + "data_type": "boolean" + } + }, + { + "title": "Zero", + "x": 320.0, + "y": 544.0, + "width": 128.0, + "height": 128.0, + "type": "Toggle Switch", + "properties": { + "topic": "Dashboard/Buttons/Drive Zero BL Offset", + "period": 0.02, + "data_type": "boolean" + } + }, + { + "title": "Zero", + "x": 320.0, + "y": 576.0, + "width": 128.0, + "height": 128.0, + "type": "Toggle Switch", + "properties": { + "topic": "Dashboard/Buttons/Drive Zero BR Offset", + "period": 0.02, + "data_type": "boolean" + } + } + ] + } + ], + "containers": [ + { + "title": "Height", + "x": 1056.0, + "y": 0.0, + "width": 128.0, + "height": 384.0, + "type": "Number Bar", + "properties": { + "topic": "Dashboard/Robot Values/Elevator Height", + "period": 0.02, + "data_type": "double", + "min_value": 0.0, + "max_value": 80.0, + "divisions": 5, + "inverted": false, + "orientation": "vertical" + } + }, + { + "title": "Setpoint", + "x": 928.0, + "y": 0.0, + "width": 128.0, + "height": 384.0, + "type": "Number Bar", + "properties": { + "topic": "Dashboard/Robot Values/Elevator Setpoint", + "period": 0.02, + "data_type": "double", + "min_value": 0.0, + "max_value": 80.0, + "divisions": 5, + "inverted": false, + "orientation": "vertical" + } + }, + { + "title": "Swerve", + "x": 0.0, + "y": 0.0, + "width": 384.0, + "height": 384.0, + "type": "SwerveDrive", + "properties": { + "topic": "/SmartDashboard/Swerve", + "period": 0.02, + "show_robot_rotation": true, + "rotation_unit": "Radians" + } + }, + { + "title": "Zero Drive Modules", + "x": 0.0, + "y": 608.0, + "width": 384.0, + "height": 96.0, + "type": "Toggle Button", + "properties": { + "topic": "Dashboard/Buttons/Drive Zero Module Offsets", + "period": 0.02, + "data_type": "boolean" + } + }, + { + "title": "Hang Speed", + "x": 928.0, + "y": 384.0, + "width": 352.0, + "height": 128.0, + "type": "Number Slider", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator Hang Speed", + "period": 0.02, + "data_type": "double", + "min_value": 0.0, + "max_value": 1.0, + "divisions": 5, + "update_continuously": false + } + }, + { + "title": "Max Downward Speed", + "x": 928.0, + "y": 512.0, + "width": 352.0, + "height": 128.0, + "type": "Number Slider", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator Max Down Speed", + "period": 0.02, + "data_type": "double", + "min_value": 0.0, + "max_value": 1.0, + "divisions": 5, + "update_continuously": false + } + }, + { + "title": "Max Upward Speed", + "x": 1280.0, + "y": 512.0, + "width": 352.0, + "height": 128.0, + "type": "Number Slider", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator Max Up Speed", + "period": 0.02, + "data_type": "double", + "min_value": 0.0, + "max_value": 1.0, + "divisions": 5, + "update_continuously": false + } + }, + { + "title": "Elevator kD", + "x": 1472.0, + "y": 384.0, + "width": 160.0, + "height": 128.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator kD", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + }, + { + "title": "Elevator kP", + "x": 1280.0, + "y": 384.0, + "width": 192.0, + "height": 128.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator kP", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + }, + { + "title": "Dropped", + "x": 512.0, + "y": 768.0, + "width": 256.0, + "height": 96.0, + "type": "Boolean Box", + "properties": { + "topic": "Dashboard/Robot Values/Funnel Is Dropped", + "period": 0.02, + "data_type": "boolean", + "true_color": 4283215696, + "false_color": 4294198070, + "true_icon": "None", + "false_icon": "None" + } + }, + { + "title": "Retract Speed", + "x": 512.0, + "y": 640.0, + "width": 512.0, + "height": 128.0, + "type": "Number Slider", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Funnel Retract Speed", + "period": 0.02, + "data_type": "double", + "min_value": 0.0, + "max_value": 1.0, + "divisions": 5, + "update_continuously": false + } + }, + { + "title": "Retract Time", + "x": 768.0, + "y": 768.0, + "width": 256.0, + "height": 96.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Funnel Retract Time", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + }, + { + "title": "Left Output", + "x": 416.0, + "y": 0.0, + "width": 128.0, + "height": 192.0, + "type": "Number Bar", + "properties": { + "topic": "Dashboard/Robot Values/Manipulator Left Percent Output", + "period": 0.02, + "data_type": "double", + "min_value": -1.0, + "max_value": 1.0, + "divisions": 5, + "inverted": false, + "orientation": "vertical" + } + }, + { + "title": "Right Output", + "x": 544.0, + "y": 0.0, + "width": 128.0, + "height": 192.0, + "type": "Number Bar", + "properties": { + "topic": "Dashboard/Robot Values/Manipulator Right Percent Output", + "period": 0.02, + "data_type": "double", + "min_value": -1.0, + "max_value": 1.0, + "divisions": 5, + "inverted": false, + "orientation": "vertical" + } + }, + { + "title": "Intake Speed", + "x": 672.0, + "y": 128.0, + "width": 224.0, + "height": 128.0, + "type": "Number Slider", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Manipulator Intake Speed", + "period": 0.02, + "data_type": "double", + "min_value": 0.0, + "max_value": 1.0, + "divisions": 5, + "update_continuously": false + } + }, + { + "title": "Output Speed", + "x": 672.0, + "y": 0.0, + "width": 224.0, + "height": 128.0, + "type": "Number Slider", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Manipulator Output Speed", + "period": 0.02, + "data_type": "double", + "min_value": 0.0, + "max_value": 1.0, + "divisions": 5, + "update_continuously": false + } + }, + { + "title": "L1 Speed Multiplier", + "x": 672.0, + "y": 256.0, + "width": 224.0, + "height": 128.0, + "type": "Number Slider", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Manipulator L1 Speed Multiplier", + "period": 0.02, + "data_type": "double", + "min_value": 0.0, + "max_value": 1.0, + "divisions": 5, + "update_continuously": false + } + }, + { + "title": "End Sensor", + "x": 416.0, + "y": 192.0, + "width": 256.0, + "height": 96.0, + "type": "Boolean Box", + "properties": { + "topic": "Dashboard/Robot Values/Manipulator End Sensor Tripped", + "period": 0.02, + "data_type": "boolean", + "true_color": 4283215696, + "false_color": 4294198070, + "true_icon": "None", + "false_icon": "None" + } + }, + { + "title": "Start Sensor", + "x": 416.0, + "y": 288.0, + "width": 256.0, + "height": 96.0, + "type": "Boolean Box", + "properties": { + "topic": "Dashboard/Robot Values/Manipulator Start Sensor Tripped", + "period": 0.02, + "data_type": "boolean", + "true_color": 4283215696, + "false_color": 4294198070, + "true_icon": "None", + "false_icon": "None" + } + } + ] + } + } + ] +} diff --git a/src/main/java/frc/robot/Autos.java b/src/main/java/frc/robot/Autos.java index ca6af30..4044640 100644 --- a/src/main/java/frc/robot/Autos.java +++ b/src/main/java/frc/robot/Autos.java @@ -2,18 +2,48 @@ import com.ctre.phoenix6.swerve.SwerveModule.DriveRequestType; import com.ctre.phoenix6.swerve.SwerveRequest.ForwardPerspectiveValue; + +import java.util.stream.IntStream; + import com.ctre.phoenix6.swerve.SwerveRequest; import choreo.auto.AutoFactory; import choreo.trajectory.SwerveSample; import edu.wpi.first.math.controller.PIDController; import edu.wpi.first.math.geometry.Pose2d; +import edu.wpi.first.wpilibj.smartdashboard.Field2d; +import edu.wpi.first.wpilibj.smartdashboard.SendableChooser; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.Commands; import frc.robot.subsystems.Drive; public class Autos { + private enum StartPosition + { + LeftTrench("Left Trench"), LeftBump("Left Bump"), Hub("Hub"), RightBump("Right Bump"), RightTrench("Right Trench"); + + private final String displayName; + + private StartPosition(String displayName) + { + this.displayName = displayName; + } + } + + private enum AllianceFuelSourceSelection + { + None("None"), Depot("Depot"), Outpost("Outpost"), DepotToOutpost("Depot to Outpost"), OutpostToDepot("Outpost to Depot"); + + private final String displayName; + + private AllianceFuelSourceSelection(String displayName) + { + this.displayName = displayName; + } + } + private final AutoFactory _autoFactory; private final Drive _driveSubsystem; private final SwerveRequest.FieldCentric _autoFollowingRequest = new SwerveRequest.FieldCentric().withDriveRequestType(DriveRequestType.OpenLoopVoltage); @@ -21,6 +51,14 @@ public class Autos private final PIDController _yController = new PIDController(0.0, 0.0, 0.0); private final PIDController _headingController = new PIDController(0.0, 0.0, 0.0); + // Dashboard + private final Field2d _field; + private final SendableChooser _autoDelayChooser; + private final SendableChooser _startPositionChooser; + private final SendableChooser _allianceFuelSourceSelectionChooser; + private final String _neutralZoneNTKey; + private final String _climbNTKey; + public Autos(Drive driveSubsystem) { _driveSubsystem = driveSubsystem; @@ -35,6 +73,42 @@ public Autos(Drive driveSubsystem) driveSubsystem ); // @formatter:on + + // Dashboard + _field = new Field2d(); + + _autoDelayChooser = new SendableChooser<>(); + _startPositionChooser = new SendableChooser<>(); + _allianceFuelSourceSelectionChooser = new SendableChooser<>(); + + _neutralZoneNTKey = "Neutral Zone"; + _climbNTKey = "Climb"; + + _autoDelayChooser.setDefaultOption("0", 0); + IntStream.range(1, 6).forEach(n -> _autoDelayChooser.addOption(String.valueOf(n), n)); + + var startPositions = StartPosition.values(); + var fuelSources = AllianceFuelSourceSelection.values(); + + _startPositionChooser.setDefaultOption(startPositions[0].displayName, startPositions[0]); + _allianceFuelSourceSelectionChooser.setDefaultOption(fuelSources[0].displayName, fuelSources[0]); + + for (int i = 1; i < startPositions.length; i++) + { + _startPositionChooser.addOption(startPositions[i].displayName, startPositions[i]); + } + + for (int i = 1; i < fuelSources.length; i++) + { + _allianceFuelSourceSelectionChooser.addOption(fuelSources[i].displayName, fuelSources[i]); + } + + SmartDashboard.putData("Autonomous Mode", _field); + SmartDashboard.putData("Auto Delay", _autoDelayChooser); + SmartDashboard.putData("Start Position", _startPositionChooser); + SmartDashboard.putData("Alliance Fuel Source", _allianceFuelSourceSelectionChooser); + SmartDashboard.putBoolean(_neutralZoneNTKey, false); + SmartDashboard.putBoolean(_climbNTKey, false); } private void followTrajectory(SwerveSample sample) diff --git a/src/main/java/frc/robot/Robot.java b/src/main/java/frc/robot/Robot.java index 7a28db4..9e67390 100644 --- a/src/main/java/frc/robot/Robot.java +++ b/src/main/java/frc/robot/Robot.java @@ -9,6 +9,8 @@ import edu.wpi.first.epilogue.Epilogue; import edu.wpi.first.epilogue.Logged; +import edu.wpi.first.net.WebServer; +import edu.wpi.first.wpilibj.Filesystem; import edu.wpi.first.wpilibj.TimedRobot; import edu.wpi.first.wpilibj.simulation.RoboRioSim; import edu.wpi.first.wpilibj2.command.Command; @@ -28,6 +30,9 @@ public Robot() { m_robotContainer = new RobotContainer(); Epilogue.bind(this); + + // Start a webserver in the deploy directory so Elastic can remotely download layouts + WebServer.start(5800, Filesystem.getDeployDirectory().getPath()); } @Override From b0a41b61201a747fb6b3fd40c5abaa21b7200123 Mon Sep 17 00:00:00 2001 From: Collin McIntyre Date: Mon, 23 Feb 2026 20:15:29 -0600 Subject: [PATCH 2/9] WIP for dashboard --- .../frc/robot/subsystems/shooter/Hood.java | 38 +++++++++++++++---- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/main/java/frc/robot/subsystems/shooter/Hood.java b/src/main/java/frc/robot/subsystems/shooter/Hood.java index 7338ce2..889361a 100644 --- a/src/main/java/frc/robot/subsystems/shooter/Hood.java +++ b/src/main/java/frc/robot/subsystems/shooter/Hood.java @@ -4,15 +4,20 @@ import static edu.wpi.first.units.Units.RadiansPerSecond; import static edu.wpi.first.units.Units.Volts; +import java.util.Map; + import com.ctre.phoenix.motorcontrol.can.WPI_VictorSPX; import edu.wpi.first.math.controller.PIDController; import edu.wpi.first.math.system.plant.DCMotor; +import edu.wpi.first.networktables.DoubleEntry; +import edu.wpi.first.networktables.NetworkTableInstance; import edu.wpi.first.units.measure.Angle; import edu.wpi.first.units.measure.Voltage; import edu.wpi.first.wpilibj.DutyCycleEncoder; import edu.wpi.first.wpilibj.RobotBase; import edu.wpi.first.wpilibj.simulation.DutyCycleEncoderSim; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; import edu.wpi.first.epilogue.Logged; import frc.robot.Constants.GeneralConstants; @@ -28,14 +33,7 @@ public class Hood { public enum HoodPosition { - Shoot(ShooterConstants.HOOD_SHOOT_ANGLE), Pass(ShooterConstants.HOOD_PASS_ANGLE), Undefined(null); - - public final Angle targetAngle; - - private HoodPosition(Angle angle) - { - targetAngle = angle; - } + Shoot, Pass, Undefined } private final WPI_VictorSPX _hoodMotor; @@ -55,6 +53,18 @@ private HoodPosition(Angle angle) @Logged private boolean _hasSetpoint; + // Dashboard + private final DoubleEntry _minAngleEntry; + private final DoubleEntry _maxAngleEntry; + private final DoubleEntry _shootAngleEntry; + private final DoubleEntry _passAngleEntry; + private final DoubleEntry _toleranceEntry; + + private final Map _angleLookup = Map.of + ( + + ); + public Hood() { _hoodMotor = new WPI_VictorSPX(CANConstants.HOOD_MOTOR); @@ -69,6 +79,18 @@ public Hood() _pidController.setTolerance(ShooterConstants.HOOD_TOLERANCE.in(Degrees)); + // Dashboard + SmartDashboard.putData("Hood PID", _pidController); + + var table = NetworkTableInstance.getDefault().getTable("Shooter").getSubTable("Hood"); + + _minAngleEntry = table.getDoubleTopic("Min Angle").getEntry(ShooterConstants.HOOD_MIN_ANGLE.in(Degrees)); + _maxAngleEntry = table.getDoubleTopic("Max Angle").getEntry(ShooterConstants.HOOD_MAX_ANGLE.in(Degrees)); + _shootAngleEntry = table.getDoubleTopic("Shoot Angle").getEntry(ShooterConstants.HOOD_SHOOT_ANGLE.in(Degrees)); + _passAngleEntry = table.getDoubleTopic("Pass Angle").getEntry(ShooterConstants.HOOD_PASS_ANGLE.in(Degrees)); + _toleranceEntry = table.getDoubleTopic("Tolerance").getEntry(ShooterConstants.HOOD_TOLERANCE.in(Degrees)); + + // Real vs. Simulation if (RobotBase.isReal()) { _hoodMotor.configFactoryDefault(); From cf2cfd4ab25684dc6666b473d4c8c598d5d1b0b6 Mon Sep 17 00:00:00 2001 From: Collin McIntyre Date: Mon, 23 Feb 2026 20:57:31 -0600 Subject: [PATCH 3/9] working on dashboard --- .../frc/robot/subsystems/dashboard/Dashboard.java | 11 +++++++++++ src/main/java/frc/robot/subsystems/shooter/Hood.java | 5 ----- 2 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 src/main/java/frc/robot/subsystems/dashboard/Dashboard.java diff --git a/src/main/java/frc/robot/subsystems/dashboard/Dashboard.java b/src/main/java/frc/robot/subsystems/dashboard/Dashboard.java new file mode 100644 index 0000000..959a0ad --- /dev/null +++ b/src/main/java/frc/robot/subsystems/dashboard/Dashboard.java @@ -0,0 +1,11 @@ +package frc.robot.subsystems.dashboard; + +import edu.wpi.first.wpilibj2.command.SubsystemBase; +import frc.robot.subsystems.intake.Intake; +import frc.robot.subsystems.shooter.Shooter; + +public class Dashboard extends SubsystemBase { + private final Intake _intake; + private final Shooter _shooter; + +} diff --git a/src/main/java/frc/robot/subsystems/shooter/Hood.java b/src/main/java/frc/robot/subsystems/shooter/Hood.java index 889361a..d3b0743 100644 --- a/src/main/java/frc/robot/subsystems/shooter/Hood.java +++ b/src/main/java/frc/robot/subsystems/shooter/Hood.java @@ -60,11 +60,6 @@ public enum HoodPosition private final DoubleEntry _passAngleEntry; private final DoubleEntry _toleranceEntry; - private final Map _angleLookup = Map.of - ( - - ); - public Hood() { _hoodMotor = new WPI_VictorSPX(CANConstants.HOOD_MOTOR); From a0d98996b3ae4b59f152061ae858b181d284b4db Mon Sep 17 00:00:00 2001 From: SAKETH11111 Date: Tue, 24 Feb 2026 17:11:55 -0600 Subject: [PATCH 4/9] Enhance Dashboard and Shooter Subsystems --- src/main/deploy/elastic-layout.json | 990 +++++++++--------- src/main/java/frc/robot/Autos.java | 3 + src/main/java/frc/robot/Robot.java | 3 +- src/main/java/frc/robot/RobotContainer.java | 6 +- .../robot/subsystems/dashboard/Dashboard.java | 128 ++- .../frc/robot/subsystems/shooter/Hood.java | 19 +- .../frc/robot/subsystems/shooter/Shooter.java | 10 + .../frc/robot/subsystems/shooter/Turret.java | 52 +- src/main/java/frc/robot/util/Utilities.java | 29 + 9 files changed, 718 insertions(+), 522 deletions(-) diff --git a/src/main/deploy/elastic-layout.json b/src/main/deploy/elastic-layout.json index dce466d..c811f1d 100644 --- a/src/main/deploy/elastic-layout.json +++ b/src/main/deploy/elastic-layout.json @@ -8,10 +8,10 @@ "layouts": [ { "title": "List Layout", - "x": 1632.0, + "x": 1344.0, "y": 0.0, - "width": 288.0, - "height": 416.0, + "width": 352.0, + "height": 448.0, "type": "List Layout", "properties": { "label_position": "TOP" @@ -88,9 +88,9 @@ "containers": [ { "title": "Alerts", - "x": 1632.0, - "y": 416.0, - "width": 288.0, + "x": 1344.0, + "y": 448.0, + "width": 352.0, "height": 320.0, "type": "Alerts", "properties": { @@ -102,8 +102,8 @@ "title": "Autonomous Mode", "x": 0.0, "y": 0.0, - "width": 1632.0, - "height": 736.0, + "width": 1344.0, + "height": 768.0, "type": "Field", "properties": { "topic": "/SmartDashboard/Autonomous Mode", @@ -129,9 +129,9 @@ "containers": [ { "title": "Alerts", - "x": 1344.0, + "x": 1728.0, "y": 0.0, - "width": 576.0, + "width": 192.0, "height": 736.0, "type": "Alerts", "properties": { @@ -143,8 +143,8 @@ "title": "Match Time", "x": 0.0, "y": 0.0, - "width": 1344.0, - "height": 736.0, + "width": 1120.0, + "height": 640.0, "type": "Match Time", "properties": { "topic": "Dashboard/Robot Values/Match Time", @@ -154,6 +154,88 @@ "red_start_time": 15, "yellow_start_time": 30 } + }, + { + "title": "Hub Active", + "x": 1120.0, + "y": 0.0, + "width": 576.0, + "height": 160.0, + "type": "Boolean Box", + "properties": { + "topic": "Dashboard/Robot Values/Hub Active", + "period": 0.02, + "data_type": "boolean", + "true_color": 4283215696, + "false_color": 4294198070, + "true_icon": "None", + "false_icon": "None" + } + }, + { + "title": "Turret Has Target", + "x": 1120.0, + "y": 480.0, + "width": 288.0, + "height": 160.0, + "type": "Boolean Box", + "properties": { + "topic": "Dashboard/Robot Values/Turret Has Target", + "period": 0.02, + "data_type": "boolean", + "true_color": 4283215696, + "false_color": 4294198070, + "true_icon": "None", + "false_icon": "None" + } + }, + { + "title": "Hub State Timer", + "x": 1120.0, + "y": 160.0, + "width": 576.0, + "height": 160.0, + "type": "Text Display", + "properties": { + "topic": "Dashboard/Robot Values/Hub State Time Remaining", + "period": 0.02, + "data_type": "double", + "show_submit_button": false + } + }, + { + "title": "Shooter Mode", + "x": 1120.0, + "y": 320.0, + "width": 576.0, + "height": 160.0, + "type": "Boolean Box", + "properties": { + "topic": "Dashboard/Robot Values/Shooter Is Shoot Mode", + "period": 0.02, + "data_type": "boolean", + "true_color": 4278190335, + "false_color": 4294934272, + "true_icon": "None", + "false_icon": "None" + } + }, + { + "title": "Turret Lined Up", + "x": 1408.0, + "y": 480.0, + "width": 288.0, + "height": 160.0, + "type": "Boolean Box", + "properties": { + "topic": "Dashboard/Robot Values/Turret Lined Up", + "period": 0.02, + "data_type": "boolean", + "true_color": 4283215696, + "false_color": 4294198070, + "true_icon": "None", + "false_icon": "None" + } } ] } @@ -163,377 +245,570 @@ "grid_layout": { "layouts": [ { - "title": "Settings", - "x": 1184.0, + "title": "Hood & Turret", + "x": 0.0, "y": 0.0, - "width": 224.0, - "height": 384.0, + "width": 256.0, + "height": 736.0, "type": "List Layout", "properties": { - "label_position": "RIGHT" + "label_position": "TOP" }, "children": [ { - "title": "Max Height", + "title": "Hood PID", "x": 0.0, "y": 0.0, - "width": 128.0, + "width": 121.0, "height": 128.0, - "type": "Text Display", + "type": "PIDController", "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator Max Height", - "period": 0.02, - "data_type": "double", - "show_submit_button": false + "topic": "/SmartDashboard/Hood PID", + "period": 0.05 } }, { - "title": "Hang Height", + "title": "Turret PID", "x": 0.0, "y": 0.0, - "width": 128.0, + "width": 121.0, "height": 128.0, - "type": "Text Display", + "type": "PIDController", "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator Hang Height", - "period": 0.02, - "data_type": "double", - "show_submit_button": false + "topic": "/SmartDashboard/Turret PID", + "period": 0.05 + } + } + ] + }, + { + "title": "Auto Driving", + "x": 256.0, + "y": 0.0, + "width": 256.0, + "height": 736.0, + "type": "List Layout", + "properties": { + "label_position": "TOP" + }, + "children": [ + { + "title": "Auto X PID", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 128.0, + "type": "PIDController", + "properties": { + "topic": "/SmartDashboard/Auto X PID", + "period": 0.05 } }, { - "title": "L4 Height", + "title": "Auto Y PID", "x": 0.0, "y": 0.0, - "width": 128.0, + "width": 121.0, "height": 128.0, - "type": "Text Display", + "type": "PIDController", "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator L4 Height", - "period": 0.02, - "data_type": "double", - "show_submit_button": false + "topic": "/SmartDashboard/Auto Y PID", + "period": 0.05 } }, { - "title": "L3 Height", + "title": "Auto Heading PID", "x": 0.0, "y": 0.0, - "width": 128.0, + "width": 121.0, "height": 128.0, + "type": "PIDController", + "properties": { + "topic": "/SmartDashboard/Auto Heading PID", + "period": 0.05 + } + } + ] + }, + { + "title": "Intake", + "x": 512.0, + "y": 0.0, + "width": 256.0, + "height": 256.0, + "type": "List Layout", + "properties": { + "label_position": "RIGHT" + }, + "children": [ + { + "title": "Forward Voltage", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, "type": "Text Display", "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator L3 Height", + "topic": "/Preferences/Dashboard/Dashboard Settings/Intake Forward Voltage", "period": 0.02, "data_type": "double", - "show_submit_button": false + "show_submit_button": true } }, { - "title": "L2 Height", + "title": "Reverse Voltage", "x": 0.0, "y": 0.0, - "width": 128.0, - "height": 128.0, + "width": 121.0, + "height": 64.0, "type": "Text Display", "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator L2 Height", + "topic": "/Preferences/Dashboard/Dashboard Settings/Intake Reverse Voltage", "period": 0.02, "data_type": "double", - "show_submit_button": false + "show_submit_button": true } }, { - "title": "L1 Height", + "title": "Extension Max Position", "x": 0.0, "y": 0.0, - "width": 128.0, - "height": 128.0, + "width": 121.0, + "height": 64.0, "type": "Text Display", "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator L1 Height", + "topic": "/Preferences/Dashboard/Dashboard Settings/Intake Extension Max Position", "period": 0.02, "data_type": "double", - "show_submit_button": false + "show_submit_button": true } }, { - "title": "Stow Height", + "title": "Extend Voltage", "x": 0.0, "y": 0.0, - "width": 128.0, - "height": 128.0, + "width": 121.0, + "height": 64.0, "type": "Text Display", "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator Stow Height", + "topic": "/Preferences/Dashboard/Dashboard Settings/Intake Extend Voltage", "period": 0.02, "data_type": "double", - "show_submit_button": false + "show_submit_button": true } }, { - "title": "Min Height", + "title": "Retract Voltage", "x": 0.0, "y": 0.0, - "width": 128.0, - "height": 128.0, + "width": 121.0, + "height": 64.0, "type": "Text Display", "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator Min Height", + "topic": "/Preferences/Dashboard/Dashboard Settings/Intake Retract Voltage", "period": 0.02, "data_type": "double", - "show_submit_button": false + "show_submit_button": true } } ] }, { - "title": "Zero", - "x": 1408.0, + "title": "Hood", + "x": 768.0, "y": 0.0, - "width": 224.0, - "height": 384.0, + "width": 256.0, + "height": 256.0, "type": "List Layout", "properties": { - "label_position": "HIDDEN" + "label_position": "RIGHT" }, "children": [ { - "title": "Zero", - "x": 800.0, - "y": 96.0, - "width": 128.0, - "height": 128.0, - "type": "Toggle Switch", + "title": "Min Angle", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", "properties": { - "topic": "Dashboard/Buttons/Elevator Zero Max Height", + "topic": "/Preferences/Dashboard/Dashboard Settings/Hood Min Angle", "period": 0.02, - "data_type": "boolean" + "data_type": "double", + "show_submit_button": true } }, { - "title": "Zero", - "x": 800.0, - "y": 160.0, - "width": 128.0, - "height": 128.0, - "type": "Toggle Switch", + "title": "Max Angle", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", "properties": { - "topic": "Dashboard/Buttons/Elevator Zero Hang Height", + "topic": "/Preferences/Dashboard/Dashboard Settings/Hood Max Angle", "period": 0.02, - "data_type": "boolean" + "data_type": "double", + "show_submit_button": true } }, { - "title": "Zero", - "x": 736.0, - "y": 192.0, - "width": 128.0, - "height": 128.0, - "type": "Toggle Switch", + "title": "Shoot Angle", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", "properties": { - "topic": "Dashboard/Buttons/Elevator Zero L4 Height", + "topic": "/Preferences/Dashboard/Dashboard Settings/Hood Shoot Angle", "period": 0.02, - "data_type": "boolean" + "data_type": "double", + "show_submit_button": true } }, { - "title": "Zero", - "x": 736.0, - "y": 224.0, - "width": 128.0, - "height": 128.0, - "type": "Toggle Switch", + "title": "Pass Angle", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", "properties": { - "topic": "Dashboard/Buttons/Elevator Zero L3 Height", + "topic": "/Preferences/Dashboard/Dashboard Settings/Hood Pass Angle", "period": 0.02, - "data_type": "boolean" + "data_type": "double", + "show_submit_button": true } }, { - "title": "Zero", - "x": 736.0, - "y": 352.0, - "width": 128.0, - "height": 128.0, - "type": "Toggle Switch", + "title": "Tolerance", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", "properties": { - "topic": "Dashboard/Buttons/Elevator Zero L2 Height", + "topic": "/Preferences/Dashboard/Dashboard Settings/Hood Tolerance", "period": 0.02, - "data_type": "boolean" + "data_type": "double", + "show_submit_button": true + } + } + ] + }, + { + "title": "Turret", + "x": 1024.0, + "y": 0.0, + "width": 256.0, + "height": 256.0, + "type": "List Layout", + "properties": { + "label_position": "RIGHT" + }, + "children": [ + { + "title": "Min Angle", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Turret Min Angle", + "period": 0.02, + "data_type": "double", + "show_submit_button": true } }, { - "title": "Zero", - "x": 736.0, - "y": 384.0, - "width": 128.0, - "height": 128.0, - "type": "Toggle Switch", + "title": "Max Angle", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", "properties": { - "topic": "Dashboard/Buttons/Elevator Zero L1 Height", + "topic": "/Preferences/Dashboard/Dashboard Settings/Turret Max Angle", "period": 0.02, - "data_type": "boolean" + "data_type": "double", + "show_submit_button": true } }, { - "title": "Zero", - "x": 736.0, - "y": 448.0, - "width": 128.0, - "height": 128.0, - "type": "Toggle Switch", + "title": "Home Angle", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", "properties": { - "topic": "Dashboard/Buttons/Elevator Zero Stow Height", + "topic": "/Preferences/Dashboard/Dashboard Settings/Turret Home Angle", "period": 0.02, - "data_type": "boolean" + "data_type": "double", + "show_submit_button": true } }, { - "title": "Zero", - "x": 704.0, - "y": 448.0, - "width": 128.0, - "height": 128.0, - "type": "Toggle Switch", + "title": "Tolerance", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", "properties": { - "topic": "Dashboard/Buttons/Elevator Zero Min Height", + "topic": "/Preferences/Dashboard/Dashboard Settings/Turret Tolerance", "period": 0.02, - "data_type": "boolean" + "data_type": "double", + "show_submit_button": true + } + }, + { + "title": "Pass Angle", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Turret Pass Angle", + "period": 0.02, + "data_type": "double", + "show_submit_button": true } } ] }, { - "title": "Offsets", - "x": 0.0, - "y": 384.0, + "title": "Flywheel", + "x": 1280.0, + "y": 0.0, "width": 256.0, - "height": 224.0, + "height": 256.0, "type": "List Layout", "properties": { "label_position": "RIGHT" }, "children": [ { - "title": "FL", - "x": 1216.0, - "y": 512.0, - "width": 128.0, - "height": 128.0, + "title": "Tolerance", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, "type": "Text Display", "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Drive FL Offset", + "topic": "/Preferences/Dashboard/Dashboard Settings/Flywheel Tolerance", "period": 0.02, "data_type": "double", - "show_submit_button": false + "show_submit_button": true } }, { - "title": "FR", - "x": 1248.0, - "y": 576.0, - "width": 128.0, - "height": 128.0, + "title": "Pass Velocity", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, "type": "Text Display", "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Drive FR Offset", + "topic": "/Preferences/Dashboard/Dashboard Settings/Flywheel Pass Velocity", "period": 0.02, "data_type": "double", - "show_submit_button": false + "show_submit_button": true } - }, + } + ] + }, + { + "title": "Feeder", + "x": 1280.0, + "y": 256.0, + "width": 256.0, + "height": 256.0, + "type": "List Layout", + "properties": { + "label_position": "RIGHT" + }, + "children": [ { - "title": "BL", - "x": 1184.0, - "y": 608.0, - "width": 128.0, - "height": 128.0, + "title": "Feed Voltage", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Feeder Voltage", + "period": 0.02, + "data_type": "double", + "show_submit_button": true + } + } + ] + }, + { + "title": "Vision", + "x": 512.0, + "y": 256.0, + "width": 256.0, + "height": 256.0, + "type": "List Layout", + "properties": { + "label_position": "RIGHT" + }, + "children": [ + { + "title": "Max Angular Rate", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, "type": "Text Display", "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Drive BL Offset", + "topic": "/Preferences/Dashboard/Dashboard Settings/Vision Max Angular Rate", "period": 0.02, "data_type": "double", - "show_submit_button": false + "show_submit_button": true } }, { - "title": "BR", - "x": 1216.0, - "y": 640.0, - "width": 128.0, - "height": 128.0, + "title": "Max Tilt", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, "type": "Text Display", "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Drive BR Offset", + "topic": "/Preferences/Dashboard/Dashboard Settings/Vision Max Tilt", "period": 0.02, "data_type": "double", - "show_submit_button": false + "show_submit_button": true } } ] }, { - "title": "Zero", - "x": 256.0, - "y": 384.0, - "width": 128.0, - "height": 224.0, + "title": "Climber", + "x": 1536.0, + "y": 0.0, + "width": 256.0, + "height": 736.0, "type": "List Layout", "properties": { - "label_position": "HIDDEN" + "label_position": "RIGHT" }, "children": [ { - "title": "Zero", - "x": 288.0, - "y": 480.0, - "width": 128.0, - "height": 128.0, - "type": "Toggle Switch", + "title": "L1 Rotation", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", "properties": { - "topic": "Dashboard/Buttons/Drive Zero FL Offset", + "topic": "/Preferences/Dashboard/Dashboard Settings/Climber L1 Rotation", "period": 0.02, - "data_type": "boolean" + "data_type": "double", + "show_submit_button": true } }, { - "title": "Zero", - "x": 288.0, - "y": 480.0, - "width": 128.0, - "height": 128.0, - "type": "Toggle Switch", + "title": "L3 Rotation", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", "properties": { - "topic": "Dashboard/Buttons/Drive Zero FR Offset", + "topic": "/Preferences/Dashboard/Dashboard Settings/Climber L3 Rotation", "period": 0.02, - "data_type": "boolean" + "data_type": "double", + "show_submit_button": true } }, { - "title": "Zero", - "x": 320.0, - "y": 544.0, - "width": 128.0, - "height": 128.0, - "type": "Toggle Switch", + "title": "Extension Threshold", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", "properties": { - "topic": "Dashboard/Buttons/Drive Zero BL Offset", + "topic": "/Preferences/Dashboard/Dashboard Settings/Climber Extension Threshold", "period": 0.02, - "data_type": "boolean" + "data_type": "double", + "show_submit_button": true } }, { - "title": "Zero", - "x": 320.0, - "y": 576.0, - "width": 128.0, - "height": 128.0, - "type": "Toggle Switch", + "title": "Retraction Threshold", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", "properties": { - "topic": "Dashboard/Buttons/Drive Zero BR Offset", + "topic": "/Preferences/Dashboard/Dashboard Settings/Climber Retraction Threshold", "period": 0.02, - "data_type": "boolean" + "data_type": "double", + "show_submit_button": true + } + }, + { + "title": "Extend Voltage", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Climber Extend Voltage", + "period": 0.02, + "data_type": "double", + "show_submit_button": true + } + }, + { + "title": "Retract Voltage", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Climber Retract Voltage", + "period": 0.02, + "data_type": "double", + "show_submit_button": true + } + }, + { + "title": "Rotate Voltage", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Climber Rotate Voltage", + "period": 0.02, + "data_type": "double", + "show_submit_button": true + } + }, + { + "title": "Tolerance", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Climber Tolerance", + "period": 0.02, + "data_type": "double", + "show_submit_button": true } } ] @@ -541,314 +816,17 @@ ], "containers": [ { - "title": "Height", - "x": 1056.0, - "y": 0.0, - "width": 128.0, - "height": 384.0, - "type": "Number Bar", - "properties": { - "topic": "Dashboard/Robot Values/Elevator Height", - "period": 0.02, - "data_type": "double", - "min_value": 0.0, - "max_value": 80.0, - "divisions": 5, - "inverted": false, - "orientation": "vertical" - } - }, - { - "title": "Setpoint", - "x": 928.0, - "y": 0.0, - "width": 128.0, - "height": 384.0, - "type": "Number Bar", - "properties": { - "topic": "Dashboard/Robot Values/Elevator Setpoint", - "period": 0.02, - "data_type": "double", - "min_value": 0.0, - "max_value": 80.0, - "divisions": 5, - "inverted": false, - "orientation": "vertical" - } - }, - { - "title": "Swerve", - "x": 0.0, - "y": 0.0, - "width": 384.0, - "height": 384.0, - "type": "SwerveDrive", - "properties": { - "topic": "/SmartDashboard/Swerve", - "period": 0.02, - "show_robot_rotation": true, - "rotation_unit": "Radians" - } - }, - { - "title": "Zero Drive Modules", - "x": 0.0, - "y": 608.0, - "width": 384.0, - "height": 96.0, - "type": "Toggle Button", - "properties": { - "topic": "Dashboard/Buttons/Drive Zero Module Offsets", - "period": 0.02, - "data_type": "boolean" - } - }, - { - "title": "Hang Speed", - "x": 928.0, - "y": 384.0, - "width": 352.0, - "height": 128.0, - "type": "Number Slider", - "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator Hang Speed", - "period": 0.02, - "data_type": "double", - "min_value": 0.0, - "max_value": 1.0, - "divisions": 5, - "update_continuously": false - } - }, - { - "title": "Max Downward Speed", - "x": 928.0, - "y": 512.0, - "width": 352.0, - "height": 128.0, - "type": "Number Slider", - "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator Max Down Speed", - "period": 0.02, - "data_type": "double", - "min_value": 0.0, - "max_value": 1.0, - "divisions": 5, - "update_continuously": false - } - }, - { - "title": "Max Upward Speed", - "x": 1280.0, - "y": 512.0, - "width": 352.0, - "height": 128.0, - "type": "Number Slider", - "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator Max Up Speed", - "period": 0.02, - "data_type": "double", - "min_value": 0.0, - "max_value": 1.0, - "divisions": 5, - "update_continuously": false - } - }, - { - "title": "Elevator kD", - "x": 1472.0, - "y": 384.0, - "width": 160.0, - "height": 128.0, - "type": "Text Display", - "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator kD", - "period": 0.02, - "data_type": "double", - "show_submit_button": false - } - }, - { - "title": "Elevator kP", - "x": 1280.0, - "y": 384.0, - "width": 192.0, - "height": 128.0, - "type": "Text Display", - "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Elevator kP", - "period": 0.02, - "data_type": "double", - "show_submit_button": false - } - }, - { - "title": "Dropped", - "x": 512.0, - "y": 768.0, - "width": 256.0, - "height": 96.0, - "type": "Boolean Box", - "properties": { - "topic": "Dashboard/Robot Values/Funnel Is Dropped", - "period": 0.02, - "data_type": "boolean", - "true_color": 4283215696, - "false_color": 4294198070, - "true_icon": "None", - "false_icon": "None" - } - }, - { - "title": "Retract Speed", - "x": 512.0, - "y": 640.0, - "width": 512.0, - "height": 128.0, - "type": "Number Slider", - "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Funnel Retract Speed", - "period": 0.02, - "data_type": "double", - "min_value": 0.0, - "max_value": 1.0, - "divisions": 5, - "update_continuously": false - } - }, - { - "title": "Retract Time", + "title": "Turret Test Mode", "x": 768.0, - "y": 768.0, - "width": 256.0, - "height": 96.0, - "type": "Text Display", - "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Funnel Retract Time", - "period": 0.02, - "data_type": "double", - "show_submit_button": false - } - }, - { - "title": "Left Output", - "x": 416.0, - "y": 0.0, - "width": 128.0, - "height": 192.0, - "type": "Number Bar", - "properties": { - "topic": "Dashboard/Robot Values/Manipulator Left Percent Output", - "period": 0.02, - "data_type": "double", - "min_value": -1.0, - "max_value": 1.0, - "divisions": 5, - "inverted": false, - "orientation": "vertical" - } - }, - { - "title": "Right Output", - "x": 544.0, - "y": 0.0, - "width": 128.0, - "height": 192.0, - "type": "Number Bar", - "properties": { - "topic": "Dashboard/Robot Values/Manipulator Right Percent Output", - "period": 0.02, - "data_type": "double", - "min_value": -1.0, - "max_value": 1.0, - "divisions": 5, - "inverted": false, - "orientation": "vertical" - } - }, - { - "title": "Intake Speed", - "x": 672.0, - "y": 128.0, - "width": 224.0, - "height": 128.0, - "type": "Number Slider", - "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Manipulator Intake Speed", - "period": 0.02, - "data_type": "double", - "min_value": 0.0, - "max_value": 1.0, - "divisions": 5, - "update_continuously": false - } - }, - { - "title": "Output Speed", - "x": 672.0, - "y": 0.0, - "width": 224.0, - "height": 128.0, - "type": "Number Slider", - "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Manipulator Output Speed", - "period": 0.02, - "data_type": "double", - "min_value": 0.0, - "max_value": 1.0, - "divisions": 5, - "update_continuously": false - } - }, - { - "title": "L1 Speed Multiplier", - "x": 672.0, "y": 256.0, - "width": 224.0, - "height": 128.0, - "type": "Number Slider", - "properties": { - "topic": "/Preferences/Dashboard/Dashboard Settings/Manipulator L1 Speed Multiplier", - "period": 0.02, - "data_type": "double", - "min_value": 0.0, - "max_value": 1.0, - "divisions": 5, - "update_continuously": false - } - }, - { - "title": "End Sensor", - "x": 416.0, - "y": 192.0, "width": 256.0, - "height": 96.0, - "type": "Boolean Box", - "properties": { - "topic": "Dashboard/Robot Values/Manipulator End Sensor Tripped", - "period": 0.02, - "data_type": "boolean", - "true_color": 4283215696, - "false_color": 4294198070, - "true_icon": "None", - "false_icon": "None" - } - }, - { - "title": "Start Sensor", - "x": 416.0, - "y": 288.0, - "width": 256.0, - "height": 96.0, - "type": "Boolean Box", + "height": 192.0, + "type": "Command", "properties": { - "topic": "Dashboard/Robot Values/Manipulator Start Sensor Tripped", - "period": 0.02, - "data_type": "boolean", - "true_color": 4283215696, - "false_color": 4294198070, - "true_icon": "None", - "false_icon": "None" + "topic": "/SmartDashboard/Turret Test Mode", + "period": 0.05, + "show_type": true, + "maximize_button_space": true } } ] diff --git a/src/main/java/frc/robot/Autos.java b/src/main/java/frc/robot/Autos.java index 4044640..1b33dfb 100644 --- a/src/main/java/frc/robot/Autos.java +++ b/src/main/java/frc/robot/Autos.java @@ -107,6 +107,9 @@ public Autos(Drive driveSubsystem) SmartDashboard.putData("Auto Delay", _autoDelayChooser); SmartDashboard.putData("Start Position", _startPositionChooser); SmartDashboard.putData("Alliance Fuel Source", _allianceFuelSourceSelectionChooser); + SmartDashboard.putData("Auto X PID", _xController); + SmartDashboard.putData("Auto Y PID", _yController); + SmartDashboard.putData("Auto Heading PID", _headingController); SmartDashboard.putBoolean(_neutralZoneNTKey, false); SmartDashboard.putBoolean(_climbNTKey, false); } diff --git a/src/main/java/frc/robot/Robot.java b/src/main/java/frc/robot/Robot.java index 9e67390..76caad8 100644 --- a/src/main/java/frc/robot/Robot.java +++ b/src/main/java/frc/robot/Robot.java @@ -31,7 +31,8 @@ public Robot() m_robotContainer = new RobotContainer(); Epilogue.bind(this); - // Start a webserver in the deploy directory so Elastic can remotely download layouts + // Start a webserver in the deploy directory so Elastic can remotely download + // layouts WebServer.start(5800, Filesystem.getDeployDirectory().getPath()); } diff --git a/src/main/java/frc/robot/RobotContainer.java b/src/main/java/frc/robot/RobotContainer.java index 388592a..b6b4860 100644 --- a/src/main/java/frc/robot/RobotContainer.java +++ b/src/main/java/frc/robot/RobotContainer.java @@ -24,6 +24,7 @@ import frc.robot.Constants.DriveConstants; import frc.robot.generated.TunerConstants; import frc.robot.subsystems.Drive; +import frc.robot.subsystems.dashboard.Dashboard; import frc.robot.subsystems.intake.Intake; import frc.robot.subsystems.shooter.Shooter; import frc.robot.subsystems.shooter.Turret; @@ -44,8 +45,9 @@ public class RobotContainer private final Drive _drivetrain = TunerConstants.createDrivetrain(); private final Intake _intake = new Intake(); private final Shooter _shooter = new Shooter(); - // private final Turret _turret = new Turret(_drivetrain::getState); - private final Autos _autos = new Autos(_drivetrain); + private final Turret _turret = new Turret(_drivetrain::getState); + private final Autos _autos = new Autos(_drivetrain); + private final Dashboard _dashboard = new Dashboard(_intake, _shooter, _turret); public RobotContainer() { diff --git a/src/main/java/frc/robot/subsystems/dashboard/Dashboard.java b/src/main/java/frc/robot/subsystems/dashboard/Dashboard.java index 959a0ad..de6c4d2 100644 --- a/src/main/java/frc/robot/subsystems/dashboard/Dashboard.java +++ b/src/main/java/frc/robot/subsystems/dashboard/Dashboard.java @@ -1,11 +1,131 @@ package frc.robot.subsystems.dashboard; +import static edu.wpi.first.units.Units.Degrees; +import static edu.wpi.first.units.Units.DegreesPerSecond; +import static edu.wpi.first.units.Units.Inches; +import static edu.wpi.first.units.Units.RPM; +import static edu.wpi.first.units.Units.Seconds; +import static edu.wpi.first.units.Units.Value; +import static edu.wpi.first.units.Units.Volts; + +import edu.wpi.first.networktables.BooleanPublisher; +import edu.wpi.first.networktables.DoublePublisher; +import edu.wpi.first.networktables.NetworkTable; +import edu.wpi.first.networktables.NetworkTableInstance; +import edu.wpi.first.networktables.StringPublisher; +import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj.Preferences; import edu.wpi.first.wpilibj2.command.SubsystemBase; +import frc.robot.Constants.ClimberConstants; +import frc.robot.Constants.IntakeConstants; +import frc.robot.Constants.ShooterConstants; +import frc.robot.Constants.VisionConstants; import frc.robot.subsystems.intake.Intake; +import frc.robot.subsystems.shooter.Hood.HoodPosition; import frc.robot.subsystems.shooter.Shooter; +import frc.robot.subsystems.shooter.Turret; +import frc.robot.util.Utilities; + +public class Dashboard extends SubsystemBase +{ + private final Intake _intake; + private final Shooter _shooter; + private final Turret _turret; + private final DoublePublisher _matchTimePublisher; + private final BooleanPublisher _hubActivePublisher; + private final DoublePublisher _hubStateTimeRemainingPublisher; + private final BooleanPublisher _turretHasTargetPublisher; + private final BooleanPublisher _turretLinedUpPublisher; + private final BooleanPublisher _shooterShootModePublisher; + private final StringPublisher _shooterModePublisher; + + public Dashboard(Intake intake, Shooter shooter, Turret turret) + { + _intake = intake; + _shooter = shooter; + _turret = turret; + + var dashboardTable = NetworkTableInstance.getDefault().getTable("Dashboard"); + var valuesTable = dashboardTable.getSubTable("Robot Values"); + + _matchTimePublisher = valuesTable.getDoubleTopic("Match Time").publish(); + _hubActivePublisher = valuesTable.getBooleanTopic("Hub Active").publish(); + _hubStateTimeRemainingPublisher = valuesTable.getDoubleTopic("Hub State Time Remaining").publish(); + _turretHasTargetPublisher = valuesTable.getBooleanTopic("Turret Has Target").publish(); + _turretLinedUpPublisher = valuesTable.getBooleanTopic("Turret Lined Up").publish(); + _shooterShootModePublisher = valuesTable.getBooleanTopic("Shooter Is Shoot Mode").publish(); + _shooterModePublisher = valuesTable.getStringTopic("Shooter Mode").publish(); + + initializeTuningPreferences(); + } + + @Override + public void periodic() + { + _matchTimePublisher.set(Math.max(DriverStation.getMatchTime(), 0.0)); + + boolean hubActive = Utilities.isHubActive(); + _hubActivePublisher.set(hubActive); + _hubStateTimeRemainingPublisher.set(Math.max(Utilities.getHubStateTimeRemaining().in(Seconds), 0.0)); + + if (_turret != null) + { + _turretHasTargetPublisher.set(_turret.hasTarget()); + _turretLinedUpPublisher.set(_turret.isLinedUp()); + } + else + { + _turretHasTargetPublisher.set(false); + _turretLinedUpPublisher.set(false); + } + + HoodPosition shooterMode = _shooter.getShooterMode(); + _shooterShootModePublisher.set(shooterMode != HoodPosition.Pass); + _shooterModePublisher.set(shooterMode.name()); + } + + private static void initPreference(String key, double value) + { + Preferences.initDouble(key, value); + } + + private void initializeTuningPreferences() + { + String prefix = "Dashboard/Dashboard Settings/"; + + initPreference(prefix + "Intake Forward Voltage", IntakeConstants.INTAKE_VOLTS.in(Volts)); + initPreference(prefix + "Intake Reverse Voltage", IntakeConstants.REVERSE_VOLTS.in(Volts)); + initPreference(prefix + "Intake Extension Max Position", IntakeConstants.EXTENSION_MAX_POSITION.in(Inches)); + initPreference(prefix + "Intake Extend Voltage", IntakeConstants.EXTEND_VOLTS.in(Volts)); + initPreference(prefix + "Intake Retract Voltage", IntakeConstants.RETRACT_VOLTS.in(Volts)); + + initPreference(prefix + "Flywheel Tolerance", ShooterConstants.FLYWHEEL_TOLERANCE.in(Value)); + initPreference(prefix + "Flywheel Pass Velocity", ShooterConstants.PASS_FLYWHEEL_VELOCITY.in(RPM)); + + initPreference(prefix + "Hood Min Angle", ShooterConstants.HOOD_MIN_ANGLE.in(Degrees)); + initPreference(prefix + "Hood Max Angle", ShooterConstants.HOOD_MAX_ANGLE.in(Degrees)); + initPreference(prefix + "Hood Shoot Angle", ShooterConstants.HOOD_SHOOT_ANGLE.in(Degrees)); + initPreference(prefix + "Hood Pass Angle", ShooterConstants.HOOD_PASS_ANGLE.in(Degrees)); + initPreference(prefix + "Hood Tolerance", ShooterConstants.HOOD_TOLERANCE.in(Degrees)); + + initPreference(prefix + "Turret Min Angle", ShooterConstants.TURRET_MIN_ANGLE.in(Degrees)); + initPreference(prefix + "Turret Max Angle", ShooterConstants.TURRET_MAX_ANGLE.in(Degrees)); + initPreference(prefix + "Turret Home Angle", ShooterConstants.TURRET_HOME_ANGLE.in(Degrees)); + initPreference(prefix + "Turret Pass Angle", ShooterConstants.TURRET_PASS_TARGET.in(Degrees)); + initPreference(prefix + "Turret Tolerance", ShooterConstants.TURRET_TOLERANCE.in(Degrees)); + + initPreference(prefix + "Feeder Voltage", ShooterConstants.FEEDER_VOLTAGE.in(Volts)); + + initPreference(prefix + "Vision Max Angular Rate", VisionConstants.MAX_ANGULAR_RATE_FOR_VISION.in(DegreesPerSecond)); + initPreference(prefix + "Vision Max Tilt", VisionConstants.MAX_TILT_FOR_VISION.in(Degrees)); -public class Dashboard extends SubsystemBase { - private final Intake _intake; - private final Shooter _shooter; - + initPreference(prefix + "Climber L1 Rotation", ClimberConstants.L1_ROTATION.in(Degrees)); + initPreference(prefix + "Climber L3 Rotation", ClimberConstants.L3_ROTATION.in(Degrees)); + initPreference(prefix + "Climber Extension Threshold", ClimberConstants.EXTENSION_THRESHOLD.in(Inches)); + initPreference(prefix + "Climber Retraction Threshold", ClimberConstants.RETRACTION_THRESHOLD.in(Inches)); + initPreference(prefix + "Climber Extend Voltage", ClimberConstants.EXTEND_OUTPUT.in(Volts)); + initPreference(prefix + "Climber Retract Voltage", ClimberConstants.RETRACT_VOLTAGE.in(Volts)); + initPreference(prefix + "Climber Rotate Voltage", ClimberConstants.ROTATE_OUTPUT.in(Volts)); + initPreference(prefix + "Climber Tolerance", ClimberConstants.ROTATION_TOLERANCE.in(Degrees)); + } } diff --git a/src/main/java/frc/robot/subsystems/shooter/Hood.java b/src/main/java/frc/robot/subsystems/shooter/Hood.java index d3b0743..b8c0e98 100644 --- a/src/main/java/frc/robot/subsystems/shooter/Hood.java +++ b/src/main/java/frc/robot/subsystems/shooter/Hood.java @@ -4,8 +4,6 @@ import static edu.wpi.first.units.Units.RadiansPerSecond; import static edu.wpi.first.units.Units.Volts; -import java.util.Map; - import com.ctre.phoenix.motorcontrol.can.WPI_VictorSPX; import edu.wpi.first.math.controller.PIDController; @@ -33,7 +31,14 @@ public class Hood { public enum HoodPosition { - Shoot, Pass, Undefined + Shoot(ShooterConstants.HOOD_SHOOT_ANGLE), Pass(ShooterConstants.HOOD_PASS_ANGLE), Undefined(null); + + public final Angle targetAngle; + + private HoodPosition(Angle targetAngle) + { + this.targetAngle = targetAngle; + } } private final WPI_VictorSPX _hoodMotor; @@ -79,11 +84,11 @@ public Hood() var table = NetworkTableInstance.getDefault().getTable("Shooter").getSubTable("Hood"); - _minAngleEntry = table.getDoubleTopic("Min Angle").getEntry(ShooterConstants.HOOD_MIN_ANGLE.in(Degrees)); - _maxAngleEntry = table.getDoubleTopic("Max Angle").getEntry(ShooterConstants.HOOD_MAX_ANGLE.in(Degrees)); + _minAngleEntry = table.getDoubleTopic("Min Angle").getEntry(ShooterConstants.HOOD_MIN_ANGLE.in(Degrees)); + _maxAngleEntry = table.getDoubleTopic("Max Angle").getEntry(ShooterConstants.HOOD_MAX_ANGLE.in(Degrees)); _shootAngleEntry = table.getDoubleTopic("Shoot Angle").getEntry(ShooterConstants.HOOD_SHOOT_ANGLE.in(Degrees)); - _passAngleEntry = table.getDoubleTopic("Pass Angle").getEntry(ShooterConstants.HOOD_PASS_ANGLE.in(Degrees)); - _toleranceEntry = table.getDoubleTopic("Tolerance").getEntry(ShooterConstants.HOOD_TOLERANCE.in(Degrees)); + _passAngleEntry = table.getDoubleTopic("Pass Angle").getEntry(ShooterConstants.HOOD_PASS_ANGLE.in(Degrees)); + _toleranceEntry = table.getDoubleTopic("Tolerance").getEntry(ShooterConstants.HOOD_TOLERANCE.in(Degrees)); // Real vs. Simulation if (RobotBase.isReal()) diff --git a/src/main/java/frc/robot/subsystems/shooter/Shooter.java b/src/main/java/frc/robot/subsystems/shooter/Shooter.java index f32c092..cd7cd9e 100644 --- a/src/main/java/frc/robot/subsystems/shooter/Shooter.java +++ b/src/main/java/frc/robot/subsystems/shooter/Shooter.java @@ -153,4 +153,14 @@ public void pass() _flywheel.setVelocity(ShooterConstants.PASS_FLYWHEEL_VELOCITY); _state = ShooterState.Priming; } + + public ShooterState getShooterState() + { + return _state; + } + + public HoodPosition getShooterMode() + { + return _hood.getHoodPosition(); + } } diff --git a/src/main/java/frc/robot/subsystems/shooter/Turret.java b/src/main/java/frc/robot/subsystems/shooter/Turret.java index 3af1c93..7da181f 100644 --- a/src/main/java/frc/robot/subsystems/shooter/Turret.java +++ b/src/main/java/frc/robot/subsystems/shooter/Turret.java @@ -23,6 +23,7 @@ import com.ctre.phoenix6.swerve.SwerveDrivetrain.SwerveDriveState; import edu.wpi.first.epilogue.Logged; +import edu.wpi.first.math.controller.PIDController; import edu.wpi.first.math.system.plant.DCMotor; import edu.wpi.first.math.system.plant.LinearSystemId; import edu.wpi.first.units.measure.Angle; @@ -31,9 +32,12 @@ import edu.wpi.first.wpilibj.AnalogInput; import edu.wpi.first.wpilibj.AnalogPotentiometer; import edu.wpi.first.wpilibj.RobotBase; +import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; import edu.wpi.first.wpilibj.simulation.AnalogInputSim; import edu.wpi.first.wpilibj.simulation.DCMotorSim; import edu.wpi.first.wpilibj.simulation.RoboRioSim; +import edu.wpi.first.wpilibj2.command.Command; +import edu.wpi.first.wpilibj2.command.Commands; import edu.wpi.first.wpilibj2.command.SubsystemBase; import frc.robot.Constants.AIOConstants; import frc.robot.Constants.CANConstants; @@ -60,6 +64,11 @@ public enum TurretState private Supplier _swerveStateSupplier; private SwerveDriveState _swerveDriveState; private PositionVoltage _positionRequest = new PositionVoltage(0).withSlot(0); + private PIDController _pidProxy; + private double _lastProxyP; + private double _lastProxyI; + private double _lastProxyD; + private boolean _testModeActive; private List _cachedTagFilter; @Logged private Angle _fieldTurretAngle; @@ -113,6 +122,27 @@ public Turret(Supplier swerveStateSupplier) _swerveDriveState = new SwerveDriveState(); _cachedTagFilter = List.of(); + _pidProxy = new PIDController(ShooterConstants.TURRET_KP, ShooterConstants.TURRET_KI, ShooterConstants.TURRET_KD); + _lastProxyP = ShooterConstants.TURRET_KP; + _lastProxyI = ShooterConstants.TURRET_KI; + _lastProxyD = ShooterConstants.TURRET_KD; + SmartDashboard.putData("Turret PID", _pidProxy); + + _testModeActive = false; + Command testModeCommand = Commands.startRun(() -> _testModeActive = true, () -> + { + Angle setpoint = Degrees.of(_pidProxy.getSetpoint()); + _turretSetpoint = MeasureUtil.clamp(setpoint, ShooterConstants.TURRET_MIN_ANGLE, ShooterConstants.TURRET_MAX_ANGLE); + _hasSetpoint = true; + _turretMotor.setControl(_positionRequest.withPosition(_turretSetpoint.times(ShooterConstants.TURRET_GEAR_RATIO).in(Rotations))); + }, this).finallyDo(() -> + { + _testModeActive = false; + _hasSetpoint = false; + _turretMotor.setVoltage(0.0); + }); + SmartDashboard.putData("Turret Test Mode", testModeCommand); + if (RobotBase.isReal()) { _turretMotorSim = null; @@ -131,6 +161,21 @@ public Turret(Supplier swerveStateSupplier) @Override public void periodic() { + double newP = _pidProxy.getP(); + double newI = _pidProxy.getI(); + double newD = _pidProxy.getD(); + if (newP != _lastProxyP || newI != _lastProxyI || newD != _lastProxyD) + { + var slot0 = new Slot0Configs(); + slot0.kP = newP; + slot0.kI = newI; + slot0.kD = newD; + _turretMotor.getConfigurator().apply(slot0); + _lastProxyP = newP; + _lastProxyI = newI; + _lastProxyD = newD; + } + _robotTurretAngle = Degrees.of(_turretSensor.get()); SwerveDriveState state = _swerveStateSupplier.get(); @@ -155,6 +200,8 @@ public void periodic() _targetHorizontalOffset = Degrees.of(targetData.getHorizontalOffset()); } + if (_testModeActive) return; + Angle requestedSetpoint = switch (_turretState) { case Idle -> null; @@ -164,11 +211,12 @@ public void periodic() if (requestedSetpoint == null) { - _turretSetpoint = null; + _hasSetpoint = false; _turretMotor.setVoltage(0.0); return; } + _hasSetpoint = true; _turretSetpoint = MeasureUtil.clamp(requestedSetpoint, ShooterConstants.TURRET_MIN_ANGLE, ShooterConstants.TURRET_MAX_ANGLE); var target = _turretSetpoint.times(ShooterConstants.TURRET_GEAR_RATIO); _turretMotor.setControl(_positionRequest.withPosition(target.in(Rotations))); @@ -212,7 +260,7 @@ public boolean hasTarget() public boolean isLinedUp() { - if (_turretSetpoint == null) return _turretState == TurretState.Idle; + if (!_hasSetpoint) return _turretState == TurretState.Idle; if (_turretState == TurretState.Track && !_hasTarget) return false; return _robotTurretAngle.isNear(_turretSetpoint, ShooterConstants.TURRET_TOLERANCE); diff --git a/src/main/java/frc/robot/util/Utilities.java b/src/main/java/frc/robot/util/Utilities.java index 5fe8a74..4bd381d 100644 --- a/src/main/java/frc/robot/util/Utilities.java +++ b/src/main/java/frc/robot/util/Utilities.java @@ -65,6 +65,35 @@ public static boolean isHubActive() } + public static Time getHubStateTimeRemaining() + { + var timeRemaining = Seconds.of(DriverStation.getMatchTime()); + if (timeRemaining.lt(Seconds.zero())) + { + return Seconds.zero(); + } + + if (DriverStation.isAutonomous()) + { + return timeRemaining; + } + + if (!DriverStation.isTeleop()) + { + return Seconds.zero(); + } + + return switch (getAllianceShift(timeRemaining)) + { + case 0 -> timeRemaining.minus(kTransitionShiftEndTimeSecs); + case 1 -> timeRemaining.minus(kShift1EndTimeSecs); + case 2 -> timeRemaining.minus(kShift2EndTimeSecs); + case 3 -> timeRemaining.minus(kShift3EndTimeSecs); + case 4 -> timeRemaining.minus(kShift4EndTimeSecs); + default -> timeRemaining; + }; + } + /** * Check if we are on the Blue alliance. */ From d83de27be9fe948ae6eca92c99e7c41485ef5a54 Mon Sep 17 00:00:00 2001 From: Collin McIntyre Date: Tue, 24 Feb 2026 17:42:25 -0600 Subject: [PATCH 5/9] made changes to dashboard layout --- networktables.json.bck | 1 + src/main/deploy/elastic-layout.json | 56 ++++++++++++++--------------- 2 files changed, 29 insertions(+), 28 deletions(-) create mode 100644 networktables.json.bck diff --git a/networktables.json.bck b/networktables.json.bck new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/networktables.json.bck @@ -0,0 +1 @@ +[] diff --git a/src/main/deploy/elastic-layout.json b/src/main/deploy/elastic-layout.json index c811f1d..4c67d25 100644 --- a/src/main/deploy/elastic-layout.json +++ b/src/main/deploy/elastic-layout.json @@ -8,7 +8,7 @@ "layouts": [ { "title": "List Layout", - "x": 1344.0, + "x": 1568.0, "y": 0.0, "width": 352.0, "height": 448.0, @@ -88,7 +88,7 @@ "containers": [ { "title": "Alerts", - "x": 1344.0, + "x": 1568.0, "y": 448.0, "width": 352.0, "height": 320.0, @@ -102,13 +102,13 @@ "title": "Autonomous Mode", "x": 0.0, "y": 0.0, - "width": 1344.0, + "width": 1568.0, "height": 768.0, "type": "Field", "properties": { "topic": "/SmartDashboard/Autonomous Mode", "period": 0.06, - "field_game": "Rebuilt", + "field_game": "Reefscape", "robot_width": 0.85, "robot_length": 0.85, "show_other_objects": true, @@ -129,10 +129,10 @@ "containers": [ { "title": "Alerts", - "x": 1728.0, + "x": 1664.0, "y": 0.0, - "width": 192.0, - "height": 736.0, + "width": 256.0, + "height": 768.0, "type": "Alerts", "properties": { "topic": "/SmartDashboard/Alerts", @@ -143,8 +143,8 @@ "title": "Match Time", "x": 0.0, "y": 0.0, - "width": 1120.0, - "height": 640.0, + "width": 1152.0, + "height": 768.0, "type": "Match Time", "properties": { "topic": "Dashboard/Robot Values/Match Time", @@ -157,10 +157,10 @@ }, { "title": "Hub Active", - "x": 1120.0, + "x": 1152.0, "y": 0.0, - "width": 576.0, - "height": 160.0, + "width": 512.0, + "height": 192.0, "type": "Boolean Box", "properties": { "topic": "Dashboard/Robot Values/Hub Active", @@ -174,10 +174,10 @@ }, { "title": "Turret Has Target", - "x": 1120.0, - "y": 480.0, - "width": 288.0, - "height": 160.0, + "x": 1152.0, + "y": 576.0, + "width": 256.0, + "height": 192.0, "type": "Boolean Box", "properties": { "topic": "Dashboard/Robot Values/Turret Has Target", @@ -191,10 +191,10 @@ }, { "title": "Hub State Timer", - "x": 1120.0, - "y": 160.0, - "width": 576.0, - "height": 160.0, + "x": 1152.0, + "y": 192.0, + "width": 512.0, + "height": 192.0, "type": "Text Display", "properties": { "topic": "Dashboard/Robot Values/Hub State Time Remaining", @@ -205,10 +205,10 @@ }, { "title": "Shooter Mode", - "x": 1120.0, - "y": 320.0, - "width": 576.0, - "height": 160.0, + "x": 1152.0, + "y": 384.0, + "width": 512.0, + "height": 192.0, "type": "Boolean Box", "properties": { "topic": "Dashboard/Robot Values/Shooter Is Shoot Mode", @@ -223,9 +223,9 @@ { "title": "Turret Lined Up", "x": 1408.0, - "y": 480.0, - "width": 288.0, - "height": 160.0, + "y": 576.0, + "width": 256.0, + "height": 192.0, "type": "Boolean Box", "properties": { "topic": "Dashboard/Robot Values/Turret Lined Up", @@ -833,4 +833,4 @@ } } ] -} +} \ No newline at end of file From b888a8e9a93a7bcd8467d820ab493bb2d1a5e3c2 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 23:44:01 +0000 Subject: [PATCH 6/9] Formatted code using spotless. --- src/main/deploy/elastic-layout.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/deploy/elastic-layout.json b/src/main/deploy/elastic-layout.json index 4c67d25..1447710 100644 --- a/src/main/deploy/elastic-layout.json +++ b/src/main/deploy/elastic-layout.json @@ -833,4 +833,4 @@ } } ] -} \ No newline at end of file +} From 6d9b54b78b6f25e7226434d3d0c31cf49e94cdcd Mon Sep 17 00:00:00 2001 From: Collin McIntyre Date: Tue, 24 Feb 2026 17:44:45 -0600 Subject: [PATCH 7/9] Delete networktables.json.bck --- networktables.json.bck | 1 - 1 file changed, 1 deletion(-) delete mode 100644 networktables.json.bck diff --git a/networktables.json.bck b/networktables.json.bck deleted file mode 100644 index fe51488..0000000 --- a/networktables.json.bck +++ /dev/null @@ -1 +0,0 @@ -[] From 1dd76e957443bc20e0f37a93a619d6c838ffeb29 Mon Sep 17 00:00:00 2001 From: Collin McIntyre Date: Tue, 24 Feb 2026 17:45:06 -0600 Subject: [PATCH 8/9] Delete Dashboard.txt --- Dashboard.txt | 73 --------------------------------------------------- 1 file changed, 73 deletions(-) delete mode 100644 Dashboard.txt diff --git a/Dashboard.txt b/Dashboard.txt deleted file mode 100644 index f08bcc4..0000000 --- a/Dashboard.txt +++ /dev/null @@ -1,73 +0,0 @@ -Autonomous Tab - Field - Display robot starting location - Display selected autonomous path - Auto Delay Chooser - 0, 1, 2, 3, 4, 5 - Start Position Chooser - Left Trench, Left Bump, Hub, Right Bump, Right Trench - Near Fuel Sources - None, Depot → Outpost, Outpost → Depot, Depot, Outpost - Neutral Zone - Yes, No - Climb - Yes, No - Alerts - Valid combination chosen - -Teleop Tab - Match Time - Period Time - Camera Stream (maybe) - Hub in Turret range - Alerts - -Programmer Tab - PID Controllers - Hood - Turret - Auto driving - X - Y - Z - - Settings - Intake - Forward Voltage - Reverse Voltage - Extension Max Position - Extend Voltage - Retract Voltage - Shooter - Flywheel - Flywheel Tolerance - Pass Velocity - Hood - Min Angle - Max Angle - Shoot Angle - Pass Angle - Tolerance - Turret - Min Angle - Max Angle - Home Angle (leave at 0?) - Tolerance - Pass Angle (if using a constant angle. If targetting, not needed) - Feeder - Feed Voltage - Vision - Max angular rate - Maximum tilt - Climber - L1 Rotation - L3 Rotation - Extension Max Position - Extend Voltage - Retract Voltage - Rotate Voltage - Tolerance - - Commands (set up to only run in test mode) - Run Hood PID - Run Turret PID From 94084d457f8a76ba33000997c32d94490b5cc9d2 Mon Sep 17 00:00:00 2001 From: SAKETH11111 Date: Thu, 26 Feb 2026 15:19:51 -0600 Subject: [PATCH 9/9] Refactor dashboard layout and add Flywheel and Turret PID settings to preferences --- src/main/deploy/elastic-layout.json | 150 +++++++++++++++--- .../robot/subsystems/dashboard/Dashboard.java | 11 ++ .../robot/subsystems/shooter/Flywheel.java | 30 ++++ .../frc/robot/subsystems/shooter/Turret.java | 33 ++-- 4 files changed, 188 insertions(+), 36 deletions(-) diff --git a/src/main/deploy/elastic-layout.json b/src/main/deploy/elastic-layout.json index 1447710..c2d387c 100644 --- a/src/main/deploy/elastic-layout.json +++ b/src/main/deploy/elastic-layout.json @@ -245,11 +245,11 @@ "grid_layout": { "layouts": [ { - "title": "Hood & Turret", + "title": "Hood PID", "x": 0.0, "y": 0.0, "width": 256.0, - "height": 736.0, + "height": 256.0, "type": "List Layout", "properties": { "label_position": "TOP" @@ -266,18 +266,6 @@ "topic": "/SmartDashboard/Hood PID", "period": 0.05 } - }, - { - "title": "Turret PID", - "x": 0.0, - "y": 0.0, - "width": 121.0, - "height": 128.0, - "type": "PIDController", - "properties": { - "topic": "/SmartDashboard/Turret PID", - "period": 0.05 - } } ] }, @@ -501,12 +489,68 @@ "x": 1024.0, "y": 0.0, "width": 256.0, - "height": 256.0, + "height": 640.0, "type": "List Layout", "properties": { "label_position": "RIGHT" }, "children": [ + { + "title": "kP", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Turret kP", + "period": 0.02, + "data_type": "double", + "show_submit_button": true + } + }, + { + "title": "kI", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Turret kI", + "period": 0.02, + "data_type": "double", + "show_submit_button": true + } + }, + { + "title": "kD", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Turret kD", + "period": 0.02, + "data_type": "double", + "show_submit_button": true + } + }, + { + "title": "Test Setpoint (deg)", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Turret Test Setpoint", + "period": 0.02, + "data_type": "double", + "show_submit_button": true + } + }, { "title": "Min Angle", "x": 0.0, @@ -584,12 +628,82 @@ "x": 1280.0, "y": 0.0, "width": 256.0, - "height": 256.0, + "height": 512.0, "type": "List Layout", "properties": { "label_position": "RIGHT" }, "children": [ + { + "title": "kP", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Flywheel kP", + "period": 0.02, + "data_type": "double", + "show_submit_button": true + } + }, + { + "title": "kD", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Flywheel kD", + "period": 0.02, + "data_type": "double", + "show_submit_button": true + } + }, + { + "title": "kS (V)", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Flywheel kS", + "period": 0.02, + "data_type": "double", + "show_submit_button": true + } + }, + { + "title": "kV (V/RPM)", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Flywheel kV", + "period": 0.02, + "data_type": "double", + "show_submit_button": true + } + }, + { + "title": "kA (V/rps²)", + "x": 0.0, + "y": 0.0, + "width": 121.0, + "height": 64.0, + "type": "Text Display", + "properties": { + "topic": "/Preferences/Dashboard/Dashboard Settings/Flywheel kA", + "period": 0.02, + "data_type": "double", + "show_submit_button": true + } + }, { "title": "Tolerance", "x": 0.0, @@ -623,9 +737,9 @@ { "title": "Feeder", "x": 1280.0, - "y": 256.0, + "y": 512.0, "width": 256.0, - "height": 256.0, + "height": 224.0, "type": "List Layout", "properties": { "label_position": "RIGHT" diff --git a/src/main/java/frc/robot/subsystems/dashboard/Dashboard.java b/src/main/java/frc/robot/subsystems/dashboard/Dashboard.java index de6c4d2..373e1ea 100644 --- a/src/main/java/frc/robot/subsystems/dashboard/Dashboard.java +++ b/src/main/java/frc/robot/subsystems/dashboard/Dashboard.java @@ -4,6 +4,8 @@ import static edu.wpi.first.units.Units.DegreesPerSecond; import static edu.wpi.first.units.Units.Inches; import static edu.wpi.first.units.Units.RPM; +import static edu.wpi.first.units.Units.RPM; +import static edu.wpi.first.units.Units.RotationsPerSecondPerSecond; import static edu.wpi.first.units.Units.Seconds; import static edu.wpi.first.units.Units.Value; import static edu.wpi.first.units.Units.Volts; @@ -99,6 +101,11 @@ private void initializeTuningPreferences() initPreference(prefix + "Intake Extend Voltage", IntakeConstants.EXTEND_VOLTS.in(Volts)); initPreference(prefix + "Intake Retract Voltage", IntakeConstants.RETRACT_VOLTS.in(Volts)); + initPreference(prefix + "Flywheel kP", ShooterConstants.FLYWHEEL_KP); + initPreference(prefix + "Flywheel kD", ShooterConstants.FLYWHEEL_KD); + initPreference(prefix + "Flywheel kS", ShooterConstants.FLYWHEEL_KS.in(Volts)); + initPreference(prefix + "Flywheel kV", ShooterConstants.FLYWHEEL_KV.in(Volts.per(RPM))); + initPreference(prefix + "Flywheel kA", ShooterConstants.FLYWHEEL_KA.in(Volts.per(RotationsPerSecondPerSecond))); initPreference(prefix + "Flywheel Tolerance", ShooterConstants.FLYWHEEL_TOLERANCE.in(Value)); initPreference(prefix + "Flywheel Pass Velocity", ShooterConstants.PASS_FLYWHEEL_VELOCITY.in(RPM)); @@ -108,6 +115,10 @@ private void initializeTuningPreferences() initPreference(prefix + "Hood Pass Angle", ShooterConstants.HOOD_PASS_ANGLE.in(Degrees)); initPreference(prefix + "Hood Tolerance", ShooterConstants.HOOD_TOLERANCE.in(Degrees)); + initPreference(prefix + "Turret kP", ShooterConstants.TURRET_KP); + initPreference(prefix + "Turret kI", ShooterConstants.TURRET_KI); + initPreference(prefix + "Turret kD", ShooterConstants.TURRET_KD); + initPreference(prefix + "Turret Test Setpoint", 0.0); initPreference(prefix + "Turret Min Angle", ShooterConstants.TURRET_MIN_ANGLE.in(Degrees)); initPreference(prefix + "Turret Max Angle", ShooterConstants.TURRET_MAX_ANGLE.in(Degrees)); initPreference(prefix + "Turret Home Angle", ShooterConstants.TURRET_HOME_ANGLE.in(Degrees)); diff --git a/src/main/java/frc/robot/subsystems/shooter/Flywheel.java b/src/main/java/frc/robot/subsystems/shooter/Flywheel.java index 5f6dccc..e3dcb9c 100644 --- a/src/main/java/frc/robot/subsystems/shooter/Flywheel.java +++ b/src/main/java/frc/robot/subsystems/shooter/Flywheel.java @@ -24,6 +24,7 @@ import edu.wpi.first.math.system.plant.LinearSystemId; import edu.wpi.first.units.measure.AngularVelocity; import edu.wpi.first.units.measure.Voltage; +import edu.wpi.first.wpilibj.Preferences; import edu.wpi.first.wpilibj.RobotBase; import edu.wpi.first.wpilibj.simulation.FlywheelSim; import edu.wpi.first.wpilibj.simulation.RoboRioSim; @@ -47,6 +48,11 @@ public class Flywheel private AngularVelocity _targetVelocity = RPM.zero(); @Logged private Voltage _flywheelVoltage = Volts.zero(); + private double _lastKP; + private double _lastKD; + private double _lastKS; + private double _lastKV; + private double _lastKA; public Flywheel() { @@ -71,6 +77,12 @@ public Flywheel() _closedLoopController = _leadMotor.getClosedLoopController(); _flywheelEncoder = _leadMotor.getEncoder(); + _lastKP = ShooterConstants.FLYWHEEL_KP; + _lastKD = ShooterConstants.FLYWHEEL_KD; + _lastKS = ShooterConstants.FLYWHEEL_KS.in(Volts); + _lastKV = ShooterConstants.FLYWHEEL_KV.in(Volts.per(RPM)); + _lastKA = ShooterConstants.FLYWHEEL_KA.in(Volts.per(RotationsPerSecondPerSecond)); + if (RobotBase.isReal()) { _leadMotor.setCANTimeout(0); @@ -90,6 +102,24 @@ public void periodic() { _velocity = RPM.of(_flywheelEncoder.getVelocity()); _flywheelVoltage = Volts.of(_leadMotor.getAppliedOutput() * _leadMotor.getBusVoltage()); + + double newP = Preferences.getDouble("Dashboard/Dashboard Settings/Flywheel kP", ShooterConstants.FLYWHEEL_KP); + double newD = Preferences.getDouble("Dashboard/Dashboard Settings/Flywheel kD", ShooterConstants.FLYWHEEL_KD); + double newS = Preferences.getDouble("Dashboard/Dashboard Settings/Flywheel kS", ShooterConstants.FLYWHEEL_KS.in(Volts)); + double newV = Preferences.getDouble("Dashboard/Dashboard Settings/Flywheel kV", ShooterConstants.FLYWHEEL_KV.in(Volts.per(RPM))); + double newA = Preferences.getDouble("Dashboard/Dashboard Settings/Flywheel kA", ShooterConstants.FLYWHEEL_KA.in(Volts.per(RotationsPerSecondPerSecond))); + if (newP != _lastKP || newD != _lastKD || newS != _lastKS || newV != _lastKV || newA != _lastKA) + { + var config = new SparkFlexConfig(); + config.closedLoop.p(newP).d(newD); + config.closedLoop.feedForward.kS(newS).kV(newV).kA(newA); + _leadMotor.configure(config, ResetMode.kNoResetSafeParameters, PersistMode.kNoPersistParameters); + _lastKP = newP; + _lastKD = newD; + _lastKS = newS; + _lastKV = newV; + _lastKA = newA; + } } public void simulationPeriodic() diff --git a/src/main/java/frc/robot/subsystems/shooter/Turret.java b/src/main/java/frc/robot/subsystems/shooter/Turret.java index 7da181f..7f472eb 100644 --- a/src/main/java/frc/robot/subsystems/shooter/Turret.java +++ b/src/main/java/frc/robot/subsystems/shooter/Turret.java @@ -23,7 +23,6 @@ import com.ctre.phoenix6.swerve.SwerveDrivetrain.SwerveDriveState; import edu.wpi.first.epilogue.Logged; -import edu.wpi.first.math.controller.PIDController; import edu.wpi.first.math.system.plant.DCMotor; import edu.wpi.first.math.system.plant.LinearSystemId; import edu.wpi.first.units.measure.Angle; @@ -31,6 +30,7 @@ import edu.wpi.first.units.measure.Voltage; import edu.wpi.first.wpilibj.AnalogInput; import edu.wpi.first.wpilibj.AnalogPotentiometer; +import edu.wpi.first.wpilibj.Preferences; import edu.wpi.first.wpilibj.RobotBase; import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; import edu.wpi.first.wpilibj.simulation.AnalogInputSim; @@ -64,10 +64,9 @@ public enum TurretState private Supplier _swerveStateSupplier; private SwerveDriveState _swerveDriveState; private PositionVoltage _positionRequest = new PositionVoltage(0).withSlot(0); - private PIDController _pidProxy; - private double _lastProxyP; - private double _lastProxyI; - private double _lastProxyD; + private double _lastKP; + private double _lastKI; + private double _lastKD; private boolean _testModeActive; private List _cachedTagFilter; @Logged @@ -122,16 +121,14 @@ public Turret(Supplier swerveStateSupplier) _swerveDriveState = new SwerveDriveState(); _cachedTagFilter = List.of(); - _pidProxy = new PIDController(ShooterConstants.TURRET_KP, ShooterConstants.TURRET_KI, ShooterConstants.TURRET_KD); - _lastProxyP = ShooterConstants.TURRET_KP; - _lastProxyI = ShooterConstants.TURRET_KI; - _lastProxyD = ShooterConstants.TURRET_KD; - SmartDashboard.putData("Turret PID", _pidProxy); + _lastKP = ShooterConstants.TURRET_KP; + _lastKI = ShooterConstants.TURRET_KI; + _lastKD = ShooterConstants.TURRET_KD; _testModeActive = false; Command testModeCommand = Commands.startRun(() -> _testModeActive = true, () -> { - Angle setpoint = Degrees.of(_pidProxy.getSetpoint()); + Angle setpoint = Degrees.of(Preferences.getDouble("Dashboard/Dashboard Settings/Turret Test Setpoint", 0.0)); _turretSetpoint = MeasureUtil.clamp(setpoint, ShooterConstants.TURRET_MIN_ANGLE, ShooterConstants.TURRET_MAX_ANGLE); _hasSetpoint = true; _turretMotor.setControl(_positionRequest.withPosition(_turretSetpoint.times(ShooterConstants.TURRET_GEAR_RATIO).in(Rotations))); @@ -161,19 +158,19 @@ public Turret(Supplier swerveStateSupplier) @Override public void periodic() { - double newP = _pidProxy.getP(); - double newI = _pidProxy.getI(); - double newD = _pidProxy.getD(); - if (newP != _lastProxyP || newI != _lastProxyI || newD != _lastProxyD) + double newP = Preferences.getDouble("Dashboard/Dashboard Settings/Turret kP", ShooterConstants.TURRET_KP); + double newI = Preferences.getDouble("Dashboard/Dashboard Settings/Turret kI", ShooterConstants.TURRET_KI); + double newD = Preferences.getDouble("Dashboard/Dashboard Settings/Turret kD", ShooterConstants.TURRET_KD); + if (newP != _lastKP || newI != _lastKI || newD != _lastKD) { var slot0 = new Slot0Configs(); slot0.kP = newP; slot0.kI = newI; slot0.kD = newD; _turretMotor.getConfigurator().apply(slot0); - _lastProxyP = newP; - _lastProxyI = newI; - _lastProxyD = newD; + _lastKP = newP; + _lastKI = newI; + _lastKD = newD; } _robotTurretAngle = Degrees.of(_turretSensor.get());