1   /* Copyright 2002-2020 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.files.ccsds;
18  
19  import java.util.ArrayList;
20  import java.util.Collections;
21  import java.util.List;
22  
23  import org.hipparchus.complex.Quaternion;
24  import org.hipparchus.geometry.euclidean.threed.Vector3D;
25  import org.orekit.time.AbsoluteDate;
26  
27  /**
28   * This class stocks all the information of the Attitude Parameter Message (APM) File parsed
29   * by APMParser. It contains the header and the metadata and a the data lines.
30   * @author Bryan Cazabonne
31   * @since 10.2
32   */
33  public class APMFile extends ADMFile {
34  
35      /** Meta-data. */
36      private final ADMMetaData metaData;
37  
38      /** Epoch of the data. */
39      private AbsoluteDate epoch;
40  
41      /** Reference frame specifying one frame of the transformation. */
42      private String qFrameA;
43  
44      /** Reference frame specifying the second portion of the transformation. */
45      private String qFrameB;
46  
47      /** Rotation direction of the attitude quaternion. */
48      private String qDir;
49  
50      /** Quaternion. */
51      private Quaternion quaternion;
52  
53      /** Derivative of the Quaternion. */
54      private Quaternion quaternionDot;
55  
56      /** Name of the reference frame specifying one frame of the transformation. */
57      private String eulerFrameA;
58  
59      /** Name of the reference frame specifying the second portion of the transformation. */
60      private String eulerFrameB;
61  
62      /** Rotation direction of the attitude Euler angles. */
63      private String eulerDir;
64  
65      /**
66       * Rotation order of the {@link #eulerFrameA} to {@link #eulerFrameB} or vice versa.
67       * (e.g., 312, where X=1, Y=2, Z=3)
68       */
69      private String eulerRotSeq;
70  
71      /** Frame of reference in which the {@link #rotationAngles} are expressed. */
72      private String rateFrame;
73  
74      /** Euler angles [rad]. */
75      private Vector3D rotationAngles;
76  
77      /** Rotation rate [rad/s]. */
78      private Vector3D rotationRates;
79  
80      /** Name of the reference frame specifying one frame of the transformation. */
81      private String spinFrameA;
82  
83      /** Name of the reference frame specifying the second portion of the transformation. */
84      private String spinFrameB;
85  
86      /** Rotation direction of the Spin angles. */
87      private String spinDir;
88  
89      /** Right ascension of spin axis vector (rad). */
90      private double spinAlpha;
91  
92      /** Declination of the spin axis vector (rad). */
93      private double spinDelta;
94  
95      /** Phase of the satellite about the spin axis (rad). */
96      private double spinAngle;
97  
98      /** Angular velocity of satellite around spin axis (rad/s). */
99      private double spinAngleVel;
100 
101     /** Nutation angle of spin axis (rad). */
102     private double nutation;
103 
104     /** Body nutation period of the spin axis (s). */
105     private double nutationPer;
106 
107     /** Inertial nutation phase (rad). */
108     private double nutationPhase;
109 
110     /** Coordinate system for the inertia tensor. */
111     private String inertiaRefFrame;
112 
113     /** Moment of Inertia about the 1-axis (kg.m²). */
114     private double i11;
115 
116     /** Moment of Inertia about the 2-axis (kg.m²). */
117     private double i22;
118 
119     /** Moment of Inertia about the 3-axis (kg.m²). */
120     private double i33;
121 
122     /** Inertia Cross Product of the 1 and 2 axes (kg.m²). */
123     private double i12;
124 
125     /** Inertia Cross Product of the 1 and 3 axes (kg.m²). */
126     private double i13;
127 
128     /** Inertia Cross Product of the 2 and 3 axes (kg.m²). */
129     private double i23;
130 
131     /** Epoch comments. The list contains a string for each line of comment. */
132     private List<String> epochComment;
133 
134     /** Euler comments. The list contains a string for each line of comment. */
135     private List<String> eulerComment;
136 
137     /** Spin comments. The list contains a string for each line of comment. */
138     private List<String> spinComment;
139 
140     /** Spacecraft comments. The list contains a string for each line of comment. */
141     private List<String> spacecraftComment;
142 
143     /** Maneuvers. */
144     private List<APMManeuver> maneuvers;
145 
146     /**
147      * APMFile constructor.
148      */
149     public APMFile() {
150         this.metaData          = new ADMMetaData(this);
151         this.epochComment      = Collections.emptyList();
152         this.eulerComment      = Collections.emptyList();
153         this.spinComment       = Collections.emptyList();
154         this.spacecraftComment = Collections.emptyList();
155         this.maneuvers         = new ArrayList<>();
156         this.rotationAngles    = Vector3D.ZERO;
157         this.rotationRates     = Vector3D.ZERO;
158         this.quaternion        = new Quaternion(0.0, 0.0, 0.0, 0.0);
159         this.quaternionDot     = new Quaternion(0.0, 0.0, 0.0, 0.0);
160     }
161 
162     /**
163      * Get the meta data.
164      * @return meta data
165      */
166     public ADMMetaData getMetaData() {
167         return metaData;
168     }
169 
170     /**
171      * Get the epoch of the data.
172      * @return epoch the epoch
173      */
174     public AbsoluteDate getEpoch() {
175         return epoch;
176     }
177 
178     /**
179      * Set the epoch of the data.
180      * @param epoch the epoch to be set
181      */
182     public void setEpoch(final AbsoluteDate epoch) {
183         this.epoch = epoch;
184     }
185 
186     /**
187      * Get the reference frame specifying one frame of the transformation.
188      * @return the reference frame A
189      */
190     public String getQuaternionFrameAString() {
191         return qFrameA;
192     }
193 
194     /**
195      * Set the reference frame specifying one frame of the transformation.
196      * @param frameA the frame to be set
197      */
198     public void setQuaternionFrameAString(final String frameA) {
199         this.qFrameA = frameA;
200     }
201 
202     /**
203      * Get the reference frame specifying the second portion of the transformation.
204      * @return the reference frame B
205      */
206     public String getQuaternionFrameBString() {
207         return qFrameB;
208     }
209 
210     /**
211      * Set the reference frame specifying the second portion of the transformation.
212      * @param frameB the frame to be set
213      */
214     public void setQuaternionFrameBString(final String frameB) {
215         this.qFrameB = frameB;
216     }
217 
218     /**
219      * Get the rotation direction of the attitude quaternion.
220      * @return the rotation direction of the attitude quaternion
221      */
222     public String getAttitudeQuaternionDirection() {
223         return qDir;
224     }
225 
226     /**
227      * Set the rotation direction of the attitude quaternion.
228      * @param direction rotation direction to be set
229      */
230     public void setAttitudeQuaternionDirection(final String direction) {
231         this.qDir = direction;
232     }
233 
234     /**
235      * Get the quaternion.
236      * @return quaternion
237      */
238     public Quaternion getQuaternion() {
239         return quaternion;
240     }
241 
242     /**
243      * Set the quaternion.
244      * @param q quaternion to set
245      */
246     public void setQuaternion(final Quaternion q) {
247         this.quaternion = q;
248     }
249 
250     /**
251      * Get the derivative of the quaternion.
252      * @return the derivative of the quaternion
253      */
254     public Quaternion getQuaternionDot() {
255         return quaternionDot;
256     }
257 
258     /**
259      * Set the derivative of the quaternion.
260      * @param qDot quaternion to set
261      */
262     public void setQuaternionDot(final Quaternion qDot) {
263         this.quaternionDot = qDot;
264     }
265 
266     /**
267      * Get the reference frame specifying one frame of the transformation.
268      * @return reference frame A
269      */
270     public String getEulerFrameAString() {
271         return eulerFrameA;
272     }
273 
274     /**
275      * Set the reference frame specifying one frame of the transformation.
276      * @param frame the frame to be set
277      */
278     public void setEulerFrameAString(final String frame) {
279         this.eulerFrameA = frame;
280     }
281 
282     /**
283      * Get the reference frame specifying the second portion of the transformation.
284      * @return reference frame B
285      */
286     public String getEulerFrameBString() {
287         return eulerFrameB;
288     }
289 
290     /**
291      * Set the reference frame specifying the second portion of the transformation.
292      * @param frame the frame to be set
293      */
294     public void setEulerFrameBString(final String frame) {
295         this.eulerFrameB = frame;
296     }
297 
298     /**
299      * Get the rotation direction of the attitude Euler angles (A2B or B2A).
300      * @return the rotation direction
301      */
302     public String getEulerDirection() {
303         return eulerDir;
304     }
305 
306     /**
307      * Set the rotation direction of the attitude Euler angles (A2B or B2A).
308      * @param direction direction to be set
309      */
310     public void setEulerDirection(final String direction) {
311         this.eulerDir = direction;
312     }
313 
314     /**
315      * Get the rotation order of Euler angles (X=1, Y=2, Z=3).
316      * @return rotation order
317      */
318     public String getEulerRotSeq() {
319         return eulerRotSeq;
320     }
321 
322     /**
323      * Set the rotation order for Euler angles (X=1, Y=2, Z=3).
324      * @param eulerRotSeq order to be setS
325      */
326     public void setEulerRotSeq(final String eulerRotSeq) {
327         this.eulerRotSeq = eulerRotSeq;
328     }
329 
330     /**
331      * Get the frame of reference in which the Euler angles are expressed.
332      * @return the frame of reference
333      */
334     public String getRateFrameString() {
335         return rateFrame;
336     }
337 
338     /**
339      * Set the frame of reference in which the Euler angles are expressed.
340      * @param frame frame to be set
341      */
342     public void setRateFrameString(final String frame) {
343         this.rateFrame = frame;
344     }
345 
346     /**
347      * Get the coordinates of the Euler angles (rad).
348      * @return rotation angles
349      */
350     public Vector3D getRotationAngles() {
351         return rotationAngles;
352     }
353 
354     /**
355      * Set the coordinates of the Euler angles (rad).
356      * @param rotationAngles coordinates to be set
357      */
358     public void setRotationAngles(final Vector3D rotationAngles) {
359         this.rotationAngles = rotationAngles;
360     }
361 
362     /**
363      * Get the rates of the Euler angles (rad/s).
364      * @return rotation rates
365      */
366     public Vector3D getRotationRates() {
367         return rotationRates;
368     }
369 
370     /**
371      * Set the rates of the Euler angles (rad/s).
372      * @param rotationRates coordinates to be set
373      */
374     public void setRotationRates(final Vector3D rotationRates) {
375         this.rotationRates = rotationRates;
376     }
377 
378     /**
379      * Get the reference frame specifying one frame of the transformation (spin).
380      * @return reference frame
381      */
382     public String getSpinFrameAString() {
383         return spinFrameA;
384     }
385 
386     /**
387      * Set the reference frame specifying one frame of the transformation (spin).
388      * @param frame frame to be set
389      */
390     public void setSpinFrameAString(final String frame) {
391         this.spinFrameA = frame;
392     }
393 
394     /**
395      * Get the reference frame specifying the second portion of the transformation (spin).
396      * @return reference frame
397      */
398     public String getSpinFrameBString() {
399         return spinFrameB;
400     }
401 
402     /**
403      * Set the reference frame specifying the second portion of the transformation (spin).
404      * @param frame frame to be set
405      */
406     public void setSpinFrameBString(final String frame) {
407         this.spinFrameB = frame;
408     }
409 
410     /**
411      * Get the rotation direction of the Spin angles.
412      * @return the rotation direction
413      */
414     public String getSpinDirection() {
415         return spinDir;
416     }
417 
418     /**
419      * Set the rotation direction of the Spin angles.
420      * @param direction rotation direction to be set
421      */
422     public void setSpinDirection(final String direction) {
423         this.spinDir = direction;
424     }
425 
426     /**
427      * Get the right ascension of spin axis vector (rad).
428      * @return the right ascension of spin axis vector
429      */
430     public double getSpinAlpha() {
431         return spinAlpha;
432     }
433 
434     /**
435      * Set the right ascension of spin axis vector (rad).
436      * @param spinAlpha value to be set
437      */
438     public void setSpinAlpha(final double spinAlpha) {
439         this.spinAlpha = spinAlpha;
440     }
441 
442     /**
443      * Get the declination of the spin axis vector (rad).
444      * @return the declination of the spin axis vector (rad).
445      */
446     public double getSpinDelta() {
447         return spinDelta;
448     }
449 
450     /**
451      * Set the declination of the spin axis vector (rad).
452      * @param spinDelta value to be set
453      */
454     public void setSpinDelta(final double spinDelta) {
455         this.spinDelta = spinDelta;
456     }
457 
458 
459     /**
460      * Get the phase of the satellite about the spin axis (rad).
461      * @return the phase of the satellite about the spin axis
462      */
463     public double getSpinAngle() {
464         return spinAngle;
465     }
466 
467     /**
468      * Set the phase of the satellite about the spin axis (rad).
469      * @param spinAngle value to be set
470      */
471     public void setSpinAngle(final double spinAngle) {
472         this.spinAngle = spinAngle;
473     }
474 
475     /**
476      * Get the angular velocity of satellite around spin axis (rad/s).
477      * @return the angular velocity of satellite around spin axis
478      */
479     public double getSpinAngleVel() {
480         return spinAngleVel;
481     }
482 
483     /**
484      * Set the angular velocity of satellite around spin axis (rad/s).
485      * @param spinAngleVel value to be set
486      */
487     public void setSpinAngleVel(final double spinAngleVel) {
488         this.spinAngleVel = spinAngleVel;
489     }
490 
491     /**
492      * Get the nutation angle of spin axis (rad).
493      * @return the nutation angle of spin axis
494      */
495     public double getNutation() {
496         return nutation;
497     }
498 
499     /**
500      * Set the nutation angle of spin axis (rad).
501      * @param nutation the nutation angle to be set
502      */
503     public void setNutation(final double nutation) {
504         this.nutation = nutation;
505     }
506 
507     /**
508      * Get the body nutation period of the spin axis (s).
509      * @return the body nutation period of the spin axis
510      */
511     public double getNutationPeriod() {
512         return nutationPer;
513     }
514 
515     /**
516      * Set the body nutation period of the spin axis (s).
517      * @param period the nutation period to be set
518      */
519     public void setNutationPeriod(final double period) {
520         this.nutationPer = period;
521     }
522 
523     /**
524      * Get the inertial nutation phase (rad).
525      * @return the inertial nutation phase
526      */
527     public double getNutationPhase() {
528         return nutationPhase;
529     }
530 
531     /**
532      * Set the inertial nutation phase (rad).
533      * @param nutationPhase the nutation phase to be set
534      */
535     public void setNutationPhase(final double nutationPhase) {
536         this.nutationPhase = nutationPhase;
537     }
538 
539     /**
540      * Get the coordinate system for the inertia tensor.
541      * @return the coordinate system for the inertia tensor
542      */
543     public String getInertiaRefFrameString() {
544         return inertiaRefFrame;
545     }
546 
547     /**
548      * Set the coordinate system for the inertia tensor.
549      * @param frame frame to be set
550      */
551     public void setInertiaRefFrameString(final String frame) {
552         this.inertiaRefFrame = frame;
553     }
554 
555     /**
556      * Get the moment of Inertia about the 1-axis (N.m²).
557      * @return the moment of Inertia about the 1-axis.
558      */
559     public double getI11() {
560         return i11;
561     }
562 
563     /**
564      * Set the moment of Inertia about the 1-axis (N.m²).
565      * @param i11 moment of Inertia about the 1-axis
566      */
567     public void setI11(final double i11) {
568         this.i11 = i11;
569     }
570 
571     /**
572      * Get the moment of Inertia about the 2-axis (N.m²).
573      * @return the moment of Inertia about the 2-axis.
574      */
575     public double getI22() {
576         return i22;
577     }
578 
579     /**
580      * Set the moment of Inertia about the 2-axis (N.m²).
581      * @param i22 moment of Inertia about the 2-axis
582      */
583     public void setI22(final double i22) {
584         this.i22 = i22;
585     }
586 
587     /**
588      * Get the moment of Inertia about the 3-axis (N.m²).
589      * @return the moment of Inertia about the 3-axis.
590      */
591     public double getI33() {
592         return i33;
593     }
594 
595     /**
596      * Set the moment of Inertia about the 3-axis (N.m²).
597      * @param i33 moment of Inertia about the 3-axis
598      */
599     public void setI33(final double i33) {
600         this.i33 = i33;
601     }
602 
603     /**
604      * Get the moment of Inertia about the 1 and 2 axes (N.m²).
605      * @return the moment of Inertia about the 1 and 2 axes.
606      */
607     public double getI12() {
608         return i12;
609     }
610 
611     /**
612      * Set the moment of Inertia about the 1 and 2 axes (N.m²).
613      * @param i12 moment of Inertia about the 1 and 2 axes
614      */
615     public void setI12(final double i12) {
616         this.i12 = i12;
617     }
618 
619     /**
620      * Get the moment of Inertia about the 1 and 3 axes (N.m²).
621      * @return the moment of Inertia about the 1 and 3 axes.
622      */
623     public double getI13() {
624         return i13;
625     }
626 
627     /**
628      * Set the moment of Inertia about the 1 and 3 axes (N.m²).
629      * @param i13 moment of Inertia about the 1 and 3 axes
630      */
631     public void setI13(final double i13) {
632         this.i13 = i13;
633     }
634 
635     /**
636      * Get the moment of Inertia about the 2 and 3 axes (N.m²).
637      * @return the moment of Inertia about the 2 and 3 axes.
638      */
639     public double getI23() {
640         return i23;
641     }
642 
643     /**
644      * Set the moment of Inertia about the 2 and 3 axes (N.m²).
645      * @param i23 moment of Inertia about the 2 and 3 axes
646      */
647     public void setI23(final double i23) {
648         this.i23 = i23;
649     }
650 
651     /**
652      * Get the comment for epoch.
653      * @return comment for epoch
654      */
655     public List<String> getEpochComment() {
656         return Collections.unmodifiableList(epochComment);
657     }
658 
659     /**
660      * Set the comment for epoch.
661      * @param comment comment to set
662      */
663     public void setEpochComment(final List<String> comment) {
664         epochComment = new ArrayList<>(comment);
665     }
666 
667     /**
668      * Get the comment for Euler angles.
669      * @return comment for Euler angles
670      */
671     public List<String> getEulerComment() {
672         return Collections.unmodifiableList(eulerComment);
673     }
674 
675     /**
676      * Set the comment for Euler angles.
677      * @param comment comment to set
678      */
679     public void setEulerComment(final List<String> comment) {
680         eulerComment = new ArrayList<>(comment);
681     }
682 
683     /**
684      * Get the comment for spin data.
685      * @return comment for spin data
686      */
687     public List<String> getSpinComment() {
688         return Collections.unmodifiableList(spinComment);
689     }
690 
691     /**
692      * Set the comment for spin data.
693      * @param comment comment to set
694      */
695     public void setSpinComment(final List<String> comment) {
696         spinComment = new ArrayList<>(comment);
697     }
698 
699     /**
700      * Get the comment for spacecraft.
701      * @return comment for spacecraft
702      */
703     public List<String> getSpacecraftComment() {
704         return Collections.unmodifiableList(spacecraftComment);
705     }
706 
707     /**
708      * Set the comment for spacecraft.
709      * @param comment comment to set
710      */
711     public void setSpacecraftComment(final List<String> comment) {
712         spacecraftComment = new ArrayList<>(comment);
713     }
714 
715     /**
716      * Get the number of maneuvers present in the APM.
717      * @return the number of maneuvers
718      */
719     public int getNbManeuvers() {
720         return maneuvers.size();
721     }
722 
723     /**
724      * Get a list of all maneuvers.
725      * @return unmodifiable list of all maneuvers.
726      */
727     public List<APMManeuver> getManeuvers() {
728         return Collections.unmodifiableList(maneuvers);
729     }
730 
731     /**
732      * Get a maneuver.
733      * @param index maneuver index, counting from 0
734      * @return maneuver
735      */
736     public APMManeuver getManeuver(final int index) {
737         return maneuvers.get(index);
738     }
739 
740     /**
741      * Add a maneuver.
742      * @param maneuver maneuver to be set
743      */
744     public void addManeuver(final APMManeuver maneuver) {
745         maneuvers.add(maneuver);
746     }
747 
748     /**
749      * Get boolean testing whether the APM contains at least one maneuver.
750      * @return true if APM contains at least one maneuver
751      *         false otherwise
752      */
753     public boolean getHasManeuver() {
754         return !maneuvers.isEmpty();
755     }
756 
757     /**
758      * Get the comment for meta-data.
759      * @return comment for meta-data
760      */
761     public List<String> getMetaDataComment() {
762         return metaData.getComment();
763     }
764 
765     /**
766      * Maneuver in an APM file.
767      */
768     public static class APMManeuver {
769 
770         /** Epoch of start of maneuver . */
771         private AbsoluteDate epochStart;
772 
773         /** Coordinate system for the torque vector, for absolute frames. */
774         private String refFrame;
775 
776         /** Duration (value is 0 for impulsive maneuver). */
777         private double duration;
778 
779         /** Torque vector (N.m). */
780         private Vector3D torque;
781 
782         /** Maneuvers data comment, each string in the list corresponds to one line of comment. */
783         private List<String> comment;
784 
785         /**
786          * Simple constructor.
787          */
788         public APMManeuver() {
789             this.torque  = Vector3D.ZERO;
790             this.comment = Collections.emptyList();
791         }
792 
793         /**
794          * Get epoch start.
795          * @return epoch start
796          */
797         public AbsoluteDate getEpochStart() {
798             return epochStart;
799         }
800 
801         /**
802          * Set epoch start.
803          * @param epochStart epoch start
804          */
805         public void setEpochStart(final AbsoluteDate epochStart) {
806             this.epochStart = epochStart;
807         }
808 
809         /**
810          * Get Coordinate system for the torque vector, for absolute frames.
811          * @return coordinate system for the torque vector, for absolute frames
812          */
813         public String getRefFrameString() {
814             return refFrame;
815         }
816 
817         /**
818          * Set Coordinate system for the torque vector, for absolute frames.
819          * @param frame coordinate system for the torque vector, for absolute frames
820          */
821         public void setRefFrameString(final String frame) {
822             this.refFrame = frame;
823         }
824 
825         /**
826          * Get duration (value is 0 for impulsive maneuver).
827          * @return duration (value is 0 for impulsive maneuver)
828          */
829         public double getDuration() {
830             return duration;
831         }
832 
833         /**
834          * Set duration (value is 0 for impulsive maneuver).
835          * @param duration duration (value is 0 for impulsive maneuver)
836          */
837         public void setDuration(final double duration) {
838             this.duration = duration;
839         }
840 
841         /**
842          * Get the torque vector (N.m).
843          * @return torque vector
844          */
845         public Vector3D getTorque() {
846             return torque;
847         }
848 
849         /**
850          * Set the torque vector (N.m).
851          * @param vector torque vector
852          */
853         public void setTorque(final Vector3D vector) {
854             this.torque = vector;
855         }
856 
857         /**
858          * Get the maneuvers data comment, each string in the list corresponds to one line of comment.
859          * @return maneuvers data comment, each string in the list corresponds to one line of comment
860          */
861         public List<String> getComment() {
862             return Collections.unmodifiableList(comment);
863         }
864 
865         /**
866          * Set the maneuvers data comment, each string in the list corresponds to one line of comment.
867          * @param comment maneuvers data comment, each string in the list corresponds to one line of comment
868          */
869         public void setComment(final List<String> comment) {
870             this.comment = new ArrayList<>(comment);
871         }
872 
873     }
874 
875 }