Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Orekit
Orekit
Commits
d64ebe44
Commit
d64ebe44
authored
Dec 24, 2021
by
Luc Maisonobe
Browse files
Moved around classes for maneuvers jacobians.
parent
92ce876f
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
src/main/java/org/orekit/
propagation/DurationJacobianColumnGenerator
.java
→
src/main/java/org/orekit/
forces/maneuvers/jacobians/Duration
.java
View file @
d64ebe44
...
...
@@ -14,7 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.orekit.propagation
;
package
org.orekit.forces.maneuvers.jacobians
;
import
org.orekit.propagation.AdditionalStateProvider
;
import
org.orekit.propagation.SpacecraftState
;
/** Generator for one column of a Jacobian matrix for special case of maneuver duration.
* <p>
...
...
@@ -23,10 +26,10 @@ package org.orekit.propagation;
* </p>
* @author Luc Maisonobe
* @since 11.1
* @see MedianDate
JacobianColumnGenerator
* @see TriggerDate
JacobianColumnGenerator
* @see MedianDate
* @see TriggerDate
*/
public
class
Duration
JacobianColumnGenerator
implements
AdditionalStateProvider
{
public
class
Duration
implements
AdditionalStateProvider
{
/** Name of the parameter corresponding to the start date. */
private
final
String
startName
;
...
...
@@ -42,7 +45,7 @@ public class DurationJacobianColumnGenerator implements AdditionalStateProvider
* @param stopName name of the parameter corresponding to the stop date
* @param columnName name of the parameter corresponding to the column
*/
public
Duration
JacobianColumnGenerator
(
final
String
startName
,
final
String
stopName
,
final
String
columnName
)
{
public
Duration
(
final
String
startName
,
final
String
stopName
,
final
String
columnName
)
{
this
.
startName
=
startName
;
this
.
stopName
=
stopName
;
this
.
columnName
=
columnName
;
...
...
src/main/java/org/orekit/
propagation/MedianDateJacobianColumnGenerator
.java
→
src/main/java/org/orekit/
forces/maneuvers/jacobians/MedianDate
.java
View file @
d64ebe44
...
...
@@ -14,7 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.orekit.propagation
;
package
org.orekit.forces.maneuvers.jacobians
;
import
org.orekit.propagation.AdditionalStateProvider
;
import
org.orekit.propagation.SpacecraftState
;
/** Generator for one column of a Jacobian matrix for special case of maneuver median date.
* <p>
...
...
@@ -23,10 +26,10 @@ package org.orekit.propagation;
* </p>
* @author Luc Maisonobe
* @since 11.1
* @see Duration
JacobianColumnGenerator
* @see TriggerDate
JacobianColumnGenerator
* @see Duration
* @see TriggerDate
*/
public
class
MedianDate
JacobianColumnGenerator
implements
AdditionalStateProvider
{
public
class
MedianDate
implements
AdditionalStateProvider
{
/** Name of the parameter corresponding to the start date. */
private
final
String
startName
;
...
...
@@ -42,7 +45,7 @@ public class MedianDateJacobianColumnGenerator implements AdditionalStateProvide
* @param stopName name of the parameter corresponding to the stop date
* @param columnName name of the parameter corresponding to the column
*/
public
MedianDate
JacobianColumnGenerator
(
final
String
startName
,
final
String
stopName
,
final
String
columnName
)
{
public
MedianDate
(
final
String
startName
,
final
String
stopName
,
final
String
columnName
)
{
this
.
startName
=
startName
;
this
.
stopName
=
stopName
;
this
.
columnName
=
columnName
;
...
...
src/main/java/org/orekit/
propagation/TriggerDateJacobianColumnGenerator
.java
→
src/main/java/org/orekit/
forces/maneuvers/jacobians/TriggerDate
.java
View file @
d64ebe44
...
...
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.orekit.
propagation
;
package
org.orekit.
forces.maneuvers.jacobians
;
import
org.hipparchus.geometry.euclidean.threed.Vector3D
;
import
org.hipparchus.linear.MatrixUtils
;
...
...
@@ -23,6 +23,8 @@ import org.hipparchus.linear.RealMatrix;
import
org.hipparchus.linear.RealVector
;
import
org.orekit.forces.maneuvers.Maneuver
;
import
org.orekit.forces.maneuvers.trigger.ManeuverTriggersResetter
;
import
org.orekit.propagation.AdditionalStateProvider
;
import
org.orekit.propagation.SpacecraftState
;
import
org.orekit.time.AbsoluteDate
;
import
org.orekit.utils.TimeSpanMap
;
...
...
@@ -78,10 +80,10 @@ import org.orekit.utils.TimeSpanMap;
* </p>
* @author Luc Maisonobe
* @since 11.1
* @see MedianDate
JacobianColumnGenerator
* @see Duration
JacobianColumnGenerator
* @see MedianDate
* @see Duration
*/
public
class
TriggerDate
JacobianColumnGenerator
public
class
TriggerDate
implements
AdditionalStateProvider
,
ManeuverTriggersResetter
{
/** Dimension of the state. */
...
...
@@ -97,10 +99,13 @@ public class TriggerDateJacobianColumnGenerator
private
final
String
stmName
;
/** Name of the parameter corresponding to the column. */
private
final
String
columnName
;
private
final
String
triggerName
;
/** Mass depletion effect. */
private
final
MassDepletionDelay
massDepletionDelay
;
/** Start/stop management flag. */
private
boolean
manageStart
;
private
final
boolean
manageStart
;
/** Maneuver force model. */
private
final
Maneuver
maneuver
;
...
...
@@ -119,28 +124,28 @@ public class TriggerDateJacobianColumnGenerator
/** Simple constructor.
* @param stmName name of State Transition Matrix state
* @param
column
Name name of the parameter corresponding to the column
* @param
trigger
Name name of the parameter corresponding to the
trigger date
column
* @param manageStart if true, we compute derivatives with respect to maneuver start
* @param maneuver maneuver force model
* @param threshold event detector threshold
*/
public
TriggerDate
JacobianColumnGenerator
(
final
String
stmName
,
final
String
columnName
,
final
boolean
manageStart
,
final
Maneuver
maneuver
,
final
double
threshold
)
{
this
.
stm
Name
=
stm
Name
;
this
.
columnName
=
columnName
;
this
.
manageStart
=
manageStart
;
this
.
maneuver
=
maneuver
;
this
.
threshold
=
threshold
;
this
.
contribution
=
null
;
this
.
trigger
=
null
;
this
.
forward
=
true
;
public
TriggerDate
(
final
String
stmName
,
final
String
triggerName
,
final
boolean
manageStart
,
final
Maneuver
maneuver
,
final
double
threshold
)
{
this
.
stmName
=
stmName
;
this
.
trigger
Name
=
trigger
Name
;
this
.
massDepletionDelay
=
new
MassDepletionDelay
(
triggerName
,
manageStart
,
maneuver
)
;
this
.
manageStart
=
manageStart
;
this
.
maneuver
=
maneuver
;
this
.
threshold
=
threshold
;
this
.
contribution
=
null
;
this
.
trigger
=
null
;
this
.
forward
=
true
;
}
/** {@inheritDoc} */
@Override
public
String
getName
()
{
return
column
Name
;
return
trigger
Name
;
}
/** {@inheritDoc}
...
...
@@ -150,7 +155,14 @@ public class TriggerDateJacobianColumnGenerator
*/
@Override
public
boolean
yield
(
final
SpacecraftState
state
)
{
return
!
state
.
hasAdditionalState
(
stmName
);
return
!(
state
.
hasAdditionalState
(
stmName
)
&&
state
.
hasAdditionalState
(
massDepletionDelay
.
getName
()));
}
/** Get the mass depletion effect processor.
* @return mass depletion effect processor
*/
public
MassDepletionDelay
getMassDepletionDelay
()
{
return
massDepletionDelay
;
}
/** {@inheritDoc} */
...
...
@@ -174,34 +186,29 @@ public class TriggerDateJacobianColumnGenerator
/** {@inheritDoc} */
@Override
public
double
[]
getAdditionalState
(
final
SpacecraftState
state
)
{
// we check contribution rather than triggered because this method
// is called after maneuverTriggered and before resetState,
// when preparing the old state to be reset
final
double
[]
c
=
contribution
==
null
?
null
:
contribution
.
get
(
state
.
getDate
());
if
(
c
==
null
)
{
// no thrust, no effect
return
ZERO
;
}
else
{
// p
art of the effect due to the acceleration performed at
trigger
tim
e
// p
rimary effect: full maneuver contribution at (delayed)
trigger
dat
e
final
double
[]
effect
=
getStm
(
state
).
operate
(
c
);
if
(
trigger
!=
null
)
{
// part of the effect due to mass change influence on current acceleration
final
double
[]
parameters
=
maneuver
.
getParameters
();
final
Vector3D
acceleration
=
maneuver
.
acceleration
(
state
,
parameters
);
final
double
flowRate
=
maneuver
.
getPropulsionModel
().
getMassDerivatives
(
state
,
parameters
);
final
double
ratio
=
state
.
getDate
().
durationFrom
(
trigger
)
*
flowRate
/
state
.
getMass
();
effect
[
3
]
+=
ratio
*
acceleration
.
getX
();
effect
[
4
]
+=
ratio
*
acceleration
.
getY
();
effect
[
5
]
+=
ratio
*
acceleration
.
getZ
();
// secondary effect: maneuver change throughout thrust as mass depletion is delayed
final
double
[]
secondary
=
state
.
getAdditionalState
(
massDepletionDelay
.
getName
());
// sum up both effects
for
(
int
i
=
0
;
i
<
effect
.
length
;
++
i
)
{
effect
[
i
]
+=
secondary
[
i
];
}
return
effect
;
}
}
/** {@inheritDoc}*/
...
...
@@ -224,7 +231,7 @@ public class TriggerDateJacobianColumnGenerator
final
Vector3D
acceleration
=
maneuver
.
acceleration
(
stateWhenFiring
,
maneuver
.
getParameters
());
// initialize derivatives computation
final
double
sign
=
(
forward
^
manageStart
)
?
+
1
:
-
1
;
final
double
sign
=
(
forward
==
manageStart
)
?
-
1
:
+
1
;
final
RealVector
rhs
=
MatrixUtils
.
createRealVector
(
STATE_DIMENSION
);
rhs
.
setEntry
(
3
,
sign
*
acceleration
.
getX
());
rhs
.
setEntry
(
4
,
sign
*
acceleration
.
getY
());
...
...
src/main/java/org/orekit/propagation/numerical/NumericalPropagator.java
View file @
d64ebe44
...
...
@@ -41,6 +41,9 @@ import org.orekit.forces.ForceModel;
import
org.orekit.forces.gravity.NewtonianAttraction
;
import
org.orekit.forces.inertia.InertialForces
;
import
org.orekit.forces.maneuvers.Maneuver
;
import
org.orekit.forces.maneuvers.jacobians.Duration
;
import
org.orekit.forces.maneuvers.jacobians.MedianDate
;
import
org.orekit.forces.maneuvers.jacobians.TriggerDate
;
import
org.orekit.forces.maneuvers.trigger.AbstractManeuverTriggers
;
import
org.orekit.forces.maneuvers.trigger.ManeuverTriggers
;
import
org.orekit.frames.Frame
;
...
...
@@ -49,13 +52,10 @@ import org.orekit.orbits.OrbitType;
import
org.orekit.orbits.PositionAngle
;
import
org.orekit.propagation.AbstractMatricesHarvester
;
import
org.orekit.propagation.AdditionalStateProvider
;
import
org.orekit.propagation.DurationJacobianColumnGenerator
;
import
org.orekit.propagation.MatricesHarvester
;
import
org.orekit.propagation.MedianDateJacobianColumnGenerator
;
import
org.orekit.propagation.PropagationType
;
import
org.orekit.propagation.Propagator
;
import
org.orekit.propagation.SpacecraftState
;
import
org.orekit.propagation.TriggerDateJacobianColumnGenerator
;
import
org.orekit.propagation.events.EventDetector
;
import
org.orekit.propagation.events.ParameterDrivenDateIntervalDetector
;
import
org.orekit.propagation.integration.AbstractIntegratedPropagator
;
...
...
@@ -503,22 +503,22 @@ public class NumericalPropagator extends AbstractIntegratedPropagator {
map
(
d
->
(
ParameterDrivenDateIntervalDetector
)
d
).
forEach
(
d
->
{
if
(
d
.
getStartDriver
().
isSelected
()
||
d
.
getMedianDriver
().
isSelected
()
||
d
.
getDurationDriver
().
isSelected
())
{
final
TriggerDate
JacobianColumnGenerator
start
=
final
TriggerDate
start
=
manageTriggerDate
(
stmName
,
maneuver
,
amt
,
d
.
getStartDriver
().
getName
(),
true
,
d
.
getThreshold
());
names
.
add
(
start
.
getName
());
}
if
(
d
.
getStopDriver
().
isSelected
()
||
d
.
getMedianDriver
().
isSelected
()
||
d
.
getDurationDriver
().
isSelected
())
{
final
TriggerDate
JacobianColumnGenerator
stop
=
final
TriggerDate
stop
=
manageTriggerDate
(
stmName
,
maneuver
,
amt
,
d
.
getStopDriver
().
getName
(),
false
,
d
.
getThreshold
());
names
.
add
(
stop
.
getName
());
}
if
(
d
.
getMedianDriver
().
isSelected
())
{
final
MedianDate
JacobianColumnGenerator
median
=
final
MedianDate
median
=
manageMedianDate
(
d
.
getStartDriver
().
getName
(),
d
.
getStopDriver
().
getName
(),
d
.
getMedianDriver
().
getName
());
names
.
add
(
median
.
getName
());
}
if
(
d
.
getDurationDriver
().
isSelected
())
{
final
Duration
JacobianColumnGenerator
duration
=
final
Duration
duration
=
manageManeuverDuration
(
d
.
getStartDriver
().
getName
(),
d
.
getStopDriver
().
getName
(),
d
.
getDurationDriver
().
getName
());
names
.
add
(
duration
.
getName
());
}
...
...
@@ -542,36 +542,37 @@ public class NumericalPropagator extends AbstractIntegratedPropagator {
* @return generator for the date driver
* @since 11.1
*/
private
TriggerDate
JacobianColumnGenerator
manageTriggerDate
(
final
String
stmName
,
final
Maneuver
maneuver
,
final
AbstractManeuverTriggers
amt
,
final
String
driverName
,
final
boolean
start
,
final
double
threshold
)
{
private
TriggerDate
manageTriggerDate
(
final
String
stmName
,
final
Maneuver
maneuver
,
final
AbstractManeuverTriggers
amt
,
final
String
driverName
,
final
boolean
start
,
final
double
threshold
)
{
TriggerDate
JacobianColumnGenerator
triggerGenerator
=
null
;
TriggerDate
triggerGenerator
=
null
;
// check if we already have set up the provider
for
(
final
AdditionalStateProvider
provider
:
getAdditionalStateProviders
())
{
if
(
provider
instanceof
TriggerDate
JacobianColumnGenerator
&&
if
(
provider
instanceof
TriggerDate
&&
provider
.
getName
().
equals
(
driverName
))
{
// the Jacobian column generator has already been set up in a previous propagation
triggerGenerator
=
(
TriggerDate
JacobianColumnGenerator
)
provider
;
triggerGenerator
=
(
TriggerDate
)
provider
;
break
;
}
}
if
(
triggerGenerator
==
null
)
{
// this is the first time we need the Jacobian column generator, create it
triggerGenerator
=
new
TriggerDateJacobianColumnGenerator
(
stmName
,
driverName
,
start
,
maneuver
,
threshold
);
triggerGenerator
=
new
TriggerDate
(
stmName
,
driverName
,
start
,
maneuver
,
threshold
);
amt
.
addResetter
(
triggerGenerator
);
addAdditionalDerivativesProvider
(
triggerGenerator
.
getMassDepletionDelay
());
addAdditionalStateProvider
(
triggerGenerator
);
}
if
(!
getInitialIntegrationState
().
hasAdditionalState
(
driverName
))
{
// add the initial Jacobian column if it is not already there
// (perhaps due to a previous propagation)
setInitialColumn
(
triggerGenerator
.
getMassDepletionDelay
().
getName
(),
new
double
[
6
]);
setInitialColumn
(
driverName
,
getHarvester
().
getInitialJacobianColumn
(
driverName
));
}
...
...
@@ -586,23 +587,23 @@ public class NumericalPropagator extends AbstractIntegratedPropagator {
* @return generator for the median driver
* @since 11.1
*/
private
MedianDate
JacobianColumnGenerator
manageMedianDate
(
final
String
startName
,
final
String
stopName
,
final
String
medianName
)
{
private
MedianDate
manageMedianDate
(
final
String
startName
,
final
String
stopName
,
final
String
medianName
)
{
MedianDate
JacobianColumnGenerator
medianGenerator
=
null
;
MedianDate
medianGenerator
=
null
;
// check if we already have set up the provider
for
(
final
AdditionalStateProvider
provider
:
getAdditionalStateProviders
())
{
if
(
provider
instanceof
MedianDate
JacobianColumnGenerator
&&
if
(
provider
instanceof
MedianDate
&&
provider
.
getName
().
equals
(
medianName
))
{
// the Jacobian column generator has already been set up in a previous propagation
medianGenerator
=
(
MedianDate
JacobianColumnGenerator
)
provider
;
medianGenerator
=
(
MedianDate
)
provider
;
break
;
}
}
if
(
medianGenerator
==
null
)
{
// this is the first time we need the Jacobian column generator, create it
medianGenerator
=
new
MedianDate
JacobianColumnGenerator
(
startName
,
stopName
,
medianName
);
medianGenerator
=
new
MedianDate
(
startName
,
stopName
,
medianName
);
addAdditionalStateProvider
(
medianGenerator
);
}
...
...
@@ -623,23 +624,23 @@ public class NumericalPropagator extends AbstractIntegratedPropagator {
* @return generator for the median driver
* @since 11.1
*/
private
Duration
JacobianColumnGenerator
manageManeuverDuration
(
final
String
startName
,
final
String
stopName
,
final
String
durationName
)
{
private
Duration
manageManeuverDuration
(
final
String
startName
,
final
String
stopName
,
final
String
durationName
)
{
Duration
JacobianColumnGenerator
durationGenerator
=
null
;
Duration
durationGenerator
=
null
;
// check if we already have set up the provider
for
(
final
AdditionalStateProvider
provider
:
getAdditionalStateProviders
())
{
if
(
provider
instanceof
Duration
JacobianColumnGenerator
&&
if
(
provider
instanceof
Duration
&&
provider
.
getName
().
equals
(
durationName
))
{
// the Jacobian column generator has already been set up in a previous propagation
durationGenerator
=
(
Duration
JacobianColumnGenerator
)
provider
;
durationGenerator
=
(
Duration
)
provider
;
break
;
}
}
if
(
durationGenerator
==
null
)
{
// this is the first time we need the Jacobian column generator, create it
durationGenerator
=
new
Duration
JacobianColumnGenerator
(
startName
,
stopName
,
durationName
);
durationGenerator
=
new
Duration
(
startName
,
stopName
,
durationName
);
addAdditionalStateProvider
(
durationGenerator
);
}
...
...
src/test/java/org/orekit/
propagation/numerical
/TriggersDerivativesTest.java
→
src/test/java/org/orekit/
forces/maneuvers/jacobians
/TriggersDerivativesTest.java
View file @
d64ebe44
This diff is collapsed.
Click to expand it.
src/test/java/org/orekit/propagation/numerical/StateTransitionMatrixGeneratorTest.java
View file @
d64ebe44
...
...
@@ -30,8 +30,10 @@ import org.hipparchus.analysis.differentiation.DerivativeStructure;
import
org.hipparchus.exception.LocalizedCoreFormats
;
import
org.hipparchus.geometry.euclidean.threed.FieldRotation
;
import
org.hipparchus.geometry.euclidean.threed.FieldVector3D
;
import
org.hipparchus.geometry.euclidean.threed.Rotation
;
import
org.hipparchus.geometry.euclidean.threed.Vector3D
;
import
org.hipparchus.linear.MatrixUtils
;
import
org.hipparchus.linear.RealMatrix
;
import
org.hipparchus.ode.nonstiff.AdaptiveStepsizeIntegrator
;
import
org.hipparchus.ode.nonstiff.DormandPrince54Integrator
;
import
org.hipparchus.ode.nonstiff.DormandPrince853Integrator
;
...
...
@@ -41,14 +43,21 @@ import org.junit.Before;
import
org.junit.Test
;
import
org.orekit.Utils
;
import
org.orekit.attitudes.Attitude
;
import
org.orekit.attitudes.AttitudeProvider
;
import
org.orekit.attitudes.InertialProvider
;
import
org.orekit.errors.OrekitException
;
import
org.orekit.forces.AbstractForceModel
;
import
org.orekit.forces.ForceModel
;
import
org.orekit.forces.gravity.HolmesFeatherstoneAttractionModel
;
import
org.orekit.forces.gravity.NewtonianAttraction
;
import
org.orekit.forces.gravity.potential.GravityFieldFactory
;
import
org.orekit.forces.gravity.potential.ICGEMFormatReader
;
import
org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider
;
import
org.orekit.forces.gravity.potential.SHMFormatReader
;
import
org.orekit.forces.maneuvers.Maneuver
;
import
org.orekit.forces.maneuvers.jacobians.TriggerDate
;
import
org.orekit.forces.maneuvers.propulsion.BasicConstantThrustPropulsionModel
;
import
org.orekit.forces.maneuvers.propulsion.PropulsionModel
;
import
org.orekit.forces.maneuvers.trigger.DateBasedManeuverTriggers
;
import
org.orekit.frames.Frame
;
import
org.orekit.frames.FramesFactory
;
import
org.orekit.orbits.CartesianOrbit
;
...
...
@@ -56,12 +65,15 @@ import org.orekit.orbits.KeplerianOrbit;
import
org.orekit.orbits.Orbit
;
import
org.orekit.orbits.OrbitType
;
import
org.orekit.orbits.PositionAngle
;
import
org.orekit.propagation.AdditionalStateProvider
;
import
org.orekit.propagation.FieldSpacecraftState
;
import
org.orekit.propagation.MatricesHarvester
;
import
org.orekit.propagation.PropagatorsParallelizer
;
import
org.orekit.propagation.SpacecraftState
;
import
org.orekit.propagation.events.EventDetector
;
import
org.orekit.propagation.events.FieldEventDetector
;
import
org.orekit.propagation.integration.AbstractIntegratedPropagator
;
import
org.orekit.propagation.integration.AdditionalDerivativesProvider
;
import
org.orekit.time.AbsoluteDate
;
import
org.orekit.time.DateComponents
;
import
org.orekit.time.TimeComponents
;
...
...
@@ -76,8 +88,87 @@ public class StateTransitionMatrixGeneratorTest {
@Before
public
void
setUp
()
{
Utils
.
setDataRoot
(
"regular-data:potential/shm-format"
);
GravityFieldFactory
.
addPotentialCoefficientsReader
(
new
SHMFormatReader
(
"^eigen_cg03c_coef$"
,
false
));
Utils
.
setDataRoot
(
"orbit-determination/february-2016:potential/icgem-format"
);
GravityFieldFactory
.
addPotentialCoefficientsReader
(
new
ICGEMFormatReader
(
"eigen-6s-truncated"
,
true
));
}
@Test
public
void
testInterrupt
()
{
final
AbsoluteDate
firing
=
new
AbsoluteDate
(
new
DateComponents
(
2004
,
1
,
2
),
new
TimeComponents
(
4
,
15
,
34.080
),
TimeScalesFactory
.
getUTC
());
final
double
duration
=
200.0
;
// first propagation, covering the maneuver
DateBasedManeuverTriggers
triggers1
=
new
DateBasedManeuverTriggers
(
"MAN_0"
,
firing
,
duration
);
final
NumericalPropagator
propagator1
=
buildPropagator
(
OrbitType
.
EQUINOCTIAL
,
PositionAngle
.
TRUE
,
20
,
firing
,
duration
,
triggers1
);
propagator1
.
getAllForceModels
().
forEach
(
fm
->
fm
.
getParametersDrivers
().
stream
().
filter
(
d
->
d
.
getName
().
equals
(
"MAN_0_START"
)
||
d
.
getName
().
equals
(
NewtonianAttraction
.
CENTRAL_ATTRACTION_COEFFICIENT
)).
forEach
(
d
->
d
.
setSelected
(
true
)));
final
MatricesHarvester
harvester1
=
propagator1
.
setupMatricesComputation
(
"stm"
,
null
,
null
);
final
SpacecraftState
state1
=
propagator1
.
propagate
(
firing
.
shiftedBy
(
2
*
duration
));
final
RealMatrix
stm1
=
harvester1
.
getStateTransitionMatrix
(
state1
);
final
RealMatrix
jacobian1
=
harvester1
.
getParametersJacobian
(
state1
);
// second propagation, interrupted during maneuver
DateBasedManeuverTriggers
triggers2
=
new
DateBasedManeuverTriggers
(
"MAN_0"
,
firing
,
duration
);
final
NumericalPropagator
propagator2
=
buildPropagator
(
OrbitType
.
EQUINOCTIAL
,
PositionAngle
.
TRUE
,
20
,
firing
,
duration
,
triggers2
);
propagator2
.
getAllForceModels
().
forEach
(
fm
->
fm
.
getParametersDrivers
().
stream
().
filter
(
d
->
d
.
getName
().
equals
(
"MAN_0_START"
)
||
d
.
getName
().
equals
(
NewtonianAttraction
.
CENTRAL_ATTRACTION_COEFFICIENT
)).
forEach
(
d
->
d
.
setSelected
(
true
)));
// some additional providers for test coverage
final
StateTransitionMatrixGenerator
dummyStmGenerator
=
new
StateTransitionMatrixGenerator
(
"dummy-1"
,
Collections
.
emptyList
(),
propagator2
.
getAttitudeProvider
());
propagator2
.
addAdditionalDerivativesProvider
(
dummyStmGenerator
);
propagator2
.
setInitialState
(
propagator2
.
getInitialState
().
addAdditionalState
(
dummyStmGenerator
.
getName
(),
new
double
[
36
]));
propagator2
.
addAdditionalDerivativesProvider
(
new
IntegrableJacobianColumnGenerator
(
dummyStmGenerator
,
"dummy-2"
));
propagator2
.
setInitialState
(
propagator2
.
getInitialState
().
addAdditionalState
(
"dummy-2"
,
new
double
[
6
]));
propagator2
.
addAdditionalDerivativesProvider
(
new
AdditionalDerivativesProvider
()
{
public
String
getName
()
{
return
"dummy-3"
;
}
public
int
getDimension
()
{
return
1
;
}
public
double
[]
derivatives
(
SpacecraftState
s
)
{
return
new
double
[
1
];
}
});
propagator2
.
setInitialState
(
propagator2
.
getInitialState
().
addAdditionalState
(
"dummy-3"
,
new
double
[
1
]));
propagator2
.
addAdditionalStateProvider
(
new
TriggerDate
(
dummyStmGenerator
.
getName
(),
"dummy-4"
,
true
,
(
Maneuver
)
propagator2
.
getAllForceModels
().
get
(
1
),
1.0
e
-
6
));
propagator2
.
addAdditionalStateProvider
(
new
AdditionalStateProvider
()
{
public
String
getName
()
{
return
"dummy-5"
;
}
public
double
[]
getAdditionalState
(
SpacecraftState
s
)
{
return
new
double
[
1
];
}
});
final
MatricesHarvester
harvester2
=
propagator2
.
setupMatricesComputation
(
"stm"
,
null
,
null
);
final
SpacecraftState
intermediate
=
propagator2
.
propagate
(
firing
.
shiftedBy
(
0.5
*
duration
));
final
RealMatrix
stmI
=
harvester2
.
getStateTransitionMatrix
(
intermediate
);
final
RealMatrix
jacobianI
=
harvester2
.
getParametersJacobian
(
intermediate
);
// intermediate state has really different matrices, they are still building up
Assert
.
assertEquals
(
0.1253
,
stmI
.
subtract
(
stm1
).
getNorm1
()
/
stm1
.
getNorm1
(),
1.0
e
-
4
);
Assert
.
assertEquals
(
0.0165
,
jacobianI
.
subtract
(
jacobian1
).
getNorm1
()
/
jacobian1
.
getNorm1
(),
1.0
e
-
4
);
// restarting propagation where we left it
final
SpacecraftState
state2
=
propagator2
.
propagate
(
firing
.
shiftedBy
(
2
*
duration
));
final
RealMatrix
stm2
=
harvester2
.
getStateTransitionMatrix
(
state2
);
final
RealMatrix
jacobian2
=
harvester2
.
getParametersJacobian
(
state2
);
// after completing the two-stage propagation, we get the same matrices
Assert
.
assertEquals
(
0.0
,
stm2
.
subtract
(
stm1
).
getNorm1
(),
1.0
e
-
13
*
stm1
.
getNorm1
());
Assert
.
assertEquals
(
0.0
,
jacobian2
.
subtract
(
jacobian1
).
getNorm1
(),
8.0
e
-
13
*
jacobian1
.
getNorm1
());
}
/**
...
...
@@ -521,6 +612,67 @@ public class StateTransitionMatrixGeneratorTest {
}
private
NumericalPropagator
buildPropagator
(
final
OrbitType
orbitType
,
final
PositionAngle
positionAngle
,
final
int
degree
,
final
AbsoluteDate
firing
,
final
double
duration
,
final
DateBasedManeuverTriggers
triggers
)
{
final
AttitudeProvider
attitudeProvider
=
buildAttitudeProvider
();
SpacecraftState
initialState
=
buildInitialState
(
attitudeProvider
);
final
double
isp
=
318
;
final
double
f
=
420
;
PropulsionModel
propulsionModel
=
new
BasicConstantThrustPropulsionModel
(
f
,
isp
,
Vector3D
.
PLUS_I
,
"ABM"
);
double
[][]
tol
=
NumericalPropagator
.
tolerances
(
0.01
,
initialState
.
getOrbit
(),
orbitType
);
AdaptiveStepsizeIntegrator
integrator
=
new
DormandPrince853Integrator
(
0.001
,
1000
,
tol
[
0
],
tol
[
1
]);
integrator
.
setInitialStepSize
(
60
);
final
NumericalPropagator
propagator
=
new
NumericalPropagator
(
integrator
);
propagator
.
setOrbitType
(
orbitType
);
propagator
.
setPositionAngleType
(
positionAngle
);
propagator
.
setAttitudeProvider
(
attitudeProvider
);
if
(
degree
>
0
)
{
propagator
.
addForceModel
(
new
HolmesFeatherstoneAttractionModel
(
FramesFactory
.
getITRF
(
IERSConventions
.
IERS_2010
,
true
),
GravityFieldFactory
.
getNormalizedProvider
(
degree
,
degree
)));
}
final
Maneuver
maneuver
=
new
Maneuver
(
null
,
triggers
,
propulsionModel
);
propagator
.
addForceModel
(
maneuver
);
propagator
.
addAdditionalStateProvider
(
new
AdditionalStateProvider
()
{
public
String
getName
()
{
return
triggers
.
getName
().
concat
(
"-acc"
);
}
public
double
[]
getAdditionalState
(
SpacecraftState
state
)
{
double
[]
parameters
=
Arrays
.
copyOfRange
(
maneuver
.
getParameters
(),
0
,
propulsionModel
.
getParametersDrivers
().
size
());
return
new
double
[]
{
propulsionModel
.
getAcceleration
(
state
,
state
.
getAttitude
(),
parameters
).
getNorm
()
};
}
});
propagator
.
setInitialState
(
initialState
);
return
propagator
;
}
private
SpacecraftState
buildInitialState
(
final
AttitudeProvider
attitudeProvider
)
{
final
double
mass
=
2500
;
final
double
a
=
24396159
;
final
double
e
=
0.72831215
;