Valkyrie 2026
Loading...
Searching...
No Matches
CoordinateFrames.h
1#pragma once
2#include <concepts>
3#include <type_traits>
4#include <variant>
5
6#include <frc/geometry/Rotation2d.h>
7#include <frc/geometry/Rotation3d.h>
8#include <frc/geometry/Transform3d.h>
9#include <frc/geometry/Translation3d.h>
10#include <frc/kinematics/ChassisSpeeds.h>
11
12namespace valor {
13
14namespace detail {
15
16template <typename... Ts>
17struct TypeList {};
18
19template <typename T, typename... Ancestors>
21 using type = TypeList<Ancestors..., T>;
22};
23
24template <typename T, typename... Ancestors>
25 requires requires { typename T::Parent; }
26struct GetAncestors<T, Ancestors...> {
27 using Parent = typename T::Parent;
28 using type = typename GetAncestors<Parent, Ancestors..., T>::type;
29};
30
31template <typename T, typename List>
32struct Contains;
33
34template <typename T, typename... Us>
35struct Contains<T, TypeList<Us...>> : std::disjunction<std::is_same<T, Us>...> {};
36
37template <typename ListA, typename ListB>
39
40template <typename ListB>
41struct FindCommon<TypeList<>, ListB> {
42 using type = void;
43};
44
45template <typename T, typename... Rest, typename ListB>
46struct FindCommon<TypeList<T, Rest...>, ListB> {
47 using type = std::conditional_t<Contains<T, ListB>::value, T, typename FindCommon<TypeList<Rest...>, ListB>::type>;
48};
49
50template <typename T>
51static constexpr T GetInverse(const T& t) {
52 return -t;
53}
54
55static constexpr frc::Transform2d GetInverse(const frc::Transform2d& t) {
56 return frc::Transform2d{-t.Translation(), -t.Rotation()};
57}
58
59static constexpr frc::Pose2d GetInverse(const frc::Pose2d& t) {
60 return frc::Pose2d{}.TransformBy(frc::Transform2d{t, {}});
61}
62
63static constexpr frc::Pose3d GetInverse(const frc::Pose3d& t) {
64 return frc::Pose3d{}.TransformBy(frc::Transform3d{t, {}});
65}
66
67template <typename T, typename U>
68static T ApplyTransform(const T& old, const U& trans) {
69 return old + trans;
70}
71
72constexpr static frc::Translation3d ApplyTransform(const frc::Translation3d& old, const frc::Transform3d& trans) {
73 return old.RotateBy(trans.Rotation()) + trans.Translation();
74}
75
76constexpr static frc::Rotation3d ApplyTransform(const frc::Rotation3d& old, const frc::Transform3d& trans) {
77 return old + trans.Rotation();
78}
79
80constexpr static frc::Pose2d ApplyTransform(const frc::Pose2d& old, const frc::Transform3d& trans) {
81 return frc::Pose2d{old.Translation() + trans.Translation().ToTranslation2d(), old.Rotation() + trans.Rotation().ToRotation2d()};
82}
83
84constexpr static frc::ChassisSpeeds ApplyTransform(const frc::ChassisSpeeds& old, const frc::Rotation2d& trans) {
85 return frc::ChassisSpeeds::FromRobotRelativeSpeeds(old, trans);
86}
87
88constexpr static frc::ChassisSpeeds ApplyTransform(const frc::ChassisSpeeds& old, const frc::Transform3d& trans) {
89 return ApplyTransform(old, trans.Rotation().ToRotation2d());
90}
91
92constexpr static frc::Translation3d ApplyTransform(const frc::Translation3d& old, const frc::Pose3d& trans) {
93 return old + trans.Translation();
94}
95
96constexpr static frc::Translation2d ApplyTransform(const frc::Translation2d& old, const frc::Transform2d& trans) {
97 return old + trans.Translation();
98}
99
100constexpr static frc::ChassisSpeeds ApplyTransform(const frc::ChassisSpeeds& old, const frc::Transform2d& trans) {
101 return ApplyTransform(old, trans.Rotation());
102}
103
104template <class From, class Common, class Geometry, class Context>
105Geometry UpTo(const Geometry& current, const Context& ctx) {
106 if constexpr (std::is_same_v<From, Common>)
107 return current;
108 else
109 return UpTo<typename From::Parent, Common>(ApplyTransform(current, ctx), ctx);
110}
111
112template <class From, class Common, class Geometry>
113Geometry UpTo(const Geometry& current) {
114 if constexpr (std::is_same_v<From, Common>)
115 return current;
116 else
117 return UpTo<typename From::Parent, Common>(ApplyTransform(current, From::GetDefaultTransform()));
118}
119
120template <class To, class Common, class Geometry, class Context>
121Geometry DownTo(const Geometry& current, const Context& ctx) {
122 if constexpr (std::is_same_v<To, Common>)
123 return current;
124 else
125 return ApplyTransform(DownTo<typename To::Parent, Common>(current, ctx), GetInverse(ctx));
126}
127
128template <class To, class Common, class Geometry>
129Geometry DownTo(const Geometry& current) {
130 if constexpr (std::is_same_v<To, Common>)
131 return current;
132 else
133 return ApplyTransform(DownTo<typename To::Parent, Common>(current), GetInverse(To::GetDefaultTransform()));
134}
135
136} // namespace detail
137
138template <class Frame, class Geometry>
139class FrameWrapper {
140 public:
141 template <typename... Args>
142 requires std::constructible_from<Geometry, Args...>
143 explicit FrameWrapper(Args&&... args) : geometry{std::forward<Args>(args)...} {}
144
145 FrameWrapper(Geometry g) : geometry{g} {}
146
147 template <class FromFrame, typename Context>
148 FrameWrapper(FrameWrapper<FromFrame, Geometry> oldFrame, const Context& ctx) : geometry{oldFrame.template To<Frame>(ctx).Get()} {}
149
150 template <class FromFrame>
151 FrameWrapper(FrameWrapper<FromFrame, Geometry> oldFrame) : geometry{oldFrame.template To<Frame>().Get()} {}
152
153 Geometry& Get() { return geometry; }
154
155 Geometry* operator->() { return &geometry; }
156
157 const Geometry& Get() const { return geometry; }
158
159 const Geometry* operator->() const { return &geometry; }
160
161 template <class ToFrame, typename Context>
162 FrameWrapper<ToFrame, Geometry> To(const Context& ctx) const {
163 using Common =
164 typename detail::FindCommon<typename detail::GetAncestors<Frame>::type, typename detail::GetAncestors<ToFrame>::type>::type;
165 static_assert(!std::is_void_v<Common>, "Frames do not share a common ancestor!");
166 return detail::DownTo<ToFrame, Common>(detail::UpTo<Frame, Common>(geometry, ctx), ctx);
167 }
168
169 template <class ToFrame>
170 FrameWrapper<ToFrame, Geometry> To() const {
171 using Common =
172 typename detail::FindCommon<typename detail::GetAncestors<Frame>::type, typename detail::GetAncestors<ToFrame>::type>::type;
173 return detail::DownTo<ToFrame, Common>(detail::UpTo<Frame, Common>(geometry));
174 }
175
176 private:
177 Geometry geometry;
178};
179
180struct FieldFrame {};
181
183 using Parent = FieldFrame;
184
185 static inline frc::Transform2d GetDefaultTransform() {
186 frc::Pose2d pose = robotPoseGetter();
187 return frc::Transform2d{{}, pose};
188 }
189
190 static std::function<frc::Pose2d()> robotPoseGetter;
191};
192
193} // namespace valor
Definition CoordinateFrames.h:180
Definition CoordinateFrames.h:182
Definition CoordinateFrames.h:32
Definition CoordinateFrames.h:38
Definition CoordinateFrames.h:20
Definition CoordinateFrames.h:17