Skip to content

BUG: Unecessary Gyroscope Rotation and Wrong Acceleremoter Rotation #811

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ Attention: The newest changes should be on top -->

### Added

- BUG: Fix StochasticFlight time_overshoot None bug [#805] (https://github.com/RocketPy-Team/RocketPy/pull/805)
- ENH: Implement Multivariate Rejection Sampling (MRS) [#738] (https://github.com/RocketPy-Team/RocketPy/pull/738)
- ENH: Create a rocketpy file to store flight simulations [#800](https://github.com/RocketPy-Team/RocketPy/pull/800)
- ENH: Support for the RSE file format has been added to the library [#798](https://github.com/RocketPy-Team/RocketPy/pull/798)
Expand All @@ -43,9 +42,11 @@ Attention: The newest changes should be on top -->

### Fixed

- BUG: Unecessary Gyroscope Rotation and Wrong Acceleremoter Rotation [#811](https://github.com/RocketPy-Team/RocketPy/pull/811)
- BUG: Fix the handling of reference pressure for older rpy files. [#808](https://github.com/RocketPy-Team/RocketPy/pull/808)
- BUG: Non-overshootable simulations error on time parsing. [#807](https://github.com/RocketPy-Team/RocketPy/pull/807)
- BUG: Wrong Phi Initialization For nose_to_tail Rockets [#809](https://github.com/RocketPy-Team/RocketPy/pull/809)
- BUG: Fix StochasticFlight time_overshoot None bug [#805](https://github.com/RocketPy-Team/RocketPy/pull/805)

## v1.9.0 - 2025-03-24

Expand Down
2 changes: 1 addition & 1 deletion rocketpy/prints/sensors_prints.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def orientation(self):
self._print_aligned("Orientation:", self.sensor.orientation)
self._print_aligned("Normal Vector:", self.sensor.normal_vector)
print("Rotation Matrix:")
for row in self.sensor.rotation_matrix:
for row in self.sensor.rotation_sensor_to_body:
value = " ".join(f"{val:.2f}" for val in row)
value = [float(val) for val in value.split()]
self._print_aligned("", value)
Expand Down
7 changes: 4 additions & 3 deletions rocketpy/sensors/accelerometer.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class Accelerometer(InertialSensor):
The cross axis sensitivity of the sensor in percentage.
name : str
The name of the sensor.
rotation_matrix : Matrix
rotation_sensor_to_body : Matrix
The rotation matrix of the sensor from the sensor frame to the rocket
frame of reference.
normal_vector : Vector
Expand Down Expand Up @@ -241,8 +241,9 @@ def measure(self, time, **kwargs):
+ Vector.cross(omega, Vector.cross(omega, r))
)
# Transform to sensor frame
inertial_to_sensor = self._total_rotation_matrix @ Matrix.transformation(
u[6:10]
inertial_to_sensor = (
self._total_rotation_sensor_to_body
@ Matrix.transformation(u[6:10]).transpose
)
A = inertial_to_sensor @ A

Expand Down
25 changes: 8 additions & 17 deletions rocketpy/sensors/gyroscope.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import numpy as np

from ..mathutils.vector_matrix import Matrix, Vector
from ..mathutils.vector_matrix import Vector
from ..prints.sensors_prints import _GyroscopePrints
from ..sensors.sensor import InertialSensor

Expand Down Expand Up @@ -44,7 +44,7 @@ class Gyroscope(InertialSensor):
The cross axis sensitivity of the sensor in percentage.
name : str
The name of the sensor.
rotation_matrix : Matrix
rotation_sensor_to_body : Matrix
The rotation matrix of the sensor from the sensor frame to the rocket
frame of reference.
normal_vector : Vector
Expand Down Expand Up @@ -222,33 +222,26 @@ def measure(self, time, **kwargs):
u_dot = kwargs["u_dot"]
relative_position = kwargs["relative_position"]

# Angular velocity of the rocket in the rocket frame
# Angular velocity of the rocket in the body frame
omega = Vector(u[10:13])

# Transform to sensor frame
inertial_to_sensor = self._total_rotation_matrix @ Matrix.transformation(
u[6:10]
)
W = inertial_to_sensor @ omega
W = self._total_rotation_sensor_to_body @ omega

# Apply noise + bias and quantize
W = self.apply_noise(W)
W = self.apply_temperature_drift(W)

# Apply acceleration sensitivity
if self.acceleration_sensitivity != Vector.zeros():
W += self.apply_acceleration_sensitivity(
omega, u_dot, relative_position, inertial_to_sensor
)
W += self.apply_acceleration_sensitivity(omega, u_dot, relative_position)

W = self.quantize(W)

self.measurement = tuple([*W])
self._save_data((time, *W))

def apply_acceleration_sensitivity(
self, omega, u_dot, relative_position, rotation_matrix
):
def apply_acceleration_sensitivity(self, omega, u_dot, relative_position):
"""
Apply acceleration sensitivity to the sensor measurement

Expand All @@ -260,8 +253,6 @@ def apply_acceleration_sensitivity(
The time derivative of the state vector
relative_position : Vector
The vector from the rocket's center of mass to the sensor
rotation_matrix : Matrix
The rotation matrix from the rocket frame to the sensor frame

Returns
-------
Expand All @@ -271,7 +262,7 @@ def apply_acceleration_sensitivity(
# Linear acceleration of rocket cdm in inertial frame
inertial_acceleration = Vector(u_dot[3:6])

# Angular velocity and accel of rocket
# Angular accel of rocket in body frame
omega_dot = Vector(u_dot[10:13])

# Acceleration felt in sensor
Expand All @@ -281,7 +272,7 @@ def apply_acceleration_sensitivity(
+ Vector.cross(omega, Vector.cross(omega, relative_position))
)
# Transform to sensor frame
A = rotation_matrix @ A
A = self._total_rotation_sensor_to_body @ A

return self.acceleration_sensitivity & A

Expand Down
16 changes: 9 additions & 7 deletions rocketpy/sensors/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,23 +460,23 @@

# rotation matrix and normal vector
if any(isinstance(row, (tuple, list)) for row in orientation): # matrix
self.rotation_matrix = Matrix(orientation)
self.rotation_sensor_to_body = Matrix(orientation)

Check warning on line 463 in rocketpy/sensors/sensor.py

View check run for this annotation

Codecov / codecov/patch

rocketpy/sensors/sensor.py#L463

Added line #L463 was not covered by tests
elif len(orientation) == 3: # euler angles
self.rotation_matrix = Matrix.transformation_euler_angles(
self.rotation_sensor_to_body = Matrix.transformation_euler_angles(
*np.deg2rad(orientation)
).round(12)
else:
raise ValueError("Invalid orientation format")
self.normal_vector = Vector(
[
self.rotation_matrix[0][2],
self.rotation_matrix[1][2],
self.rotation_matrix[2][2],
self.rotation_sensor_to_body[0][2],
self.rotation_sensor_to_body[1][2],
self.rotation_sensor_to_body[2][2],
]
).unit_vector

# cross axis sensitivity matrix
_cross_axis_matrix = 0.01 * Matrix(
cross_axis_matrix = 0.01 * Matrix(
[
[100, self.cross_axis_sensitivity, self.cross_axis_sensitivity],
[self.cross_axis_sensitivity, 100, self.cross_axis_sensitivity],
Expand All @@ -485,7 +485,9 @@
)

# compute total rotation matrix given cross axis sensitivity
self._total_rotation_matrix = self.rotation_matrix @ _cross_axis_matrix
self._total_rotation_sensor_to_body = (
self.rotation_sensor_to_body @ cross_axis_matrix
)

def _vectorize_input(self, value, name):
if isinstance(value, (int, float)):
Expand Down
Loading