1 //============================================================================== 2 // 3 // This file is part of GPSTk, the GPS Toolkit. 4 // 5 // The GPSTk is free software; you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published 7 // by the Free Software Foundation; either version 3.0 of the License, or 8 // any later version. 9 // 10 // The GPSTk is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public 16 // License along with GPSTk; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 18 // 19 // This software was developed by Applied Research Laboratories at the 20 // University of Texas at Austin. 21 // Copyright 2004-2020, The Board of Regents of The University of Texas System 22 // 23 //============================================================================== 24 25 //============================================================================== 26 // 27 // This software was developed by Applied Research Laboratories at the 28 // University of Texas at Austin, under contract to an agency or agencies 29 // within the U.S. Department of Defense. The U.S. Government retains all 30 // rights to use, duplicate, distribute, disclose, or release this software. 31 // 32 // Pursuant to DoD Directive 523024 33 // 34 // DISTRIBUTION STATEMENT A: This software has been approved for public 35 // release, distribution is unlimited. 36 // 37 //============================================================================== 38 39 /// @file GalEphemeris.cpp Encapsulates the GPS legacy broadcast ephemeris and clock. 40 /// Inherits OrbitEph, which does most of the work; this class adds health and 41 /// accuracy information, fit interval, ionospheric correction terms and data 42 /// flags. 43 44 #include <string> 45 #include "Exception.hpp" 46 #include "TimeString.hpp" 47 #include "CivilTime.hpp" 48 #include "GALWeekSecond.hpp" 49 50 #include "GalEphemeris.hpp" 51 52 using namespace std; 53 54 namespace gpstk 55 { 56 // Returns true if the time, ct, is within the period of validity of 57 // this OrbitEph object. 58 // @throw Invalid Request if the required data has not been stored. isValid(const CommonTime & ct) const59 bool GalEphemeris::isValid(const CommonTime& ct) const 60 { 61 try { 62 if(ct >= beginValid && ct <= endValid) return true; 63 return false; 64 } 65 catch(Exception& e) { GPSTK_RETHROW(e); } 66 } 67 68 // This function returns the health status of the SV. isHealthy(void) const69 bool GalEphemeris::isHealthy(void) const 70 { 71 if (health==Xvt::Healthy) 72 return true; 73 return false; 74 } 75 76 // adjustBeginningValidity determines the beginValid and endValid times. 77 // @throw Invalid Request if the required data has not been stored. 78 // 79 // NOTE: The Galileo ICD does not make the same sort of promises about 80 // the relationship of t-sub-oe and beginning time of transmission as 81 // GPS. Therefore, we should NOT adjust the beginValid time to be 82 // anything other than the earliest tranmit time we recorded. 83 // 84 // The end of validity presents a problem also. There is no guidance in 85 // the ICD. The only guidance in the SDD is "do not use beyond four hours 86 // from initial time of transmission". We don't KNOW that the transmission 87 // time we have in hand is the earliest transmission. Typically, the toe is 88 // about ten minutes prior to the first time of transmission. Therefore, 89 // we will go with that. 90 // adjustValidity(void)91 void GalEphemeris::adjustValidity(void) 92 { 93 try { 94 OrbitEph::adjustValidity(); // for dataLoaded check 95 beginValid = transmitTime; 96 endValid = ctToe + (3600*4); // Four hours 97 } 98 catch(Exception& e) { GPSTK_RETHROW(e); } 99 } 100 101 // Dump the orbit, etc information to the given output stream. 102 // @throw Invalid Request if the required data has not been stored. dumpBody(std::ostream & os) const103 void GalEphemeris::dumpBody(std::ostream& os) const 104 { 105 try { 106 OrbitEph::dumpBody(os); 107 108 os << " Galileo-SPECIFIC PARAMETERS\n" 109 << scientific << setprecision(8) 110 << "Tgd (E5a/E1) : " << setw(16) << Tgda << " meters" << endl 111 << "Tgd (E5b/E1) : " << setw(16) << Tgdb << " meters" << endl 112 << "HOW time : " << setw(6) << HOWtime << " (sec of GAL week " 113 << setw(4) << static_cast<GALWeekSecond>(ctToe).getWeek() << ")" << endl 114 << "TransmitTime : " << OrbitEph::timeDisplay(transmitTime) << endl 115 << "IODNav: " << IODnav << fixed << setprecision(2) 116 << " Accuracy : " << getAccuracy() << " meters" 117 << " fitDuration: " << setw(2) << fitDuration << " hours" << endl 118 << "Healthy? : 0x" << hex << setw(2) << health << dec << " :" 119 << " [E1b_D " << ((health & 0x1) ? "N":"Y") << "]" 120 << " [E1b_H " << ((health & 0x2) ? "N":"Y") << "]" 121 << " [E5a_D " << ((health & 0x4) ? "N":"Y") << "]" 122 << " [E5a_H " << ((health & 0x18) ? "N":"Y") << "]" 123 << " [E5b_D " << ((health & 0x20) ? "N":"Y") << "]" 124 << " [E5b_H " << ((health & 0xC0) ? "N":"Y") << "]" 125 << endl 126 << "Datasources : " << setw(3) << datasources << " :" 127 << ((datasources & 0x1) ? " [I/NAV E1-B]" : "") 128 << ((datasources & 0x2) ? " [F/NAV E5a-I]" : "") 129 << ((datasources & 0x4) ? " [I/NAV E5b-I]" : "") 130 << ((datasources & 0x8) ? " [bit 3 reserved]" : "") 131 << ((datasources & 0x10) ? " [bit 4 reserved]" : "") 132 << ((datasources & 0x100) ? " [set clk/Toc/acc for E5a,E1]" : "") 133 << ((datasources & 0x200) ? " [set clk/Toc/acc for E5b,E1]" : "") 134 << endl; 135 } 136 catch(Exception& e) { GPSTK_RETHROW(e); } 137 } 138 139 // Dump the overhead information as a string containing a single line. 140 // @throw Invalid Request if the required data has not been stored. asString(void) const141 string GalEphemeris::asString(void) const 142 { 143 if(!dataLoadedFlag) 144 GPSTK_THROW(InvalidRequest("Data not loaded")); 145 try { 146 ostringstream os; 147 CivilTime ct; 148 os << "EPH E" << setfill('0') << setw(2) << satID.id << setfill(' '); 149 ct = CivilTime(beginValid); 150 os << printTime(ct," | %4Y %3j %02H:%02M:%02S |"); 151 ct = CivilTime(ctToe); 152 os << printTime(ct," %3j %02H:%02M:%02S |"); 153 ct = CivilTime(ctToc); 154 os << printTime(ct," %3j %02H:%02M:%02S |"); 155 ct = CivilTime(endValid); 156 os << printTime(ct," %3j %02H:%02M:%02S |"); 157 ct = CivilTime(transmitTime); 158 os << printTime(ct," %3j %02H:%02M:%02S | "); 159 os << setw(3) << IODnav; 160 //<< " | " << fixed << setprecision(2) << getAccuracy() 161 os << " | 0x" << hex << setw(3) <<setfill('0')<< health <<dec<<setfill(' '); 162 os << " | " 163 << ((datasources & 0x5) ? "E15b" : "") // 1 or 4 164 << ((datasources & 0x2) ? "E5a " : "") 165 //<< ((datasources & 0x4) ? "E5b " : "") 166 << ((datasources & 0x100) ? " a1" : "") 167 << ((datasources & 0x200) ? " b1" : "") 168 << " |"; 169 return os.str(); 170 } 171 catch(Exception& e) { GPSTK_RETHROW(e); 172 } 173 } 174 deriveHealth(const unsigned short SHS,const unsigned short DVS,const unsigned short SISA)175 Xvt::HealthStatus GalEphemeris::deriveHealth(const unsigned short SHS, 176 const unsigned short DVS, 177 const unsigned short SISA ) 178 { 179 if (SHS==1 || SHS==3) 180 return Xvt::Unhealthy; 181 182 if (SHS==2) 183 return Xvt::Degraded; 184 185 if (SHS==0) 186 { 187 if (DVS==1) 188 return Xvt::Degraded; 189 190 if (DVS==0) 191 { 192 if (SISA==255) 193 return Xvt::Degraded; 194 if (SISA<255) 195 return Xvt::Healthy; 196 } 197 } 198 return Xvt::Unknown; 199 } 200 201 } // end namespace 202