Interface LEDPattern
- Functional Interface:
- This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
WPIUtilJNI.now()
is recommended, since it can be mocked in simulation and unit tests), or on
some other dynamic input (see synchronizedBlink(BooleanSupplier)
, for example).
Patterns should be updated periodically in order for animations to play smoothly. For example,
a hypothetical LED subsystem could create a Command
that will continuously apply the
pattern to its LED data buffer as part of the main periodic loop.
public class LEDs extends SubsystemBase {
private final AddressableLED m_led = new AddressableLED(0);
private final AddressableLEDBuffer m_ledData = new AddressableLEDBuffer(120);
public LEDs() {
m_led.setLength(120);
m_led.start();
}
@Override
public void periodic() {
m_led.writeData(m_ledData);
}
public Command runPattern(LEDPattern pattern) {
return run(() -> pattern.applyTo(m_ledData));
}
}
LED patterns are stateless, and as such can be applied to multiple LED strips (or different sections of the same LED strip, since the roboRIO can only drive a single LED strip). In this example, we split the single buffer into two views - one for the section of the LED strip on the left side of a robot, and another view for the section of LEDs on the right side. The same pattern is able to be applied to both sides.
public class LEDs extends SubsystemBase {
private final AddressableLED m_led = new AddressableLED(0);
private final AddressableLEDBuffer m_ledData = new AddressableLEDBuffer(60);
private final AddressableLEDBufferView m_leftData = m_ledData.createView(0, 29);
private final AddressableLEDBufferView m_rightData = m_ledData.createView(30, 59).reversed();
public LEDs() {
m_led.setLength(60);
m_led.start();
}
@Override
public void periodic() {
m_led.writeData(m_ledData);
}
public Command runPattern(LEDPattern pattern) {
// Use the single input pattern to drive both sides
return runSplitPatterns(pattern, pattern);
}
public Command runSplitPatterns(LEDPattern left, LEDPattern right) {
return run(() -> {
left.applyTo(m_leftData);
right.applyTo(m_rightData);
});
}
}
-
Nested Class Summary
Modifier and TypeInterfaceDescriptionstatic enum
Types of gradients.static interface
A functional interface for index mapping functions. -
Field Summary
-
Method Summary
Modifier and TypeMethodDescriptionvoid
Writes the pattern to an LED buffer.applyTo
(T readWriter) Convenience forapplyTo(LEDReader, LEDWriter)
when one object provides both a read and a write interface.default LEDPattern
atBrightness
(Dimensionless relativeBrightness) Creates a pattern that plays this one, but at a different brightness.default LEDPattern
blend
(LEDPattern other) Creates a pattern that displays outputs as a combination of this pattern and another.default LEDPattern
Likeblink(onTime, offTime)
, but where the "off" time is exactly equal to the "on" time.default LEDPattern
Creates a pattern that switches between playing this pattern and turning the entire LED strip off.default LEDPattern
Creates a pattern that brightens and dims this one over time.static LEDPattern
gradient
(LEDPattern.GradientType type, Color... colors) Creates a pattern that displays a non-animated gradient of colors across the entire length of the LED strip.default LEDPattern
mapIndex
(LEDPattern.IndexMapper indexMapper) Creates a pattern with remapped indices.default LEDPattern
mask
(LEDPattern mask) Similar toblend(LEDPattern)
, but performs a bitwise mask on each color channel rather than averaging the colors for each LED.default LEDPattern
offsetBy
(int offset) Creates a pattern that plays this one, but offset by a certain number of LEDs.default LEDPattern
overlayOn
(LEDPattern base) Creates a pattern that plays this pattern overlaid on another.static LEDPattern
progressMaskLayer
(DoubleSupplier progressSupplier) Creates a pattern that works as a mask layer formask(LEDPattern)
that illuminates only the portion of the LED strip corresponding with some progress.static LEDPattern
rainbow
(int saturation, int value) Creates an LED pattern that displays a rainbow across the color wheel.default LEDPattern
reversed()
Creates a pattern that displays this one in reverse.default LEDPattern
scrollAtAbsoluteSpeed
(LinearVelocity velocity, Distance ledSpacing) Creates a pattern that plays this one scrolling up an LED strip.default LEDPattern
scrollAtRelativeSpeed
(Frequency velocity) Creates a pattern that plays this one scrolling up the buffer.static LEDPattern
Creates a pattern that displays a single static color along the entire length of the LED strip.static LEDPattern
Display a set of colors in steps across the length of the LED strip.default LEDPattern
synchronizedBlink
(BooleanSupplier signal) Creates a pattern that blinks this one on and off in sync with a true/false signal.
-
Field Details
-
kOff
A pattern that turns off all LEDs.
-
-
Method Details
-
applyTo
Writes the pattern to an LED buffer. Dynamic animations should be called periodically (such as with a command or with a periodic method) to refresh the buffer over time.This method is intentionally designed to use separate objects for reading and writing data. By splitting them up, we can easily modify the behavior of some base pattern to make it
scroll
,blink
, orbreathe
by intercepting the data writes to transform their behavior to whatever we like.- Parameters:
reader
- data reader for accessing buffer length and current colorswriter
- data writer for setting new LED colors on the buffer
-
applyTo
Convenience forapplyTo(LEDReader, LEDWriter)
when one object provides both a read and a write interface. This is most helpful for playing an animated pattern directly on anAddressableLEDBuffer
for the sake of code clarity.AddressableLEDBuffer data = new AddressableLEDBuffer(120); LEDPattern pattern = ... void periodic() { pattern.applyTo(data); }
- Type Parameters:
T
- the type of the object that can both read and write LED data- Parameters:
readWriter
- the object to use for both reading and writing to a set of LEDs
-
mapIndex
Creates a pattern with remapped indices.- Parameters:
indexMapper
- the index mapper- Returns:
- the mapped pattern
-
reversed
Creates a pattern that displays this one in reverse. Scrolling patterns will scroll in the opposite direction (but at the same speed). It will treat the end of an LED strip as the start, and the start of the strip as the end. This can be useful for making ping-pong patterns that travel from one end of an LED strip to the other, then reverse direction and move back to the start. This can also be useful when working with LED strips connected in a serpentine pattern (where the start of one strip is connected to the end of the previous one); however, consider using areversed view
of the overall buffer for that segment rather than reversing patterns.- Returns:
- the reverse pattern
- See Also:
-
offsetBy
Creates a pattern that plays this one, but offset by a certain number of LEDs. The offset pattern will wrap around, if necessary.- Parameters:
offset
- how many LEDs to offset by- Returns:
- the offset pattern
-
scrollAtRelativeSpeed
Creates a pattern that plays this one scrolling up the buffer. The velocity controls how fast the pattern returns back to its original position, and is in terms of the length of the LED strip; scrolling across a segment that is 10 LEDs long will travel twice as fast as on a segment that's only 5 LEDs long (assuming equal LED density on both segments).For example, scrolling a pattern by one quarter of any LED strip's length per second, regardless of the total number of LEDs on that strip:
LEDPattern rainbow = LEDPattern.rainbow(255, 255); LEDPattern scrollingRainbow = rainbow.scrollAtRelativeSpeed(Percent.per(Second).of(25));
- Parameters:
velocity
- how fast the pattern should move, in terms of how long it takes to do a full scroll along the length of LEDs and return back to the starting position- Returns:
- the scrolling pattern
-
scrollAtAbsoluteSpeed
Creates a pattern that plays this one scrolling up an LED strip. A negative velocity makes the pattern play in reverse.For example, scrolling a pattern at 4 inches per second along an LED strip with 60 LEDs per meter:
// LEDs per meter, a known value taken from the spec sheet of our particular LED strip Distance LED_SPACING = Meters.of(1.0 / 60); LEDPattern rainbow = LEDPattern.rainbow(); LEDPattern scrollingRainbow = rainbow.scrollAtAbsoluteSpeed(InchesPerSecond.of(4), LED_SPACING);
Note that this pattern will scroll faster if applied to a less dense LED strip (such as 30 LEDs per meter), or slower if applied to a denser LED strip (such as 120 or 144 LEDs per meter).
- Parameters:
velocity
- how fast the pattern should move along a physical LED stripledSpacing
- the distance between adjacent LEDs on the physical LED strip- Returns:
- the scrolling pattern
-
blink
Creates a pattern that switches between playing this pattern and turning the entire LED strip off.- Parameters:
onTime
- how long the pattern should play for, per cycleoffTime
- how long the pattern should be turned off for, per cycle- Returns:
- the blinking pattern
-
blink
Likeblink(onTime, offTime)
, but where the "off" time is exactly equal to the "on" time.- Parameters:
onTime
- how long the pattern should play for (and be turned off for), per cycle- Returns:
- the blinking pattern
-
synchronizedBlink
Creates a pattern that blinks this one on and off in sync with a true/false signal. The pattern will play while the signal outputstrue
, and will turn off while the signal outputsfalse
.- Parameters:
signal
- the signal to synchronize with- Returns:
- the blinking pattern
-
breathe
Creates a pattern that brightens and dims this one over time. Brightness follows a sinusoidal pattern.- Parameters:
period
- how fast the breathing pattern should complete a single cycle- Returns:
- the breathing pattern
-
overlayOn
Creates a pattern that plays this pattern overlaid on another. Anywhere this pattern sets an LED to off (orColor.kBlack
), the base pattern will be displayed instead.- Parameters:
base
- the base pattern to overlay on top of- Returns:
- the combined overlay pattern
-
blend
Creates a pattern that displays outputs as a combination of this pattern and another. Color values are calculated as the average color of both patterns; if both patterns set the same LED to the same color, then it is set to that color, but if one pattern sets to one color and the other pattern sets it to off, then it will show the color of the first pattern but at approximately half brightness. This is different fromoverlayOn(edu.wpi.first.wpilibj.LEDPattern)
, which will show the base pattern at full brightness if the overlay is set to off at that position.- Parameters:
other
- the pattern to blend with- Returns:
- the blended pattern
-
mask
Similar toblend(LEDPattern)
, but performs a bitwise mask on each color channel rather than averaging the colors for each LED. This can be helpful for displaying only a portion of the base pattern by applying a mask that sets the desired area to white, and all other areas to black. However, it can also be used to display only certain color channels or hues; for example, masking withLEDPattern.color(Color.kRed)
will turn off the green and blue channels on the output pattern, leaving only the red LEDs to be illuminated.- Parameters:
mask
- the mask to apply- Returns:
- the masked pattern
-
atBrightness
Creates a pattern that plays this one, but at a different brightness. Brightness multipliers are applied per-channel in the RGB space; no HSL or HSV conversions are applied. Multipliers are also uncapped, which may result in the original colors washing out and appearing less saturated or even just a bright white.This method is predominantly intended for dimming LEDs to avoid painfully bright or distracting patterns from playing (apologies to the 2024 NE Greater Boston field staff).
For example, dimming can be done simply by adding a call to `atBrightness` at the end of a pattern:
// Solid red, but at 50% brightness LEDPattern.solid(Color.kRed).atBrightness(Percent.of(50)); // Solid white, but at only 10% (i.e. ~0.5V) LEDPattern.solid(Color.kWhite).atBrightness(Percent.of(10));
- Parameters:
relativeBrightness
- the multiplier to apply to all channels to modify brightness- Returns:
- the input pattern, displayed at
-
solid
Creates a pattern that displays a single static color along the entire length of the LED strip.- Parameters:
color
- the color to display- Returns:
- the pattern
-
progressMaskLayer
Creates a pattern that works as a mask layer formask(LEDPattern)
that illuminates only the portion of the LED strip corresponding with some progress. The mask pattern will start from the base and set LEDs to white at a proportion equal to the progress returned by the function. Some usages for this could be for displaying progress of a flywheel to its target velocity, progress of a complex autonomous sequence, or the height of an elevator.For example, creating a mask for displaying a red-to-blue gradient, starting from the red end, based on where an elevator is in its range of travel.
LEDPattern basePattern = gradient(Color.kRed, Color.kBlue); LEDPattern progressPattern = basePattern.mask(progressMaskLayer(() -> elevator.getHeight() / elevator.maxHeight());
- Parameters:
progressSupplier
- the function to call to determine the progress. This should return values in the range [0, 1]; any values outside that range will be clamped.- Returns:
- the mask pattern
-
steps
Display a set of colors in steps across the length of the LED strip. No interpolation is done between colors. Colors are specified by the first LED on the strip to show that color. The last color in the map will be displayed all the way to the end of the strip. LEDs positioned before the first specified step will be turned off (you can think of this as if there's a 0 -> black step by default)// Display red from 0-33%, white from 33% - 67%, and blue from 67% to 100% steps(Map.of(0.00, Color.kRed, 0.33, Color.kWhite, 0.67, Color.kBlue)) // Half off, half on steps(Map.of(0.5, Color.kWhite))
- Parameters:
steps
- a map of progress to the color to start displaying at that position along the LED strip- Returns:
- a motionless step pattern
-
gradient
Creates a pattern that displays a non-animated gradient of colors across the entire length of the LED strip. Colors are evenly distributed along the full length of the LED strip. The gradient type is configured with thetype
parameter, allowing the gradient to be either continuous (no seams, good for scrolling effects) or discontinuous (a clear seam is visible, but the gradient applies to the full length of the LED strip without needing to use some space for wrapping).- Parameters:
type
- the type of gradient (continuous or discontinuous)colors
- the colors to display in the gradient- Returns:
- a motionless gradient pattern
-
rainbow
Creates an LED pattern that displays a rainbow across the color wheel. The rainbow pattern will stretch across the entire length of the LED strip.- Parameters:
saturation
- the saturation of the HSV colors, in [0, 255]value
- the value of the HSV colors, in [0, 255]- Returns:
- the rainbow pattern
-