////////////////////////////////////////////////////////////////////////// // // (C) Copyright 2003 by GATS, Inc. // 11864 Canon Blvd., STE 101 // Newport News, VA 23606 // // All Rights Reserved. No part of this software or publication may be // reproduced, stored in a retrieval system, or transmitted, in any form // or by any means, electronic, mechanical, photocopying, recording, or // otherwise without the prior written permission of GATS, Inc. // /////////////////////////////////////////////////////////////////////////// // // Class: GeoCal // // Filename: GeoCal.cpp // // Description: GeoCal class has member functions to manipulate calculate // all geolocation parameters used in SABER Level1. // // Author: Y.Wang // (757)873-5920 // // ///////////////////////////////////////////////////////////////////////////// #include #include #include #include #include //#include "SCsabertime.h" #include "DVector.h" #include "DMatrix.h" #include "GeoCal.h" #include "General_Dimension_Math_Consts.h" #define SECSperDAY 86400. //seconds per day #define HOURSperDAY 24. #define DEGREESperHOUR 15. // 360/24=15 #define SPEED_OF_LIGHT 299792.458 //km/s //Added by CWBrown for Fukushima Algorithm #define DELTATCONCRIT 1.0e-15 //Convergence Criteria #define MAXITS 20 // Maximum Iterations (should take less than 5) #define CHECKQFUNC(x, a, b, c) (a*x*x*x*x + b*x*x*x + c*x - a >= 0) using namespace std; static const double RADperARCsec= 4.848136811095360e-6 ; /* radiance per arc second*/ //////////////////////////////////////////////////////////////////////// // Class constructor //////////////////////////////////////////////////////////////////////// GeoCal::GeoCal() { } //////////////////////////////////////////////////////////////////////// // Class destructor //////////////////////////////////////////////////////////////////////// GeoCal::~GeoCal() { } ////////////////////////////////////////////////////////////////////////// // Method: cal_SC_los_vector(double scanAng) // Description // Calculate line of sight vector in Spacecraft Coords // Input: // scanAng in radians // Note the following codes work when scan angle is on YZ plane(XZ plane // is the orbit plane) /////////////////////////////////////////////////////////////////////////// DVector GeoCal::cal_SC_los_vector(double scanAng) { //scanAng in radians DVector losSC(3); double rAngle,cosAng,sinAng; //rAngle=RADperDEGREE * scanAng; rAngle = scanAng; losSC[0]= 0.; losSC[1]=cos(rAngle); losSC[2]=sin(rAngle); return losSC; } /////////////////////////////////////////////////////////////////////////// // Method: cal_ORB_los_vector // Description: // Calculate line of sight vector in Orbit Coords // // Inputs: // scanAng- scan angle in radians // roll - in degrees // pitch - in degrees // yaw - in degrees //////////////////////////////////////////////////////////////////////////// DVector GeoCal::cal_ORB_los_vector(double scanAng,double roll,double pitch, double yaw) { DVector losORB(3); double cosR,cosP,cosY,cosS,sinR,sinP,sinY,sinS; double rRoll,rPitch,rYaw,rScan; rRoll = RADperDEGREE * roll; rPitch = RADperDEGREE * pitch; rYaw = RADperDEGREE * yaw; rScan = scanAng; //in radians cosR = cos(rRoll); cosP =cos (rPitch); cosY = cos (rYaw); cosS = cos (rScan); sinR = sin(rRoll); sinP =sin (rPitch); sinY = sin (rYaw); sinS = sin(rScan); //sin scan angle DVector losSC(3); losSC[0] = 0.; losSC[1] = cosS; losSC[2] = sinS; //cout<<"losSC from tran = "< 1.00001) { cerr<<" Input vector is not a unit vector !!!!! Stop!!!\n"; return 1; } DVector tmpECF1(3), tmpECF2(3); DVector vDivc(3); tmpECF1 = matrixORBtoECF * unitposORB ; //double vDivc[3]; //used to correct aberration double tmpnorm; for(int iXYZ=0; iXYZ<3; iXYZ++) { vDivc[iXYZ] = scVelECF[iXYZ]/SPEED_OF_LIGHT; } tmpECF2 =tmpECF1 - vDivc; tmpnorm = sqrt( tmpECF2 * tmpECF2); unitposECF = tmpECF2/ tmpnorm; return 0; } ///////////////////////////////////////////////////////////////////////////// // Method: // Description Calculate local horizontal elevation angle in LVLH coord // Inputs: // scPosECI: spacecraft postion vector in ECI // scanAng: mirror scan angle in radians // roll,pitch,yaw in degrees // Output: elevation angle in radians /////////////////////////////////////////////////////////////////////////// void GeoCal::cal_horizontal_elevation_angle(double scanAng, double roll,double pitch, double yaw, double &elevAngle) { int n=3; DVector losORB(n); losORB = cal_ORB_los_vector(scanAng,roll,pitch,yaw); double losDotlos = losORB *losORB; elevAngle = acos (losORB[1]/sqrt(losDotlos)); return; } ///////////////////////////////////////////////////////////////////////////// // Method: // Description Calculate trans matrix from ORB coords to ECF coords) // Inputs: scVelECF: spacecraft velocity vector in ECF // scPosECF: spacecraft postion vector in ECF // Return: conversion matrix ///////////////////////////////////////////////////////////////////////////// DMatrix GeoCal::matrix_ORBtoECF(DVector &scVelECF, DVector &scPosECF) { // !!!! scPosECF and scVelECF should not be zero. //cout<<"scVelECF from tran = "<= 1) t = p / (zp + c); // Use Lowerbound else if (CHECKQFUNC(tm, p, u, v)) t = p / (zp + c); // Use Lowerbound else t = (p - c + zp) / (p - c + 2*zp); // Use Upperbound deltaT = calDeltaT(t, p, u, v); while(fabs(deltaT) > DELTATCONCRIT && i180) { dlon = 360.0 -rlong ; //counted positive west of greenwich }else { dlon = -rlong; } //cout<<"rlong,dlon="<= 1.e-15) goto Five; he = sqrt(xysq) - re; rlat = 0.; goto twoone; Five: for(i=0; i<24;i++){ zt =z + t; h1 = sqrt(xysq+ zt*zt); sinphi = zt/h1; esqsp =eqs*sinphi; h2=re/sqrt(double(1.)-esqsp*sinphi); //cout<<"zt,sinphi,epsqsp ="<