From 97654be1008042326f4078029ef33d00c5e2d136 Mon Sep 17 00:00:00 2001 From: Julio Machado Date: Sat, 29 Mar 2025 19:07:15 -0300 Subject: [PATCH 1/5] ENH: Support for the RSE file format has been added to the library. The import_rse method in the Abstract Motor class and the load_from_rse_file method in the GenericMotor class are now available. With this update, the library natively supports Rock Sim software data, eliminating the need for users to manually convert motor files. The implementation was based on the import_eng and load_from_eng_file methods, utilizing Python's standard XML library. --- rocketpy/motors/motor.py | 222 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 220 insertions(+), 2 deletions(-) diff --git a/rocketpy/motors/motor.py b/rocketpy/motors/motor.py index 5f4b0dc0b..4665014b3 100644 --- a/rocketpy/motors/motor.py +++ b/rocketpy/motors/motor.py @@ -1,4 +1,5 @@ import re +import xml.etree.ElementTree as ET import warnings from abc import ABC, abstractmethod from functools import cached_property @@ -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(" ### Added +- ENH: Support for the RSE file format has been added to the library [#798](https://github.com/RocketPy-Team/RocketPy/pull/798) ### Changed