diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a2503d23..a59eebab5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ Attention: The newest changes should be on top --> ### Added +- ENH: Support for the RSE file format has been added to the library [#798](https://github.com/RocketPy-Team/RocketPy/pull/798) ### Changed diff --git a/data/motors/rse_example/rse_motor_example_file.rse b/data/motors/rse_example/rse_motor_example_file.rse new file mode 100644 index 000000000..f934b9f2e --- /dev/null +++ b/data/motors/rse_example/rse_motor_example_file.rse @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + diff --git a/rocketpy/motors/motor.py b/rocketpy/motors/motor.py index 5f4b0dc0b..6a12665dd 100644 --- a/rocketpy/motors/motor.py +++ b/rocketpy/motors/motor.py @@ -1,5 +1,6 @@ import re import warnings +import xml.etree.ElementTree as ET from abc import ABC, abstractmethod from functools import cached_property from os import path @@ -268,8 +269,9 @@ class Function. Thrust units are Newtons. self.dry_I_13 = inertia[4] self.dry_I_23 = inertia[5] - # Handle .eng file inputs + # Handle .eng or .rse file inputs self.description_eng_file = None + self.rse_motor_data = None if isinstance(thrust_source, str): if ( path.exists(thrust_source) @@ -277,7 +279,12 @@ class Function. Thrust units are Newtons. ): _, self.description_eng_file, points = Motor.import_eng(thrust_source) thrust_source = points - + elif ( + path.exists(thrust_source) + and path.splitext(path.basename(thrust_source))[1] == ".rse" + ): + self.rse_motor_data, points = Motor.import_rse(thrust_source) + thrust_source = points # Evaluate raw thrust source self.thrust_source = thrust_source self.thrust = Function( @@ -381,6 +388,10 @@ def dry_mass(self, dry_mass): self._dry_mass = float(self.description_eng_file[-2]) - float( self.description_eng_file[-3] ) + elif self.rse_motor_data: + self._dry_mass = float( + self.rse_motor_data["description"]["total_mass"] + ) - float(self.rse_motor_data["description"]["propellant_mass"]) else: raise ValueError("Dry mass must be specified.") @@ -990,6 +1001,83 @@ def clip_thrust(thrust, new_burn_time): "zero", ) + @staticmethod + def import_rse(file_name): + """ + Reads motor data from a file and extracts comments, model, description, and data points. + + Parameters + ---------- + file_path : str + Path to the motor data file. + + Returns + ------- + dict + A dictionary containing the extracted data: + - comments: List of comments in the file. + - model: Dictionary with manufacturer, code, and type of the motor. + - description: Dictionary with performance data (dimensions, weights, thrust, etc.). + - data_points: List of temporal data points (time, thrust, mass, cg). + tuple + A tuple representing the thrust curve (time, thrust). + """ + + # Parse the XML file + tree = ET.parse(file_name) + root = tree.getroot() + + # Extract comments + comments = [] + for comment in root.iter(): + if comment.tag.startswith("