|
Isis 3.0 Object Programmers' Reference |
Home |
00001 00023 #include "PushFrameCameraGroundMap.h" 00024 00025 #include "CameraDistortionMap.h" 00026 #include "CameraFocalPlaneMap.h" 00027 #include "Latitude.h" 00028 #include "Longitude.h" 00029 #include "PushFrameCameraDetectorMap.h" 00030 #include "SurfacePoint.h" 00031 00032 namespace Isis { 00041 bool PushFrameCameraGroundMap::SetGround(const Latitude &lat, 00042 const Longitude &lon) { 00043 PushFrameCameraDetectorMap *detectorMap = (PushFrameCameraDetectorMap *) p_camera->DetectorMap(); 00044 00045 SurfacePoint surfacePoint(lat, lon, p_camera->LocalRadius(lat, lon)); 00046 00047 // Get ending bounding framelets and distances for iterative loop to minimize the spacecraft distance 00048 int startFramelet = 1; 00049 double startDist = FindSpacecraftDistance(1, surfacePoint); 00050 00051 int endFramelet = detectorMap->TotalFramelets(); 00052 double endDist = FindSpacecraftDistance(endFramelet, surfacePoint); 00053 00054 bool minimizedSpacecraftDist = false; 00055 00056 for(int j = 0; j < 30 && !minimizedSpacecraftDist; j++) { 00057 int deltaX = abs(startFramelet - endFramelet) / 2; 00058 00059 // start + deltaX = middle framelet. 00060 // We're able to optimize this modified binary search 00061 // because the 'V' shape -- it's mostly parallel. Meaning, 00062 // if the left side is higher than the right, then the 00063 // solution is closer to the right. The bias factor will 00064 // determine how much closer, and then back off a little so 00065 // we dont overshoot it. 00066 double biasFactor = startDist / endDist; 00067 00068 if(biasFactor < 1.0) { 00069 biasFactor = -1.0 / biasFactor; 00070 biasFactor = -(biasFactor + 1) / biasFactor; 00071 00072 // The bias is about 50% unsure... sometimes our V is a U 00073 biasFactor = std::min(biasFactor + 0.50, 0.0); 00074 } 00075 else { 00076 biasFactor = (biasFactor - 1) / biasFactor; 00077 00078 // The bias is about 50% unsure... sometimes our V is a U 00079 biasFactor = std::max(biasFactor - 0.50, 0.0); 00080 } 00081 00082 int middleFramelet = startFramelet + (int)(deltaX + biasFactor * deltaX); 00083 double middleDist = FindSpacecraftDistance(middleFramelet, surfacePoint); 00084 00085 if(startDist > endDist) { 00086 // This makes sure we don't get stuck halfway between framelets 00087 if(startFramelet == middleFramelet) middleFramelet++; 00088 startFramelet = middleFramelet; 00089 startDist = middleDist; 00090 } 00091 else { 00092 endFramelet = middleFramelet; 00093 endDist = middleDist; 00094 } 00095 00096 if(startFramelet == endFramelet) { 00097 minimizedSpacecraftDist = true; 00098 } 00099 } 00100 00101 if(!minimizedSpacecraftDist) { 00102 return false; 00103 } 00104 00105 int realFramelet = startFramelet; 00106 bool frameletEven = (realFramelet % 2 == 0); 00107 bool timeAscendingFramelets = detectorMap->timeAscendingFramelets(); 00108 00109 // Do we need to find a neighboring framelet? Get the closest (minimize distance) 00110 if((timeAscendingFramelets && frameletEven != p_evenFramelets) || 00111 (!timeAscendingFramelets && frameletEven == p_evenFramelets)) { 00112 realFramelet ++; // this direction doesnt really matter... it's simply a guess 00113 } 00114 00115 int direction = 2; 00116 00117 double realDist = FindDistance(realFramelet, surfacePoint); 00118 int guessFramelet = realFramelet + direction; 00119 double guessDist = FindDistance(guessFramelet, surfacePoint); 00120 00121 if(guessDist > realDist) { 00122 direction = -1 * direction; // reverse the search direction 00123 guessFramelet = realFramelet + direction; 00124 guessDist = FindDistance(guessFramelet, surfacePoint); 00125 } 00126 00127 for(int j = 0; (realDist >= guessDist) && (j < 30); j++) { 00128 realFramelet = guessFramelet; 00129 realDist = guessDist; 00130 00131 guessFramelet = realFramelet + direction; 00132 guessDist = FindDistance(guessFramelet, surfacePoint); 00133 00134 if(realFramelet <= 0 || realFramelet > detectorMap->TotalFramelets()) { 00135 return false; 00136 } 00137 } 00138 00139 detectorMap->SetFramelet(realFramelet); 00140 00141 return CameraGroundMap::SetGround(surfacePoint); 00142 } 00143 00144 00145 bool PushFrameCameraGroundMap::SetGround(const SurfacePoint &surfacePt) { 00146 return SetGround(surfacePt.GetLatitude(), surfacePt.GetLongitude()); 00147 } 00148 00149 00160 double PushFrameCameraGroundMap::FindDistance(int framelet, 00161 const SurfacePoint &surfacePoint) { 00162 PushFrameCameraDetectorMap *detectorMap = (PushFrameCameraDetectorMap *) p_camera->DetectorMap(); 00163 CameraDistortionMap *distortionMap = (CameraDistortionMap *) p_camera->DistortionMap(); 00164 00165 detectorMap->SetFramelet(framelet); 00166 if(!p_camera->Sensor::SetGround(surfacePoint, false)) return DBL_MAX; 00167 00168 double lookC[3]; 00169 p_camera->Sensor::LookDirection(lookC); 00170 double ux = p_camera->FocalLength() * lookC[0] / lookC[2]; 00171 double uy = p_camera->FocalLength() * lookC[1] / lookC[2]; 00172 00173 if(!distortionMap->SetUndistortedFocalPlane(ux, uy)) return DBL_MAX; 00174 00175 double dx = distortionMap->FocalPlaneX(); 00176 double dy = distortionMap->FocalPlaneY(); 00177 00178 CameraFocalPlaneMap *focalMap = p_camera->FocalPlaneMap(); 00179 if(!focalMap->SetFocalPlane(dx, dy)) return DBL_MAX; 00180 00181 detectorMap->SetDetector(focalMap->DetectorSample(), focalMap->DetectorLine()); 00182 00183 double actualFrameletHeight = detectorMap->frameletHeight() / detectorMap->LineScaleFactor(); 00184 double frameletDeltaY = detectorMap->frameletLine() - (actualFrameletHeight / 2.0); 00185 00186 return frameletDeltaY * frameletDeltaY; 00187 } 00188 00199 double PushFrameCameraGroundMap::FindSpacecraftDistance(int framelet, 00200 const SurfacePoint &surfacePoint) { 00201 PushFrameCameraDetectorMap *detectorMap = (PushFrameCameraDetectorMap *) p_camera->DetectorMap(); 00202 00203 detectorMap->SetFramelet(framelet); 00204 if(!p_camera->Sensor::SetGround(surfacePoint, false)) return DBL_MAX; 00205 00206 return p_camera->SlantDistance(); 00207 } 00208 }