Tudat / tudat

NOTE: This Tudat version is no longer supported. See https://docs.tudat.space/en/stable/ and https://github.com/tudat-team/tudat-bundle for the new version
BSD 3-Clause "New" or "Revised" License
87 stars 143 forks source link

When using multiple termination conditions, which is the one that stopped the propagation? #646

Closed liampieters closed 4 years ago

liampieters commented 4 years ago

Hi all!

I propagate a laser satellite and a set of debris objects orbiting Earth. I want to stop the propagation when the laser comes within 800 km of any debris object. From there I start a second propagation where I add ablative deceleration to the respective object. But I would like to know with which debris object the laser has the interaction in order to add the acceleration to the right object. Is there any way of figuring out which termination condition was the one that stopped the propagation? Below I have stated the configuration of the terminationSettingsList. I use a for loop and add a termination condition between the laser 'Asterix' and the representative debris object 'debrisNumber' that refers to a previously created debris object with its own characteristics. Ideally I want to know what 'debrisNumber' terminated the propagation.

Thanks a lot in advance!! Kind regards, Liam

std::vector< std::shared_ptr< PropagationTerminationSettings > > terminationSettingsList ;
        for( unsigned int j = 0; j < debrisFragments.size( ); j++ )
        {
            // Define termination conditions
            const double LowerLimit = 800.0e3;
            std::string debrisNumber = "debris" + std::to_string( j + 1 );

            std::shared_ptr< SingleDependentVariableSaveSettings > relativeDistanceTermination =
                  std::make_shared< SingleDependentVariableSaveSettings >(
                      relative_distance_dependent_variable, "Asterix", debrisNumber );

            std::shared_ptr< PropagationTerminationSettings > terminationDistance =
                  std::make_shared< PropagationDependentVariableTerminationSettings >(
                        relativeDistanceTermination, LowerLimit, true );

            terminationSettingsList.push_back( terminationDistance ) ;

            std::shared_ptr< PropagationTerminationSettings > terminationSettingsInteraction =
                  std::make_shared< PropagationHybridTerminationSettings>( terminationSettingsList, true);

        }
SamFayolle commented 4 years ago

Hi Liam,

First of all, sorry for the delay, Tudat support is a bit limited during the summer period :)

Concerning your question, you can use the function getPropagationTerminationReason( ) from your DynamicsSimulator object. This will return a pointer to a PropagationTerminationDetails object. Since you are using hybrid termination conditions here, it will more precisely return a PropagationTerminationDetailsFromHybridCondition pointer, derived from base class PropagationTerminationDetails. You can check how it is exactly defined here: https://github.com/Tudat/tudat/blob/master/Tudat/SimulationSetup/PropagationSetup/propagationTermination.h#L318-L391 . In particular, the function getWasConditionMetWhenStopping( ) that you can call from the PropagationTerminationDetailsFromHybridCondition object will give you exactly what you need. It returns a vector of booleans denoting whether the several termination conditions are met or not (booleans in this vector follow the same order as the one in which you provided your termination conditions).

I hope this will help you a bit!

Best of luck,

Marie

liampieters commented 4 years ago

Hi Marie,

No problem of course, thanks for the reply! The function getWasConditionMetWhenStopping( ) indeed sounds like that would solve all my problems! I just can't seem to get it to work though.. I have constructed my Hybrid propagation termination as follows; I loop over the number of debris fragments and compute a distance termination setting for each of them and add them to a terminationSettingList. I then configure the Hybris propagation termination with this list:

        std::shared_ptr< PropagationTerminationSettings > terminationSettingsPropagation =
              std::make_shared< PropagationHybridTerminationSettings>( terminationSettingsList, true);

But the getWasConditionMetWhenStopping( ) function only works on a PropagationTerminationDetailsFromHybridCondition object. And such an object requires a std::shared_ptr< HybridPropagationTerminationCondition > terminationCondition This HybridPropagationTerminationCondition requires a list of termination conditions that are used. However, I get an error whenever I input my terminationList here.. The list that HybridPropagationTerminationCondition requires is a list of PropagationTerminationConditions, but I cant use push_back to make this list. Am I a bit lost or am i overthinking the whole situation? Thanks for any help!! Sorry if this message is a little unclear!

Best, Liam

SamFayolle commented 4 years ago

Hi Liam,

Actually, you can directly retrieve the HybridPropagationTerminationCondition object from your SingleArcDynamicsSimulator object, as follows: std::shared_ptr< HybridPropagationTerminationCondition > hybridPropagationTerminationCondition = std::dynamic_pointer_cast< HybridPropagationTerminationCondition >( dynamicsSimulator.getPropagationTerminationCondition( ) );

And then you can call the function getIsConditionMetWhenStopping from hybridPropagationTerminationCondition and it will return the vector of booleans you are looking for.

Sorry if my former explanations were a bit confusing! I hope this will make it a bit clearer and will help you solving it :)

Marie

liampieters commented 4 years ago

Amazing Marie!! It works flawlessly! Thanks a million!

Best, Liam