USGS

Isis 3.0 Object Programmers' Reference

Home

CameraGroundMap.cpp
Go to the documentation of this file.
1 
23 #include "CameraGroundMap.h"
24 
25 #include <QDebug>
26 
27 #include <iostream>
28 
29 #include "NaifStatus.h"
30 #include "SurfacePoint.h"
31 #include "Latitude.h"
32 #include "Longitude.h"
33 #include "Target.h"
34 
35 using namespace std;
36 
37 namespace Isis {
38  CameraGroundMap::CameraGroundMap(Camera *parent) {
39  p_camera = parent;
40  p_camera->SetGroundMap(this);
41  }
42 
55  bool CameraGroundMap::SetFocalPlane(const double ux, const double uy,
56  double uz) {
57  NaifStatus::CheckErrors();
58 
59  SpiceDouble lookC[3];
60  lookC[0] = ux;
61  lookC[1] = uy;
62  lookC[2] = uz;
63 
64  SpiceDouble unitLookC[3];
65  vhat_c(lookC, unitLookC);
66 
67  NaifStatus::CheckErrors();
68 
69  bool result = p_camera->SetLookDirection(unitLookC);
70  return result;
71  }
72 
80  bool CameraGroundMap::SetGround(const Latitude &lat, const Longitude &lon) {
81  if (p_camera->target()->shape()->name() == "Plane") {
82  double radius = lat.degrees(); // m
83  // double azimuth = lon.degrees();
84  Latitude lat(0., Angle::Degrees);
85  if (radius < 0.0) radius = 0.0; // TODO: massive, temporary kluge to get around testing latitude at -90 in caminfo app (are there more issues like this? Probably)KE
86  if (p_camera->Sensor::SetGround(SurfacePoint(lat, lon, Distance(radius, Distance::Meters)))) {
87  LookCtoFocalPlaneXY();
88  return true;
89  }
90  }
91  else {
92  Distance radius(p_camera->LocalRadius(lat, lon));
93  if (radius.isValid()) {
94  if(p_camera->Sensor::SetGround(SurfacePoint(lat, lon, radius))) {
95  LookCtoFocalPlaneXY();
96  return true;
97  }
98  }
99  }
100 
101  return false;
102  }
103 
105  void CameraGroundMap::LookCtoFocalPlaneXY() {
106  double lookC[3];
107  p_camera->Sensor::LookDirection(lookC);
108 
109  //Get the fl as the z coordinate to handle instruments looking down the -z axis 2013-02-22.
110  double focalLength = p_camera->DistortionMap()->UndistortedFocalPlaneZ();
111  double scale = focalLength / lookC[2];
112 
113  p_focalPlaneX = lookC[0] * scale;
114  p_focalPlaneY = lookC[1] * scale;
115  }
116 
125  bool CameraGroundMap::SetGround(const SurfacePoint &surfacePoint) {
126  if(p_camera->Sensor::SetGround(surfacePoint)) {
127  LookCtoFocalPlaneXY();
128  return true;
129  }
130 
131  return false;
132  }
133 
134 
146  bool CameraGroundMap::GetXY(const SurfacePoint &point, double *cudx, double *cudy) {
147 
148  double pB[3];
149  pB[0] = point.GetX().kilometers();
150  pB[1] = point.GetY().kilometers();
151  pB[2] = point.GetZ().kilometers();
152 
153  // Check for Sky images
154  if(p_camera->target()->isSky()) {
155  return false;
156  }
157 
158  // Should a check be added to make sure SetImage has been called???
159 
160  // Compute the look vector in body-fixed coordinates
161 // double pB[3]; // Point on surface
162 // latrec_c(radius / 1000.0, lon * Isis::PI / 180.0, lat * Isis::PI / 180.0, pB);
163 
164  // Get spacecraft vector in body-fixed coordinates
165  SpiceRotation *bodyRot = p_camera->bodyRotation();
166  SpiceRotation *instRot = p_camera->instrumentRotation();
167  std::vector<double> sB = bodyRot->ReferenceVector(p_camera->instrumentPosition()->Coordinate());
168  std::vector<double> lookB(3);
169  for(int ic = 0; ic < 3; ic++) lookB[ic] = pB[ic] - sB[ic];
170 
171  // Check for point on back of planet by checking to see if surface point is viewable (test emission angle)
172  // During iterations, we may not want to do the back of planet test???
173  double upsB[3], upB[3], dist;
174  vminus_c((SpiceDouble *) &lookB[0], upsB);
175  unorm_c(upsB, upsB, &dist);
176  unorm_c(pB, upB, &dist);
177  double angle = vdot_c(upB, upsB);
178  double emission;
179  if(angle > 1) {
180  emission = 0;
181  }
182  else if(angle < -1) {
183  emission = 180.;
184  }
185  else {
186  emission = acos(angle) * 180.0 / Isis::PI;
187  }
188  if(fabs(emission) > 90.) return false;
189 
190  // Get the look vector in the camera frame and the instrument rotation
191  p_lookJ.resize(3);
192  p_lookJ = p_camera->bodyRotation()->J2000Vector(lookB);
193  std::vector <double> lookC(3);
194  lookC = instRot->ReferenceVector(p_lookJ);
195 
196  // Get focal length with direction for scaling coordinates
197  double fl = p_camera->DistortionMap()->UndistortedFocalPlaneZ();
198 
199  *cudx = lookC[0] * fl / lookC[2];
200  *cudy = lookC[1] * fl / lookC[2];
201  return true;
202  }
203 
204 
205 
206 
220  bool CameraGroundMap::GetXY(const double lat, const double lon,
221  const double radius, double *cudx, double *cudy) {
222  SurfacePoint spoint(Latitude(lat, Angle::Degrees),
223  Longitude(lon, Angle::Degrees),
224  Distance(radius, Distance::Meters));
225  return GetXY(spoint, cudx, cudy);
226  }
227 
228 
242  // also have a GetDxyDorientation and a GetDxyDpoint
243  bool CameraGroundMap::GetdXYdPosition(const SpicePosition::PartialType varType, int coefIndex,
244  double *dx, double *dy) {
245 
246  // TODO add a check to make sure p_lookJ has been set
247 
248  // Get directional fl for scaling coordinates
249  double fl = p_camera->DistortionMap()->UndistortedFocalPlaneZ();
250 
251  // Rotate look vector into camera frame
252  SpiceRotation *instRot = p_camera->instrumentRotation();
253  std::vector <double> lookC(3);
254  lookC = instRot->ReferenceVector(p_lookJ);
255 
256  SpicePosition *instPos = p_camera->instrumentPosition();
257 
258  std::vector<double> d_lookJ = instPos->CoordinatePartial(varType, coefIndex);
259  for(int j = 0; j < 3; j++) d_lookJ[j] *= -1.0;
260  std::vector<double> d_lookC = instRot->ReferenceVector(d_lookJ);
261  *dx = fl * DQuotient(lookC, d_lookC, 0);
262  *dy = fl * DQuotient(lookC, d_lookC, 1);
263  return true;
264  }
265 
279  // also have a GetDxyDorientation and a GetDxyDpoint
280  bool CameraGroundMap::GetdXYdOrientation(const SpiceRotation::PartialType varType, int coefIndex,
281  double *dx, double *dy) {
282 
283  // TODO add a check to make sure p_lookJ has been set
284 
285  // Get directional fl for scaling coordinates
286  double fl = p_camera->DistortionMap()->UndistortedFocalPlaneZ();
287 
288  // Rotate look vector into camera frame
289  SpiceRotation *instRot = p_camera->instrumentRotation();
290  std::vector <double> lookC(3);
291  lookC = instRot->ReferenceVector(p_lookJ);
292 
293  std::vector<double> d_lookC = instRot->ToReferencePartial(p_lookJ, varType, coefIndex);
294  *dx = fl * DQuotient(lookC, d_lookC, 0);
295  *dy = fl * DQuotient(lookC, d_lookC, 1);
296  return true;
297  }
298 
312  bool CameraGroundMap::GetdXYdPoint(std::vector<double> d_lookB, double *dx, double *dy) {
313 
314  // TODO add a check to make sure p_lookJ has been set
315 
316  // Get directional fl for scaling coordinates
317  double fl = p_camera->DistortionMap()->UndistortedFocalPlaneZ();
318 
319  // Rotate look vector into camera frame
320  SpiceRotation *instRot = p_camera->instrumentRotation();
321  std::vector <double> lookC(3);
322  lookC = instRot->ReferenceVector(p_lookJ);
323 
324  SpiceRotation *bodyRot = p_camera->bodyRotation();
325  std::vector<double> d_lookJ = bodyRot->J2000Vector(d_lookB);
326  std::vector<double> d_lookC = instRot->ReferenceVector(d_lookJ);
327 
328  *dx = fl * DQuotient(lookC, d_lookC, 0);
329  *dy = fl * DQuotient(lookC, d_lookC, 1);
330  return true;
331  }
332 
333 
343  std::vector<double> CameraGroundMap::PointPartial(SurfacePoint spoint, PartialType wrt) {
344  double rlat = spoint.GetLatitude().radians();
345  double rlon = spoint.GetLongitude().radians();
346  double sinLon = sin(rlon);
347  double cosLon = cos(rlon);
348  double sinLat = sin(rlat);
349  double cosLat = cos(rlat);
350  double radkm = spoint.GetLocalRadius().kilometers();
351 
352  std::vector<double> v(3);
353  if(wrt == WRT_Latitude) {
354  v[0] = -radkm * sinLat * cosLon;
355  v[1] = -radkm * sinLon * sinLat;
356  v[2] = radkm * cosLat;
357  }
358  else if(wrt == WRT_Longitude) {
359  v[0] = -radkm * cosLat * sinLon;
360  v[1] = radkm * cosLat * cosLon;
361  v[2] = 0.0;
362  }
363  else {
364  v[0] = cosLon * cosLat;
365  v[1] = sinLon * cosLat;
366  v[2] = sinLat;
367  }
368 
369  return v;
370  }
371 
372 
385  double CameraGroundMap::DQuotient(std::vector<double> &look,
386  std::vector<double> &dlook,
387  int index) {
388  return (look[2] * dlook[index] - look[index] * dlook[2]) /
389  (look[2] * look[2]);
390  }
391 }