[copybara] Sync with robotpy (#8964)

GitOrigin-RevId: 9dff8f977401e78be0bb6f39cea2328320ab2d95
This commit is contained in:
PJ Reiniger
2026-06-08 22:22:48 -04:00
committed by GitHub
parent 0213ecf382
commit 111130d8bb
20 changed files with 1026 additions and 265 deletions

View File

@@ -94,6 +94,8 @@ DYNAMIC_CAMERA_SERVER = 1
Filesystem = "rpy/Filesystem.h"
MotorControllerGroup = "rpy/MotorControllerGroup.h"
Notifier = "rpy/Notifier.h"
# rpy only
AddressableLEDBuffer = "rpy/AddressableLEDBuffer.h"
# wpi/counter
EdgeConfiguration = "wpi/counter/EdgeConfiguration.hpp"

View File

@@ -1,3 +1,6 @@
extra_includes:
- rpy/AddressableLEDBuffer.h
functions:
format_as:
ignore: true
@@ -19,6 +22,10 @@ classes:
SetGlobalData:
enums:
ColorOrder:
inline_code: |
.def("setData", [](wpi::AddressableLED& self, const wpi::AddressableLEDBuffer& data) {
return self.SetData(data);
}, release_gil(), py::prepend());
wpi::AddressableLED::LEDData:
force_no_trampoline: true
ignored_bases:

View File

@@ -0,0 +1,58 @@
classes:
wpi::AddressableLEDBuffer:
methods:
AddressableLEDBuffer:
SetRGB:
SetHSV:
SetLED:
overloads:
size_t, const wpi::util::Color&:
size_t, const wpi::util::Color8Bit&:
size:
rename: __len__
GetRed:
GetGreen:
GetBlue:
GetLED:
GetLED8Bit:
at:
rename: __getitem__
begin:
ignore: true
end:
ignore: true
CreateView:
rename: __getitem__
no_release_gil: true
keepalive:
- [0, 1]
inline_code: |
.def("__iter__", [](wpi::AddressableLEDBuffer& self) {
return py::make_iterator(self.begin(), self.end());
}, py::keep_alive<0, 1>())
wpi::AddressableLEDBuffer::View:
methods:
size:
rename: __len__
SetRGB:
SetHSV:
SetLED:
overloads:
size_t, const wpi::util::Color&:
size_t, const wpi::util::Color8Bit&:
at:
rename: __getitem__
overloads:
size_t:
size_t [const]:
ignore: true
begin:
ignore: true
end:
ignore: true
GetLED:
GetLED8Bit:
inline_code: |
.def("__iter__", [](wpi::AddressableLEDBuffer::View& self) {
return py::make_iterator(self.begin(), self.end());
}, py::keep_alive<0, 1>())

View File

@@ -1,3 +1,6 @@
extra_includes:
- rpy/AddressableLEDBuffer.h
classes:
wpi::LEDPattern:
enums:
@@ -8,8 +11,16 @@ classes:
ApplyTo:
overloads:
std::span<wpi::AddressableLED::LEDData> [const]:
cpp_code: |
[](const wpi::LEDPattern& self, wpi::AddressableLEDBuffer::View data) {
return self.ApplyTo(data);
}
LEDReader, std::function<void (int, wpi::util::Color)> [const]:
std::span<wpi::AddressableLED::LEDData>, std::function<void (int, wpi::util::Color)> [const]:
cpp_code: |
[](const wpi::LEDPattern& self, wpi::AddressableLEDBuffer::View data, std::function<void(int, wpi::util::Color)> writer) {
return self.ApplyTo(data, writer);
}
Reversed:
OffsetBy:
ScrollAtRelativeVelocity:
@@ -38,6 +49,14 @@ classes:
ignore: true
Rainbow:
MapIndex:
inline_code: |
.def("applyTo", [](const wpi::LEDPattern& self, wpi::AddressableLEDBuffer& data) {
self.ApplyTo(static_cast<std::span<wpi::AddressableLED::LEDData>>(data));
}, py::arg("data"), release_gil())
.def("applyTo", [](const wpi::LEDPattern& self, wpi::AddressableLEDBuffer& data,
std::function<void (int, wpi::util::Color)> writer) {
self.ApplyTo(static_cast<std::span<wpi::AddressableLED::LEDData>>(data), std::move(writer));
}, py::arg("data"), py::arg("writer").none(false), release_gil())
wpi::LEDPattern::LEDReader:
methods:
LEDReader:

View File

@@ -4,6 +4,7 @@ from . import _init__wpilib
from ._wpilib import (
ADXL345_I2C,
AddressableLED,
AddressableLEDBuffer,
Alert,
Alliance,
AnalogAccelerometer,
@@ -117,6 +118,7 @@ from ._wpilib import (
__all__ = [
"ADXL345_I2C",
"AddressableLED",
"AddressableLEDBuffer",
"Alert",
"Alliance",
"AnalogAccelerometer",

View File

@@ -177,7 +177,7 @@ class RobotStarter:
for i in range(100):
if (
inst.getNetworkMode()
& ntcore.NetworkTableInstance.NetworkMode.kNetModeStarting
& ntcore.NetworkTableInstance.NetworkMode.STARTING.value
) == 0:
break
# real sleep since we're waiting for the server, not simulated sleep

View File

@@ -0,0 +1,129 @@
// 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 "rpy/AddressableLEDBuffer.h"
#include <stdexcept>
#include <span>
namespace wpi {
void AddressableLEDBuffer::SetRGB(size_t index, int r, int g, int b) {
m_buffer.at(index).SetRGB(r, g, b);
}
void AddressableLEDBuffer::SetHSV(size_t index, int h, int s, int v) {
m_buffer.at(index).SetHSV(h, s, v);
}
void AddressableLEDBuffer::SetLED(size_t index, const wpi::util::Color& color) {
m_buffer.at(index).SetLED(color);
}
void AddressableLEDBuffer::SetLED(size_t index, const wpi::util::Color8Bit& color) {
m_buffer.at(index).SetLED(color);
}
int AddressableLEDBuffer::GetRed(size_t index) const { return m_buffer.at(index).r; }
int AddressableLEDBuffer::GetGreen(size_t index) const {
return m_buffer.at(index).g;
}
int AddressableLEDBuffer::GetBlue(size_t index) const { return m_buffer.at(index).b; }
wpi::util::Color AddressableLEDBuffer::GetLED(size_t index) const {
const auto& led = m_buffer.at(index);
return wpi::util::Color{led.r / 255.0, led.g / 255.0, led.b / 255.0};
}
wpi::util::Color8Bit AddressableLEDBuffer::GetLED8Bit(size_t index) const {
const auto& led = m_buffer.at(index);
return wpi::util::Color8Bit{led.r, led.g, led.b};
}
AddressableLED::LEDData& AddressableLEDBuffer::at(size_t index) {
return m_buffer.at(index);
}
AddressableLED::LEDData& AddressableLEDBuffer::operator[](size_t index) {
return m_buffer.at(index);
}
const AddressableLED::LEDData& AddressableLEDBuffer::operator[](
size_t index) const {
return m_buffer.at(index);
}
void AddressableLEDBuffer::View::SetRGB(size_t index, int r, int g, int b) {
at(index).SetRGB(r, g, b);
}
void AddressableLEDBuffer::View::SetHSV(size_t index, int h, int s, int v) {
at(index).SetHSV(h, s, v);
}
void AddressableLEDBuffer::View::SetLED(size_t index, const wpi::util::Color& color) {
at(index).SetLED(color);
}
void AddressableLEDBuffer::View::SetLED(size_t index,
const wpi::util::Color8Bit& color) {
at(index).SetLED(color);
}
AddressableLED::LEDData& AddressableLEDBuffer::View::at(size_t index) {
// std::span::at doesn't exist until C++26
if (index >= m_data.size()) {
throw std::out_of_range("Index out of range");
}
return m_data[index];
}
AddressableLED::LEDData& AddressableLEDBuffer::View::operator[](
size_t index) {
return at(index);
}
const AddressableLED::LEDData& AddressableLEDBuffer::View::at(
size_t index) const {
// std::span::at doesn't exist until C++26
if (index >= m_data.size()) {
throw std::out_of_range("Index out of range");
}
return m_data[index];
}
const AddressableLED::LEDData& AddressableLEDBuffer::View::operator[](
size_t index) const {
return at(index);
}
wpi::util::Color AddressableLEDBuffer::View::GetLED(size_t index) const {
const auto& led = at(index);
return wpi::util::Color{led.r / 255.0, led.g / 255.0, led.b / 255.0};
}
wpi::util::Color8Bit AddressableLEDBuffer::View::GetLED8Bit(size_t index) const {
const auto& led = at(index);
return wpi::util::Color8Bit{led.r, led.g, led.b};
}
AddressableLEDBuffer::View::View(std::span<AddressableLED::LEDData> data)
: m_data(data) {}
AddressableLEDBuffer::View AddressableLEDBuffer::CreateView(
pybind11::slice slice) {
size_t start = 0, stop = 0, step = 0, slicelength = 0;
slice.compute(m_buffer.size(), &start, &stop, &step, &slicelength);
if (step != 1) {
throw std::out_of_range("step != 1");
}
if (!slicelength) {
throw std::out_of_range("zero length view");
}
return View(std::span(m_buffer).subspan(start, slicelength));
}
} // namespace wpi

View File

@@ -0,0 +1,285 @@
// 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 <span>
#include <stdexcept>
#include <vector>
#include "pybind11/pytypes.h"
#include "wpi/hardware/led/AddressableLED.hpp"
#include "wpi/util/Color.hpp"
#include "wpi/util/Color8Bit.hpp"
namespace wpi {
/**
* Buffer storage for Addressable LEDs.
*/
class AddressableLEDBuffer {
public:
/**
* Constructs a new LED buffer with the specified length.
*
* @param length The length of the buffer in pixels
*/
explicit AddressableLEDBuffer(size_t length) : m_buffer(length) {}
/**
* Sets a specific LED in the buffer.
*
* @param index the index to write
* @param r the r value [0-255]
* @param g the g value [0-255]
* @param b the b value [0-255]
*/
void SetRGB(size_t index, int r, int g, int b);
/**
* Sets a specific LED in the buffer.
*
* @param index the index to write
* @param h the h value [0-180)
* @param s the s value [0-255]
* @param v the v value [0-255]
*/
void SetHSV(size_t index, int h, int s, int v);
/**
* Sets a specific LED in the buffer.
*
* @param index the index to write
* @param color the color to write
*/
void SetLED(size_t index, const wpi::util::Color& color);
/**
* Sets a specific LED in the buffer.
*
* @param index the index to write
* @param color the color to write
*/
void SetLED(size_t index, const wpi::util::Color8Bit& color);
/**
* Gets the buffer length.
*
* @return the buffer length
*/
size_t size() const { return m_buffer.size(); }
/**
* Gets the red value at the specified index.
*
* @param index the index
* @return the red value
*/
int GetRed(size_t index) const;
/**
* Gets the green value at the specified index.
*
* @param index the index
* @return the green value
*/
int GetGreen(size_t index) const;
/**
* Gets the blue value at the specified index.
*
* @param index the index
* @return the blue value
*/
int GetBlue(size_t index) const;
/**
* Gets the color at the specified index.
*
* @param index the index
* @return the LED color
*/
wpi::util::Color GetLED(size_t index) const;
/**
* Gets the color at the specified index.
*
* @param index the index
* @return the LED color
*/
wpi::util::Color8Bit GetLED8Bit(size_t index) const;
/**
* Implicit conversion to span of LED data
*/
operator std::span<wpi::AddressableLED::LEDData>() {
return std::span{m_buffer};
}
/**
* Implicit conversion to span of const LED data
*/
operator std::span<const wpi::AddressableLED::LEDData>() const {
return std::span{m_buffer};
}
/**
* Gets the LED data at the specified index.
*
* @param index the index
* @return reference to the LED data
*/
wpi::AddressableLED::LEDData& at(size_t index);
/**
* Gets the LED data at the specified index.
*
* @param index the index
* @return reference to the LED data
*/
wpi::AddressableLED::LEDData& operator[](size_t index);
/**
* Gets the LED data at the specified index.
*
* @param index the index
* @return const reference to the LED data
*/
const wpi::AddressableLED::LEDData& operator[](size_t index) const;
auto begin() { return m_buffer.begin(); }
auto end() { return m_buffer.end(); }
/**
* A view of another addressable LED buffer. Views provide an easy way to split a large LED
* strip into smaller sections that can be animated individually.
*/
class View {
public:
/**
* Gets the length of the view.
*/
size_t size() const { return m_data.size(); }
/**
* Sets a specific LED in the view.
*
* @param index the index to write
* @param r the r value [0-255]
* @param g the g value [0-255]
* @param b the b value [0-255]
*/
void SetRGB(size_t index, int r, int g, int b);
/**
* Sets a specific LED in the view.
*
* @param index the index to write
* @param h the h value [0-180)
* @param s the s value [0-255]
* @param v the v value [0-255]
*/
void SetHSV(size_t index, int h, int s, int v);
/**
* Sets a specific LED in the view.
*
* @param index the index to write
* @param color the color to write
*/
void SetLED(size_t index, const wpi::util::Color& color);
/**
* Sets a specific LED in the view.
*
* @param index the index to write
* @param color the color to write
*/
void SetLED(size_t index, const wpi::util::Color8Bit& color);
/**
* Gets the LED data at the specified index.
*
* @param index the index
* @return reference to the LED data
*/
wpi::AddressableLED::LEDData& at(size_t index);
/**
* Gets the LED data at the specified index.
*
* @param index the index
* @return reference to the LED data
*/
wpi::AddressableLED::LEDData& operator[](size_t index);
/**
* Gets the LED data at the specified index.
*
* @param index the index
* @return const reference to the LED data
*/
const wpi::AddressableLED::LEDData& at(size_t index) const;
/**
* Gets the LED data at the specified index.
*
* @param index the index
* @return const reference to the LED data
*/
const wpi::AddressableLED::LEDData& operator[](size_t index) const;
auto begin() { return m_data.begin(); }
auto end() { return m_data.end(); }
/**
* Gets the color at the specified index.
*
* @param index the index
* @return the LED color
*/
wpi::util::Color GetLED(size_t index) const;
/**
* Gets the color at the specified index.
*
* @param index the index
* @return the LED color
*/
wpi::util::Color8Bit GetLED8Bit(size_t index) const;
/**
* Implicit conversion to span of LED data
*/
operator std::span<wpi::AddressableLED::LEDData>() {
return m_data;
}
/**
* Implicit conversion to span of const LED data
*/
operator std::span<const wpi::AddressableLED::LEDData>() const {
return m_data;
}
private:
friend class AddressableLEDBuffer;
explicit View(std::span<wpi::AddressableLED::LEDData> data);
std::span<wpi::AddressableLED::LEDData> m_data;
};
/**
* Creates a read/write view of this buffer.
*
* @param slice the desired slice of the buffer (e.g. 2:4), step must be unspecified or 1
* @return View object representing the view
* @throws std::out_of_range if the view would exceed buffer bounds
*/
View CreateView(pybind11::slice slice);
private:
std::vector<wpi::AddressableLED::LEDData> m_buffer;
};
} // namespace frc