diff --git a/include/usgscsm/UsgsAstroLsSensorModel.h b/include/usgscsm/UsgsAstroLsSensorModel.h index b2d0a9b4b62b84f27cc1fdbe443cceb4764f7a20..fcc304834da648562aa1df1750ae2068a654edc7 100644 --- a/include/usgscsm/UsgsAstroLsSensorModel.h +++ b/include/usgscsm/UsgsAstroLsSensorModel.h @@ -78,7 +78,9 @@ public: double m_startingEphemerisTime; double m_centerEphemerisTime; double m_detectorSampleSumming; - double m_startingSample; + double m_detectorLineSumming; + double m_startingDetectorSample; + double m_startingDetectorLine; int m_ikCode; double m_focalLength; double m_zDirection; diff --git a/src/UsgsAstroLsSensorModel.cpp b/src/UsgsAstroLsSensorModel.cpp index 5fc142b7a3257a3111448c0873204e4e35718723..81625270acc0ae42246f406a0e7cc60f61feaf70 100644 --- a/src/UsgsAstroLsSensorModel.cpp +++ b/src/UsgsAstroLsSensorModel.cpp @@ -73,6 +73,7 @@ const std::string UsgsAstroLsSensorModel::_STATE_KEYWORD[] = "m_startingEphemerisTime", "m_centerEphemerisTime", "m_detectorSampleSumming", + "m_detectorSampleSumming", "m_startingDetectorSample", "m_startingDetectorLine", "m_ikCode", @@ -163,17 +164,21 @@ void UsgsAstroLsSensorModel::replaceModelState(const std::string &stateString ) m_startingEphemerisTime = j["m_startingEphemerisTime"]; m_centerEphemerisTime = j["m_centerEphemerisTime"]; m_detectorSampleSumming = j["m_detectorSampleSumming"]; - m_startingSample = j["m_startingDetectorSample"]; + m_detectorLineSumming = j["m_detectorLineSumming"]; + m_startingDetectorSample = j["m_startingDetectorSample"]; + m_startingDetectorLine = j["m_startingDetectorLine"]; m_ikCode = j["m_ikCode"]; MESSAGE_LOG(m_logger, "m_startingEphemerisTime: {} " "m_centerEphemerisTime: {} " "m_detectorSampleSumming: {} " - "m_startingSample: {} " + "m_detectorLineSumming: {} " + "m_startingDetectorSample: {} " "m_ikCode: {} ", j["m_startingEphemerisTime"].dump(), j["m_centerEphemerisTime"].dump(), j["m_detectorSampleSumming"].dump(), - j["m_startingSample"].dump(), j["m_ikCode"].dump()) + j["m_detectorLineSumming"].dump(), + j["m_startingDetectorSample"].dump(), j["m_ikCode"].dump()) m_focalLength = j["m_focalLength"]; m_zDirection = j["m_zDirection"]; @@ -334,7 +339,8 @@ std::string UsgsAstroLsSensorModel::getModelState() const { json state; state["m_modelName"] = _SENSOR_MODEL_NAME; - state["m_startingDetectorSample"] = m_startingSample; + state["m_startingDetectorSample"] = m_startingDetectorSample; + state["m_startingDetectorLine"] = m_startingDetectorLine; state["m_imageIdentifier"] = m_imageIdentifier; state["m_sensorName"] = m_sensorName; state["m_nLines"] = m_nLines; @@ -359,13 +365,16 @@ std::string UsgsAstroLsSensorModel::getModelState() const { m_centerEphemerisTime) state["m_detectorSampleSumming"] = m_detectorSampleSumming; - state["m_startingSample"] = m_startingSample; + state["m_detectorLineSumming"] = m_detectorLineSumming; + state["m_startingDetectorSample"] = m_startingDetectorSample; state["m_ikCode"] = m_ikCode; MESSAGE_LOG(m_logger, "m_detectorSampleSumming: {} " - "m_startingSample: {} " - "m_ikCode: {} ", - m_detectorSampleSumming, m_startingSample, - m_ikCode) + "m_detectorLineSumming: {} " + "m_startingDetectorSample: {} " + "m_ikCode: {} ", + m_detectorSampleSumming, m_detectorLineSumming, + m_startingDetectorSample, + m_ikCode) state["m_focalLength"] = m_focalLength; state["m_zDirection"] = m_zDirection; @@ -487,7 +496,8 @@ void UsgsAstroLsSensorModel::reset() m_startingEphemerisTime = 0.0; // 13 m_centerEphemerisTime = 0.0; // 14 m_detectorSampleSumming = 1.0; // 15 - m_startingSample = 1.0; // 16 + m_detectorLineSumming = 1.0; + m_startingDetectorSample = 1.0; // 16 m_ikCode = -85600; // 17 m_focalLength = 350.0; // 18 m_zDirection = 1.0; // 19 @@ -667,6 +677,7 @@ csm::ImageCoord UsgsAstroLsSensorModel::groundToImage( std::vector<double> detectorView; double detectorLine = m_nLines; + double detectorSample = 0; double count = 0; double timei; @@ -677,7 +688,9 @@ csm::ImageCoord UsgsAstroLsSensorModel::groundToImage( // Convert to detector line detectorLine = m_iTransL[0] + m_iTransL[1] * detectorView[0] - + m_iTransL[2] * detectorView[1]; + + m_iTransL[2] * detectorView[1] + + m_detectorLineOrigin - m_startingDetectorLine; + detectorLine /= m_detectorLineSumming; // Convert to image line approxPt.line += detectorLine; @@ -695,23 +708,25 @@ csm::ImageCoord UsgsAstroLsSensorModel::groundToImage( detectorLine = m_iTransL[0] + m_iTransL[1] * distortedFocalX + m_iTransL[2] * distortedFocalY; - double detectorSample = m_iTransS[0] - + m_iTransS[1] * distortedFocalX - + m_iTransS[2] * distortedFocalY; - + detectorSample = m_iTransS[0] + + m_iTransS[1] * distortedFocalX + + m_iTransS[2] * distortedFocalY; // Convert to image sample line - approxPt.line += detectorLine; - approxPt.samp = (detectorSample + m_detectorSampleOrigin - m_startingSample) + double finalUpdate = (detectorLine + m_detectorLineOrigin - m_startingDetectorLine) + / m_detectorLineSumming; + approxPt.line += finalUpdate; + approxPt.samp = (detectorSample + m_detectorSampleOrigin - m_startingDetectorSample) / m_detectorSampleSumming; + double precision = detectorLine + m_detectorLineOrigin - m_startingDetectorLine; if (achievedPrecision) { - *achievedPrecision = detectorLine; + *achievedPrecision = finalUpdate; } MESSAGE_LOG(m_logger, "groundToImage: image line sample {} {}", approxPt.line, approxPt.samp) - if (warnings && (desiredPrecision > 0.0) && (abs(detectorLine) > desiredPrecision)) + if (warnings && (desiredPrecision > 0.0) && (abs(finalUpdate) > desiredPrecision)) { warnings->push_back( csm::Warning( @@ -807,7 +822,6 @@ csm::EcefCoord UsgsAstroLsSensorModel::imageToGround( { MESSAGE_LOG(m_logger, "Computing imageToGround for {}, {}, {}, with desired precision {}", image_pt.line, image_pt.samp, height, desired_precision); - double xc, yc, zc; double vx, vy, vz; double xl, yl, zl; @@ -1266,7 +1280,6 @@ std::string UsgsAstroLsSensorModel::getReferenceDateAndTime() const double UsgsAstroLsSensorModel::getImageTime( const csm::ImageCoord& image_pt) const { - // Remove 0.5 after ISIS dependency in the linescanrate is gone double lineFull = image_pt.line; auto referenceLineIt = std::upper_bound(m_intTimeLines.begin(), @@ -1513,7 +1526,7 @@ csm::ImageVector UsgsAstroLsSensorModel::getImageSize() const // m_startingEphemerisTime = j["m_startingEphemerisTime"]; // m_centerEphemerisTime = j["m_centerEphemerisTime"]; // m_detectorSampleSumming = j["m_detectorSampleSumming"]; -// m_startingSample = j["m_startingSample"]; +// m_startingDetectorSample = j["m_startingDetectorSample"]; // m_ikCode = j["m_ikCode"]; // m_focalLength = j["m_focalLength"]; // m_isisZDirection = j["m_isisZDirection"]; @@ -1884,10 +1897,10 @@ void UsgsAstroLsSensorModel::losToEcf( // Compute distorted image coordinates in mm (sample, line on image (pixels) -> focal plane double distortedFocalPlaneX, distortedFocalPlaneY; computeDistortedFocalPlaneCoordinates( - m_detectorLineOrigin, sampleUSGSFull, + 0.0, sampleUSGSFull, m_detectorSampleOrigin, m_detectorLineOrigin, - m_detectorSampleSumming, 1.0, - m_startingSample, 0.0, + m_detectorSampleSumming, m_detectorLineSumming, + m_startingDetectorSample, m_startingDetectorLine, m_iTransS, m_iTransL, distortedFocalPlaneX, distortedFocalPlaneY); MESSAGE_LOG(m_logger, "losToEcf: distorted focal plane coordinate {} {}", @@ -2705,16 +2718,19 @@ std::string UsgsAstroLsSensorModel::constructStateFromIsd(const std::string imag state["m_intTimes"].dump()) state["m_detectorSampleSumming"] = getSampleSumming(isd, parsingWarnings); + state["m_detectorLineSumming"] = getLineSumming(isd, parsingWarnings); state["m_startingDetectorSample"] = getDetectorStartingSample(isd, parsingWarnings); state["m_startingDetectorLine"] = getDetectorStartingLine(isd, parsingWarnings); state["m_detectorSampleOrigin"] = getDetectorCenterSample(isd, parsingWarnings); state["m_detectorLineOrigin"] = getDetectorCenterLine(isd, parsingWarnings); MESSAGE_LOG(m_logger, "m_detectorSampleSumming: {} " + "m_detectorLineSumming: {}" "m_startingDetectorSample: {} " "m_startingDetectorLine: {} " "m_detectorSampleOrigin: {} " "m_detectorLineOrigin: {} ", state["m_detectorSampleSumming"].dump(), + state["m_detectorLineSumming"].dump(), state["m_startingDetectorSample"].dump(), state["m_startingDetectorLine"].dump(), state["m_detectorSampleOrigin"].dump(), diff --git a/tests/LineScanCameraTests.cpp b/tests/LineScanCameraTests.cpp index 5daec7f73159d2bbd69853178cf2dc1ab46e0387..d029563600d3bdf37484f934f644ebf0e3284e85 100644 --- a/tests/LineScanCameraTests.cpp +++ b/tests/LineScanCameraTests.cpp @@ -26,11 +26,11 @@ TEST_F(ConstVelocityLineScanSensorModel, State) { // Fly by tests TEST_F(ConstVelocityLineScanSensorModel, Center) { - csm::ImageCoord imagePt(8.5, 8.0); + csm::ImageCoord imagePt(8.0, 8.0); csm::EcefCoord groundPt = sensorModel->imageToGround(imagePt, 0.0); - EXPECT_NEAR(groundPt.x, 10.0, 1e-12); - EXPECT_NEAR(groundPt.y, 0.0, 1e-12); - EXPECT_NEAR(groundPt.z, 0.0, 1e-12); + EXPECT_NEAR(groundPt.x, 9.99999500000, 1e-10); + EXPECT_NEAR(groundPt.y, 0.0, 1e-10); + EXPECT_NEAR(groundPt.z, 0.00999999500, 1e-10); } TEST_F(ConstVelocityLineScanSensorModel, Inversion) { @@ -45,34 +45,46 @@ TEST_F(ConstVelocityLineScanSensorModel, Inversion) { } TEST_F(ConstVelocityLineScanSensorModel, OffBody) { - csm::ImageCoord imagePt(4.5, 4.0); + csm::ImageCoord imagePt(0.0, 4.0); csm::EcefCoord groundPt = sensorModel->imageToGround(imagePt, 0.0); - EXPECT_NEAR(groundPt.x, 0.063995905, 1e-8); - EXPECT_NEAR(groundPt.y, -7.999488033, 1e-8); - EXPECT_NEAR(groundPt.z, 8, 1e-8); + EXPECT_NEAR(groundPt.x, 0.04799688020, 1e-10); + EXPECT_NEAR(groundPt.y, -7.99961602495, 1e-10); + EXPECT_NEAR(groundPt.z, 16.00004799688, 1e-10); } TEST_F(ConstVelocityLineScanSensorModel, ProximateImageLocus) { - csm::ImageCoord imagePt(8.5, 8.0); - csm::EcefCoord groundPt(5, 5, 5); + csm::ImageCoord imagePt(8.0, 8.0); + csm::EcefCoord groundPt(10, 2, 1); + csm::EcefLocus remoteLocus = sensorModel->imageToRemoteImagingLocus(imagePt); csm::EcefLocus locus = sensorModel->imageToProximateImagingLocus(imagePt, groundPt); - EXPECT_NEAR(locus.direction.x, -1.0, 1e-12); - EXPECT_NEAR(locus.direction.y, 0.0, 1e-12); - EXPECT_NEAR(locus.direction.z, 0.0, 1e-12); - EXPECT_NEAR(locus.point.x, 5.0, 1e-12); - EXPECT_NEAR(locus.point.y, 0.0, 1e-12); - EXPECT_NEAR(locus.point.z, 0.0, 1e-12); + double locusToGroundX = locus.point.x - groundPt.x; + double locusToGroundY = locus.point.y - groundPt.y; + double locusToGroundZ = locus.point.z - groundPt.z; + EXPECT_NEAR(locus.direction.x, remoteLocus.direction.x, 1e-10); + EXPECT_NEAR(locus.direction.y, remoteLocus.direction.y, 1e-10); + EXPECT_NEAR(locus.direction.z, remoteLocus.direction.z, 1e-10); + EXPECT_NEAR(locusToGroundX * locus.direction.x + + locusToGroundY * locus.direction.y + + locusToGroundZ * locus.direction.z, 0.0, 1e-10); } TEST_F(ConstVelocityLineScanSensorModel, RemoteImageLocus) { csm::ImageCoord imagePt(8.5, 8.0); csm::EcefLocus locus = sensorModel->imageToRemoteImagingLocus(imagePt); - EXPECT_NEAR(locus.direction.x, -1.0, 1e-12); - EXPECT_NEAR(locus.direction.y, 0.0, 1e-12); - EXPECT_NEAR(locus.direction.z, 0.0, 1e-12); - EXPECT_NEAR(locus.point.x, 1000.0, 1e-12); - EXPECT_NEAR(locus.point.y, 0.0, 1e-12); - EXPECT_NEAR(locus.point.z, 0.0, 1e-12); + csm::EcefCoord groundPt = sensorModel->imageToGround(imagePt, 0.0); + double lookX = groundPt.x - locus.point.x; + double lookY = groundPt.y - locus.point.y; + double lookZ = groundPt.z - locus.point.z; + double lookMag = sqrt(lookX * lookX + lookY * lookY + lookZ * lookZ); + lookX /= lookMag; + lookY /= lookMag; + lookZ /= lookMag; + EXPECT_NEAR(locus.direction.x, lookX, 1e-12); + EXPECT_NEAR(locus.direction.y, lookY, 1e-12); + EXPECT_NEAR(locus.direction.z, lookZ, 1e-12); + EXPECT_NEAR(locus.point.x, 1000.0, 1e-12); + EXPECT_NEAR(locus.point.y, 0.0, 1e-12); + EXPECT_NEAR(locus.point.z, 0.0, 1e-12); } TEST_F(ConstVelocityLineScanSensorModel, calculateAttitudeCorrection) { @@ -129,7 +141,6 @@ TEST_F(OrbitalLineScanSensorModel, getIlluminationDirectionStationary) { } TEST_F(OrbitalLineScanSensorModel, getSunPositionLagrange){ - std::cout<<sensorModel->m_t0Ephem<<std::endl; csm::EcefVector sunPosition = sensorModel->getSunPosition(-.6); EXPECT_DOUBLE_EQ(sunPosition.x, 125); EXPECT_DOUBLE_EQ(sunPosition.y, 125); @@ -169,9 +180,9 @@ TEST_F(OrbitalLineScanSensorModel, getSunPositionStationary){ TEST_F(OrbitalLineScanSensorModel, Center) { csm::ImageCoord imagePt(8.5, 8.0); csm::EcefCoord groundPt = sensorModel->imageToGround(imagePt, 0.0); - EXPECT_DOUBLE_EQ(groundPt.x, 999999.70975015126); + EXPECT_DOUBLE_EQ(groundPt.x, 999999.67040488799); EXPECT_DOUBLE_EQ(groundPt.y, 0.0); - EXPECT_DOUBLE_EQ(groundPt.z, -761.90525203960692); + EXPECT_DOUBLE_EQ(groundPt.z, -811.90523782723039); } TEST_F(OrbitalLineScanSensorModel, Inversion) { @@ -234,7 +245,8 @@ TEST_F(ConstVelocityLineScanSensorModel, FocalLengthAdjustment) { csm::ImageCoord imagePt(8.5, 4.0); sensorModel->setParameterValue(15, -45); csm::EcefLocus locus = sensorModel->imageToRemoteImagingLocus(imagePt); - EXPECT_DOUBLE_EQ(locus.direction.x, -5.0 / sqrt(5 * 5 + 0.4 * 0.4)); - EXPECT_DOUBLE_EQ(locus.direction.y, -0.4 / sqrt(5 * 5 + 0.4 * 0.4)); - EXPECT_DOUBLE_EQ(locus.direction.z, 0.0); + double scale = sqrt(5 * 5 + 0.4 * 0.4 + 0.05 * 0.05); + EXPECT_DOUBLE_EQ(locus.direction.x, -5.0 / scale); + EXPECT_DOUBLE_EQ(locus.direction.y, -0.4 / scale); + EXPECT_DOUBLE_EQ(locus.direction.z, -0.05 / scale); } diff --git a/tests/data/constVelocityLineScan.json b/tests/data/constVelocityLineScan.json index 89b187bd2532b6eaed703f97a33ec8eeb233540b..3e5f8254498d3be364bd6c19eb4a9de2db8a84c4 100644 --- a/tests/data/constVelocityLineScan.json +++ b/tests/data/constVelocityLineScan.json @@ -78,7 +78,7 @@ [0.0, -0.707106781186547, 0.0, 0.707106781186547] ] }, - "starting_detector_line": 0, + "starting_detector_line": 1, "starting_detector_sample": 0, "sun_position": { "positions": [ diff --git a/tests/data/orbitalLineScan.json b/tests/data/orbitalLineScan.json index f101451cedfaee24b47248435c9518f387f9ddb7..15c2c3f1f9ea6757647ae0ec03d78088bc3c43e7 100644 --- a/tests/data/orbitalLineScan.json +++ b/tests/data/orbitalLineScan.json @@ -99,7 +99,7 @@ [0.0, -0.70660152, 0.0, 0.70761168] ] }, - "starting_detector_line": 0, + "starting_detector_line": 1, "starting_detector_sample": 0, "sun_position": { "positions": [