Data initialization : Différence entre versions
(→Vehicle) |
|||
(42 révisions intermédiaires par le même utilisateur non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
+ | The main modifications between V11.3 and previous versions are due to the use of original [http://patrius.cnes.fr PATRIUS] classes rather than to use "Custom" classes originally proposed by [http://genopus.cnes.fr GENOPUS]. Anyway, some "Custom" classes still remain as [http://patrius.cnes.fr PATRIUS] classes are not sufficiently consistent. | ||
+ | |||
+ | |||
== Orbit == | == Orbit == | ||
Ligne 29 : | Ligne 32 : | ||
:* '''NOTHING''' (all options set to null) | :* '''NOTHING''' (all options set to null) | ||
:* '''ONLY_PREC_NUT''' (only precession and nutation) | :* '''ONLY_PREC_NUT''' (only precession and nutation) | ||
− | :* '''FACTORY''' (equivalent to the most complete definition as in the <font color=#FF8C00>GUI</font>) | + | :* '''FACTORY''' (equivalent to the most complete definition as in the <font color=#FF8C00 title="Graphical User Interface">GUI</font>) |
:* '''IGNORE''' (nothing is define internally by <font color=#556B2F>'''PSIMU'''</font> which will take into account the user parametrization previously done) | :* '''IGNORE''' (nothing is define internally by <font color=#556B2F>'''PSIMU'''</font> which will take into account the user parametrization previously done) | ||
== Vehicle == | == Vehicle == | ||
− | In fact, we need to pass both an <font color=#4169E1>Assembly</font> and a <font color=#4169E1>MassProvider</font>. It could seem curious but it is due to the fact that, if we have maneuvers, it will be mandatory to initialize them with the same <font color=#4169E1>MassProvider</font> (see example [[#Maneuvers|here]]). To get them, we | + | Since V11.3, it is no more necessary to pass an <font color=#4169E1>Assembly</font> object but a <font color=#4169E1>Vehicle one</font>. Anyway, it is allways mandatory to pass a <font color=#4169E1>MassProvider</font> object, issued from the <font color=#4169E1>Vehicle</font> one. It could seem curious but it is due to the fact that, if we have maneuvers, it will be mandatory to initialize them with the same <font color=#4169E1>MassProvider</font> (see example [[#Maneuvers|here]]). |
+ | |||
+ | In fact, we need to pass both an <font color=#4169E1>Assembly</font> and a <font color=#4169E1>MassProvider</font>. It could seem curious but it is due to the fact that, if we have maneuvers, it will be mandatory to initialize them with the same <font color=#4169E1>MassProvider</font> (see example [[#Maneuvers|here]]). To get them, we will use the <font color=#4169E1>createAssembly()</font> method given by <font color=#4169E1>Vehicle</font> class. | ||
+ | |||
+ | <syntaxhighlight lang="java"> | ||
+ | final Assembly assembly = vehicle.createAssembly(GCRF); | ||
+ | final MassProvider mm = new MassModel(assembly); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ''<font color=#FF0000>'''Note : for CPU time purpose it is recommanded that the frame (GCRF in the previous example), mandatory in the construction of the vehicle, must be exactly the same that the one used for the propagation.'''</font>'' | ||
+ | |||
+ | In the example below, we will then use the <font color=#4169E1>Vehicle</font> class initializing mass and aerodynamic properties (here no engines and no tanks): | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
Ligne 40 : | Ligne 54 : | ||
final double dryMass = 1000.; | final double dryMass = 1000.; | ||
final MassProperty dryMassProperty = new MassProperty(dryMass); | final MassProperty dryMassProperty = new MassProperty(dryMass); | ||
+ | |||
// Shape | // Shape | ||
− | final | + | final double sref = 5.0; |
− | + | Sphere sphere = new Sphere(sref); | |
− | + | final RightParallelepiped solarPanels = new RightParallelepiped(10., 0., 0.); | |
+ | VehicleSurfaceModel vehicleRefSurface = new VehicleSurfaceModel(sphere, solarPanels); | ||
+ | |||
// Aerodynamic properties | // Aerodynamic properties | ||
final double cd = 2.0; | final double cd = 2.0; | ||
final double cl = 0.; | final double cl = 0.; | ||
− | final | + | final AerodynamicProperties aerodynamicProperties = new AerodynamicProperties(vehicleRefSurface, cd, cl); |
− | + | ||
+ | final Vehicle vehicle = new Vehicle(vehicleRefSurface, null, dryMassProperty, aerodynamicProperties, null, null, null); | ||
− | + | final Assembly assembly = vehicle.createAssembly(GCRF); | |
− | + | ||
− | final Assembly assembly = vehicle. | + | |
final MassProvider mm = new MassModel(assembly); | final MassProvider mm = new MassModel(assembly); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | <font color=#FF0000>''Note : | + | ''<font color=#FF0000>'''Note : due to a PATRIUS anomaly, if the user needs to define solar panels characteristics, it is mandatory to use the Vehicle constructor with all parameters and the VehiculeSurfaceModel including the panels as above (and not a list of Facet); also, do not use the setters methods.'''</font>'' |
== Forces == | == Forces == | ||
− | + | Since V11.3, to define, which forces will be applied along the trajectory, we use the [http://patrius.cnes.fr PATRIUS] <font color=#4169E1>ForceModelsData</font> class (no more necessary to use the specific <font color=#4169E1>CustomForceModels</font> class which does not exist anymore). | |
=== Potential === | === Potential === | ||
Ligne 67 : | Ligne 83 : | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
// Potential | // Potential | ||
− | final ForceModel potential = | + | final ForceModel potential = EarthGravitationalModelFactory.getDroziner(GravityFieldNames.GRGS, "grim4s4_gr", 8, 8, true); |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | final ForceModelsData forces = new ForceModelsData(potential, null, null, null, null, null, null, null, null, null, null, null, null, null, null); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Aerodynamic === | === Aerodynamic === | ||
− | Then we could add an aerodynamic force model | + | Then we could add an aerodynamic force model. Since V11.3, it is no more necessary to use "Custom" classes. |
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
Ligne 115 : | Ligne 99 : | ||
new ExtendedOneAxisEllipsoid(REQ, FLAT, ITRF, "EARTH"); | new ExtendedOneAxisEllipsoid(REQ, FLAT, ITRF, "EARTH"); | ||
− | final | + | final Atmosphere atmosphere = new US76(EARTH); |
− | final | + | final DragForce dragForce = new DragForce(1., atmosphere, assembly); |
forces.setDragForce(dragForce); | forces.setDragForce(dragForce); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | === Solar | + | === Solar radiative pressure === |
− | Here are explained how to use both radiative pressure and rediffused radiative pressure force models | + | Here are explained how to use both radiative pressure and rediffused radiative pressure force models. Again, since V11.3, no more tu use old "Custom" classes. |
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
Ligne 132 : | Ligne 116 : | ||
new ExtendedOneAxisEllipsoid(REQ, FLAT, ITRF, "EARTH"); | new ExtendedOneAxisEllipsoid(REQ, FLAT, ITRF, "EARTH"); | ||
− | + | SolarRadiationPressureEllipsoid radPres = new SolarRadiationPressureEllipsoid(dRef, pRef, sunBody, EARTH, assembly, 1.); | |
− | + | ||
forces.setSolarRadiationPressure(radPres); | forces.setSolarRadiationPressure(radPres); | ||
Ligne 147 : | Ligne 130 : | ||
final double coefIr = 1.; | final double coefIr = 1.; | ||
− | + | RediffusedRadiativeModel rdm = new RediffusedRadiativeModel(inAlbedo, inIr, coefAlbedo, coefIr, assembly); | |
− | + | RediffusedRadiationPressure reDiff = new RediffusedRadiationPressure(sunBody, GCRF, inCorona, inMeridian, inEmissivityModel, rdm); | |
− | + | ||
− | + | forces.setRediffusedRadiationPressure(reDiff); | |
− | + | </syntaxhighlight> | |
− | forces. | + | |
+ | === Specific forces === | ||
+ | |||
+ | It is also possible to add specific forces via the <font color=#4169E1>addForceModel()</font> method as below: | ||
+ | |||
+ | <syntaxhighlight lang="java"> | ||
+ | final Psimu test = new Psimu(...); | ||
+ | test.addForceModel(myForce); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Ligne 162 : | Ligne 151 : | ||
=== Propulsive properties === | === Propulsive properties === | ||
− | First, the user will have to define propulsive properties with engine(s) and tank(s) | + | First, the user will have to define propulsive properties with engine(s) and tank(s). |
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
// Propulsive properties | // Propulsive properties | ||
− | final | + | final PropulsiveProperty engine = new PropulsiveProperty(400, 320.); |
− | final ArrayList< | + | engine.setPartName("ENGINE"); |
+ | final ArrayList<PropulsiveProperty> listOfEngines = new ArrayList<PropulsiveProperty>(); | ||
listOfEngines.add(engine); | listOfEngines.add(engine); | ||
− | final | + | final TankProperty tank = new TankProperty(200.); |
− | final ArrayList< | + | tank.setPartName("TANK"); |
+ | final ArrayList<TankProperty> listOfTanks = new ArrayList<TankProperty>(); | ||
+ | listOfTanks.add(tank); | ||
listOfTanks.add(tank); | listOfTanks.add(tank); | ||
− | final | + | final Vehicle vehicle = new Vehicle(vehicleRefSurface, null, dryMassProperty, null, null, listOfEngines, listOfTanks); |
− | + | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Sequence === | === Sequence === | ||
− | Then, a maneuver sequence will be created thanks to the <font color=#4169E1>CustomManeuverSequence</font> (the [[https://logiciels.cnes.fr/en/node/62?type=desc PATRIUS]] <font color=#4169E1>ManeuverSequence</font> is not directly used as it does not still manage | + | Then, a maneuver sequence will be created thanks to the <font color=#4169E1>CustomManeuverSequence</font> (the [[https://logiciels.cnes.fr/en/node/62?type=desc PATRIUS]] <font color=#4169E1>ManeuverSequence</font> is not directly used as it does not still manage events. |
=== Impulsive maneuver === | === Impulsive maneuver === | ||
− | Here we have an example of a 10m/s impulse maneuver in <font color=#FF8C00>TNW</font>: | + | Here we have an example of a 10m/s impulse maneuver in <font color=#FF8C00>TNW</font> occuring for an <font color=#FF8C00 title="Argument Of Latitude">AOL</font> of 180 degrees: |
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
final double aol = FastMath.toRadians(180.); | final double aol = FastMath.toRadians(180.); | ||
− | final CustomAOLDetector | + | final CustomAOLDetector aolDetector = new CustomAOLDetector(aol, PositionAngle.TRUE, GCRF, MAXCHECK, THRESHOLD, Action.STOP); |
− | + | final IntervalOccurrenceDetectorWrapper impEvent = new IntervalOccurrenceDetectorWrapper(aolDetector, 1, 1, 1, Action.STOP); | |
− | + | ||
− | final | + | |
− | + | ||
− | + | ||
final Vector3D deltaV = new Vector3D(10., 0., 0.); | final Vector3D deltaV = new Vector3D(10., 0., 0.); | ||
− | + | final CustomImpulseManeuver imp = new CustomImpulseManeuver("Impulse maneuver", listOfEngines.get(0), listOfTanks.get(0), LOFType.TNW, impEvent, deltaV, mm); | |
− | final CustomImpulseManeuver imp = | + | |
− | + | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | <font color=#FF0000> | + | ''<font color=#FF0000> |
− | ' | + | '''Note: it is mandatory to configure the event with a STOP action (needed by [[https://logiciels.cnes.fr/en/node/62?type=desc PATRIUS]]).''' |
− | + | </font>'' | |
− | ''Note: it is | + | |
− | </font> | + | |
At last, the user will create the maneuver sequence to pass to <font color=#556B2F>'''PSIMU'''</font>: | At last, the user will create the maneuver sequence to pass to <font color=#556B2F>'''PSIMU'''</font>: | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
− | + | final CustomManeuverSequence manSeq = new CustomManeuverSequence(0., 0.); | |
− | + | manSeq.addManeuver(imp); | |
− | + | ||
− | final CustomManeuverSequence manSeq = new CustomManeuverSequence( | + | |
</syntaxhighlight> | </syntaxhighlight> | ||
Ligne 221 : | Ligne 202 : | ||
final double start = iniOrbit.getKeplerianPeriod(); | final double start = iniOrbit.getKeplerianPeriod(); | ||
final AbsoluteDate startDate = date.shiftedBy(start); | final AbsoluteDate startDate = date.shiftedBy(start); | ||
− | final CustomDateDetector startEvent = | + | final CustomDateDetector startEvent = new CustomDateDetector(startDate, MAXCHECK, THRESHOLD, Action.STOP); |
− | + | final double dur = 1000.; | |
− | + | final AbsoluteDate endDate = startDate.shiftedBy(dur); | |
− | + | final CustomDateDetector stopEvent = new CustomDateDetector(endDate, MAXCHECK, THRESHOLD, Action.STOP); | |
− | final double | + | |
− | + | ||
− | final AbsoluteDate endDate = startDate.shiftedBy( | + | |
− | final CustomDateDetector stopEvent = | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
final Vector3D direction = new Vector3D(-1., 0., 0.); | final Vector3D direction = new Vector3D(-1., 0., 0.); | ||
− | + | CustomConstantManeuver cont = | |
− | + | new CustomConstantManeuver("Continuous maneuver", listOfEngines.get(0), listOfTanks.get(0), LOFType.TNW, startEvent, stopEvent, direction, mm); | |
− | + | ||
− | + | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Ligne 243 : | Ligne 214 : | ||
It is mandatory to get at least one attitude law. With the V11.0, it is not possible to have only one law and it is mandatory to use the “switch” possibility by using the [[https://logiciels.cnes.fr/en/node/62?type=desc PATRIUS]] <font color=#4169E1>AttitudesSequence</font> class. | It is mandatory to get at least one attitude law. With the V11.0, it is not possible to have only one law and it is mandatory to use the “switch” possibility by using the [[https://logiciels.cnes.fr/en/node/62?type=desc PATRIUS]] <font color=#4169E1>AttitudesSequence</font> class. | ||
+ | |||
+ | This example shows how to define a single law (available since V11.1): | ||
+ | |||
+ | <syntaxhighlight lang="java"> | ||
+ | final AttitudeLaw attitudeLaw = new LofOffset(LOFType.TNW); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | This other example uses a switching possibility: | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
Ligne 254 : | Ligne 233 : | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | <font color=#FF0000>''Note : be very careful not to use by default constructors for event detectors as they introduce a STOP event, so your propagation will stop anyway !''</font> | + | ''<font color=#FF0000>'''Note : be very careful not to use by default constructors for event detectors as they introduce a STOP event, so your propagation will stop anyway !'''</font>'' |
== Integration == | == Integration == | ||
− | Then integration data have to be defined. Here an example with <font color=#FF8C00>RK4</font> integrator … | + | Then integration data have to be defined. Here an example with <font color=#FF8C00 title="Runge Kutta 4th order">RK4</font> integrator … |
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
final double duration = 86400.; | final double duration = 86400.; | ||
final double hStop = 120.e+3; | final double hStop = 120.e+3; | ||
− | final PsimuPropagationData propagationData = | + | final PsimuPropagationData propagationData = new PsimuPropagationData(duration, GCRF, hStop); |
− | + | ||
final double step = 5.; | final double step = 5.; | ||
final RK4data integrationData = new RK4data(propagationData, step); | final RK4data integrationData = new RK4data(propagationData, step); | ||
− | <syntaxhighlight> | + | </syntaxhighlight> |
… or with the <font color=#FF8C00>DOP</font> integrator … | … or with the <font color=#FF8C00>DOP</font> integrator … | ||
Ligne 289 : | Ligne 267 : | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
− | final Psimu test = | + | final Psimu test = new Psimu(iniOrbit, EARTH, UserFramesConfsEnum.IGNORE, integrationData, vehicle, mm, forces, manSeq, attitudeLaw); |
− | + | ||
</syntaxhighlight> | </syntaxhighlight> |
Version actuelle en date du 14 mai 2020 à 17:34
The main modifications between V11.3 and previous versions are due to the use of original PATRIUS classes rather than to use "Custom" classes originally proposed by GENOPUS. Anyway, some "Custom" classes still remain as PATRIUS classes are not sufficiently consistent.
Sommaire
Orbit
To initialize an orbit, we simply have to build it using [PATRIUS] object. For example:
final TimeScale TUC = TimeScalesFactory.getUTC(); final AbsoluteDate date = new AbsoluteDate("2010-01-01T12:00:00.000", TUC); final double sma = Constants.WGS84_EARTH_EQUATORIAL_RADIUS + 250.e3; final double ecc = 0.; final double inc = FastMath.toRadians(51.6); final double raan = FastMath.toRadians(0.); final double pa = FastMath.toRadians(0.); final double ano = FastMath.toRadians(0.); final Frame GCRF = FramesFactory.getGCRF(); final KeplerianOrbit iniOrbit = new KeplerianOrbit(sma, ecc, inc, raan, pa, ano, PositionAngle.MEAN, GCRF, date, MU);
Earth features
Data equivalent to the “Earth features” tab are distributed via two arguments:
- 1. A ExtendedOneAxisEllipsoid object which will define the shape of the planet
final ExtendedOneAxisEllipsoid EARTH = new ExtendedOneAxisEllipsoid(REQ, FLAT, ITRF, "EARTH");
- 2. A type of enumerates that will propose some pre-defined configurations as:
- NOTHING (all options set to null)
- ONLY_PREC_NUT (only precession and nutation)
- FACTORY (equivalent to the most complete definition as in the GUI)
- IGNORE (nothing is define internally by PSIMU which will take into account the user parametrization previously done)
Vehicle
Since V11.3, it is no more necessary to pass an Assembly object but a Vehicle one. Anyway, it is allways mandatory to pass a MassProvider object, issued from the Vehicle one. It could seem curious but it is due to the fact that, if we have maneuvers, it will be mandatory to initialize them with the same MassProvider (see example here).
In fact, we need to pass both an Assembly and a MassProvider. It could seem curious but it is due to the fact that, if we have maneuvers, it will be mandatory to initialize them with the same MassProvider (see example here). To get them, we will use the createAssembly() method given by Vehicle class.
final Assembly assembly = vehicle.createAssembly(GCRF); final MassProvider mm = new MassModel(assembly);
Note : for CPU time purpose it is recommanded that the frame (GCRF in the previous example), mandatory in the construction of the vehicle, must be exactly the same that the one used for the propagation.
In the example below, we will then use the Vehicle class initializing mass and aerodynamic properties (here no engines and no tanks):
// Dry mass final double dryMass = 1000.; final MassProperty dryMassProperty = new MassProperty(dryMass); // Shape final double sref = 5.0; Sphere sphere = new Sphere(sref); final RightParallelepiped solarPanels = new RightParallelepiped(10., 0., 0.); VehicleSurfaceModel vehicleRefSurface = new VehicleSurfaceModel(sphere, solarPanels); // Aerodynamic properties final double cd = 2.0; final double cl = 0.; final AerodynamicProperties aerodynamicProperties = new AerodynamicProperties(vehicleRefSurface, cd, cl); final Vehicle vehicle = new Vehicle(vehicleRefSurface, null, dryMassProperty, aerodynamicProperties, null, null, null); final Assembly assembly = vehicle.createAssembly(GCRF); final MassProvider mm = new MassModel(assembly);
Note : due to a PATRIUS anomaly, if the user needs to define solar panels characteristics, it is mandatory to use the Vehicle constructor with all parameters and the VehiculeSurfaceModel including the panels as above (and not a list of Facet); also, do not use the setters methods.
Forces
Since V11.3, to define, which forces will be applied along the trajectory, we use the PATRIUS ForceModelsData class (no more necessary to use the specific CustomForceModels class which does not exist anymore).
Potential
In the following example, we will initialize the potential model (mandatory).
// Potential final ForceModel potential = EarthGravitationalModelFactory.getDroziner(GravityFieldNames.GRGS, "grim4s4_gr", 8, 8, true); final ForceModelsData forces = new ForceModelsData(potential, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
Aerodynamic
Then we could add an aerodynamic force model. Since V11.3, it is no more necessary to use "Custom" classes.
final double REQ = Constants.WGS84_EARTH_EQUATORIAL_RADIUS; final double FLAT = Constants.WGS84_EARTH_FLATTENING; final Frame ITRF = FramesFactory.getITRF(); final ExtendedOneAxisEllipsoid EARTH = new ExtendedOneAxisEllipsoid(REQ, FLAT, ITRF, "EARTH"); final Atmosphere atmosphere = new US76(EARTH); final DragForce dragForce = new DragForce(1., atmosphere, assembly); forces.setDragForce(dragForce);
Solar radiative pressure
Here are explained how to use both radiative pressure and rediffused radiative pressure force models. Again, since V11.3, no more tu use old "Custom" classes.
final CelestialBody sunBody = new MeeusSun(); final double dRef = 1.4959787E11; final double pRef = 4.5605E-6; final ExtendedOneAxisEllipsoid EARTH = new ExtendedOneAxisEllipsoid(REQ, FLAT, ITRF, "EARTH"); SolarRadiationPressureEllipsoid radPres = new SolarRadiationPressureEllipsoid(dRef, pRef, sunBody, EARTH, assembly, 1.); forces.setSolarRadiationPressure(radPres); // By default values used when GUI mode ... final int inCorona = 1; final int inMeridian = 10; final IEmissivityModel inEmissivityModel = new KnockeRiesModel(); // Value accessible via GUI mode final boolean inAlbedo = false; final boolean inIr = false; final double coefAlbedo = 1.; final double coefIr = 1.; RediffusedRadiativeModel rdm = new RediffusedRadiativeModel(inAlbedo, inIr, coefAlbedo, coefIr, assembly); RediffusedRadiationPressure reDiff = new RediffusedRadiationPressure(sunBody, GCRF, inCorona, inMeridian, inEmissivityModel, rdm); forces.setRediffusedRadiationPressure(reDiff);
Specific forces
It is also possible to add specific forces via the addForceModel() method as below:
final Psimu test = new Psimu(...); test.addForceModel(myForce);
Maneuvers
If the user wants to add some maneuvers, it will have to do it using the [GENOPUS] Custom ManeuverSequence class. Indeed, this class is derivated from the PATRIUS ManeuverSequence but allows taking into account Engines and Tanks notion. From [PATRIUS] V3.4, it will be possible to directly use [PATRIUS] class.
Propulsive properties
First, the user will have to define propulsive properties with engine(s) and tank(s).
// Propulsive properties final PropulsiveProperty engine = new PropulsiveProperty(400, 320.); engine.setPartName("ENGINE"); final ArrayList<PropulsiveProperty> listOfEngines = new ArrayList<PropulsiveProperty>(); listOfEngines.add(engine); final TankProperty tank = new TankProperty(200.); tank.setPartName("TANK"); final ArrayList<TankProperty> listOfTanks = new ArrayList<TankProperty>(); listOfTanks.add(tank); listOfTanks.add(tank); final Vehicle vehicle = new Vehicle(vehicleRefSurface, null, dryMassProperty, null, null, listOfEngines, listOfTanks);
Sequence
Then, a maneuver sequence will be created thanks to the CustomManeuverSequence (the [PATRIUS] ManeuverSequence is not directly used as it does not still manage events.
Impulsive maneuver
Here we have an example of a 10m/s impulse maneuver in TNW occuring for an AOL of 180 degrees:
final double aol = FastMath.toRadians(180.); final CustomAOLDetector aolDetector = new CustomAOLDetector(aol, PositionAngle.TRUE, GCRF, MAXCHECK, THRESHOLD, Action.STOP); final IntervalOccurrenceDetectorWrapper impEvent = new IntervalOccurrenceDetectorWrapper(aolDetector, 1, 1, 1, Action.STOP); final Vector3D deltaV = new Vector3D(10., 0., 0.); final CustomImpulseManeuver imp = new CustomImpulseManeuver("Impulse maneuver", listOfEngines.get(0), listOfTanks.get(0), LOFType.TNW, impEvent, deltaV, mm);
Note: it is mandatory to configure the event with a STOP action (needed by [PATRIUS]).
At last, the user will create the maneuver sequence to pass to PSIMU:
final CustomManeuverSequence manSeq = new CustomManeuverSequence(0., 0.); manSeq.addManeuver(imp);
Constant thrust maneuver
The next source code shows how to define a constant thrust maneuver …
final double start = iniOrbit.getKeplerianPeriod(); final AbsoluteDate startDate = date.shiftedBy(start); final CustomDateDetector startEvent = new CustomDateDetector(startDate, MAXCHECK, THRESHOLD, Action.STOP); final double dur = 1000.; final AbsoluteDate endDate = startDate.shiftedBy(dur); final CustomDateDetector stopEvent = new CustomDateDetector(endDate, MAXCHECK, THRESHOLD, Action.STOP); final Vector3D direction = new Vector3D(-1., 0., 0.); CustomConstantManeuver cont = new CustomConstantManeuver("Continuous maneuver", listOfEngines.get(0), listOfTanks.get(0), LOFType.TNW, startEvent, stopEvent, direction, mm);
Attitude
It is mandatory to get at least one attitude law. With the V11.0, it is not possible to have only one law and it is mandatory to use the “switch” possibility by using the [PATRIUS] AttitudesSequence class.
This example shows how to define a single law (available since V11.1):
final AttitudeLaw attitudeLaw = new LofOffset(LOFType.TNW);
This other example uses a switching possibility:
final AttitudeLaw law = new LofOffset(LOFType.TNW, RotationOrder.ZYX, 0., 0., 0.); final double maxCheck = AbstractDetector.DEFAULT_MAXCHECK; final double threshold = AbstractDetector.DEFAULT_THRESHOLD; final EventDetector event = new DateDetector(date, maxCheck, threshold, Action.RESET_STATE); final AttitudesSequence seqAtt = new AttitudesSequence(); seqAtt.addSwitchingCondition(law, event, true, false, law);
Note : be very careful not to use by default constructors for event detectors as they introduce a STOP event, so your propagation will stop anyway !
Integration
Then integration data have to be defined. Here an example with RK4 integrator …
final double duration = 86400.; final double hStop = 120.e+3; final PsimuPropagationData propagationData = new PsimuPropagationData(duration, GCRF, hStop); final double step = 5.; final RK4data integrationData = new RK4data(propagationData, step);
… or with the DOP integrator …
final double minStep = 0.1; final double maxStep = 30.; final double[] vecAbsoluteTolerance = { 1.0E-5, 1.0E-5, 1.0E-5, 1.0E-8, 1.0E-8, 1.0E-8 }; final double[] vecRelativeTolerance = { 1.0E-8, 1.0E-8, 1.0E-8, 1.0E-8, 1.0E-8, 1.0E-8 }; final double absMassTolerance = 1.0E-3; final double relMassTolerance = 1.0E-2; final double positionError = 0.; final DopData intData = new DopData(propagationData, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance, absMassTolerance, relMassTolerance);
PSIMU object
As we have all mandatory data to initialize PSIMU, we can build such an object (note that in this example there is a “null” argument for the sequence of maneuvers.
final Psimu test = new Psimu(iniOrbit, EARTH, UserFramesConfsEnum.IGNORE, integrationData, vehicle, mm, forces, manSeq, attitudeLaw);