示例#1
0
  /**
   * Constructs an Apollo Metric Camera object using the image labels.
   *
   * @param lab Pvl label from an Apollo Metric image.
   *
   * @internal
   *   @history 2011-01-14 Travis Addair - Added new CK/SPK accessor methods.
   *   @history 2011-05-03 Jeannie Walldren - Added documentation.
   */
  ApolloMetricCamera::ApolloMetricCamera(Pvl &lab) : FramingCamera(lab) {
    NaifStatus::CheckErrors();

    // Get the camera characteristics
    SetFocalLength();
    SetPixelPitch();

    // Setup detector map
    new CameraDetectorMap(this);

    // Setup focal plane map
    CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this, naifIkCode());
    focalMap->SetDetectorOrigin(ParentSamples() / 2.0, ParentLines() / 2.0);

    QString ppKey("INS" + toString(naifIkCode()) + "_PP");
    QString odkKey("INS" + toString(naifIkCode()) + "_OD_K");
    QString decenterKey("INS" + toString(naifIkCode()) + "_DECENTER");

    new ApolloMetricDistortionMap(this, getDouble(ppKey, 0),
                                  getDouble(ppKey, 1), getDouble(odkKey, 0), getDouble(odkKey, 1),
                                  getDouble(odkKey, 2), getDouble(decenterKey, 0),
                                  getDouble(decenterKey, 1), getDouble(decenterKey, 2));

    // Setup the ground and sky map
    new CameraGroundMap(this);
    new CameraSkyMap(this);

    const PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse);

    // The Spacecraft Name should be either Apollo 15, 16, or 17.  The name
    // itself could be formatted any number of ways, but the number contained
    // in the name should be unique between the missions
    QString spacecraft = inst.findKeyword("SpacecraftName")[0];
    if (spacecraft.contains("15")) {
      p_ckFrameId = -915240;
      p_ckReferenceId = 1400015;
      p_spkTargetId = -915;
    }
    else if (spacecraft.contains("16")) {
      p_ckFrameId = -916240;
      p_ckReferenceId = 1400016;
      p_spkTargetId = -916;
    }
    else if (spacecraft.contains("17")) {
      p_ckFrameId = -917240;
      p_ckReferenceId = 1400017;
      p_spkTargetId = -917;
    }
    else {
      QString msg = "File does not appear to be an Apollo image";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    // Create a cache and grab spice info since it does not change for
    // a framing camera (fixed spacecraft position and pointing)
    // Convert the start time to et
    setTime((QString)inst["StartTime"]);
    LoadCache();
    NaifStatus::CheckErrors();
  }
示例#2
0
  /**
   * Constructor for the Themis Vis Camera Model
   *
   * @param lab Pvl label from an Odyssey Themis VIS image.
   *
   * @throws IException::User - The image does not appear to be a Themis
   *                                  VIS image
   * @internal
   *   @history 2010-08-04 Jeannie Walldren - Added NAIF error check.
   */
  ThemisVisCamera::ThemisVisCamera(Pvl &lab) : PushFrameCamera(lab) {
    NaifStatus::CheckErrors();
    // Set up the camera characteristics
    // LoadFrameMounting("M01_SPACECRAFT","M01_THEMIS_VIS");
    // Changed Focal Length from 203.9 (millimeters????) to 202.059, per request from
    // Christopher Edwards ([email protected]) at ASU, on 2/18/11.
    SetFocalLength(202.059);
    SetPixelPitch(0.009);

    PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse);
    // make sure it is a themis vis image
    if(inst["InstrumentId"][0] != "THEMIS_VIS") {
      string msg = "The image does not appear to be a Themis Vis Image";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    // Get necessary variables
    p_exposureDur = inst["ExposureDuration"];
    p_interframeDelay = inst["InterframeDelay"];
    int sumMode = inst["SpatialSumming"];

    // Get the start and end time
    double et;
    QString stime = inst["SpacecraftClockCount"];
    et = getClockTime(stime).Et();

    double offset = inst["SpacecraftClockOffset"];
    p_etStart = et + offset - ((p_exposureDur / 1000.0) / 2.0);
    p_nframes = inst["NumFramelets"];

    // Get the keywords from labels
    PvlGroup &bandBin = lab.findGroup("BandBin", Pvl::Traverse);
    PvlKeyword &orgBand = bandBin["OriginalBand"];
    for(int i = 0; i < orgBand.size(); i++) {
      p_originalBand.push_back(toInt(orgBand[i]));
    }

    // Setup detector map
    double frameRate = p_interframeDelay;
    PushFrameCameraDetectorMap *dmap =
      new PushFrameCameraDetectorMap(this, p_etStart, frameRate, 192);
    dmap->SetDetectorSampleSumming(sumMode);
    dmap->SetDetectorLineSumming(sumMode);

    // Setup focal plane map
    CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this, naifIkCode());
    focalMap->SetDetectorOrigin(512.5, 512.5);

    // Setup distortion map
    new ThemisVisDistortionMap(this);

    // Setup the ground and sky map
    bool evenFramelets = (inst["Framelets"][0] == "Even");
    new PushFrameCameraGroundMap(this, evenFramelets);
    new CameraSkyMap(this);

    LoadCache();
    NaifStatus::CheckErrors();
  }
