From 294fd5786fbcb65334dd9beaae6727064180e3b2 Mon Sep 17 00:00:00 2001 From: elma Date: Wed, 13 Aug 2025 21:02:39 +0300 Subject: [PATCH 01/15] initial commit for library, led example --- src/main/java/frc/kelrotlib/leds/Led.java | 20 +++++++++++++++++++ src/main/java/frc/robot/RobotContainer.java | 1 + .../frc/robot/subsystems/LedSubsystem.java | 20 +++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 src/main/java/frc/kelrotlib/leds/Led.java create mode 100644 src/main/java/frc/robot/subsystems/LedSubsystem.java diff --git a/src/main/java/frc/kelrotlib/leds/Led.java b/src/main/java/frc/kelrotlib/leds/Led.java new file mode 100644 index 0000000..cb47f2b --- /dev/null +++ b/src/main/java/frc/kelrotlib/leds/Led.java @@ -0,0 +1,20 @@ +package frc.kelrotlib.leds; + +import edu.wpi.first.wpilibj2.command.SubsystemBase; + +public class Led extends SubsystemBase { + /** Creates a new ExampleSubsystem. */ + public Led() { + + } + + @Override + public void periodic() { + // This method will be called once per scheduler run + } + + @Override + public void simulationPeriodic() { + // This method will be called once per scheduler run during simulation + } +} diff --git a/src/main/java/frc/robot/RobotContainer.java b/src/main/java/frc/robot/RobotContainer.java index 5374114..20bd630 100644 --- a/src/main/java/frc/robot/RobotContainer.java +++ b/src/main/java/frc/robot/RobotContainer.java @@ -5,6 +5,7 @@ package frc.robot; import edu.wpi.first.wpilibj2.command.Command; +import frc.kelrotlib.leds.Led; public class RobotContainer { public RobotContainer() { diff --git a/src/main/java/frc/robot/subsystems/LedSubsystem.java b/src/main/java/frc/robot/subsystems/LedSubsystem.java new file mode 100644 index 0000000..b036163 --- /dev/null +++ b/src/main/java/frc/robot/subsystems/LedSubsystem.java @@ -0,0 +1,20 @@ +package frc.robot.subsystems; + +import frc.kelrotlib.leds.Led; + +public class LedSubsystem extends Led { + /** Creates a new ExampleSubsystem. */ + public LedSubsystem() { + + } + + @Override + public void periodic() { + // This method will be called once per scheduler run + } + + @Override + public void simulationPeriodic() { + // This method will be called once per scheduler run during simulation + } +} From b4e8899fc5f125290edf5578397c4b340f062d74 Mon Sep 17 00:00:00 2001 From: elma Date: Wed, 13 Aug 2025 21:35:12 +0300 Subject: [PATCH 02/15] led example finished, needs review --- gradlew | 0 src/main/java/frc/kelrotlib/leds/Led.java | 104 +++++++++++++++--- src/main/java/frc/robot/Constants.java | 9 ++ src/main/java/frc/robot/RobotContainer.java | 7 +- .../frc/robot/subsystems/LedSubsystem.java | 11 +- 5 files changed, 104 insertions(+), 27 deletions(-) mode change 100644 => 100755 gradlew diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/src/main/java/frc/kelrotlib/leds/Led.java b/src/main/java/frc/kelrotlib/leds/Led.java index cb47f2b..e3e197f 100644 --- a/src/main/java/frc/kelrotlib/leds/Led.java +++ b/src/main/java/frc/kelrotlib/leds/Led.java @@ -1,20 +1,94 @@ package frc.kelrotlib.leds; +import static edu.wpi.first.units.Units.MetersPerSecond; +import static edu.wpi.first.units.Units.Seconds; + +import java.util.HashMap; + +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.wpilibj.util.Color; +import edu.wpi.first.wpilibj2.command.Command; import edu.wpi.first.wpilibj2.command.SubsystemBase; +import frc.robot.Constants.LedConstants; + +public class Led extends SubsystemBase{ //a Java inheritance example + private AddressableLED m_led; + private AddressableLEDBuffer m_buffer; + private HashMap m_groupList; + private HashMap m_patternList; + private LEDPattern k_defaultPattern = LEDPattern.solid(Color.kBlack); + + public Led() { + m_led = new AddressableLED(LedConstants.kLedPort); //every variable you might change later (ports, length etc.) should be added to Constants.java* + m_buffer = new AddressableLEDBuffer(LedConstants.kLedLength); // * this way every port and important variable is in one place. + m_led.setLength(LedConstants.kLedLength); //setting the length takes a lot of load so do it only one time when possible + m_led.start(); + + m_groupList = new HashMap(); //I decided to use Integers for the keys as it is much more straight-forward, in future uses the keys can be String's for more complicated group identification needs. + m_patternList = new HashMap(); //For this version of grouping we need to store previous patterns for each group + + setDefaultCommand(runPattern(k_defaultPattern).withName("Off")); //set all leds to off/black on start + } + + public void createGroup(int startingIndex, int endingIndex, Integer groupID) { //infinite amount of groups creatable, without complicating the code + AddressableLEDBufferView group = m_buffer.createView(startingIndex, endingIndex); //create new group(view) + m_groupList.put(groupID, group); + m_patternList.put(groupID, k_defaultPattern); //initially set the defaultPattern, so the runPattern command doesn't break + } + + public void setSolidColor(Color color, Integer[] groupIDs){ + LEDPattern solidColorPattern = LEDPattern.solid(color); + for (int i = 0; i < groupIDs.length; i++) { //update the latest pattern for every LED group given + m_patternList.replace(groupIDs[i], solidColorPattern); //I love hashmap it is just so cool + } + runPattern(); + } + + public void setBlinkColor(Color color, double interval, Integer[] groupIDs){ + LEDPattern base = LEDPattern.solid(color); + LEDPattern blinkPattern = base.blink(Seconds.of(interval)); //synchronised blink, wpilib also has support for asynchronised blink + for (int i = 0; i < groupIDs.length; i++) { + m_patternList.replace(groupIDs[i], blinkPattern); + } + runPattern(); + } + + public void rainbow(Integer[] groupIDs){ + LEDPattern rainbow = LEDPattern.rainbow(255, 128); //all hues at maximum saturation and *half* brightness + LEDPattern scrollingRainbow = rainbow.scrollAtAbsoluteSpeed(MetersPerSecond.of(1), LedConstants.kLedSpacing); //moves/scrolls the effect at a speed of 1 meter per second + for (int i = 0; i < groupIDs.length; i++) { + m_patternList.replace(groupIDs[i], scrollingRainbow); + } + runPattern(); + } + + public void turnOff(){ + runPattern(k_defaultPattern); + } + + public Command runPattern(){ //A command is used as it doesn't allow actions to run simultaneously, for this usage it is crucial, because we need to stop the previous patterns and start the new ones. + return run(() -> { + for (Integer i : m_groupList.keySet()) { //parsing through every key in the groupList HashMap + m_patternList.get(i).applyTo(m_groupList.get(i)); //getting every setted pattern and applying it to the ID'd LED Group + } + }); + } + + public Command runPattern(LEDPattern pattern) { //might get removed later. + return run(() -> { + pattern.applyTo(m_buffer); + }); + } -public class Led extends SubsystemBase { - /** Creates a new ExampleSubsystem. */ - public Led() { - - } - - @Override - public void periodic() { - // This method will be called once per scheduler run - } - - @Override - public void simulationPeriodic() { - // This method will be called once per scheduler run during simulation - } + @Override + public void periodic() { //update the data every 20ms + m_led.setData(m_buffer); + } + + @Override + public void simulationPeriodic() { + } } diff --git a/src/main/java/frc/robot/Constants.java b/src/main/java/frc/robot/Constants.java index 43947fc..eef6ae4 100644 --- a/src/main/java/frc/robot/Constants.java +++ b/src/main/java/frc/robot/Constants.java @@ -4,6 +4,15 @@ package frc.robot; +import static edu.wpi.first.units.Units.Meters; + +import edu.wpi.first.units.measure.Distance; + public final class Constants { + public static class LedConstants { + public static final int kLedPort = 6; //PWM port on RoborIO + public static final int kLedLength = 60; //led count + public static final Distance kLedSpacing = Meters.of(1/ 60.0); // density of 120 LEDs per meter + } } diff --git a/src/main/java/frc/robot/RobotContainer.java b/src/main/java/frc/robot/RobotContainer.java index 20bd630..95567f9 100644 --- a/src/main/java/frc/robot/RobotContainer.java +++ b/src/main/java/frc/robot/RobotContainer.java @@ -4,13 +4,16 @@ package frc.robot; +import edu.wpi.first.wpilibj.util.Color; import edu.wpi.first.wpilibj2.command.Command; -import frc.kelrotlib.leds.Led; +import frc.robot.subsystems.LedSubsystem; public class RobotContainer { + private final LedSubsystem leds = new LedSubsystem(); + public RobotContainer() { - configureBindings(); + leds.setSolidColor(Color.kFirstBlue, new Integer[] {1}); } private void configureBindings() { diff --git a/src/main/java/frc/robot/subsystems/LedSubsystem.java b/src/main/java/frc/robot/subsystems/LedSubsystem.java index b036163..8c14452 100644 --- a/src/main/java/frc/robot/subsystems/LedSubsystem.java +++ b/src/main/java/frc/robot/subsystems/LedSubsystem.java @@ -5,16 +5,7 @@ public class LedSubsystem extends Led { /** Creates a new ExampleSubsystem. */ public LedSubsystem() { - + createGroup(0,29, 1); } - @Override - public void periodic() { - // This method will be called once per scheduler run - } - - @Override - public void simulationPeriodic() { - // This method will be called once per scheduler run during simulation - } } From d828bb3aa81d79a4d24d1c73f2ac8ddcf51f9cb7 Mon Sep 17 00:00:00 2001 From: elma Date: Wed, 13 Aug 2025 21:49:11 +0300 Subject: [PATCH 03/15] added second group --- src/main/java/frc/robot/subsystems/LedSubsystem.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/frc/robot/subsystems/LedSubsystem.java b/src/main/java/frc/robot/subsystems/LedSubsystem.java index 8c14452..4ac9a0d 100644 --- a/src/main/java/frc/robot/subsystems/LedSubsystem.java +++ b/src/main/java/frc/robot/subsystems/LedSubsystem.java @@ -6,6 +6,7 @@ public class LedSubsystem extends Led { /** Creates a new ExampleSubsystem. */ public LedSubsystem() { createGroup(0,29, 1); + createGroup(30,59,2); } } From a066ba8fd4ef9e838b83ba057a79948660314a91 Mon Sep 17 00:00:00 2001 From: recepsirin0 <159413980+recepsirin0@users.noreply.github.com> Date: Thu, 14 Aug 2025 15:39:21 +0300 Subject: [PATCH 04/15] Update Led.java --- src/main/java/frc/kelrotlib/leds/Led.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/frc/kelrotlib/leds/Led.java b/src/main/java/frc/kelrotlib/leds/Led.java index e3e197f..f73686b 100644 --- a/src/main/java/frc/kelrotlib/leds/Led.java +++ b/src/main/java/frc/kelrotlib/leds/Led.java @@ -14,7 +14,7 @@ import edu.wpi.first.wpilibj2.command.SubsystemBase; import frc.robot.Constants.LedConstants; -public class Led extends SubsystemBase{ //a Java inheritance example +public class Led extends SubsystemBase { //a Java inheritance example private AddressableLED m_led; private AddressableLEDBuffer m_buffer; private HashMap m_groupList; From bbccbf9e3643d4f04ff9f421a11ef209906cec61 Mon Sep 17 00:00:00 2001 From: recepsirin0 Date: Thu, 14 Aug 2025 18:08:00 +0300 Subject: [PATCH 05/15] Added Tunable Number class and logging something. --- simgui-ds.json | 92 +++++++++++++++++++ .../frc/kelrotlib/utils/TunableNumber.java | 73 +++++++++++++++ src/main/java/frc/robot/Constants.java | 13 +-- src/main/java/frc/robot/RobotContainer.java | 4 +- .../robot/subsystems/ExampleSubsystem.java | 3 + vendordeps/DogLog.json | 20 ++++ 6 files changed, 198 insertions(+), 7 deletions(-) create mode 100644 simgui-ds.json create mode 100644 src/main/java/frc/kelrotlib/utils/TunableNumber.java create mode 100644 vendordeps/DogLog.json diff --git a/simgui-ds.json b/simgui-ds.json new file mode 100644 index 0000000..73cc713 --- /dev/null +++ b/simgui-ds.json @@ -0,0 +1,92 @@ +{ + "keyboardJoysticks": [ + { + "axisConfig": [ + { + "decKey": 65, + "incKey": 68 + }, + { + "decKey": 87, + "incKey": 83 + }, + { + "decKey": 69, + "decayRate": 0.0, + "incKey": 82, + "keyRate": 0.009999999776482582 + } + ], + "axisCount": 3, + "buttonCount": 4, + "buttonKeys": [ + 90, + 88, + 67, + 86 + ], + "povConfig": [ + { + "key0": 328, + "key135": 323, + "key180": 322, + "key225": 321, + "key270": 324, + "key315": 327, + "key45": 329, + "key90": 326 + } + ], + "povCount": 1 + }, + { + "axisConfig": [ + { + "decKey": 74, + "incKey": 76 + }, + { + "decKey": 73, + "incKey": 75 + } + ], + "axisCount": 2, + "buttonCount": 4, + "buttonKeys": [ + 77, + 44, + 46, + 47 + ], + "povCount": 0 + }, + { + "axisConfig": [ + { + "decKey": 263, + "incKey": 262 + }, + { + "decKey": 265, + "incKey": 264 + } + ], + "axisCount": 2, + "buttonCount": 6, + "buttonKeys": [ + 260, + 268, + 266, + 261, + 269, + 267 + ], + "povCount": 0 + }, + { + "axisCount": 0, + "buttonCount": 0, + "povCount": 0 + } + ] +} diff --git a/src/main/java/frc/kelrotlib/utils/TunableNumber.java b/src/main/java/frc/kelrotlib/utils/TunableNumber.java new file mode 100644 index 0000000..6c8578a --- /dev/null +++ b/src/main/java/frc/kelrotlib/utils/TunableNumber.java @@ -0,0 +1,73 @@ +package frc.kelrotlib.utils; + +import edu.wpi.first.networktables.*; +import dev.doglog.DogLog; + +import java.util.EnumSet; +import java.util.function.Consumer; + +public class TunableNumber { + private final NetworkTableEntry entry; + private double lastValue; + private NetworkTableInstance inst = NetworkTableInstance.getDefault(); + + + /** + * @param key + * @param defaultValue + * @param onChange + */ + public TunableNumber(String key, double defaultValue, Consumer onChange) { + this.lastValue = defaultValue; + entry = NetworkTableInstance.getDefault() + .getTable("SmartDashboard") + .getEntry("/Tuning" + "/" + key); + + entry.setDouble(defaultValue); + +inst.addListener( + entry, + EnumSet.of(NetworkTableEvent.Kind.kValueAll), + event -> { + double newValue = entry.getDouble(lastValue); + if(this.lastValue != newValue) { + DogLog.log("/Tuning" + "/" + key, entry.getDouble(lastValue)); + System.out.println(newValue); + this.lastValue = newValue; + onChange.accept(lastValue); + } + }); + } + + /** + * @param key + * @param defaultValue + * @param onChange + */ + public TunableNumber(String key, double defaultValue) { + this.lastValue = defaultValue; + entry = NetworkTableInstance.getDefault() + .getTable("SmartDashboard") + .getEntry("/Tuning" + "/" + key); + + entry.setDouble(defaultValue); + + inst.addListener( + entry, + EnumSet.of(NetworkTableEvent.Kind.kValueAll), + event -> { + double newValue = entry.getDouble(lastValue); + if(this.lastValue != newValue) { + DogLog.log("/Tuning" + "/" + key, entry.getDouble(lastValue)); + System.out.println(newValue); + this.lastValue = newValue; + } + }); + + } + + /** Şu an dashboard’daki güncel değeri döner */ + public double get() { + return entry.getDouble(lastValue); + } +} diff --git a/src/main/java/frc/robot/Constants.java b/src/main/java/frc/robot/Constants.java index eef6ae4..6a2c6b8 100644 --- a/src/main/java/frc/robot/Constants.java +++ b/src/main/java/frc/robot/Constants.java @@ -9,10 +9,11 @@ import edu.wpi.first.units.measure.Distance; public final class Constants { - public static class LedConstants { - public static final int kLedPort = 6; //PWM port on RoborIO - public static final int kLedLength = 60; //led count - public static final Distance kLedSpacing = Meters.of(1/ 60.0); // density of 120 LEDs per meter - } - + public static boolean tuningMode = false; + public static class LedConstants { + public static final int kLedPort = 6; // PWM port on RoborIO + public static final int kLedLength = 60; // led count + public static final Distance kLedSpacing = Meters.of(1 / 60.0); // density of 120 LEDs per meter + } + } diff --git a/src/main/java/frc/robot/RobotContainer.java b/src/main/java/frc/robot/RobotContainer.java index 95567f9..39b7954 100644 --- a/src/main/java/frc/robot/RobotContainer.java +++ b/src/main/java/frc/robot/RobotContainer.java @@ -6,11 +6,13 @@ import edu.wpi.first.wpilibj.util.Color; import edu.wpi.first.wpilibj2.command.Command; +import frc.kelrotlib.utils.TunableNumber; +import frc.robot.subsystems.ExampleSubsystem; import frc.robot.subsystems.LedSubsystem; public class RobotContainer { private final LedSubsystem leds = new LedSubsystem(); - + private final ExampleSubsystem example = new ExampleSubsystem(); public RobotContainer() { configureBindings(); leds.setSolidColor(Color.kFirstBlue, new Integer[] {1}); diff --git a/src/main/java/frc/robot/subsystems/ExampleSubsystem.java b/src/main/java/frc/robot/subsystems/ExampleSubsystem.java index 0c013ba..d1d5279 100644 --- a/src/main/java/frc/robot/subsystems/ExampleSubsystem.java +++ b/src/main/java/frc/robot/subsystems/ExampleSubsystem.java @@ -1,8 +1,11 @@ package frc.robot.subsystems; import edu.wpi.first.wpilibj2.command.SubsystemBase; +import frc.kelrotlib.utils.TunableNumber; public class ExampleSubsystem extends SubsystemBase { + + private final TunableNumber newnumber = new TunableNumber("sa", 0); /** Creates a new ExampleSubsystem. */ public ExampleSubsystem() { diff --git a/vendordeps/DogLog.json b/vendordeps/DogLog.json new file mode 100644 index 0000000..2ee13f6 --- /dev/null +++ b/vendordeps/DogLog.json @@ -0,0 +1,20 @@ +{ + "javaDependencies": [ + { + "groupId": "com.github.jonahsnider", + "artifactId": "doglog", + "version": "2025.8.1" + } + ], + "fileName": "DogLog.json", + "frcYear": "2025", + "jsonUrl": "https://doglog.dev/vendordep.json", + "name": "DogLog", + "jniDependencies": [], + "mavenUrls": [ + "https://jitpack.io" + ], + "cppDependencies": [], + "version": "2025.8.1", + "uuid": "65592ce1-2251-4a31-8e4b-2df20dacebe4" +} \ No newline at end of file From a9c6743c681b8d7c8b3a48bf58f3d915ace0bd62 Mon Sep 17 00:00:00 2001 From: EgeCmnn Date: Thu, 14 Aug 2025 18:20:16 +0300 Subject: [PATCH 06/15] update --- src/main/java/frc/kelrotlib/utils/TunableNumber.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/frc/kelrotlib/utils/TunableNumber.java b/src/main/java/frc/kelrotlib/utils/TunableNumber.java index 6c8578a..ec4d349 100644 --- a/src/main/java/frc/kelrotlib/utils/TunableNumber.java +++ b/src/main/java/frc/kelrotlib/utils/TunableNumber.java @@ -1,3 +1,4 @@ +//hellooo package frc.kelrotlib.utils; import edu.wpi.first.networktables.*; From 29f63645b344a22abd50f9ea8e7774462d67a9a3 Mon Sep 17 00:00:00 2001 From: recepsirin0 Date: Thu, 14 Aug 2025 18:51:18 +0300 Subject: [PATCH 07/15] Fixed the values when tuningMode is off. --- src/main/java/frc/kelrotlib/utils/TunableNumber.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/frc/kelrotlib/utils/TunableNumber.java b/src/main/java/frc/kelrotlib/utils/TunableNumber.java index ec4d349..efb3a6d 100644 --- a/src/main/java/frc/kelrotlib/utils/TunableNumber.java +++ b/src/main/java/frc/kelrotlib/utils/TunableNumber.java @@ -1,7 +1,7 @@ -//hellooo package frc.kelrotlib.utils; import edu.wpi.first.networktables.*; +import frc.robot.Constants; import dev.doglog.DogLog; import java.util.EnumSet; @@ -13,7 +13,7 @@ public class TunableNumber { private NetworkTableInstance inst = NetworkTableInstance.getDefault(); - /** + /** * @param key * @param defaultValue * @param onChange @@ -31,7 +31,7 @@ public TunableNumber(String key, double defaultValue, Consumer onChange) EnumSet.of(NetworkTableEvent.Kind.kValueAll), event -> { double newValue = entry.getDouble(lastValue); - if(this.lastValue != newValue) { + if(this.lastValue != newValue && Constants.tuningMode) { DogLog.log("/Tuning" + "/" + key, entry.getDouble(lastValue)); System.out.println(newValue); this.lastValue = newValue; @@ -58,7 +58,7 @@ public TunableNumber(String key, double defaultValue) { EnumSet.of(NetworkTableEvent.Kind.kValueAll), event -> { double newValue = entry.getDouble(lastValue); - if(this.lastValue != newValue) { + if(this.lastValue != newValue && Constants.tuningMode) { DogLog.log("/Tuning" + "/" + key, entry.getDouble(lastValue)); System.out.println(newValue); this.lastValue = newValue; @@ -67,8 +67,8 @@ public TunableNumber(String key, double defaultValue) { } - /** Şu an dashboard’daki güncel değeri döner */ + /* Return last value on the dashboard */ public double get() { - return entry.getDouble(lastValue); + return lastValue; } } From b4420e4fe4a4da9ad491084098ee32ef5233231a Mon Sep 17 00:00:00 2001 From: recepsirin0 Date: Thu, 14 Aug 2025 19:21:55 +0300 Subject: [PATCH 08/15] Added Constants, tested and added usage examples. --- src/main/java/frc/robot/Constants.java | 2 +- src/main/java/frc/robot/RobotContainer.java | 3 ++- .../robot/subsystems/ExampleSubsystem.java | 2 +- .../subsystems/TunableNumberExample.java | 27 +++++++++++++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 src/main/java/frc/robot/subsystems/TunableNumberExample.java diff --git a/src/main/java/frc/robot/Constants.java b/src/main/java/frc/robot/Constants.java index 6a2c6b8..576367a 100644 --- a/src/main/java/frc/robot/Constants.java +++ b/src/main/java/frc/robot/Constants.java @@ -9,7 +9,7 @@ import edu.wpi.first.units.measure.Distance; public final class Constants { - public static boolean tuningMode = false; + public static boolean tuningMode = true; public static class LedConstants { public static final int kLedPort = 6; // PWM port on RoborIO public static final int kLedLength = 60; // led count diff --git a/src/main/java/frc/robot/RobotContainer.java b/src/main/java/frc/robot/RobotContainer.java index 39b7954..0081c59 100644 --- a/src/main/java/frc/robot/RobotContainer.java +++ b/src/main/java/frc/robot/RobotContainer.java @@ -9,10 +9,11 @@ import frc.kelrotlib.utils.TunableNumber; import frc.robot.subsystems.ExampleSubsystem; import frc.robot.subsystems.LedSubsystem; +import frc.robot.subsystems.TunableNumberExample; public class RobotContainer { private final LedSubsystem leds = new LedSubsystem(); - private final ExampleSubsystem example = new ExampleSubsystem(); + private final TunableNumberExample example = new TunableNumberExample(); public RobotContainer() { configureBindings(); leds.setSolidColor(Color.kFirstBlue, new Integer[] {1}); diff --git a/src/main/java/frc/robot/subsystems/ExampleSubsystem.java b/src/main/java/frc/robot/subsystems/ExampleSubsystem.java index d1d5279..be79a90 100644 --- a/src/main/java/frc/robot/subsystems/ExampleSubsystem.java +++ b/src/main/java/frc/robot/subsystems/ExampleSubsystem.java @@ -5,7 +5,7 @@ public class ExampleSubsystem extends SubsystemBase { - private final TunableNumber newnumber = new TunableNumber("sa", 0); + /** Creates a new ExampleSubsystem. */ public ExampleSubsystem() { diff --git a/src/main/java/frc/robot/subsystems/TunableNumberExample.java b/src/main/java/frc/robot/subsystems/TunableNumberExample.java new file mode 100644 index 0000000..2888581 --- /dev/null +++ b/src/main/java/frc/robot/subsystems/TunableNumberExample.java @@ -0,0 +1,27 @@ +package frc.robot.subsystems; + +import edu.wpi.first.wpilibj2.command.SubsystemBase; +import frc.kelrotlib.utils.TunableNumber; + +public class TunableNumberExample extends SubsystemBase { + + private final TunableNumber newnumber = new TunableNumber("sa", 0); + + private final TunableNumber newnumber2 = new TunableNumber("test2", 0, value -> { + System.out.println("Tunable Number is changed, new number is" + value); + }); + /** Creates a new ExampleSubsystem. */ + public TunableNumberExample() { + + } + + @Override + public void periodic() { + // This method will be called once per scheduler run + } + + @Override + public void simulationPeriodic() { + // This method will be called once per scheduler run during simulation + } +} From 5ce1d25438f17466a7c8ea64444d5ab32e9dcd2a Mon Sep 17 00:00:00 2001 From: recepsirin0 Date: Thu, 14 Aug 2025 19:27:30 +0300 Subject: [PATCH 09/15] Fixed the values when tuningMode is on. --- src/main/java/frc/kelrotlib/utils/TunableNumber.java | 4 ++++ src/main/java/frc/robot/subsystems/TunableNumberExample.java | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/main/java/frc/kelrotlib/utils/TunableNumber.java b/src/main/java/frc/kelrotlib/utils/TunableNumber.java index efb3a6d..b806019 100644 --- a/src/main/java/frc/kelrotlib/utils/TunableNumber.java +++ b/src/main/java/frc/kelrotlib/utils/TunableNumber.java @@ -36,6 +36,8 @@ public TunableNumber(String key, double defaultValue, Consumer onChange) System.out.println(newValue); this.lastValue = newValue; onChange.accept(lastValue); + } else { + entry.setDouble(this.lastValue); } }); } @@ -62,6 +64,8 @@ public TunableNumber(String key, double defaultValue) { DogLog.log("/Tuning" + "/" + key, entry.getDouble(lastValue)); System.out.println(newValue); this.lastValue = newValue; + } else { + entry.setDouble(this.lastValue); } }); diff --git a/src/main/java/frc/robot/subsystems/TunableNumberExample.java b/src/main/java/frc/robot/subsystems/TunableNumberExample.java index 2888581..961a311 100644 --- a/src/main/java/frc/robot/subsystems/TunableNumberExample.java +++ b/src/main/java/frc/robot/subsystems/TunableNumberExample.java @@ -9,6 +9,9 @@ public class TunableNumberExample extends SubsystemBase { private final TunableNumber newnumber2 = new TunableNumber("test2", 0, value -> { System.out.println("Tunable Number is changed, new number is" + value); + + // Usage is not like motor.setVoltage(newnumber) + // You should motor.setVoltage(newnumber.get()) }); /** Creates a new ExampleSubsystem. */ public TunableNumberExample() { From 5347d73844c5e7d415b42f3d0a3ce5db8669a638 Mon Sep 17 00:00:00 2001 From: recepsirin0 Date: Thu, 14 Aug 2025 19:27:51 +0300 Subject: [PATCH 10/15] Minimal variable changes. --- src/main/java/frc/robot/Constants.java | 2 +- src/main/java/frc/robot/RobotContainer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/frc/robot/Constants.java b/src/main/java/frc/robot/Constants.java index 576367a..6a2c6b8 100644 --- a/src/main/java/frc/robot/Constants.java +++ b/src/main/java/frc/robot/Constants.java @@ -9,7 +9,7 @@ import edu.wpi.first.units.measure.Distance; public final class Constants { - public static boolean tuningMode = true; + public static boolean tuningMode = false; public static class LedConstants { public static final int kLedPort = 6; // PWM port on RoborIO public static final int kLedLength = 60; // led count diff --git a/src/main/java/frc/robot/RobotContainer.java b/src/main/java/frc/robot/RobotContainer.java index 0081c59..299d334 100644 --- a/src/main/java/frc/robot/RobotContainer.java +++ b/src/main/java/frc/robot/RobotContainer.java @@ -13,7 +13,7 @@ public class RobotContainer { private final LedSubsystem leds = new LedSubsystem(); - private final TunableNumberExample example = new TunableNumberExample(); + private final TunableNumberExample yTunableNumberExample = new TunableNumberExample(); public RobotContainer() { configureBindings(); leds.setSolidColor(Color.kFirstBlue, new Integer[] {1}); From 4877426cef54a34cb5fa1242b8e7f966cafa7a09 Mon Sep 17 00:00:00 2001 From: recepsirin0 Date: Thu, 14 Aug 2025 19:29:40 +0300 Subject: [PATCH 11/15] Added descriptive comments --- .../frc/kelrotlib/utils/TunableNumber.java | 85 +++++++++++-------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/src/main/java/frc/kelrotlib/utils/TunableNumber.java b/src/main/java/frc/kelrotlib/utils/TunableNumber.java index b806019..c2b6002 100644 --- a/src/main/java/frc/kelrotlib/utils/TunableNumber.java +++ b/src/main/java/frc/kelrotlib/utils/TunableNumber.java @@ -14,64 +14,81 @@ public class TunableNumber { /** - * @param key - * @param defaultValue - * @param onChange + * Constructor with onChange callback + * @param key The name of the tunable value + * @param defaultValue The default value if not set on the dashboard + * @param onChange A callback that runs whenever the value changes */ public TunableNumber(String key, double defaultValue, Consumer onChange) { this.lastValue = defaultValue; + + // Get or create the NetworkTable entry for this tunable number entry = NetworkTableInstance.getDefault() .getTable("SmartDashboard") .getEntry("/Tuning" + "/" + key); + // Set the initial value on the dashboard entry.setDouble(defaultValue); -inst.addListener( - entry, - EnumSet.of(NetworkTableEvent.Kind.kValueAll), - event -> { - double newValue = entry.getDouble(lastValue); - if(this.lastValue != newValue && Constants.tuningMode) { - DogLog.log("/Tuning" + "/" + key, entry.getDouble(lastValue)); - System.out.println(newValue); - this.lastValue = newValue; - onChange.accept(lastValue); - } else { - entry.setDouble(this.lastValue); - } - }); + // Add a listener to detect changes in the entry + inst.addListener( + entry, + EnumSet.of(NetworkTableEvent.Kind.kValueAll), + event -> { + double newValue = entry.getDouble(lastValue); + + // If the value changed and tuningMode is ON, accept the change + if(this.lastValue != newValue && Constants.tuningMode) { + DogLog.log("/Tuning" + "/" + key, entry.getDouble(lastValue)); + System.out.println(newValue); + this.lastValue = newValue; + onChange.accept(lastValue); // call the callback + } else { + // Otherwise, reset the value to the last known value + entry.setDouble(this.lastValue); + } + }); } /** - * @param key - * @param defaultValue - * @param onChange + * Constructor without onChange callback + * @param key The name of the tunable value + * @param defaultValue The default value if not set on the dashboard */ public TunableNumber(String key, double defaultValue) { this.lastValue = defaultValue; + + // Get or create the NetworkTable entry for this tunable number entry = NetworkTableInstance.getDefault() .getTable("SmartDashboard") .getEntry("/Tuning" + "/" + key); + // Set the initial value on the dashboard entry.setDouble(defaultValue); - + + // Add a listener to detect changes in the entry inst.addListener( - entry, - EnumSet.of(NetworkTableEvent.Kind.kValueAll), - event -> { - double newValue = entry.getDouble(lastValue); - if(this.lastValue != newValue && Constants.tuningMode) { - DogLog.log("/Tuning" + "/" + key, entry.getDouble(lastValue)); - System.out.println(newValue); - this.lastValue = newValue; - } else { - entry.setDouble(this.lastValue); - } - }); + entry, + EnumSet.of(NetworkTableEvent.Kind.kValueAll), + event -> { + double newValue = entry.getDouble(lastValue); + // If the value changed and tuningMode is ON, accept the change + if(this.lastValue != newValue && Constants.tuningMode) { + DogLog.log("/Tuning" + "/" + key, entry.getDouble(lastValue)); + System.out.println(newValue); + this.lastValue = newValue; + } else { + // Otherwise, reset the value to the last known value + entry.setDouble(this.lastValue); + } + }); } - /* Return last value on the dashboard */ + /* + * Return the current value of this tunable number + * This always returns the last accepted value + */ public double get() { return lastValue; } From 32ea108a0a533838f25843232a6ce4b0d6f1ac32 Mon Sep 17 00:00:00 2001 From: recepsirin0 Date: Sat, 16 Aug 2025 21:14:26 +0300 Subject: [PATCH 12/15] removed led files --- src/main/java/frc/kelrotlib/leds/Led.java | 94 ------------------- src/main/java/frc/robot/Constants.java | 6 -- src/main/java/frc/robot/RobotContainer.java | 3 - .../frc/robot/subsystems/LedSubsystem.java | 12 --- 4 files changed, 115 deletions(-) delete mode 100644 src/main/java/frc/kelrotlib/leds/Led.java delete mode 100644 src/main/java/frc/robot/subsystems/LedSubsystem.java diff --git a/src/main/java/frc/kelrotlib/leds/Led.java b/src/main/java/frc/kelrotlib/leds/Led.java deleted file mode 100644 index f73686b..0000000 --- a/src/main/java/frc/kelrotlib/leds/Led.java +++ /dev/null @@ -1,94 +0,0 @@ -package frc.kelrotlib.leds; - -import static edu.wpi.first.units.Units.MetersPerSecond; -import static edu.wpi.first.units.Units.Seconds; - -import java.util.HashMap; - -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.wpilibj.util.Color; -import edu.wpi.first.wpilibj2.command.Command; -import edu.wpi.first.wpilibj2.command.SubsystemBase; -import frc.robot.Constants.LedConstants; - -public class Led extends SubsystemBase { //a Java inheritance example - private AddressableLED m_led; - private AddressableLEDBuffer m_buffer; - private HashMap m_groupList; - private HashMap m_patternList; - private LEDPattern k_defaultPattern = LEDPattern.solid(Color.kBlack); - - public Led() { - m_led = new AddressableLED(LedConstants.kLedPort); //every variable you might change later (ports, length etc.) should be added to Constants.java* - m_buffer = new AddressableLEDBuffer(LedConstants.kLedLength); // * this way every port and important variable is in one place. - m_led.setLength(LedConstants.kLedLength); //setting the length takes a lot of load so do it only one time when possible - m_led.start(); - - m_groupList = new HashMap(); //I decided to use Integers for the keys as it is much more straight-forward, in future uses the keys can be String's for more complicated group identification needs. - m_patternList = new HashMap(); //For this version of grouping we need to store previous patterns for each group - - setDefaultCommand(runPattern(k_defaultPattern).withName("Off")); //set all leds to off/black on start - } - - public void createGroup(int startingIndex, int endingIndex, Integer groupID) { //infinite amount of groups creatable, without complicating the code - AddressableLEDBufferView group = m_buffer.createView(startingIndex, endingIndex); //create new group(view) - m_groupList.put(groupID, group); - m_patternList.put(groupID, k_defaultPattern); //initially set the defaultPattern, so the runPattern command doesn't break - } - - public void setSolidColor(Color color, Integer[] groupIDs){ - LEDPattern solidColorPattern = LEDPattern.solid(color); - for (int i = 0; i < groupIDs.length; i++) { //update the latest pattern for every LED group given - m_patternList.replace(groupIDs[i], solidColorPattern); //I love hashmap it is just so cool - } - runPattern(); - } - - public void setBlinkColor(Color color, double interval, Integer[] groupIDs){ - LEDPattern base = LEDPattern.solid(color); - LEDPattern blinkPattern = base.blink(Seconds.of(interval)); //synchronised blink, wpilib also has support for asynchronised blink - for (int i = 0; i < groupIDs.length; i++) { - m_patternList.replace(groupIDs[i], blinkPattern); - } - runPattern(); - } - - public void rainbow(Integer[] groupIDs){ - LEDPattern rainbow = LEDPattern.rainbow(255, 128); //all hues at maximum saturation and *half* brightness - LEDPattern scrollingRainbow = rainbow.scrollAtAbsoluteSpeed(MetersPerSecond.of(1), LedConstants.kLedSpacing); //moves/scrolls the effect at a speed of 1 meter per second - for (int i = 0; i < groupIDs.length; i++) { - m_patternList.replace(groupIDs[i], scrollingRainbow); - } - runPattern(); - } - - public void turnOff(){ - runPattern(k_defaultPattern); - } - - public Command runPattern(){ //A command is used as it doesn't allow actions to run simultaneously, for this usage it is crucial, because we need to stop the previous patterns and start the new ones. - return run(() -> { - for (Integer i : m_groupList.keySet()) { //parsing through every key in the groupList HashMap - m_patternList.get(i).applyTo(m_groupList.get(i)); //getting every setted pattern and applying it to the ID'd LED Group - } - }); - } - - public Command runPattern(LEDPattern pattern) { //might get removed later. - return run(() -> { - pattern.applyTo(m_buffer); - }); - } - - @Override - public void periodic() { //update the data every 20ms - m_led.setData(m_buffer); - } - - @Override - public void simulationPeriodic() { - } -} diff --git a/src/main/java/frc/robot/Constants.java b/src/main/java/frc/robot/Constants.java index 6a2c6b8..94461c8 100644 --- a/src/main/java/frc/robot/Constants.java +++ b/src/main/java/frc/robot/Constants.java @@ -10,10 +10,4 @@ public final class Constants { public static boolean tuningMode = false; - public static class LedConstants { - public static final int kLedPort = 6; // PWM port on RoborIO - public static final int kLedLength = 60; // led count - public static final Distance kLedSpacing = Meters.of(1 / 60.0); // density of 120 LEDs per meter - } - } diff --git a/src/main/java/frc/robot/RobotContainer.java b/src/main/java/frc/robot/RobotContainer.java index 299d334..e5bd595 100644 --- a/src/main/java/frc/robot/RobotContainer.java +++ b/src/main/java/frc/robot/RobotContainer.java @@ -11,12 +11,9 @@ import frc.robot.subsystems.LedSubsystem; import frc.robot.subsystems.TunableNumberExample; public class RobotContainer { - - private final LedSubsystem leds = new LedSubsystem(); private final TunableNumberExample yTunableNumberExample = new TunableNumberExample(); public RobotContainer() { configureBindings(); - leds.setSolidColor(Color.kFirstBlue, new Integer[] {1}); } private void configureBindings() { diff --git a/src/main/java/frc/robot/subsystems/LedSubsystem.java b/src/main/java/frc/robot/subsystems/LedSubsystem.java deleted file mode 100644 index 4ac9a0d..0000000 --- a/src/main/java/frc/robot/subsystems/LedSubsystem.java +++ /dev/null @@ -1,12 +0,0 @@ -package frc.robot.subsystems; - -import frc.kelrotlib.leds.Led; - -public class LedSubsystem extends Led { - /** Creates a new ExampleSubsystem. */ - public LedSubsystem() { - createGroup(0,29, 1); - createGroup(30,59,2); - } - -} From cdb940b57213535c45979b68d707bbb0e77ab0f1 Mon Sep 17 00:00:00 2001 From: recepsirin0 Date: Sat, 16 Aug 2025 22:02:48 +0300 Subject: [PATCH 13/15] fix --- src/main/java/frc/robot/RobotContainer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/frc/robot/RobotContainer.java b/src/main/java/frc/robot/RobotContainer.java index e5bd595..6a4930e 100644 --- a/src/main/java/frc/robot/RobotContainer.java +++ b/src/main/java/frc/robot/RobotContainer.java @@ -8,7 +8,6 @@ import edu.wpi.first.wpilibj2.command.Command; import frc.kelrotlib.utils.TunableNumber; import frc.robot.subsystems.ExampleSubsystem; -import frc.robot.subsystems.LedSubsystem; import frc.robot.subsystems.TunableNumberExample; public class RobotContainer { private final TunableNumberExample yTunableNumberExample = new TunableNumberExample(); From e38ea33e9471abcc2e819ac731415403c3e964ae Mon Sep 17 00:00:00 2001 From: recepsirin0 Date: Thu, 13 Nov 2025 16:42:57 +0300 Subject: [PATCH 14/15] unimportant lines deleted --- src/main/java/frc/kelrotlib/utils/TunableNumber.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/frc/kelrotlib/utils/TunableNumber.java b/src/main/java/frc/kelrotlib/utils/TunableNumber.java index c2b6002..543abce 100644 --- a/src/main/java/frc/kelrotlib/utils/TunableNumber.java +++ b/src/main/java/frc/kelrotlib/utils/TunableNumber.java @@ -40,7 +40,6 @@ public TunableNumber(String key, double defaultValue, Consumer onChange) // If the value changed and tuningMode is ON, accept the change if(this.lastValue != newValue && Constants.tuningMode) { DogLog.log("/Tuning" + "/" + key, entry.getDouble(lastValue)); - System.out.println(newValue); this.lastValue = newValue; onChange.accept(lastValue); // call the callback } else { @@ -76,7 +75,6 @@ public TunableNumber(String key, double defaultValue) { // If the value changed and tuningMode is ON, accept the change if(this.lastValue != newValue && Constants.tuningMode) { DogLog.log("/Tuning" + "/" + key, entry.getDouble(lastValue)); - System.out.println(newValue); this.lastValue = newValue; } else { // Otherwise, reset the value to the last known value From 14216cb2db08f20b370d41ecfd8eb32c1a29e301 Mon Sep 17 00:00:00 2001 From: recepsirin0 Date: Thu, 13 Nov 2025 17:33:35 +0300 Subject: [PATCH 15/15] unnecessary import deleted --- src/main/java/frc/robot/subsystems/ExampleSubsystem.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/frc/robot/subsystems/ExampleSubsystem.java b/src/main/java/frc/robot/subsystems/ExampleSubsystem.java index be79a90..8331a42 100644 --- a/src/main/java/frc/robot/subsystems/ExampleSubsystem.java +++ b/src/main/java/frc/robot/subsystems/ExampleSubsystem.java @@ -1,12 +1,11 @@ package frc.robot.subsystems; import edu.wpi.first.wpilibj2.command.SubsystemBase; -import frc.kelrotlib.utils.TunableNumber; public class ExampleSubsystem extends SubsystemBase { - /** Creates a new ExampleSubsystem. */ + /* Creates a new ExampleSubsystem. */ public ExampleSubsystem() { }