Vulcan
Aerospace Engineering Utilities Built on Janus
Loading...
Searching...
No Matches
Guided5Dof.hpp
Go to the documentation of this file.
1// Vulcan Pseudo-5DOF Dynamics
2// Pure stateless dynamics functions for guided vehicle simulation
3//
4// Pseudo-5DOF: 3-DOF translation + 2-DOF attitude (pitch/yaw) with roll
5// commanded. Attitude responds to commands via second-order transfer function
6// dynamics. Supports bank-to-turn and skid-to-turn steering laws.
7#pragma once
8
10
11#include <janus/janus.hpp>
12
14
15// =============================================================================
16// Position Kinematics
17// =============================================================================
18
25template <typename Scalar>
26Vec3<Scalar> position_dot(const Vec3<Scalar> &velocity) {
27 return velocity;
28}
29
30// =============================================================================
31// Attitude Dynamics via Transfer Function
32// =============================================================================
33
48template <typename Scalar>
49Scalar attitude_response_accel(const Scalar &angle, const Scalar &angle_dot,
50 const Scalar &angle_cmd, const Scalar &omega_n,
51 const Scalar &zeta) {
52 Scalar omega_sq = omega_n * omega_n;
53 return omega_sq * (angle_cmd - angle) -
54 Scalar(2) * zeta * omega_n * angle_dot;
55}
56
57// =============================================================================
58// Force Direction for Different Steering Laws
59// =============================================================================
60
69template <typename Scalar>
70Vec3<Scalar> thrust_direction_btt(const Scalar &gamma, const Scalar &chi) {
71 Scalar cos_gamma = janus::cos(gamma);
72 Scalar sin_gamma = janus::sin(gamma);
73 Scalar cos_chi = janus::cos(chi);
74 Scalar sin_chi = janus::sin(chi);
75
76 // Thrust aligned with velocity direction
77 return Vec3<Scalar>{
78 cos_gamma * cos_chi, // North
79 cos_gamma * sin_chi, // East
80 -sin_gamma // Down (negative for nose up)
81 };
82}
83
94template <typename Scalar>
95Vec3<Scalar> lift_direction_btt(const Scalar &gamma, const Scalar &chi,
96 const Scalar &phi) {
97 Scalar cos_gamma = janus::cos(gamma);
98 Scalar sin_gamma = janus::sin(gamma);
99 Scalar cos_chi = janus::cos(chi);
100 Scalar sin_chi = janus::sin(chi);
101 Scalar cos_phi = janus::cos(phi);
102 Scalar sin_phi = janus::sin(phi);
103
104 // "Up" direction in velocity frame (perpendicular to velocity, in vertical
105 // plane)
106 Vec3<Scalar> up_v{sin_gamma * cos_chi, sin_gamma * sin_chi, cos_gamma};
107
108 // "Right" direction (perpendicular to velocity, horizontal)
109 // When chi=0 (North), right = East = (0, 1, 0)
110 Vec3<Scalar> right_v{-sin_chi, cos_chi, Scalar(0)};
111
112 // Lift direction rotated by bank angle
113 return cos_phi * up_v + sin_phi * right_v;
114}
115
124template <typename Scalar>
125Vec3<Scalar> thrust_direction_stt(const Scalar &theta, const Scalar &psi) {
126 Scalar cos_theta = janus::cos(theta);
127 Scalar sin_theta = janus::sin(theta);
128 Scalar cos_psi = janus::cos(psi);
129 Scalar sin_psi = janus::sin(psi);
130
131 return Vec3<Scalar>{
132 cos_theta * cos_psi, // North
133 cos_theta * sin_psi, // East
134 -sin_theta // Down
135 };
136}
137
146template <typename Scalar>
147Vec3<Scalar> side_force_direction_stt(const Scalar &theta, const Scalar &psi) {
148 Scalar cos_psi = janus::cos(psi);
149 Scalar sin_psi = janus::sin(psi);
150
151 // Body Y is perpendicular to body X, in horizontal plane
152 return Vec3<Scalar>{-sin_psi, cos_psi, Scalar(0)};
153}
154
163template <typename Scalar>
164Vec3<Scalar> normal_force_direction_stt(const Scalar &theta,
165 const Scalar &psi) {
166 Scalar cos_theta = janus::cos(theta);
167 Scalar sin_theta = janus::sin(theta);
168 Scalar cos_psi = janus::cos(psi);
169 Scalar sin_psi = janus::sin(psi);
170
171 // Body -Z (up in body frame)
172 return Vec3<Scalar>{sin_theta * cos_psi, sin_theta * sin_psi, cos_theta};
173}
174
175// =============================================================================
176// Velocity Derivatives
177// =============================================================================
178
190template <typename Scalar>
191Vec3<Scalar> velocity_dot_btt(const Scalar &thrust, const Scalar &drag,
192 const Scalar &lift, const Scalar &mass,
193 const Scalar &gravity, const Scalar &gamma,
194 const Scalar &chi, const Scalar &phi) {
195 Vec3<Scalar> T_dir = thrust_direction_btt(gamma, chi);
196 Vec3<Scalar> L_dir = lift_direction_btt(gamma, chi, phi);
197 Vec3<Scalar> D_dir = -T_dir; // Drag opposes thrust direction
198
199 Vec3<Scalar> grav{Scalar(0), Scalar(0), gravity}; // Z-down
200
201 return (thrust / mass) * T_dir + (drag / mass) * D_dir +
202 (lift / mass) * L_dir + grav;
203}
204
216template <typename Scalar>
217Vec3<Scalar> velocity_dot_stt(const Scalar &thrust, const Scalar &drag,
218 const Scalar &normal_force,
219 const Scalar &side_force, const Scalar &mass,
220 const Scalar &gravity, const Scalar &theta,
221 const Scalar &psi) {
222 Vec3<Scalar> T_dir = thrust_direction_stt(theta, psi);
223 Vec3<Scalar> N_dir = normal_force_direction_stt(theta, psi);
224 Vec3<Scalar> S_dir = side_force_direction_stt(theta, psi);
225 Vec3<Scalar> D_dir = -T_dir; // Drag opposes thrust
226
227 Vec3<Scalar> grav{Scalar(0), Scalar(0), gravity}; // Z-down
228
229 return (thrust / mass) * T_dir + (drag / mass) * D_dir +
230 (normal_force / mass) * N_dir + (side_force / mass) * S_dir + grav;
231}
232
233// =============================================================================
234// Flight Path Angle Derivatives
235// =============================================================================
236
250template <typename Scalar>
251Scalar gamma_dot(const Scalar &lift, const Scalar &weight, const Scalar &mass,
252 const Scalar &velocity, const Scalar &gamma,
253 const Scalar &phi) {
254 Scalar cos_phi = janus::cos(phi);
255 Scalar cos_gamma = janus::cos(gamma);
256 return (lift * cos_phi - weight * cos_gamma) /
257 (mass * velocity + Scalar(1e-12));
258}
259
270template <typename Scalar>
271Scalar chi_dot_btt(const Scalar &lift, const Scalar &mass,
272 const Scalar &velocity, const Scalar &gamma,
273 const Scalar &phi) {
274 Scalar sin_phi = janus::sin(phi);
275 Scalar cos_gamma = janus::cos(gamma);
276 return (lift * sin_phi) /
277 (mass * velocity * (cos_gamma + Scalar(1e-12)) + Scalar(1e-12));
278}
279
287template <typename Scalar>
288Scalar load_factor_from_lift(const Scalar &lift, const Scalar &weight) {
289 return lift / (weight + Scalar(1e-12));
290}
291
301template <typename Scalar>
302Scalar bank_for_turn_rate(const Scalar &velocity, const Scalar &chi_dot,
303 const Scalar &gravity) {
304 return janus::atan(velocity * chi_dot / gravity);
305}
306
307} // namespace vulcan::dynamics
Definition Guided5Dof.hpp:13
Vec3< Scalar > thrust_direction_stt(const Scalar &theta, const Scalar &psi)
Definition Guided5Dof.hpp:125
Vec3< Scalar > lift_direction_btt(const Scalar &gamma, const Scalar &chi, const Scalar &phi)
Definition Guided5Dof.hpp:95
Vec3< Scalar > velocity_dot_btt(const Scalar &thrust, const Scalar &drag, const Scalar &lift, const Scalar &mass, const Scalar &gravity, const Scalar &gamma, const Scalar &chi, const Scalar &phi)
Definition Guided5Dof.hpp:191
Scalar chi_dot_btt(const Scalar &lift, const Scalar &mass, const Scalar &velocity, const Scalar &gamma, const Scalar &phi)
Definition Guided5Dof.hpp:271
Scalar bank_for_turn_rate(const Scalar &velocity, const Scalar &chi_dot, const Scalar &gravity)
Definition Guided5Dof.hpp:302
Vec3< Scalar > side_force_direction_stt(const Scalar &theta, const Scalar &psi)
Definition Guided5Dof.hpp:147
Vec3< Scalar > normal_force_direction_stt(const Scalar &theta, const Scalar &psi)
Definition Guided5Dof.hpp:164
Vec3< Scalar > position_dot(const Vec3< Scalar > &velocity)
Definition Guided5Dof.hpp:26
Scalar attitude_response_accel(const Scalar &angle, const Scalar &angle_dot, const Scalar &angle_cmd, const Scalar &omega_n, const Scalar &zeta)
Definition Guided5Dof.hpp:49
Vec3< Scalar > velocity_dot_stt(const Scalar &thrust, const Scalar &drag, const Scalar &normal_force, const Scalar &side_force, const Scalar &mass, const Scalar &gravity, const Scalar &theta, const Scalar &psi)
Definition Guided5Dof.hpp:217
Scalar gamma_dot(const Scalar &lift, const Scalar &weight, const Scalar &mass, const Scalar &velocity, const Scalar &gamma, const Scalar &phi)
Definition Guided5Dof.hpp:251
Vec3< Scalar > thrust_direction_btt(const Scalar &gamma, const Scalar &chi)
Definition Guided5Dof.hpp:70
Scalar load_factor_from_lift(const Scalar &lift, const Scalar &weight)
Definition Guided5Dof.hpp:288
Definition GravityTypes.hpp:7
Definition MassProperties.hpp:12