示例#3
0
    /** 
     * @internal 
     *   @history 2008-11-05 Jeannie Walldren - Replaced reference
     *          to MocLabels IsWideAngleRed() with MocLabels
     *          WideAngleRed().
     */
    MocWideAngleCamera::MocWideAngleCamera (Isis::Pvl &lab) : LineScanCamera(lab) {
      // See if we have a moc camera
      MocLabels *moclab = new Isis::Mgs::MocLabels(lab);
      double lineRate = moclab->LineRate();
      double csum = moclab->CrosstrackSumming();
      double dsum = moclab->DowntrackSumming();
      double ss = moclab->FirstLineSample();
      bool isRed = moclab->WideAngleRed();

      // Set up the camera info from ik/iak kernels
      // LoadEulerMounting();
      SetFocalLength();
      SetPixelPitch();

      if ( PixelPitch() == 1) {
        throw iException::Message(iException::User,
              "Cube file needs to be spiceinit'd with updated iak",_FILEINFO_);
      }
      InstrumentRotation()->SetTimeBias(-1.15);

      // Get the start time from labels
      Isis::PvlGroup &inst = lab.FindGroup ("Instrument",Isis::Pvl::Traverse);
      string stime = inst["SpacecraftClockCount"];
      SpiceDouble etStart;
      scs2e_c (NaifSpkCode(),stime.c_str(),&etStart);

      // Setup detector map
      MocWideAngleDetectorMap *detectorMap =
        new MocWideAngleDetectorMap(this,etStart,lineRate,moclab);
      detectorMap->SetDetectorSampleSumming(csum);
      detectorMap->SetDetectorLineSumming(dsum);
      detectorMap->SetStartingDetectorSample(ss);

      // Setup focal plane map
      CameraFocalPlaneMap *focalMap =
        new CameraFocalPlaneMap(this,NaifIkCode());
      if (isRed) {
        focalMap->SetDetectorOrigin(1674.65,0.0);
        focalMap->SetDetectorOffset(0.0,6.7785);
      }
      else {
        focalMap->SetDetectorOrigin(1688.58,0.0);
        focalMap->SetDetectorOffset(0.0,-0.8486);
      }

      // Setup distortion map
      new MocWideAngleDistortionMap(this,isRed);

      // Setup the ground and sky map
      new LineScanCameraGroundMap(this);
      new LineScanCameraSkyMap(this);

      LoadCache();
    }
示例#4
0
  HiresCamera::HiresCamera (Pvl &lab) : FramingCamera(lab) {

    // Get the camera characteristics
    iString filter = (string)(lab.FindGroup("BandBin", Pvl::Traverse))["FilterName"];
    filter = filter.UpCase();

    SetFocalLength ();
    SetPixelPitch ();

    // Get the start time in et
    PvlGroup inst = lab.FindGroup ("Instrument",Pvl::Traverse);
    string stime = inst["StartTime"];

    double time; 
    str2et_c(stime.c_str(),&time);



    // Do not correct time for center of the exposure duration. This is because
    // the kernels were built to accept the start times of the images. 
    // time += ((double)inst["ExposureDuration"] / 1000.0) / 2.0; // Add half
    // exposure duration in milliseconds

    // Setup detector map
    new CameraDetectorMap(this);

    // Setup focal plane map
    CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this,NaifIkCode());

    focalMap->SetDetectorOrigin (
                   Spice::GetDouble("INS" + (iString)(int)NaifIkCode() +
                                    "_BORESIGHT_SAMPLE"), 
                   Spice::GetDouble("INS" + (iString)(int)NaifIkCode() +
                                    "_BORESIGHT_LINE"));

    // Setup distortion map 
    new CameraDistortionMap(this);

    // Setup the ground and sky map
    new CameraGroundMap(this);
    new CameraSkyMap(this);

    SetEphemerisTime(time);
    LoadCache();
  }
示例#5
0
  IssWACamera::IssWACamera (Pvl &lab) : FramingCamera(lab) {
    PvlGroup bandBin = lab.FindGroup ("BandBin",Pvl::Traverse);
    // Get the camera characteristics
    iString key = string("INS"+(iString)(int)NaifIkCode()+"_")+ (string)bandBin["FilterName"] + "_FOCAL_LENGTH";
    key = key.Convert("/",'_');
    double focalLength = Spice::GetDouble(key);
    
    SetFocalLength (focalLength);
    SetPixelPitch ();
    InstrumentRotation()->SetFrame(Spice::GetInteger("INS_"+(iString)(int)NaifIkCode()+"_FRAME_ID"));


    // Get the start time in et
    PvlGroup inst = lab.FindGroup ("Instrument",Pvl::Traverse);
    string stime = inst["StartTime"];
    double et; 
    str2et_c(stime.c_str(),&et);
    double exposureDuration = (double)inst["ExposureDuration"] /1000.0;
    et += exposureDuration / 2.0;

    // Setup detector map
    int summingMode = inst["SummingMode"];
    CameraDetectorMap *detectorMap = new CameraDetectorMap(this);
    detectorMap->SetDetectorLineSumming(summingMode);
    detectorMap->SetDetectorSampleSumming(summingMode);

    // Setup focal plane map
    CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this,NaifIkCode());

    focalMap->SetDetectorOrigin (Spice::GetDouble("INS" + (iString)(int)NaifIkCode() + "_BORESIGHT_SAMPLE"), 
                                 Spice::GetDouble("INS" + (iString)(int)NaifIkCode() + "_BORESIGHT_LINE"));

    // Setup distortion map
    double k1 = Spice::GetDouble("INS" + (iString)(int)NaifIkCode() + "_K1");
    new RadialDistortionMap(this, k1);

    // Setup the ground and sky map
    new CameraGroundMap(this);
    new CameraSkyMap(this);
  
    SetEphemerisTime(et);
    LoadCache();
  }
示例#6
0
  /**
   * Creates a HrscCamera Camera Model
   *
   * @param lab Pvl label from the iamge
   * @internal
   *   @history 2011-05-03 Jeannie Walldren - Added NAIF error check.
   */
  HrscCamera::HrscCamera(Pvl &lab) : LineScanCamera(lab) {
    NaifStatus::CheckErrors();
    // Setup camera characteristics from instrument and frame kernel
    SetFocalLength();
    SetPixelPitch(0.007);
    instrumentRotation()->SetFrame(-41210);

    // Get required keywords from instrument group
    PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse);

    ReadLineRates(lab.fileName());

    // Setup detector map for transform of image pixels to detector position
    new VariableLineScanCameraDetectorMap(this, p_lineRates);
    DetectorMap()->SetDetectorSampleSumming(inst["Summing"]);

    // Setup focal plane map for transform of detector position to
    // focal plane x/y.  This will read the appropriate CCD
    // transformation coefficients from the instrument kernel

    new CameraFocalPlaneMap(this, naifIkCode());

    QString ikernKey = "INS" + toString(naifIkCode())  + "_BORESIGHT_SAMPLE";
    double sampleBoresight = getDouble(ikernKey);

    ikernKey = "INS" + toString(naifIkCode())  + "_BORESIGHT_LINE";
    double lineBoresight = getDouble(ikernKey);

    FocalPlaneMap()->SetDetectorOrigin(sampleBoresight, lineBoresight);

    // Setup distortion map.  This will read the optical distortion
    // coefficients from the instrument kernel
    new CameraDistortionMap(this);

    // Setup the ground and sky map to transform undistorted focal
    // plane x/y to lat/lon or ra/dec respectively.
    new LineScanCameraGroundMap(this);
    new LineScanCameraSkyMap(this);

    LoadCache();
    NaifStatus::CheckErrors();
  }
