Unverified Commit 56bbb366 authored by Oleg Alexandrov's avatar Oleg Alexandrov Committed by GitHub
Browse files

Add fix for ground to image calculation for LRO NAC cameras (#341)



* Add fix for ground to image calculation for LRO NAC cameras

* Make the choice of the sign of m_iTransL only once at model loading

* Reword a comment

* Robustness fix, must always ensure fractional part is 0.5

* Remove the abs, cannot assume those values are positive

* Added opposite flight and detector test

Co-authored-by: default avatarJesse Mapel <jmapel@usgs.gov>
parent 9414c80a
Loading
Loading
Loading
Loading
+31 −1
Original line number Diff line number Diff line
@@ -648,6 +648,36 @@ void UsgsAstroLsSensorModel::updateState() {

  // Set focal length variance
  m_covariance[15 * num_params + 15] = positionVariance;

  // Test if a pixel projected to the ground and projected back
  // returns to the original location. If not, flip the sign of
  // m_iTransL. It is very important here to pick a pixel which is not
  // an integer, as this test may succeed for integer pixels and fail
  // for non-integer ones. Also, need to pick the answer with the
  // smallest achieved precision, even when neither of them is smaller
  // than the desired precision.

  lineCtr = round(m_nLines / 2.0) + 0.5;
  sampCtr = round(m_nSamples / 2.0) + 0.5;

  double desiredPrecision = 0.001;
  ip = csm::ImageCoord(lineCtr, sampCtr);
  csm::EcefCoord xyz = imageToGround(ip, refHeight);

  double achievedPrecision1 = 1.0;
  // Will use m_iTransL on the next line
  ip = groundToImage(xyz, desiredPrecision, &achievedPrecision1);

  double achievedPrecision2 = 1.0;
  for (int it = 0; it < sizeof(m_iTransL)/sizeof(double); it++)
    m_iTransL[it] = -m_iTransL[it]; // use a flipped m_iTransL
  ip = groundToImage(xyz, desiredPrecision, &achievedPrecision2);

  if (std::abs(achievedPrecision1) <= std::abs(achievedPrecision2)) {
    // Flip back m_iTransL as the original was better
    for (int it = 0; it < sizeof(m_iTransL)/sizeof(double); it++)
      m_iTransL[it] = -m_iTransL[it];
  }
}

//---------------------------------------------------------------------------
@@ -2045,7 +2075,7 @@ std::vector<double> UsgsAstroLsSensorModel::computeDetectorView(
                       bodyToCamera[5] * bodyLookY +
                       bodyToCamera[8] * bodyLookZ;
  MESSAGE_LOG(
      "computeDetectorView: look vector (camrea ref frame)"
      "computeDetectorView: look vector (camera ref frame)"
      "{} {} {}",
      cameraLookX, cameraLookY, cameraLookZ)

+26 −0
Original line number Diff line number Diff line
@@ -261,6 +261,32 @@ class OrbitalLineScanSensorModel : public ::testing::Test {
  }
};

class FlippedOrbitalLineScanSensorModel : public ::testing::Test {
 protected:
  csm::Isd isd;
  UsgsAstroLsSensorModel *sensorModel;

  void SetUp() override {
    sensorModel = NULL;

    isd.setFilename("data/flippedOrbitalLineScan.img");
    UsgsAstroPlugin cameraPlugin;

    csm::Model *model = cameraPlugin.constructModelFromISD(
        isd, "USGS_ASTRO_LINE_SCANNER_SENSOR_MODEL");
    sensorModel = dynamic_cast<UsgsAstroLsSensorModel *>(model);

    ASSERT_NE(sensorModel, nullptr);
  }

  void TearDown() override {
    if (sensorModel) {
      delete sensorModel;
      sensorModel = NULL;
    }
  }
};

class TwoLineScanSensorModels : public ::testing::Test {
 protected:
  csm::Isd isd;
+8 −0
Original line number Diff line number Diff line
@@ -276,6 +276,14 @@ TEST_F(OrbitalLineScanSensorModel, ReferenceDateTime) {
  EXPECT_EQ(date, "2000-01-01T00:16:39Z");
}

TEST_F(FlippedOrbitalLineScanSensorModel, OppositeFlightDetector) {
  csm::ImageCoord imagePt(8.7, 8.0);
  csm::EcefCoord groundPt = sensorModel->imageToGround(imagePt, 0.0);
  csm::ImageCoord backProjImagePt = sensorModel->groundToImage(groundPt);
  EXPECT_NEAR(imagePt.line, backProjImagePt.line, 0.001);
  EXPECT_NEAR(imagePt.samp, backProjImagePt.samp, 0.001);
}

TEST_F(TwoLineScanSensorModels, CrossCovariance) {
  std::vector<double> crossCovars =
      sensorModel1->getCrossCovarianceMatrix(*sensorModel2);
+241 −0
Original line number Diff line number Diff line
{
  "name_model" : "USGS_ASTRO_LINE_SCANNER_SENSOR_MODEL",
  "name_platform" : "TEST_PLATFORM",
  "name_sensor" : "TEST_SENSOR",
  "center_ephemeris_time": 1000.0,
  "starting_ephemeris_time": 999.2,
  "line_scan_rate": [
    [0.5, -0.85, 0.1]
  ],
  "detector_sample_summing": 1,
  "detector_line_summing": 1,
  "t0_ephemeris": -0.8,
  "dt_ephemeris": 0.1,
  "t0_quaternion": -0.8,
  "dt_quaternion": 0.1,
  "focal2pixel_lines": [0.0, 10.0, 0.0],
  "focal2pixel_samples": [0.0, 0.0, 10.0],
  "focal_length_model": {
    "focal_length": 50
  },
  "image_lines": 16,
  "image_samples": 16,
  "detector_center" : {
    "line" : 0.5,
    "sample" : 8.0
  },
  "interpolation_method": "lagrange",
  "optical_distortion": {
    "radial": {
      "coefficients": [0.0, 0.0, 0.0]
    }
  },
  "radii": {
    "semimajor": 1000,
    "semiminor": 1000,
    "unit":"km"
  },
  "reference_height": {
    "maxheight": 1000,
    "minheight": -1000,
    "unit": "m"
  },
  "instrument_position": {
    "unit": "km",
    "positions": [
      [1050.0, 0.0, -0.0],
      [1049.99999524, 0.0, -0.1],
      [1049.99998095, 0.0, -0.2],
      [1049.99995714, 0.0, -0.3],
      [1049.99992381, 0.0, -0.39999999],
      [1049.99988095, 0.0, -0.49999998],
      [1049.99982857, 0.0, -0.59999997],
      [1049.99976667, 0.0, -0.69999995],
      [1049.99969524, 0.0, -0.79999992],
      [1049.99961429, 0.0, -0.89999989],
      [1049.99952381, 0.0, -0.99999985],
      [1049.99942381, 0.0, -1.0999998],
      [1049.99931429, 0.0, -1.19999974],
      [1049.99919524, 0.0, -1.29999967],
      [1049.99906667, 0.0, -1.39999959],
      [1049.99892857, 0.0, -1.49999949]
    ],
    "velocities": [
      [-0.0, 0.0, -1.0500],
      [-0.1, 0.0, -1.04999999524],
      [-0.2, 0.0, -1.04999998095],
      [-0.3, 0.0, -1.04999995714],
      [-0.39999999, 0.0 ,-1.04999992381],
      [-0.49999998, 0.0 ,-1.04999988095],
      [-0.59999997, 0.0 ,-1.04999982857],
      [-0.69999995, 0.0 ,-1.04999976667],
      [-0.79999992, 0.0 ,-1.04999969524],
      [-0.89999989, 0.0 ,-1.04999961429],
      [-0.99999985, 0.0 ,-1.04999952381],
      [-1.0999998, 0.0 ,-1.04999942381],
      [-1.19999974, 0.0 ,-1.04999931429],
      [-1.29999967, 0.0 ,-1.04999919524],
      [-1.39999959, 0.0 ,-1.04999906667],
      [-1.49999949, 0.0, -1.04999892857]
    ],
    "ephemeris_times": [
      999.2,
      999.3,
      999.4,
      999.5,
      999.6,
      999.7,
      999.8,
      999.9,
      1000.0,
      1000.1,
      1000.2,
      1000.3,
      1000.4,
      1000.5,
      1000.6,
      1000.7
    ],
    "reference_frame": 1
  },
  "instrument_pointing": {
    "quaternions": [
      [0.70710678, 0.0, -0.70710678, 0.0],
      [0.70707311, 0.0, -0.70714045, 0.0],
      [0.70703943, 0.0, -0.70717412, 0.0],
      [0.70700576, 0.0, -0.70720779, 0.0],
      [0.70697208, 0.0, -0.70724146, 0.0],
      [0.7069384,  0.0, -0.70727512, 0.0],
      [0.70690472, 0.0, -0.70730878, 0.0],
      [0.70687104, 0.0, -0.70734244, 0.0],
      [0.70683736, 0.0, -0.7073761 , 0.0],
      [0.70680367, 0.0, -0.70740976, 0.0],
      [0.70676998, 0.0, -0.70744342, 0.0],
      [0.70673629, 0.0, -0.70747707, 0.0],
      [0.7067026,  0.0, -0.70751073, 0.0],
      [0.70666891, 0.0, -0.70754438, 0.0],
      [0.70663522, 0.0, -0.70757803, 0.0],
      [0.70660152, 0.0, -0.70761168, 0.0]
    ],
    "ephemeris_times": [
      999.2,
      999.3,
      999.4,
      999.5,
      999.6,
      999.7,
      999.8,
      999.9,
      1000.0,
      1000.1,
      1000.2,
      1000.3,
      1000.4,
      1000.5,
      1000.6,
      1000.7
    ],
    "angular_velocities": [
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0]
    ],
    "reference_frame": 1
  },
  "body_rotation": {
    "quaternions": [
      [1.0, 0.0, 0.0, 0.0],
      [1.0, 0.0, 0.0, 0.0],
      [1.0, 0.0, 0.0, 0.0],
      [1.0, 0.0, 0.0, 0.0],
      [1.0, 0.0, 0.0, 0.0],
      [1.0, 0.0, 0.0, 0.0],
      [1.0, 0.0, 0.0, 0.0],
      [1.0, 0.0, 0.0, 0.0],
      [1.0, 0.0, 0.0, 0.0],
      [1.0, 0.0, 0.0, 0.0],
      [1.0, 0.0, 0.0, 0.0],
      [1.0, 0.0, 0.0, 0.0],
      [1.0, 0.0, 0.0, 0.0],
      [1.0, 0.0, 0.0, 0.0],
      [1.0, 0.0, 0.0, 0.0],
      [1.0, 0.0, 0.0, 0.0]
    ],
    "ephemeris_times": [
      999.2,
      999.3,
      999.4,
      999.5,
      999.6,
      999.7,
      999.8,
      999.9,
      1000.0,
      1000.1,
      1000.2,
      1000.3,
      1000.4,
      1000.5,
      1000.6,
      1000.7
    ],
    "angular_velocities": [
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0],
      [0.0, 0.0, 0.0]
    ],
    "reference_frame": 1,
    "constant_frames": [1, 2, 3],
    "time_dependent_frames": [4, 5, 6]
  },
  "starting_detector_line": 1,
  "starting_detector_sample": 0,
  "sun_position": {
    "positions": [
      [0.100, 0.100, 0.100],
      [0.150, 0.150, 0.150],
      [0.200, 0.200, 0.200],
      [0.250, 0.250, 0.250]
    ],
    "velocities": [
      [0.125, 0.125, 0.125],
      [0.125, 0.125, 0.125],
      [0.125, 0.125, 0.125],
      [0.125, 0.125, 0.125]
    ],
    "ephemeris_times": [
      999.2,
      999.6,
      1000.0,
      1000.4
    ],
    "reference_frame": 1,
    "unit": "km"
  }
}