ModelSpace
All Classes Namespaces Functions Variables Enumerations Pages
frameutils.hpp
1/******************************************************************************
2* Copyright (c) ATTX LLC 2024. All Rights Reserved.
3*
4* This software and associated documentation (the "Software") are the
5* proprietary and confidential information of ATTX, LLC. The Software is
6* furnished under a license agreement between ATTX and the user organization
7* and may be used or copied only in accordance with the terms of the agreement.
8* Refer to 'license/attx_license.adoc' for standard license terms.
9*
10* EXPORT CONTROL NOTICE: THIS SOFTWARE MAY INCLUDE CONTENT CONTROLLED UNDER THE
11* INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) OR THE EXPORT ADMINISTRATION
12* REGULATIONS (EAR99). No part of the Software may be used, reproduced, or
13* transmitted in any form or by any means, for any purpose, without the express
14* written permission of ATTX, LLC.
15******************************************************************************/
16/*
17Frame Utils header file
18-----------------------
19The frame utils class is a class of utilities designed to
20work with frame objects.
21
22Author: Alex Reynolds
23*/
24
25#ifndef FRAME_UTILS_HPP
26#define FRAME_UTILS_HPP
27
28#include "core/macros.h"
29#include "core/clockwerkerrors.h"
30#include "core/CartesianVector.hpp"
31#include "six_dof_dynamics/Frame.hpp"
32
33namespace clockwerk {
34
35 /// @brief A function to get the DCM represnting the relationship [f1/f2]
36 /// @param f1 The first frame for our DCM relationship
37 /// @param f2 The second frame for our DCM relationship
38 /// @return Error code corresponding to success/failure
39 template <typename T>
40 int getFrameRelativeDCM(Frame<T> &f1, Frame<T> &f2, DCM<T> &dcm_f1_f2) {
41 /// First, verify that frames f1 and f2 are part of the same tree.
42 /// Return an error if not.
43 if(f1.getFrameRootPointer() != f2.getFrameRootPointer()) {
45 }
46
47 /// We want to construct the DCM [f1/f2]=[f1/root]*[root/f2]
48 DCM<T> dcm_f1_root, dcm_f2_root, dcm_root_f2;
49 f1.rootRelDCM(dcm_f1_root);
50 f2.rootRelDCM(dcm_f2_root);
51 dcm_f2_root.inverse(dcm_root_f2);
52 multiply(dcm_f1_root, dcm_root_f2, dcm_f1_f2);
53
54 return NO_ERROR;
55 }
56
57 /// @brief A function to rotate vector vec__f1 from frame f1 into frame f2
58 /// @param vec__f1 A vector represented in frame f1
59 /// @param f1 The frame in which vec__f1 is represented
60 /// @param f2 The frame we want to rotate vec__f1 into
61 /// @param vec__f2 Implicit return of our rotated vector
62 /// @return Error code corresponding to success/failure
63 template <typename T>
64 int frameRotate(const CartesianVector<T, 3> &vec__f1, Frame<T> &f1,
65 Frame<T> &f2, CartesianVector<T, 3> &vec__f2) {
66 /// First, verify that frames f1 and f2 are part of the same tree.
67 /// Return an error if not.
68 if(f1.getFrameRootPointer() != f2.getFrameRootPointer()) {
70 }
71
72 /// Our general process is to get our attitudes of each frame relative
73 /// to root, construct a DCM representing the relative attitude, and rotate
74 /// our vector accordingly
75 /// We want to construct the DCM [f2/f1]=[f2/root]*[root/f1]
76 DCM<T> dcm_f2_f1;
77 getFrameRelativeDCM(f2, f1, dcm_f2_f1);
78
79 /// Now rotate our vector from our DCM
80 multiply(dcm_f2_f1, vec__f1, vec__f2);
81
82 return NO_ERROR;
83 }
84
85 /// @brief A function to transform a position vector relative to the origin of
86 /// f1 to a vector relative to the origin of f2
87 /// @param vec_f1__f1 A vector relative to the origin of f1
88 /// @param f1 The frame in which vec_f1__f1 is represented
89 /// @param f2 The frame we want to rotate vec_f2__f1 into
90 /// @param vec_f1__f2 Implicit return of our transformed vector
91 /// @return Error code corresponding to success/failure
92 template <typename T>
93 int framePositionTransform(const CartesianVector<T, 3> &vec_f1__f1, Frame<T> &f1,
94 Frame<T> &f2, CartesianVector<T, 3> &vec_f2__f2) {
95 /// First, verify that frames f1 and f2 are part of the same tree.
96 /// Return an error if not.
97 if(f1.getFrameRootPointer() != f2.getFrameRootPointer()) {
99 }
100
101 // First get current position vector represented in root
102 CartesianVector<T, 3> pos_tmp = f1.rootRelPosition() + f1.rootRelDCM().inverse()*vec_f1__f1;
103
104 // Now get our position relative to f2
105 vec_f2__f2 = f2.rootRelDCM()*(pos_tmp - f2.rootRelPosition());
106
107 return NO_ERROR;
108 }
109
110 /// @brief A function to transform a velocity vector represented in frame
111 /// f1 to a vector represented in f2
112 /// @param vel_f1__f1 Velocity represented in frame f1
113 /// @param pos_f1__f1 The position in f1 at which velocity is represented
114 /// @param f1 The frame in which vel_f1__f1 is represented
115 /// @param f2 The frame we want to represent velocity in
116 /// @param vel_f1__f2 Implicit return of velocity represented in f2
117 /// @return Error code corresponding to success/failure
118 template <typename T>
119 int frameVelocityTransform(const CartesianVector<T, 3> &vel_f1__f1, const CartesianVector<T, 3> &pos_f1__f1,
120 Frame<T> &f1, Frame<T> &f2, CartesianVector<T, 3> &vel_f2__f2) {
121 /// First, verify that frames f1 and f2 are part of the same tree.
122 /// Return an error if not.
123 if(f1.getFrameRootPointer() != f2.getFrameRootPointer()) {
125 }
126
127 // First get current velocity vector represented in root. That comes from the velocity of the
128 // frame, velocity in the frame, and angular velocity of the frame
129 DCM<T> dcm_root_f1 = f1.rootRelDCM().inverse();
130 CartesianVector<T, 3> vel_tmp = f1.rootRelVelocity() + dcm_root_f1*vel_f1__f1;
131 vel_tmp = vel_tmp + dcm_root_f1*cross(f1.rootRelAngularVelocity(), pos_f1__f1);
132
133 // Now get position relative to frame f2
134 CartesianVector<T, 3> pos_f2__f2;
135 framePositionTransform(pos_f1__f1, f1, f2, pos_f2__f2);
136
137 // Now perform the inverse operation with frame f2 to get velocity measured in frame f2
138 DCM<T> dcm_root_f2 = f2.rootRelDCM().inverse();
139 vel_tmp = vel_tmp - dcm_root_f2*cross(f2.rootRelAngularVelocity(), pos_f2__f2);
140 vel_tmp = vel_tmp - f2.rootRelVelocity();
141 vel_f2__f2 = f2.rootRelDCM()*vel_tmp;
142
143 return NO_ERROR;
144 }
145
146}
147
148#endif
Standard vector class derived from Matrix.
Definition CartesianVector.hpp:39
Class defining a direction cosine matrix inherited from Matrix.
Definition DCM.hpp:71
Frame class definition.
Definition Frame.hpp:92
#define NO_ERROR
Definition clockwerkerrors.h:31
#define ERROR_DIFFERENT_TREE
Definition clockwerkerrors.h:123