示例#7
0
    // constructors
    LoHighCamera::LoHighCamera (Pvl &lab) : FramingCamera(lab) {
      // Get the Instrument label information needed to define the camera for this frame
      PvlGroup inst = lab.FindGroup ("Instrument",Pvl::Traverse);
      iString spacecraft = (string)inst["SpacecraftName"];
      iString instId = (string)inst["InstrumentId"];

      // Turn off the aberration corrections for the instrument position object
        InstrumentPosition()->SetAberrationCorrection("NONE");

        // Get the camera characteristics
      SetFocalLength ();
      SetPixelPitch ();

      // Get the start time in et
      string stime = inst["StartTime"];
      double time; 
      str2et_c(stime.c_str(),&time);

      // Setup focal plane map

      LoCameraFiducialMap fid( inst, NaifIkCode());

      // Setup detector map
      new CameraDetectorMap(this);

      // Setup focalplane map
      CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this,NaifIkCode());
      // Try (0.,0.)
      focalMap->SetDetectorOrigin(0.0,0.0);

      // Setup distortion map
      LoHighDistortionMap *distortionMap = new LoHighDistortionMap(this);
      distortionMap->SetDistortion(NaifIkCode());
      // Setup the ground and sky map
      new CameraGroundMap(this);
      new CameraSkyMap(this);

      SetEphemerisTime(time);
      LoadCache();
    }
示例#8
0
void C3dCamera::ReInit()
{
	SetLookAtPos(0.0f, 0.0f, 0.0f);
	SetEyePos(9.0f, 9.0f, 9.0f);
	SetFocalLength(9.0f);
	SetRotationAboutLookAt(-30.0f, 0.0f, -30.0f);
	SetUpVector(0.0f, 0.0f, 1.0f);	// Z-Axis is up
	m_fPitch = 0.0f;
	m_fYaw   = 0.0f;
	m_fRoll  = 0.0f;

	m_fFovY = 45.0f;
	m_fNear = 1.0f;
	m_fFar  = 10000.0f;

	m_bPerspective	= TRUE;
	m_bBuildLists	= TRUE;
	m_iDisplayLists = 0;
	m_bResetClippingPlanes	= TRUE;

	// Clear our modelview and projection matrix
	memset(&m_dModelViewMatrix, 0, sizeof(GLdouble)*16);
	memset(&m_dProjectionMatrix, 0, sizeof(GLdouble)*16);
}
示例#9
0
  /**
   * Creates a Mariner10 Camera Model
   *
   * @param lab Pvl label from a Mariner 10 image.
   *
   * @throw iException::User - "File does not appear to be a Mariner 10 image.
   *        Invalid InstrumentId."
   * @throw iException::Programmer - "Unable to create distortion map."
   * @internal
   *   @history 2011-05-03 Jeannie Walldren - Added NAIF error check.
   *
   */
  Mariner10Camera::Mariner10Camera(Pvl &lab) : FramingCamera(lab) {
    NaifStatus::CheckErrors();

    //  Turn off the aberration corrections for instrument position object
    instrumentPosition()->SetAberrationCorrection("NONE");
    instrumentRotation()->SetFrame(-76000);

    // Set camera parameters
    SetFocalLength();
    SetPixelPitch();

    PvlGroup inst = lab.findGroup("Instrument", Pvl::Traverse);
    // Get utc start time
    QString stime = inst["StartTime"];

    iTime startTime;
    startTime.setUtc((QString)inst["StartTime"]);
    setTime(startTime);

    // Setup detector map
    new CameraDetectorMap(this);

    // Setup focal plane map, and detector origin
    CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this, naifIkCode());

    QString ikernKey = "INS" + toString((int)naifIkCode()) + "_BORESIGHT_SAMPLE";
    double sampleBoresight = getDouble(ikernKey);
    ikernKey = "INS" + toString((int)naifIkCode()) + "_BORESIGHT_LINE";
    double lineBoresight = getDouble(ikernKey);

    focalMap->SetDetectorOrigin(sampleBoresight, lineBoresight);

    // Setup distortion map which is dependent on encounter, use start time
    // MOON:  1973-11-08T03:16:26.350
    QString spacecraft = (QString)inst["SpacecraftName"];
    QString instId = (QString)inst["InstrumentId"];
    QString cam;
    if(instId == "M10_VIDICON_A") {
      cam = "a";
    }
    else if(instId == "M10_VIDICON_B") {
      cam = "b";
    }
    else {
      QString msg = "File does not appear to be a Mariner10 image. InstrumentId ["
          + instId + "] is invalid Mariner 10 value.";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    QString fname = FileName("$mariner10/reseaus/mar10" + cam
                             + "MasterReseaus.pvl").expanded();

    try {
      new ReseauDistortionMap(this, lab, fname);
    }
    catch(IException &e) {
      string msg = "Unable to create distortion map.";
      throw IException(e, IException::Programmer, msg, _FILEINFO_);
    }

    // Setup the ground and sky map
    new CameraGroundMap(this);
    new CameraSkyMap(this);

    LoadCache();
    NaifStatus::CheckErrors();
  }
