diff --git a/CHANGELOG.md b/CHANGELOG.md index 296adab8a6..05e2edf568 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,8 @@ release. - Changed 'User Parameters' group in camstats to UserParameters for PVL compliance [#5625](https://github.com/DOI-USGS/ISIS3/issues/5625). ### Fixed +- Fixed bug in the method BundleSolutionInfo::outputPointsCSV() where, when performing a rectangular (XYZ) bundle adjustment, the Lat/Lon/Radius point corrections written to points.csv are incorrect and do not match those written to bundleout.txt. Also modified the ctest FunctionalTestJigsawBundleXYZ to spot check six lines (points) in points.csv. +Issue: [5646](https://github.com/DOI-USGS/ISIS3/issues/5646) - Fixed noseam bug where a debugging output statement was inadvertently left in noseam.cpp. Issue: [5660](https://github.com/DOI-USGS/ISIS3/issues/5660) - Fixed jigsaw bugs in which RADIUS is handled incorrectly in the jigsaw gui and in the bundleout.txt diff --git a/isis/src/control/objs/BundleSolutionInfo/BundleSolutionInfo.cpp b/isis/src/control/objs/BundleSolutionInfo/BundleSolutionInfo.cpp index ed8fc99afc..512dc2de7b 100755 --- a/isis/src/control/objs/BundleSolutionInfo/BundleSolutionInfo.cpp +++ b/isis/src/control/objs/BundleSolutionInfo/BundleSolutionInfo.cpp @@ -1613,9 +1613,15 @@ namespace Isis { double dX, dY, dZ; double dSigmaLat, dSigmaLong, dSigmaRadius; QString strStatus; - double cor_lat_m; - double cor_lon_m; - double cor_rad_m; + double cor_lat_dd = 0.0; // lat correction, decimal degrees + double cor_lon_dd = 0.0; // lon correction, decimal degrees + double cor_rad_km = 0.0; // radius correction, kilometers + double cor_lat_m = 0.0; // lat correction, meters + double cor_lon_m = 0.0; // lon correction, meters + double cor_rad_m = 0.0; // radius correction, meters + double latInit = Isis::Null; + double lonInit = Isis::Null; + double radInit = Isis::Null; int numMeasures, numRejectedMeasures; double dResidualRms; @@ -1655,13 +1661,63 @@ namespace Isis { numRejectedMeasures = bundlecontrolpoint->numberOfRejectedMeasures(); dResidualRms = bundlecontrolpoint->residualRms(); + // Use the local radius in meters, rad*1000., to convert radians to meters now instead of the + // target body equatorial radius (DAC 09/17/2018; from BundleControlPoint.cpp) + double rtm = dRadius * 1000.; + // point corrections and initial sigmas boost::numeric::ublas::bounded_vector< double, 3 > corrections = bundlecontrolpoint-> - corrections(); - // Now use the local radius to convert radians to meters instead of the target body equatorial radius - cor_lat_m = bundlecontrolpoint->adjustedSurfacePoint().LatitudeToMeters(corrections[0]); - cor_lon_m = bundlecontrolpoint->adjustedSurfacePoint().LongitudeToMeters(corrections[1]); - cor_rad_m = corrections[2]*1000.0; + corrections(); + + if (m_settings->controlPointCoordTypeBundle() == SurfacePoint::Rectangular) { + double xCor = corrections(0); // km + double yCor = corrections(1); // km + double zCor = corrections(2); // km + + if (!IsSpecial(dX) && !IsSpecial(dY) && !IsSpecial(dZ)) { + SurfacePoint rectPoint(Displacement(dX - xCor, Displacement::Kilometers), + Displacement(dY - yCor, Displacement::Kilometers), + Displacement(dZ - zCor, Displacement::Kilometers)); + + latInit = rectPoint.GetLatitude().degrees(); + lonInit = rectPoint.GetLongitude().degrees(); + radInit = rectPoint.GetLocalRadius().kilometers(); + + if (!IsSpecial(dLat)) { + cor_lat_dd = (dLat - latInit); // degrees + cor_lat_m = cor_lat_dd * DEG2RAD * rtm; + } + if (!IsSpecial(dLon)) { + cor_lon_dd = (dLon - lonInit); // degrees + cor_lon_m = cor_lon_dd * DEG2RAD * rtm * cos(dLat*DEG2RAD); // lon corrections meters + } + if (!IsSpecial(dRadius)) { + cor_rad_km = dRadius - radInit; + cor_rad_m = cor_rad_km * 1000.; + } + } + } + else if (m_settings->controlPointCoordTypeBundle() == SurfacePoint::Latitudinal) { + cor_lat_dd = corrections(0) * RAD2DEG; // lat correction, decimal degs + cor_lon_dd = corrections(1) * RAD2DEG; // lon correction, decimal degs + cor_rad_m = corrections(2) * 1000.0; // radius correction, meters + + cor_lat_m = bundlecontrolpoint->adjustedSurfacePoint().LatitudeToMeters(corrections(0)); + cor_lon_m = bundlecontrolpoint->adjustedSurfacePoint().LongitudeToMeters(corrections(1)); + cor_rad_km = corrections(2); + + if (!IsSpecial(dLat)) { + latInit = dLat - cor_lat_dd; + } + + if (!IsSpecial(dLon)) { + lonInit = dLon - cor_lon_dd; + } + + if (!IsSpecial(dRadius)) { + radInit = dRadius - corrections(2); // km + } + } if (bundlecontrolpoint->type() == ControlPoint::Fixed) { strStatus = "FIXED"; diff --git a/isis/src/control/objs/BundleSolutionInfo/BundleSolutionInfo.h b/isis/src/control/objs/BundleSolutionInfo/BundleSolutionInfo.h index 6ba6d9540c..170efe0311 100755 --- a/isis/src/control/objs/BundleSolutionInfo/BundleSolutionInfo.h +++ b/isis/src/control/objs/BundleSolutionInfo/BundleSolutionInfo.h @@ -164,7 +164,10 @@ namespace Isis { * solution. 3) Cleaned up spacing of Point Coordinate output in the * "INPUT: GLOBAL IMAGE PARAMETER UNCERTAINTIES" section. Originally * added to UofA code on 2019-07-30. - * + * @history 2024-12-03 Ken Edmundson - Fixed bug where, when performing a rectangular (XYZ) + * bundle adjustment, the Lat/Lon/Radius point corrections written + * to the points.csv file are incorrect and do not match those written + * to the bundleout.txt file. */ class BundleSolutionInfo : public QObject { Q_OBJECT diff --git a/isis/tests/FunctionalTestsJigsaw.cpp b/isis/tests/FunctionalTestsJigsaw.cpp index b8fcfa9d15..9ec8ba322c 100644 --- a/isis/tests/FunctionalTestsJigsaw.cpp +++ b/isis/tests/FunctionalTestsJigsaw.cpp @@ -291,6 +291,22 @@ TEST_F(ApolloNetwork, FunctionalTestJigsawBundleXYZ) { UserInterface ui3(APP_XML, args3); jigsaw(ui3); + // spot check several points in rectlat_bundleout=_points.csv file for hard-coded values + QString pointsOutput = tempDir.path() + "/rectlat_bundleout_points.csv"; + + CSVReader::CSVAxis csvLine; + CSVReader line = CSVReader(pointsOutput, false, 0, ',', false, true); + + // A few "Free" points: + compareCsvLine(line.getRow(30), "AS15_000031957,FREE,3,0,0.33,24.24953243,6.15316218,1736.04358729,293.41498797,289.79559800,472.66868036,842.07328770,-1763.20169592,-574.06347857,1573.74545615,169.66190348,713.01291344"); + compareCsvLine(line.getRow(185), "AS15_000055107,FREE,2,0,2.22,24.26546675,6.76093993,1735.38959424,326.33192236,324.29734631,531.76648698,860.53696982,-1800.17000826,-593.89727230,1571.06817968,186.25235838,713.18432228"); + compareCsvLine(line.getRow(396), "AS15_Tie14,FREE,4,0,0.76,23.33873588,4.52915858,1737.24818101,272.63659718,266.05983706,414.39324142,981.58162483,-1855.42653496,-276.42906027,1590.12330171,125.95969814,688.23926236"); + + // A few "Constrained" points: + compareCsvLine(line.getRow(352), "AS15_SocetPAN_01,CONSTRAINED,3,0,0.27,27.61551409,2.18873444,1735.73157411,189.25634559,169.77950505,259.83985021,122.85201072,202.20461434,253.94911381,1536.87168268,58.73802953,804.57403154", 2); + compareCsvLine(line.getRow(360), "AS15_SocetPAN_10,CONSTRAINED,4,0,1.14,25.96576384,3.54303398,1735.73354221,138.47609050,115.15295944,171.82752027,-57.33146538,185.48616378,16.79221293,1557.53867571,96.43742025,759.96317490", 2); + compareCsvLine(line.getRow(380), "AS15_SocetPAN_40,CONSTRAINED,2,0,0.42,25.77444416, 1.88039771,1735.54642874,157.27333414,137.46544829,212.01849634,7.32724742,68.12099922,156.67875462,1562.04017978,51.28321523,754.66675754", 2); + // Compare network and images.csv against the latitude, latitude bundle // Compare network against the latitude/latitude network