Source code for rocketpy.sensors.gnss_receiver
import math
import numpy as np
from rocketpy.tools import inverted_haversine
from ..mathutils.vector_matrix import Matrix, Vector
from ..prints.sensors_prints import _GnssReceiverPrints
from .sensor import ScalarSensor
[docs]
class GnssReceiver(ScalarSensor):
"""Class for the GNSS Receiver sensor.
Attributes
----------
prints : _GnssReceiverPrints
Object that contains the print functions for the sensor.
sampling_rate : float
Sample rate of the sensor in Hz.
position_accuracy : float
Accuracy of the sensor interpreted as the standard deviation of the
position in meters.
altitude_accuracy : float
Accuracy of the sensor interpreted as the standard deviation of the
position in meters.
name : str
The name of the sensor.
measurement : tuple
The measurement of the sensor.
measured_data : list
The stored measured data of the sensor.
"""
units = "°, m"
[docs]
def __init__(
self,
sampling_rate,
position_accuracy=0,
altitude_accuracy=0,
name="GnssReceiver",
):
"""Initialize the Gnss Receiver sensor.
Parameters
----------
sampling_rate : float
Sample rate of the sensor in Hz.
position_accuracy : float
Accuracy of the sensor interpreted as the standard deviation of the
position in meters. Default is 0.
altitude_accuracy : float
Accuracy of the sensor interpreted as the standard deviation of the
position in meters. Default is 0.
name : str
The name of the sensor. Default is "GnssReceiver".
"""
super().__init__(sampling_rate=sampling_rate, name=name)
self.position_accuracy = position_accuracy
self.altitude_accuracy = altitude_accuracy
self.prints = _GnssReceiverPrints(self)
[docs]
def measure(self, time, **kwargs):
"""Measure the position of the rocket in latitude, longitude and
altitude.
Parameters
----------
time : float
Current time in seconds.
kwargs : dict
Keyword arguments dictionary containing the following keys:
- u : np.array
State vector of the rocket.
- u_dot : np.array
Derivative of the state vector of the rocket.
- relative_position : np.array
Position of the sensor relative to the rocket center of mass.
- environment : Environment
Environment object containing the atmospheric conditions.
"""
u = kwargs["u"]
relative_position = kwargs["relative_position"]
lat, lon = kwargs["environment"].latitude, kwargs["environment"].longitude
earth_radius = kwargs["environment"].earth_radius
# Get from state u and add relative position
x, y, z = (Matrix.transformation(u[6:10]) @ relative_position) + Vector(u[0:3])
# Apply accuracy to the position
x = np.random.normal(x, self.position_accuracy)
y = np.random.normal(y, self.position_accuracy)
altitude = np.random.normal(z, self.altitude_accuracy)
# Convert x and y to latitude and longitude
drift = (x**2 + y**2) ** 0.5
bearing = (2 * math.pi - math.atan2(-x, y)) * (180 / math.pi)
# Applies the haversine equation to find final lat/lon coordinates
latitude, longitude = inverted_haversine(lat, lon, drift, bearing, earth_radius)
self.measurement = (latitude, longitude, altitude)
self._save_data((time, *self.measurement))
[docs]
def export_measured_data(self, filename, file_format="csv"):
"""Export the measured values to a file
Parameters
----------
filename : str
Name of the file to export the values to
file_format : str
Format of the file to export the values to. Options are "csv" and
"json". Default is "csv".
Returns
-------
None
"""
self._generic_export_measured_data(
filename=filename,
file_format=file_format,
data_labels=("t", "latitude", "longitude", "altitude"),
)
def to_dict(self, **kwargs):
return {
"sampling_rate": self.sampling_rate,
"position_accuracy": self.position_accuracy,
"altitude_accuracy": self.altitude_accuracy,
"name": self.name,
}
@classmethod
def from_dict(cls, data):
return cls(
sampling_rate=data["sampling_rate"],
position_accuracy=data["position_accuracy"],
altitude_accuracy=data["altitude_accuracy"],
name=data["name"],
)