示例#10
0
  /**
   * Creates a Hirise Camera Model
   *
   * @param lab Pvl label from the iamge
   * @internal 
   *   @history 2011-05-03 Jeannie Walldren - Added NAIF error check.
   */
  HiriseCamera::HiriseCamera(Cube &cube) : LineScanCamera(cube) {
    NaifStatus::CheckErrors();
    // Setup camera characteristics from instrument and frame kernel
    SetFocalLength();
    SetPixelPitch();
    //LoadFrameMounting("MRO_SPACECRAFT", "MRO_HIRISE_OPTICAL_AXIS");
    instrumentRotation()->SetFrame(-74690);

    // Get required keywords from instrument group
    Pvl &lab = *cube.label();
    PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse);
    int tdiMode = inst["Tdi"];
    double binMode = inst["Summing"];
    int chan = inst["ChannelNumber"];
    int cpmm = inst["CpmmNumber"];
    double deltaLineTimerCount = inst["DeltaLineTimerCount"];
    QString stime = inst["SpacecraftClockStartCount"];

    // Convert CPMM number to CCD number
    static int cpmm2ccd[] = {0, 1, 2, 3, 12, 4, 10, 11, 5, 13, 6, 7, 8, 9};
    int ccd = cpmm2ccd[cpmm];

    // Compute the line rate, convert to seconds, and multiply by the
    // downtrack summing
    double unBinnedRate = (74.0 + (deltaLineTimerCount / 16.0)) / 1000000.0;
    double lineRate = unBinnedRate * binMode;

    // Convert the spacecraft clock count to ephemeris time
    SpiceDouble et;
    // The -74999 is the code to select the transformation from
    // high-precision MRO SCLK to ET
    et = getClockTime(stime, -74999).Et();

    // Adjust the start time so that it is the effective time for
    // the first line in the image file.  Note that on 2006-03-29, this
    // time is now subtracted as opposed to adding it.  The computed start
    // time in the EDR is at the first serial line.
    et -= unBinnedRate * (((double) tdiMode / 2.0) - 0.5);
    // Effective observation
    // time for all the TDI lines used for the
    // first line before doing binning
    et += unBinnedRate * (((double) binMode / 2.0) - 0.5);
    // Effective observation time of the first line
    // in the image file, which is possibly binned

    // Compute effective line number within the CCD (in pixels) for the
    // given TDI mode.
    //   This is the "centered" 0-based line number, where line 0 is the
    //   center of the detector array and line numbers decrease going
    //   towards the serial readout.  Line number +64 sees a spot
    //   on the ground before line number 0 or -64.
    double ccdLine_c = -64.0 + ((double) tdiMode / 2.0);

    // Setup detector map for transform of image pixels to detector position
    //      CameraDetectorMap *detectorMap =
    //        new LineScanCameraDetectorMap(this,et,lineRate);
    LineScanCameraDetectorMap *detectorMap =
      new LineScanCameraDetectorMap(this, et, lineRate);
    detectorMap->SetDetectorSampleSumming(binMode);
    detectorMap->SetDetectorLineSumming(binMode);
    if(chan == 0) {
      detectorMap->SetStartingDetectorSample(1025.0);
    }

    // Setup focal plane map for transform of detector position to
    // focal plane x/y.  This will read the appropriate CCD
    // transformation coefficients from the instrument kernel
    CameraFocalPlaneMap *focalMap =
      new CameraFocalPlaneMap(this, -74600 - ccd);
    focalMap->SetDetectorOrigin(1024.5, 0.0);
    focalMap->SetDetectorOffset(0.0, ccdLine_c);

    // Setup distortion map.  This will read the optical distortion
    // coefficients from the instrument kernel
    CameraDistortionMap *distortionMap = new CameraDistortionMap(this);
    distortionMap->SetDistortion(naifIkCode());

    // Setup the ground and sky map to transform undistorted focal
    // plane x/y to lat/lon or ra/dec respectively.
    new LineScanCameraGroundMap(this);
    new LineScanCameraSkyMap(this);

    LoadCache();
    NaifStatus::CheckErrors();
  }
示例#11
0
  /**
   * Constructs a Clementine HiresCamera object using the image labels.
   *
   * @param lab Pvl label from a Clementine HIRES image.
   *
   * @internal
   *   @history 2011-05-03 Jeannie Walldren - Added NAIF error check.  Added
   *                          call to ShutterOpenCloseTimes() method. Changed
   *                          centertime to add half exposure duration to start
   *                          time to maintain consistency with other Clementine
   *                          models.
   */
  NirCamera::NirCamera(Cube &cube) : FramingCamera(cube) {
    NaifStatus::CheckErrors();
    // Get the camera characteristics

    Pvl &lab = *cube.label();
    QString filter = (QString)(lab.findGroup("BandBin", Pvl::Traverse))["FilterName"];

    filter = filter.toUpper();

    if(filter.compare("A") == 0) {
      SetFocalLength(2548.2642 * 0.038);
    }
    else if(filter.compare("B") == 0) {
      SetFocalLength(2530.8958 * 0.038);
    }
    else if(filter.compare("C") == 0) {
      SetFocalLength(2512.6589 * 0.038);
    }
    else if(filter.compare("D") == 0) {
      SetFocalLength(2509.0536 * 0.038);
    }
    else if(filter.compare("E") == 0) {
      SetFocalLength(2490.7378 * 0.038);
    }
    else if(filter.compare("F") == 0) {
      SetFocalLength(2487.8694 * 0.038);
    }

    SetPixelPitch();

    // Get the start time in et
    PvlGroup inst = lab.findGroup("Instrument", Pvl::Traverse);

    // set variables startTime and exposureDuration
    double et = iTime((QString)inst["StartTime"]).Et();

    // divide exposure duration keyword value by 1000 to convert to seconds
    double exposureDuration = ((double) inst["ExposureDuration"]) / 1000.0;
    pair<iTime, iTime> shuttertimes = ShutterOpenCloseTimes(et, exposureDuration);

    /************************************************************************
     * The following line was uncommented to maintain consistency within all
     * clementine camera models. Not sure why the following was originally
     * commented out:
     * 2010-08-05 Jeannie Walldren
     ***********************************************************************/
    // Do not correct time for center of the exposure duration. This is because
    // the kernels were built to accept the start times of the images.
    iTime centerTime = shuttertimes.first.Et() + exposureDuration / 2.0;

    // Setup detector map
    new CameraDetectorMap(this);

    // Setup focal plane map
    CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this, naifIkCode());

    focalMap->SetDetectorOrigin(
      Spice::getDouble("INS" + toString(naifIkCode()) +
                       "_BORESIGHT_SAMPLE"),
      Spice::getDouble("INS" + toString(naifIkCode()) +
                       "_BORESIGHT_LINE"));

    // Setup distortion map
    new RadialDistortionMap(this, -0.0006364);

    // Setup the ground and sky map
    new CameraGroundMap(this);
    new CameraSkyMap(this);

    setTime(centerTime);
    LoadCache();
    NaifStatus::CheckErrors();
  }
