Feature/cluster motor structure#924
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new ClusterMotor implementation to RocketPy, intended to model a symmetric cluster of identical motors by aggregating thrust, mass, and inertia (including parallel-axis/Steiner corrections), with accompanying integration tests.
Changes:
- Introduces
rocketpy.motors.cluster_motor.ClusterMotor(new motor type built on top ofMotor). - Implements cluster-scaled thrust/mass/inertia behavior plus a simple cluster layout plotting helper.
- Adds integration tests validating basic scaling and Steiner-theorem inertia expectations.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
rocketpy/motors/cluster_motor.py |
New ClusterMotor class that aggregates an underlying motor’s properties for clustered configurations. |
tests/integration/motors/test_cluster_motor.py |
New integration tests for cluster initialization, scaling, and inertia calculations. |
You can also share your feedback on Copilot code review. Take the survey.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #924 +/- ##
===========================================
+ Coverage 80.27% 81.12% +0.85%
===========================================
Files 104 108 +4
Lines 12769 14075 +1306
===========================================
+ Hits 10250 11419 +1169
- Misses 2519 2656 +137 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
… appeared through th merge
MateusStano
left a comment
There was a problem hiding this comment.
This is really good! Just requested a few changes and it should be good to merge
| class ClusterMotor(Motor): | ||
| """ | ||
| A class representing a cluster of N identical motors arranged symmetrically. | ||
|
|
||
| This class aggregates the physical properties (thrust, mass, inertia) of | ||
| multiple motors using the Parallel Axis Theorem (Huygens-Steiner theorem). | ||
|
|
||
| Attributes | ||
| ---------- | ||
| motor : SolidMotor | ||
| The single motor instance used in the cluster. | ||
| number : int | ||
| The number of motors in the cluster. | ||
| radius : float | ||
| The radial distance from the rocket's central axis to the center of each motor. | ||
| """ |
There was a problem hiding this comment.
This is a good description of the class. One question, this is only modelling cases where the motors are constructed radially? A symmetric case considering a motor in the middle (aligned with upper frame central axis) is not modelled here right?
Can you clarify this aspect in the docstrings, please?
Also, I would suggest changing the name of the class to RingClusterMotor or AnnularClusterMotor (or something similar to your preference).
| Ixx_cluster = self.number * Ixx_loc + (self.number / 2) * m_dry * ( | ||
| self.radius**2 | ||
| ) | ||
| Iyy_cluster = self.number * Iyy_loc + (self.number / 2) * m_dry * ( | ||
| self.radius**2 | ||
| ) |
There was a problem hiding this comment.
Where do the terms (self.number/2) come from here? Are you sure this works in cases where self.number=2? I believe if there are two motors, the values of Ixx and Iyy should be different
| Ixx_term1 = self.motor.propellant_I_11 * self.number | ||
| Ixx_term2 = self.motor.propellant_mass * (0.5 * self.number * self.radius**2) | ||
| self._propellant_I_11 = Ixx_term1 + Ixx_term2 | ||
| self._propellant_I_22 = self._propellant_I_11 | ||
|
|
||
| Izz_term1 = self.motor.propellant_I_33 * self.number | ||
| Izz_term2 = self.motor.propellant_mass * (self.number * self.radius**2) | ||
| self._propellant_I_33 = Izz_term1 + Izz_term2 |
There was a problem hiding this comment.
these inertias calculations probably also have issues in the case of self.number=2
Pull request type
Checklist
black rocketpy/ tests/) has passed locallypytest tests/integration/motors/test_cluster_motor.py) have passed locallyCHANGELOG.mdhas been updated (if relevant)Current behavior
Currently, RocketPy does not have native support for clustered motor configurations.
Users attempting to simulate a cluster (e.g., 3x or 4x motors) must manually create a "custom" single motor with scaled thrust curves and manually calculate the complex inertia changes caused by the off-axis mass distribution using external tools. This process is error-prone and does not dynamically update the inertia tensor correctly as propellant is consumed.
New behavior
This PR introduces a new
ClusterMotorclass inrocketpy.motors.SolidMotorobject, preserving all its internal ballistics.Breaking change
To do
Once implementation has been validated, we will still need to improve the draw() function to enable the drawing of grouped projects. For now, I have only implemented a rear view, so that the placement of the engines is visible.
This feature was developed by the French rocket science association IPSA SPACE SYSTEMS. Come say hello to us on Instagram!
https://www.instagram.com/ipsa_space_systems/