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
16#include "valkyrie/sensors/BaseSensor.h"
17
18namespace valor {
19namespace sensors {
20
27class CANdleSensor : public BaseSensor<int>, public ctre::phoenix6::hardware::core::CoreCANdle {
28 public:
29 static constexpr frc::Color8Bit VALOR_GOLD{0xEE, 0xA8, 0x00};
30 static constexpr frc::Color8Bit VALOR_PURPLE{0xFF, 0x00, 0xFF};
31 static constexpr frc::Color8Bit RED{0xFF, 0x00, 0x00};
32 static constexpr frc::Color8Bit ORANGE{0xFF, 0x30, 0x00};
33 static constexpr frc::Color8Bit GREEN{0x00, 0xFF, 0x00};
34 static constexpr frc::Color8Bit BLUE{0x00, 0x00, 0xFF};
35 static constexpr frc::Color8Bit LIGHT_BLUE{0xFF, 0x00, 0xF9};
36 static constexpr frc::Color8Bit WHITE{0xFF, 0xFF, 0xFF};
37 static constexpr frc::Color8Bit OFF{0x00, 0x00, 0x00};
38
39 enum class Priority { LOW, MEDIUM, HIGH };
40
47 static frc::Color8Bit CANcoderMagnetHealthGetter(ctre::phoenix6::hardware::CANcoder* cancoder);
48
49 static frc::Color8Bit CANrangeHealthGetter(ctre::phoenix6::hardware::core::CoreCANrange& canrange);
50
60 CANdleSensor(int ledCount, int numSegments, int canID, std::string canbus = "baseCAN");
61 CANdleSensor(std::vector<int> segmentSizes, int canID, std::string canbus = "baseCAN");
62
63 CANdleSensor(int ledCount, int numSegments);
64 explicit CANdleSensor(std::vector<int> segmentSizes);
65
66 void SetBrightness(double brightness, bool saveImmediately = true);
67 void SetStripType(ctre::phoenix6::signals::StripTypeValue stripType, bool saveImmediately = true);
68
69 inline void ApplyConfig() { GetConfigurator().Apply(config); }
70
77 void SetLED(int led, frc::Color8Bit color);
78
86 void SetColor(int segment, frc::Color8Bit color, Priority priority = Priority::LOW);
87
94 void SetColor(frc::Color8Bit color, Priority priority = Priority::LOW);
95
104 template <typename T>
105 void SetAnimation(int segment, frc::Color8Bit color, Priority priority = Priority::LOW) {
106 if (priority < currentPriority)
107 return;
108 currentPriority = priority;
109 if (!segments[segment].animationSlot) {
110 for (size_t i = 0; i < slots.size(); i++) {
111 if (!slots.test(i)) {
112 segments[segment].animationSlot = i;
113 slots.set(i);
114 break;
115 }
116 }
117 }
118 auto controlRequest = std::make_unique<T>(segments[segment].startLed, segments[segment].endLed);
119 if constexpr (requires(T& t) { t.Color; })
120 controlRequest->Color = color;
121 controlRequest->Slot = segments[segment].animationSlot.value();
122 segments[segment].controlRequest = std::move(controlRequest);
123 }
124
132 template <typename T>
133 void SetAnimation(frc::Color8Bit color, Priority priority = Priority::LOW) {
134 if (priority < currentPriority)
135 return;
136 currentPriority = priority;
137 slots.reset();
138 slots.set(0);
139 segments[0].animationSlot = 0;
140 for (size_t i = 1; i < segments.size(); i++) {
141 segments[i].animationSlot.reset();
142 segments[i].controlRequest.reset();
143 }
144 auto controlRequest = std::make_unique<T>(segments[1].startLed, segments.back().endLed);
145 controlRequest->Slot = 0;
146 if constexpr (requires(T& t) { t.Color; })
147 controlRequest->Color = color;
148 segments[0].controlRequest = std::move(controlRequest);
149 }
150
157 void ClearAnimation(int segment);
158
162 void Reset() override;
163
164 private:
168 struct Segment {
169 std::unique_ptr<ctre::phoenix6::controls::ControlRequest> controlRequest;
170 std::optional<int> animationSlot;
171 int startLed;
172 int endLed;
173 };
174
175 std::vector<int> GenerateSegmentSizes(int ledCount, int numSegments);
176
177 Priority currentPriority = Priority::LOW;
178 std::vector<Segment> segments;
179
183 void Calculate() override;
184
185 std::bitset<8> slots;
186
187 ctre::phoenix6::configs::CANdleConfiguration config;
188};
189
190} // namespace sensors
191} // namespace valor
Abstract class that all Valor sensors should implement.
Definition BaseSensor.h:52
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:133
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:105