示例#12
0
  /**
   * Constructor for the LRO NAC Camera Model
   *
   * @param lab Pvl Label to create the camera model from
   *
   * @internal 
   *   @history 2011-05-03 Jeannie Walldren - Added NAIF error check.
   */
  LroNarrowAngleCamera::LroNarrowAngleCamera(Cube &cube) : LineScanCamera(cube) {
    NaifStatus::CheckErrors();
    // Set up the camera info from ik/iak kernels
    SetFocalLength();
    SetPixelPitch();

    double constantTimeOffset = 0.0,
           additionalPreroll = 0.0,
           additiveLineTimeError = 0.0,
           multiplicativeLineTimeError = 0.0;

    QString ikernKey = "INS" + toString(naifIkCode()) + "_CONSTANT_TIME_OFFSET";
    constantTimeOffset = getDouble(ikernKey);

    ikernKey = "INS" + toString(naifIkCode()) + "_ADDITIONAL_PREROLL";
    additionalPreroll = getDouble(ikernKey);

    ikernKey = "INS" + toString(naifIkCode()) + "_ADDITIVE_LINE_ERROR";
    additiveLineTimeError = getDouble(ikernKey);

    ikernKey = "INS" + toString(naifIkCode()) + "_MULTIPLI_LINE_ERROR";
    multiplicativeLineTimeError = getDouble(ikernKey);

    // Get the start time from labels
    Pvl &lab = *cube.label();
    PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse);
    QString stime = inst["SpacecraftClockPrerollCount"];
    SpiceDouble etStart;

    if(stime != "NULL") {
      etStart = getClockTime(stime).Et();
    }
    else {
      etStart = iTime((QString)inst["PrerollTime"]).Et();
    }

    // Get other info from labels
    double csum = inst["SpatialSumming"];
    double lineRate = (double) inst["LineExposureDuration"] / 1000.0;
    double ss = inst["SampleFirstPixel"];
    ss += 1.0;

    lineRate *= 1.0 + multiplicativeLineTimeError;
    lineRate += additiveLineTimeError;
    etStart += additionalPreroll * lineRate;
    etStart += constantTimeOffset;

    setTime(etStart);

    // Setup detector map
    LineScanCameraDetectorMap *detectorMap = new LineScanCameraDetectorMap(this, etStart, lineRate);
    detectorMap->SetDetectorSampleSumming(csum);
    detectorMap->SetStartingDetectorSample(ss);

    // Setup focal plane map
    CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this, naifIkCode());

    //  Retrieve boresight location from instrument kernel (IK) (addendum?)
    ikernKey = "INS" + toString(naifIkCode()) + "_BORESIGHT_SAMPLE";
    double sampleBoreSight = getDouble(ikernKey);

    ikernKey = "INS" + toString(naifIkCode()) + "_BORESIGHT_LINE";
    double lineBoreSight = getDouble(ikernKey);

    focalMap->SetDetectorOrigin(sampleBoreSight, lineBoreSight);
    focalMap->SetDetectorOffset(0.0, 0.0);

    // Setup distortion map
    LroNarrowAngleDistortionMap *distMap = new LroNarrowAngleDistortionMap(this);
    distMap->SetDistortion(naifIkCode());

    // Setup the ground and sky map
    new LineScanCameraGroundMap(this);
    new LineScanCameraSkyMap(this);

    LoadCache();
    NaifStatus::CheckErrors();
  }
示例#13
0
  /**
   * @brief Initialize the MDIS camera model for NAC and WAC
   *
   * This constructor reads the Messenger/MDIS instrument addendum for many of
   * its default parameters.
   *
   * This camera model does not support subframes of jailbar imaging modes.
   * An exception is thrown in those cases.
   *
   * @param lab Pvl label from a Messenger MDIS image.
   *
   * @throws iException::User - "Subframe imaging mode is not supported"
   * @throws iException::User - "Jail bar observations are not supported"
   * @throws iException::User - "New MDIS/NAC distortion model invalidates
   *                 previous SPICE - you must rerun spiceinit to get new
   *                 kernels"
   * @internal
   *   @history 2011-05-03 Jeannie Walldren - Added NAIF error check.
   *
   */
  MdisCamera::MdisCamera(Pvl &lab) : FramingCamera(lab) {
    NaifStatus::CheckErrors();
    // Set up detector constants
    const int MdisWac(-236800);
    // const int MdisNac(-236820);

    PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse);

    // Clarification on MDIS subframe image mode provides us the ability to
    // support this mode now.  The entire MDIS frame is geometrically valid
    // but only portions of the full frame actually contain image data.  The
    // portions outside subframes should be NULL and not interfere in
    // downstream processing, such as mosaics.
#if defined(MDIS_SUBFRAMES_UNSUPPORTED)
    int subFrameMode = inst["SubFrameMode"];
    if(subFrameMode != 0) {
      string msg = "Subframe imaging mode is not supported!";
      throw iException::Message(iException::User, msg, _FILEINFO_);
    }
#endif

    //  According to the MDIS team, this is nothing to be concerned with and
    //  should be treated as other normal observations.  So the test to
    // disallow it has been effectively removed 2007-09-05 (KJB).
#if defined(MDIS_JAILBARS_UNSUPPORTED)
    int jailBars = inst["JailBars"];
    if(jailBars != 0) {
      string msg = "Jail bar observations are not currently supported!";
      throw iException::Message(iException::Programmer, msg, _FILEINFO_);
    }
