Shows the robot's safety state on the NeoPixels.
The panel says the same thing, but takes the better part of three seconds to say it. These are immediate, which is what you want from something telling you whether the robot is about to move.
All four show the same colour rather than being used as a bar: the point is to be readable from wherever you happen to be standing.
They breathe rather than sitting still, which reads as a robot that is running rather than one that has locked up.
One timer here drives all four, rather than each pixel running the kernel's pattern trigger. Four independent timers each reschedule against themselves, so their errors accumulate separately and the pixels visibly drift apart over minutes. Brightness is worked out from the monotonic clock rather than accumulated tick by tick, so a late or dropped tick costs a frame instead of shifting the phase permanently.
They are turned off when the robot shuts down, since the board stays powered and would otherwise leave them lit with nothing behind them.
Summary
Functions
The brightness of a breath elapsed milliseconds in.
The colour a state is shown in.
The brightness of a flash elapsed milliseconds in.
The colour a state is shown in, and whether it breathes or flashes.
Functions
@spec breath(non_neg_integer(), non_neg_integer(), non_neg_integer(), pos_integer()) :: non_neg_integer()
The brightness of a breath elapsed milliseconds in.
A raised cosine, so it eases at both ends rather than turning corners the way a triangle would. Phase comes from elapsed time rather than a counter, which is what keeps every pixel together no matter how the timer behaves.
@spec colour(atom()) :: BB.NSK.Leds.colour()
The colour a state is shown in.
@spec flash(non_neg_integer(), non_neg_integer(), non_neg_integer(), pos_integer()) :: non_neg_integer()
The brightness of a flash elapsed milliseconds in.
Square rather than eased: on for the first half of the period, off for the second. A breath says the robot is busy; a flash says it wants something.
@spec pattern(atom()) :: {BB.NSK.Leds.colour(), :breathe | :flash}
The colour a state is shown in, and whether it breathes or flashes.