1   package org.orekit.rugged.adjustment.util;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import org.hipparchus.geometry.euclidean.threed.Rotation;
7   import org.hipparchus.geometry.euclidean.threed.RotationConvention;
8   import org.hipparchus.geometry.euclidean.threed.Vector3D;
9   import org.hipparchus.util.FastMath;
10  import org.orekit.rugged.linesensor.LineDatation;
11  import org.orekit.rugged.linesensor.LineSensor;
12  import org.orekit.rugged.linesensor.LinearLineDatation;
13  import org.orekit.rugged.los.FixedRotation;
14  import org.orekit.rugged.los.FixedZHomothety;
15  import org.orekit.rugged.los.LOSBuilder;
16  import org.orekit.rugged.los.TimeDependentLOS;
17  import org.orekit.time.AbsoluteDate;
18  import org.orekit.time.TimeScale;
19  import org.orekit.time.TimeScalesFactory;
20  
21  /**
22   * Pleiades viewing model for refining Junit tests.
23   */
24  public class PleiadesViewingModel {
25  
26      /** Pleiades parameters. */
27      private static final double FOV = 1.65; // 20km - alt 694km
28      private static final int DIMENSION = 40000;
29      private static final double LINE_PERIOD =  1.e-4; 
30  
31      private double rollAngle;
32      private LineSensor lineSensor;
33      private String referenceDate;
34      private String sensorName;
35  
36      /** PleiadesViewingModel constructor.
37       * @param sensorName sensor name
38       * @param rollAngle roll angle
39       * @param referenceDate reference date
40       */
41      public PleiadesViewingModel(final String sensorName, final double rollAngle, final String referenceDate) {
42  
43          this.sensorName = sensorName;
44          this.referenceDate = referenceDate;
45          this.rollAngle = rollAngle;
46          this.createLineSensor();
47      }
48  
49      /** Create raw fixed Line Of sight
50       */
51      public LOSBuilder rawLOS(final Vector3D center, final Vector3D normal, final double halfAperture, final int n) {
52  
53          final List<Vector3D> list = new ArrayList<Vector3D>(n);
54          for (int i = 0; i < n; ++i) {
55              final double alpha = (halfAperture * (2 * i + 1 - n)) / (n - 1);
56              list.add(new Rotation(normal, alpha, RotationConvention.VECTOR_OPERATOR).applyTo(center));
57          }
58  
59          return new LOSBuilder(list);
60      }
61  
62      /** Build a LOS provider
63       */
64      public TimeDependentLOS buildLOS() {
65  
66          // Roll angle applied to the LOS
67          // Compute the transformation of vector K (Z axis) through the rotation around I (X axis) with the roll angle
68          // If roll angle = 0: vector center = vector K (Z axis)
69          final LOSBuilder losBuilder = rawLOS(new Rotation(Vector3D.PLUS_I, FastMath.toRadians(rollAngle),
70                                                            RotationConvention.VECTOR_OPERATOR).applyTo(Vector3D.PLUS_K),
71                                               Vector3D.PLUS_I, FastMath.toRadians(FOV / 2), DIMENSION);
72  
73          losBuilder.addTransform(new FixedRotation(sensorName + InitInterRefiningTest.rollSuffix,  Vector3D.MINUS_I, 0.00));
74          losBuilder.addTransform(new FixedRotation(sensorName + InitInterRefiningTest.pitchSuffix, Vector3D.MINUS_J, 0.00));
75  
76          // factor is a common parameters shared between all Pleiades models
77          losBuilder.addTransform(new FixedZHomothety(InitInterRefiningTest.factorName, 1.0));
78  
79          return losBuilder.build();
80      }
81  
82      /** Get the reference date.
83       */
84      public AbsoluteDate getDatationReference() {
85  
86          // We use Orekit for handling time and dates, and Rugged for defining the datation model:
87          final TimeScale utc = TimeScalesFactory.getUTC();
88  
89          return new AbsoluteDate(referenceDate, utc);
90      }
91  
92      /** Get the min date.
93       */
94      public AbsoluteDate getMinDate() {
95          return lineSensor.getDate(0);
96      }
97  
98      /** Get the max date.
99       */
100     public AbsoluteDate getMaxDate() {
101         return lineSensor.getDate(DIMENSION);
102     }
103 
104     /** Get the line sensor.
105      */
106     public LineSensor getLineSensor() {
107         return lineSensor;
108     }
109 
110     /** Get the sensor name.
111      */
112     public String getSensorName() {
113         return sensorName;
114     }
115 
116     /** Get the number of lines of the sensor.
117      * @return the number of lines of the sensor
118      */
119     public int getDimension() {
120         return DIMENSION;
121     }
122 
123     /** Create the line sensor.
124      */
125     private void createLineSensor() {
126 
127         // Offset of the MSI from center of mass of satellite
128         // one line sensor
129         // los: swath in the (YZ) plane, looking at 50° roll, 2.6" per pixel
130         final Vector3D msiOffset = new Vector3D(0, 0, 0);
131 
132         final TimeDependentLOS lineOfSight = buildLOS();
133 
134         final double rate =  1. / LINE_PERIOD;
135         // linear datation model: at reference time we get the middle line, and the rate is one line every 1.5ms
136 
137         final LineDatation lineDatation = new LinearLineDatation(getDatationReference(), DIMENSION / 2, rate);
138 
139         lineSensor = new LineSensor(sensorName, lineDatation, msiOffset, lineOfSight);
140     }
141 
142 }
143