JSim 2026.06.01-p(1)
Loading...
Searching...
No Matches
spin_decay_model.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cmath>
4
9
11
30 public:
38 explicit SpinDecayModel(const MagnusModel& magnus_model = MagnusModel())
39 : magnus_model_(magnus_model) {}
40
58 Vector3 step(const Vector3& omegaLocal,
59 const Vector3& velocityWorld,
60 const Quaternion& orientation,
61 double dt) const noexcept {
62 // --- Rotation transforms ---
63 Matrix3 R = Matrix3::fromQuaternion(orientation);
64 Matrix3 Rinv = R.transpose();
65
66 // body -> world angular velocity
67 Vector3 omegaWorld = R * omegaLocal;
68
69 double vMag = velocityWorld.norm();
70 double wMag = omegaWorld.norm();
71
72 // --- Angular damping terms ---
73
75 Vector3 linearDamping = omegaWorld * m_linearDecay;
76
78 Vector3 velocityDamping = omegaWorld * (m_velocityCoupling * vMag);
79
81 Vector3 nonlinearDamping = omegaWorld * (m_nonlinearDecay * wMag);
82
83 // --- Magnus coupling (external model) ---
84
89 Vector3 magnusForce =
90 magnus_model_.computeForce(velocityWorld, omegaWorld);
91
93 Vector3 magnusTorque = m_radiusVector.cross(magnusForce);
94
95 // --- Angular acceleration ---
96 Vector3 domega =
97 magnusTorque
98 - linearDamping
99 - velocityDamping
100 - nonlinearDamping;
101
102 // integrate in world frame
103 omegaWorld = omegaWorld + domega * dt;
104
105 // world -> body
106 return Rinv * omegaWorld;
107 }
108
109 // --- Tunables ---
110
115 void setLinearDecay(double k) noexcept { m_linearDecay = k; }
116
121 void setVelocityCoupling(double k) noexcept { m_velocityCoupling = k; }
122
127 void setNonlinearDecay(double k) noexcept { m_nonlinearDecay = k; }
128
134 void setRadiusVector(const Vector3& r) noexcept { m_radiusVector = r; }
135
136 private:
138 MagnusModel magnus_model_;
139
141 double m_linearDecay{0.05};
142
144 double m_velocityCoupling{0.01};
145
147 double m_nonlinearDecay{0.02};
148
154 Vector3 m_radiusVector{0.0, 0.0, 0.05};
155};
156
157} // namespace frcsim::aerodynamics
Computes a Magnus lift force from linear velocity and spin.
Definition magnus_model.hpp:23
void setVelocityCoupling(double k) noexcept
Sets velocity-coupled damping coefficient.
Definition spin_decay_model.hpp:121
void setLinearDecay(double k) noexcept
Sets linear angular decay coefficient.
Definition spin_decay_model.hpp:115
Vector3 step(const Vector3 &omegaLocal, const Vector3 &velocityWorld, const Quaternion &orientation, double dt) const noexcept
Advances angular velocity forward in time.
Definition spin_decay_model.hpp:58
void setNonlinearDecay(double k) noexcept
Sets nonlinear angular decay coefficient.
Definition spin_decay_model.hpp:127
SpinDecayModel(const MagnusModel &magnus_model=MagnusModel())
Constructs a spin decay model.
Definition spin_decay_model.hpp:38
void setRadiusVector(const Vector3 &r) noexcept
Sets radius (lever arm) used for Magnus torque calculation.
Definition spin_decay_model.hpp:134
Definition spin_decay_model.hpp:10
3x3 matrix type used for rotations and inertia-tensor operations.
Definition matrix.hpp:27
static Matrix3 fromQuaternion(const Quaternion &q) noexcept
Definition matrix.hpp:164
Matrix3 transpose() const noexcept
Definition matrix.hpp:111
Unit-quaternion rotation representation and rotation algebra helpers.
Definition quaternion.hpp:25
3D vector utility used throughout JSim physics.
Definition vector.hpp:22
double norm() const noexcept
Returns Euclidean magnitude.
Definition vector.hpp:114
Vector3 cross(const Vector3 &o) const noexcept
Returns cross product with o.
Definition vector.hpp:172