Valkyrie 2026
Loading...
Searching...
No Matches
CANdleSensor.h
1#pragma once
2
3#include <bitset>
4#include <iostream>
5#include <memory>
6#include <string>
7#include <unordered_map>
8#include <utility>
9#include <vector>
10
11#include <ctre/phoenix6/CANcoder.hpp>
12#include <ctre/phoenix6/core/CoreCANdle.hpp>
13#include <ctre/phoenix6/core/CoreCANrange.hpp>
14#include <frc/TimedRobot.h>
15#include <valkyrie/sensors/BaseSensor.h>
16
17namespace valor {
18namespace sensors {
19
26class CANdleSensor : public BaseSensor<int>, public ctre::phoenix6::hardware::core::CoreCANdle {
27 public:
28 static constexpr frc::Color8Bit VALOR_GOLD{0xEE, 0xA8, 0x00};
29 static constexpr frc::Color8Bit VALOR_PURPLE{0xFF, 0x00, 0xFF};
30 static constexpr frc::Color8Bit RED{0xFF, 0x00, 0x00};
31 static constexpr frc::Color8Bit ORANGE{0xFF, 0x30, 0x00};
32 static constexpr frc::Color8Bit GREEN{0x00, 0xFF, 0x00};
33 static constexpr frc::Color8Bit BLUE{0x00, 0x00, 0xFF};
34 static constexpr frc::Color8Bit LIGHT_BLUE{0xFF, 0x00, 0xF9};
35 static constexpr frc::Color8Bit WHITE{0xFF, 0xFF, 0xFF};
36 static constexpr frc::Color8Bit OFF{0x00, 0x00, 0x00};
37
38 enum class Priority { LOW, MEDIUM, HIGH };
39
46 static frc::Color8Bit CANcoderMagnetHealthGetter(ctre::phoenix6::hardware::CANcoder* cancoder);
47
48 static frc::Color8Bit CANrangeHealthGetter(ctre::phoenix6::hardware::core::CoreCANrange& canrange);
49
59 CANdleSensor(int ledCount, int numSegments, int canID, std::string canbus = "baseCAN");
60 CANdleSensor(std::vector<int> segmentSizes, int canID, std::string canbus = "baseCAN");
61
62 CANdleSensor(int ledCount, int numSegments);
63 explicit CANdleSensor(std::vector<int> segmentSizes);
64
65 void SetBrightness(double brightness, bool saveImmediately = true);
66 void SetStripType(ctre::phoenix6::signals::StripTypeValue stripType, bool saveImmediately = true);
67
68 inline void ApplyConfig() { GetConfigurator().Apply(config); }
69
76 void SetLED(int led, frc::Color8Bit color);
77
85 void SetColor(int segment, frc::Color8Bit color, Priority priority = Priority::LOW);
86
93 void SetColor(frc::Color8Bit color, Priority priority = Priority::LOW);
94
103 template <typename T>
104 void SetAnimation(int segment, frc::Color8Bit color, Priority priority = Priority::LOW) {
105 if (priority < currentPriority)
106 return;
107 currentPriority = priority;
108 if (!segments[segment].animationSlot) {
109 for (size_t i = 0; i < slots.size(); i++) {
110 if (!slots.test(i)) {
111 segments[segment].animationSlot = i;
112 slots.set(i);
113 break;
114 }
115 }
116 }
117 auto controlRequest = std::make_unique<T>(segments[segment].startLed, segments[segment].endLed);
118 if constexpr (requires(T& t) { t.Color; })
119 controlRequest->Color = color;
120 controlRequest->Slot = segments[segment].animationSlot.value();
121 segments[segment].controlRequest = std::move(controlRequest);
122 }
123
131 template <typename T>
132 void SetAnimation(frc::Color8Bit color, Priority priority = Priority::LOW) {
133 if (priority < currentPriority)
134 return;
135 currentPriority = priority;
136 slots.reset();
137 slots.set(0);
138 segments[0].animationSlot = 0;
139 for (size_t i = 1; i < segments.size(); i++) {
140 segments[i].animationSlot.reset();
141 segments[i].controlRequest.reset();
142 }
143 auto controlRequest = std::make_unique<T>(segments[1].startLed, segments.back().endLed);
144 controlRequest->Slot = 0;
145 if constexpr (requires(T& t) { t.Color; })
146 controlRequest->Color = color;
147 segments[0].controlRequest = std::move(controlRequest);
148 }
149
156 void ClearAnimation(int segment);
157
161 void Reset() override;
162
163 private:
167 struct Segment {
168 std::unique_ptr<ctre::phoenix6::controls::ControlRequest> controlRequest;
169 std::optional<int> animationSlot;
170 int startLed;
171 int endLed;
172 };
173
174 std::vector<int> GenerateSegmentSizes(int ledCount, int numSegments);
175
176 Priority currentPriority = Priority::LOW;
177 std::vector<Segment> segments;
178
182 void Calculate() override;
183
184 std::bitset<8> slots;
185
186 ctre::phoenix6::configs::CANdleConfiguration config;
187};
188
189} // namespace sensors
190} // namespace valor
Abstract class that all Valor sensors should implement.
Definition BaseSensor.h:50
static frc::Color8Bit CANcoderMagnetHealthGetter(ctre::phoenix6::hardware::CANcoder *cancoder)
Get the health status of a CANcoder magnet.
void SetLED(int led, frc::Color8Bit color)
Set the color of a specific LED.
void Reset() override
Resets the CANdle device.
void SetAnimation(frc::Color8Bit color, Priority priority=Priority::LOW)
Set an animation for all segments.
Definition CANdleSensor.h:132
CANdleSensor(int ledCount, int numSegments, int canID, std::string canbus="baseCAN")
Construct a new CANdleSensor object.
void SetColor(frc::Color8Bit color, Priority priority=Priority::LOW)
Set the color for all segments.
void SetColor(int segment, frc::Color8Bit color, Priority priority=Priority::LOW)
Set the color of a specific segment.
void ClearAnimation(int segment)
Clears any active animation for a specific segment.
void SetAnimation(int segment, frc::Color8Bit color, Priority priority=Priority::LOW)
Set an animation for a specific segment.
Definition CANdleSensor.h:104