AshtechMBEN.cpp
Go to the documentation of this file.
1 //==============================================================================
2 //
3 // This file is part of GNSSTk, the ARL:UT GNSS Toolkit.
4 //
5 // The GNSSTk 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 GNSSTk 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 GNSSTk; 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-2022, 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 #include "AshtechMBEN.hpp"
40 #include "AshtechStream.hpp"
41 #include "GNSSconstants.hpp"
42 
43 using namespace std;
44 
45 namespace gnsstk
46  {
47  const char* AshtechMBEN::mpcId = "MPC";
48  const char* AshtechMBEN::mcaId = "MCA";
49 
50 
51  //---------------------------------------------------------------------------
52  void AshtechMBEN::reallyGetRecord(FFStream& ffs)
53  {
54  AshtechStream& stream=dynamic_cast<AshtechStream&>(ffs);
55 
56  // make sure the object is reset before starting the search
57  clear(fmtbit | lenbit | crcbit);
58  string& rawData = stream.rawData;
59 
60  // If this object doesn't have an id set yet, assume that the streams
61  // most recent read id is what we need to be
62  if (id == "" && rawData.size()>=11 &&
63  rawData.substr(0,7) == preamble &&
64  rawData[10]==',')
65  id = rawData.substr(7,3);
66 
67  // If that didn't work, or this is object is not of the right type,
68  // then give up.
69  if (id == "" || !checkId(id))
70  return;
71 
72  readBody(stream);
73  }
74 
75 
76  //---------------------------------------------------------------------------
77  void AshtechMBEN::decode(const std::string& data)
78  {
80 
81  string str(data);
82 
83  uint8_t csum=0;
84  if (str.length() == 108 || str.length()==52)
85  {
86  ascii=false;
87  header = str.substr(0,11); str.erase(0,11);
88 
89  seq = decodeVar<uint16_t>(str);
90  left = decodeVar<uint8_t>(str);
91  svprn = decodeVar<uint8_t>(str);
92  el = decodeVar<uint8_t>(str);
93  az = decodeVar<uint8_t>(str);
94  chid = decodeVar<uint8_t>(str);
95 
96  ca.decodeBIN(str);
97 
98  if (id == mpcId)
99  {
100  p1.decodeBIN(str);
101  p2.decodeBIN(str);
102  }
103 
104  checksum = decodeVar<uint8_t>(str);
105 
106  clear();
107 
108  int end = data.size() - 3;
109  for (int i=11; i<end; i++)
110  csum ^= data[i];
111  }
112  else
113  {
114  ascii=true;
115  header = str.substr(0,11); str.erase(0,11);
116  stringstream iss(str);
117  char c;
118  iss >> seq >> c
119  >> left >> c
120  >> svprn >> c
121  >> el >> c
122  >> az >> c
123  >> chid >> c;
124 
125  ca.decodeASCII(iss);
126 
127  if (id == mpcId)
128  {
129  p1.decodeASCII(iss);
130  p2.decodeASCII(iss);
131  }
132 
133  iss >> checksum;
134 
135  if (iss)
136  clear();
137 
138  int end=data.rfind(',');
139  for (int i=11; i<=end; i++)
140  csum ^= data[i];
141  }
142 
143 
144  if (csum != checksum)
145  {
146  setstate(crcbit);
147  if (debugLevel)
148  cout << "checksum error, computed:" << hex << (uint16_t) csum
149  << " received:" << checksum << dec << endl;
150  }
151 
152  if (seq>36000)
153  setstate(fmtbit);
154  }
155 
156 
157  //---------------------------------------------------------------------------
158  void AshtechMBEN::code_block::decodeASCII(stringstream& str)
159  {
160  char c;
161  str >> warning >> c
162  >> goodbad >> c
163  >> polarity_known>> c
164  >> ireg >> c
165  >> qa_phase >> c
166  >> full_phase >> c
167  >> raw_range >> c
168  >> doppler >> c
169  >> smoothing >> c
170  >> smooth_cnt >> c;
171 
172  // The ashtech docs say this field should be in 1e-4 Hz
173  // The data sure doesn't look like it, however
174  //doppler *= 1e-4;
175  raw_range *= 1e-3; //convert ms to sec
176  }
177 
178 
179  //---------------------------------------------------------------------------
180  void AshtechMBEN::code_block::decodeBIN(string& str)
181  {
183  uint32_t smo;
184  warning = decodeVar<uint8_t>(str);
185  goodbad = decodeVar<uint8_t>(str);
186  polarity_known = decodeVar<uint8_t>(str);
187  ireg = decodeVar<uint8_t>(str);
188  qa_phase = decodeVar<uint8_t>(str);
189  full_phase = decodeVar<double>(str);
190  raw_range = decodeVar<double>(str);
191  doppler = decodeVar<int32_t>(str);
192  smo = decodeVar<uint32_t>(str);
193 
194  doppler *= 1e-4;
195  smoothing = (smo & 0x800000 ? -1e-3 : 1e-3) * (smo & 0x7fffff);
196  smooth_cnt = (smo >> 24) & 0xff;
197  }
198 
199 
200  //---------------------------------------------------------------------------
201  void AshtechMBEN::code_block::dump(ostream& out) const
202  {
204  out << hex
205  << "warn:" << (int)warning
206  << " gb:" << (int)goodbad
207  << " pol:" << (int)polarity_known
208  << dec
209  << " ireg:" << (int)ireg
210  << " qa:" << (int)qa_phase
211  << " phase:" << asString(full_phase, 1)
212  << " range:" << asString(raw_range*1e3, 3)
213  << " doppler:" << doppler
214  << " smo:" << smoothing
215  << " smo_cnt:" << smooth_cnt;
216  }
217 
218 
219  //---------------------------------------------------------------------------
220  float AshtechMBEN::code_block::snr(float chipRate, float m) const noexcept
221  {
222  const float n = 20000; // number of samples in 1 ms
223  const float bw = 0.9 * chipRate; // equivalent noise bandwidth (Hz)
224 
225  const float d = PI/(n*n*m*m*4.0);
226  float snr=0;
227  // Note that ireg is as output from the MBEN which is 0-255, not the 0-99
228  // as displayed on the front panel.
229  if (ireg)
230  {
231  snr = exp(((float)ireg)/25.0);
232  snr = snr*snr*bw*d;
233  snr = 10 * log10(snr);
234  }
235 
236  return snr;
237  }
238 
239  //---------------------------------------------------------------------------
240  void AshtechMBEN::dump(ostream& out) const noexcept
241  {
242  ostringstream oss;
244 
245  AshtechData::dump(oss);
246  oss << getName() << "1:"
247  << " seq:" << 0.05 * seq
248  << " left:" << (int)left
249  << " prn:" << (int)svprn
250  << " el:" << (int)el
251  << " az:" << (int)az
252  << " chid:" << (int)chid
253  << " " << (ascii?"ascii":"bin")
254  << endl;
255 
256  oss << getName() << "2: ca ";
257  ca.dump(oss);
258  oss << endl;
259 
260  if (id == mpcId)
261  {
262  oss << getName() << "3: p1 ";
263  p1.dump(oss);
264  oss << endl;
265  oss << getName() << "4: p2 ";
266  p2.dump(oss);
267  oss << endl;
268  }
269  out << oss.str() << flush;
270  }
271 } // namespace gnsstk
gnsstk::dump
void dump(vector< SatPass > &SatPassList, ostream &os, bool rev, bool dbug)
Definition: SatPassUtilities.cpp:59
example3.header
header
Definition: example3.py:22
gnsstk::lenbit
static const std::ios_base::iostate lenbit
Definition: DataStatus.hpp:88
gnsstk::FFStream
Definition: FFStream.hpp:119
AshtechMBEN.hpp
gnsstk::crcbit
static const std::ios_base::iostate crcbit
Define additional/other bits are the data requires.
Definition: DataStatus.hpp:86
gnsstk::StringUtils::asString
std::string asString(IonexStoreStrategy e)
Convert a IonexStoreStrategy to a whitespace-free string name.
Definition: IonexStoreStrategy.cpp:46
gnsstk::fmtbit
static const std::ios_base::iostate fmtbit
Definition: DataStatus.hpp:87
gnsstk::PI
const double PI
GPS value of PI; also specified by GAL.
Definition: GNSSconstants.hpp:62
AshtechStream.hpp
GNSSconstants.hpp
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::AshtechStream
Definition: AshtechStream.hpp:54
example3.data
data
Definition: example3.py:22
std
Definition: Angle.hpp:142
gnsstk::AshtechStream::rawData
std::string rawData
The raw bytes read from the file.
Definition: AshtechStream.hpp:78
gnsstk::BinUtils::decodeVar
T decodeVar(const std::string &str, std::string::size_type pos)
Definition: BinUtils.hpp:366


gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:38