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 /** 40 * @file SEMData.cpp 41 * Encapsulate SEM almanac file data, including I/O 42 */ 43 44 #include "StringUtils.hpp" 45 #include "GNSSconstants.hpp" 46 47 #include "SEMData.hpp" 48 #include "SEMStream.hpp" 49 50 51 using namespace gpstk::StringUtils; 52 using namespace std; 53 54 namespace gpstk 55 { SEMData()56 SEMData::SEMData() 57 : ecc(0, FFLead::Zero, 15, 4, 0, 'E', FFSign::NegSpace), 58 i_offset(0, FFLead::Zero, 15, 4, 0, 'E', FFSign::NegSpace), 59 OMEGAdot(0, FFLead::Zero, 15, 4, 0, 'E', FFSign::NegSpace), 60 Ahalf(0, FFLead::Zero, 15, 4, 0, 'E', FFSign::NegSpace), 61 OMEGA0(0, FFLead::Zero, 15, 4, 0, 'E', FFSign::NegSpace), 62 w(0, FFLead::Zero, 15, 4, 0, 'E', FFSign::NegSpace), 63 M0(0, FFLead::Zero, 15, 4, 0, 'E', FFSign::NegSpace), 64 AF0(0, FFLead::Zero, 15, 4, 0, 'E', FFSign::NegSpace), 65 AF1(0, FFLead::Zero, 15, 4, 0, 'E', FFSign::NegSpace) 66 { 67 } 68 69 reallyPutRecord(FFStream & ffs) const70 void SEMData::reallyPutRecord(FFStream& ffs) const 71 { 72 string line; 73 74 SEMStream& strm = dynamic_cast<SEMStream&>(ffs); 75 76 //First output blank line to mark between records 77 strm << std::endl; 78 79 //PRN output 80 strm << asString<short>(PRN) << endl; 81 82 //SVNnum 83 strm << asString<short>(SVNnum) << endl; 84 85 //URAnum 86 strm << asString<short>(URAnum) << endl; 87 88 //Ecc, i_offset, OMEGAdot 89 strm << ecc << " " << (i_offset / gpstk::PI) << " " 90 << (OMEGAdot / gpstk::PI) << endl; 91 92 //Ahalf, OMEGA0, w 93 strm << Ahalf << " " << (OMEGA0/gpstk::PI) << " " << (w/gpstk::PI) 94 << endl; 95 96 //M0, AF0, AF1 97 strm << (M0/gpstk::PI) << " " << AF0 << " " << AF1 << endl; 98 99 //SV_health 100 strm << asString<short>(SV_health) << endl; 101 102 //satConfig 103 strm << asString<short>(satConfig) << endl; 104 105 106 } // end SEMData::reallyPutRecord 107 108 reallyGetRecord(FFStream & ffs)109 void SEMData::reallyGetRecord(FFStream& ffs) 110 { 111 string line; 112 113 SEMStream& strm = dynamic_cast<SEMStream&>(ffs); 114 115 //if(!strm.headerRead) 116 // strm >> strm.header; 117 118 SEMHeader& hdr = strm.header; 119 120 //Don't need first line - empty space 121 strm.formattedGetLine(line, true); 122 123 // Second line - PRN 124 strm.formattedGetLine(line, true); 125 PRN = asInt(line); 126 127 // Third line - SVN Number 128 // HACKHACKHACK This information might not be here??? Find out more info 129 strm.formattedGetLine(line, true); 130 SVNnum = (short) asInt(line); 131 132 // Fourth line - Average URA Number as defined in ICD-GPS-200 133 strm.formattedGetLine(line, true); 134 URAnum = (short) asInt(line); 135 136 string whitespace = " \t\r\n"; 137 138 // Fifth line - Eccentricity, Inclination Offset, and Rate of Right Ascension 139 strm.formattedGetLine(line, true); 140 string::size_type front = line.find_first_not_of(whitespace); 141 string::size_type end = line.find_first_of(whitespace,front); 142 string::size_type length = end - front; 143 ecc = line.substr(front,length); 144 145 front = line.find_first_not_of(whitespace,end); 146 end = line.find_first_of(whitespace,front); 147 length = end - front; 148 i_offset = line.substr(front,length); 149 i_total = i_offset + 54.0 * (gpstk::PI / 180.0); 150 151 front = line.find_first_not_of(whitespace,end); 152 length = line.length() - front; 153 OMEGAdot = line.substr(front,length); 154 i_offset *= gpstk::PI; 155 OMEGAdot *= gpstk::PI; 156 157 // Sixth line - Sqrt of A, Omega0, and Arg of Perigee 158 strm.formattedGetLine(line, true); 159 160 front = line.find_first_not_of(whitespace); 161 end = line.find_first_of(whitespace,front); 162 length = end - front; 163 Ahalf = line.substr(front,length); 164 165 front = line.find_first_not_of(whitespace,end); 166 end = line.find_first_of(whitespace,front); 167 length = end - front; 168 OMEGA0 = line.substr(front,length); 169 170 front = line.find_first_not_of(whitespace,end); 171 length = line.length() - front; 172 OMEGA0 *= gpstk::PI; 173 w = line.substr(front,length); 174 w *= gpstk::PI; 175 176 // Seventh Line - M0, AF0, AF1 177 strm.formattedGetLine(line, true); 178 179 front = line.find_first_not_of(whitespace); 180 end = line.find_first_of(whitespace,front); 181 length = end - front; 182 M0 = line.substr(front,length); 183 M0 *= gpstk::PI; 184 185 front = line.find_first_not_of(whitespace,end); 186 end = line.find_first_of(whitespace,front); 187 length = end - front; 188 AF0 = line.substr(front,length); 189 190 front = line.find_first_not_of(whitespace,end); 191 length = line.length() - front; 192 AF1 = line.substr(front,length); 193 194 // Eigth line - Satellite Health 195 strm.formattedGetLine(line, true); 196 SV_health = (short) asInt(line); 197 198 // Ninth line - Satellite Config 199 strm.formattedGetLine(line, true); 200 satConfig = (short) asInt(line); 201 202 week = hdr.week; 203 Toa = hdr.Toa; 204 205 xmit_time = 0; 206 207 } // end of reallyGetRecord() 208 dump(ostream & s) const209 void SEMData::dump(ostream& s) const 210 { 211 s << "PRN = " << PRN << std::endl; 212 s << "SVNnum = " << SVNnum << std::endl; 213 s << "URAnum = " << URAnum << std::endl; 214 s << "ecc = " << ecc << std::endl; 215 s << "i_offset = " << i_offset << std::endl; 216 s << "OMEGAdot = " << OMEGAdot << std::endl; 217 s << "Ahalf = " << Ahalf << std::endl; 218 s << "OMEGA0 = " << OMEGA0 << std::endl; 219 s << "w = " << w << std::endl; 220 s << "M0 = " << M0 << std::endl; 221 s << "AF0 = " << AF0 << std::endl; 222 s << "AF1 = " << AF1 << std::endl; 223 s << "SV_health = " << SV_health << std::endl; 224 s << "satConfig = " << satConfig << std::endl; 225 s << "xmit_time = " << xmit_time << std::endl; 226 s << "week = " << week << std::endl; 227 s << "toa = " << Toa << std::endl; 228 } 229 operator AlmOrbit() const230 SEMData::operator AlmOrbit() const 231 { 232 233 AlmOrbit ao(PRN, ecc,i_offset, OMEGAdot, Ahalf, OMEGA0, 234 w, M0, AF0, AF1, Toa, xmit_time, week, SV_health); 235 236 return ao; 237 } 238 operator OrbAlmGen() const239 SEMData::operator OrbAlmGen() const 240 { 241 OrbAlmGen oag; 242 243 oag.AHalf = Ahalf; 244 oag.A = Ahalf * Ahalf; 245 oag.af1 = AF1; 246 oag.af0 = AF0; 247 oag.OMEGA0 = OMEGA0; 248 oag.ecc = ecc; 249 oag.deltai = i_offset; 250 oag.i0 = i_total; 251 oag.OMEGAdot = OMEGAdot; 252 oag.w = w; 253 oag.M0 = M0; 254 oag.toa = Toa; 255 oag.health = SV_health; 256 257 // At this writing Yuma almanacs only exist for GPS 258 oag.subjectSV = SatID(PRN, SatelliteSystem::GPS); 259 260 // Unfortunately, we've NO IDEA which SV transmitted 261 // these data. 262 oag.satID = SatID(0,SatelliteSystem::GPS); 263 264 // 265 oag.ctToe = GPSWeekSecond(week,Toa,TimeSystem::GPS); 266 267 // There is no transmit time in the SEM alamanc format. 268 // Therefore, beginValid and endvalid are estimated. The 269 // estimate is based on IS-GPS-200 Table 20-XIII. 270 oag.beginValid = oag.ctToe - (70 * 3600.0); 271 oag.endValid = oag.beginValid + (144 * 3600.0); 272 273 oag.dataLoadedFlag = true; 274 oag.setHealthy(false); 275 if (oag.health==0) 276 oag.setHealthy(true); 277 278 // It is assumed that the data were broadcast on 279 // each of L1 C/A, L1 P(Y), and L2 P(Y). We'll 280 // load obsID with L1 C/A for the sake of completeness, 281 // but this will probably never be examined. 282 oag.obsID = ObsID(ObservationType::NavMsg,CarrierBand::L1,TrackingCode::CA); 283 284 return oag; 285 } 286 287 288 } // namespace 289