OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
SarSensor.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
2 //
3 // "Copyright Centre National d'Etudes Spatiales"
4 //
5 // License: LGPL
6 //
7 // See LICENSE.txt file in the top level directory for more details.
8 //
9 //----------------------------------------------------------------------------
10 // $Id$
11 
12 #include <otb/SarSensor.h>
13 #include <otb/JSDDateTime.h>
14 #include <otb/Ephemeris.h>
16 #include <otb/Sensor.h>
17 #include <otb/SensorParams.h>
18 #include <otb/PlatformPosition.h>
19 #include <otb/Equation.h>
21 #include <otb/GeodesicCoordinate.h>
22 #include <complex>
23 
24 
25 namespace ossimplugins
26 {
27 
28 
29 SarSensor::SarSensor(SensorParams* params, PlatformPosition* position) : Sensor(params, position)
30 {
31 }
32 
34 {
35 }
36 
37 int SarSensor::ImageToWorld(double distance, JSDDateTime time, double height, double& lon, double& lat) const
38 {
39  const double TWOPI = 6.28318530717958647693 ;
40 
41  double semiMajorAxis = _params->get_semiMajorAxis() ; // default : WGS84
42  double semiMinorAxis = _params->get_semiMinorAxis() ; // default : WGS84
43 
44  double lambda = _params->get_rwl();
45  int sensVisee ;
46  if (_params->get_sightDirection() == SensorParams::Right) sensVisee = 1 ;
47  else sensVisee = -1 ;
48 
49  Ephemeris* satPosition = _position->Interpolate(time);
50 
51  GeographicEphemeris *geoEph = (GeographicEphemeris*)satPosition;
52 
54 
55  double dopplerCentroid = _params->get_dopcen();
56  double dopcenLinear = _params->get_dopcenLinear();
57  if (dopcenLinear != 0.0)
58  {
59  dopplerCentroid += dopcenLinear * distance/1000; // Hz/km
60  }
61 
62  // note : the Doppler frequency is set to zero
63  int etatLoc = localisationSAR(*geoEph, lambda, distance, dopplerCentroid, sensVisee, semiMajorAxis , semiMinorAxis , height, &cart);
64 
66  cart.AsGeodesicCoordinates(semiMajorAxis , semiMinorAxis, &geo);
67  lon = (geo.get_x())*360.0/TWOPI;
68  lat = (geo.get_y())*360.0/TWOPI;
69 
70  delete satPosition;
71 
72  return etatLoc ;
73 }
74 
75 int SarSensor::localisationSAR ( GeographicEphemeris posSpeed , double lambda ,
76  double dist , double fDop , int sensVisee ,
77  double equRadius , double polRadius ,
78  double h , RectangularCoordinate* cart ) const
79 {
80  double coordCart[3];
81  coordCart[0]=0.0;
82  coordCart[1]=0.0;
83  coordCart[2]=0.0;
84 
85 
86  double rho2 , k , a , b , c , d , u , v , w ;
87  double x[4] , y[4] , z[4] , r[4] ;
88  bool isEnd;
89 
90 
91  /* Initialization of characteristical values */
92  /* note : for precise computation : */
93  /* - ranges are processed in mm */
94  /* - velocities are processed in km/s */
95  /* - frequencies are processed in kHz */
96  const double KILO = 1.0e-3 ;
97  const double MEGA = 1.0e-6 ;
98  const double EPSILON = 1.0e-12 ;
99 
100 
101  double dist1 = dist * MEGA ;
102  double fDop1 = fDop * KILO ;
103 
104  double he = (equRadius + h) * MEGA ; /* Equatorial radius + h */
105  double hp = (polRadius + h) * MEGA ; /* Polar radius + h */
106 
107  double posX = posSpeed.get_position()[0] * MEGA ;
108  double posY = posSpeed.get_position()[1] * MEGA ;
109  double posZ = posSpeed.get_position()[2] * MEGA ;
110  double speedX = - posSpeed.get_speed()[0] * KILO ;
111  double speedY = - posSpeed.get_speed()[1] * KILO ;
112  double speedZ = - posSpeed.get_speed()[2] * KILO ;
113 
114 
115  /* Coefficients computation and equation solving */
116  int state = 0;
117  u = speedX * posY - speedY * posX ;
118  a = (speedX / u) * (1.0 - (he / hp) * (he / hp)) / 2.0 ;
119  b = (speedX * posZ - speedZ * posX) / u ;
120  rho2 = posX * posX + posY * posY + posZ * posZ ;
121  k = posX * speedX + posY * speedY + posZ * speedZ -
122  lambda * dist1 * fDop1 / 2.0 ;
123  c = (speedX * (he * he + rho2 - dist1 * dist1) - 2.0 * k * posX) / (2.0 * u);
124 
125  u = speedZ - b * speedY ;
126  v = c * speedY - k ;
127  w = v * v - (speedX * speedX) * (he * he - c * c) ;
128 
129  std::complex<double> aa[5];
130  aa[0] = std::complex<double>(w,0.0); /* Constant coefficient */
131  w = 2.0 * (u * v - (b * c) * (speedX * speedX)) ;
132  aa[1] = std::complex<double>(w,0.0) ; /* First order coefficient */
133  w = u * u + 2.0 * a * v * speedY +
134  (speedX * speedX) * ((he / hp) * (he / hp) + b * b + 2.0 * a * c) ;
135  aa[2] = std::complex<double>(w,0.0) ; /* Second order coefficient */
136  w = 2.0 * a * (u * speedY - b * speedX * speedX) ;
137  aa[3] = std::complex<double>(w,0.0) ; /* Third order coefficient */
138  w = (speedX * speedX + speedY * speedY) * a * a ;
139  aa[4] = std::complex<double>(w,0.0) ; /* Fourth order coefficient */
140 
141  Equation eq(4,aa); /* Equation solving */
142  eq.Solve();
143 
144  int n = eq.get_nbrSol();
145  const std::complex<double> *root = eq.get_solutions();
146 
147  int nRoot = 0 ;
148  for (int i = 0 ; i < n ; i++) /* Real root selection */
149  {
150  d = fabs(root[i].imag()) ;
151  if (d < EPSILON)
152  {
153  z[nRoot] = root[i].real();
154  y[nRoot] = (a * z[nRoot] - b) * z[nRoot] + c ;
155  x[nRoot] = (k - (speedY * y[nRoot] + speedZ * z[nRoot])) / speedX ;
156  nRoot = nRoot + 1 ;
157  }
158  }
159  if (nRoot == 0)
160  state = 2 ; /* No root */
161 
162 
163  /* Computed roots sort */
164 
165  if (state == 0)
166  {
167  int indice[4] ;
168  for (int i = 0 ; i < nRoot ; i++)
169  {
170  /* Computation of the "distance" between roots images and equation values */
171  u = x[i] - posX ;
172  v = y[i] - posY ;
173  w = z[i] - posZ ;
174  r[i] = fabs ((u * u + v * v + w * w) / (dist1 * dist1) - 1.0 ) ;
175  u = u * speedX ;
176  v = v * speedY ;
177  w = w * speedZ ;
178  if (fabs (fDop) > EPSILON)
179  r[i] = r[i] + fabs (1.0 + 2.0 * (u + v + w) / (lambda * dist1 * fDop1));
180  else
181  r[i] = r[i] + fabs (2.0 * (u + v + w) / (lambda * dist1)) ;
182  u = x[i] / he ;
183  v = y[i] / he ;
184  w = z[i] / hp ;
185  r[i] = r[i] + fabs (u * u + v * v + w * w - 1.0) ;
186  indice[i] = i ;
187  }
188 
189  /* Roots sort by increasing differences */
190  isEnd = false ;
191  while (!isEnd)
192  {
193  isEnd = true;
194  for (int i = 0 ; i < (nRoot - 1) ; i++)
195  {
196  int i1 = indice[i] ;
197  int i2 = indice[i+1] ;
198  if (r[i2] < r[i1])
199  {
200  indice[i] = i2 ;
201  indice[i+1] = i1 ;
202  isEnd = false ;
203  }
204  }
205  }
206 
207  /* Selection of the correct root (corresponding to the imaging direction) */
208  isEnd = false ;
209  int i = 0 ;
210  while (!isEnd && (i < nRoot))
211  {
212  int i1 = indice[i] ;
213  u = posY * speedZ - posZ * speedY ;
214  v = posZ * speedX - posX * speedZ ;
215  w = posX * speedY - posY * speedX ;
216  a = x[i1] - posX ;
217  b = y[i1] - posY ;
218  c = z[i1] - posZ ;
219  d = (a * u + b * v + c * w) * sensVisee;
220  if (d >= 0.0)
221  {
222  coordCart[0] = x[i1] / MEGA ; /* Coordinates in the */
223  coordCart[1] = y[i1] / MEGA ; /* geographic referential, */
224  coordCart[2] = z[i1] / MEGA ; /* in legal units (m) */
225  isEnd = true;
226  }
227  i++ ;
228  }
229  if (!isEnd)
230  state = 1 ; /* No root in the imaging direction */
231  }
232 
233  cart->set_coordinates(coordCart[0], coordCart[1], coordCart[2]);
234  return state ;
235 }
236 }
This class represent an ephemeris in Geographic coordinates system.
ossim_uint32 x
This class handles the platform position.
ossim_uint32 y
void set_coordinates(double x, double y, double z)
Definition: Coordinate.cpp:54
virtual int ImageToWorld(double distance, JSDDateTime time, double height, double &lon, double &lat) const
This function is able to convert image coordinates into geodetic world coordinates using a geometric ...
Definition: SarSensor.cpp:37
SarSensor(SensorParams *params, PlatformPosition *position)
Constructor.
Definition: SarSensor.cpp:29
double * get_speed()
Definition: Ephemeris.h:78
This class represents a coordinate in a geodesic reference.
This class handles the sensor parameters.
Definition: SensorParams.h:29
int localisationSAR(GeographicEphemeris posSpeed, double lambda, double dist, double fDop, int sensVisee, double equRadius, double polRadius, double h, RectangularCoordinate *cart) const
This function is able to convert image coordinates into rectangular world coordinates.
Definition: SarSensor.cpp:75
Ephemeris * Interpolate(JSDDateTime date) const
This function interpolates its ephemeris to create a new ephemeris at the given date and time...
virtual ~SarSensor()
Destructor.
Definition: SarSensor.cpp:33
SightDirection get_sightDirection() const
Definition: SensorParams.h:88
This class represents an ephemeris.
Definition: Ephemeris.h:28
os2<< "> n<< " > nendobj n
double get_semiMajorAxis() const
Definition: SensorParams.h:143
PlatformPosition * _position
Definition: Sensor.h:55
int get_nbrSol() const
Definition: Equation.h:48
double * get_position()
Definition: Ephemeris.h:68
This class provides basic location services.
Definition: Sensor.h:29
double get_dopcenLinear() const
Definition: SensorParams.h:168
This class manages and solves an equation of the fourth degree.
Definition: Equation.h:26
double get_semiMinorAxis() const
Definition: SensorParams.h:148
This class represents a coordinate in a rectangular reference.
void AsGeodesicCoordinates(double demiGdAxe, double demiPtAxe, GeodesicCoordinate *geod)
SensorParams * _params
Definition: Sensor.h:54
This class represents a date.
Definition: JSDDateTime.h:30
float distance(double lat1, double lon1, double lat2, double lon2, int units)
const std::complex< double > * get_solutions() const
Definition: Equation.h:53