Changeset 10946 in ntrip
- Timestamp:
- Jun 24, 2026, 4:39:53 PM (12 hours ago)
- Location:
- trunk/BNC
- Files:
-
- 5 edited
-
CHANGELOG.md (modified) (1 diff)
-
src/bncantex.cpp (modified) (3 diffs)
-
src/bncantex.h (modified) (1 diff)
-
src/bnchelp.html (modified) (1 diff)
-
src/combination/bnccomb.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/BNC/CHANGELOG.md
r10945 r10946 4 4 - ADDED: L1C/B (RINEX code: '1E') in QZSS Signal ID Mapping 5 5 - ADDED: Minimum Elevation parameter to BNC's RINEX Editing & QC feature [(#195)](https://software.rtcm-ntrip.org/ticket/195) 6 - ADDED: GLONASS-M yaw-fixed attitude model for the APC/CoM offset applied when saving SP3 files, reducing along-track/cross-track errors near the orbit noon/midnight points 6 7 - FIXED: BNC is now able to work with com ports with higher numbers, e.g. COM11 or COM17 [(#205)](https://software.rtcm-ntrip.org/ticket/205) 7 8 - FIXED: Handling of ionospheric constraints [(#220)](https://software.rtcm-ntrip.org/ticket/220) 9 - FIXED: SP3/Clock RINEX clock values produced by the Upload Corrections feature no longer depend on whether 'Center of Mass' is ticked, since that setting should only affect the uploaded SSR Broadcast Correction stream 8 10 9 11 -
trunk/BNC/src/bncantex.cpp
r10619 r10946 40 40 41 41 #include <iostream> 42 #include <cmath> 42 43 #include <newmatio.h> 43 44 … … 330 331 } 331 332 333 // GLONASS Yaw Angle (Sun-pointing law overridden near noon/midnight when 334 // the satellite cannot mechanically keep up, following the GLONASS-M 335 // "yaw-fixed" behaviour described in Dilssner, Springer, Flohrer, Dow 336 // (2011), "The GLONASS-M satellite yaw-attitude model", Advances in Space 337 // Research 47(1), 160-171. 338 // 339 // Unlike GPS/Galileo/BeiDou, which are commonly approximated by the 340 // nominal Sun-pointing yaw-steering law of Bar-Sever (1996) at all times, 341 // GLONASS-M has been found to stop tracking that law and hold a constant 342 // (frozen) yaw angle whenever the required yaw rate would exceed the 343 // satellite's slew capability - which happens close to the orbit 344 // noon/midnight points whenever the Sun's elevation above the orbital 345 // plane (the "beta" angle) is small. The maximum yaw rate used below 346 // (0.25 deg/s) and the general approach follow that paper; satellite 347 // telemetry was not available to validate the exact rate against this 348 // installation's GLONASS satellites, so it should be checked against 349 // independently-known attitude/orbit residuals if high accuracy matters. 350 //////////////////////////////////////////////////////////////////////////// 351 double bncAntex::glonassYawAngle(const QString& prn, const ColumnVector& xSat, 352 const ColumnVector& vSat, 353 const ColumnVector& xSun) { 354 355 const double MAX_YAW_RATE = 0.25 * M_PI / 180.0; // [rad/s], approximate 356 357 // Inertial-consistent velocity (xSat, vSat are Earth-fixed; remove the 358 // Earth-rotation contribution so that the orbit normal below is not 359 // contaminated by it) 360 // ------------------------------------------------------------------- 361 ColumnVector Omega(3); Omega(1) = 0.0; Omega(2) = 0.0; Omega(3) = t_CST::omega; 362 ColumnVector vInert = vSat + crossproduct(Omega, xSat); 363 364 // Orbit normal and instantaneous orbital rate from r x v (exact, valid 365 // for any Keplerian orbit, not just circular ones) 366 // --------------------------------------------------------------------- 367 ColumnVector h = crossproduct(xSat, vInert); 368 double hNorm = sqrt(DotProduct(h, h)); 369 ColumnVector orbNormal = h / hNorm; 370 double r = sqrt(DotProduct(xSat, xSat)); 371 double nRate = hNorm / (r * r); // [rad/s] 372 373 // Beta angle (Sun elevation above the orbital plane) 374 // ---------------------------------------------------- 375 double beta = asin(DotProduct(orbNormal, xSun)); 376 377 // Orbit angle mu, measured from the orbit midnight point, increasing in 378 // the direction of satellite motion 379 // ----------------------------------------------------------------------- 380 ColumnVector sunProj = xSun - DotProduct(xSun, orbNormal) * orbNormal; 381 sunProj /= sqrt(DotProduct(sunProj, sunProj)); 382 ColumnVector eX = -1.0 * sunProj; // midnight direction, mu = 0 383 ColumnVector eY = crossproduct(orbNormal, eX); 384 ColumnVector rHat = xSat / r; 385 double mu = atan2(DotProduct(rHat, eY), DotProduct(rHat, eX)); 386 387 // Nominal Sun-pointing yaw angle and its rate (Bar-Sever 1996) 388 // ---------------------------------------------------------------- 389 double tanBeta = tan(beta); 390 double sinMu = sin(mu); 391 double psiNom = atan2(-tanBeta, sinMu); 392 double denom = tanBeta * tanBeta + sinMu * sinMu; 393 double psiRate = (denom > 1e-12) 394 ? nRate * fabs(tanBeta * cos(mu)) / denom 395 : 1e9; 396 397 t_glonassYaw& st = _glonassYaw[prn]; 398 double psiEff; 399 if (psiRate > MAX_YAW_RATE) { 400 if (!st.valid) { 401 st.yaw = psiNom; // no prior history - best available estimate 402 } 403 psiEff = st.yaw; // hold the frozen yaw angle 404 } 405 else { 406 st.yaw = psiNom; 407 st.valid = true; 408 psiEff = psiNom; 409 } 410 411 return psiEff; 412 } 413 332 414 // Satellite Antenna Offset 333 415 //////////////////////////////////////////////////////////////////////////// 334 416 t_irc bncAntex::satCoMcorrection(const QString& prn, double Mjd, 335 const ColumnVector& xSat, ColumnVector& dx) { 417 const ColumnVector& xSat, 418 const ColumnVector& vSat, ColumnVector& dx) { 336 419 337 420 t_frequency::type frqType = t_frequency::dummy; … … 374 457 xSun /= sqrt(DotProduct(xSun,xSun)); 375 458 376 ColumnVector sy = crossproduct(sz, xSun); 377 sy /= sqrt(DotProduct(sy,sy)); 378 379 ColumnVector sx = crossproduct(sy, sz); 459 ColumnVector sy, sx; 460 461 // GLONASS: override the nominal Sun-pointing attitude near the 462 // orbit noon/midnight points when the beta angle is small (see 463 // glonassYawAngle() above). Elsewhere GLONASS-M follows the same 464 // nominal law as the other constellations, so the result is 465 // identical to the direct Sun-pointing computation used below. 466 // ----------------------------------------------------------------- 467 if (prn[0] == 'R' && vSat.size() == 3) { 468 double psi = glonassYawAngle(prn, xSat, vSat, xSun); 469 470 ColumnVector vInert = vSat; 471 ColumnVector Omega(3); Omega(1) = 0.0; Omega(2) = 0.0; Omega(3) = t_CST::omega; 472 vInert += crossproduct(Omega, xSat); 473 474 ColumnVector sy0 = crossproduct(sz, vInert); 475 sy0 /= sqrt(DotProduct(sy0,sy0)); 476 ColumnVector sx0 = crossproduct(sy0, sz); 477 478 // Rodrigues rotation of (sx0, sy0) around sz by angle psi 479 double cosY = cos(psi); 480 double sinY = sin(psi); 481 sx = sx0 * cosY + crossproduct(sz, sx0) * sinY; 482 sy = sy0 * cosY + crossproduct(sz, sy0) * sinY; 483 } 484 else { 485 sy = crossproduct(sz, xSun); 486 sy /= sqrt(DotProduct(sy,sy)); 487 sx = crossproduct(sy, sz); 488 } 380 489 381 490 dx[0] = sx[0] * neu[0] + sy[0] * neu[1] + sz[0] * neu[2]; -
trunk/BNC/src/bncantex.h
r10130 r10946 47 47 double eleSat, double azSat, bool& found) const; 48 48 t_irc satCoMcorrection(const QString& prn, double Mjd, 49 const ColumnVector& xSat, ColumnVector& dx); 49 const ColumnVector& xSat, const ColumnVector& vSat, 50 ColumnVector& dx); 50 51 51 52 private: 53 // Per-satellite GLONASS yaw state, used to freeze the yaw angle while 54 // the satellite cannot follow the nominal Sun-pointing attitude law 55 // (see glonassYawAngle() below). 56 class t_glonassYaw { 57 public: 58 t_glonassYaw() { 59 yaw = 0.0; 60 valid = false; 61 } 62 double yaw; 63 bool valid; 64 }; 65 66 double glonassYawAngle(const QString& prn, const ColumnVector& xSat, 67 const ColumnVector& vSat, const ColumnVector& xSun); 68 69 QMap<QString, t_glonassYaw> _glonassYaw; 70 52 71 class t_frqMap { 53 72 public: -
trunk/BNC/src/bnchelp.html
r10945 r10946 5640 5640 </p> 5641 5641 <p> 5642 For GLONASS satellites, that APC/CoM offset is rotated into the satellite-fixed frame using the satellite's 5643 yaw attitude. BNC assumes the nominal Sun-pointing yaw-steering law used for the other GNSS systems, except 5644 close to the orbit noon and midnight points when the Sun's elevation above the orbital plane (the 'beta' 5645 angle) is small. There, GLONASS-M satellites are known to stop tracking that law and instead hold the yaw 5646 angle fixed, following the model described in Dilssner, Springer, Flohrer, Dow (2011), 'The GLONASS-M 5647 satellite yaw-attitude model', Advances in Space Research 47(1), 160-171. Without that correction, the 5648 converted GLONASS CoM position can be off by several decimeters in the along-track and cross-track 5649 components in that situation. The maximum yaw rate used to decide when GLONASS-M can no longer follow the 5650 nominal law (0.25 deg/s) is taken from the literature and not calibrated against any specific satellite, so 5651 results should be checked against independently known attitude or orbit information where high accuracy on 5652 GLONASS is required. 5653 </p> 5654 <p> 5642 5655 Note that clocks in the SP3 orbit files are not corrected for the conventional periodic relativistic effect. 5643 5656 </p> -
trunk/BNC/src/combination/bnccomb.cpp
r10890 r10946 1205 1205 char sys = corr->_eph->prn().system(); 1206 1206 masterIsAPC = _masterIsAPC[sys]; 1207 if (_antex->satCoMcorrection(corr->_prn, Mjd, xc.Rows(1,3), dx) != success) { 1207 if (_antex->satCoMcorrection(corr->_prn, Mjd, xc.Rows(1,3), vv, dx) != success) { 1208 1208 dx = 0; 1209 1209 _log += "antenna not found " + corr->_prn.mid(0,3).toLatin1() + '\n';
Note:
See TracChangeset
for help on using the changeset viewer.
