Commit f9ce135b authored by Ken Edmundson's avatar Ken Edmundson
Browse files

added preliminary target body functionality to ipce

git-svn-id: http://subversion.wr.usgs.gov/repos/prog/isis3/branches/ipce@6346 41f8697f-d340-4b68-9986-7bafba869bb8
parent f7aea713
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -66,6 +66,9 @@ namespace Isis {
      virtual std::pair <iTime, iTime> ShutterOpenCloseTimes(double time, 
                                                             double exposureDuration);

      //QString name();
      //void setName(QString name);

      /**
       * CK frame ID -
       * Apollo 15 instrument code (A15_METRIC) = -915240
+1 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ namespace Isis {
   *   @history 2012-02-16 Steven Lambright - Brought up to method and member naming standards.
   *   @history 2012-03-22 Steven Lambright - Renamed text() to toString().
   *   @history 2012-06-29 Steven Lambright and Kimberly Oyama - Removed duplicate code from the
   *                           contstructor. Added the fullRotation() method which creates
   *                           constructor. Added the fullRotation() method which creates
   *                           an angle of 360 degrees and modified the unit test to
   *                           exercise this. References #958.
   *   @history 2012-07-26 Steven Lambright and Kimberly Oyama - Modified the < and >
+2 −0
Original line number Diff line number Diff line
@@ -145,6 +145,7 @@ namespace Isis {
    }
  }


  /**
   * Sets the sample/line values of the image to get the lat/lon values
   *
@@ -266,6 +267,7 @@ namespace Isis {
    return false;
  }


  /**
   * Sets the lat/lon values to get the sample/line values
   *
+144 −18
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@

#include <iostream>

#include "IException.h"
#include "NaifStatus.h"
#include "SurfacePoint.h"
#include "Latitude.h"
@@ -82,7 +83,9 @@ namespace Isis {
      double radius = lat.degrees(); //  m
      // double azimuth = lon.degrees();
      Latitude lat(0., Angle::Degrees);
      if (radius < 0.0) radius = 0.0; // TODO: massive, temporary kluge to get around testing latitude at -90 in caminfo app (are there more issues like this? Probably)KE
      if (radius < 0.0) radius = 0.0; // TODO: massive, temporary kluge to get around testing
                                                     // latitude at -90 in caminfo app (are there
                                                     // more issues like this? Probably)KE
      if (p_camera->Sensor::SetGround(SurfacePoint(lat, lon, Distance(radius, Distance::Meters)))) {
         LookCtoFocalPlaneXY();
         return true;
@@ -145,7 +148,7 @@ namespace Isis {
   */
  bool CameraGroundMap::GetXY(const SurfacePoint &point, double *cudx, double *cudy) {

    double pB[3];
    std::vector<double> pB(3);
    pB[0] = point.GetX().kilometers();
    pB[1] = point.GetY().kilometers();
    pB[2] = point.GetZ().kilometers();
@@ -157,23 +160,26 @@ namespace Isis {

    // Should a check be added to make sure SetImage has been called???

    // Compute the look vector in body-fixed coordinates
//    double pB[3]; // Point on surface
//    latrec_c(radius / 1000.0, lon * Isis::PI / 180.0, lat * Isis::PI / 180.0, pB);

    // Get spacecraft vector in body-fixed coordinates
    SpiceRotation *bodyRot = p_camera->bodyRotation();
    SpiceRotation *instRot = p_camera->instrumentRotation();
    std::vector<double> sB = bodyRot->ReferenceVector(p_camera->instrumentPosition()->Coordinate());
    std::vector<double> lookB(3);
    for(int ic = 0; ic < 3; ic++)   lookB[ic] = pB[ic] - sB[ic];
    std::vector<double> pJ = bodyRot->J2000Vector(pB);
    std::vector<double> sJ = p_camera->instrumentPosition()->Coordinate();

    // Calculate lookJ
    std::vector<double> lookJ(3);
    for(int ic = 0; ic < 3; ic++)   lookJ[ic] = pJ[ic] - sJ[ic];

    // Save pB for target body partial derivative calculations NEW *** DAC 8-14-2015
    p_pB = pB;
    
    // Check for point on back of planet by checking to see if surface point is viewable (test emission angle)
    // During iterations, we may not want to do the back of planet test???
    std::vector<double> lookB = bodyRot->ReferenceVector(lookJ);
    double upsB[3], upB[3], dist;
    vminus_c((SpiceDouble *) &lookB[0], upsB);
    unorm_c(upsB, upsB, &dist);
    unorm_c(pB, upB, &dist);
    unorm_c((SpiceDouble *) &pB[0], upB, &dist);
    double angle = vdot_c(upB, upsB);
    double emission;
    if (angle > 1) {
@@ -185,11 +191,12 @@ namespace Isis {
    else {
      emission = acos(angle) * 180.0 / Isis::PI;
    }

    if (fabs(emission) > 90.) return false;

    // Get the look vector in the camera frame and the instrument rotation
    p_lookJ.resize(3);
    p_lookJ = p_camera->bodyRotation()->J2000Vector(lookB);
    p_lookJ = lookJ;
    std::vector <double> lookC(3);
    lookC = instRot->ReferenceVector(p_lookJ);

@@ -263,7 +270,7 @@ namespace Isis {
    return true;
  }

  /** Compute derivative of focal plane coordinate w/r to orientation from ground position using current Spice from SetImage call
  /** Compute derivative of fp coordinate w/r to instrument using current state from SetImage call
   *
   * This method will compute the derivative of the undistorted focal plane coordinate for
   * a ground position with respect to the instrument orientation, using the current Spice
@@ -285,22 +292,24 @@ namespace Isis {
    // Get directional fl for scaling coordinates
    double fl = p_camera->DistortionMap()->UndistortedFocalPlaneZ();

    // Rotate look vector into camera frame
    // Rotate J2000 look vector into camera frame
    SpiceRotation *instRot = p_camera->instrumentRotation();
    std::vector <double> lookC(3);
    lookC = instRot->ReferenceVector(p_lookJ);

    // Rotate J2000 look vector into camera frame through the derivative rotation
    std::vector<double> d_lookC = instRot->ToReferencePartial(p_lookJ, varType, coefIndex);

    *dx = fl * DQuotient(lookC, d_lookC, 0);
    *dy = fl * DQuotient(lookC, d_lookC, 1);
    return true;
  }

  /** Compute derivative of focal plane coordinate w/r to ground point from ground position using current Spice from SetImage call
  /** Compute derivative of focal plane coordinate w/r to target body using current state
   *
   * This method will compute the derivative of the undistorted focal plane coordinate for
   * a ground position with respect to lat, lon, or radius, using the current Spice settings (time and kernels)
   * without resetting the current point values for lat/lon/radius/x/y.
   * a ground position with respect to the target body orientation, using the current Spice
   * settings (time and kernels) without resetting the current point values for lat/lon/radius/x/y.
   *
   * @param varType enumerated partial type (definitions in SpicePosition)
   * @param coefIndex coefficient index of fit polynomial
@@ -309,7 +318,51 @@ namespace Isis {
   *
   * @return conversion was successful
   */
  bool CameraGroundMap::GetdXYdPoint(std::vector<double> d_lookB, double *dx, double *dy) {
  //  also have a GetDxyDorientation and a GetDxyDpoint
  bool CameraGroundMap::GetdXYdTOrientation(const SpiceRotation::PartialType varType, int coefIndex,
      double *dx, double *dy) {

    //  TODO  add a check to make sure p_pB and p_lookJ have been set. 
    // 0.  calculate or save from previous GetXY call lookB.  We need ToJ2000Partial that is 
    //     like a derivative form of J2000Vector  
    // 1.  we will call d_lookJ = bodyrot->ToJ2000Partial (Make sure the partials are correct for the target body
    //             orientation matrix.
    // 2.  we will then call d_lookC = instRot->ReferenceVector(d_lookJ)
    // 3.  the rest should be the same.

    // Get directional fl for scaling coordinates
    double fl = p_camera->DistortionMap()->UndistortedFocalPlaneZ();

    // Rotate body-fixed look vector into J2000 through the derivative rotation
    SpiceRotation *bodyRot = p_camera->bodyRotation();
    SpiceRotation *instRot = p_camera->instrumentRotation();
    std::vector<double> dlookJ = bodyRot->ToJ2000Partial(p_pB, varType, coefIndex);
    std::vector <double> lookC(3);
    std::vector <double> dlookC(3);

    // Rotate both the J2000 look vector and the derivative J2000 look vector into the camera
    lookC = instRot->ReferenceVector(p_lookJ);
    dlookC = instRot->ReferenceVector(dlookJ);

    *dx = fl * DQuotient(lookC, dlookC, 0);
    *dy = fl * DQuotient(lookC, dlookC, 1);
    return true;
  }

  /** Compute derivative of focal plane coordinate w/r to ground point using current state
   *
   * This method will compute the derivative of the undistorted focal plane coordinate for
   * a ground position with respect to lat, lon, or radius, using the current Spice settings (time
   *  and kernels) without resetting the current point values for lat/lon/radius/x/y.
   *
   * @param varType enumerated partial type (definitions in SpicePosition)
   * @param coefIndex coefficient index of fit polynomial
   * @param *dx pointer to partial derivative of undistorted focal plane x
   * @param *dy pointer to partial derivative of undistorted focal plane y
   *
   * @return conversion was successful 
   */
  bool CameraGroundMap::GetdXYdPoint(std::vector<double> d_pB, double *dx, double *dy) {

    //  TODO  add a check to make sure p_lookJ has been set

@@ -322,7 +375,7 @@ namespace Isis {
    lookC = instRot->ReferenceVector(p_lookJ);

    SpiceRotation *bodyRot = p_camera->bodyRotation();
    std::vector<double> d_lookJ = bodyRot->J2000Vector(d_lookB);
    std::vector<double> d_lookJ = bodyRot->J2000Vector(d_pB);
    std::vector<double> d_lookC = instRot->ReferenceVector(d_lookJ);

    *dx = fl * DQuotient(lookC, d_lookC, 0);
@@ -331,6 +384,79 @@ namespace Isis {
  }


  /** Compute derivative of focal plane coordinate w/r to one of the ellipsoidal radii (a, b, or c)
   *
   * This method will compute the derivative of the undistorted focal plane coordinate for
   * a ground position with respect to the a (major axis), b (minor axis), or c (polar axis) radius, 
   * using the current Spice settings (time and kernels) without resetting the current point 
   * values for lat/lon/radius/x/y.
   *
   * @param raxis Radius axis enumerated partial type (definitions in TBD)
   * @param spoint Surface point whose derivative is to be evalutated
   *
   * @return partialDerivative of body-fixed  point with respect to selected ellipsoid axis
   */
  std::vector<double> CameraGroundMap::EllipsoidPartial(SurfacePoint spoint, PartialType raxis) {
    double rlat = spoint.GetLatitude().radians();
    double rlon = spoint.GetLongitude().radians();
    double sinLon = sin(rlon);
    double cosLon = cos(rlon);
    double sinLat = sin(rlat);
    double cosLat = cos(rlat);

    std::vector<double> v(3);

    switch(raxis) {
      case WRT_MajorAxis:   
         v[0] = cosLat * cosLon;
         v[1] = 0.0;
         v[2] =  0.0;
         break;
      case WRT_MinorAxis:  
         v[0] = 0.0;
         v[1] =  cosLat * sinLon;
         v[2] =  0.0;
         break;
      case WRT_PolarAxis: 
         v[0] = 0.0;
         v[1] = 0.0;
         v[2] = sinLat;
         break;
      default:
        QString msg = "Invalid partial type for this method";
        throw IException(IException::Programmer, msg, _FILEINFO_);
    }

    return v;
  }


  /** Compute derivative of focal plane coordinate w/r to one of the ellipsoidal radii (a, b, or c)
   *
   * This method will compute the derivative of the undistorted focal plane coordinate for
   * a ground position with respect to the a (major axis), b (minor axis), or c (polar axis) radius, 
   * using the current Spice settings (time and kernels) without resetting the current point 
   * values for lat/lon/radius/x/y.
   *
   * @param spoint Surface point whose derivative is to be evalutated
   *
   * @return partialDerivative of body-fixed point with respect to mean radius
   * TODO This method assumes the radii of all points in the adjustment have been set identically
   *            to the  
   */
  std::vector<double> CameraGroundMap::MeanRadiusPartial(SurfacePoint spoint, Distance meanRadius) {
    double radkm = meanRadius.kilometers();

    std::vector<double> v(3);

    v[0] = spoint.GetX().kilometers() / radkm;
    v[1] = spoint.GetY().kilometers() / radkm;
    v[2] = spoint.GetZ().kilometers() / radkm;

    return v;
  }


  /** Compute derivative with respect to indicated variable of conversion function from lat/lon/rad to rectangular coord
   *
   * @param lat planetocentric latitude in degrees
+18 −6
Original line number Diff line number Diff line
@@ -65,15 +65,18 @@ namespace Isis {
   *  @history 2011-02-09 Steven Lambright SetGround now uses the Latitude,
   *                       Longitude and SurfacePoint classes.
   *  @history 2011-03-18 Debbie A. Cook Added reference to surface point in GetXY
   *  @history 2012-07-06 Debbie A. Cook Updated Spice members to be more compliant with Isis 
   *                       coding standards. References #972.
   *  @history 2012-07-06 Debbie A. Cook Updated Spice members to be more 
   *                       compliant with Isis coding standards. References #972.
   *  @history 2012-10-10 Debbie A. Cook Modified to use new Target class.
   *                        References Mantis ticket #775 and #1114.
   *  @history 2013-02-22 Debbie A. Cook Fixed LookCtoFocalPlaneXY method to properly handle
   *                        instruments with a look direction along the negative z axis.
   *                        Fixes Mantis ticket #1524
   *  @history 2013-02-22 Debbie A. Cook Fixed LookCtoFocalPlaneXY method 
   *                        to properly handle instruments with a look direction along 
   *                        the negative z axis.  Fixes Mantis ticket #1524
   *   @history 2014-04-17 Jeannie Backer - Replaced local variable names with more
   *                           descriptive names. References #1659.
   *  @history 2015-07-24 Debbie A. Cook Added new methods GetdXYdTOrientation, 
   *                        EllipsoidPartial, and MeanRadiusPartial along with new member 
   *                        p_lookB.   References Mantis ticket TBD.
   *
   */
  class CameraGroundMap {
@@ -89,7 +92,10 @@ namespace Isis {
      enum PartialType {
        WRT_Latitude,
        WRT_Longitude,
        WRT_Radius
        WRT_Radius,
        WRT_MajorAxis,
        WRT_MinorAxis,
        WRT_PolarAxis
      };

      virtual bool SetGround(const Latitude &lat, const Longitude &lon);
@@ -103,9 +109,14 @@ namespace Isis {
      virtual bool GetdXYdOrientation(const SpiceRotation::PartialType varType,
                                      int coefIndex,
                                      double *cudx, double *cudy);
      virtual bool GetdXYdTOrientation(const SpiceRotation::PartialType varType,
                                      int coefIndex,
                                      double *cudx, double *cudy);
      virtual bool GetdXYdPoint(std::vector<double> d_lookB,
                                double *cudx, double *cudy);
      std::vector<double> PointPartial(SurfacePoint spoint, PartialType wrt);
      std::vector<double> EllipsoidPartial(SurfacePoint spoint, PartialType raxis);
      std::vector<double> MeanRadiusPartial(SurfacePoint spoint, Distance meanRadius);
      double DQuotient(std::vector<double> &look, std::vector<double> &dlook,
                       int index);

@@ -126,6 +137,7 @@ namespace Isis {

    private:
      void LookCtoFocalPlaneXY();     //!< Calculate focalplane x/y from lookvector in camera
      std::vector<double> p_pB;  //!< Surface point calculated from ground coordinates in GetXY and used for partials
      std::vector<double> p_lookJ;   //!< Look vector in J2000 calculated from ground coordinates in GetXY and used for partials
  };
};
Loading