#endif

    //  Determine filter number.  Only conditional code required for
    //  NAC and WAC support!
    int filterNumber(0);    //  Default appropriate for MDIS-NAC
    if(naifIkCode() == MdisWac) {
      PvlGroup &bandBin = lab.findGroup("BandBin", Pvl::Traverse);
      filterNumber = bandBin["Number"];
    }

    //  Set up instrument and filter code strings
    QString ikCode = toString(naifIkCode());
    int fnCode(naifIkCode() - filterNumber);
    QString filterCode = toString(fnCode);
    QString ikernKey;

    // Fetch the frame translations from the instrument kernels
    ikernKey = "INS" + ikCode + "_REFERENCE_FRAME";
    QString baseFrame = getString(ikernKey);

    ikernKey = "INS" + filterCode + "_FRAME";
    QString ikFrame = getString(ikernKey);

    // Set up the camera info from ik/iak kernels

    //  Turns out (2008-01-17) the WAC has different focal lengths for
    // each filter.  Added to the instrument kernel (IAK) on this date.
    //  Add temperature dependant focal length
    SetFocalLength(computeFocalLength(filterCode, lab));

    SetPixelPitch();

    // Removed by Jeff Anderson.  The refactor of the SPICE class
    // uses frames always so this is no longer needed
    //      LoadFrameMounting(baseFrame, ikFrame, false);

    // Get the start time from labels as the starting image time plus half
    // the exposure duration (in <MS>) to get pointing attitude.
    //  !!NOTE:  The ephemeris time MUST be set prior to creating the
    //           cache (CreateCache) because the kernels are all unloaded
    //           after the cache is done and this operation will fail!!
    QString stime = inst["SpacecraftClockCount"];
    double exposureDuration = ((double) inst["ExposureDuration"]) / 1000.0;// divide by 1000 to convert to seconds

    iTime etStart = getClockTime(stime);

    //  Setup camera detector map
    CameraDetectorMap *detMap = new CameraDetectorMap(this);

    // Setup focal plane map, and detector origin for the instrument that
    // may have a filter (WAC only!).
    CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this, fnCode);

    //  Retrieve boresight location from instrument kernel (IK) (addendum?)
    ikernKey = "INS" + ikCode + "_BORESIGHT_SAMPLE";
    double sampleBoreSight = getDouble(ikernKey);

    ikernKey = "INS" + ikCode + "_BORESIGHT_LINE";
    double lineBoreSight = getDouble(ikernKey);

    //  Apply the boresight
    focalMap->SetDetectorOrigin(sampleBoreSight, lineBoreSight);

    // Determine summing.  MDIS has two sources of summing or binning.
    // One is performed in the FPU and the in the MP, post-observation,
    // on-board after coming out of the FPGAs, where the FPU binning is
    // performed.  The FPU binning was programmed incorrectly and the
    // actual pixels from the detector are peculiar.  Hence, I have
    // designed this camera model such that the offsets can be managed
    // external to the code.  See the MDIS instrument kernel addendum
    // in $ISIS3DATA/messenger/kernels/iak/mdisAddendum???.ti for the
    // offsets for *each* detector.  Note that an offset is only applied
    // when FPU binning is performed.
    int fpuBinMode   = inst["FpuBinningMode"];
    int pixelBinMode = inst["PixelBinningMode"];

    int summing = ((pixelBinMode == 0) ? 1 : pixelBinMode);
    //  FPU binning was performed, retrieve the FPU binning offsets and
    //  apply them to the focal plane mapping.
    if(fpuBinMode == 1) {
#if defined(USE_FPU_BINNING_OFFSETS)
      ikernKey = "INS" + ikCode + "_FPUBIN_START_SAMPLE";
      double fpuStartingSample = getDouble(ikernKey);
      detMap->SetStartingDetectorSample(fpuStartingSample);

      ikernKey = "INS" + ikCode + "_FPUBIN_START_LINE";
      double fpuStartingLine = getDouble(ikernKey);
      detMap->SetStartingDetectorLine(fpuStartingLine);
#endif
      summing *= 2;
    }

    //  Set summing/binning modes as an accumulation of FPU and MP binning.
    detMap->SetDetectorLineSumming(summing);
    detMap->SetDetectorSampleSumming(summing);

    // Setup distortion map.  As of 2007/12/06, we now have an actual model.
    // Note that this model supports distinct distortion for each WAC filter.
    // See $ISIS3DATA/messenger/kernels/iak/mdisAddendumXXX.ti or possibly
    // $ISIS3DATA/messenger/kernels/ik/msgr_mdis_vXXX.ti for the *_OD_K
    // parameters.
    // NAC has a new implementation of its distortion contributed by
    // Scott Turner and Lillian Nguyen at JHUAPL.
    // (2010/10/06) The WAC now uses the same disortion model implementation.
    // Valid Taylor Series parameters are in versions msgr_mdis_v120.ti IK
    // and above.   Note fnCode works for NAC as well as long as
    // filterNumber stays at 0 for the NAC only!
    try {
      TaylorCameraDistortionMap *distortionMap = new TaylorCameraDistortionMap(this);
      distortionMap->SetDistortion(fnCode);
    }
    catch(IException &ie) {
      string msg = "New MDIS NAC/WAC distortion models will invalidate previous "
                   "SPICE - you may need to rerun spiceinit to get new kernels";
      throw IException(ie, IException::User, msg, _FILEINFO_);
    }

    // Setup the ground and sky map
    new CameraGroundMap(this);
    new CameraSkyMap(this);

    // Create a cache and grab spice info since it does not change for
    // a framing camera (fixed spacecraft position and pointing) after,
    // of course applying the gimble offset which is handled in the SPICE
    // kernels (thank you!).  Note this was done automagically in the
    // SetEpheremisTime call above.  IMPORTANT that it be done prior to
    // creating the cache since all kernels are unloaded, essentially
    // clearing the pool and whacking the frames definitions, required to
    iTime centerTime = etStart + (exposureDuration / 2.0);
    setTime(centerTime);
    LoadCache();
    NaifStatus::CheckErrors();
  }
