1   /* Copyright 2002-2021 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.definitions;
18  
19  import org.orekit.data.DataContext;
20  import org.orekit.errors.OrekitException;
21  import org.orekit.frames.Frame;
22  import org.orekit.utils.IERSConventions;
23  
24  /** Facade in front of several frames types in CCSDS messages.
25   * @author Luc Maisonobe
26   * @since 11.0
27   */
28  public class FrameFacade {
29  
30      /** Reference to node in Orekit frames tree. */
31      private final Frame frame;
32  
33      /** Reference to celestial body centered frame. */
34      private final CelestialBodyFrame celestialBodyFrame;
35  
36      /** Reference to orbit-relative frame. */
37      private final OrbitRelativeFrame orbitRelativeFrame;
38  
39      /** Reference to spacecraft body frame. */
40      private final SpacecraftBodyFrame spacecraftBodyFrame;
41  
42      /** Name of the frame. */
43      private final String name;
44  
45      /** Simple constructor.
46       * <p>
47       * At most one of {@code celestialBodyFrame}, {@code orbitRelativeFrame}
48       * or {@code spacecraftBodyFrame} may be non null. They may all be null
49       * if frame is unknown, in which case only the name will be available.
50       * </p>
51       * @param frame reference to node in Orekit frames tree (may be null)
52       * @param celestialBodyFrame reference to celestial body centered frame (may be null)
53       * @param orbitRelativeFrame reference to orbit-relative frame (may be null)
54       * @param spacecraftBodyFrame reference to spacecraft body frame (may be null)
55       * @param name name of the frame
56       */
57      public FrameFacade(final Frame frame,
58                         final CelestialBodyFrame celestialBodyFrame,
59                         final OrbitRelativeFrame orbitRelativeFrame,
60                         final SpacecraftBodyFrame spacecraftBodyFrame,
61                         final String name) {
62          this.frame               = frame;
63          this.celestialBodyFrame  = celestialBodyFrame;
64          this.orbitRelativeFrame  = orbitRelativeFrame;
65          this.spacecraftBodyFrame = spacecraftBodyFrame;
66          this.name                = name;
67      }
68  
69      /**
70       * Get the associated frame tree node.
71       * @return associated frame tree node, or null if none exists
72       */
73      public Frame asFrame() {
74          return frame;
75      }
76  
77      /** Get the associated {@link CelestialBodyFrame celestial body frame}.
78       * @return associated celestial body frame, or null if frame is
79       * associated to a {@link #asOrbitRelativeFrame() orbit},
80       * a {@link #asSpacecraftBodyFrame spacecraft} or is not supported
81       */
82      public CelestialBodyFrame asCelestialBodyFrame() {
83          return celestialBodyFrame;
84      }
85  
86      /** Get the associated {@link OrbitRelativeFrame orbit relative frame}.
87       * @return associated orbit relative frame, or null if frame is
88       * associated to a {@link #asCelestialBodyFrame() celestial body},
89       * a {@link #asSpacecraftBodyFrame spacecraft} or is not supported
90       */
91      public OrbitRelativeFrame asOrbitRelativeFrame() {
92          return orbitRelativeFrame;
93      }
94  
95      /** Get the associated {@link SpacecraftBodyFrame spacecraft body frame}.
96       * @return associated spacecraft body frame, or null if frame is
97       * associated to a {@link #asCelestialBodyFrame() celestial body},
98       * an {@link #asOrbitRelativeFrame orbit} or is not supported
99       */
100     public SpacecraftBodyFrame asSpacecraftBodyFrame() {
101         return spacecraftBodyFrame;
102     }
103 
104     /** Get the CCSDS name for the frame.
105      * @return CCSDS name
106      */
107     public String getName() {
108         return name;
109     }
110 
111     /** Map an Orekit frame to a CCSDS frame facade.
112      * @param frame a reference frame.
113      * @return the CCSDSFrame corresponding to the Orekit frame
114      */
115     public static FrameFacade map(final Frame frame) {
116         final CelestialBodyFrame cbf = CelestialBodyFrame.map(frame);
117         return new FrameFacade(frame, cbf, null, null, cbf.name());
118     }
119 
120     /** Simple constructor.
121      * @param name name of the frame
122      * @param conventions IERS conventions to use
123      * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
124      * @param dataContext to use when creating the frame
125      * @param allowCelestial if true, {@link CelestialBodyFrame} are allowed
126      * @param allowOrbit if true, {@link OrbitRelativeFrame} are allowed
127      * @param allowSpacecraft if true, {@link SpacecraftBodyFrame} are allowed
128      * @return frame facade corresponding to the CCSDS name
129      */
130     public static FrameFacade parse(final String name,
131                                     final IERSConventions conventions,
132                                     final boolean simpleEOP,
133                                     final DataContext dataContext,
134                                     final boolean allowCelestial,
135                                     final boolean allowOrbit,
136                                     final boolean allowSpacecraft) {
137         try {
138             final CelestialBodyFrame cbf = CelestialBodyFrame.parse(name);
139             if (allowCelestial) {
140                 return new FrameFacade(cbf.getFrame(conventions, simpleEOP, dataContext),
141                                        cbf, null, null, cbf.name());
142             }
143         } catch (IllegalArgumentException iaeC) {
144             try {
145                 final OrbitRelativeFrame orf = OrbitRelativeFrame.valueOf(name.replace(' ', '_'));
146                 if (allowOrbit) {
147                     return new FrameFacade(null, null, orf, null, orf.name());
148                 }
149             } catch (IllegalArgumentException iaeO) {
150                 try {
151                     final SpacecraftBodyFrame sbf = SpacecraftBodyFrame.parse(name.replace(' ', '_'));
152                     if (allowSpacecraft) {
153                         return new FrameFacade(null, null, null, sbf, sbf.toString());
154                     }
155                 } catch (OrekitException | IllegalArgumentException e) {
156                     // nothing to do here, use fallback below
157                 }
158             }
159         }
160 
161         // we don't know any frame with this name, just store the name itself
162         return new FrameFacade(null, null, null, null, name);
163 
164     }
165 
166 }