diff --git a/rocketpy/rocket/rocket.py b/rocketpy/rocket/rocket.py index 68c2d102e..602ad1543 100644 --- a/rocketpy/rocket/rocket.py +++ b/rocketpy/rocket/rocket.py @@ -1004,8 +1004,8 @@ def evaluate_nozzle_to_cdm(self): def evaluate_nozzle_gyration_tensor(self): """Calculates and returns the nozzle gyration tensor relative to the - rocket's center of dry mass. The gyration tensor is saved and returned - in units of kg*m². + rocket's center of dry mass. The gyration tensor is a second moment of + area per unit area, so it is saved and returned in units of m². Returns ------- @@ -1013,7 +1013,7 @@ def evaluate_nozzle_gyration_tensor(self): Matrix containing the nozzle gyration tensor. """ S_noz_33 = 0.5 * self.motor.nozzle_radius**2 - S_noz_11 = S_noz_22 = 0.5 * S_noz_33 + 0.25 * self.nozzle_to_cdm**2 + S_noz_11 = S_noz_22 = 0.5 * S_noz_33 + self.nozzle_to_cdm**2 S_noz_12, S_noz_13, S_noz_23 = 0, 0, 0 # Due to axis symmetry self.nozzle_gyration_tensor = Matrix( [ diff --git a/tests/acceptance/test_defiance_rocket.py b/tests/acceptance/test_defiance_rocket.py index 9ac574671..47d96359b 100644 --- a/tests/acceptance/test_defiance_rocket.py +++ b/tests/acceptance/test_defiance_rocket.py @@ -11,8 +11,8 @@ MAX_RELATIVE_APOGEE_ERROR = 0.01 REFERENCE_MAX_SPEED = 444.24 REFERENCE_MAX_ACCELERATION = 10400.76 -REFERENCE_IMPACT_X = 1625.55 -REFERENCE_IMPACT_Y = 81.78 +REFERENCE_IMPACT_X = 1609.40 +REFERENCE_IMPACT_Y = 87.03 REFERENCE_METRIC_RELATIVE_TOLERANCE = 0.01 REFERENCE_IMPACT_ABSOLUTE_TOLERANCE = 3.0 diff --git a/tests/unit/rocket/test_rocket.py b/tests/unit/rocket/test_rocket.py index 2682f5b90..d1914d688 100644 --- a/tests/unit/rocket/test_rocket.py +++ b/tests/unit/rocket/test_rocket.py @@ -515,9 +515,9 @@ def test_evaluate_nozzle_to_cdm(calisto): def test_evaluate_nozzle_gyration_tensor(calisto): expected_gyration_tensor = np.array( - [[0.3940207, 0, 0], [0, 0.3940207, 0], [0, 0, 0.0005445]] + [[1.5752660, 0, 0], [0, 1.5752660, 0], [0, 0, 0.0005445]] ) - atol = 1e-3 * 1e-2 * 1e-2 # Equivalent to 1g * 1cm^2 + atol = 1e-7 # equivalent to 0.1 mm^2 assert np.allclose( expected_gyration_tensor, np.array(calisto.nozzle_gyration_tensor), atol=atol ) @@ -526,6 +526,34 @@ def test_evaluate_nozzle_gyration_tensor(calisto): assert np.allclose(expected_gyration_tensor, np.array(res), atol=atol) +@pytest.mark.parametrize( + "rocket_fixture", + ["calisto", "calisto_liquid_modded", "calisto_hybrid_modded"], +) +def test_evaluate_nozzle_gyration_tensor_matches_the_exit_disk(rocket_fixture, request): + """The tensor is the exit disk second moment per unit area, about the CDM.""" + rocket = request.getfixturevalue(rocket_fixture) + radius = rocket.motor.nozzle_radius + offset = rocket.nozzle_to_cdm + + tensor = np.array(rocket.evaluate_nozzle_gyration_tensor()) + + lateral = radius**2 / 4 + offset**2 + assert tensor[0, 0] == pytest.approx(lateral, rel=1e-12) + assert tensor[1, 1] == pytest.approx(lateral, rel=1e-12) + assert tensor[2, 2] == pytest.approx(radius**2 / 2, rel=1e-12) + assert (tensor[0, 1], tensor[0, 2], tensor[1, 2]) == (0, 0, 0) + + +def test_evaluate_nozzle_gyration_tensor_parallel_axis_term(calisto): + """Taking the disk term out leaves the whole squared offset, not a fraction.""" + tensor = np.array(calisto.evaluate_nozzle_gyration_tensor()) + + parallel_axis = tensor[0, 0] - tensor[2, 2] / 2 + + assert parallel_axis == pytest.approx(calisto.nozzle_to_cdm**2, rel=1e-12) + + def test_evaluate_com_to_cdm_function(calisto): atol = 1e-3 # Equivalent to 1mm assert np.allclose( diff --git a/tests/unit/simulation/test_flight.py b/tests/unit/simulation/test_flight.py index a6ef31d80..3d35d1cdb 100644 --- a/tests/unit/simulation/test_flight.py +++ b/tests/unit/simulation/test_flight.py @@ -316,7 +316,7 @@ def test_export_sensor_data(flight_calisto_with_sensors): [ ("t_initial", (0.25886, -0.649623, 0)), ("out_of_rail_time", (0.792028, -1.987634, 0)), - ("apogee_time", (-0.509420, -0.732933, -2.089120e-14)), + ("apogee_time", (-0.519917, -0.734918, -1.005368e-18)), ("t_final", (0, 0, 0)), ], ) @@ -355,7 +355,7 @@ def test_aerodynamic_moments(flight_calisto_custom_wind, flight_time, expected_v [ ("t_initial", (1.654150, 0.659142, -0.067103)), ("out_of_rail_time", (5.052628, 2.013361, -1.75370)), - ("apogee_time", (2.321838, -1.613641, -0.962108)), + ("apogee_time", (2.322999, -1.643037, -0.950316)), ("t_final", (-0.019802, 0.012030, 159.051604)), ], ) @@ -396,7 +396,7 @@ def test_aerodynamic_forces(flight_calisto_custom_wind, flight_time, expected_va ("out_of_rail_time", (0, 2.248540, 25.700928)), ( "apogee_time", - (-14.826350, 15.670022, -0.000264), + (-14.593411, 15.743567, -0.000409), ), ("t_final", (5, 2, -5.660155)), ],