mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-29 02:21:44 +00:00
[examples] AddressableLED: Add unit test (#4779)
This commit is contained in:
@@ -2,54 +2,37 @@
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include <array>
|
||||
#include "Robot.h"
|
||||
|
||||
#include <frc/AddressableLED.h>
|
||||
#include <frc/TimedRobot.h>
|
||||
#include <frc/smartdashboard/SmartDashboard.h>
|
||||
void Robot::RobotInit() {
|
||||
// Default to a length of 60, start empty output
|
||||
// Length is expensive to set, so only set it once, then just update data
|
||||
m_led.SetLength(kLength);
|
||||
m_led.SetData(m_ledBuffer);
|
||||
m_led.Start();
|
||||
}
|
||||
|
||||
class Robot : public frc::TimedRobot {
|
||||
static constexpr int kLength = 60;
|
||||
void Robot::RobotPeriodic() {
|
||||
// Fill the buffer with a rainbow
|
||||
Rainbow();
|
||||
// Set the LEDs
|
||||
m_led.SetData(m_ledBuffer);
|
||||
}
|
||||
|
||||
// PWM port 9
|
||||
// Must be a PWM header, not MXP or DIO
|
||||
frc::AddressableLED m_led{9};
|
||||
std::array<frc::AddressableLED::LEDData, kLength>
|
||||
m_ledBuffer; // Reuse the buffer
|
||||
// Store what the last hue of the first pixel is
|
||||
int firstPixelHue = 0;
|
||||
|
||||
public:
|
||||
void Rainbow() {
|
||||
// For every pixel
|
||||
for (int i = 0; i < kLength; i++) {
|
||||
// Calculate the hue - hue is easier for rainbows because the color
|
||||
// shape is a circle so only one value needs to precess
|
||||
const auto pixelHue = (firstPixelHue + (i * 180 / kLength)) % 180;
|
||||
// Set the value
|
||||
m_ledBuffer[i].SetHSV(pixelHue, 255, 128);
|
||||
}
|
||||
// Increase by to make the rainbow "move"
|
||||
firstPixelHue += 3;
|
||||
// Check bounds
|
||||
firstPixelHue %= 180;
|
||||
void Robot::Rainbow() {
|
||||
// For every pixel
|
||||
for (int i = 0; i < kLength; i++) {
|
||||
// Calculate the hue - hue is easier for rainbows because the color
|
||||
// shape is a circle so only one value needs to precess
|
||||
const auto pixelHue = (firstPixelHue + (i * 180 / kLength)) % 180;
|
||||
// Set the value
|
||||
m_ledBuffer[i].SetHSV(pixelHue, 255, 128);
|
||||
}
|
||||
|
||||
void RobotInit() override {
|
||||
// Default to a length of 60, start empty output
|
||||
// Length is expensive to set, so only set it once, then just update data
|
||||
m_led.SetLength(kLength);
|
||||
m_led.SetData(m_ledBuffer);
|
||||
m_led.Start();
|
||||
}
|
||||
|
||||
void RobotPeriodic() override {
|
||||
// Fill the buffer with a rainbow
|
||||
Rainbow();
|
||||
// Set the LEDs
|
||||
m_led.SetData(m_ledBuffer);
|
||||
}
|
||||
};
|
||||
// Increase by to make the rainbow "move"
|
||||
firstPixelHue += 3;
|
||||
// Check bounds
|
||||
firstPixelHue %= 180;
|
||||
}
|
||||
|
||||
#ifndef RUNNING_FRC_TESTS
|
||||
int main() {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <frc/AddressableLED.h>
|
||||
#include <frc/TimedRobot.h>
|
||||
|
||||
class Robot : public frc::TimedRobot {
|
||||
public:
|
||||
void Rainbow();
|
||||
void RobotInit() override;
|
||||
void RobotPeriodic() override;
|
||||
|
||||
private:
|
||||
static constexpr int kLength = 60;
|
||||
|
||||
// PWM port 9
|
||||
// Must be a PWM header, not MXP or DIO
|
||||
frc::AddressableLED m_led{9};
|
||||
std::array<frc::AddressableLED::LEDData, kLength>
|
||||
m_ledBuffer; // Reuse the buffer
|
||||
// Store what the last hue of the first pixel is
|
||||
int firstPixelHue = 0;
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <frc/AddressableLED.h>
|
||||
#include <frc/simulation/AddressableLEDSim.h>
|
||||
#include <frc/util/Color.h>
|
||||
#include <frc/util/Color8Bit.h>
|
||||
#include <hal/AddressableLEDTypes.h>
|
||||
|
||||
#include "Robot.h"
|
||||
|
||||
void AssertIndexColor(std::array<frc::AddressableLED::LEDData, 60> data,
|
||||
int index, int hue, int saturation, int value);
|
||||
|
||||
TEST(RainbowTest, RainbowPattern) {
|
||||
Robot robot;
|
||||
robot.RobotInit();
|
||||
frc::sim::AddressableLEDSim ledSim =
|
||||
frc::sim::AddressableLEDSim::CreateForChannel(9);
|
||||
EXPECT_TRUE(ledSim.GetRunning());
|
||||
EXPECT_EQ(60, ledSim.GetLength());
|
||||
|
||||
auto rainbowFirstPixelHue = 0;
|
||||
std::array<frc::AddressableLED::LEDData, 60> data;
|
||||
for (int iteration = 0; iteration < 100; iteration++) {
|
||||
SCOPED_TRACE(fmt::format("Iteration {} of 100", iteration));
|
||||
robot.RobotPeriodic();
|
||||
ledSim.GetData(data.data());
|
||||
for (int i = 0; i < 60; i++) {
|
||||
SCOPED_TRACE(fmt::format("LED {} of 60", i));
|
||||
auto hue = (rainbowFirstPixelHue + (i * 180 / 60)) % 180;
|
||||
AssertIndexColor(data, i, hue, 255, 128);
|
||||
}
|
||||
rainbowFirstPixelHue += 3;
|
||||
rainbowFirstPixelHue %= 180;
|
||||
}
|
||||
}
|
||||
|
||||
void AssertIndexColor(std::array<frc::AddressableLED::LEDData, 60> data,
|
||||
int index, int hue, int saturation, int value) {
|
||||
frc::Color8Bit color{frc::Color::FromHSV(hue, saturation, value)};
|
||||
|
||||
EXPECT_EQ(0, data[index].padding);
|
||||
EXPECT_EQ(color.red, data[index].r & 0xFF);
|
||||
EXPECT_EQ(color.green, data[index].g & 0xFF);
|
||||
EXPECT_EQ(color.blue, data[index].b & 0xFF);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include <hal/HALBase.h>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
/**
|
||||
* Runs all unit tests.
|
||||
*/
|
||||
int main(int argc, char** argv) {
|
||||
HAL_Initialize(500, 0);
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int ret = RUN_ALL_TESTS();
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user