Commit 53a08bda authored by Jesse Mapel's avatar Jesse Mapel
Browse files

Lidar points (#4709)

* Added LidarControlPoint

* Hand merge Lidar changes to ControlPoint

* Hand merge changes to ControlPoint for Lidar

* Minor build fix

* Fixed negation

* Moved LidarControlPoint test to gtest
parent 5b23dce4
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -959,7 +959,7 @@ namespace Isis {

    // if point is Fixed or Constrained in any number of coordinates, initialize adjusted surface
    // point to a priori coordinates (set in e.g. qnet or cneteditor) and exit
    if( IsFixed() || IsConstrained()) {
    if( IsFixed() || IsConstrained() || id.contains("Lidar")) {
      adjustedSurfacePoint = aprioriSurfacePoint;
      return Success;
    }
@@ -2053,8 +2053,7 @@ namespace Isis {


  /**
   * What the heck is the point of this?
   *
   * Signal to indicate the point has been modified. Resets the last modified dateTime to null.
   */
  void ControlPoint::PointModified() {
    dateTime = "";
+8 −6
Original line number Diff line number Diff line
@@ -348,6 +348,8 @@ namespace Isis {
   *                           #2591). Added check to IsConstrained() method to see if point type is
   *                           Free, in which case we ignore stored a priori sigmas on the
   *                           coordinates.
   *   @history 2019-04-28 Ken Edmundson Moved PointModified signal and Measures member variable to
   *                           protected and made destructor virtual for subclass LidarControlPoint.
   *  @history 2019-05-16 Debbie A. Cook  See history entry for ComputeResiduals.  Modified call to
   *                           CameraGroundMap to not do back-of-planet test. References #2591.
   */
@@ -461,7 +463,7 @@ namespace Isis {
      ControlPoint();
      ControlPoint(const ControlPoint &);
      ControlPoint(const QString &id);
      ~ControlPoint();
      virtual ~ControlPoint();

      ControlNet *Parent() { return parentNetwork; }

@@ -591,19 +593,19 @@ namespace Isis {
      double GetResidualRms() const;
      void ClearJigsawRejected();

    protected:
      void PointModified();
      //!< List of Control Measures
      QHash< QString, ControlMeasure * > * measures;

    private:
      void SetExplicitReference(ControlMeasure *measure);
      void ValidateMeasure(QString serialNumber) const;
      void AddMeasure(ControlMeasure *measure);
      void PointModified();


    private:
      ControlNet *parentNetwork;

      //!< List of Control Measures
      QHash< QString, ControlMeasure * > * measures;

      QStringList *cubeSerials;

      ControlMeasure *referenceMeasure;
+215 −0
Original line number Diff line number Diff line
#include "LidarControlPoint.h"

#include <QString>
#include <QVector>

#include "Camera.h"
#include "CameraDistortionMap.h"
#include "CameraFocalPlaneMap.h"
#include "CameraGroundMap.h"
#include "ControlMeasure.h"
#include "ControlPoint.h"
#include "Cube.h"
#include "IException.h"
#include "iTime.h"

using namespace std;

namespace Isis {
  

  /**
   * Constructs a LidarControlPoint with the given time, range, and sigma range.
   * 
   */
  LidarControlPoint::LidarControlPoint() {
    m_time = iTime();
    m_range = -1.0;
    m_sigmaRange = -1.0;
    m_snSimultaneous = NULL;

    m_snSimultaneous = new QStringList;
  }
  
  
  /**
   * Destructor
   */
  LidarControlPoint::~LidarControlPoint() {
    if (m_snSimultaneous) {
      delete m_snSimultaneous;
      m_snSimultaneous = NULL;
    }
    
  }
  
  
  /**
   * Set the time of the LidarControlPoint
   * 
   * @param time The time to set
   */
  ControlPoint::Status LidarControlPoint::setTime(iTime time) {
    if (IsEditLocked()) {
      return ControlPoint::Status::PointLocked;
    }
    m_time = time;
    return ControlPoint::Status::Success;
  }

  
  /**
   * Set the range of the LidarControlPoint
   * 
   * @param range The range to set
   */
  ControlPoint::Status LidarControlPoint::setRange(double range) {
    if (IsEditLocked()) {
      return ControlPoint::Status::PointLocked;
    }
    m_range = range;
    return ControlPoint::Status::Success;
  }
  
  
  /**
   * Sets the sigma range
   * 
   * @param sigmaRange The sigma range to set
   */
  ControlPoint::Status LidarControlPoint::setSigmaRange(double sigmaRange) {
    if (IsEditLocked()) {
      return ControlPoint::Status::PointLocked;
    }
    m_sigmaRange = sigmaRange;
    return ControlPoint::Status::Success;
  }
  
  
  /**
   * Add a measure to the list of simultaneous images of a  LidarControlPoint
   * 
   * @param time The serial number of the simultaneous image to add
   */
  ControlPoint::Status LidarControlPoint::addSimultaneous(QString newSerial) {
    m_snSimultaneous->append(newSerial);
    return ControlPoint::Status::Success;
  }
  
  
  /**
   * Returns the range of the point
   * 
   * @return double The range
   */
  double LidarControlPoint::range() {
    return m_range;
  }
  
  
  /**
   * Returns the time of the point
   * 
   * @return double The time
   */
  iTime LidarControlPoint::time() {
    return m_time;
  }
  
  
  /**
   * Returns the sigma range of the point
   * 
   * @return double The sigma range
   */
  double LidarControlPoint::sigmaRange() {
    return m_sigmaRange;
  }
  
  
  /**
   * Returns the list of serial numbers of simultaneous images of the Lidar point
   * 
   * @return QStringList The list of serial numbers
   */
  QStringList LidarControlPoint::snSimultaneous() const{
    return *m_snSimultaneous;
  }


  /**
   * Determines if input serial number is in list of simultaneous measure serial numbers.
   *
   * @param serialNumber Serial number to check.
   *
   * @return bool true if serialNumber is contained in m_snSimultaneous.
   */
  bool LidarControlPoint::isSimultaneous(QString serialNumber) {

    if (m_snSimultaneous->contains(serialNumber)) {
      return true;
    }

    return false;
  }


  /**
   * TODO: clean up code and document why this is different from the ComputeResiduals method for a
   *       normal photogrammetric control point.
   * TODO: compute residuals is a misnomer, we are really moving the measure to it's new back-
   *       projected location in the image
   * TODO: should code be special for radar?
   *
   *     *** Warning:  Only BundleAdjust and its applications should be
   *                   using this method.
   *
   * @history 2019-02-26 Ken Edmundson, initial version.
   */
  ControlPoint::Status LidarControlPoint::ComputeResiduals() {
    if (IsIgnored()) {
      return Failure;
    }

    ControlPoint::PointModified();

    double newSampleDistorted = 0.0;
    double newLineDistorted = 0.0;

    // Loop for each measure to compute the error
    QList<QString> keys = measures->keys();

    for (int j = 0; j < keys.size(); j++) {
      ControlMeasure *measure = (*measures)[keys[j]];
      if (measure->IsIgnored()) {
        continue;
      }

      // back project the adjusted surface point with SPICE updated from current bundle iteration
      Camera* camera = measure->Camera();
      if (camera->SetGround(GetAdjustedSurfacePoint())) {
        newSampleDistorted = camera->Sample();
        newLineDistorted = camera->Line();
        measure->SetRejected(false);
      }
      // what happens if SetGround fails (e.g. if back-projection is off the image?
      else {
        measure->SetRejected(true);
        measure->SetResidual(0.0, 0.0);
        continue;
      }

      // set measures sample, line to the back-projected location
      measure->SetCoordinate(newSampleDistorted, newLineDistorted);

      double measuredUndistortedFPx = camera->DistortionMap()->UndistortedFocalPlaneX();
      double measuredUndistortedFPy = camera->DistortionMap()->UndistortedFocalPlaneY();
      measure->SetFocalPlaneMeasured(measuredUndistortedFPx,measuredUndistortedFPy);
      measure->SetFocalPlaneComputed(measuredUndistortedFPx, measuredUndistortedFPy);

      measure->SetResidual(0.0, 0.0);
    }

    return Success;
  }
}
+107 −0
Original line number Diff line number Diff line
#ifndef LidarControlPoint_h
#define LidarControlPoint_h

/**
 * @file
 * $Revision: 1.14 $
 * $Date: 2009/09/08 17:38:17 $
 *
 *   Unless noted otherwise, the portions of Isis written by the USGS are
 *   public domain. See individual third-party library and package descriptions
 *   for intellectual property information, user agreements, and related
 *   information.
 *
 *   Although Isis has been used by the USGS, no warranty, expressed or
 *   implied, is made by the USGS as to the accuracy and functioning of such
 *   software and related material nor shall the fact of distribution
 *   constitute any such warranty, and no responsibility is assumed by the
 *   USGS in connection therewith.
 *
 *   For additional information, launch
 *   $ISISROOT/doc//documents/Disclaimers/Disclaimers.html
 *   in a browser or see the Privacy &amp; Disclaimers page on the Isis website,
 *   http://isis.astrogeology.usgs.gov, and the USGS privacy and disclaimers on
 *   http://www.usgs.gov/privacy.html.
 */

#include <algorithm>
#include <functional>

#include <QPointer>
#include <QSharedPointer>

#include "ControlMeasure.h"
#include "ControlPoint.h"
#include "Cube.h"
#include "iTime.h"

namespace Isis {
  /**
   * @brief A lidar control ControlPoint
   * 
   * A lidar control point that extends from ControlPoint. Currently only works for LOLA data
   * 
   * @author 2018-01-29 Makayla Shepherd
   * 
   * @see ControlPoint
   *
   * @internal
   *   @history 2018-01-29 Makayla Shepherd Original version
   *   @history 2018-02-09 Ken Edmundson Added typedef forLidarControlPointQsp
   *   @history 2018-03-18 Debbie A. Cook Added Simultaneous measures 
   *   @history 2019-02-23 Debbie A. Cook Added Functor Predicate struct to sort
   *                                        based on Id.  This is needed for getting consistent 
   *                                        output for comparing test data. References #5343.
   *   @history 2019-04-28 Ken Edmundson Modified ComputeResiduals method to correct lidar measure
   *                                        by it's residuals, i.e. by simply moving the measure to
   *                                        it's current, back-projected location in the image.
   */
  
  class LidarControlPoint : public ControlPoint {
    
  public:

    LidarControlPoint();
    
    ~LidarControlPoint();
    
    ControlPoint::Status setRange(double range);
    ControlPoint::Status setSigmaRange(double sigmaRange);
    ControlPoint::Status setTime(iTime time);
    ControlPoint::Status addSimultaneous(QString newSerial);

    ControlPoint::Status ComputeResiduals();

    //  Functor predicate for sorting LidarControlPoints
    struct LidarControlPointLessThanFunctor :
      public std::binary_function<QSharedPointer<LidarControlPoint>,
                                                      QSharedPointer<LidarControlPoint>,
                                                      bool> {
      bool operator() ( QSharedPointer<LidarControlPoint> lcp1,
                                    QSharedPointer<LidarControlPoint> lcp2)
          {
           return (lcp1->GetId() < lcp2->GetId());
          }
    };

    double range();
    double sigmaRange();
    iTime time();
    QStringList snSimultaneous() const;
    bool isSimultaneous(QString serialNumber);

  private:
    double m_range;                //!< range
    double m_sigmaRange;           //!< range sigma
    iTime m_time;                  //!< time lidar point was acquired
    QStringList *m_snSimultaneous; //!< serial number(s) of simultaneous image(s)
    
  };

  // typedefs
  //! Definition for a shared pointer to a LidarControlPoint.
  typedef QSharedPointer<LidarControlPoint> LidarControlPointQsp;
}

#endif
    
+7 −0
Original line number Diff line number Diff line
ifeq ($(ISISROOT), $(BLANK))
.SILENT:
error:
	echo "Please set ISISROOT";
else
	include $(ISISROOT)/make/isismake.objs
endif
 No newline at end of file
Loading