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>
16template <
typename... Ts>
19template <
typename T,
typename... Ancestors>
21 using type =
TypeList<Ancestors..., T>;
24template <
typename T,
typename... Ancestors>
25 requires requires {
typename T::Parent; }
27 using Parent =
typename T::Parent;
28 using type =
typename GetAncestors<Parent, Ancestors..., T>::type;
31template <
typename T,
typename List>
34template <
typename T,
typename... Us>
37template <
typename ListA,
typename ListB>
40template <
typename ListB>
45template <
typename T,
typename... Rest,
typename ListB>
47 using type = std::conditional_t<Contains<T, ListB>::value, T,
typename FindCommon<
TypeList<Rest...>, ListB>::type>;
51static constexpr T GetInverse(
const T& t) {
55static constexpr frc::Transform2d GetInverse(
const frc::Transform2d& t) {
56 return frc::Transform2d{-t.Translation(), -t.Rotation()};
59static constexpr frc::Pose2d GetInverse(
const frc::Pose2d& t) {
60 return frc::Pose2d{}.TransformBy(frc::Transform2d{t, {}});
63static constexpr frc::Pose3d GetInverse(
const frc::Pose3d& t) {
64 return frc::Pose3d{}.TransformBy(frc::Transform3d{t, {}});
67template <
typename T,
typename U>
68static T ApplyTransform(
const T& old,
const U& trans) {
72constexpr static frc::Translation3d ApplyTransform(
const frc::Translation3d& old,
const frc::Transform3d& trans) {
73 return old.RotateBy(trans.Rotation()) + trans.Translation();
76constexpr static frc::Rotation3d ApplyTransform(
const frc::Rotation3d& old,
const frc::Transform3d& trans) {
77 return old + trans.Rotation();
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()};
84constexpr static frc::ChassisSpeeds ApplyTransform(
const frc::ChassisSpeeds& old,
const frc::Rotation2d& trans) {
85 return frc::ChassisSpeeds::FromRobotRelativeSpeeds(old, trans);
88constexpr static frc::ChassisSpeeds ApplyTransform(
const frc::ChassisSpeeds& old,
const frc::Transform3d& trans) {
89 return ApplyTransform(old, trans.Rotation().ToRotation2d());
92constexpr static frc::Translation3d ApplyTransform(
const frc::Translation3d& old,
const frc::Pose3d& trans) {
93 return old + trans.Translation();
96constexpr static frc::Translation2d ApplyTransform(
const frc::Translation2d& old,
const frc::Transform2d& trans) {
97 return old + trans.Translation();
100constexpr static frc::ChassisSpeeds ApplyTransform(
const frc::ChassisSpeeds& old,
const frc::Transform2d& trans) {
101 return ApplyTransform(old, trans.Rotation());
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>)
109 return UpTo<typename From::Parent, Common>(ApplyTransform(current, ctx), ctx);
112template <
class From,
class Common,
class Geometry>
113Geometry UpTo(
const Geometry& current) {
114 if constexpr (std::is_same_v<From, Common>)
117 return UpTo<typename From::Parent, Common>(ApplyTransform(current, From::GetDefaultTransform()));
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>)
125 return ApplyTransform(DownTo<typename To::Parent, Common>(current, ctx), GetInverse(ctx));
128template <
class To,
class Common,
class Geometry>
129Geometry DownTo(
const Geometry& current) {
130 if constexpr (std::is_same_v<To, Common>)
133 return ApplyTransform(DownTo<typename To::Parent, Common>(current), GetInverse(To::GetDefaultTransform()));
138template <
class Frame,
class Geometry>
141 template <
typename... Args>
142 requires std::constructible_from<Geometry, Args...>
143 explicit FrameWrapper(Args&&... args) : geometry{std::forward<Args>(args)...} {}
145 FrameWrapper(Geometry g) : geometry{g} {}
147 template <
class FromFrame,
typename Context>
148 FrameWrapper(FrameWrapper<FromFrame, Geometry> oldFrame,
const Context& ctx) : geometry{oldFrame.template To<Frame>(ctx).Get()} {}
150 template <
class FromFrame>
151 FrameWrapper(FrameWrapper<FromFrame, Geometry> oldFrame) : geometry{oldFrame.template To<Frame>().Get()} {}
153 Geometry& Get() {
return geometry; }
155 Geometry* operator->() {
return &geometry; }
157 const Geometry& Get()
const {
return geometry; }
159 const Geometry* operator->()
const {
return &geometry; }
161 template <
class ToFrame,
typename Context>
162 FrameWrapper<ToFrame, Geometry> To(
const Context& ctx)
const {
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);
169 template <
class ToFrame>
170 FrameWrapper<ToFrame, Geometry> To()
const {
173 return detail::DownTo<ToFrame, Common>(detail::UpTo<Frame, Common>(geometry));
185 static inline frc::Transform2d GetDefaultTransform() {
186 frc::Pose2d pose = robotPoseGetter();
187 return frc::Transform2d{{}, pose};
190 static std::function<frc::Pose2d()> robotPoseGetter;
Definition CoordinateFrames.h:180
Definition CoordinateFrames.h:182
Definition CoordinateFrames.h:32
Definition CoordinateFrames.h:38
Definition CoordinateFrames.h:20
Definition CoordinateFrames.h:17