Turns out the motor digest hash function can have collisions. Since the digest is stored in the .ork file we don't want to rewrite it as that will cause *lots* of spurious "thrust curves don't match" warnings, and I really don't want to get into looking up by some sort of new digest if it exists else old digest.
Since some motor description fields are also stored in the .ork file, I'm effectively using these as a key to resolve collisions. Now that I need to pass them in to the findMotor() method, I'm merging it with findMotors() (which searches based on motor descriptions)
New combined method returns all motors that match digest and description;
If there are none returns all motors that match digest;
If there are none returns all motors that match description (may be empty)
Passing a digest and no other description emulates the behavior of the old findMotor() (but it may return more than one motor).
Passing description elements and no digest duplicates the behavior of the old findMotors()
mass calculations now correctly treat the center-of-mass offset as relative to the individual
component (whereas, previously, it was an absolute offset / relative to the center of the rocket)
One thing to mention is I had a choice of either adding a special case for the rocket itself, or change the result of isStageActive for stage -1 to be true instead of false as previously. I couldn't see a place where the previous version mattered, so I changed it.
Adds the MotorClusterState from the current SimulationState to the MassCalculation constructor. The ignition time of each motor is subtracted from the current simulationTime to calculate its current mass.
MassCalculation is also used for static analysis; in this case a synthetic time is passed (and there is no SimulationState). In this case, a null is passed in to the MassCalculation constructor; whether or not this the case is used to determine whether or not to calculate a motor time based on its ignition time.
Also clamp motorTime from MotorClusterState to be no less than 0 when calculating motor mass.
rather than separating out the propellant data. This commit clarifies
the code by replacing instances of "propellant" with "motor" in
variable names and messages where appropriate.
It does not update the translations into other languages.
Background: a motor that has burned out can be in one of two states: DELAYING (the delay charge has not yet fired) or SPENT (either the delay charge, if any, has fired or there was no delay charge).
The existing SimulationStatus:getActiveMotors() method returned a list of motors that were active for the stage, and which were not SPENT. The test for the warning redudantly tested for a SPENT motor, still didn't test for a DELAYING motr, and consequently set the warning.
This PR
(1) adds a boolean MotorClusterStatus:isDelaying() method, analogous to the existing state test methods
(2) modifies SimulationStatus.java:getActiveMotors() to return all the motors, not just the ones that aren't SPENT. This is to improve consistency with FlightConfiguration:getActiveMotors(), and to make for a more consistent usage between the two calls to the method.
(3) adds !isDelaying() to the test for the warning.