From 6421de4a9f2133f7d9142430e85b6d8ec6d778a3 Mon Sep 17 00:00:00 2001 From: RobotLeopard86 <63123751+RobotLeopard86@users.noreply.github.com> Date: Mon, 24 Feb 2025 17:19:26 -0800 Subject: [PATCH 01/21] Add initial AddressableLED subsystem implementation --- .../commands/SetAddressableLEDPattern.java | 40 ++++++++++++++++ .../AddressableLEDConstants.java | 10 ++++ .../AddressableLEDSubsystem.java | 46 +++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 src/main/java/frc/robot/commands/SetAddressableLEDPattern.java create mode 100644 src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java create mode 100644 src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java diff --git a/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java b/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java new file mode 100644 index 00000000..7aed2755 --- /dev/null +++ b/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java @@ -0,0 +1,40 @@ +package frc.robot.commands; + +import edu.wpi.first.wpilibj.LEDPattern; +import edu.wpi.first.wpilibj2.command.Command; + +public class SetAddressableLEDPattern extends Command { + private final AddressableLEDSubsystem ledSystem; + private final int + section; // If this is -1, that means that this command is targeting the whole strip + private final LEDPattern pattern; + + /** + * @param + */ + public SetAddressableLEDPattern(AddressableLEDSubsystem led, LEDPattern pattern, int section) { + this.section = section; + this.pattern = pattern; + ledSystem = led; + } + + public SetAddressableLEDPattern(AddressableLEDSubsystem led, LEDPattern pattern) { + this(led, pattern, -1); + } + + public void initialize() {} + + public void execute() { + if (section < 0) { + ledSystem.applyPattern(pattern); + } else { + ledSystem.applySectionedPattern(pattern, section); + } + } + + public boolean isFinished() { + return true; + } + + public void end(boolean interrupted) {} +} diff --git a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java new file mode 100644 index 00000000..56fd811c --- /dev/null +++ b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java @@ -0,0 +1,10 @@ +package frc.robot.subsystems.addressableled; + +public class AddressableLEDConstants { + private record Range(int low, int high) {} + + // TODO: Implement real values + public static final int LED_COUNT = 64; + public static final int LED_STRIP_PORT = 0; + public static final Range SECTIONS[] = {new Range(0, LED_COUNT)}; +} diff --git a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java new file mode 100644 index 00000000..fbf04745 --- /dev/null +++ b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java @@ -0,0 +1,46 @@ +package frc.robot.subsystems.addressableled; + +import edu.wpi.first.wpilibj.AddressableLED; +import edu.wpi.first.wpilibj.AddressableLEDBuffer; +import edu.wpi.first.wpilibj.AddressableLEDBufferView; +import edu.wpi.first.wpilibj.LEDPattern; +import edu.wpi.first.wpilibj2.command.SubsystemBase; + +public class AddressableLEDSubsystem extends SubsystemBase { + private final AddressableLED led; + private final AddressableLEDBuffer ledBuffer; + private AddressableLEDBufferView ledViews[]; + + public AddressableLEDSubsystem() { + // Create strip and buffer + led = new AddressableLED(AddressableLEDConstants.LED_STRIP_PORT); + ledBuffer = new AddressableLEDBuffer(AddressableLEDConstants.LED_COUNT); + led.setLength(AddressableLEDConstants.LED_COUNT); + + // Create section views + ledViews = new AddressableLEDBufferView[AddressableLEDConstants.SECTIONS.length]; + for (int i = 0; i < ledViews.length; i++) { + ledViews[i] = + new AddressableLEDBufferView( + ledBuffer, + AddressableLEDConstants.SECTIONS[i].low, + AddressableLEDConstants.SECTIONS[i].high); + } + } + + // Periodically update the LED strip + public void periodic() { + led.setData(ledBuffer); + } + + // Apply a color pattern to a section of the LED strip + public void applySectionedPattern(LEDPattern pattern, int section) { + if (section < 0 || section >= ledViews.length) return; + pattern.applyTo(ledViews[section]); + } + + // Apply a color pattern to a section of the LED strip + public void applyPattern(LEDPattern pattern) { + pattern.applyTo(ledBuffer); + } +} From fa8e40a3c37486d5a99a3549220e2131455b3a80 Mon Sep 17 00:00:00 2001 From: RobotLeopard86 <63123751+RobotLeopard86@users.noreply.github.com> Date: Mon, 24 Feb 2025 17:24:02 -0800 Subject: [PATCH 02/21] Fix missing imports and improper record access --- .../java/frc/robot/commands/SetAddressableLEDPattern.java | 1 + .../subsystems/addressableled/AddressableLEDConstants.java | 2 +- .../subsystems/addressableled/AddressableLEDSubsystem.java | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java b/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java index 7aed2755..cb6bb6c2 100644 --- a/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java +++ b/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java @@ -2,6 +2,7 @@ import edu.wpi.first.wpilibj.LEDPattern; import edu.wpi.first.wpilibj2.command.Command; +import frc.robot.subsystems.addressableled.AddressableLEDSubsystem; public class SetAddressableLEDPattern extends Command { private final AddressableLEDSubsystem ledSystem; diff --git a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java index 56fd811c..40639882 100644 --- a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java +++ b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java @@ -1,7 +1,7 @@ package frc.robot.subsystems.addressableled; public class AddressableLEDConstants { - private record Range(int low, int high) {} + public record Range(int low, int high) {} // TODO: Implement real values public static final int LED_COUNT = 64; diff --git a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java index fbf04745..5ef39728 100644 --- a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java +++ b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java @@ -23,8 +23,8 @@ public AddressableLEDSubsystem() { ledViews[i] = new AddressableLEDBufferView( ledBuffer, - AddressableLEDConstants.SECTIONS[i].low, - AddressableLEDConstants.SECTIONS[i].high); + AddressableLEDConstants.SECTIONS[i].low(), + AddressableLEDConstants.SECTIONS[i].high()); } } From 8b27e762a933baec671570c19d614fc412264805 Mon Sep 17 00:00:00 2001 From: RobotLeopard86 <63123751+RobotLeopard86@users.noreply.github.com> Date: Mon, 24 Feb 2025 17:50:51 -0800 Subject: [PATCH 03/21] Add missing @Override declarations and add Javadoc --- .../commands/SetAddressableLEDPattern.java | 25 +++++++++++++------ .../AddressableLEDSubsystem.java | 1 + 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java b/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java index cb6bb6c2..d8b9265d 100644 --- a/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java +++ b/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java @@ -6,12 +6,17 @@ public class SetAddressableLEDPattern extends Command { private final AddressableLEDSubsystem ledSystem; - private final int - section; // If this is -1, that means that this command is targeting the whole strip + + // If this is -1, that means that this command is targeting the whole strip + private final int section; + private final LEDPattern pattern; /** - * @param + * @param led Addressable LED subsystem to use + * @param pattern Pattern to apply when command run + * @param section Section of LED strip to apply pattern to (index into + * AddressableLEDConstants.SECTIONS) */ public SetAddressableLEDPattern(AddressableLEDSubsystem led, LEDPattern pattern, int section) { this.section = section; @@ -19,12 +24,17 @@ public SetAddressableLEDPattern(AddressableLEDSubsystem led, LEDPattern pattern, ledSystem = led; } + /** + * @param led Addressable LED subsystem to use + * @param pattern Pattern to apply when command run + */ public SetAddressableLEDPattern(AddressableLEDSubsystem led, LEDPattern pattern) { - this(led, pattern, -1); + this.section = -1; + this.pattern = pattern; + ledSystem = led; } - public void initialize() {} - + @Override public void execute() { if (section < 0) { ledSystem.applyPattern(pattern); @@ -33,9 +43,8 @@ public void execute() { } } + @Override public boolean isFinished() { return true; } - - public void end(boolean interrupted) {} } diff --git a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java index 5ef39728..71395b90 100644 --- a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java +++ b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java @@ -29,6 +29,7 @@ public AddressableLEDSubsystem() { } // Periodically update the LED strip + @Override public void periodic() { led.setData(ledBuffer); } From e8279961ef999308c157b6fdf3bb724f5c8a0f82 Mon Sep 17 00:00:00 2001 From: RobotLeopard86 <63123751+RobotLeopard86@users.noreply.github.com> Date: Wed, 26 Feb 2025 17:14:36 -0800 Subject: [PATCH 04/21] Address code review feedback for AddressableLED subsystem and add scaffold for testing command --- .../frc/robot/commands/SetAddressableLEDPattern.java | 12 +++++++----- .../commands/test/AddressableLEDTestCommand.java | 5 +++++ 2 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java diff --git a/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java b/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java index d8b9265d..ef9067e3 100644 --- a/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java +++ b/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java @@ -18,20 +18,22 @@ public class SetAddressableLEDPattern extends Command { * @param section Section of LED strip to apply pattern to (index into * AddressableLEDConstants.SECTIONS) */ - public SetAddressableLEDPattern(AddressableLEDSubsystem led, LEDPattern pattern, int section) { + public SetAddressableLEDPattern(AddressableLEDSubsystem ledSystem, LEDPattern pattern, int section) { this.section = section; this.pattern = pattern; - ledSystem = led; + this.ledSystem = ledSystem; + addRequirements(ledSystem); } /** * @param led Addressable LED subsystem to use * @param pattern Pattern to apply when command run */ - public SetAddressableLEDPattern(AddressableLEDSubsystem led, LEDPattern pattern) { - this.section = -1; + public SetAddressableLEDPattern(AddressableLEDSubsystem ledSystem, LEDPattern pattern) { + section = -1; this.pattern = pattern; - ledSystem = led; + this.ledSystem = ledSystem; + addRequirements(ledSystem); } @Override diff --git a/src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java b/src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java new file mode 100644 index 00000000..558dab29 --- /dev/null +++ b/src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java @@ -0,0 +1,5 @@ +package frc.robot.commands.test; + +public class AddressableLEDTestCommand extends Command { + +} From fad22dbdd3bda39a6205574bf601f8fe9e89de58 Mon Sep 17 00:00:00 2001 From: RobotLeopard86 <63123751+RobotLeopard86@users.noreply.github.com> Date: Wed, 26 Feb 2025 17:28:31 -0800 Subject: [PATCH 05/21] Add AddressableLED testing command --- .../test/AddressableLEDTestCommand.java | 50 ++++++++++++++++++- .../AddressableLEDConstants.java | 5 ++ .../AddressableLEDSubsystem.java | 11 ++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java b/src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java index 558dab29..2416d51d 100644 --- a/src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java +++ b/src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java @@ -1,5 +1,53 @@ package frc.robot.commands.test; +import static edu.wpi.first.units.Units.MetersPerSecond; +import static edu.wpi.first.units.Units.Seconds; + +import edu.wpi.first.wpilibj.LEDPattern; +import edu.wpi.first.wpilibj.util.Color; +import edu.wpi.first.wpilibj2.command.Command; +import frc.robot.subsystems.addressableled.AddressableLEDConstants; +import frc.robot.subsystems.addressableled.AddressableLEDSubsystem; + public class AddressableLEDTestCommand extends Command { - + private final AddressableLEDSubsystem ledSystem; + private LEDPattern currentPattern; + private int ticker = 0; + private int testCount = 0; + + public AddressableLEDTestCommand(AddressableLEDSubsystem ledSystem) { + this.ledSystem = ledSystem; + addRequirements(ledSystem); + } + + @Override + public void initialize() { + ticker = 0; + testCount = 0; + currentPattern = LEDPattern.rainbow(255, 128).scrollAtAbsoluteSpeed(MetersPerSecond.of(1), AddressableLEDConstants.LED_DENSITY); + } + + @Override + public void execute() { + if(ticker < 500) { + ticker++; + } else { + ticker = 0; + testCount++; + if(testCount == AddressableLEDConstants.SECTIONS.length) { + currentPattern = LEDPattern.solid(Color.kLimeGreen).breathe(Seconds.of(2)); + } + } + } + + @Override + public boolean isFinished() { + return testCount < (AddressableLEDConstants.SECTIONS.length + 1); + } + + @Override + public void end(boolean interrupted) { + // TODO Auto-generated method stub + super.end(interrupted); + } } diff --git a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java index 40639882..033065c5 100644 --- a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java +++ b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java @@ -1,10 +1,15 @@ package frc.robot.subsystems.addressableled; +import static edu.wpi.first.units.Units.Meters; + +import edu.wpi.first.units.measure.Distance; + public class AddressableLEDConstants { public record Range(int low, int high) {} // TODO: Implement real values public static final int LED_COUNT = 64; + public static final Distance LED_DENSITY = Meters.of(1.0 / LED_COUNT); public static final int LED_STRIP_PORT = 0; public static final Range SECTIONS[] = {new Range(0, LED_COUNT)}; } diff --git a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java index 71395b90..cde651db 100644 --- a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java +++ b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java @@ -10,6 +10,7 @@ public class AddressableLEDSubsystem extends SubsystemBase { private final AddressableLED led; private final AddressableLEDBuffer ledBuffer; private AddressableLEDBufferView ledViews[]; + private LEDPattern[] currentPatterns; public AddressableLEDSubsystem() { // Create strip and buffer @@ -17,6 +18,9 @@ public AddressableLEDSubsystem() { ledBuffer = new AddressableLEDBuffer(AddressableLEDConstants.LED_COUNT); led.setLength(AddressableLEDConstants.LED_COUNT); + //Create current pattern trackers + currentPatterns = new LEDPattern[AddressableLEDConstants.SECTIONS.length]; + // Create section views ledViews = new AddressableLEDBufferView[AddressableLEDConstants.SECTIONS.length]; for (int i = 0; i < ledViews.length; i++) { @@ -31,6 +35,9 @@ public AddressableLEDSubsystem() { // Periodically update the LED strip @Override public void periodic() { + for(int i = 0; i < ledViews.length; i++) { + currentPatterns[i].applyTo(ledViews[i]); + } led.setData(ledBuffer); } @@ -38,10 +45,14 @@ public void periodic() { public void applySectionedPattern(LEDPattern pattern, int section) { if (section < 0 || section >= ledViews.length) return; pattern.applyTo(ledViews[section]); + currentPatterns[section] = pattern; } // Apply a color pattern to a section of the LED strip public void applyPattern(LEDPattern pattern) { pattern.applyTo(ledBuffer); + for(int i = 0; i < currentPatterns.length; i++) { + currentPatterns[i] = pattern; + } } } From 74fb53fc197f2486fe647eef67ba68f08c8a3b3b Mon Sep 17 00:00:00 2001 From: RobotLeopard86 <63123751+RobotLeopard86@users.noreply.github.com> Date: Wed, 26 Feb 2025 17:44:38 -0800 Subject: [PATCH 06/21] Actually apply the patterns for the AddressableLED test --- .../frc/robot/commands/test/AddressableLEDTestCommand.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java b/src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java index 2416d51d..eee33670 100644 --- a/src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java +++ b/src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java @@ -33,9 +33,13 @@ public void execute() { ticker++; } else { ticker = 0; + ledSystem.applySectionedPattern(LEDPattern.kOff, testCount); testCount++; if(testCount == AddressableLEDConstants.SECTIONS.length) { currentPattern = LEDPattern.solid(Color.kLimeGreen).breathe(Seconds.of(2)); + ledSystem.applyPattern(currentPattern); + } else { + ledSystem.applySectionedPattern(currentPattern, testCount); } } } @@ -47,7 +51,6 @@ public boolean isFinished() { @Override public void end(boolean interrupted) { - // TODO Auto-generated method stub - super.end(interrupted); + ledSystem.applyPattern(LEDPattern.kOff); } } From 0cc78fe727940912498e102ebd3fd9e230915b2b Mon Sep 17 00:00:00 2001 From: RobotLeopard86 <63123751+RobotLeopard86@users.noreply.github.com> Date: Wed, 26 Feb 2025 17:44:53 -0800 Subject: [PATCH 07/21] Run Spotless! --- .../java/frc/robot/commands/SetAddressableLEDPattern.java | 3 ++- .../robot/commands/test/AddressableLEDTestCommand.java | 8 +++++--- .../addressableled/AddressableLEDSubsystem.java | 6 +++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java b/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java index ef9067e3..f423ba6b 100644 --- a/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java +++ b/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java @@ -18,7 +18,8 @@ public class SetAddressableLEDPattern extends Command { * @param section Section of LED strip to apply pattern to (index into * AddressableLEDConstants.SECTIONS) */ - public SetAddressableLEDPattern(AddressableLEDSubsystem ledSystem, LEDPattern pattern, int section) { + public SetAddressableLEDPattern( + AddressableLEDSubsystem ledSystem, LEDPattern pattern, int section) { this.section = section; this.pattern = pattern; this.ledSystem = ledSystem; diff --git a/src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java b/src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java index eee33670..805eb0f1 100644 --- a/src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java +++ b/src/main/java/frc/robot/commands/test/AddressableLEDTestCommand.java @@ -24,18 +24,20 @@ public AddressableLEDTestCommand(AddressableLEDSubsystem ledSystem) { public void initialize() { ticker = 0; testCount = 0; - currentPattern = LEDPattern.rainbow(255, 128).scrollAtAbsoluteSpeed(MetersPerSecond.of(1), AddressableLEDConstants.LED_DENSITY); + currentPattern = + LEDPattern.rainbow(255, 128) + .scrollAtAbsoluteSpeed(MetersPerSecond.of(1), AddressableLEDConstants.LED_DENSITY); } @Override public void execute() { - if(ticker < 500) { + if (ticker < 500) { ticker++; } else { ticker = 0; ledSystem.applySectionedPattern(LEDPattern.kOff, testCount); testCount++; - if(testCount == AddressableLEDConstants.SECTIONS.length) { + if (testCount == AddressableLEDConstants.SECTIONS.length) { currentPattern = LEDPattern.solid(Color.kLimeGreen).breathe(Seconds.of(2)); ledSystem.applyPattern(currentPattern); } else { diff --git a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java index cde651db..7cbdfa91 100644 --- a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java +++ b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDSubsystem.java @@ -18,7 +18,7 @@ public AddressableLEDSubsystem() { ledBuffer = new AddressableLEDBuffer(AddressableLEDConstants.LED_COUNT); led.setLength(AddressableLEDConstants.LED_COUNT); - //Create current pattern trackers + // Create current pattern trackers currentPatterns = new LEDPattern[AddressableLEDConstants.SECTIONS.length]; // Create section views @@ -35,7 +35,7 @@ public AddressableLEDSubsystem() { // Periodically update the LED strip @Override public void periodic() { - for(int i = 0; i < ledViews.length; i++) { + for (int i = 0; i < ledViews.length; i++) { currentPatterns[i].applyTo(ledViews[i]); } led.setData(ledBuffer); @@ -51,7 +51,7 @@ public void applySectionedPattern(LEDPattern pattern, int section) { // Apply a color pattern to a section of the LED strip public void applyPattern(LEDPattern pattern) { pattern.applyTo(ledBuffer); - for(int i = 0; i < currentPatterns.length; i++) { + for (int i = 0; i < currentPatterns.length; i++) { currentPatterns[i] = pattern; } } From 7f0147cbd67dc8e9ff6483f1fbf2857ffd9d7f64 Mon Sep 17 00:00:00 2001 From: RobotLeopard86 <63123751+RobotLeopard86@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:36:43 -0800 Subject: [PATCH 08/21] Add Javadocs for AddressableLED subsystem I didn't forget to run Spotless this time! --- .../frc/robot/commands/SetAddressableLEDPattern.java | 4 +++- .../addressableled/AddressableLEDConstants.java | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java b/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java index f423ba6b..cf3ece76 100644 --- a/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java +++ b/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java @@ -7,7 +7,9 @@ public class SetAddressableLEDPattern extends Command { private final AddressableLEDSubsystem ledSystem; - // If this is -1, that means that this command is targeting the whole strip + /** + * @apiNote If this is -1, that means that this command is targeting the whole strip + */ private final int section; private final LEDPattern pattern; diff --git a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java index 033065c5..3d4f75f4 100644 --- a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java +++ b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java @@ -5,11 +5,20 @@ import edu.wpi.first.units.measure.Distance; public class AddressableLEDConstants { + /** + * @param low The lower bound of the range + * @param high The upper bound of the range + */ public record Range(int low, int high) {} // TODO: Implement real values public static final int LED_COUNT = 64; public static final Distance LED_DENSITY = Meters.of(1.0 / LED_COUNT); public static final int LED_STRIP_PORT = 0; + + /** + * @apiNote The lower bound of the range represents the lowest index LED for this section, and the + * upper bound represents the highest index LED + */ public static final Range SECTIONS[] = {new Range(0, LED_COUNT)}; } From 6cf0918718c808701f750c22c0a955c57bb804e9 Mon Sep 17 00:00:00 2001 From: RobotLeopard86 <63123751+RobotLeopard86@users.noreply.github.com> Date: Sat, 1 Mar 2025 11:28:30 -0800 Subject: [PATCH 09/21] Clarify separation between Blinkin and AddressableLED subsystems --- .../robot/commands/SetBlinkinLEDPattern.java | 43 +++++++++++++++++ .../frc/robot/commands/SetLightPattern.java | 46 ------------------- ...ommand.java => BlinkinLEDTestCommand.java} | 16 +++---- .../BlinkinLEDConstants.java} | 6 +-- .../BlinkinLEDSubsystem.java} | 12 +++-- .../superstructure/wrist/WristConstants.java | 2 +- 6 files changed, 62 insertions(+), 63 deletions(-) create mode 100644 src/main/java/frc/robot/commands/SetBlinkinLEDPattern.java delete mode 100644 src/main/java/frc/robot/commands/SetLightPattern.java rename src/main/java/frc/robot/commands/test/{LEDTestCommand.java => BlinkinLEDTestCommand.java} (63%) rename src/main/java/frc/robot/subsystems/{led/LEDConstants.java => blinkinled/BlinkinLEDConstants.java} (91%) rename src/main/java/frc/robot/subsystems/{led/LEDSubsystem.java => blinkinled/BlinkinLEDSubsystem.java} (81%) diff --git a/src/main/java/frc/robot/commands/SetBlinkinLEDPattern.java b/src/main/java/frc/robot/commands/SetBlinkinLEDPattern.java new file mode 100644 index 00000000..d563411a --- /dev/null +++ b/src/main/java/frc/robot/commands/SetBlinkinLEDPattern.java @@ -0,0 +1,43 @@ +package frc.robot.commands; + +import edu.wpi.first.wpilibj2.command.Command; +import frc.robot.subsystems.blinkinled.BlinkinLEDSubsystem; + +public class SetBlinkinLEDPattern extends Command { + private BlinkinLEDSubsystem ledSystem; + private double pattern; + + /** + * @apiNote If this is -1, that means that this command is targeting the whole strip + */ + private int section; + + private boolean invalid; + + public SetBlinkinLEDPattern(BlinkinLEDSubsystem ledSystem, int section, double pattern) { + invalid = (section < -1 || section >= ledSystem.stripCount); + this.section = section; + this.ledSystem = ledSystem; + this.pattern = pattern; + } + + public SetBlinkinLEDPattern(BlinkinLEDSubsystem led, double pattern) { + this(led, -1, pattern); + } + + @Override + public void initialize() { + if (invalid) return; + if (section == -1) { + ledSystem.applyPatternToAll(pattern); + } else { + ledSystem.applyPatternTo(section, pattern); + } + } + + // Since executing the command is a one-time thing, we always report being done instantly + @Override + public boolean isFinished() { + return true; + } +} diff --git a/src/main/java/frc/robot/commands/SetLightPattern.java b/src/main/java/frc/robot/commands/SetLightPattern.java deleted file mode 100644 index dd713fac..00000000 --- a/src/main/java/frc/robot/commands/SetLightPattern.java +++ /dev/null @@ -1,46 +0,0 @@ -package frc.robot.commands; - -import edu.wpi.first.wpilibj2.command.Command; -import frc.robot.subsystems.led.LEDSubsystem; - -public class SetLightPattern extends Command { - private LEDSubsystem ledSystem; - private double pattern; - - // Set this to -1 to have the command apply to all strips - private int stripID; - - public SetLightPattern(LEDSubsystem led, int strip, double pattern) { - if (strip < -1) - throw new IllegalArgumentException( - "LED configuration commands may ONLY use -1 (all strips) or higher for strip IDs!"); - ledSystem = led; - this.pattern = pattern; - } - - public SetLightPattern(LEDSubsystem led, double pattern) { - this(led, -1, pattern); - } - - @Override - public void initialize() {} - - @Override - public void execute() { - if (stripID == -1) { - ledSystem.applyPatternToAll(pattern); - } else { - ledSystem.applyPatternTo(stripID, pattern); - } - } - - // Since executing the command is a one-time thing, we always report being done instantly - - @Override - public boolean isFinished() { - return true; - } - - @Override - public void end(boolean interrupted) {} -} diff --git a/src/main/java/frc/robot/commands/test/LEDTestCommand.java b/src/main/java/frc/robot/commands/test/BlinkinLEDTestCommand.java similarity index 63% rename from src/main/java/frc/robot/commands/test/LEDTestCommand.java rename to src/main/java/frc/robot/commands/test/BlinkinLEDTestCommand.java index d5840d2e..4108253c 100644 --- a/src/main/java/frc/robot/commands/test/LEDTestCommand.java +++ b/src/main/java/frc/robot/commands/test/BlinkinLEDTestCommand.java @@ -1,11 +1,11 @@ package frc.robot.commands.test; import edu.wpi.first.wpilibj2.command.Command; -import frc.robot.subsystems.led.LEDConstants; -import frc.robot.subsystems.led.LEDSubsystem; +import frc.robot.subsystems.blinkinled.BlinkinLEDConstants; +import frc.robot.subsystems.blinkinled.BlinkinLEDSubsystem; -public class LEDTestCommand extends Command { - private LEDSubsystem ledSystem; +public class BlinkinLEDTestCommand extends Command { + private BlinkinLEDSubsystem ledSystem; private double currentPattern; @@ -17,14 +17,14 @@ public class LEDTestCommand extends Command { * @param time Time in robot updates to wait between changes (each update is 20ms, so 50 updates * is 1 second) */ - public LEDTestCommand(LEDSubsystem led, int time) { + public BlinkinLEDTestCommand(BlinkinLEDSubsystem led, int time) { ledSystem = led; delay = time; } @Override public void initialize() { - currentPattern = LEDConstants.LEDPatterns.BLACK; + currentPattern = BlinkinLEDConstants.Patterns.BLACK; ticker = 0; } @@ -39,11 +39,11 @@ public void execute() { @Override public boolean isFinished() { - return currentPattern <= LEDConstants.LEDPatterns.HOT_PINK; + return currentPattern <= BlinkinLEDConstants.Patterns.HOT_PINK; } @Override public void end(boolean interrupted) { - currentPattern = LEDConstants.LEDPatterns.BLACK; + currentPattern = BlinkinLEDConstants.Patterns.BLACK; } } diff --git a/src/main/java/frc/robot/subsystems/led/LEDConstants.java b/src/main/java/frc/robot/subsystems/blinkinled/BlinkinLEDConstants.java similarity index 91% rename from src/main/java/frc/robot/subsystems/led/LEDConstants.java rename to src/main/java/frc/robot/subsystems/blinkinled/BlinkinLEDConstants.java index 0680007d..18fdd6af 100644 --- a/src/main/java/frc/robot/subsystems/led/LEDConstants.java +++ b/src/main/java/frc/robot/subsystems/blinkinled/BlinkinLEDConstants.java @@ -1,11 +1,11 @@ -package frc.robot.subsystems.led; +package frc.robot.subsystems.blinkinled; -public class LEDConstants { +public class BlinkinLEDConstants { /** * @brief Patterns taken from * @link https://www.revrobotics.com/content/docs/REV-11-1105-UM.pdf */ - public static class LEDPatterns { + public static class Patterns { public static final double HOT_PINK = 0.57; public static final double DARK_RED = 0.59; public static final double RED = 0.61; diff --git a/src/main/java/frc/robot/subsystems/led/LEDSubsystem.java b/src/main/java/frc/robot/subsystems/blinkinled/BlinkinLEDSubsystem.java similarity index 81% rename from src/main/java/frc/robot/subsystems/led/LEDSubsystem.java rename to src/main/java/frc/robot/subsystems/blinkinled/BlinkinLEDSubsystem.java index 30f75b04..94a0db97 100644 --- a/src/main/java/frc/robot/subsystems/led/LEDSubsystem.java +++ b/src/main/java/frc/robot/subsystems/blinkinled/BlinkinLEDSubsystem.java @@ -1,10 +1,10 @@ -package frc.robot.subsystems.led; +package frc.robot.subsystems.blinkinled; import edu.wpi.first.wpilibj.motorcontrol.Spark; import edu.wpi.first.wpilibj2.command.SubsystemBase; -import frc.robot.subsystems.led.LEDConstants.LEDPatterns; +import frc.robot.subsystems.blinkinled.BlinkinLEDConstants.Patterns; -public class LEDSubsystem extends SubsystemBase { +public class BlinkinLEDSubsystem extends SubsystemBase { private class LEDStrip { public Spark pwm; public double pattern; @@ -16,12 +16,14 @@ public LEDStrip(Spark pwmController, double initialPattern) { } private LEDStrip[] strips; + public final int stripCount; - public LEDSubsystem(int... pwmPorts) { + public BlinkinLEDSubsystem(int... pwmPorts) { // Create all the strip objects + stripCount = pwmPorts.length; strips = new LEDStrip[pwmPorts.length]; for (int i = pwmPorts.length; i >= 0; i--) { - strips[i] = new LEDStrip(new Spark(pwmPorts[i]), LEDPatterns.BLACK); + strips[i] = new LEDStrip(new Spark(pwmPorts[i]), Patterns.BLACK); } } diff --git a/src/main/java/frc/robot/subsystems/superstructure/wrist/WristConstants.java b/src/main/java/frc/robot/subsystems/superstructure/wrist/WristConstants.java index df369073..5c9ba589 100644 --- a/src/main/java/frc/robot/subsystems/superstructure/wrist/WristConstants.java +++ b/src/main/java/frc/robot/subsystems/superstructure/wrist/WristConstants.java @@ -11,7 +11,7 @@ public class WristConstants { public static final double CORAL_SCORING_POSITION_L1_L2_L3 = Units.degreesToRotations(35); public static final double CORAL_SCORING_POSITION_L4 = Units.degreesToRotations(0); public static final double CORAL_PICKUP_POSITION = Units.degreesToRotations(55); - + public static final double ABSOLUTE_ENCODER_OFFSET = 0.0; public static final double RELATIVE_CONVERSION_FACTOR = 0.0; From e9c44d43395c795b010a5d656802c4492dad63f0 Mon Sep 17 00:00:00 2001 From: RobotLeopard86 <63123751+RobotLeopard86@users.noreply.github.com> Date: Sat, 1 Mar 2025 11:47:57 -0800 Subject: [PATCH 10/21] Fix Wrist build error resulting from main merge --- .../robot/subsystems/superstructure/wrist/WristConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/frc/robot/subsystems/superstructure/wrist/WristConstants.java b/src/main/java/frc/robot/subsystems/superstructure/wrist/WristConstants.java index ed9ea306..1053773a 100644 --- a/src/main/java/frc/robot/subsystems/superstructure/wrist/WristConstants.java +++ b/src/main/java/frc/robot/subsystems/superstructure/wrist/WristConstants.java @@ -1,5 +1,6 @@ package frc.robot.subsystems.superstructure.wrist; +import edu.wpi.first.math.util.Units; import frc.robot.Constants; import frc.robot.utility.records.PIDConstants; @@ -17,7 +18,6 @@ public class WristConstants { public static final int MOTOR_ID = 0; public static final int CANCODER_ID = 0; - public static final double ABSOLUTE_ENCODER_OFFSET = 0.0; public static final double GEAR_REDUCTION = 1.0; public static final int CURRENT_LIMIT = 30; From d3c6e7b2a1e2c767c2d4a73c31e7a252fe43bf76 Mon Sep 17 00:00:00 2001 From: RobotLeopard86 <63123751+RobotLeopard86@users.noreply.github.com> Date: Sat, 1 Mar 2025 13:33:32 -0800 Subject: [PATCH 11/21] Add superstructure LED patterns --- src/main/java/frc/robot/RobotContainer.java | 28 +++++++++++++++---- .../commands/SetAddressableLEDPattern.java | 16 ++++++----- .../AddressableLEDConstants.java | 26 ++++++++++++++--- 3 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/main/java/frc/robot/RobotContainer.java b/src/main/java/frc/robot/RobotContainer.java index f1fbc12d..b6b23f38 100644 --- a/src/main/java/frc/robot/RobotContainer.java +++ b/src/main/java/frc/robot/RobotContainer.java @@ -1,5 +1,7 @@ package frc.robot; +import static edu.wpi.first.units.Units.Percent; +import static edu.wpi.first.units.Units.Second; import static frc.robot.subsystems.drive.DriveConstants.DRIVE_CONFIG; import com.pathplanner.lib.auto.AutoBuilder; @@ -10,13 +12,17 @@ import edu.wpi.first.math.geometry.Transform2d; import edu.wpi.first.math.geometry.Translation2d; import edu.wpi.first.math.util.Units; +import edu.wpi.first.units.measure.Frequency; import edu.wpi.first.wpilibj.Alert; import edu.wpi.first.wpilibj.Alert.AlertType; import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj.LEDPattern; import edu.wpi.first.wpilibj.GenericHID.RumbleType; +import edu.wpi.first.wpilibj.LEDPattern.GradientType; import edu.wpi.first.wpilibj.RobotBase; import edu.wpi.first.wpilibj.smartdashboard.SendableChooser; import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; +import edu.wpi.first.wpilibj.util.Color; import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.CommandScheduler; import edu.wpi.first.wpilibj2.command.Commands; @@ -26,10 +32,12 @@ import frc.robot.Constants.Mode; import frc.robot.commands.AdaptiveAutoAlignCommands; import frc.robot.commands.DriveCommands; +import frc.robot.commands.SetAddressableLEDPattern; import frc.robot.commands.controllers.JoystickInputController; import frc.robot.commands.controllers.SpeedLevelController; import frc.robot.commands.intake.SetIntakeSpeed; import frc.robot.commands.wrist.SetWrist; +import frc.robot.subsystems.addressableled.AddressableLEDSubsystem; import frc.robot.subsystems.dashboard.DriverDashboard; import frc.robot.subsystems.drive.Drive; import frc.robot.subsystems.drive.DriveConstants; @@ -86,6 +94,7 @@ public class RobotContainer { private final Wrist wrist; private final AlgaeIntake algaeIntake; private final CoralIntake coralIntake; + private final AddressableLEDSubsystem led; private final Hang hang; @@ -145,6 +154,7 @@ public RobotContainer() { elevator = new Elevator(new ElevatorIOHardwareFollow(ElevatorConstants.ELEVATOR_CONFIG)); hang = new Hang(new HangIOHardwareRelative(HangConstants.HANG_CONFIG)); wrist = new Wrist(new WristIO() {}); + led = new AddressableLEDSubsystem(); // algaeIntake = // new AlgaeIntake( @@ -181,6 +191,7 @@ public RobotContainer() { algaeIntake = new AlgaeIntake(new IntakeIO() {}); coralIntake = new CoralIntake(new IntakeIO() {}); + led = new AddressableLEDSubsystem(); break; @@ -504,19 +515,24 @@ private void configureDriverControllerBindings(boolean includeAutoAlign) { private void configureOperatorControllerBindings() { operatorController.back().onTrue(drive.runOnce(drive::stop).withName("CANCEL and stop")); - configureOperatorControllerBindingLevel(operatorController.y(), Superstructure.State.L4); - configureOperatorControllerBindingLevel(operatorController.x(), Superstructure.State.L3); - configureOperatorControllerBindingLevel(operatorController.b(), Superstructure.State.L2); - configureOperatorControllerBindingLevel(operatorController.a(), Superstructure.State.L1); + configureOperatorControllerBindingLevel(operatorController.y(), Superstructure.State.L4, Color.kAqua); + configureOperatorControllerBindingLevel(operatorController.x(), Superstructure.State.L3, Color.kGold); + configureOperatorControllerBindingLevel(operatorController.b(), Superstructure.State.L2, Color.kLime); + configureOperatorControllerBindingLevel(operatorController.a(), Superstructure.State.L1, Color.kPurple); operatorController.leftBumper().whileTrue(hang.set(+0.5).withName("Hang Arm Up")); operatorController.rightBumper().whileTrue(hang.set(-0.5).withName("Hang Arm Down")); } private void configureOperatorControllerBindingLevel( - Trigger trigger, Superstructure.State state) { + Trigger trigger, Superstructure.State state, Color color) { trigger.onTrue(superstructure.setNextPrepare(state)); - trigger.and(operatorController.rightTrigger()).onTrue(superstructure.runPrepare(state)); + if(led != null) { + LEDPattern pattern = LEDPattern.gradient(GradientType.kContinuous, Color.kBlack, color).scrollAtRelativeSpeed(Percent.per(Second).of(35)); + trigger.and(operatorController.rightTrigger()).onTrue(superstructure.runPrepare(state).alongWith(new SetAddressableLEDPattern(led, pattern, 4, 5))); + } else { + trigger.and(operatorController.rightTrigger()).onTrue(superstructure.runPrepare(state)); + } } private Command rumbleController(CommandXboxController controller, double rumbleIntensity) { diff --git a/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java b/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java index cf3ece76..d05ff094 100644 --- a/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java +++ b/src/main/java/frc/robot/commands/SetAddressableLEDPattern.java @@ -8,9 +8,9 @@ public class SetAddressableLEDPattern extends Command { private final AddressableLEDSubsystem ledSystem; /** - * @apiNote If this is -1, that means that this command is targeting the whole strip + * @apiNote If this is empty, that means that this command is targeting the whole strip */ - private final int section; + private final int[] sections; private final LEDPattern pattern; @@ -21,8 +21,8 @@ public class SetAddressableLEDPattern extends Command { * AddressableLEDConstants.SECTIONS) */ public SetAddressableLEDPattern( - AddressableLEDSubsystem ledSystem, LEDPattern pattern, int section) { - this.section = section; + AddressableLEDSubsystem ledSystem, LEDPattern pattern, int... sections) { + this.sections = sections; this.pattern = pattern; this.ledSystem = ledSystem; addRequirements(ledSystem); @@ -33,7 +33,7 @@ public SetAddressableLEDPattern( * @param pattern Pattern to apply when command run */ public SetAddressableLEDPattern(AddressableLEDSubsystem ledSystem, LEDPattern pattern) { - section = -1; + sections = new int[0]; this.pattern = pattern; this.ledSystem = ledSystem; addRequirements(ledSystem); @@ -41,10 +41,12 @@ public SetAddressableLEDPattern(AddressableLEDSubsystem ledSystem, LEDPattern pa @Override public void execute() { - if (section < 0) { + if (sections.length <= 0) { ledSystem.applyPattern(pattern); } else { - ledSystem.applySectionedPattern(pattern, section); + for(int i = 0; i < sections.length; i++) { + ledSystem.applySectionedPattern(pattern, sections[i]); + } } } diff --git a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java index 3d4f75f4..a727114e 100644 --- a/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java +++ b/src/main/java/frc/robot/subsystems/addressableled/AddressableLEDConstants.java @@ -11,14 +11,32 @@ public class AddressableLEDConstants { */ public record Range(int low, int high) {} - // TODO: Implement real values - public static final int LED_COUNT = 64; - public static final Distance LED_DENSITY = Meters.of(1.0 / LED_COUNT); + // TODO: Replace these with real values + public static final int LED_COUNT = 60; + public static final Distance LED_DENSITY = Meters.of(1.0 / 60.0); public static final int LED_STRIP_PORT = 0; /** * @apiNote The lower bound of the range represents the lowest index LED for this section, and the * upper bound represents the highest index LED + * + *