WPILibC++ 2025.0.0-alpha-1-2-g5e745bc
LEDPattern.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <functional>
8#include <span>
9#include <utility>
10
11#include <units/frequency.h>
12#include <units/length.h>
13#include <units/time.h>
14#include <units/velocity.h>
15
16#include "frc/AddressableLED.h"
17#include "util/Color.h"
18
19namespace frc {
20
21/**
22 * Sets the LED at the given index to the given color.
23 */
24using LEDWriterFn = std::function<void(int, frc::Color)>;
25
26/**
27 * Accepts a data buffer (1st argument) and a callback (2nd argument) for
28 * writing data.
29 */
31 std::function<void(std::span<frc::AddressableLED::LEDData>, LEDWriterFn)>;
32
34 public:
35 explicit LEDPattern(LEDPatternFn impl);
36
37 /**
38 * Writes the pattern to an LED buffer. Dynamic animations should be called
39 * periodically (such as with a command or with a periodic method) to refresh
40 * the buffer over time.
41 *
42 * This method is intentionally designed to use separate objects for reading
43 * and writing data. By splitting them up, we can easily modify the behavior
44 * of some base pattern to make it scroll, blink, or breathe by intercepting
45 * the data writes to transform their behavior to whatever we like.
46 *
47 * @param data the current data of the LED strip
48 * @param writer data writer for setting new LED colors on the LED strip
49 */
50 void ApplyTo(std::span<frc::AddressableLED::LEDData> data,
51 LEDWriterFn writer) const;
52
53 /**
54 * Writes the pattern to an LED buffer. Dynamic animations should be called
55 * periodically (such as with a command or with a periodic method) to refresh
56 * the buffer over time.
57 *
58 * This method is intentionally designed to use separate objects for reading
59 * and writing data. By splitting them up, we can easily modify the behavior
60 * of some base pattern to make it scroll, blink, or breathe by intercepting
61 * the data writes to transform their behavior to whatever we like.
62 *
63 * @param data the current data of the LED strip
64 */
65 void ApplyTo(std::span<frc::AddressableLED::LEDData> data) const;
66
67 /**
68 * Creates a pattern that displays this one in reverse. Scrolling patterns
69 * will scroll in the opposite direction (but at the same speed). It will
70 * treat the end of an LED strip as the start, and the start of the strip as
71 * the end. This can be useful for making ping-pong patterns that travel from
72 * one end of an LED strip to the other, then reverse direction and move back
73 * to the start. This can also be useful when working with LED strips
74 * connected in a serpentine pattern (where the start of one strip is
75 * connected to the end of the previous one).
76 *
77 * @return the reverse pattern
78 */
79 [[nodiscard]]
81
82 /**
83 * Creates a pattern that displays this one, but offset by a certain number of
84 * LEDs. The offset pattern will wrap around, if necessary.
85 *
86 * @param offset how many LEDs to offset by
87 * @return the offset pattern
88 */
89 [[nodiscard]]
90 LEDPattern OffsetBy(int offset);
91
92 /**
93 * Creates a pattern that plays this one scrolling up the buffer. The velocity
94 * controls how fast the pattern returns back to its original position, and is
95 * in terms of the length of the LED strip; scrolling across a segment that is
96 * 10 LEDs long will travel twice as fast as on a segment that's only 5 LEDs
97 * long (assuming equal LED density on both segments).
98 */
99 [[nodiscard]]
100 LEDPattern ScrollAtRelativeSpeed(units::hertz_t velocity);
101
102 /**
103 * Creates a pattern that plays this one scrolling up an LED strip. A negative
104 * velocity makes the pattern play in reverse.
105 *
106 * <p>For example, scrolling a pattern at 4 inches per second along an LED
107 * strip with 60 LEDs per meter:
108 *
109 * <pre>
110 * // LEDs per meter, a known value taken from the spec sheet of our
111 * particular LED strip units::meter_t LED_SPACING = units::meter_t{1 /60.0};
112 *
113 * frc::LEDPattern rainbow = frc::LEDPattern::Rainbow();
114 * frc::LEDPattern scrollingRainbow =
115 * rainbow.ScrollAtAbsoluteSpeed(units::inches_per_second_t{4},
116 * LED_SPACING);
117 * </pre>
118 *
119 * <p>Note that this pattern will scroll <i>faster</i> if applied to a less
120 * dense LED strip (such as 30 LEDs per meter), or <i>slower</i> if applied to
121 * a denser LED strip (such as 120 or 144 LEDs per meter).
122 *
123 * @param velocity how fast the pattern should move along a physical LED strip
124 * @param ledSpacing the distance between adjacent LEDs on the physical LED
125 * strip
126 * @return the scrolling pattern
127 */
128 [[nodiscard]]
129 LEDPattern ScrollAtAbsoluteSpeed(units::meters_per_second_t velocity,
130 units::meter_t ledSpacing);
131
132 /**
133 * Creates a pattern that switches between playing this pattern and turning
134 * the entire LED strip off.
135 *
136 * @param onTime how long the pattern should play for, per cycle
137 * @param offTime how long the pattern should be turned off for, per cycle
138 * @return the blinking pattern
139 */
140 [[nodiscard]]
141 LEDPattern Blink(units::second_t onTime, units::second_t offTime);
142
143 /**
144 * Like {@link LEDPattern::Blink(units::second_t)}, but where the
145 * "off" time is exactly equal to the "on" time.
146 *
147 * @param onTime how long the pattern should play for (and be turned off for),
148 * per cycle
149 * @return the blinking pattern
150 */
151 [[nodiscard]]
152 LEDPattern Blink(units::second_t onTime);
153
154 /**
155 * Creates a pattern that blinks this one on and off in sync with a true/false
156 * signal. The pattern will play while the signal outputs {@code true}, and
157 * will turn off while the signal outputs
158 * {@code false}.
159 *
160 * @param signal the signal to synchronize with
161 * @return the blinking pattern
162 */
163 [[nodiscard]]
164 LEDPattern SynchronizedBlink(std::function<bool()> signal);
165
166 /**
167 * Creates a pattern that brightens and dims this one over time. Brightness
168 * follows a sinusoidal pattern.
169 *
170 * @param period how fast the breathing pattern should complete a single cycle
171 * @return the breathing pattern
172 */
173 [[nodiscard]]
174 LEDPattern Breathe(units::second_t period);
175
176 /**
177 * Creates a pattern that plays this pattern overlaid on another. Anywhere
178 * this pattern sets an LED to off (or {@link frc::Color::kBlack}), the base
179 * pattern will be displayed instead.
180 *
181 * @param base the base pattern to overlay on top of
182 * @return the combined overlay pattern
183 */
184 [[nodiscard]]
186
187 /**
188 * Creates a pattern that displays outputs as a combination of this pattern
189 * and another. Color values are calculated as the average color of both
190 * patterns; if both patterns set the same LED to the same color, then it is
191 * set to that color, but if one pattern sets to one color and the other
192 * pattern sets it to off, then it will show the color of the first pattern
193 * but at approximately half brightness. This is different from {@link
194 * LEDPattern::OverlayOn(const LEDPattern&)}, which will show the base pattern
195 * at full brightness if the overlay is set to off at that position.
196 *
197 * @param other the pattern to blend with
198 * @return the blended pattern
199 */
200 [[nodiscard]]
202
203 /**
204 * Similar to {@link LEDPattern::Blend(const LEDPattern&)}, but performs a
205 * bitwise mask on each color channel rather than averaging the colors for
206 * each LED. This can be helpful for displaying only a portion of the base
207 * pattern by applying a mask that sets the desired area to white, and all
208 * other areas to black. However, it can also be used to display only certain
209 * color channels or hues; for example, masking with {@code
210 * LEDPattern.color(Color.kRed)} will turn off the green and blue channels on
211 * the output pattern, leaving only the red LEDs to be illuminated.
212 *
213 * @param mask the mask to apply
214 * @return the masked pattern
215 */
216 [[nodiscard]]
218
219 /**
220 * Creates a pattern that plays this one, but at a different brightness.
221 * Brightness multipliers are applied per-channel in the RGB space; no HSL or
222 * HSV conversions are applied. Multipliers are also uncapped, which may
223 * result in the original colors washing out and appearing less saturated or
224 * even just a bright white.
225 *
226 * <p>This method is predominantly intended for dimming LEDs to avoid
227 * painfully bright or distracting patterns from playing (apologies to the
228 * 2024 NE Greater Boston field staff).
229 *
230 * <p>For example, dimming can be done simply by adding a call to
231 * `atBrightness` at the end of a pattern:
232 *
233 * <pre>
234 * // Solid red, but at 50% brightness
235 * frc::LEDPattern::Solid(frc::Color::kRed).AtBrightness(0.5);
236 *
237 * // Solid white, but at only 10% (i.e. ~0.5V)
238 * frc::LEDPattern::Solid(frc:Color::kWhite).AtBrightness(0.1);
239 * </pre>
240 *
241 * @param relativeBrightness the multiplier to apply to all channels to modify
242 * brightness
243 * @return the input pattern, displayed at
244 */
245 [[nodiscard]]
246 LEDPattern AtBrightness(double relativeBrightness);
247
248 /** A pattern that turns off all LEDs. */
250
251 /**
252 * Creates a pattern that displays a single static color along the entire
253 * length of the LED strip.
254 *
255 * @param color the color to display
256 * @return the pattern
257 */
259
260 /**
261 * Creates a pattern that works as a mask layer for {@link
262 * LEDPattern::Mask(const LEDPattern&)} that illuminates only the portion of
263 * the LED strip corresponding with some progress. The mask pattern will start
264 * from the base and set LEDs to white at a proportion equal to the progress
265 * returned by the function. Some usages for this could be for displaying
266 * progress of a flywheel to its target velocity, progress of a complex
267 * autonomous sequence, or the height of an elevator.
268 *
269 * <p>For example, creating a mask for displaying a red-to-blue gradient,
270 * starting from the red end, based on where an elevator is in its range of
271 * travel.
272 *
273 * <pre>
274 * frc::LEDPattern basePattern =
275 * frc::LEDPattern::Gradient(frc::Color::kRed, frc::Color::kBlue);
276 * frc::LEDPattern progressPattern =
277 * basePattern.Mask(frc::LEDPattern::ProgressMaskLayer([&]() {
278 * return elevator.GetHeight() / elevator.MaxHeight();
279 * });
280 * </pre>
281 *
282 * @param progressFunction the function to call to determine the progress.
283 * This should return values in the range [0, 1]; any values outside that
284 * range will be clamped.
285 * @return the mask pattern
286 */
287 static LEDPattern ProgressMaskLayer(std::function<double()> progressFunction);
288
289 /**
290 * Display a set of colors in steps across the length of the LED strip. No
291 * interpolation is done between colors. Colors are specified by the first LED
292 * on the strip to show that color. The last color in the map will be
293 * displayed all the way to the end of the strip. LEDs positioned before the
294 * first specified step will be turned off (you can think of this as if
295 * there's a 0 -> black step by default).
296 *
297 * @param steps a map of progress to the color to start displaying at that
298 * position along the LED strip
299 * @return a motionless step pattern
300 */
301 static LEDPattern Steps(std::span<const std::pair<double, Color>> steps);
302
303 /**
304 * Display a set of colors in steps across the length of the LED strip. No
305 * interpolation is done between colors. Colors are specified by the first LED
306 * on the strip to show that color. The last color in the map will be
307 * displayed all the way to the end of the strip. LEDs positioned before the
308 * first specified step will be turned off (you can think of this as if
309 * there's a 0 -> black step by default).
310 *
311 * @param steps a map of progress to the color to start displaying at that
312 * position along the LED strip
313 * @return a motionless step pattern
314 */
316 std::initializer_list<std::pair<double, Color>> steps);
317
318 /**
319 * Creates a pattern that displays a non-animated gradient of colors across
320 * the entire length of the LED strip. The gradient wraps around so the start
321 * and end of the strip are the same color, which allows the gradient to be
322 * modified with a scrolling effect with no discontinuities. Colors are evenly
323 * distributed along the full length of the LED strip.
324 *
325 * @param colors the colors to display in the gradient
326 * @return a motionless gradient pattern
327 */
328 static LEDPattern Gradient(std::span<const Color> colors);
329
330 /**
331 * Creates a pattern that displays a non-animated gradient of colors across
332 * the entire length of the LED strip. The gradient wraps around so the start
333 * and end of the strip are the same color, which allows the gradient to be
334 * modified with a scrolling effect with no discontinuities. Colors are evenly
335 * distributed along the full length of the LED strip.
336 *
337 * @param colors the colors to display in the gradient
338 * @return a motionless gradient pattern
339 */
340 static LEDPattern Gradient(std::initializer_list<Color> colors);
341
342 /**
343 * Creates an LED pattern that displays a rainbow across the color wheel. The
344 * rainbow pattern will stretch across the entire length of the LED strip.
345 *
346 * @param saturation the saturation of the HSV colors, in [0, 255]
347 * @param value the value of the HSV colors, in [0, 255]
348 * @return the rainbow pattern
349 */
350 static LEDPattern Rainbow(int saturation, int value);
351
352 private:
353 LEDPatternFn m_impl;
354};
355} // namespace frc
Represents colors that can be used with Addressable LEDs.
Definition: Color.h:24
Definition: LEDPattern.h:33
void ApplyTo(std::span< frc::AddressableLED::LEDData > data, LEDWriterFn writer) const
Writes the pattern to an LED buffer.
LEDPattern Breathe(units::second_t period)
Creates a pattern that brightens and dims this one over time.
LEDPattern Blink(units::second_t onTime, units::second_t offTime)
Creates a pattern that switches between playing this pattern and turning the entire LED strip off.
LEDPattern(LEDPatternFn impl)
LEDPattern SynchronizedBlink(std::function< bool()> signal)
Creates a pattern that blinks this one on and off in sync with a true/false signal.
static LEDPattern Solid(const Color color)
Creates a pattern that displays a single static color along the entire length of the LED strip.
LEDPattern AtBrightness(double relativeBrightness)
Creates a pattern that plays this one, but at a different brightness.
LEDPattern Blend(const LEDPattern &other)
Creates a pattern that displays outputs as a combination of this pattern and another.
void ApplyTo(std::span< frc::AddressableLED::LEDData > data) const
Writes the pattern to an LED buffer.
LEDPattern ScrollAtRelativeSpeed(units::hertz_t velocity)
Creates a pattern that plays this one scrolling up the buffer.
LEDPattern Mask(const LEDPattern &mask)
Similar to LEDPattern::Blend(const LEDPattern&), but performs a bitwise mask on each color channel ra...
LEDPattern Reversed()
Creates a pattern that displays this one in reverse.
static LEDPattern Rainbow(int saturation, int value)
Creates an LED pattern that displays a rainbow across the color wheel.
static LEDPattern Steps(std::span< const std::pair< double, Color > > steps)
Display a set of colors in steps across the length of the LED strip.
static LEDPattern Gradient(std::initializer_list< Color > colors)
Creates a pattern that displays a non-animated gradient of colors across the entire length of the LED...
LEDPattern OverlayOn(const LEDPattern &base)
Creates a pattern that plays this pattern overlaid on another.
LEDPattern ScrollAtAbsoluteSpeed(units::meters_per_second_t velocity, units::meter_t ledSpacing)
Creates a pattern that plays this one scrolling up an LED strip.
static LEDPattern ProgressMaskLayer(std::function< double()> progressFunction)
Creates a pattern that works as a mask layer for LEDPattern::Mask(const LEDPattern&) that illuminates...
LEDPattern Blink(units::second_t onTime)
Like LEDPattern::Blink(units::second_t), but where the "off" time is exactly equal to the "on" time.
static LEDPattern Steps(std::initializer_list< std::pair< double, Color > > steps)
Display a set of colors in steps across the length of the LED strip.
LEDPattern OffsetBy(int offset)
Creates a pattern that displays this one, but offset by a certain number of LEDs.
static LEDPattern kOff
A pattern that turns off all LEDs.
Definition: LEDPattern.h:249
static LEDPattern Gradient(std::span< const Color > colors)
Creates a pattern that displays a non-animated gradient of colors across the entire length of the LED...
Definition: AprilTagDetector_cv.h:11
std::function< void(std::span< frc::AddressableLED::LEDData >, LEDWriterFn)> LEDPatternFn
Accepts a data buffer (1st argument) and a callback (2nd argument) for writing data.
Definition: LEDPattern.h:31
std::function< void(int, frc::Color)> LEDWriterFn
Sets the LED at the given index to the given color.
Definition: LEDPattern.h:24
color
Definition: color.h:16