示例#14
0
void C3dCamera::FitBounds(double minX, double minY, double minZ, 
						  double maxX, double maxY,double maxZ)
{
	boundingPlane boundsRight;
	boundingPlane boundsLeft;
	boundingPlane boundsTop;
	boundingPlane boundsBottom;
	boundingPlane boundsNear;
	boundingPlane boundsFar;
	SG_VECTOR boundsMax;
	SG_VECTOR boundsMin;
	SG_VECTOR vecCenter;
	SG_VECTOR vertices[8];
	SG_VECTOR vecOffset;
	sgCMatrix matrix;
	GLdouble focalLength;
	GLdouble fDepthWidth, fDepthHeight;
	GLdouble rx, ry, rz;
	GLdouble fTan;
	GLdouble fx, fz;

	// Initialize our function variables
	boundsRight.fDepth	= 0.0;
	boundsLeft.fDepth	= 0.0;
	boundsTop.fDepth	= 0.0;
	boundsBottom.fDepth	= 0.0;
	boundsNear.fDepth	= 0.0;
	boundsFar.fDepth	= 0.0;
	memset(&(boundsRight.vec),0,sizeof(SG_VECTOR));
	memset(&(boundsLeft.vec),0,sizeof(SG_VECTOR));
	memset(&(boundsTop.vec),0,sizeof(SG_VECTOR));
	memset(&(boundsBottom.vec),0,sizeof(SG_VECTOR));
	memset(&(boundsNear.vec),0,sizeof(SG_VECTOR));
	memset(&(boundsFar.vec),0,sizeof(SG_VECTOR));
	memset(&(vecOffset),0,sizeof(SG_VECTOR));
	memset(&(boundsMin),0,sizeof(SG_VECTOR));
	memset(&(boundsMax),0,sizeof(SG_VECTOR));
	memset(&(vecCenter),0,sizeof(SG_VECTOR));
	
	fTan = (double)tanf((float)Radiansf(m_fFovY/2));


	// Get the cameras rotatiom about the LookAt position, as we 
	// will use this to restore the rotation values after we move
	// the camera and it's focal length.
	GetRotationAboutLookAt(&rx, &ry, &rz);

	// Copy the bounds to our local variable
	boundsMin.x = minX;	boundsMin.y = minY;	boundsMin.z = minZ;
	boundsMax.x = maxX;	boundsMax.y = maxY;	boundsMax.z = maxZ;

	double spanX, spanY, spanZ;

	spanX = Diff(boundsMax.x, boundsMin.x);
	spanY = Diff(boundsMax.y, boundsMin.y);
	spanZ = Diff(boundsMax.z, boundsMin.z);

	vecCenter.x = boundsMax.x - fabs(spanX)/2;
	vecCenter.y = boundsMax.y - fabs(spanY)/2;
	vecCenter.z = boundsMax.z - fabs(spanZ)/2;

	boundsMax.x = spanX/2;
	boundsMax.y = spanY/2;
	boundsMax.z = spanZ/2;

	boundsMin.x = -spanX/2;
	boundsMin.y = -spanY/2;
	boundsMin.z = -spanZ/2;

	// Given the bounding box, fill in the missing vertices to complete our
	// cube
	vertices[0] = boundsMax;	// Left
vertices[1].x = boundsMax.x; vertices[1].y = boundsMax.y; vertices[1].z = boundsMin.x;
vertices[2].x = boundsMax.x; vertices[2].y = boundsMin.y; vertices[2].z = boundsMin.x;
vertices[3].x = boundsMax.x; vertices[3].y = boundsMin.y; vertices[3].z = boundsMax.x;
	
	vertices[4] = boundsMin;
vertices[5].x = boundsMin.x; vertices[5].y = boundsMin.y; vertices[5].z = boundsMax.x;
vertices[6].x = boundsMin.x; vertices[6].y = boundsMax.y; vertices[6].z = boundsMax.x;
vertices[7].x = boundsMin.x; vertices[7].y = boundsMax.y; vertices[7].z = boundsMin.x;

	// Get the cameras rotation matrix
	GetRotationMatrix(matrix);

	for(int i=0; i<8; i++)
	{
		// Transform the vertice by the camera rotation matrix.  Since we define the 
		// default 'Up' camera position as Z-axis Up, the coordinates map as follows:
		//		X maps to Width,
		//		Y maps to Depth
		//		Z mpas to Height
		zero_p.x  = zero_p.y  =zero_p.z  =0.0;
		matrix.ApplyMatrixToVector(zero_p, vertices[i]);

		// Calculate the focal length needed to fit the near bounding plane
		fDepthWidth  = (fabs(vertices[i].x)/fTan/m_fAspect)-vertices[i].y;
		fDepthHeight = (fabs(vertices[i].z)/fTan)-vertices[i].y;


		// Calculate the Near clipping bounds.  This will be used to fit Isometric views and
		// for calculating the Near/Far clipping m_fFrustum.
		if(vertices[i].y<0)
		{
			if( fabs(vertices[i].x) > fabs(boundsNear.vec.x) ||
			   (fabs(vertices[i].x) == boundsNear.vec.x && fabs(vertices[i].y) > fabs(boundsNear.vec.z)) )
			{
				boundsNear.vec.x = fabs(vertices[i].x);
				boundsNear.vec.z = fabs(vertices[i].y);
			}

			if( fabs(vertices[i].z) > fabs(boundsNear.vec.y) ||
			   (fabs(vertices[i].z) == boundsNear.vec.y) )
			{
				boundsNear.vec.y = fabs(vertices[i].z);
				//boundsNear.vec[W] = fabs(vertices[i].y);
			}

			// Get the bounding depth closest to the viewer
			if(fDepthWidth < boundsNear.fDepth || boundsNear.fDepth == 0)
				boundsNear.fDepth = fDepthWidth;
			if(fDepthHeight < boundsNear.fDepth || boundsNear.fDepth == 0)
				boundsNear.fDepth = fDepthHeight;
		}
		else
		{
			if( fabs(vertices[i].x) > fabs(boundsFar.vec.x) ||
			   (fabs(vertices[i].x) == boundsFar.vec.x && fabs(vertices[i].y) < fabs(boundsFar.vec.z)) )
			{
				boundsFar.vec.x = vertices[i].x;
				boundsFar.vec.z = vertices[i].y;
			}

			if( fabs(vertices[i].z) > fabs(boundsFar.vec.y) ||
			   (fabs(vertices[i].z) == fabs(boundsFar.vec.y)) )
			{
				boundsFar.vec.y = vertices[i].z;
				//boundsFar.vec[W] = vertices[i].y;
			}

			// Get the bounding depth furtherest from the viewer
			if(fDepthWidth > boundsFar.fDepth)
				boundsFar.fDepth = fDepthWidth;
			if(fDepthHeight > boundsFar.fDepth)
				boundsFar.fDepth = fDepthHeight;
		}


		// Calculate the Right, Left, Top and Bottom clipping bounds.  This will be used to fit
		// Perspective views.
		if(vertices[i].x > 0)
		{
			if(fDepthWidth > boundsRight.fDepth)
			{
				boundsRight.fDepth = fDepthWidth;
				boundsRight.vec.x = vertices[i].x;
				//boundsRight.vec[W] = vertices[i].y;
			}
		}
		if(vertices[i].x <= 0)
		{
			if(fDepthWidth > boundsLeft.fDepth)
			{
				boundsLeft.fDepth = fDepthWidth;
				boundsLeft.vec.x = vertices[i].x;
				//boundsLeft.vec[W] = vertices[i].y;
			}
		}
		if(vertices[i].z > 0)
		{
			if(fDepthHeight > boundsTop.fDepth)
			{
				boundsTop.fDepth = fDepthHeight;
				boundsTop.vec.x = vertices[i].x;
				//boundsTop.vec[W] = vertices[i].y;
			}
		}
		if(vertices[i].z <= 0)
		{
			if(fDepthHeight > boundsBottom.fDepth)
			{
				boundsBottom.fDepth = fDepthHeight;
				boundsBottom.vec.x = vertices[i].x;
				//boundsBottom.vec[W] = vertices[i].y;
			}
		}
	}

	// Now that we have the view clipping bounds, we can calculate the focal depth
	// required to fit the volumn and the offset necessary to center the volumn.
	if(m_bPerspective)
	{
		sgCMatrix invMatrix;

		if(boundsRight.fDepth == boundsLeft.fDepth &&
		   boundsTop.fDepth == boundsBottom.fDepth )
		{
			// Front, Side or Top view

			//  Since the bounds are symetric, just use the Right and Top focal depth.
			fx = boundsRight.fDepth;
			fz = boundsTop.fDepth;

			// No offset necessary
			vecOffset.x = vecOffset.y = vecOffset.z = 0.0;
		}
		else
		{
			// Calculate the average focal length needed to fit the bounding box
			fx = (boundsRight.fDepth + boundsLeft.fDepth)/2;
			fz = (boundsTop.fDepth + boundsBottom.fDepth)/2;

			// Calculate the offset necessary to center the bounding box.  Note that we
			// use a scaling factor for centering the non-limiting bounds to achieve a
			// more visually appealing center.
			if(fx > fz)
			{
				GLdouble fScale	= sqrt(boundsTop.fDepth/boundsBottom.fDepth);
				GLdouble fTop	= fTan*fx - fTan*boundsTop.fDepth;
				GLdouble fBottom = fTan*fx - fTan*boundsBottom.fDepth;

				vecOffset.x = (fTan*m_fAspect*boundsRight.fDepth - fTan*m_fAspect*fx);
				vecOffset.z = (fBottom-fTop*fScale)/2;
			}
			else
			{
				GLdouble fScale	= sqrt(boundsLeft.fDepth/boundsRight.fDepth);
				GLdouble fRight = fTan*m_fAspect*fz - fTan*m_fAspect*boundsRight.fDepth;
				GLdouble fLeft  = fTan*m_fAspect*fz - fTan*m_fAspect*boundsLeft.fDepth;

				vecOffset.z = (fTan*boundsTop.fDepth - fTan*fz);
				vecOffset.x = (fLeft - fRight*fScale)/2; 
			}
		}

		// Now that we have the offsets necessary to center the bounds, we must rotate
		// the vertices (camera coordinates) by the cameras inverse rotation matrix to
		// convert the offsets to world coordinates.
		GetInvRotationMatrix(invMatrix);
		zero_p.x  = zero_p.y  =zero_p.z  =0.0;

		invMatrix.ApplyMatrixToVector(zero_p,vecOffset);
	
	}
	else
	{
		// Isometric View
		// Calculate the focal length needed to fit the near bounding plane
		if(m_iScreenWidth <= m_iScreenHeight)
		{
			fx = boundsNear.vec.x/tanf((float)Radiansf(m_fFovY/2));
			fz = boundsNear.vec.y/tanf((float)Radiansf(m_fFovY/2))/((GLdouble)m_iScreenHeight/(GLdouble)m_iScreenWidth);
		}
		else
		{
			fx = boundsNear.vec.x/tanf((float)Radiansf(m_fFovY/2))/m_fAspect;
			fz = boundsNear.vec.y/tanf((float)Radiansf(m_fFovY/2));
		}
	}
	
	// Set the focal length equal to the largest length required to fit either the 
	// Width (Horizontal) or Height (Vertical)
	focalLength = (fx > fz? fx : fz);

	// Set the camera's new LookAt position to focus on the center
	// of the bounding box.
	SetLookAtPos(vecCenter.x+vecOffset.x, vecCenter.y+vecOffset.y, vecCenter.z+vecOffset.z);

	// Set the camera focal Length
	if(focalLength > m_fNear)
		SetFocalLength(focalLength, TRUE);

	// Adjust the Near clipping plane if necessary
//	if((boundsNear.fDepth/2) > 0.5f)
//		m_fNear = boundsNear.fDepth/2;

	// Adjust the Far clipping plane if necessary
	if(focalLength+boundsFar.fDepth > m_fFar)
		m_fFar = focalLength+boundsFar.fDepth;

	// Recalculate the camera view m_fFrustum;
	ResetView();

	// Restore the cameras rotation about the LookAt position
	SetRotationAboutLookAt(rx, ry, rz);
}