1   /* Copyright 2013-2025 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.rugged.linesensor;
18  
19  import java.util.stream.Stream;
20  
21  import org.hipparchus.analysis.differentiation.Derivative;
22  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
23  import org.hipparchus.geometry.euclidean.threed.Vector3D;
24  import org.hipparchus.util.FastMath;
25  import org.orekit.rugged.errors.DumpManager;
26  import org.orekit.rugged.los.TimeDependentLOS;
27  import org.orekit.rugged.utils.DerivativeGenerator;
28  import org.orekit.time.AbsoluteDate;
29  import org.orekit.utils.ParameterDriver;
30  
31  /** Line sensor model.
32   * @author Luc Maisonobe
33   * @author Guylaine Prat
34   */
35  public class LineSensor {
36  
37      /** Name of the sensor. */
38      private final String name;
39  
40      /** Datation model. */
41      private final LineDatation datationModel;
42  
43      /** Sensor position. */
44      private final Vector3D position;
45  
46      /** Pixels lines-of-sight. */
47      private final TimeDependentLOS los;
48  
49      /** Simple constructor.
50       * @param name name of the sensor
51       * @param datationModel datation model
52       * @param position sensor position in spacecraft frame
53       * @param los pixels lines-of-sight in spacecraft frame
54       * @see org.orekit.rugged.los.LOSBuilder
55       */
56      public LineSensor(final String name, final LineDatation datationModel,
57                        final Vector3D position, final TimeDependentLOS los) {
58  
59          this.name          = name;
60          this.datationModel = datationModel;
61          this.position      = position;
62          this.los           = los;
63  
64      }
65  
66      /** Get the name of the sensor.
67       * @return name of the sensor
68       */
69      public String getName() {
70          return name;
71      }
72  
73      /** Get the number of pixels.
74       * @return number of pixels
75       */
76      public int getNbPixels() {
77          return los.getNbPixels();
78      }
79  
80      /** Get the drivers for LOS parameters.
81       * @return drivers for LOS parameters
82       * @since 2.0
83       */
84      public Stream<ParameterDriver> getParametersDrivers() {
85          return los.getParametersDrivers();
86      }
87  
88      /** Get the pixel normalized line-of-sight at some date.
89       * @param date current date
90       * @param i pixel index (must be between 0 and {@link #getNbPixels()} - 1
91       * @return pixel normalized line-of-sight
92       */
93      public Vector3D getLOS(final AbsoluteDate date, final int i) {
94          final Vector3D l = los.getLOS(i, date);
95          DumpManager.dumpSensorLOS(this, date, i, l);
96          return l;
97      }
98  
99      /** Get the pixel normalized interpolated line-of-sight at some date.
100      * @param date current date
101      * @param i pixel index (must be between 0 and {@link #getNbPixels()} - 1
102      * @return pixel normalized line-of-sight
103      * @since 2.0
104      */
105     public Vector3D getLOS(final AbsoluteDate date, final double i) {
106 
107         final int iInf = FastMath.max(0, FastMath.min(getNbPixels() - 2, (int) FastMath.floor(i)));
108         final int iSup = iInf + 1;
109         final Vector3D interpolatedLos     = new Vector3D(iSup - i, los.getLOS(iInf, date),
110                                                   i - iInf, los.getLOS(iSup, date));
111         return interpolatedLos;
112     }
113 
114     /** Get the pixel normalized line-of-sight at some date,
115      * and their derivatives with respect to estimated parameters.
116      * @param <T> derivative type
117      * @param date current date
118      * @param i pixel index (must be between 0 and {@link #getNbPixels()} - 1
119      * @param generator generator to use for building {@link Derivative} instances
120      * @return pixel normalized line-of-sight
121      */
122     public <T extends Derivative<T>> FieldVector3D<T> getLOSDerivatives(final AbsoluteDate date, final int i,
123                                                                         final DerivativeGenerator<T> generator) {
124         return los.getLOSDerivatives(i, date, generator);
125     }
126 
127     /** Get the pixel normalized line-of-sight at some date,
128      * and their derivatives with respect to estimated parameters.
129      * @param <T> derivative type
130      * @param date current date
131      * @param i pixel index (must be between 0 and {@link #getNbPixels()} - 1
132      * @param generator generator to use for building {@link Derivative} instances
133      * @return pixel normalized line-of-sight
134      * @since 2.0
135      */
136     public <T extends Derivative<T>> FieldVector3D<T> getLOSDerivatives(final AbsoluteDate date, final double i,
137                                                                         final DerivativeGenerator<T> generator) {
138 
139         // find surrounding pixels of pixelB (in order to interpolate LOS from pixelB (that is not an integer)
140         final int iInf = FastMath.max(0, FastMath.min(getNbPixels() - 2, (int) FastMath.floor(i)));
141         final int iSup = iInf + 1;
142 
143         final FieldVector3D<T> interpolatedLos =
144                         new FieldVector3D<> (iSup - i, los.getLOSDerivatives(iInf, date, generator),
145                                              i - iInf, los.getLOSDerivatives(iSup, date, generator)).normalize();
146         return interpolatedLos;
147     }
148 
149     /** Get the date.
150      * @param lineNumber line number
151      * @return date corresponding to line number
152      */
153     public AbsoluteDate getDate(final double lineNumber) {
154         final AbsoluteDate date = datationModel.getDate(lineNumber);
155         DumpManager.dumpSensorDatation(this, lineNumber, date);
156         return date;
157     }
158 
159     /** Get the line number.
160      * @param date date
161      * @return line number corresponding to date
162      */
163     public double getLine(final AbsoluteDate date) {
164         final double lineNumber = datationModel.getLine(date);
165         DumpManager.dumpSensorDatation(this, lineNumber, date);
166         return lineNumber;
167     }
168 
169     /** Get the rate of lines scanning.
170      * @param lineNumber line number
171      * @return rate of lines scanning (lines / seconds)
172      */
173     public double getRate(final double lineNumber) {
174         final double rate = datationModel.getRate(lineNumber);
175         DumpManager.dumpSensorRate(this, lineNumber, rate);
176         return rate;
177     }
178 
179     /** Get the sensor position.
180      * @return position
181      */
182     public Vector3D getPosition() {
183         return position;
184     }
185 
186     /** Dump the rate for the current line number.
187      * @param lineNumber line number
188      */
189     public void dumpRate(final double lineNumber) {
190         final double rate = datationModel.getRate(lineNumber);
191         DumpManager.dumpSensorRate(this, lineNumber, rate);
192     }
193 }