Skip to content

Commit fc4228c

Browse files
aZira371Gui-FernandesBR
authored andcommitted
MNT: updating location of 3 dof doc in users index.rst
- MNT: 3 dof documentation only referred in users section/getting started - MNT: correction of docstring in flight.py - MNT: corrected unit_vector call when defining rotation axis in u_dot_generalized_3dof - MNT: docstring correction in test_flight_3dof.py - ENH: test coverage added for anti alignment case in weathercock model to test_flight_3dof.py
1 parent 14d199d commit fc4228c

File tree

3 files changed

+48
-5
lines changed

3 files changed

+48
-5
lines changed

docs/user/index.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ RocketPy's User Guide
77

88
Installation and Requirements <installation.rst>
99
First Simulation <first_simulation.rst>
10-
3-DOF Simulations <three_dof_simulation.rst>
10+
3 DOF Simulations and comparison <three_dof_simulation.rst>
1111

1212
.. toctree::
1313
:maxdepth: 1
@@ -28,7 +28,7 @@ RocketPy's User Guide
2828
Air Brakes Example <airbrakes.rst>
2929
../notebooks/sensors.ipynb
3030
../matlab/matlab.rst
31-
3 DOF Simulations and comparison<three_dof_simulation.rst>
31+
3232
.. toctree::
3333
:maxdepth: 2
3434
:caption: Monte Carlo Simulations

rocketpy/simulation/flight.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,7 +1810,7 @@ def u_dot_generalized_3dof(self, t, u, post_processing=False):
18101810
t : float
18111811
Time in seconds.
18121812
u : list
1813-
State vector: [x, y, z, vx, vy, vz, q0, q1, q2, q3, omega1, omega2, omega3].
1813+
State vector: [x, y, z, vx, vy, vz, e0, e1, e2, e3, omega1, omega2, omega3].
18141814
post_processing : bool, optional
18151815
If True, adds flight data to self variables like self.angle_of_attack.
18161816
@@ -1940,7 +1940,6 @@ def u_dot_generalized_3dof(self, t, u, post_processing=False):
19401940
sin_angle = min(1.0, max(-1.0, sin_angle))
19411941

19421942
# Angular velocity magnitude proportional to misalignment angle
1943-
# Angular velocity magnitude proportional to sin(angle)
19441943
omega_mag = self.weathercock_coeff * sin_angle
19451944

19461945
# Angular velocity in inertial frame
@@ -1976,7 +1975,7 @@ def u_dot_generalized_3dof(self, t, u, post_processing=False):
19761975
# If parallel, use y axis
19771976
y_axis = Vector([0.0, 1.0, 0.0])
19781977
perp_axis = body_z_inertial ^ y_axis
1979-
rotation_axis = perp_axis.normalized()
1978+
rotation_axis = perp_axis.unit_vector
19801979
# 180 degree rotation: sin(angle) = 1
19811980
omega_mag = self.weathercock_coeff * 1.0
19821981
omega_inertial = rotation_axis * omega_mag

tests/unit/simulation/test_flight_3dof.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ def test_invalid_simulation_mode(example_plain_env, calisto):
141141

142142
def test_weathercock_coeff_stored(example_plain_env, point_mass_rocket):
143143
"""Tests that the weathercock_coeff parameter is correctly stored.
144+
144145
Parameters
145146
----------
146147
example_plain_env : rocketpy.Environment
@@ -160,6 +161,7 @@ def test_weathercock_coeff_stored(example_plain_env, point_mass_rocket):
160161

161162
def test_weathercock_coeff_default(example_plain_env, point_mass_rocket):
162163
"""Tests that the default weathercock_coeff is 1.0.
164+
163165
Parameters
164166
----------
165167
example_plain_env : rocketpy.Environment
@@ -180,6 +182,7 @@ def test_weathercock_zero_gives_fixed_attitude(example_plain_env, point_mass_roc
180182
"""Tests that weathercock_coeff=0 results in fixed attitude (no quaternion change).
181183
When weathercock_coeff is 0, the quaternion derivatives should be zero,
182184
meaning the attitude does not evolve.
185+
183186
Parameters
184187
----------
185188
example_plain_env : rocketpy.Environment
@@ -208,6 +211,7 @@ def test_weathercock_nonzero_evolves_attitude(example_plain_env, point_mass_rock
208211
"""Tests that non-zero weathercock_coeff causes attitude evolution.
209212
When the body axis is misaligned with the relative wind and weathercock_coeff
210213
is positive, the quaternion derivatives should be non-zero.
214+
211215
Parameters
212216
----------
213217
example_plain_env : rocketpy.Environment
@@ -238,6 +242,7 @@ def test_weathercock_aligned_no_evolution(example_plain_env, point_mass_rocket):
238242
"""Tests that when body axis is aligned with relative wind, no rotation occurs.
239243
When the rocket's body z-axis is already aligned with the negative of the
240244
freestream velocity, the quaternion derivatives should be approximately zero.
245+
241246
Parameters
242247
----------
243248
example_plain_env : rocketpy.Environment
@@ -266,3 +271,42 @@ def test_weathercock_aligned_no_evolution(example_plain_env, point_mass_rocket):
266271
assert e_dot_magnitude < 1e-8, (
267272
"Quaternion derivatives should be very small when aligned"
268273
)
274+
275+
276+
def test_weathercock_anti_aligned_uses_perp_axis_and_evolves(
277+
example_plain_env, point_mass_rocket
278+
):
279+
"""Tests the anti-aligned case where body z-axis is opposite freestream.
280+
281+
This should exercise the branch that selects a perpendicular axis (y-axis)
282+
when the cross with x-axis is nearly zero, producing a non-zero quaternion
283+
derivative.
284+
"""
285+
flight = Flight(
286+
rocket=point_mass_rocket,
287+
environment=example_plain_env,
288+
rail_length=1,
289+
simulation_mode="3 DOF",
290+
weathercock_coeff=1.0,
291+
)
292+
293+
sqrt2_2 = np.sqrt(2) / 2
294+
# Build quaternion that makes body z-axis = [-1, 0, 0]
295+
# This corresponds to a -90 deg rotation about the y-axis: e0=cos(45°), e2=-sin(45°)
296+
e0 = sqrt2_2
297+
e1 = 0
298+
e2 = -sqrt2_2
299+
e3 = 0
300+
301+
# State: [x, y, z, vx, vy, vz, e0, e1, e2, e3, w1, w2, w3]
302+
# Set velocity so desired_direction becomes [1,0,0]
303+
u = [0, 0, 100, 50, 0, 0, e0, e1, e2, e3, 0, 0, 0]
304+
305+
result = flight.u_dot_generalized_3dof(0, u)
306+
307+
# Quaternion derivatives (indices 6-9) should be non-zero in anti-aligned case
308+
e_dot = result[6:10]
309+
e_dot_magnitude = sum(ed**2 for ed in e_dot) ** 0.5
310+
assert e_dot_magnitude > 1e-6, (
311+
"Quaternion derivatives should be non-zero for anti-aligned"
312+
)

0 commit comments

Comments
 (0)