mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-23 01:21:42 +00:00
[wpimath] Improve C++ SimpleMotorFeedforward unit type support (#7440)
Allow using non-base types Allow using angles for serde
This commit is contained in:
@@ -20,8 +20,7 @@ namespace frc {
|
||||
* permanent-magnet DC motor.
|
||||
*/
|
||||
template <class Distance>
|
||||
requires std::same_as<units::meter, Distance> ||
|
||||
std::same_as<units::radian, Distance>
|
||||
requires units::length_unit<Distance> || units::angle_unit<Distance>
|
||||
class SimpleMotorFeedforward {
|
||||
public:
|
||||
using Velocity =
|
||||
|
||||
@@ -12,10 +12,12 @@
|
||||
#include "wpimath/protobuf/controller.npb.h"
|
||||
|
||||
// Everything is converted into units for
|
||||
// frc::SimpleMotorFeedforward<units::meters>
|
||||
// frc::SimpleMotorFeedforward<units::meters> or
|
||||
// frc::SimpleMotorFeedforward<units::radians>
|
||||
|
||||
template <class Distance>
|
||||
struct wpi::Protobuf<frc::SimpleMotorFeedforward<Distance>> { // NOLINT
|
||||
requires units::length_unit<Distance> || units::angle_unit<Distance>
|
||||
struct wpi::Protobuf<frc::SimpleMotorFeedforward<Distance>> {
|
||||
using MessageStruct = wpi_proto_ProtobufSimpleMotorFeedforward;
|
||||
using InputStream =
|
||||
wpi::ProtoInputStream<frc::SimpleMotorFeedforward<Distance>>;
|
||||
@@ -24,6 +26,9 @@ struct wpi::Protobuf<frc::SimpleMotorFeedforward<Distance>> { // NOLINT
|
||||
|
||||
static std::optional<frc::SimpleMotorFeedforward<Distance>> Unpack(
|
||||
InputStream& stream) {
|
||||
using BaseUnit =
|
||||
units::unit<std::ratio<1>, units::traits::base_unit_of<Distance>>;
|
||||
using BaseFeedforward = frc::SimpleMotorFeedforward<BaseUnit>;
|
||||
wpi_proto_ProtobufSimpleMotorFeedforward msg;
|
||||
if (!stream.Decode(msg)) {
|
||||
return {};
|
||||
@@ -31,26 +36,23 @@ struct wpi::Protobuf<frc::SimpleMotorFeedforward<Distance>> { // NOLINT
|
||||
|
||||
return frc::SimpleMotorFeedforward<Distance>{
|
||||
units::volt_t{msg.ks},
|
||||
units::unit_t<frc::SimpleMotorFeedforward<units::meters>::kv_unit>{
|
||||
msg.kv},
|
||||
units::unit_t<frc::SimpleMotorFeedforward<units::meters>::ka_unit>{
|
||||
msg.ka},
|
||||
units::unit_t<typename BaseFeedforward::kv_unit>{msg.kv},
|
||||
units::unit_t<typename BaseFeedforward::ka_unit>{msg.ka},
|
||||
units::second_t{msg.dt},
|
||||
};
|
||||
}
|
||||
|
||||
static bool Pack(OutputStream& stream,
|
||||
const frc::SimpleMotorFeedforward<Distance>& value) {
|
||||
using BaseUnit =
|
||||
units::unit<std::ratio<1>, units::traits::base_unit_of<Distance>>;
|
||||
using BaseFeedforward = frc::SimpleMotorFeedforward<BaseUnit>;
|
||||
wpi_proto_ProtobufSimpleMotorFeedforward msg{
|
||||
.ks = value.GetKs().value(),
|
||||
.kv =
|
||||
units::unit_t<frc::SimpleMotorFeedforward<units::meters>::kv_unit>{
|
||||
value.GetKv()}
|
||||
.value(),
|
||||
.ka =
|
||||
units::unit_t<frc::SimpleMotorFeedforward<units::meters>::ka_unit>{
|
||||
value.GetKa()}
|
||||
.value(),
|
||||
.kv = units::unit_t<typename BaseFeedforward::kv_unit>{value.GetKv()}
|
||||
.value(),
|
||||
.ka = units::unit_t<typename BaseFeedforward::ka_unit>{value.GetKa()}
|
||||
.value(),
|
||||
.dt = units::second_t{value.GetDt()}.value(),
|
||||
};
|
||||
return stream.Encode(msg);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
// frc::SimpleMotorFeedforward<units::radians>
|
||||
|
||||
template <class Distance>
|
||||
requires units::length_unit<Distance> || units::angle_unit<Distance>
|
||||
struct wpi::Struct<frc::SimpleMotorFeedforward<Distance>> {
|
||||
static constexpr std::string_view GetTypeName() {
|
||||
return "SimpleMotorFeedforward";
|
||||
@@ -25,40 +26,44 @@ struct wpi::Struct<frc::SimpleMotorFeedforward<Distance>> {
|
||||
|
||||
static frc::SimpleMotorFeedforward<Distance> Unpack(
|
||||
std::span<const uint8_t> data) {
|
||||
using BaseUnit =
|
||||
units::unit<std::ratio<1>, units::traits::base_unit_of<Distance>>;
|
||||
using BaseFeedforward = frc::SimpleMotorFeedforward<BaseUnit>;
|
||||
constexpr size_t kKsOff = 0;
|
||||
constexpr size_t kKvOff = kKsOff + 8;
|
||||
constexpr size_t kKaOff = kKvOff + 8;
|
||||
constexpr size_t kDtOff = kKaOff + 8;
|
||||
return {units::volt_t{wpi::UnpackStruct<double, kKsOff>(data)},
|
||||
units::unit_t<frc::SimpleMotorFeedforward<units::meters>::kv_unit>{
|
||||
units::unit_t<typename BaseFeedforward::kv_unit>{
|
||||
wpi::UnpackStruct<double, kKvOff>(data)},
|
||||
units::unit_t<frc::SimpleMotorFeedforward<units::meters>::ka_unit>{
|
||||
units::unit_t<typename BaseFeedforward::ka_unit>{
|
||||
wpi::UnpackStruct<double, kKaOff>(data)},
|
||||
units::second_t{wpi::UnpackStruct<double, kDtOff>(data)}};
|
||||
}
|
||||
|
||||
static void Pack(std::span<uint8_t> data,
|
||||
const frc::SimpleMotorFeedforward<Distance>& value) {
|
||||
using BaseUnit =
|
||||
units::unit<std::ratio<1>, units::traits::base_unit_of<Distance>>;
|
||||
using BaseFeedforward = frc::SimpleMotorFeedforward<BaseUnit>;
|
||||
constexpr size_t kKsOff = 0;
|
||||
constexpr size_t kKvOff = kKsOff + 8;
|
||||
constexpr size_t kKaOff = kKvOff + 8;
|
||||
constexpr size_t kDtOff = kKaOff + 8;
|
||||
wpi::PackStruct<kKsOff>(data, value.GetKs().value());
|
||||
wpi::PackStruct<kKvOff>(
|
||||
data,
|
||||
units::unit_t<frc::SimpleMotorFeedforward<units::meters>::kv_unit>{
|
||||
value.GetKv()}
|
||||
.value());
|
||||
data, units::unit_t<typename BaseFeedforward::kv_unit>{value.GetKv()}
|
||||
.value());
|
||||
wpi::PackStruct<kKaOff>(
|
||||
data,
|
||||
units::unit_t<frc::SimpleMotorFeedforward<units::meters>::ka_unit>{
|
||||
value.GetKa()}
|
||||
.value());
|
||||
data, units::unit_t<typename BaseFeedforward::ka_unit>{value.GetKa()}
|
||||
.value());
|
||||
wpi::PackStruct<kDtOff>(data, units::second_t{value.GetDt()}.value());
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(
|
||||
wpi::StructSerializable<frc::SimpleMotorFeedforward<units::meters>>);
|
||||
static_assert(
|
||||
wpi::StructSerializable<frc::SimpleMotorFeedforward<units::feet>>);
|
||||
static_assert(
|
||||
wpi::StructSerializable<frc::SimpleMotorFeedforward<units::radians>>);
|
||||
|
||||
Reference in New Issue
Block a user