1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-11-19 00:04:58 +00:00

Fix building in MacOS, code refactoring, position test integration

Bugs from previous commits have been fixed. Working in macOS and Linux. This commit includes a pull from next
This commit is contained in:
Carles Fernandez 2017-04-23 02:03:43 +02:00
commit 57a17ac5d5
48 changed files with 8223 additions and 6454 deletions

View File

@ -271,6 +271,14 @@ set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
# Append -O2 optimization flag for Debug builds # Append -O2 optimization flag for Debug builds
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O2") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O2")
# allow 'large' files in 32 bit builds
if(UNIX)
add_definitions( -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64
-D_LARGE_FILES
)
endif(UNIX)
################################################################################ ################################################################################
@ -331,7 +339,6 @@ if(OS_IS_LINUX)
endif(OS_IS_LINUX) endif(OS_IS_LINUX)
################################################################################ ################################################################################
# Googletest - https://github.com/google/googletest # Googletest - https://github.com/google/googletest
################################################################################ ################################################################################
@ -520,11 +527,11 @@ if(NOT VOLK_GNSSSDR_FOUND)
-DCMAKE_CXX_FLAGS=${CXX_FLAGS} -DCMAKE_CXX_FLAGS=${CXX_FLAGS}
-DCMAKE_C_FLAGS=${C_FLAGS} -DCMAKE_C_FLAGS=${C_FLAGS}
-DCMAKE_INCLUDE_PATH=${Boost_INCLUDE_DIR} -DCMAKE_INCLUDE_PATH=${Boost_INCLUDE_DIR}
-DENABLE_ORC=OFF
${STRIP_VOLK_GNSSSDR_PROFILE} ${STRIP_VOLK_GNSSSDR_PROFILE}
${USE_THIS_PYTHON} ) ${USE_THIS_PYTHON} )
if(EXISTS $ENV{OECORE_TARGET_SYSROOT}) if(EXISTS $ENV{OECORE_TARGET_SYSROOT})
set(VOLK_GNSSSDR_CMAKE_ARGS ${VOLK_GNSSSDR_CMAKE_ARGS} set(VOLK_GNSSSDR_CMAKE_ARGS ${VOLK_GNSSSDR_CMAKE_ARGS}
-DENABLE_ORC=OFF
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/Toolchains/oe-sdk_cross.cmake -DCMAKE_TOOLCHAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/Toolchains/oe-sdk_cross.cmake
-DCROSSCOMPILE_MULTILIB=TRUE ) -DCROSSCOMPILE_MULTILIB=TRUE )
endif(EXISTS $ENV{OECORE_TARGET_SYSROOT}) endif(EXISTS $ENV{OECORE_TARGET_SYSROOT})
@ -884,26 +891,17 @@ if(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO)
message(STATUS " Armadillo has not been found.") message(STATUS " Armadillo has not been found.")
message(STATUS " Armadillo will be downloaded and built automatically") message(STATUS " Armadillo will be downloaded and built automatically")
message(STATUS " when doing 'make'. ") message(STATUS " when doing 'make'. ")
set(armadillo_BRANCH 7.800.x)
if(CMAKE_VERSION VERSION_LESS 3.1) set(armadillo_RELEASE ${armadillo_BRANCH})
# ExternalProject in CMake > 3.1 cannot open .xz files
set(armadillo_RELEASE 6.700.7)
set(armadillo_MD5 "8116185e1d7391eed3bf6c500f81b4d8")
set(ARMA_FILE_EXTENSION "gz")
else(CMAKE_VERSION VERSION_LESS 3.1)
set(armadillo_RELEASE 7.800.1)
set(armadillo_MD5 "e094351771c40a6e06e1a9c1ffdfc2b8")
set(ARMA_FILE_EXTENSION "xz")
endif(CMAKE_VERSION VERSION_LESS 3.1)
ExternalProject_Add( ExternalProject_Add(
armadillo-${armadillo_RELEASE} armadillo-${armadillo_RELEASE}
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE} PREFIX ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}
URL http://sourceforge.net/projects/arma/files/armadillo-${armadillo_RELEASE}.tar.${ARMA_FILE_EXTENSION} GIT_REPOSITORY https://github.com/conradsnicta/armadillo-code.git
DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}/download/armadillo-${armadillo_RELEASE} GIT_TAG ${armadillo_BRANCH}
URL_MD5 ${armadillo_MD5} SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/armadillo/armadillo-${armadillo_RELEASE}
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DBUILD_SHARED_LIBS=OFF BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}
BUILD_IN_SOURCE 1 CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DBUILD_SHARED_LIBS=OFF -DCMAKE_CXX_FLAGS=-std=c++11
BUILD_COMMAND make BUILD_COMMAND make
UPDATE_COMMAND "" UPDATE_COMMAND ""
INSTALL_COMMAND "" INSTALL_COMMAND ""
@ -911,7 +909,7 @@ if(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO)
# Set up variables # Set up variables
ExternalProject_Get_Property(armadillo-${armadillo_RELEASE} binary_dir) ExternalProject_Get_Property(armadillo-${armadillo_RELEASE} binary_dir)
set(ARMADILLO_INCLUDE_DIRS ${binary_dir}/include ) set(ARMADILLO_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/armadillo/armadillo-${armadillo_RELEASE}/include )
find_library(LAPACK NAMES lapack HINTS /usr/lib /usr/local/lib /usr/lib64) find_library(LAPACK NAMES lapack HINTS /usr/lib /usr/local/lib /usr/lib64)
if(OS_IS_MACOSX) if(OS_IS_MACOSX)
find_library(BLAS blas) find_library(BLAS blas)
@ -925,10 +923,6 @@ if(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO)
endif(NOT GFORTRAN) endif(NOT GFORTRAN)
set(ARMADILLO_LIBRARIES ${BLAS} ${LAPACK} ${GFORTRAN} ${binary_dir}/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo.a) set(ARMADILLO_LIBRARIES ${BLAS} ${LAPACK} ${GFORTRAN} ${binary_dir}/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo.a)
set(LOCAL_ARMADILLO true CACHE STRING "Armadillo downloaded and built automatically" FORCE) set(LOCAL_ARMADILLO true CACHE STRING "Armadillo downloaded and built automatically" FORCE)
# Save a copy at the thirdparty folder
file(COPY ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}
DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/armadillo
)
set(ARMADILLO_VERSION_STRING ${armadillo_RELEASE}) set(ARMADILLO_VERSION_STRING ${armadillo_RELEASE})
else(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO) else(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO)
set(armadillo_RELEASE ${ARMADILLO_VERSION_STRING}) set(armadillo_RELEASE ${ARMADILLO_VERSION_STRING})
@ -1180,8 +1174,17 @@ if($ENV{RTLSDR_DRIVER})
endif($ENV{RTLSDR_DRIVER}) endif($ENV{RTLSDR_DRIVER})
if(ENABLE_OSMOSDR) if(ENABLE_OSMOSDR)
find_package(GrOsmoSDR)
if(GROSMOSDR_FOUND)
message(STATUS "The driver for OsmoSDR and other front-ends (HackRF, bladeRF, Realtek's RTL2832U-based dongles, etc.) will be compiled." ) message(STATUS "The driver for OsmoSDR and other front-ends (HackRF, bladeRF, Realtek's RTL2832U-based dongles, etc.) will be compiled." )
message(STATUS "You can disable it with 'cmake -DENABLE_OSMOSDR=OFF ../'" ) message(STATUS "You can disable it with 'cmake -DENABLE_OSMOSDR=OFF ../'" )
else(GROSMOSDR_FOUND)
if(ENABLE_PACKAGING)
message(WARNING "gr-osmosdr has not been found. Source blocks depending on it will NOT be built.")
else(ENABLE_PACKAGING)
message(FATAL_ERROR "gr-osmosdr required to build gnss-sdr with the optional OSMOSDR driver")
endif(ENABLE_PACKAGING)
endif(GROSMOSDR_FOUND)
else(ENABLE_OSMOSDR) else(ENABLE_OSMOSDR)
message(STATUS "The (optional) driver for OsmoSDR and related front-ends is not enabled." ) message(STATUS "The (optional) driver for OsmoSDR and related front-ends is not enabled." )
message(STATUS "Enable it with 'cmake -DENABLE_OSMOSDR=ON ../' to add support for OsmoSDR and other front-ends (HackRF, bladeRF, Realtek's RTL2832U-based USB dongles, etc.)" ) message(STATUS "Enable it with 'cmake -DENABLE_OSMOSDR=ON ../' to add support for OsmoSDR and other front-ends (HackRF, bladeRF, Realtek's RTL2832U-based USB dongles, etc.)" )
@ -1314,4 +1317,3 @@ add_custom_target(uninstall
# Add subdirectories (in order of deps) # Add subdirectories (in order of deps)
######################################################################## ########################################################################
add_subdirectory(src) add_subdirectory(src)

74
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,74 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at carles.fernandez@cttc.es. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

176
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,176 @@
# Contributing to GNSS-SDR
:+1::tada: Thanks for taking the time to contribute! :tada::+1:
Third-party contributions are essential for keeping GNSS-SDR
continuously improving. We simply cannot access the huge number of
platforms and myriad configurations for running GNSS-SDR. We want to
keep it as easy as possible to contribute changes that get things
working in your environment. There are a few guidelines that we need
contributors to follow so that we can have a chance of keeping on top of
things.
The following is a set of guidelines for contributing to GNSS-SDR, which
is hosted in the [GNSS-SDR Organization](https://github.com/gnss-sdr) on
GitHub. These are just guidelines, not rules. Use your best judgment,
and feel free to propose changes to this document in a [pull
request](#how-to-submit-a-pull-request).
## Code of Conduct
This project adheres to the Contributor Covenant [code of
conduct](CODE_OF_CONDUCT.md). By participating, you are expected to
uphold this code. Please report unacceptable behavior.
## Reporting an issue
Have you found a bug in the code which is not in the [list of known
bugs](https://github.com/gnss-sdr/gnss-sdr/issues)? Do you have a
suggestion for improvement? Then by all means please [submit a new
issue](https://github.com/gnss-sdr/gnss-sdr/issues/new), and do not
hesitate to comment on existing [open
issues](https://github.com/gnss-sdr/gnss-sdr/issues).
When filling a new issue, please remember to:
* **Use a clear and descriptive title** for the issue to identify the
problem.
* **Describe the exact steps which reproduce the problem** in as many
details as possible. For example, start by describing your computing
platform (Operating System and version, how did you installed GNSS-SDR
and its dependencies, what file or front-end are you using as a signal
source, etc.). You can also include the configuration file you are
using, or a dump of the terminal output you are getting. The more
information you provide, the more chances to get useful answers.
* **Please be patient**. This organization is run on a volunteer basis,
so it can take some time to the Developer Team to reach your issue.
They will do their best to fix it as soon as possible.
* If you opened an issue that is now solved, it is a good practice to
**close it**.
The list of [open issues](https://github.com/gnss-sdr/gnss-sdr/issues)
can be a good starting point and a source of ideas if you are looking to
contribute to the source code.
## Contributing to the source code
### Preliminaries
1. If you still have not done so, [create your personal account on
GitHub](https://github.com/join).
2. [Fork GNSS-SDR from
GitHub](https://github.com/gnss-sdr/gnss-sdr/fork). This will copy the
whole gnss-sdr repository to your personal account.
3. Then, go to your favourite working folder in your computer and
clone your forked repository by typing (replacing ```YOUR_USERNAME``` by
the actual username of your GitHub account):
$ git clone https://github.com/YOUR_USERNAME/gnss-sdr
4. Your forked repository https://github.com/YOUR_USERNAME/gnss-sdr
will receive the default name of `origin`. You can also add the original
gnss-sdr repository, which is usually called `upstream`:
$ cd gnss-sdr
$ git remote add upstream https://github.com/gnss-sdr/gnss-sdr.git
To verify the new upstream repository you have specified for your fork,
type `git remote -v`. You should see the URL for your fork as `origin`,
and the URL for the original repository as `upstream`:
```
$ git remote -v
origin https://github.com/YOUR_USERNAME/gnss-sdr.git (fetch)
origin https://github.com/YOUR_USERNAME/gnss-sdr.git (push)
upstream https://github.com/gnss-sdr/gnss-sdr.git (fetch)
upstream https://github.com/gnss-sdr/gnss-sdr.git (push)
```
### Start working on your contribution
Checkout the `next` branch of the git repository in order to get
synchronized with the latest development code:
```
$ git checkout next
$ git pull upstream next
```
When start working in a new improvement, please **always** branch off
from `next`. Open a new branch and start working on it:
```
$ git checkout -b my_feature
```
Now you can do changes, add files, do commits (please take a look at
[how to write good commit
messages](https://chris.beams.io/posts/git-commit/)!) and push them to
your repository:
```
$ git push origin my_feature
```
If there have been new pushes to the `next` branch of the `upstream`
repository since the last time you pulled from it, you might want to put
your commits on top of them (this is mandatory for pull requests):
```
$ git pull --rebase upstream next
```
### How to submit a pull request
When the contribution is ready, you can [submit a pull
request](https://github.com/gnss-sdr/gnss-sdr/compare/). Head to your
GitHub repository, switch to your `my_feature` branch, and click the
_**Pull Request**_ button, which will do all the work for you. Code
comparison must be always to the `next` branch.
Once a pull request is sent, the Developer Team can review the set of
changes, discuss potential modifications, and even push follow-up
commits if necessary.
Some things that will increase the chance that your pull request is
accepted:
* Avoid platform-dependent code. If your code require external
dependencies, they must be available as packages in [Debian OldStable](https://wiki.debian.org/DebianOldStable).
* Write tests.
* Follow our [coding style guide](http://gnss-sdr.org/coding-style/).
* Write a descriptive and detailed summary. Please consider that
reviewing pull requests is hard, so include as much information as
possible to make your pull request's intent clear.
For more details about Git usage, please check out [our
tutorial](http://gnss-sdr.org/docs/tutorials/using-git/).
## Contributing to the website
The content of http://gnss-sdr.org lives in a GitHub repository at
https://github.com/gnss-sdr/geniuss-place
You can fork that repository, reproduce the entire website on your
computer using [Jekyll](https://jekyllrb.com/), do changes and submit
pull requests, just as explained above. For more details, please check
out [how to contribute](http://gnss-sdr.org/contribute/).
Last but not the least, you can leave your comments on the website.
------
![GeNiuSS
contributes](http://gnss-sdr.org/assets/images/geniuss-contribute.png)
Thanks for your contribution to GNSS-SDR!

View File

@ -129,9 +129,9 @@ or manually as explained below, and then please follow instructions on how to [d
$ sudo apt-get install libopenblas-dev liblapack-dev # For Debian/Ubuntu/LinuxMint $ sudo apt-get install libopenblas-dev liblapack-dev # For Debian/Ubuntu/LinuxMint
$ sudo yum install lapack-devel blas-devel # For Fedora/CentOS/RHEL $ sudo yum install lapack-devel blas-devel # For Fedora/CentOS/RHEL
$ sudo zypper install lapack-devel blas-devel # For OpenSUSE $ sudo zypper install lapack-devel blas-devel # For OpenSUSE
$ wget http://sourceforge.net/projects/arma/files/armadillo-7.800.1.tar.xz $ wget http://sourceforge.net/projects/arma/files/armadillo-7.800.2.tar.xz
$ tar xvfz armadillo-7.800.1.tar.xz $ tar xvfz armadillo-7.800.2.tar.xz
$ cd armadillo-7.800.1 $ cd armadillo-7.800.2
$ cmake . $ cmake .
$ make $ make
$ sudo make install $ sudo make install

View File

@ -17,7 +17,7 @@ SignalSource.implementation=File_Signal_Source
;#filename: path to file with the captured GNSS signal samples to be processed ;#filename: path to file with the captured GNSS signal samples to be processed
;#SignalSource.filename=/home/javier/Descargas/rtlsdr_tcxo_l1/rtlsdr_tcxo_l1.bin ; <- PUT YOUR FILE HERE ;#SignalSource.filename=/home/javier/Descargas/rtlsdr_tcxo_l1/rtlsdr_tcxo_l1.bin ; <- PUT YOUR FILE HERE
SignalSource.filename=/home/javier/git/gnss-sdr/build/signal_out.bin ; <- PUT YOUR FILE HERE SignalSource.filename=/Users/carlesfernandez/git/cttc/build/signal_out.bin ; <- PUT YOUR FILE HERE
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
SignalSource.item_type=byte SignalSource.item_type=byte

258
docs/changelog Normal file
View File

@ -0,0 +1,258 @@
## [0.0.9](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.9)
DOI: https://doi.org/10.5281/zenodo.291371
This release has several improvements, addition of new features and bug fixes in many dimensions:
### Improvements in Accuracy:
- Major rewriting in the generation of pseudoranges.
- Fixed bug in Galileo E5a/I codes.
- Fixed bug in Galileo E1 correlator spacing.
- Fixed bug that was causing errors in receivers above the troposphere.
- Fixed 16-bit complex resampler.
- Improved time tracking algorithm.
- Added Bancroft's algorithm implementation for PVT initialization.
### Improvements in Availability:
- Improved numerical stability of the PVT solution. The infamous bug that was causing apparently random error peaks has finally been fixed.
### Improvements in Efficiency:
- VOLK_GNSSSDR: Added NEON,AVX and unaligned protokernels for volk_gnsssdr_32f_index_max_32 kernel.
- VOLK_GNSSSDR: Added volk_gnsssdr-config-info to the list of generated executables.
### Improvements in Flexibility:
- Added maximum number of dwells in the Tong algorithm.
### Improvements in Interoperability:
- Added six new Galileo satellites: FM7, FM10, FM11, FM12, FM13, FM14.
- The Hybrid_Observables and Hybrid_PVT implementations can now handle more types of GNSS signals.
- The RINEX printer can now print L2C and E5a observables and navigation files, including multiband configurations.
- Added RTCM 3.2 output to more receiver configurations.
### Improvements in Maintainability:
- The VOLK_GNSSSDR library can now be built with Python 3. Switched dependencies for VOLK_GNSSDR: from (old, python2.7-only) python-cheetah templates to Python3 friendly python-mako and python-six. So, Python-cheetah dependency has been dropped, and python-mako and python-six have been added.
- If suitable versions of gflags, glog, armadillo or googletest are not found in the system, they will be downloaded and built at compile time (versions 2.2.0, 0.3.4, 7.600.2 and 1.8.0, respectively).
- Fixed more than 30 defects detected by Coverity Scan.
- Added CMake Python finder and module checker.
- Deleted files related to CPack.
- Fixes, updates and improvements in the documentation.
- Improvements in CMake scripts: General code cleaning and addition of comments. Improved user information in case of failure. Improved detection of dependencies in more processor architectures (e.g. aarch64).
### Improvements in Marketability:
- Reduced time from a commit to deployment (see virtualization mechanisms in Portability).
### Improvements in Portability:
- Now GNSS-SDR can be run in virtual environments through snap packages (see https://github.com/carlesfernandez/snapcraft-sandbox) and docker images (see https://github.com/carlesfernandez/docker-gnsssdr).
- Now GNSS-SDR is adapted to cross-compiling environments for embedded devices (see https://github.com/carlesfernandez/oe-gnss-sdr-manifest).
- BLAS and LAPACK libraries are not longer mandatory on ARM devices.
### Improvements in Scalability:
- Fixed bug in acquisition with rata rates higher than 16 Msps in 4ms code periods.
### Improvements in Testability:
- Major QA source code refactoring: they has been split into src/tests/unit-tests and src/tests/system-tests folders. They are optionally built with the ENABLE_UNIT_TESTING=ON (unit testing QA code), ENABLE_UNIT_TESTING_EXTRA=ON (unit tests that require extra files downloaded at configure time), ENABLE_SYSTEM_TESTING=ON (system tests, such as measurement of Time-To-First-Fix) and ENABLE_SYSTEM_TESTING_EXTRA=ON (extra system test requiring external tools, automatically downloaded and built at building time) configuration flags. The EXTRA options also download and build a custom software-defined signal generator and version 2.9 of GPSTk, if not already found on the system. Download and local link of version 2.9 can be forced by ENABLE_OWN_GPSTK=ON building configuration flag. Only ENABLE_UNIT_TESTING is set to ON by default.
- Unit tests added: CPU_multicorrelator_test and GPU_multicorrelator_test measure computer performance in multicorrelator setups.
- Unit tests added: GpsL1CADllPllTracking and GpsL1CATelemetryDecoderTest.
- System test added: ttff_gps_l1 performs a set of cold / assisted runs of the software receiver and computes statistics about the obtained Time To First Fix.
- System test added: obs_gps_l1_system_test uses an external software-defined signal generator to produce raw digital GNSS signal from a RINEX navigation file and a position (static or dynamic), processes it with GNSS-SDR, and then compares the RINEX observation file produced by the software receiver to that produced by the signal generator.
- Software Development Kit provided for embedded devices (see http://gnss-sdr.org/docs/tutorials/cross-compiling/).
### Improvements in Usability:
- Now the block factory automatically detects Channel input data type, so it is no longer required to specify Channel.input_type in the configuration. An error raises if Acquisition and Tracking Blocks are not configured with the same input data type.
- Block names changed from L2_M to L2C.
- Documentation available at http://gnss-sdr.org/docs/
- Improved tools for compilation, execution and testing in embedded devices.
See the definitions of concepts and metrics at http://gnss-sdr.org/design-forces/
## [0.0.8](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.8)
DOI: https://doi.org/10.5281/zenodo.57022
This is a maintenance and bug fix release with no relevant new features with respect to v0.0.7. The main changes are:
- Fixed a bug that broke building when using latest VOLK release
- Updated PYBOMBS instructions
- Added Tests for FFT length
- Added Tests for CUDA-based tracking
- Added Tests for SIMD-based tracking
- Improved CUDA-based correlation.
- Updated documentation
- Fixed building in mips and powerpc architectures.
- gr-gn3s and gr-dbfcttc moved to its own repository.
- Improved package reproducibility
- VOLK_GNSSSDR: Fixed a bug in AVX2 puppet
- VOLK_GNSSSDR: can now be built using the C98 standard
- VOLK_GNSSSDR: Fixed a bug that broke building when linking to Boost in some configurations.
- VOLK_GNSSSDR: Added an option to trigger profiling at building time.
- VOLK_GNSSSDR: Fix the CMake-based check for posix_memalign.
## [0.0.7](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.7)
DOI: https://doi.org/10.5281/zenodo.51521
This release has several improvements, addition of new features and bug fixes:
- Improvements in receiver design: Internal block communication has been redesigned to accommodate the addition of new signals, and now upstream and downstream communication within blocks is implemented through the GNU Radio blocks asynchronous message passing system, leading to a more scalable, more robust and cleaner design.
- Improvements in receiver design: Correlators have been rewritten to take full advantage of VOLK and VOLK_GNSSSDR, and they are of general use for any tracking block. Their API now admit an arbitrary number of correlators, spaced in an arbitrary manner, in 16ic and 32fc versions.
- Improvements in receiver design: Block adapters are now all managed by smart pointers, ensuring better memory management.
- Improvements in processing speed: The VOLK_GNSSSDR library has been rewritten, following current VOLK standards and adding a number of new kernels. This approach addresses both efficiency and portability. Now the library provides the key kernels for GNSS signal processing in 16ic and 32fc versions, including SSE2, SSE3, SSE4.1, AVX, AV2 and NEON implementations. Please execute volk_gnsssdr_profile and volk_profile to use the fastest implementation for your host machine.
- New source block: Two_Bit_Packed_File_Signal_Source. This block takes 2 bit samples that have been packed into bytes or shorts as input and generates a byte for each sample.
- Fixes in SUPL assistance (supl.nokia.com removed).
- Improvements in acquisition: Added a non CFAR PCPS acquisition algorithm based on the estimation of the post correlation noise floor. If enabled as an option in the acquisition configuration, it allows setting more stable thresholds in the presence of non-gaussian front-end noise (which is the usual behavior of front-ends.)
- Fixes in acquisition: Fixed mismatch between the config files and the acquisition code in the specification of the IF. Fixed a bug in the length of the FFT of local codes.
- Improvements in tracking sensitivity: Added configuration option to customize the extension of the GPS L1 CA correlation length after bit synchronization (options are: [1,2,4,5,10,20] ms). Only available in the GPS_L1_CA_DLL_PLL_C_Aid_Tracking implementation.
- New tracking block introduced: GPS_L1_CA_DLL_PLL_C_Aid_Tracking is a GPS L1 C/A carrier PLL and code DLL with optional carrier-aid feedback. It is available in both 32 bits gr_complex input samples and in 16 bits short int complex samples. The gr_complex version has also the capability to extend the coherent correlation period from 1ms to 20ms using telemetry symbol synchronization.
- Increased resolution in CN0 estimator internal variables.
- Fixed a bug in computation of GPS L1 C/A carrier phase observable.
- Fixed a bug in the internal state machine that was blocking the receiver after a few hours of usage. Now the receiver can work continually (tested for more than one week, no known limit).
- New tracking block introduced: GPS_L1_CA_DLL_PLL_Tracking_GPU is a GPS L1 C/A carrier PLL and code DLL that uses the CUDA-compatible GPU to compute carrier wipe off and correlation operations, alleviating the CPU load.
- Obsolete/buggy blocks removed: GPS_L1_CA_DLL_FLL_PLL_Tracking, GPS_L1_CA_DLL_PLL_Optim_Tracking.
- Added a RTCM printer and TCP server in PVT blocks (still experimental). The receiver is now able to stream data in real time, serving RTCM 3.2 messages to multiple clients. For instance, it can act as a Ntrip Source feeding a Ntrip Server, or to be used as data input in RTKLIB, obtaining Precise Point Positioning fixes in real-time. The TCP port, Station ID, and rate of MT1019/MT1045 and MSM can be configured. GPS_L1_CA_PVT serves MT1019 (GPS Ephemeris) and MSM7 (MT1077, full GPS pseudoranges, phase ranges, phase range rates and CNR - high resolution) messages, while GALILEO_E1_PVT serves MT1045 (Galileo ephemeris) and MSM7 (MT1097, full Galileo pseudoranges, phase ranges, phase range rates and CNR - high resolution).
- Added a GeoJSON printer. Basic (least-squares) position fixes can be now also stored in this format, in addition to KML.
- Obsolete block removed: output filter.
- QA code migrated to the new asynchronous message passing system.
- Improvements in documentation: update of README.md file, addition of documentation for the VOLK_GNSSSDR library, updated links to new ICDs.
- Improvements in documentation: Satellite identification updated to current constellation status.
- Updated and cleaner console output. Now Galileo satellites have the E identifier in their PRN number.
- Several improvements in CMake scripts allow to build GNSS-SDR in Linux Debian (Jessie, Stretch and Sid), Ubuntu (from 12.04 to 16.04), including amd64, i386, armhf and arm64 architectures, and possibly in other GNU/Linux distributions, as well as in Mac OS X 10.9 to 10.11. It also works well with CMake 3.5 (some problems solved with VOLK_GNSSSDR as a sub-project).
- The software can link either against OpenSSL or against GnuTLS with openssl extensions, whatever it is available. This allows buildings in distributions such as Fedora or ArchLinux, while being compatible with binary distribution through Debian packages.
- Fixed a number of defects detected by Coverity Scan.
- Some fixes required by Debian licensing and packaging system.
- Added a CGRAN (http://www.cgran.org/) manifest
- Lots of code cleaning and fixes of typos and small bugs.
## [0.0.6](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.6)
This release has several improvements and bug fixes:
- Added initial support to multi-band, multi-source configurations (multiple signal sources and signal conditioners).
- Updated configuration files to new notation. Old and new configuration notations still compatible.
- Added skeleton for mixed (multi-frequency and multi-system) observables block.
- Faster local carrier update (25% of improvement).
- Added initial support to GPS L2C real time tracking and decoding of CNAV message with NSL STEREO v2, Fraunhofers Flexiband, and USRPx front-ends (the latter requiring external clock).
- Added initial support to select the frontend clock reference source in UHD signal source (i.e. internal or external clock reference).
- Added 2 bits complex file source for GNSS-SDR GSoC 2015 signal sampler designed by Ajith Peter.
- Added a new rtl_tcp signal source, remote access to RTL2832U-based dongles via TCP.
- Always build front-end-cal, a calibration tool for some DVB-T receivers based on the Realtek's RTL2832U chipset.
- Fixed bug in UTC time computation for GPS signals.
- Updated satellite identification for GPS and Galileo.
- Defined cbyte as a new input data type (std::complex<unsigned char>)
- Adding a new data_type_adapter, from interleaved short to std::complex<short>
- Adding a filter for complex short streams.
- Adding a fir_filter for std::complex<signed char> (aka cbyte). It converts the data type to floats, filters, and converts back to cbyte.
- Added a resampler for cbytes and cshorts.
- First working version of a GPS tracking block implementation using CUDA with multi-GPU device support.
- Updating RINEX obs header when leap second is available.
- Updating RINEX nav file when IONO and UTC data are available.
- Include Signal Strength Indicator in RINEX observable files.
- Tests fixed.
- Fixed more than 200 code defects detected by Coverity Scan.
- Updated documentation.
- Updated documentation and CMake scripts for the GN3S v2 driver (Linux-only)
- Armadillo version automatically downloaded and built if it is not present in the system is now 5.400.3.
- Updated old links from googlecode to new links at GitHub for Google Test, gflags, glog and gperftools.
- gfortran is no longer a required package, but it is used if available.
- Added an option to remove logging.
- Enabled cross-compilation for ARM devices.
- Lots of code cleaning.
## [0.0.5](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.5)
This release has several improvements and bug fixes:
- Now GNSS-SDR can be installed on the system with the usual cmake ../ && make && sudo make install.
- Added volk_gnsssdr library, a volk-like library implementing some specific kernels and ensuring portable executables. It comes with a volk_gnsssdr_profile executable, in the fashion of volk_profile. Volk and volk_gnsssdr are compatible and can be mixed together. This is expected to enable faster execution of the software receiver in upcoming versions.
- The former rtlsdr_signal_source has been replaced by a more general osmosdr_signal_source compatible with all those front-ends accessible by the OsmoSDR driver (bladeRF, hackRF, etc.) in addition to RTL-based dongles.
- Added manpages when binaries gnss-sdr, volk_gnsssdr_profile and front-end-cal are installed.
- Now GNSS-SDR can be build on i386, amd64, armhf, armel and arm64 architectures.
- Now GNSS-SDR builds on Ubuntu 14.04 and 14.10, Debian jessie/sid and Mac OS X 10.9 and 10.10.
- Improved detection of dependencies, specially when installed as .deb packages.
- Added a check' target with some minimal tests.
- Added support for interleaved I/Q byte-size sample files.
- Minor bug fixes, updated documentation and code cleaning.
## [0.0.4](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.4)
This release has several improvements and bug fixes:
- Added hybrid processing GPS L1 C/A and Galileo E1B, providing position fixes make use of observables for both constellations.
- Added implementations of the QuickSync algorithm for GPS L1 C/A and Galileo E1 acquisition.
- Added processing blocks for Galileo E5a: Acquisition, Tracking, Telemetry_Decoder (experimental)
- New configuration files allow to configure GPS and Galileo channels in the same receiver.
- Added tropospheric corrections to GPS and Galileo PVT solution.
- Improved precision obtained by changing some variables from float to double.
- New building options: ENABLE_GN3S, ENABLE_RTLSDR and ENABLE_ARRAY and ENABLE_OPENCL.
- Improved documentation on how to enable optional drivers.
- Fixed bug in memory alignment that caused problems with high data rates.
- Added ENABLE_GENERIC_ARCH, an option to build the binary without detecting the SIMD instruction set present in the compiling machine, so it can be executed in other machines without those specific sets.
- Added ENABLE_GPERFTOOLS, which links the executable to tcmalloc and profiler if Gperftools is available on the system.
- Added carrier phase, Doppler shift and signal strength observables to the RINEX files. Static PPP solutions are available for GPS with RTKLIB via RINEX files.
- The executable now produces RINEX files version 3.02 of Galileo Observables, Navigation data, and mixed (GPS/Galileo) observables and nav data. RINEX 3.02 is the default version of RINEX files.
- Armadillo version updated to 4.400.2
- Armadillo now uses OpenBLAS instead of BLAS if the former is available on the system.
- Some raw pointers have been changed to smart pointers.
- Minor bug fixes and code cleaning.
## [0.0.3](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.3)
This release has several improvements and bug fixes, completing the transition from Subversion to Git. The main changes are:
- Created some missing directories lost in the SVN to Git transition.
- New C++11-ized block factory, flow graph and tests, resulting in better memory management and fewer segmentation faults. Several raw pointers converted to smart pointers.
- Reorganization of assistance data input and output.
- Fixed memory leak when talking to SUPL servers.
- Improved retrieval of assistance data.
- Fixing an error in a constant value related to Galileo.
- Inform users if the temporal folder is not /tmp.
- Fixes and additions to the documentation.
- README in markdown language so it looks better in Git repositories.
- Fixed a bug that prevented the update of all shared map structures (ephemeris, iono parameters, etc…).
- The configuration script now throws error if GCC is older than 4.7 or Boost is older than 1.45
- Improved detection / downloading & building if missing of Gflags and Glog.
- Improved detection / downloading & building if missing of Armadillo and related dependencies.
- Fixes many warnings that appeared when using CMake 3.0.
- Improved detection of GTEST_DIR variable.
- Include header files in libraries so IDEs such as Xcode can display them.
Enjoy it!

View File

@ -217,8 +217,8 @@ bool rtklib_solver::get_PVT(std::map<int,Gnss_Synchro> gnss_observables_map, dou
nav_data.n=valid_obs; nav_data.n=valid_obs;
for (int i=0; i< MAXSAT;i++) for (int i=0; i< MAXSAT;i++)
{ {
nav_data.lam[i][0]=CLIGHT/FREQ1; /* L1/E1 */ nav_data.lam[i][0]=SPEED_OF_LIGHT/FREQ1; /* L1/E1 */
nav_data.lam[i][1]=CLIGHT/FREQ2; /* L2 */ nav_data.lam[i][1]=SPEED_OF_LIGHT/FREQ2; /* L2 */
} }
result=pntpos(obs_data, valid_obs, &nav_data, &rtklib_opt, &old_pvt_sol, NULL, NULL,rtklib_msg); result=pntpos(obs_data, valid_obs, &nav_data, &rtklib_opt, &old_pvt_sol, NULL, NULL,rtklib_msg);

View File

@ -1,4 +1,4 @@
# Copyright (C) 2012-2015 (see AUTHORS file for a list of contributors) # Copyright (C) 2012-2017 (see AUTHORS file for a list of contributors)
# #
# This file is part of GNSS-SDR. # This file is part of GNSS-SDR.
# #
@ -38,14 +38,13 @@ include_directories(
${GFlags_INCLUDE_DIRS} ${GFlags_INCLUDE_DIRS}
${GLOG_INCLUDE_DIRS} ${GLOG_INCLUDE_DIRS}
) )
file(GLOB RTKLIB_LIB_HEADERS "*.h") file(GLOB RTKLIB_LIB_HEADERS "*.h")
list(SORT RTKLIB_LIB_HEADERS) list(SORT RTKLIB_LIB_HEADERS)
add_library(rtklib_lib ${RTKLIB_LIB_SOURCES} ${RTKLIB_LIB_HEADERS}) add_library(rtklib_lib ${RTKLIB_LIB_SOURCES} ${RTKLIB_LIB_HEADERS})
source_group(Headers FILES ${RTKLIB_LIB_HEADERS}) source_group(Headers FILES ${RTKLIB_LIB_HEADERS})
add_dependencies(rtklib_lib armadillo-${armadillo_RELEASE} glog-${glog_RELEASE}) add_dependencies(rtklib_lib armadillo-${armadillo_RELEASE} glog-${glog_RELEASE})
#set_property(SOURCE rtklib_rtkcmn.cc APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-missing-field-initializers ")
target_link_libraries( target_link_libraries(
rtklib_lib rtklib_lib
${Boost_LIBRARIES} ${Boost_LIBRARIES}
@ -56,5 +55,3 @@ target_link_libraries(
${LAPACK} ${LAPACK}
) )
#MESSAGE( STATUS "*****************BLAS: " ${BLAS} )

View File

@ -48,356 +48,243 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef RTKLIB_H_
#define RTKLIB_H_ #ifndef GNSS_SDR_RTKLIB_H_
#define GNSS_SDR_RTKLIB_H_
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <cstring> #include <cstring>
#include <math.h> #include <cmath>
#include <time.h> #include <time.h>
#include <ctype.h> #include <ctype.h>
#include "MATH_CONSTANTS.h"
#include "gnss_frequencies.h"
#include "gnss_obs_codes.h"
#define thread_t pthread_t
#define lock_t pthread_mutex_t
#define initlock(f) pthread_mutex_init(f,NULL)
#define lock(f) pthread_mutex_lock(f)
#define unlock(f) pthread_mutex_unlock(f)
#define FILEPATHSEP '/'
#define PI 3.1415926535897932 /* pi */ const int FILEPATHSEP = '/';
#define D2R (PI/180.0) /* deg to rad */
#define R2D (180.0/PI) /* rad to deg */
#define CLIGHT 299792458.0 /* speed of light (m/s) */
#define SC2RAD 3.1415926535898 /* semi-circle to radian (IS-GPS) */
#define AU 149597870691.0 /* 1 AU (m) */
#define AS2R (D2R/3600.0) /* arc sec to radian */
#define OMGE 7.2921151467E-5 /* earth angular velocity (IS-GPS) (rad/s) */ const double RE_WGS84 = 6378137.0; //!< earth semimajor axis (WGS84) (m)
const double FE_WGS84 = (1.0 / 298.257223563); //!< earth flattening (WGS84)
#define RE_WGS84 6378137.0 /* earth semimajor axis (WGS84) (m) */ const double HION = 350000.0; //!< ionosphere height (m)
#define FE_WGS84 (1.0/298.257223563) /* earth flattening (WGS84) */
#define HION 350000.0 /* ionosphere height (m) */ const unsigned int POLYCRC32 = 0xEDB88320u; //!< CRC32 polynomial
const unsigned int POLYCRC24Q = 0x1864CFBu; //!< CRC24Q polynomial
#define P2_5 0.03125 /* 2^-5 */ const unsigned int PMODE_SINGLE = 0; //!< positioning mode: single
#define P2_6 0.015625 /* 2^-6 */ const unsigned int PMODE_DGPS = 1; //!< positioning mode: DGPS/DGNSS
#define P2_11 4.882812500000000E-04 /* 2^-11 */ const unsigned int PMODE_KINEMA = 2; //!< positioning mode: kinematic
#define P2_15 3.051757812500000E-05 /* 2^-15 */ const unsigned int PMODE_STATIC = 3; //!< positioning mode: static
#define P2_17 7.629394531250000E-06 /* 2^-17 */ const unsigned int PMODE_MOVEB = 4; //!< positioning mode: moving-base
#define P2_19 1.907348632812500E-06 /* 2^-19 */ const unsigned int PMODE_FIXED = 5; //!< positioning mode: fixed
#define P2_20 9.536743164062500E-07 /* 2^-20 */ const unsigned int PMODE_PPP_KINEMA = 6; //!< positioning mode: PPP-kinemaric
#define P2_21 4.768371582031250E-07 /* 2^-21 */ const unsigned int PMODE_PPP_STATIC = 7; //!< positioning mode: PPP-static
#define P2_23 1.192092895507810E-07 /* 2^-23 */ const unsigned int PMODE_PPP_FIXED = 8; //!< positioning mode: PPP-fixed
#define P2_24 5.960464477539063E-08 /* 2^-24 */
#define P2_27 7.450580596923828E-09 /* 2^-27 */
#define P2_29 1.862645149230957E-09 /* 2^-29 */
#define P2_30 9.313225746154785E-10 /* 2^-30 */
#define P2_31 4.656612873077393E-10 /* 2^-31 */
#define P2_32 2.328306436538696E-10 /* 2^-32 */
#define P2_33 1.164153218269348E-10 /* 2^-33 */
#define P2_35 2.910383045673370E-11 /* 2^-35 */
#define P2_38 3.637978807091710E-12 /* 2^-38 */
#define P2_39 1.818989403545856E-12 /* 2^-39 */
#define P2_40 9.094947017729280E-13 /* 2^-40 */
#define P2_43 1.136868377216160E-13 /* 2^-43 */
#define P2_48 3.552713678800501E-15 /* 2^-48 */
#define P2_50 8.881784197001252E-16 /* 2^-50 */
#define P2_55 2.775557561562891E-17 /* 2^-55 */
#define POLYCRC32 0xEDB88320u /* CRC32 polynomial */ const unsigned int SOLF_LLH = 0; //!< solution format: lat/lon/height
#define POLYCRC24Q 0x1864CFBu /* CRC24Q polynomial */ const unsigned int SOLF_XYZ = 1; //!< solution format: x/y/z-ecef
const unsigned int SOLF_ENU = 2; //!< solution format: e/n/u-baseline
const unsigned int SOLF_NMEA = 3; //!< solution format: NMEA-183
const unsigned int SOLF_STAT = 4; //!< solution format: solution status
const unsigned int SOLF_GSIF = 5; //!< solution format: GSI F1/F2
#define PMODE_SINGLE 0 /* positioning mode: single */ const unsigned int SOLQ_NONE = 0; //!< solution status: no solution
#define PMODE_DGPS 1 /* positioning mode: DGPS/DGNSS */ const unsigned int SOLQ_FIX = 1; //!< solution status: fix
#define PMODE_KINEMA 2 /* positioning mode: kinematic */ const unsigned int SOLQ_FLOAT = 2; //!< solution status: float
#define PMODE_STATIC 3 /* positioning mode: static */ const unsigned int SOLQ_SBAS = 3; //!< solution status: SBAS
#define PMODE_MOVEB 4 /* positioning mode: moving-base */ const unsigned int SOLQ_DGPS = 4; //!< solution status: DGPS/DGNSS
#define PMODE_FIXED 5 /* positioning mode: fixed */ const unsigned int SOLQ_SINGLE = 5; //!< solution status: single
#define PMODE_PPP_KINEMA 6 /* positioning mode: PPP-kinemaric */ const unsigned int SOLQ_PPP = 6; //!< solution status: PPP
#define PMODE_PPP_STATIC 7 /* positioning mode: PPP-static */ const unsigned int SOLQ_DR = 7; //!< solution status: dead reckoning
#define PMODE_PPP_FIXED 8 /* positioning mode: PPP-fixed */ const unsigned int MAXSOLQ = 7; //!< max number of solution status
#define SOLF_LLH 0 /* solution format: lat/lon/height */ const unsigned int TIMES_GPST = 0; //!< time system: gps time
#define SOLF_XYZ 1 /* solution format: x/y/z-ecef */ const unsigned int TIMES_UTC = 1; //!< time system: utc
#define SOLF_ENU 2 /* solution format: e/n/u-baseline */ const unsigned int TIMES_JST = 2; //!< time system: jst
#define SOLF_NMEA 3 /* solution format: NMEA-183 */
#define SOLF_STAT 4 /* solution format: solution status */
#define SOLF_GSIF 5 /* solution format: GSI F1/F2 */
#define SOLQ_NONE 0 /* solution status: no solution */ const int MAXFREQ = 7; //!< max NFREQ
#define SOLQ_FIX 1 /* solution status: fix */
#define SOLQ_FLOAT 2 /* solution status: float */
#define SOLQ_SBAS 3 /* solution status: SBAS */
#define SOLQ_DGPS 4 /* solution status: DGPS/DGNSS */
#define SOLQ_SINGLE 5 /* solution status: single */
#define SOLQ_PPP 6 /* solution status: PPP */
#define SOLQ_DR 7 /* solution status: dead reconing */
#define MAXSOLQ 7 /* max number of solution status */
#define TIMES_GPST 0 /* time system: gps time */ const int MAXLEAPS = 64; //!< max number of leap seconds table
#define TIMES_UTC 1 /* time system: utc */ const double DTTOL = 0.005; //!< tolerance of time difference (s)
#define TIMES_JST 2 /* time system: jst */
#define MAXFREQ 7 /* max NFREQ */ const int NFREQ = 3;
const int NEXOBS = 0; //!< number of extended obs codes
const int MAXANT = 64; //!< max length of station name/antenna type
#define FREQ1 1.57542E9 /* L1/E1 frequency (Hz) */ const int MINPRNGPS = 1; //!< min satellite PRN number of GPS
#define FREQ2 1.22760E9 /* L2 frequency (Hz) */ const int MAXPRNGPS = 32; //!< max satellite PRN number of GPS
#define FREQ5 1.17645E9 /* L5/E5a frequency (Hz) */ const int NSATGPS = (MAXPRNGPS - MINPRNGPS + 1); //!< number of GPS satellites
#define FREQ6 1.27875E9 /* E6/LEX frequency (Hz) */ const int NSYSGPS = 1;
#define FREQ7 1.20714E9 /* E5b frequency (Hz) */
#define FREQ8 1.191795E9 /* E5a+b frequency (Hz) */
#define FREQ9 2.492028E9 /* S frequency (Hz) */
#define FREQ1_GLO 1.60200E9 /* GLONASS G1 base frequency (Hz) */
#define DFRQ1_GLO 0.56250E6 /* GLONASS G1 bias frequency (Hz/n) */
#define FREQ2_GLO 1.24600E9 /* GLONASS G2 base frequency (Hz) */
#define DFRQ2_GLO 0.43750E6 /* GLONASS G2 bias frequency (Hz/n) */
#define FREQ3_GLO 1.202025E9 /* GLONASS G3 frequency (Hz) */
#define FREQ1_CMP 1.561098E9 /* BeiDou B1 frequency (Hz) */
#define FREQ2_CMP 1.20714E9 /* BeiDou B2 frequency (Hz) */
#define FREQ3_CMP 1.26852E9 /* BeiDou B3 frequency (Hz) */
#define MAXLEAPS 64 /* max number of leap seconds table */ const int SYS_NONE = 0x00; //!< navigation system: none
#define DTTOL 0.005 /* tolerance of time difference (s) */ const int SYS_GPS = 0x01; //!< navigation system: GPS
const int SYS_SBS = 0x02; //!< navigation system: SBAS
#define NFREQ 3 const int SYS_GLO = 0x04; //!< navigation system: GLONASS
#define NEXOBS 0 /* number of extended obs codes */ const int SYS_GAL = 0x08; //!< navigation system: Galileo
#define MAXANT 64 /* max length of station name/antenna type */ const int SYS_QZS = 0x10; //!< navigation system: QZSS
const int SYS_BDS = 0x20; //!< navigation system: BeiDou
#define MINPRNGPS 1 /* min satellite PRN number of GPS */ const int SYS_IRN = 0x40; //!< navigation system: IRNS
#define MAXPRNGPS 32 /* max satellite PRN number of GPS */ const int SYS_LEO = 0x80; //!< navigation system: LEO
#define NSATGPS (MAXPRNGPS-MINPRNGPS+1) /* number of GPS satellites */ const int SYS_ALL = 0xFF; //!< navigation system: all
#define NSYSGPS 1
#define SYS_NONE 0x00 /* navigation system: none */
#define SYS_GPS 0x01 /* navigation system: GPS */
#define SYS_SBS 0x02 /* navigation system: SBAS */
#define SYS_GLO 0x04 /* navigation system: GLONASS */
#define SYS_GAL 0x08 /* navigation system: Galileo */
#define SYS_QZS 0x10 /* navigation system: QZSS */
#define SYS_CMP 0x20 /* navigation system: BeiDou */
#define SYS_IRN 0x40 /* navigation system: IRNS */
#define SYS_LEO 0x80 /* navigation system: LEO */
#define SYS_ALL 0xFF /* navigation system: all */
#define CODE_NONE 0 /* obs code: none or unknown */
#define CODE_L1C 1 /* obs code: L1C/A,G1C/A,E1C (GPS,GLO,GAL,QZS,SBS) */
#define CODE_L1P 2 /* obs code: L1P,G1P (GPS,GLO) */
#define CODE_L1W 3 /* obs code: L1 Z-track (GPS) */
#define CODE_L1Y 4 /* obs code: L1Y (GPS) */
#define CODE_L1M 5 /* obs code: L1M (GPS) */
#define CODE_L1N 6 /* obs code: L1codeless (GPS) */
#define CODE_L1S 7 /* obs code: L1C(D) (GPS,QZS) */
#define CODE_L1L 8 /* obs code: L1C(P) (GPS,QZS) */
#define CODE_L1E 9 /* (not used) */
#define CODE_L1A 10 /* obs code: E1A (GAL) */
#define CODE_L1B 11 /* obs code: E1B (GAL) */
#define CODE_L1X 12 /* obs code: E1B+C,L1C(D+P) (GAL,QZS) */
#define CODE_L1Z 13 /* obs code: E1A+B+C,L1SAIF (GAL,QZS) */
#define CODE_L2C 14 /* obs code: L2C/A,G1C/A (GPS,GLO) */
#define CODE_L2D 15 /* obs code: L2 L1C/A-(P2-P1) (GPS) */
#define CODE_L2S 16 /* obs code: L2C(M) (GPS,QZS) */
#define CODE_L2L 17 /* obs code: L2C(L) (GPS,QZS) */
#define CODE_L2X 18 /* obs code: L2C(M+L),B1I+Q (GPS,QZS,CMP) */
#define CODE_L2P 19 /* obs code: L2P,G2P (GPS,GLO) */
#define CODE_L2W 20 /* obs code: L2 Z-track (GPS) */
#define CODE_L2Y 21 /* obs code: L2Y (GPS) */
#define CODE_L2M 22 /* obs code: L2M (GPS) */
#define CODE_L2N 23 /* obs code: L2codeless (GPS) */
#define CODE_L5I 24 /* obs code: L5/E5aI (GPS,GAL,QZS,SBS) */
#define CODE_L5Q 25 /* obs code: L5/E5aQ (GPS,GAL,QZS,SBS) */
#define CODE_L5X 26 /* obs code: L5/E5aI+Q/L5B+C (GPS,GAL,QZS,IRN,SBS) */
#define CODE_L7I 27 /* obs code: E5bI,B2I (GAL,CMP) */
#define CODE_L7Q 28 /* obs code: E5bQ,B2Q (GAL,CMP) */
#define CODE_L7X 29 /* obs code: E5bI+Q,B2I+Q (GAL,CMP) */
#define CODE_L6A 30 /* obs code: E6A (GAL) */
#define CODE_L6B 31 /* obs code: E6B (GAL) */
#define CODE_L6C 32 /* obs code: E6C (GAL) */
#define CODE_L6X 33 /* obs code: E6B+C,LEXS+L,B3I+Q (GAL,QZS,CMP) */
#define CODE_L6Z 34 /* obs code: E6A+B+C (GAL) */
#define CODE_L6S 35 /* obs code: LEXS (QZS) */
#define CODE_L6L 36 /* obs code: LEXL (QZS) */
#define CODE_L8I 37 /* obs code: E5(a+b)I (GAL) */
#define CODE_L8Q 38 /* obs code: E5(a+b)Q (GAL) */
#define CODE_L8X 39 /* obs code: E5(a+b)I+Q (GAL) */
#define CODE_L2I 40 /* obs code: B1I (BDS) */
#define CODE_L2Q 41 /* obs code: B1Q (BDS) */
#define CODE_L6I 42 /* obs code: B3I (BDS) */
#define CODE_L6Q 43 /* obs code: B3Q (BDS) */
#define CODE_L3I 44 /* obs code: G3I (GLO) */
#define CODE_L3Q 45 /* obs code: G3Q (GLO) */
#define CODE_L3X 46 /* obs code: G3I+Q (GLO) */
#define CODE_L1I 47 /* obs code: B1I (BDS) */
#define CODE_L1Q 48 /* obs code: B1Q (BDS) */
#define CODE_L5A 49 /* obs code: L5A SPS (IRN) */
#define CODE_L5B 50 /* obs code: L5B RS(D) (IRN) */
#define CODE_L5C 51 /* obs code: L5C RS(P) (IRN) */
#define CODE_L9A 52 /* obs code: SA SPS (IRN) */
#define CODE_L9B 53 /* obs code: SB RS(D) (IRN) */
#define CODE_L9C 54 /* obs code: SC RS(P) (IRN) */
#define CODE_L9X 55 /* obs code: SB+C (IRN) */
#define MAXCODE 55 /* max number of obs code */
#ifdef ENAGLO #ifdef ENAGLO
#define MINPRNGLO 1 /* min satellite slot number of GLONASS */ const int MINPRNGLO = 1; //!< min satellite slot number of GLONASS
#define MAXPRNGLO 27 /* max satellite slot number of GLONASS */ const int MAXPRNGLO = 27; //!< max satellite slot number of GLONASS
#define NSATGLO (MAXPRNGLO-MINPRNGLO+1) /* number of GLONASS satellites */ const int NSATGLO = (MAXPRNGLO - MINPRNGLO + 1); //!< number of GLONASS satellites
#define NSYSGLO 1 const int NSYSGLO = 1;
#else #else
#define MINPRNGLO 0 const int MINPRNGLO = 0;
#define MAXPRNGLO 0 const int MAXPRNGLO = 0;
#define NSATGLO 0 const int NSATGLO = 0;
#define NSYSGLO 0 const int NSYSGLO = 0;
#endif #endif
#ifdef ENAGAL #ifdef ENAGAL
#define MINPRNGAL 1 /* min satellite PRN number of Galileo */ const int MINPRNGAL = 1; //!< min satellite PRN number of Galileo
#define MAXPRNGAL 30 /* max satellite PRN number of Galileo */ const int MAXPRNGAL = 30; //!< max satellite PRN number of Galileo
#define NSATGAL (MAXPRNGAL-MINPRNGAL+1) /* number of Galileo satellites */ const int NSATGAL = (MAXPRNGAL - MINPRNGAL + 1); //!< number of Galileo satellites
#define NSYSGAL 1 const int NSYSGAL = 1;
#else #else
#define MINPRNGAL 0 const int MINPRNGAL = 0;
#define MAXPRNGAL 0 const int MAXPRNGAL = 0;
#define NSATGAL 0 const int NSATGAL = 0;
#define NSYSGAL 0 const int NSYSGAL = 0;
#endif #endif
#ifdef ENAQZS #ifdef ENAQZS
#define MINPRNQZS 193 /* min satellite PRN number of QZSS */ const int MINPRNQZS = 193; //!< min satellite PRN number of QZSS
#define MAXPRNQZS 199 /* max satellite PRN number of QZSS */ const int MAXPRNQZS = 199; //!< max satellite PRN number of QZSS
#define MINPRNQZS_S 183 /* min satellite PRN number of QZSS SAIF */ const int MINPRNQZS_S = 183; //!< min satellite PRN number of QZSS SAIF
#define MAXPRNQZS_S 189 /* max satellite PRN number of QZSS SAIF */ const int MAXPRNQZS_S = 189; //!< max satellite PRN number of QZSS SAIF
#define NSATQZS (MAXPRNQZS-MINPRNQZS+1) /* number of QZSS satellites */ const int NSATQZS = (MAXPRNQZS - MINPRNQZS + 1); //!< number of QZSS satellites
#define NSYSQZS 1 const int NSYSQZS = 1;
#else #else
#define MINPRNQZS 0 const int MINPRNQZS = 0;
#define MAXPRNQZS 0 const int MAXPRNQZS = 0;
#define MINPRNQZS_S 0 const int MINPRNQZS_S = 0;
#define MAXPRNQZS_S 0 const int MAXPRNQZS_S = 0;
#define NSATQZS 0 const int NSATQZS = 0;
#define NSYSQZS 0 const int NSYSQZS = 0;
#endif #endif
#ifdef ENACMP
#define MINPRNCMP 1 /* min satellite sat number of BeiDou */ #ifdef ENABDS
#define MAXPRNCMP 35 /* max satellite sat number of BeiDou */ const int MINPRNBDS = 1; //!< min satellite sat number of BeiDou
#define NSATCMP (MAXPRNCMP-MINPRNCMP+1) /* number of BeiDou satellites */ const int MAXPRNBDS = 35; //!< max satellite sat number of BeiDou
#define NSYSCMP 1 const int NSATBDS = (MAXPRNBDS - MINPRNCM + 1); //!< number of BeiDou satellites
const int NSYSBDS = 1;
#else #else
#define MINPRNCMP 0 const int MINPRNBDS = 0;
#define MAXPRNCMP 0 const int MAXPRNBDS = 0;
#define NSATCMP 0 const int NSATBDS = 0;
#define NSYSCMP 0 const int NSYSBDS = 0;
#endif #endif
#ifdef ENAIRN #ifdef ENAIRN
#define MINPRNIRN 1 /* min satellite sat number of IRNSS */ const int MINPRNIRN = 1; //!< min satellite sat number of IRNSS
#define MAXPRNIRN 7 /* max satellite sat number of IRNSS */ const int MAXPRNIRN = 7; //!< max satellite sat number of IRNSS
#define NSATIRN (MAXPRNIRN-MINPRNIRN+1) /* number of IRNSS satellites */ const int NSATIRN = (MAXPRNIRN - MINPRNIRN + 1); //!< number of IRNSS satellites
#define NSYSIRN 1 const int NSYSIRN = 1;
#else #else
#define MINPRNIRN 0 const int MINPRNIRN = 0;
#define MAXPRNIRN 0 const int MAXPRNIRN = 0;
#define NSATIRN 0 const int NSATIRN = 0;
#define NSYSIRN 0 const int NSYSIRN = 0;
#endif #endif
#ifdef ENALEO #ifdef ENALEO
#define MINPRNLEO 1 /* min satellite sat number of LEO */ const int MINPRNLEO = 1; //!< min satellite sat number of LEO
#define MAXPRNLEO 10 /* max satellite sat number of LEO */ const int NSATLEO = 10; //!< max satellite sat number of LEO
#define NSATLEO (MAXPRNLEO-MINPRNLEO+1) /* number of LEO satellites */ const int NSATLEO = (MAXPRNLEO - MINPRNLEO + 1); //!< number of LEO satellites
#define NSYSLEO 1 const int NSYSLEO = 1;
#else #else
#define MINPRNLEO 0 const int MINPRNLEO = 0;
#define MAXPRNLEO 0 const int MAXPRNLEO = 0;
#define NSATLEO 0 const int NSATLEO = 0;
#define NSYSLEO 0 const int NSYSLEO = 0;
#endif #endif
#define NSYS (NSYSGPS+NSYSGLO+NSYSGAL+NSYSQZS+NSYSCMP+NSYSIRN+NSYSLEO) /* number of systems */ const int NSYS = (NSYSGPS + NSYSGLO + NSYSGAL + NSYSQZS + NSYSBDS + NSYSIRN + NSYSLEO); //!< number of systems
#define MINPRNSBS 120 /* min satellite PRN number of SBAS */ const int MINPRNSBS = 120; //!< min satellite PRN number of SBAS
#define MAXPRNSBS 142 /* max satellite PRN number of SBAS */ const int MAXPRNSBS = 142; //!< max satellite PRN number of SBAS
#define NSATSBS (MAXPRNSBS-MINPRNSBS+1) /* number of SBAS satellites */ const int NSATSBS = (MAXPRNSBS - MINPRNSBS + 1); //!< number of SBAS satellites
#define MAXSAT (NSATGPS+NSATGLO+NSATGAL+NSATQZS+NSATCMP+NSATIRN+NSATSBS+NSATLEO) const int MAXSAT = (NSATGPS + NSATGLO + NSATGAL + NSATQZS + NSATBDS + NSATIRN + NSATSBS + NSATLEO);
#define MAXNIGP 201 /* max number of IGP in SBAS band */ const int MAXSTA = 255;
#define MAXCODE 55 /* max number of obs code */
#define MAXSTA 255
#ifndef MAXOBS #ifndef MAXOBS
#define MAXOBS 64 /* max number of obs in an epoch */ const int MAXOBS = 64; //!< max number of obs in an epoch
#endif #endif
#define MAXRCV 64 /* max receiver number (1 to MAXRCV) */ const int MAXRCV = 64; //!< max receiver number (1 to MAXRCV)
#define MAXOBSTYPE 64 /* max number of obs type in RINEX */ const int MAXOBSTYPE = 64; //!< max number of obs type in RINEX
#define DTTOL 0.005 /* tolerance of time difference (s) */ const double MAXDTOE = 7200.0; //!< max time difference to GPS Toe (s)
#define MAXDTOE 7200.0 /* max time difference to GPS Toe (s) */ const double MAXDTOE_QZS = 7200.0; //!< max time difference to QZSS Toe (s)
#define MAXDTOE_QZS 7200.0 /* max time difference to QZSS Toe (s) */ const double MAXDTOE_GAL = 10800.0; //!< max time difference to Galileo Toe (s)
#define MAXDTOE_GAL 10800.0 /* max time difference to Galileo Toe (s) */ const double MAXDTOE_BDS = 21600.0; //!< max time difference to BeiDou Toe (s)
#define MAXDTOE_CMP 21600.0 /* max time difference to BeiDou Toe (s) */ const double MAXDTOE_GLO = 1800.0; //!< max time difference to GLONASS Toe (s)
#define MAXDTOE_GLO 1800.0 /* max time difference to GLONASS Toe (s) */ const double MAXDTOE_SBS = 360.0; //!< max time difference to SBAS Toe (s)
#define MAXDTOE_SBS 360.0 /* max time difference to SBAS Toe (s) */ const double MAXDTOE_S = 86400.0; //!< max time difference to ephem toe (s) for other
#define MAXDTOE_S 86400.0 /* max time difference to ephem toe (s) for other */ const double MAXGDOP = 300.0; //!< max GDOP
#define MAXGDOP 300.0 /* max GDOP */
#define MAXSBSAGEF 30.0 /* max age of SBAS fast correction (s) */ const int MAXSBSURA = 8; //!< max URA of SBAS satellite
#define MAXSBSAGEL 1800.0 /* max age of SBAS long term corr (s) */ const int MAXBAND = 10; //!< max SBAS band of IGP
#define MAXSBSURA 8 /* max URA of SBAS satellite */ const int MAXNIGP = 201; //!< max number of IGP in SBAS band
#define MAXBAND 10 /* max SBAS band of IGP */ const int MAXNGEO = 4; //!< max number of GEO satellites
#define MAXNIGP 201 /* max number of IGP in SBAS band */
#define MAXNGEO 4 /* max number of GEO satellites */
#define MAXSOLMSG 8191 /* max length of solution message */ const int MAXSOLMSG = 8191; //!< max length of solution message
#define MAXERRMSG 4096 /* max length of error/warning message */ const int MAXERRMSG = 4096; //!< max length of error/warning message
#define IONOOPT_OFF 0 /* ionosphere option: correction off */ const unsigned int IONOOPT_OFF = 0; //!< ionosphere option: correction off
#define IONOOPT_BRDC 1 /* ionosphere option: broadcast model */ const unsigned int IONOOPT_BRDC = 1; //!< ionosphere option: broadcast model
#define IONOOPT_SBAS 2 /* ionosphere option: SBAS model */ const unsigned int IONOOPT_SBAS = 2; //!< ionosphere option: SBAS model
#define IONOOPT_IFLC 3 /* ionosphere option: L1/L2 or L1/L5 iono-free LC */ const unsigned int IONOOPT_IFLC = 3; //!< ionosphere option: L1/L2 or L1/L5 iono-free LC
#define IONOOPT_EST 4 /* ionosphere option: estimation */ const unsigned int IONOOPT_EST = 4; //!< ionosphere option: estimation
#define IONOOPT_TEC 5 /* ionosphere option: IONEX TEC model */ const unsigned int IONOOPT_TEC = 5; //!< ionosphere option: IONEX TEC model
#define IONOOPT_QZS 6 /* ionosphere option: QZSS broadcast model */ const unsigned int IONOOPT_QZS = 6; //!< ionosphere option: QZSS broadcast model
#define IONOOPT_LEX 7 /* ionosphere option: QZSS LEX ionospehre */ const unsigned int IONOOPT_LEX = 7; //!< ionosphere option: QZSS LEX ionospehre
#define IONOOPT_STEC 8 /* ionosphere option: SLANT TEC model */ const unsigned int IONOOPT_STEC = 8; //!< ionosphere option: SLANT TEC model
#define TROPOPT_OFF 0 /* troposphere option: correction off */ const unsigned int TROPOPT_OFF = 0; //!< troposphere option: correction off
#define TROPOPT_SAAS 1 /* troposphere option: Saastamoinen model */ const unsigned int TROPOPT_SAAS = 1; //!< troposphere option: Saastamoinen model
#define TROPOPT_SBAS 2 /* troposphere option: SBAS model */ const unsigned int TROPOPT_SBAS = 2; //!< troposphere option: SBAS model
#define TROPOPT_EST 3 /* troposphere option: ZTD estimation */ const unsigned int TROPOPT_EST = 3; //!< troposphere option: ZTD estimation
#define TROPOPT_ESTG 4 /* troposphere option: ZTD+grad estimation */ const unsigned int TROPOPT_ESTG = 4; //!< troposphere option: ZTD+grad estimation
#define TROPOPT_ZTD 5 /* troposphere option: ZTD correction */ const unsigned int TROPOPT_ZTD = 5; //!< troposphere option: ZTD correction
#define EPHOPT_BRDC 0 /* ephemeris option: broadcast ephemeris */ const unsigned int EPHOPT_BRDC = 0; //!< ephemeris option: broadcast ephemeris
#define EPHOPT_PREC 1 /* ephemeris option: precise ephemeris */ const unsigned int EPHOPT_PREC = 1; //!< ephemeris option: precise ephemeris
#define EPHOPT_SBAS 2 /* ephemeris option: broadcast + SBAS */ const unsigned int EPHOPT_SBAS = 2; //!< ephemeris option: broadcast + SBAS
#define EPHOPT_SSRAPC 3 /* ephemeris option: broadcast + SSR_APC */ const unsigned int EPHOPT_SSRAPC = 3; //!< ephemeris option: broadcast + SSR_APC
#define EPHOPT_SSRCOM 4 /* ephemeris option: broadcast + SSR_COM */ const unsigned int EPHOPT_SSRCOM = 4; //!< ephemeris option: broadcast + SSR_COM
#define EPHOPT_LEX 5 /* ephemeris option: QZSS LEX ephemeris */ const unsigned int EPHOPT_LEX = 5; //!< ephemeris option: QZSS LEX ephemeris
#define EFACT_GPS 1.0 /* error factor: GPS */ const double EFACT_GPS = 1.0; //!< error factor: GPS
#define EFACT_GLO 1.5 /* error factor: GLONASS */ const double EFACT_GLO = 1.5; //!< error factor: GLONASS
#define EFACT_GAL 1.0 /* error factor: Galileo */ const double EFACT_GAL = 1.0; //!< error factor: Galileo
#define EFACT_QZS 1.0 /* error factor: QZSS */ const double EFACT_QZS = 1.0; //!< error factor: QZSS
#define EFACT_CMP 1.0 /* error factor: BeiDou */ const double EFACT_BDS = 1.0; //!< error factor: BeiDou
#define EFACT_IRN 1.5 /* error factor: IRNSS */ const double EFACT_IRN = 1.5; //!< error factor: IRNSS
#define EFACT_SBS 3.0 /* error factor: SBAS */ const double EFACT_SBS = 3.0; //!< error factor: SBAS
const int MAXEXFILE = 1024; //!< max number of expanded files
const double MAXSBSAGEF = 30.0; //!< max age of SBAS fast correction (s)
const double MAXSBSAGEL = 1800.0; //!< max age of SBAS long term corr (s)
#define MAXEXFILE 1024 /* max number of expanded files */ typedef void fatalfunc_t(const char *); //!< fatal callback function type
#define MAXSBSAGEF 30.0 /* max age of SBAS fast correction (s) */
#define MAXSBSAGEL 1800.0 /* max age of SBAS long term corr (s) */
#define MAXSBSURA 8 /* max URA of SBAS satellite */
#define MAXBAND 10 /* max SBAS band of IGP */
#define MAXNIGP 201 /* max number of IGP in SBAS band */
typedef void fatalfunc_t(const char *); /* fatal callback function type */
typedef struct { /* time struct */ typedef struct { /* time struct */
time_t time; /* time (s) expressed by standard time_t */ time_t time; /* time (s) expressed by standard time_t */
double sec; /* fraction of second under 1 s */ double sec; /* fraction of second under 1 s */
} gtime_t; } gtime_t;
typedef struct { /* observation data record */ typedef struct { /* observation data record */
gtime_t time; /* receiver sampling time (GPST) */ gtime_t time; /* receiver sampling time (GPST) */
unsigned char sat,rcv; /* satellite/receiver number */ unsigned char sat,rcv; /* satellite/receiver number */
@ -409,11 +296,13 @@ typedef struct { /* observation data record */
float D[NFREQ+NEXOBS]; /* observation data doppler frequency (Hz) */ float D[NFREQ+NEXOBS]; /* observation data doppler frequency (Hz) */
} obsd_t; } obsd_t;
typedef struct { /* observation data */ typedef struct { /* observation data */
int n,nmax; /* number of obervation data/allocated */ int n,nmax; /* number of obervation data/allocated */
obsd_t *data; /* observation data records */ obsd_t *data; /* observation data records */
} obs_t; } obs_t;
typedef struct { /* earth rotation parameter data type */ typedef struct { /* earth rotation parameter data type */
double mjd; /* mjd (days) */ double mjd; /* mjd (days) */
double xp,yp; /* pole offset (rad) */ double xp,yp; /* pole offset (rad) */
@ -422,11 +311,13 @@ typedef struct { /* earth rotation parameter data type */
double lod; /* length of day (s/day) */ double lod; /* length of day (s/day) */
} erpd_t; } erpd_t;
typedef struct { /* earth rotation parameter type */ typedef struct { /* earth rotation parameter type */
int n,nmax; /* number and max number of data */ int n,nmax; /* number and max number of data */
erpd_t *data; /* earth rotation parameter data */ erpd_t *data; /* earth rotation parameter data */
} erp_t; } erp_t;
typedef struct { /* antenna parameter type */ typedef struct { /* antenna parameter type */
int sat; /* satellite number (0:receiver) */ int sat; /* satellite number (0:receiver) */
char type[MAXANT]; /* antenna type */ char type[MAXANT]; /* antenna type */
@ -437,11 +328,13 @@ typedef struct { /* antenna parameter type */
/* el=90,85,...,0 or nadir=0,1,2,3,... (deg) */ /* el=90,85,...,0 or nadir=0,1,2,3,... (deg) */
} pcv_t; } pcv_t;
typedef struct { /* antenna parameters type */ typedef struct { /* antenna parameters type */
int n,nmax; /* number of data/allocated */ int n,nmax; /* number of data/allocated */
pcv_t *pcv; /* antenna parameters data */ pcv_t *pcv; /* antenna parameters data */
} pcvs_t; } pcvs_t;
typedef struct { /* almanac type */ typedef struct { /* almanac type */
int sat; /* satellite number */ int sat; /* satellite number */
int svh; /* sv health (0:ok) */ int svh; /* sv health (0:ok) */
@ -454,14 +347,15 @@ typedef struct { /* almanac type */
double f0,f1; /* SV clock parameters (af0,af1) */ double f0,f1; /* SV clock parameters (af0,af1) */
} alm_t; } alm_t;
typedef struct { /* GPS/QZS/GAL broadcast ephemeris type */ typedef struct { /* GPS/QZS/GAL broadcast ephemeris type */
int sat; /* satellite number */ int sat; /* satellite number */
int iode,iodc; /* IODE,IODC */ int iode,iodc; /* IODE,IODC */
int sva; /* SV accuracy (URA index) */ int sva; /* SV accuracy (URA index) */
int svh; /* SV health (0:ok) */ int svh; /* SV health (0:ok) */
int week; /* GPS/QZS: gps week, GAL: galileo week */ int week; /* GPS/QZS: gps week, GAL: galileo week */
int code; /* GPS/QZS: code on L2, GAL/CMP: data sources */ int code; /* GPS/QZS: code on L2, GAL/BDS: data sources */
int flag; /* GPS/QZS: L2 P data flag, CMP: nav type */ int flag; /* GPS/QZS: L2 P data flag, BDS: nav type */
gtime_t toe,toc,ttr; /* Toe,Toc,T_trans */ gtime_t toe,toc,ttr; /* Toe,Toc,T_trans */
/* SV orbit parameters */ /* SV orbit parameters */
double A,e,i0,OMG0,omg,M0,deln,OMGd,idot; double A,e,i0,OMG0,omg,M0,deln,OMGd,idot;
@ -472,10 +366,11 @@ typedef struct { /* GPS/QZS/GAL broadcast ephemeris type */
double tgd[4]; /* group delay parameters */ double tgd[4]; /* group delay parameters */
/* GPS/QZS:tgd[0]=TGD */ /* GPS/QZS:tgd[0]=TGD */
/* GAL :tgd[0]=BGD E5a/E1,tgd[1]=BGD E5b/E1 */ /* GAL :tgd[0]=BGD E5a/E1,tgd[1]=BGD E5b/E1 */
/* CMP :tgd[0]=BGD1,tgd[1]=BGD2 */ /* BDS :tgd[0]=BGD1,tgd[1]=BGD2 */
double Adot,ndot; /* Adot,ndot for CNAV */ double Adot,ndot; /* Adot,ndot for CNAV */
} eph_t; } eph_t;
typedef struct { /* GLONASS broadcast ephemeris type */ typedef struct { /* GLONASS broadcast ephemeris type */
int sat; /* satellite number */ int sat; /* satellite number */
int iode; /* IODE (0-6 bit of tb field) */ int iode; /* IODE (0-6 bit of tb field) */
@ -490,6 +385,7 @@ typedef struct { /* GLONASS broadcast ephemeris type */
double dtaun; /* delay between L1 and L2 (s) */ double dtaun; /* delay between L1 and L2 (s) */
} geph_t; } geph_t;
typedef struct { /* precise ephemeris type */ typedef struct { /* precise ephemeris type */
gtime_t time; /* time (GPST) */ gtime_t time; /* time (GPST) */
int index; /* ephemeris index for multiple files */ int index; /* ephemeris index for multiple files */
@ -501,6 +397,7 @@ typedef struct { /* precise ephemeris type */
float vco[MAXSAT][3]; /* satellite velocity covariance (m^2) */ float vco[MAXSAT][3]; /* satellite velocity covariance (m^2) */
} peph_t; } peph_t;
typedef struct { /* precise clock type */ typedef struct { /* precise clock type */
gtime_t time; /* time (GPST) */ gtime_t time; /* time (GPST) */
int index; /* clock index for multiple files */ int index; /* clock index for multiple files */
@ -508,6 +405,7 @@ typedef struct { /* precise clock type */
float std[MAXSAT][1]; /* satellite clock std (s) */ float std[MAXSAT][1]; /* satellite clock std (s) */
} pclk_t; } pclk_t;
typedef struct { /* SBAS ephemeris type */ typedef struct { /* SBAS ephemeris type */
int sat; /* satellite number */ int sat; /* satellite number */
gtime_t t0; /* reference epoch time (GPST) */ gtime_t t0; /* reference epoch time (GPST) */
@ -520,6 +418,7 @@ typedef struct { /* SBAS ephemeris type */
double af0,af1; /* satellite clock-offset/drift (s,s/s) */ double af0,af1; /* satellite clock-offset/drift (s,s/s) */
} seph_t; } seph_t;
typedef struct { /* norad two line element data type */ typedef struct { /* norad two line element data type */
char name [32]; /* common name */ char name [32]; /* common name */
char alias[32]; /* alias name */ char alias[32]; /* alias name */
@ -541,11 +440,13 @@ typedef struct { /* norad two line element data type */
int rev; /* revolution number at epoch */ int rev; /* revolution number at epoch */
} tled_t; } tled_t;
typedef struct { /* norad two line element type */ typedef struct { /* norad two line element type */
int n,nmax; /* number/max number of two line element data */ int n,nmax; /* number/max number of two line element data */
tled_t *data; /* norad two line element data */ tled_t *data; /* norad two line element data */
} tle_t; } tle_t;
typedef struct { /* TEC grid type */ typedef struct { /* TEC grid type */
gtime_t time; /* epoch time (GPST) */ gtime_t time; /* epoch time (GPST) */
int ndata[3]; /* TEC grid data size {nlat,nlon,nhgt} */ int ndata[3]; /* TEC grid data size {nlat,nlon,nhgt} */
@ -557,23 +458,27 @@ typedef struct { /* TEC grid type */
float *rms; /* RMS values (tecu) */ float *rms; /* RMS values (tecu) */
} tec_t; } tec_t;
typedef struct { /* satellite fcb data type */ typedef struct { /* satellite fcb data type */
gtime_t ts,te; /* start/end time (GPST) */ gtime_t ts,te; /* start/end time (GPST) */
double bias[MAXSAT][3]; /* fcb value (cyc) */ double bias[MAXSAT][3]; /* fcb value (cyc) */
double std [MAXSAT][3]; /* fcb std-dev (cyc) */ double std [MAXSAT][3]; /* fcb std-dev (cyc) */
} fcbd_t; } fcbd_t;
typedef struct { /* SBAS message type */ typedef struct { /* SBAS message type */
int week,tow; /* receiption time */ int week,tow; /* receiption time */
int prn; /* SBAS satellite PRN number */ int prn; /* SBAS satellite PRN number */
unsigned char msg[29]; /* SBAS message (226bit) padded by 0 */ unsigned char msg[29]; /* SBAS message (226bit) padded by 0 */
} sbsmsg_t; } sbsmsg_t;
typedef struct { /* SBAS messages type */ typedef struct { /* SBAS messages type */
int n,nmax; /* number of SBAS messages/allocated */ int n,nmax; /* number of SBAS messages/allocated */
sbsmsg_t *msgs; /* SBAS messages */ sbsmsg_t *msgs; /* SBAS messages */
} sbs_t; } sbs_t;
typedef struct { /* SBAS fast correction type */ typedef struct { /* SBAS fast correction type */
gtime_t t0; /* time of applicability (TOF) */ gtime_t t0; /* time of applicability (TOF) */
double prc; /* pseudorange correction (PRC) (m) */ double prc; /* pseudorange correction (PRC) (m) */
@ -584,6 +489,7 @@ typedef struct { /* SBAS fast correction type */
short ai; /* degradation factor indicator */ short ai; /* degradation factor indicator */
} sbsfcorr_t; } sbsfcorr_t;
typedef struct { /* SBAS long term satellite error correction type */ typedef struct { /* SBAS long term satellite error correction type */
gtime_t t0; /* correction time */ gtime_t t0; /* correction time */
int iode; /* IODE (issue of date ephemeris) */ int iode; /* IODE (issue of date ephemeris) */
@ -592,12 +498,14 @@ typedef struct { /* SBAS long term satellite error correction type */
double daf0,daf1; /* delta clock-offset/drift (s,s/s) */ double daf0,daf1; /* delta clock-offset/drift (s,s/s) */
} sbslcorr_t; } sbslcorr_t;
typedef struct { /* SBAS satellite correction type */ typedef struct { /* SBAS satellite correction type */
int sat; /* satellite number */ int sat; /* satellite number */
sbsfcorr_t fcorr; /* fast correction */ sbsfcorr_t fcorr; /* fast correction */
sbslcorr_t lcorr; /* long term correction */ sbslcorr_t lcorr; /* long term correction */
} sbssatp_t; } sbssatp_t;
typedef struct { /* SBAS satellite corrections type */ typedef struct { /* SBAS satellite corrections type */
int iodp; /* IODP (issue of date mask) */ int iodp; /* IODP (issue of date mask) */
int nsat; /* number of satellites */ int nsat; /* number of satellites */
@ -605,6 +513,7 @@ typedef struct { /* SBAS satellite corrections type */
sbssatp_t sat[MAXSAT]; /* satellite correction */ sbssatp_t sat[MAXSAT]; /* satellite correction */
} sbssat_t; } sbssat_t;
typedef struct { /* SBAS ionospheric correction type */ typedef struct { /* SBAS ionospheric correction type */
gtime_t t0; /* correction time */ gtime_t t0; /* correction time */
short lat,lon; /* latitude/longitude (deg) */ short lat,lon; /* latitude/longitude (deg) */
@ -612,6 +521,7 @@ typedef struct { /* SBAS ionospheric correction type */
float delay; /* vertical delay estimate (m) */ float delay; /* vertical delay estimate (m) */
} sbsigp_t; } sbsigp_t;
typedef struct { /* IGP band type */ typedef struct { /* IGP band type */
short x; /* longitude/latitude (deg) */ short x; /* longitude/latitude (deg) */
const short *y; /* latitudes/longitudes (deg) */ const short *y; /* latitudes/longitudes (deg) */
@ -619,12 +529,14 @@ typedef struct { /* IGP band type */
unsigned char bite; /* IGP mask end bit */ unsigned char bite; /* IGP mask end bit */
} sbsigpband_t; } sbsigpband_t;
typedef struct { /* SBAS ionospheric corrections type */ typedef struct { /* SBAS ionospheric corrections type */
int iodi; /* IODI (issue of date ionos corr) */ int iodi; /* IODI (issue of date ionos corr) */
int nigp; /* number of igps */ int nigp; /* number of igps */
sbsigp_t igp[MAXNIGP]; /* ionospheric correction */ sbsigp_t igp[MAXNIGP]; /* ionospheric correction */
} sbsion_t; } sbsion_t;
typedef struct { /* DGPS/GNSS correction type */ typedef struct { /* DGPS/GNSS correction type */
gtime_t t0; /* correction time */ gtime_t t0; /* correction time */
double prc; /* pseudorange correction (PRC) (m) */ double prc; /* pseudorange correction (PRC) (m) */
@ -633,6 +545,7 @@ typedef struct { /* DGPS/GNSS correction type */
double udre; /* UDRE */ double udre; /* UDRE */
} dgps_t; } dgps_t;
typedef struct { /* SSR correction type */ typedef struct { /* SSR correction type */
gtime_t t0[6]; /* epoch time (GPST) {eph,clk,hrclk,ura,bias,pbias} */ gtime_t t0[6]; /* epoch time (GPST) {eph,clk,hrclk,ura,bias,pbias} */
double udi[6]; /* SSR update interval (s) */ double udi[6]; /* SSR update interval (s) */
@ -652,6 +565,7 @@ typedef struct { /* SSR correction type */
unsigned char update; /* update flag (0:no update,1:update) */ unsigned char update; /* update flag (0:no update,1:update) */
} ssr_t; } ssr_t;
typedef struct { /* QZSS LEX message type */ typedef struct { /* QZSS LEX message type */
int prn; /* satellite PRN number */ int prn; /* satellite PRN number */
int type; /* message type */ int type; /* message type */
@ -662,11 +576,13 @@ typedef struct { /* QZSS LEX message type */
unsigned char msg[212]; /* LEX message data part 1695 bits */ unsigned char msg[212]; /* LEX message data part 1695 bits */
} lexmsg_t; } lexmsg_t;
typedef struct { /* QZSS LEX messages type */ typedef struct { /* QZSS LEX messages type */
int n,nmax; /* number of LEX messages and allocated */ int n,nmax; /* number of LEX messages and allocated */
lexmsg_t *msgs; /* LEX messages */ lexmsg_t *msgs; /* LEX messages */
} lex_t; } lex_t;
typedef struct { /* QZSS LEX ephemeris type */ typedef struct { /* QZSS LEX ephemeris type */
gtime_t toe; /* epoch time (GPST) */ gtime_t toe; /* epoch time (GPST) */
gtime_t tof; /* message frame time (GPST) */ gtime_t tof; /* message frame time (GPST) */
@ -682,6 +598,7 @@ typedef struct { /* QZSS LEX ephemeris type */
double isc[8]; /* ISC */ double isc[8]; /* ISC */
} lexeph_t; } lexeph_t;
typedef struct { /* QZSS LEX ionosphere correction type */ typedef struct { /* QZSS LEX ionosphere correction type */
gtime_t t0; /* epoch time (GPST) */ gtime_t t0; /* epoch time (GPST) */
double tspan; /* valid time span (s) */ double tspan; /* valid time span (s) */
@ -689,6 +606,7 @@ typedef struct { /* QZSS LEX ionosphere correction type */
double coef[3][2]; /* coefficients lat x lon (3 x 2) */ double coef[3][2]; /* coefficients lat x lon (3 x 2) */
} lexion_t; } lexion_t;
typedef struct { /* stec data type */ typedef struct { /* stec data type */
gtime_t time; /* time (GPST) */ gtime_t time; /* time (GPST) */
unsigned char sat; /* satellite number */ unsigned char sat; /* satellite number */
@ -698,12 +616,14 @@ typedef struct { /* stec data type */
unsigned char flag; /* fix flag */ unsigned char flag; /* fix flag */
} stec_t; } stec_t;
typedef struct { /* trop data type */ typedef struct { /* trop data type */
gtime_t time; /* time (GPST) */ gtime_t time; /* time (GPST) */
double trp[3]; /* zenith tropos delay/gradient (m) */ double trp[3]; /* zenith tropos delay/gradient (m) */
float std[3]; /* std-dev (m) */ float std[3]; /* std-dev (m) */
} trop_t; } trop_t;
typedef struct { /* ppp corrections type */ typedef struct { /* ppp corrections type */
int nsta; /* number of stations */ int nsta; /* number of stations */
char stas[MAXSTA][8]; /* station names */ char stas[MAXSTA][8]; /* station names */
@ -714,6 +634,7 @@ typedef struct { /* ppp corrections type */
trop_t *trop[MAXSTA]; /* trop data */ trop_t *trop[MAXSTA]; /* trop data */
} pppcorr_t; } pppcorr_t;
typedef struct { /* navigation data type */ typedef struct { /* navigation data type */
int n,nmax; /* number of broadcast ephemeris */ int n,nmax; /* number of broadcast ephemeris */
int ng,ngmax; /* number of glonass ephemeris */ int ng,ngmax; /* number of glonass ephemeris */
@ -761,6 +682,7 @@ typedef struct { /* navigation data type */
pppcorr_t pppcorr; /* ppp corrections */ pppcorr_t pppcorr; /* ppp corrections */
} nav_t; } nav_t;
typedef struct { /* station parameter type */ typedef struct { /* station parameter type */
char name [MAXANT]; /* marker name */ char name [MAXANT]; /* marker name */
char marker [MAXANT]; /* marker number */ char marker [MAXANT]; /* marker number */
@ -777,6 +699,7 @@ typedef struct { /* station parameter type */
double hgt; /* antenna height (m) */ double hgt; /* antenna height (m) */
} sta_t; } sta_t;
typedef struct { /* solution type */ typedef struct { /* solution type */
gtime_t time; /* time (GPST) */ gtime_t time; /* time (GPST) */
double rr[6]; /* position/velocity (m|m/s) */ double rr[6]; /* position/velocity (m|m/s) */
@ -793,6 +716,7 @@ typedef struct { /* solution type */
float thres; /* AR ratio threshold for valiation */ float thres; /* AR ratio threshold for valiation */
} sol_t; } sol_t;
typedef struct { /* solution buffer type */ typedef struct { /* solution buffer type */
int n,nmax; /* number of solution/max number of buffer */ int n,nmax; /* number of solution/max number of buffer */
int cyclic; /* cyclic buffer flag */ int cyclic; /* cyclic buffer flag */
@ -804,6 +728,7 @@ typedef struct { /* solution buffer type */
int nb; /* number of byte in message buffer */ int nb; /* number of byte in message buffer */
} solbuf_t; } solbuf_t;
typedef struct { /* solution status type */ typedef struct { /* solution status type */
gtime_t time; /* time (GPST) */ gtime_t time; /* time (GPST) */
unsigned char sat; /* satellite number */ unsigned char sat; /* satellite number */
@ -819,11 +744,13 @@ typedef struct { /* solution status type */
unsigned short rejc; /* reject counter */ unsigned short rejc; /* reject counter */
} solstat_t; } solstat_t;
typedef struct { /* solution status buffer type */ typedef struct { /* solution status buffer type */
int n,nmax; /* number of solution/max number of buffer */ int n,nmax; /* number of solution/max number of buffer */
solstat_t *data; /* solution status data */ solstat_t *data; /* solution status data */
} solstatbuf_t; } solstatbuf_t;
typedef struct { /* RTCM control struct type */ typedef struct { /* RTCM control struct type */
int staid; /* station id */ int staid; /* station id */
int stah; /* station health */ int stah; /* station health */
@ -855,6 +782,7 @@ typedef struct { /* RTCM control struct type */
char opt[256]; /* RTCM dependent options */ char opt[256]; /* RTCM dependent options */
} rtcm_t; } rtcm_t;
typedef struct { /* download url type */ typedef struct { /* download url type */
char type[32]; /* data type */ char type[32]; /* data type */
char path[1024]; /* url path */ char path[1024]; /* url path */
@ -862,6 +790,7 @@ typedef struct { /* download url type */
double tint; /* time interval (s) */ double tint; /* time interval (s) */
} url_t; } url_t;
typedef struct { /* option type */ typedef struct { /* option type */
const char *name; /* option name */ const char *name; /* option name */
int format; /* option format (0:int,1:double,2:string,3:enum) */ int format; /* option format (0:int,1:double,2:string,3:enum) */
@ -869,6 +798,7 @@ typedef struct { /* option type */
const char *comment; /* option comment/enum labels/unit */ const char *comment; /* option comment/enum labels/unit */
} opt_t; } opt_t;
typedef struct { /* extended receiver error model */ typedef struct { /* extended receiver error model */
int ena[4]; /* model enabled */ int ena[4]; /* model enabled */
double cerr[4][NFREQ*2]; /* code errors (m) */ double cerr[4][NFREQ*2]; /* code errors (m) */
@ -877,11 +807,13 @@ typedef struct { /* extended receiver error model */
double gloicb [NFREQ]; /* glonass interchannel bias (m/fn) */ double gloicb [NFREQ]; /* glonass interchannel bias (m/fn) */
} exterr_t; } exterr_t;
typedef struct { /* SNR mask type */ typedef struct { /* SNR mask type */
int ena[2]; /* enable flag {rover,base} */ int ena[2]; /* enable flag {rover,base} */
double mask[NFREQ][9]; /* mask (dBHz) at 5,10,...85 deg */ double mask[NFREQ][9]; /* mask (dBHz) at 5,10,...85 deg */
} snrmask_t; } snrmask_t;
typedef struct { /* processing options type */ typedef struct { /* processing options type */
int mode; /* positioning mode (PMODE_???) */ int mode; /* positioning mode (PMODE_???) */
int soltype; /* solution type (0:forward,1:backward,2:combined) */ int soltype; /* solution type (0:forward,1:backward,2:combined) */
@ -944,6 +876,7 @@ typedef struct { /* processing options type */
char pppopt[256]; /* ppp option */ char pppopt[256]; /* ppp option */
} prcopt_t; } prcopt_t;
typedef struct { /* solution options type */ typedef struct { /* solution options type */
int posf; /* solution format (SOLF_???) */ int posf; /* solution format (SOLF_???) */
int times; /* time system (TIMES_???) */ int times; /* time system (TIMES_???) */
@ -966,7 +899,6 @@ typedef struct { /* solution options type */
} solopt_t; } solopt_t;
typedef struct { /* satellite status type */ typedef struct { /* satellite status type */
unsigned char sys; /* navigation system */ unsigned char sys; /* navigation system */
unsigned char vs; /* valid satellite flag single */ unsigned char vs; /* valid satellite flag single */
@ -990,6 +922,7 @@ typedef struct { /* satellite status type */
double ph[2][NFREQ]; /* previous carrier-phase observable (cycle) */ double ph[2][NFREQ]; /* previous carrier-phase observable (cycle) */
} ssat_t; } ssat_t;
typedef struct { /* ambiguity control type */ typedef struct { /* ambiguity control type */
gtime_t epoch[4]; /* last epoch */ gtime_t epoch[4]; /* last epoch */
int n[4]; /* number of epochs */ int n[4]; /* number of epochs */
@ -999,6 +932,7 @@ typedef struct { /* ambiguity control type */
char flags[MAXSAT]; /* fix flags */ char flags[MAXSAT]; /* fix flags */
} ambc_t; } ambc_t;
typedef struct { /* RTK control/result type */ typedef struct { /* RTK control/result type */
sol_t sol; /* RTK solution */ sol_t sol; /* RTK solution */
double rb[6]; /* base position/velocity (ecef) (m|m/s) */ double rb[6]; /* base position/velocity (ecef) (m|m/s) */
@ -1014,6 +948,7 @@ typedef struct { /* RTK control/result type */
prcopt_t opt; /* processing options */ prcopt_t opt; /* processing options */
} rtk_t; } rtk_t;
typedef struct half_cyc_tag { /* half-cycle correction list type */ typedef struct half_cyc_tag { /* half-cycle correction list type */
unsigned char sat; /* satellite number */ unsigned char sat; /* satellite number */
unsigned char freq; /* frequency number (0:L1,1:L2,2:L5) */ unsigned char freq; /* frequency number (0:L1,1:L2,2:L5) */
@ -1036,9 +971,11 @@ const double chisqr[100]={ /* chi-sqr(n) (alpha=0.001) */
126 , 127 , 128 , 129 , 131 , 132 , 133 , 134 , 135 , 137 , 126 , 127 , 128 , 129 , 131 , 132 , 133 , 134 , 135 , 137 ,
138 , 139 , 140 , 142 , 143 , 144 , 145 , 147 , 148 , 149 138 , 139 , 140 , 142 , 143 , 144 , 145 , 147 , 148 , 149
}; };
const double lam_carr[MAXFREQ] = { /* carrier wave length (m) */ const double lam_carr[MAXFREQ] = { /* carrier wave length (m) */
CLIGHT/FREQ1,CLIGHT/FREQ2,CLIGHT/FREQ5,CLIGHT/FREQ6,CLIGHT/FREQ7, SPEED_OF_LIGHT / FREQ1, SPEED_OF_LIGHT / FREQ2, SPEED_OF_LIGHT / FREQ5, SPEED_OF_LIGHT / FREQ6, SPEED_OF_LIGHT / FREQ7,
CLIGHT/FREQ8,CLIGHT/FREQ9 SPEED_OF_LIGHT / FREQ8, SPEED_OF_LIGHT / FREQ9
}; };
#endif #endif

View File

@ -46,13 +46,15 @@
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "rtklib_conversions.h" #include "rtklib_conversions.h"
obsd_t obs_to_rtklib(Gnss_Synchro gnss_synchro, int week) obsd_t obs_to_rtklib(Gnss_Synchro gnss_synchro, int week)
{ {
obsd_t rtklib_obs; obsd_t rtklib_obs = {};
rtklib_obs.D[0] = gnss_synchro.Carrier_Doppler_hz; rtklib_obs.D[0] = gnss_synchro.Carrier_Doppler_hz;
rtklib_obs.P[0] = gnss_synchro.Pseudorange_m; rtklib_obs.P[0] = gnss_synchro.Pseudorange_m;
rtklib_obs.L[0] = gnss_synchro.Carrier_phase_rads;//todo: check units rtklib_obs.L[0] = gnss_synchro.Carrier_phase_rads;//todo: check units
@ -62,9 +64,11 @@ obsd_t obs_to_rtklib(Gnss_Synchro gnss_synchro, int week)
//printf("OBS RX TIME [%i]: %s,%f\n\r",rtklib_obs.sat,time_str(rtklib_obs.time,3),rtklib_obs.time.sec); //printf("OBS RX TIME [%i]: %s,%f\n\r",rtklib_obs.sat,time_str(rtklib_obs.time,3),rtklib_obs.time.sec);
return rtklib_obs; return rtklib_obs;
} }
eph_t eph_to_rtklib(Galileo_Ephemeris gal_eph) eph_t eph_to_rtklib(Galileo_Ephemeris gal_eph)
{ {
eph_t rtklib_sat; eph_t rtklib_sat = {};
rtklib_sat.sat = gal_eph.i_satellite_PRN; rtklib_sat.sat = gal_eph.i_satellite_PRN;
rtklib_sat.A = gal_eph.A_1 * gal_eph.A_1; rtklib_sat.A = gal_eph.A_1 * gal_eph.A_1;
rtklib_sat.M0 = gal_eph.M0_1; rtklib_sat.M0 = gal_eph.M0_1;
@ -109,9 +113,10 @@ eph_t eph_to_rtklib(Galileo_Ephemeris gal_eph)
return rtklib_sat; return rtklib_sat;
} }
eph_t eph_to_rtklib(Gps_Ephemeris gps_eph) eph_t eph_to_rtklib(Gps_Ephemeris gps_eph)
{ {
eph_t rtklib_sat; eph_t rtklib_sat = {};
rtklib_sat.sat = gps_eph.i_satellite_PRN; rtklib_sat.sat = gps_eph.i_satellite_PRN;
rtklib_sat.A = gps_eph.d_sqrt_A * gps_eph.d_sqrt_A; rtklib_sat.A = gps_eph.d_sqrt_A * gps_eph.d_sqrt_A;
rtklib_sat.M0 = gps_eph.d_M_0; rtklib_sat.M0 = gps_eph.d_M_0;
@ -157,9 +162,11 @@ eph_t eph_to_rtklib(Gps_Ephemeris gps_eph)
return rtklib_sat; return rtklib_sat;
} }
eph_t eph_to_rtklib(Gps_CNAV_Ephemeris gps_cnav_eph) eph_t eph_to_rtklib(Gps_CNAV_Ephemeris gps_cnav_eph)
{ {
eph_t rtklib_sat; eph_t rtklib_sat = {};
rtklib_sat.sat = gps_cnav_eph.i_satellite_PRN; rtklib_sat.sat = gps_cnav_eph.i_satellite_PRN;
const double A_REF = 26559710.0; // See IS-GPS-200H, pp. 170 const double A_REF = 26559710.0; // See IS-GPS-200H, pp. 170
rtklib_sat.A = A_REF + gps_cnav_eph.d_DELTA_A; rtklib_sat.A = A_REF + gps_cnav_eph.d_DELTA_A;
@ -206,5 +213,4 @@ eph_t eph_to_rtklib(Gps_CNAV_Ephemeris gps_cnav_eph)
rtklib_sat.ttr = gpst2time(rtklib_sat.week, tow); rtklib_sat.ttr = gpst2time(rtklib_sat.week, tow);
return rtklib_sat; return rtklib_sat;
} }

View File

@ -47,8 +47,10 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
#ifndef SRC_ALGORITHMS_PVT_LIBS_RTKLIB_CONVERSIONS_H_
#define SRC_ALGORITHMS_PVT_LIBS_RTKLIB_CONVERSIONS_H_
#ifndef GNSS_SDR_RTKLIB_CONVERSIONS_H_
#define GNSS_SDR_RTKLIB_CONVERSIONS_H_
#include "rtklib_rtkcmn.h" #include "rtklib_rtkcmn.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
@ -62,4 +64,4 @@ eph_t eph_to_rtklib(Gps_CNAV_Ephemeris gps_cnav_eph);
obsd_t obs_to_rtklib(Gnss_Synchro gnss_synchro, int week); obsd_t obs_to_rtklib(Gnss_Synchro gnss_synchro, int week);
#endif /* SRC_ALGORITHMS_PVT_LIBS_RTKLIB_CONVERSIONS_H_ */ #endif /* GNSS_SDR_RTKLIB_CONVERSIONS_H_ */

View File

@ -47,69 +47,41 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* history : 2010/07/28 1.1 moved from rtkcmn.c */
* added api:
* eph2clk(),geph2clk(),seph2clk(),satantoff()
* satposs()
* changed api:
* eph2pos(),geph2pos(),satpos()
* deleted api:
* satposv(),satposiode()
* 2010/08/26 1.2 add ephemeris option EPHOPT_LEX
* 2010/09/09 1.3 fix problem when precise clock outage
* 2011/01/12 1.4 add api alm2pos()
* change api satpos(),satposs()
* enable valid unhealthy satellites and output status
* fix bug on exception by glonass ephem computation
* 2013/01/10 1.5 support beidou (compass)
* use newton's method to solve kepler eq.
* update ssr correction algorithm
* 2013/03/20 1.6 fix problem on ssr clock relativitic correction
* 2013/09/01 1.7 support negative pseudorange
* fix bug on variance in case of ura ssr = 63
* 2013/11/11 1.8 change constant MAXAGESSR 70.0 -> 90.0
* 2014/10/24 1.9 fix bug on return of var_uraeph() if ura<0||15<ura
* 2014/12/07 1.10 modify MAXDTOE for qzss,gal and bds
* test max number of iteration for Kepler
* 2015/08/26 1.11 update RTOL_ELPLER 1E-14 -> 1E-13
* set MAX_ITER_KEPLER for alm2pos()
*-----------------------------------------------------------------------------*/
#include "rtklib_ephemeris.h" #include "rtklib_ephemeris.h"
static const char rcsid[]="$Id:$";
/* constants and macros ------------------------------------------------------*/ /* constants ------------------------------------------------------*/
#define SQR(x) ((x)*(x)) const double RE_GLO = 6378136.0; /* radius of earth (m) ref [2] */
const double MU_GPS = 3.9860050e14; /* gravitational constant ref [1] */
const double MU_GLO = 3.9860044e14; /* gravitational constant ref [2] */
const double MU_GAL = 3.986004418e14; /* earth gravitational constant ref [7] */
const double MU_BDS = 3.986004418e14; /* earth gravitational constant ref [9] */
const double J2_GLO = 1.0826257e-3; /* 2nd zonal harmonic of geopot ref [2] */
#define RE_GLO 6378136.0 /* radius of earth (m) ref [2] */ const double OMGE_GLO = 7.292115e-5; /* earth angular velocity (rad/s) ref [2] */
#define MU_GPS 3.9860050E14 /* gravitational constant ref [1] */ const double OMGE_GAL = 7.2921151467e-5; /* earth angular velocity (rad/s) ref [7] */
#define MU_GLO 3.9860044E14 /* gravitational constant ref [2] */ const double OMGE_BDS = 7.292115e-5; /* earth angular velocity (rad/s) ref [9] */
#define MU_GAL 3.986004418E14 /* earth gravitational constant ref [7] */
#define MU_CMP 3.986004418E14 /* earth gravitational constant ref [9] */
#define J2_GLO 1.0826257E-3 /* 2nd zonal harmonic of geopot ref [2] */
#define OMGE_GLO 7.292115E-5 /* earth angular velocity (rad/s) ref [2] */ const double SIN_5 = -0.0871557427476582; /* sin(-5.0 deg) */
#define OMGE_GAL 7.2921151467E-5 /* earth angular velocity (rad/s) ref [7] */ const double COS_5 = 0.9961946980917456; /* cos(-5.0 deg) */
#define OMGE_CMP 7.292115E-5 /* earth angular velocity (rad/s) ref [9] */
#define SIN_5 -0.0871557427476582 /* sin(-5.0 deg) */ const double ERREPH_GLO = 5.0; /* error of glonass ephemeris (m) */
#define COS_5 0.9961946980917456 /* cos(-5.0 deg) */ const double TSTEP = 60.0; /* integration step glonass ephemeris (s) */
const double RTOL_KEPLER = 1e-13; /* relative tolerance for Kepler equation */
#define ERREPH_GLO 5.0 /* error of glonass ephemeris (m) */ const double DEFURASSR = 0.15; /* default accurary of ssr corr (m) */
#define TSTEP 60.0 /* integration step glonass ephemeris (s) */ const double MAXECORSSR = 10.0; /* max orbit correction of ssr (m) */
#define RTOL_KEPLER 1E-13 /* relative tolerance for Kepler equation */ const double MAXCCORSSR = 1e-6 * SPEED_OF_LIGHT; /* max clock correction of ssr (m) */
const double MAXAGESSR = 90.0; /* max age of ssr orbit and clock (s) */
const double MAXAGESSR_HRCLK = 10.0; /* max age of ssr high-rate clock (s) */
const double STD_BRDCCLK = 30.0; /* error of broadcast clock (m) */
#define DEFURASSR 0.15 /* default accurary of ssr corr (m) */ const int MAX_ITER_KEPLER = 30; /* max number of iteration of Kelpler */
#define MAXECORSSR 10.0 /* max orbit correction of ssr (m) */
#define MAXCCORSSR (1E-6*CLIGHT) /* max clock correction of ssr (m) */
#define MAXAGESSR 90.0 /* max age of ssr orbit and clock (s) */
#define MAXAGESSR_HRCLK 10.0 /* max age of ssr high-rate clock (s) */
#define STD_BRDCCLK 30.0 /* error of broadcast clock (m) */
#define MAX_ITER_KEPLER 30 /* max number of iteration of Kelpler */
/* variance by ura ephemeris (ref [1] 20.3.3.3.1.1) --------------------------*/ /* variance by ura ephemeris (ref [1] 20.3.3.3.1.1) --------------------------*/
double var_uraeph(int ura) double var_uraeph(int ura)
@ -118,17 +90,21 @@ double var_uraeph(int ura)
2.4, 3.4, 4.85, 6.85, 9.65, 13.65, 24.0, 48.0, 96.0, 192.0, 384.0, 768.0, 1536.0, 2.4, 3.4, 4.85, 6.85, 9.65, 13.65, 24.0, 48.0, 96.0, 192.0, 384.0, 768.0, 1536.0,
3072.0, 6144.0 3072.0, 6144.0
}; };
return ura<0||15<ura?SQR(6144.0):SQR(ura_value[ura]); return ura < 0 || 15 < ura ? std::pow(6144.0, 2.0) : std::pow(ura_value[ura], 2.0);
} }
/* variance by ura ssr (ref [4]) ---------------------------------------------*/ /* variance by ura ssr (ref [4]) ---------------------------------------------*/
double var_urassr(int ura) double var_urassr(int ura)
{ {
double std; double std_;
if (ura<= 0) return SQR(DEFURASSR); if (ura <= 0) return std::pow(DEFURASSR, 2.0);
if (ura>=63) return SQR(5.4665); if (ura >= 63) return std::pow(5.4665, 2.0);
std=(pow(3.0,(ura>>3)&7)*(1.0+(ura&7)/4.0)-1.0)*1E-3; std_ = (std::pow((ura >> 3) & 7, 2.0) * (1.0 + (ura & 7) / 4.0) - 1.0) * 1e-3;
return SQR(std); return std::pow(std_, 2.0);
} }
/* almanac to satellite position and clock bias -------------------------------- /* almanac to satellite position and clock bias --------------------------------
* compute satellite position and clock bias with almanac (gps, galileo, qzss) * compute satellite position and clock bias with almanac (gps, galileo, qzss)
* args : gtime_t time I time (gpst) * args : gtime_t time I time (gpst)
@ -147,31 +123,42 @@ void alm2pos(gtime_t time, const alm_t *alm, double *rs, double *dts)
tk = timediff(time, alm->toa); tk = timediff(time, alm->toa);
if (alm->A<=0.0) { if (alm->A <= 0.0)
{
rs[0] = rs[1] = rs[2] = *dts = 0.0; rs[0] = rs[1] = rs[2] = *dts = 0.0;
return; return;
} }
mu = satsys(alm->sat, NULL) == SYS_GAL ? MU_GAL : MU_GPS; mu = satsys(alm->sat, NULL) == SYS_GAL ? MU_GAL : MU_GPS;
M = alm->M0 + sqrt(mu / (alm->A * alm->A * alm->A)) * tk; M = alm->M0 + sqrt(mu / (alm->A * alm->A * alm->A)) * tk;
for (n=0,E=M,Ek=0.0;fabs(E-Ek)>RTOL_KEPLER&&n<MAX_ITER_KEPLER;n++) { for (n = 0, E = M, Ek = 0.0; fabs(E - Ek) > RTOL_KEPLER && n < MAX_ITER_KEPLER; n++)
Ek=E; E-=(E-alm->e*sin(E)-M)/(1.0-alm->e*cos(E)); {
Ek = E;
E -= (E - alm->e * sin(E) - M) / (1.0 - alm->e * cos(E));
} }
if (n>=MAX_ITER_KEPLER) { if (n >= MAX_ITER_KEPLER)
{
trace(2, "alm2pos: kepler iteration overflow sat=%2d\n", alm->sat); trace(2, "alm2pos: kepler iteration overflow sat=%2d\n", alm->sat);
return; return;
} }
sinE=sin(E); cosE=cos(E); sinE = sin(E);
cosE = cos(E);
u = atan2(sqrt(1.0 - alm->e * alm->e) * sinE, cosE - alm->e) + alm->omg; u = atan2(sqrt(1.0 - alm->e * alm->e) * sinE, cosE - alm->e) + alm->omg;
r = alm->A * (1.0 - alm->e*cosE); r = alm->A * (1.0 - alm->e*cosE);
i = alm->i0; i = alm->i0;
O=alm->OMG0+(alm->OMGd-OMGE)*tk-OMGE*alm->toas; O = alm->OMG0 + (alm->OMGd - DEFAULT_OMEGA_EARTH_DOT) * tk - DEFAULT_OMEGA_EARTH_DOT * alm->toas;
x=r*cos(u); y=r*sin(u); sinO=sin(O); cosO=cos(O); cosi=cos(i); x = r * cos(u);
y = r * sin(u);
sinO = sin(O);
cosO = cos(O);
cosi = cos(i);
rs[0] = x * cosO - y * cosi * sinO; rs[0] = x * cosO - y * cosi * sinO;
rs[1] = x * sinO + y * cosi * cosO; rs[1] = x * sinO + y * cosi * cosO;
rs[2] = y * sin(i); rs[2] = y * sin(i);
*dts = alm->f0 + alm->f1 * tk; *dts = alm->f0 + alm->f1 * tk;
} }
/* broadcast ephemeris to satellite clock bias --------------------------------- /* broadcast ephemeris to satellite clock bias ---------------------------------
* compute satellite clock bias with broadcast ephemeris (gps, galileo, qzss) * compute satellite clock bias with broadcast ephemeris (gps, galileo, qzss)
* args : gtime_t time I time by satellite clock (gpst) * args : gtime_t time I time by satellite clock (gpst)
@ -189,11 +176,14 @@ double eph2clk(gtime_t time, const eph_t *eph)
t = timediff(time, eph->toc); t = timediff(time, eph->toc);
for (i=0;i<2;i++) { for (i = 0; i < 2; i++)
{
t -= eph->f0 + eph->f1 * t + eph->f2 * t * t; t -= eph->f0 + eph->f1 * t + eph->f2 * t * t;
} }
return eph->f0 + eph->f1 * t + eph->f2 * t *t; return eph->f0 + eph->f1 * t + eph->f2 * t *t;
} }
/* broadcast ephemeris to satellite position and clock bias -------------------- /* broadcast ephemeris to satellite position and clock bias --------------------
* compute satellite position and clock bias with broadcast ephemeris (gps, * compute satellite position and clock bias with broadcast ephemeris (gps,
* galileo, qzss) * galileo, qzss)
@ -216,27 +206,33 @@ void eph2pos(gtime_t time, const eph_t *eph, double *rs, double *dts,
trace(4, "eph2pos : time=%s sat=%2d\n", time_str(time, 3), eph->sat); trace(4, "eph2pos : time=%s sat=%2d\n", time_str(time, 3), eph->sat);
if (eph->A<=0.0) { if (eph->A <= 0.0)
{
rs[0] = rs[1] = rs[2] = *dts = *var = 0.0; rs[0] = rs[1] = rs[2] = *dts = *var = 0.0;
return; return;
} }
tk = timediff(time , eph->toe); tk = timediff(time , eph->toe);
switch ((sys=satsys(eph->sat,&prn))) { switch ((sys = satsys(eph->sat, &prn)))
{
case SYS_GAL: mu = MU_GAL; omge = OMGE_GAL; break; case SYS_GAL: mu = MU_GAL; omge = OMGE_GAL; break;
case SYS_CMP: mu=MU_CMP; omge=OMGE_CMP; break; case SYS_BDS: mu = MU_BDS; omge = OMGE_BDS; break;
default: mu=MU_GPS; omge=OMGE; break; default: mu = MU_GPS; omge = DEFAULT_OMEGA_EARTH_DOT; break;
} }
M = eph->M0 + (sqrt(mu / (eph->A * eph->A * eph->A)) + eph->deln) * tk; M = eph->M0 + (sqrt(mu / (eph->A * eph->A * eph->A)) + eph->deln) * tk;
for (n=0,E=M,Ek=0.0;fabs(E-Ek)>RTOL_KEPLER&&n<MAX_ITER_KEPLER;n++) { for (n = 0, E = M, Ek = 0.0; fabs(E - Ek) > RTOL_KEPLER && n < MAX_ITER_KEPLER; n++)
Ek=E; E-=(E-eph->e*sin(E)-M)/(1.0-eph->e*cos(E)); {
Ek = E;
E -= (E - eph->e * sin(E) - M) / (1.0 - eph->e * cos(E));
} }
if (n>=MAX_ITER_KEPLER) { if (n >= MAX_ITER_KEPLER)
{
trace(2, "eph2pos: kepler iteration overflow sat=%2d\n", eph->sat); trace(2, "eph2pos: kepler iteration overflow sat=%2d\n", eph->sat);
return; return;
} }
sinE=sin(E); cosE=cos(E); sinE = sin(E);
cosE = cos(E);
trace(4, "kepler: sat=%2d e=%8.5f n=%2d del=%10.3e\n", eph->sat, eph->e, n, E - Ek); trace(4, "kepler: sat=%2d e=%8.5f n=%2d del=%10.3e\n", eph->sat, eph->e, n, E - Ek);
@ -247,23 +243,30 @@ void eph2pos(gtime_t time, const eph_t *eph, double *rs, double *dts,
u += eph->cus * sin2u + eph->cuc * cos2u; u += eph->cus * sin2u + eph->cuc * cos2u;
r += eph->crs * sin2u + eph->crc * cos2u; r += eph->crs * sin2u + eph->crc * cos2u;
i += eph->cis * sin2u + eph->cic * cos2u; i += eph->cis * sin2u + eph->cic * cos2u;
x=r*cos(u); y=r*sin(u); cosi=cos(i); x = r * cos(u);
y = r * sin(u);
cosi = cos(i);
/* beidou geo satellite (ref [9]) */ /* beidou geo satellite (ref [9]) */
if (sys==SYS_CMP&&prn<=5) { if (sys == SYS_BDS && prn <= 5)
{
O = eph->OMG0 + eph->OMGd * tk - omge * eph->toes; O = eph->OMG0 + eph->OMGd * tk - omge * eph->toes;
sinO=sin(O); cosO=cos(O); sinO = sin(O);
cosO = cos(O);
xg = x * cosO - y * cosi * sinO; xg = x * cosO - y * cosi * sinO;
yg = x * sinO + y * cosi * cosO; yg = x * sinO + y * cosi * cosO;
zg = y * sin(i); zg = y * sin(i);
sino=sin(omge*tk); coso=cos(omge*tk); sino = sin(omge * tk);
coso = cos(omge * tk);
rs[0] = xg * coso + yg * sino * COS_5 + zg * sino * SIN_5; rs[0] = xg * coso + yg * sino * COS_5 + zg * sino * SIN_5;
rs[1] = -xg * sino + yg * coso * COS_5 + zg * coso * SIN_5; rs[1] = -xg * sino + yg * coso * COS_5 + zg * coso * SIN_5;
rs[2] = -yg * SIN_5 + zg * COS_5; rs[2] = -yg * SIN_5 + zg * COS_5;
} }
else { else
{
O = eph->OMG0 + (eph->OMGd - omge) * tk - omge * eph->toes; O = eph->OMG0 + (eph->OMGd - omge) * tk - omge * eph->toes;
sinO=sin(O); cosO=cos(O); sinO = sin(O);
cosO = cos(O);
rs[0] = x * cosO - y * cosi * sinO; rs[0] = x * cosO - y * cosi * sinO;
rs[1] = x * sinO + y *cosi * cosO; rs[1] = x * sinO + y *cosi * cosO;
rs[2] = y * sin(i); rs[2] = y * sin(i);
@ -272,29 +275,35 @@ void eph2pos(gtime_t time, const eph_t *eph, double *rs, double *dts,
*dts = eph->f0 + eph->f1 * tk + eph->f2 * tk * tk; *dts = eph->f0 + eph->f1 * tk + eph->f2 * tk * tk;
/* relativity correction */ /* relativity correction */
*dts-=2.0*sqrt(mu*eph->A)*eph->e*sinE/SQR(CLIGHT); *dts -= 2.0 * sqrt(mu * eph->A) * eph-> e* sinE / std::pow(SPEED_OF_LIGHT, 2.0);
/* position and clock error variance */ /* position and clock error variance */
*var = var_uraeph(eph->sva); *var = var_uraeph(eph->sva);
} }
/* glonass orbit differential equations --------------------------------------*/ /* glonass orbit differential equations --------------------------------------*/
void deq(const double *x, double *xdot, const double *acc) void deq(const double *x, double *xdot, const double *acc)
{ {
double a,b,c,r2=dot(x,x,3),r3=r2*sqrt(r2),omg2=SQR(OMGE_GLO); double a, b, c, r2 = dot(x, x, 3), r3 = r2 * sqrt(r2), omg2 = std::pow(OMGE_GLO, 2.0);
if (r2<=0.0) { if (r2 <= 0.0)
{
xdot[0] = xdot[1] = xdot[2] = xdot[3] = xdot[4] = xdot[5] = 0.0; xdot[0] = xdot[1] = xdot[2] = xdot[3] = xdot[4] = xdot[5] = 0.0;
return; return;
} }
/* ref [2] A.3.1.2 with bug fix for xdot[4],xdot[5] */ /* ref [2] A.3.1.2 with bug fix for xdot[4],xdot[5] */
a=1.5*J2_GLO*MU_GLO*SQR(RE_GLO)/r2/r3; /* 3/2*J2*mu*Ae^2/r^5 */ a = 1.5 * J2_GLO * MU_GLO * std::pow(RE_GLO, 2.0) / r2 / r3; /* 3/2*J2*mu*Ae^2/r^5 */
b = 5.0 * x[2] * x[2] / r2; /* 5*z^2/r^2 */ b = 5.0 * x[2] * x[2] / r2; /* 5*z^2/r^2 */
c = -MU_GLO / r3 - a * (1.0 - b); /* -mu/r^3-a(1-b) */ c = -MU_GLO / r3 - a * (1.0 - b); /* -mu/r^3-a(1-b) */
xdot[0]=x[3]; xdot[1]=x[4]; xdot[2]=x[5]; xdot[0] = x[3];
xdot[1] = x[4]; xdot[2] = x[5];
xdot[3] = (c + omg2) * x[0] + 2.0 * OMGE_GLO * x[4] + acc[0]; xdot[3] = (c + omg2) * x[0] + 2.0 * OMGE_GLO * x[4] + acc[0];
xdot[4] = (c + omg2) * x[1] - 2.0 * OMGE_GLO * x[3] + acc[1]; xdot[4] = (c + omg2) * x[1] - 2.0 * OMGE_GLO * x[3] + acc[1];
xdot[5] = (c - 2.0 * a) * x[2] + acc[2]; xdot[5] = (c - 2.0 * a) * x[2] + acc[2];
} }
/* glonass position and velocity by numerical integration --------------------*/ /* glonass position and velocity by numerical integration --------------------*/
void glorbit(double t, double *x, const double *acc) void glorbit(double t, double *x, const double *acc)
{ {
@ -307,6 +316,8 @@ void glorbit(double t, double *x, const double *acc)
deq(w, k4, acc); deq(w, k4, acc);
for (i = 0; i < 6; i++) x[i] += (k1[i] + 2.0 * k2[i] + 2.0 * k3[i] + k4[i]) * t / 6.0; for (i = 0; i < 6; i++) x[i] += (k1[i] + 2.0 * k2[i] + 2.0 * k3[i] + k4[i]) * t / 6.0;
} }
/* glonass ephemeris to satellite clock bias ----------------------------------- /* glonass ephemeris to satellite clock bias -----------------------------------
* compute satellite clock bias with glonass ephemeris * compute satellite clock bias with glonass ephemeris
* args : gtime_t time I time by satellite clock (gpst) * args : gtime_t time I time by satellite clock (gpst)
@ -323,11 +334,14 @@ double geph2clk(gtime_t time, const geph_t *geph)
t = timediff(time, geph->toe); t = timediff(time, geph->toe);
for (i=0;i<2;i++) { for (i = 0; i < 2; i++)
{
t -= -geph->taun + geph->gamn * t; t -= -geph->taun + geph->gamn * t;
} }
return -geph->taun + geph->gamn * t; return -geph->taun + geph->gamn * t;
} }
/* glonass ephemeris to satellite position and clock bias ---------------------- /* glonass ephemeris to satellite position and clock bias ----------------------
* compute satellite position and clock bias with glonass ephemeris * compute satellite position and clock bias with glonass ephemeris
* args : gtime_t time I time (gpst) * args : gtime_t time I time (gpst)
@ -350,18 +364,22 @@ void geph2pos(gtime_t time, const geph_t *geph, double *rs, double *dts,
*dts = -geph->taun + geph->gamn * t; *dts = -geph->taun + geph->gamn * t;
for (i=0;i<3;i++) { for (i = 0; i < 3; i++)
{
x[i ] = geph->pos[i]; x[i ] = geph->pos[i];
x[i+3] = geph->vel[i]; x[i+3] = geph->vel[i];
} }
for (tt=t<0.0?-TSTEP:TSTEP;fabs(t)>1E-9;t-=tt) { for (tt = t < 0.0 ? - TSTEP : TSTEP; fabs(t) > 1e-9; t -= tt)
{
if (fabs(t) < TSTEP) tt = t; if (fabs(t) < TSTEP) tt = t;
glorbit(tt, x, geph->acc); glorbit(tt, x, geph->acc);
} }
for (i = 0; i < 3; i++) rs[i] = x[i]; for (i = 0; i < 3; i++) rs[i] = x[i];
*var=SQR(ERREPH_GLO); *var = std::pow(ERREPH_GLO, 2.0);
} }
/* sbas ephemeris to satellite clock bias -------------------------------------- /* sbas ephemeris to satellite clock bias --------------------------------------
* compute satellite clock bias with sbas ephemeris * compute satellite clock bias with sbas ephemeris
* args : gtime_t time I time by satellite clock (gpst) * args : gtime_t time I time by satellite clock (gpst)
@ -378,11 +396,14 @@ double seph2clk(gtime_t time, const seph_t *seph)
t = timediff(time, seph->t0); t = timediff(time, seph->t0);
for (i=0;i<2;i++) { for (i = 0; i < 2; i++)
{
t-=seph->af0 + seph->af1 * t; t-=seph->af0 + seph->af1 * t;
} }
return seph->af0 + seph->af1 * t; return seph->af0 + seph->af1 * t;
} }
/* sbas ephemeris to satellite position and clock bias ------------------------- /* sbas ephemeris to satellite position and clock bias -------------------------
* compute satellite position and clock bias with sbas ephemeris * compute satellite position and clock bias with sbas ephemeris
* args : gtime_t time I time (gpst) * args : gtime_t time I time (gpst)
@ -403,13 +424,16 @@ void seph2pos(gtime_t time, const seph_t *seph, double *rs, double *dts,
t = timediff(time, seph->t0); t = timediff(time, seph->t0);
for (i=0;i<3;i++) { for (i = 0; i < 3; i++)
{
rs[i] = seph->pos[i] + seph->vel[i] * t + seph->acc[i] * t * t / 2.0; rs[i] = seph->pos[i] + seph->vel[i] * t + seph->acc[i] * t * t / 2.0;
} }
*dts = seph->af0 + seph->af1 * t; *dts = seph->af0 + seph->af1 * t;
*var = var_uraeph(seph->sva); *var = var_uraeph(seph->sva);
} }
/* select ephememeris --------------------------------------------------------*/ /* select ephememeris --------------------------------------------------------*/
eph_t *seleph(gtime_t time, int sat, int iode, const nav_t *nav) eph_t *seleph(gtime_t time, int sat, int iode, const nav_t *nav)
{ {
@ -418,28 +442,33 @@ eph_t *seleph(gtime_t time, int sat, int iode, const nav_t *nav)
trace(4, "seleph : time=%s sat=%2d iode=%d\n", time_str(time, 3), sat, iode); trace(4, "seleph : time=%s sat=%2d iode=%d\n", time_str(time, 3), sat, iode);
switch (satsys(sat,NULL)) { switch (satsys(sat, NULL))
{
case SYS_QZS: tmax = MAXDTOE_QZS + 1.0; break; case SYS_QZS: tmax = MAXDTOE_QZS + 1.0; break;
case SYS_GAL: tmax = MAXDTOE_GAL + 1.0; break; case SYS_GAL: tmax = MAXDTOE_GAL + 1.0; break;
case SYS_CMP: tmax=MAXDTOE_CMP+1.0; break; case SYS_BDS: tmax = MAXDTOE_BDS + 1.0; break;
default: tmax = MAXDTOE + 1.0; break; default: tmax = MAXDTOE + 1.0; break;
} }
tmin = tmax + 1.0; tmin = tmax + 1.0;
for (i=0;i<nav->n;i++) { for (i = 0; i < nav->n; i++)
{
if (nav->eph[i].sat != sat) continue; if (nav->eph[i].sat != sat) continue;
if (iode >= 0 && nav->eph[i].iode != iode) continue; if (iode >= 0 && nav->eph[i].iode != iode) continue;
if ((t = fabs(timediff(nav->eph[i].toe, time))) > tmax) continue; if ((t = fabs(timediff(nav->eph[i].toe, time))) > tmax) continue;
if (iode >= 0) return nav->eph + i; if (iode >= 0) return nav->eph + i;
if (t <= tmin) {j = i; tmin = t;} /* toe closest to time */ if (t <= tmin) {j = i; tmin = t;} /* toe closest to time */
} }
if (iode>=0||j<0) { if (iode >= 0 || j<0)
{
trace(3, "no broadcast ephemeris: %s sat=%2d iode=%3d\n", time_str(time, 0), trace(3, "no broadcast ephemeris: %s sat=%2d iode=%3d\n", time_str(time, 0),
sat, iode); sat, iode);
return NULL; return NULL;
} }
return nav->eph + j; return nav->eph + j;
} }
/* select glonass ephememeris ------------------------------------------------*/ /* select glonass ephememeris ------------------------------------------------*/
geph_t *selgeph(gtime_t time, int sat, int iode, const nav_t *nav) geph_t *selgeph(gtime_t time, int sat, int iode, const nav_t *nav)
{ {
@ -448,20 +477,24 @@ geph_t *selgeph(gtime_t time, int sat, int iode, const nav_t *nav)
trace(4, "selgeph : time=%s sat=%2d iode=%2d\n", time_str(time, 3), sat, iode); trace(4, "selgeph : time=%s sat=%2d iode=%2d\n", time_str(time, 3), sat, iode);
for (i=0;i<nav->ng;i++) { for (i = 0; i < nav->ng; i++)
{
if (nav->geph[i].sat != sat) continue; if (nav->geph[i].sat != sat) continue;
if (iode >= 0 && nav->geph[i].iode != iode) continue; if (iode >= 0 && nav->geph[i].iode != iode) continue;
if ((t = fabs(timediff(nav->geph[i].toe, time))) > tmax) continue; if ((t = fabs(timediff(nav->geph[i].toe, time))) > tmax) continue;
if (iode >= 0) return nav->geph + i; if (iode >= 0) return nav->geph + i;
if (t <= tmin) {j = i; tmin = t;} /* toe closest to time */ if (t <= tmin) {j = i; tmin = t;} /* toe closest to time */
} }
if (iode>=0||j<0) { if (iode >= 0 || j < 0)
{
trace(3, "no glonass ephemeris : %s sat=%2d iode=%2d\n", time_str(time, 0), trace(3, "no glonass ephemeris : %s sat=%2d iode=%2d\n", time_str(time, 0),
sat, iode); sat, iode);
return NULL; return NULL;
} }
return nav->geph + j; return nav->geph + j;
} }
/* select sbas ephememeris ---------------------------------------------------*/ /* select sbas ephememeris ---------------------------------------------------*/
seph_t *selseph(gtime_t time, int sat, const nav_t *nav) seph_t *selseph(gtime_t time, int sat, const nav_t *nav)
{ {
@ -470,17 +503,21 @@ seph_t *selseph(gtime_t time, int sat, const nav_t *nav)
trace(4, "selseph : time=%s sat=%2d\n", time_str(time, 3), sat); trace(4, "selseph : time=%s sat=%2d\n", time_str(time, 3), sat);
for (i=0;i<nav->ns;i++) { for (i = 0; i < nav->ns; i++)
{
if (nav->seph[i].sat != sat) continue; if (nav->seph[i].sat != sat) continue;
if ((t = fabs(timediff(nav->seph[i].t0, time))) > tmax) continue; if ((t = fabs(timediff(nav->seph[i].t0, time))) > tmax) continue;
if (t <= tmin) {j = i; tmin = t;} /* toe closest to time */ if (t <= tmin) {j = i; tmin = t;} /* toe closest to time */
} }
if (j<0) { if (j < 0)
{
trace(3, "no sbas ephemeris : %s sat=%2d\n", time_str(time, 0), sat); trace(3, "no sbas ephemeris : %s sat=%2d\n", time_str(time, 0), sat);
return NULL; return NULL;
} }
return nav->seph + j; return nav->seph + j;
} }
/* satellite clock with broadcast ephemeris ----------------------------------*/ /* satellite clock with broadcast ephemeris ----------------------------------*/
int ephclk(gtime_t time, gtime_t teph, int sat, const nav_t *nav, int ephclk(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
double *dts) double *dts)
@ -494,15 +531,18 @@ int ephclk(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
sys = satsys(sat, NULL); sys = satsys(sat, NULL);
if (sys==SYS_GPS||sys==SYS_GAL||sys==SYS_QZS||sys==SYS_CMP) { if (sys == SYS_GPS || sys == SYS_GAL || sys == SYS_QZS || sys == SYS_BDS)
{
if (!(eph = seleph(teph, sat, -1, nav))) return 0; if (!(eph = seleph(teph, sat, -1, nav))) return 0;
*dts = eph2clk(time, eph); *dts = eph2clk(time, eph);
} }
else if (sys==SYS_GLO) { else if (sys == SYS_GLO)
{
if (!(geph = selgeph(teph, sat, -1, nav))) return 0; if (!(geph = selgeph(teph, sat, -1, nav))) return 0;
*dts = geph2clk(time, geph); *dts = geph2clk(time, geph);
} }
else if (sys==SYS_SBS) { else if (sys == SYS_SBS)
{
if (!(seph = selseph(teph, sat, nav))) return 0; if (!(seph = selseph(teph, sat, nav))) return 0;
*dts = seph2clk(time, seph); *dts = seph2clk(time, seph);
} }
@ -510,6 +550,8 @@ int ephclk(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
return 1; return 1;
} }
/* satellite position and clock by broadcast ephemeris -----------------------*/ /* satellite position and clock by broadcast ephemeris -----------------------*/
int ephpos(gtime_t time, gtime_t teph, int sat, const nav_t *nav, int ephpos(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
int iode, double *rs, double *dts, double *var, int *svh) int iode, double *rs, double *dts, double *var, int *svh)
@ -517,7 +559,7 @@ int ephpos(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
eph_t *eph; eph_t *eph;
geph_t *geph; geph_t *geph;
seph_t *seph; seph_t *seph;
double rst[3],dtst[1],tt=1E-3; double rst[3], dtst[1], tt = 1e-3;
int i, sys; int i, sys;
trace(4, "ephpos : time=%s sat=%2d iode=%d\n", time_str(time, 3), sat, iode); trace(4, "ephpos : time=%s sat=%2d iode=%d\n", time_str(time, 3), sat, iode);
@ -526,7 +568,8 @@ int ephpos(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
*svh = -1; *svh = -1;
if (sys==SYS_GPS||sys==SYS_GAL||sys==SYS_QZS||sys==SYS_CMP) { if (sys == SYS_GPS || sys == SYS_GAL || sys == SYS_QZS || sys == SYS_BDS)
{
if (!(eph = seleph(teph, sat, iode, nav))) return 0; if (!(eph = seleph(teph, sat, iode, nav))) return 0;
eph2pos(time, eph, rs, dts, var); eph2pos(time, eph, rs, dts, var);
@ -534,14 +577,16 @@ int ephpos(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
eph2pos(time, eph, rst, dtst, var); eph2pos(time, eph, rst, dtst, var);
*svh = eph->svh; *svh = eph->svh;
} }
else if (sys==SYS_GLO) { else if (sys == SYS_GLO)
{
if (!(geph = selgeph(teph, sat, iode, nav))) return 0; if (!(geph = selgeph(teph, sat, iode, nav))) return 0;
geph2pos(time, geph, rs, dts, var); geph2pos(time, geph, rs, dts, var);
time = timeadd(time, tt); time = timeadd(time, tt);
geph2pos(time, geph, rst, dtst, var); geph2pos(time, geph, rst, dtst, var);
*svh = geph->svh; *svh = geph->svh;
} }
else if (sys==SYS_SBS) { else if (sys == SYS_SBS)
{
if (!(seph = selseph(teph, sat, nav))) return 0; if (!(seph = selseph(teph, sat, nav))) return 0;
seph2pos(time, seph, rs, dts, var); seph2pos(time, seph, rs, dts, var);
@ -557,6 +602,8 @@ int ephpos(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
return 1; return 1;
} }
/* satellite position and clock with sbas correction -------------------------*/ /* satellite position and clock with sbas correction -------------------------*/
int satpos_sbas(gtime_t time, gtime_t teph, int sat, const nav_t *nav, int satpos_sbas(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
double *rs, double *dts, double *var, int *svh) double *rs, double *dts, double *var, int *svh)
@ -567,11 +614,13 @@ int satpos_sbas(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
trace(4, "satpos_sbas: time=%s sat=%2d\n", time_str(time, 3), sat); trace(4, "satpos_sbas: time=%s sat=%2d\n", time_str(time, 3), sat);
/* search sbas satellite correciton */ /* search sbas satellite correciton */
for (i=0;i<nav->sbssat.nsat;i++) { for (i = 0; i < nav->sbssat.nsat; i++)
{
sbs = nav->sbssat.sat + i; sbs = nav->sbssat.sat + i;
if (sbs->sat == sat) break; if (sbs->sat == sat) break;
} }
if (i>=nav->sbssat.nsat) { if (i >= nav->sbssat.nsat)
{
trace(2, "no sbas correction for orbit: %s sat=%2d\n", time_str(time, 0), sat); trace(2, "no sbas correction for orbit: %s sat=%2d\n", time_str(time, 0), sat);
ephpos(time, teph, sat, nav, -1, rs, dts, var, svh); ephpos(time, teph, sat, nav, -1, rs, dts, var, svh);
*svh = -1; *svh = -1;
@ -585,6 +634,8 @@ int satpos_sbas(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
*svh = -1; *svh = -1;
return 0; return 0;
} }
/* satellite position and clock with ssr correction --------------------------*/ /* satellite position and clock with ssr correction --------------------------*/
int satpos_ssr(gtime_t time, gtime_t teph, int sat, const nav_t *nav, int satpos_ssr(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
int opt, double *rs, double *dts, double *var, int *svh) int opt, double *rs, double *dts, double *var, int *svh)
@ -598,16 +649,19 @@ int satpos_ssr(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
ssr = nav->ssr + sat - 1; ssr = nav->ssr + sat - 1;
if (!ssr->t0[0].time) { if (!ssr->t0[0].time)
{
trace(2, "no ssr orbit correction: %s sat=%2d\n", time_str(time, 0), sat); trace(2, "no ssr orbit correction: %s sat=%2d\n", time_str(time, 0), sat);
return 0; return 0;
} }
if (!ssr->t0[1].time) { if (!ssr->t0[1].time)
{
trace(2, "no ssr clock correction: %s sat=%2d\n", time_str(time, 0), sat); trace(2, "no ssr clock correction: %s sat=%2d\n", time_str(time, 0), sat);
return 0; return 0;
} }
/* inconsistency between orbit and clock correction */ /* inconsistency between orbit and clock correction */
if (ssr->iod[0]!=ssr->iod[1]) { if (ssr->iod[0] != ssr->iod[1])
{
trace(2, "inconsist ssr correction: %s sat=%2d iod=%d %d\n", trace(2, "inconsist ssr correction: %s sat=%2d iod=%d %d\n",
time_str(time, 0), sat, ssr->iod[0], ssr->iod[1]); time_str(time, 0), sat, ssr->iod[0], ssr->iod[1]);
*svh = -1; *svh = -1;
@ -618,7 +672,8 @@ int satpos_ssr(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
t3 = timediff(time, ssr->t0[2]); t3 = timediff(time, ssr->t0[2]);
/* ssr orbit and clock correction (ref [4]) */ /* ssr orbit and clock correction (ref [4]) */
if (fabs(t1)>MAXAGESSR||fabs(t2)>MAXAGESSR) { if (fabs(t1) > MAXAGESSR || fabs(t2) > MAXAGESSR)
{
trace(2, "age of ssr error: %s sat=%2d t=%.0f %.0f\n", time_str(time, 0), trace(2, "age of ssr error: %s sat=%2d t=%.0f %.0f\n", time_str(time, 0),
sat, t1, t2); sat, t1, t2);
*svh = -1; *svh = -1;
@ -631,10 +686,12 @@ int satpos_ssr(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
dclk = ssr->dclk[0] + ssr->dclk[1] * t2 + ssr->dclk[2] * t2 * t2; dclk = ssr->dclk[0] + ssr->dclk[1] * t2 + ssr->dclk[2] * t2 * t2;
/* ssr highrate clock correction (ref [4]) */ /* ssr highrate clock correction (ref [4]) */
if (ssr->iod[0]==ssr->iod[2]&&ssr->t0[2].time&&fabs(t3)<MAXAGESSR_HRCLK) { if (ssr->iod[0] == ssr->iod[2] && ssr->t0[2].time && fabs(t3) < MAXAGESSR_HRCLK)
{
dclk += ssr->hrclk; dclk += ssr->hrclk;
} }
if (norm(deph,3)>MAXECORSSR||fabs(dclk)>MAXCCORSSR) { if (norm(deph, 3) > MAXECORSSR || fabs(dclk) > MAXCCORSSR)
{
trace(3, "invalid ssr correction: %s deph=%.1f dclk=%.1f\n", trace(3, "invalid ssr correction: %s deph=%.1f dclk=%.1f\n",
time_str(time, 0), norm(deph, 3), dclk); time_str(time, 0), norm(deph, 3), dclk);
*svh = -1; *svh = -1;
@ -645,7 +702,8 @@ int satpos_ssr(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
/* satellite clock for gps, galileo and qzss */ /* satellite clock for gps, galileo and qzss */
sys = satsys(sat, NULL); sys = satsys(sat, NULL);
if (sys==SYS_GPS||sys==SYS_GAL||sys==SYS_QZS||sys==SYS_CMP) { if (sys == SYS_GPS || sys == SYS_GAL || sys == SYS_QZS || sys == SYS_BDS)
{
if (!(eph = seleph(teph, sat, ssr->iode, nav))) return 0; if (!(eph = seleph(teph, sat, ssr->iode, nav))) return 0;
/* satellite clock by clock parameters */ /* satellite clock by clock parameters */
@ -654,26 +712,29 @@ int satpos_ssr(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
dts[1] = eph->f1 + 2.0*eph->f2 * tk; dts[1] = eph->f1 + 2.0*eph->f2 * tk;
/* relativity correction */ /* relativity correction */
dts[0]-=2.0*dot(rs,rs+3,3)/CLIGHT/CLIGHT; dts[0] -= 2.0 * dot(rs, rs + 3, 3) / SPEED_OF_LIGHT / SPEED_OF_LIGHT;
} }
/* radial-along-cross directions in ecef */ /* radial-along-cross directions in ecef */
if (!normv3(rs + 3, ea)) return 0; if (!normv3(rs + 3, ea)) return 0;
cross3(rs, rs + 3, rc); cross3(rs, rs + 3, rc);
if (!normv3(rc,ec)) { if (!normv3(rc, ec))
{
*svh = -1; *svh = -1;
return 0; return 0;
} }
cross3(ea, ec, er); cross3(ea, ec, er);
/* satellite antenna offset correction */ /* satellite antenna offset correction */
if (opt) { if (opt)
{
satantoff(time, rs, sat, nav, dant); satantoff(time, rs, sat, nav, dant);
} }
for (i=0;i<3;i++) { for (i = 0; i < 3; i++)
{
rs[i] += -(er[i] * deph[0] + ea[i] * deph[1] + ec[i] * deph[2]) + dant[i]; rs[i] += -(er[i] * deph[0] + ea[i] * deph[1] + ec[i] * deph[2]) + dant[i];
} }
/* t_corr = t_sv - (dts(brdc) + dclk(ssr) / CLIGHT) (ref [10] eq.3.12-7) */ /* t_corr = t_sv - (dts(brdc) + dclk(ssr) / SPEED_OF_LIGHT) (ref [10] eq.3.12-7) */
dts[0]+=dclk/CLIGHT; dts[0] += dclk / SPEED_OF_LIGHT;
/* variance by ssr ura */ /* variance by ssr ura */
*var = var_urassr(ssr->ura); *var = var_urassr(ssr->ura);
@ -683,6 +744,8 @@ int satpos_ssr(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
return 1; return 1;
} }
/* satellite position and clock ------------------------------------------------ /* satellite position and clock ------------------------------------------------
* compute satellite position, velocity and clock * compute satellite position, velocity and clock
* args : gtime_t time I time (gpst) * args : gtime_t time I time (gpst)
@ -707,7 +770,8 @@ int satpos(gtime_t time, gtime_t teph, int sat, int ephopt,
*svh = 0; *svh = 0;
switch (ephopt) { switch (ephopt)
{
case EPHOPT_BRDC : return ephpos (time, teph, sat, nav, -1, rs, dts, var, svh); case EPHOPT_BRDC : return ephpos (time, teph, sat, nav, -1, rs, dts, var, svh);
case EPHOPT_SBAS : return satpos_sbas(time, teph, sat, nav, rs, dts, var, svh); case EPHOPT_SBAS : return satpos_sbas(time, teph, sat, nav, rs, dts, var, svh);
case EPHOPT_SSRAPC: return satpos_ssr (time, teph, sat, nav, 0, rs, dts, var, svh); case EPHOPT_SSRAPC: return satpos_ssr (time, teph, sat, nav, 0, rs, dts, var, svh);
@ -721,6 +785,8 @@ int satpos(gtime_t time, gtime_t teph, int sat, int ephopt,
*svh = -1; *svh = -1;
return 0; return 0;
} }
/* satellite positions and clocks ---------------------------------------------- /* satellite positions and clocks ----------------------------------------------
* compute satellite positions, velocities and clocks * compute satellite positions, velocities and clocks
* args : gtime_t teph I time to select ephemeris (gpst) * args : gtime_t teph I time to select ephemeris (gpst)
@ -754,23 +820,27 @@ void satposs(gtime_t teph, const obsd_t *obs, int n, const nav_t *nav,
trace(3, "satposs : teph=%s n=%d ephopt=%d\n", time_str(teph, 3), n, ephopt); trace(3, "satposs : teph=%s n=%d ephopt=%d\n", time_str(teph, 3), n, ephopt);
for (i=0;i<n&&i<MAXOBS;i++) { for (i = 0; i < n && i < MAXOBS; i++)
{
for (j = 0; j < 6; j++) rs [j + i * 6] = 0.0; for (j = 0; j < 6; j++) rs [j + i * 6] = 0.0;
for (j = 0; j < 2; j++) dts[j + i * 2] = 0.0; for (j = 0; j < 2; j++) dts[j + i * 2] = 0.0;
var[i]=0.0; svh[i]=0; var[i] = 0.0;
svh[i] = 0;
/* search any psuedorange */ /* search any pseudorange */
for (j = 0, pr = 0.0; j < NFREQ; j++) if ((pr = obs[i].P[j]) != 0.0) break; for (j = 0, pr = 0.0; j < NFREQ; j++) if ((pr = obs[i].P[j]) != 0.0) break;
if (j>=NFREQ) { if (j >= NFREQ)
{
trace(2, "no pseudorange %s sat=%2d\n", time_str(obs[i].time, 3), obs[i].sat); trace(2, "no pseudorange %s sat=%2d\n", time_str(obs[i].time, 3), obs[i].sat);
continue; continue;
} }
/* transmission time by satellite clock */ /* transmission time by satellite clock */
time[i]=timeadd(obs[i].time,-pr/CLIGHT); time[i] = timeadd(obs[i].time, -pr / SPEED_OF_LIGHT);
/* satellite clock bias by broadcast ephemeris */ /* satellite clock bias by broadcast ephemeris */
if (!ephclk(time[i],teph,obs[i].sat,nav,&dt)) { if (!ephclk(time[i], teph, obs[i].sat, nav, &dt))
{
trace(3, "no broadcast clock %s sat=%2d\n", time_str(time[i], 3), obs[i].sat); trace(3, "no broadcast clock %s sat=%2d\n", time_str(time[i], 3), obs[i].sat);
continue; continue;
} }
@ -778,20 +848,23 @@ void satposs(gtime_t teph, const obsd_t *obs, int n, const nav_t *nav,
/* satellite position and clock at transmission time */ /* satellite position and clock at transmission time */
if (!satpos(time[i], teph, obs[i].sat, ephopt, nav, rs + i * 6, dts + i * 2, var + i, if (!satpos(time[i], teph, obs[i].sat, ephopt, nav, rs + i * 6, dts + i * 2, var + i,
svh+i)) { svh + i))
{
trace(3, "no ephemeris %s sat=%2d\n", time_str(time[i], 3), obs[i].sat); trace(3, "no ephemeris %s sat=%2d\n", time_str(time[i], 3), obs[i].sat);
continue; continue;
} }
/* if no precise clock available, use broadcast clock instead */ /* if no precise clock available, use broadcast clock instead */
if (dts[i*2]==0.0) { if (dts[i * 2] == 0.0)
{
if (!ephclk(time[i], teph, obs[i].sat, nav, dts + i * 2)) continue; if (!ephclk(time[i], teph, obs[i].sat, nav, dts + i * 2)) continue;
dts[1 + i * 2] = 0.0; dts[1 + i * 2] = 0.0;
*var=SQR(STD_BRDCCLK); *var = std::pow(STD_BRDCCLK, 2.0);
} }
} }
for (i=0;i<n&&i<MAXOBS;i++) { for (i = 0; i < n && i < MAXOBS; i++)
{
trace(4, "%s sat=%2d rs=%13.3f %13.3f %13.3f dts=%12.3f var=%7.3f svh=%02X\n", trace(4, "%s sat=%2d rs=%13.3f %13.3f %13.3f dts=%12.3f var=%7.3f svh=%02X\n",
time_str(time[i], 6), obs[i].sat, rs[i * 6], rs[1 + i * 6], rs[2 + i * 6], time_str(time[i], 6), obs[i].sat, rs[i * 6], rs[1 + i * 6], rs[2 + i * 6],
dts[i*2]*1E9,var[i],svh[i]); dts[i * 2] * 1e9, var[i], svh[i]);
} }
} }

View File

@ -47,38 +47,12 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* history : 2010/07/28 1.1 moved from rtkcmn.c
* added api:
* eph2clk(),geph2clk(),seph2clk(),satantoff()
* satposs()
* changed api:
* eph2pos(),geph2pos(),satpos()
* deleted api:
* satposv(),satposiode()
* 2010/08/26 1.2 add ephemeris option EPHOPT_LEX
* 2010/09/09 1.3 fix problem when precise clock outage
* 2011/01/12 1.4 add api alm2pos()
* change api satpos(),satposs()
* enable valid unhealthy satellites and output status
* fix bug on exception by glonass ephem computation
* 2013/01/10 1.5 support beidou (compass)
* use newton's method to solve kepler eq.
* update ssr correction algorithm
* 2013/03/20 1.6 fix problem on ssr clock relativitic correction
* 2013/09/01 1.7 support negative pseudorange
* fix bug on variance in case of ura ssr = 63
* 2013/11/11 1.8 change constant MAXAGESSR 70.0 -> 90.0
* 2014/10/24 1.9 fix bug on return of var_uraeph() if ura<0||15<ura
* 2014/12/07 1.10 modify MAXDTOE for qzss,gal and bds
* test max number of iteration for Kepler
* 2015/08/26 1.11 update RTOL_ELPLER 1E-14 -> 1E-13
* set MAX_ITER_KEPLER for alm2pos()
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
#ifndef RTKLIB_EPHEMERIS_H_ #ifndef GNSS_SDR_RTKLIB_EPHEMERIS_H_
#define RTKLIB_EPHEMERIS_H_ #define GNSS_SDR_RTKLIB_EPHEMERIS_H_
#include "rtklib.h" #include "rtklib.h"
#include "rtklib_rtkcmn.h" #include "rtklib_rtkcmn.h"
@ -122,4 +96,4 @@ void satposs(gtime_t teph, const obsd_t *obs, int n, const nav_t *nav,
#endif /* RTKLIB_EPHEMERIS_H_ */ #endif /* GNSS_SDR_RTKLIB_EPHEMERIS_H_ */

View File

@ -55,14 +55,11 @@
* Maps based on GPS Carrier Phase Data Routinely producted by CODE * Maps based on GPS Carrier Phase Data Routinely producted by CODE
* Analysis Center, Proceeding of the IGS Analysis Center Workshop, 1996 * Analysis Center, Proceeding of the IGS Analysis Center Workshop, 1996
* *
* version : $Revision:$ $Date:$
* history : 2011/03/29 1.0 new
* 2013/03/05 1.1 change api readtec()
* fix problem in case of lat>85deg or lat<-85deg
* 2014/02/22 1.2 fix problem on compiled as C++
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
#include "rtklib_ionex.h" #include "rtklib_ionex.h"
/* get index -----------------------------------------------------------------*/ /* get index -----------------------------------------------------------------*/
int getindex(double value, const double *range) int getindex(double value, const double *range)
{ {
@ -71,17 +68,23 @@ int getindex(double value, const double *range)
if (range[1] < 0.0 && (value < range[1] || range[0]<value)) return -1; if (range[1] < 0.0 && (value < range[1] || range[0]<value)) return -1;
return (int)floor((value - range[0]) / range[2] + 0.5); return (int)floor((value - range[0]) / range[2] + 0.5);
} }
/* get number of items -------------------------------------------------------*/ /* get number of items -------------------------------------------------------*/
int nitem(const double *range) int nitem(const double *range)
{ {
return getindex(range[1], range) + 1; return getindex(range[1], range) + 1;
} }
/* data index (i:lat,j:lon,k:hgt) --------------------------------------------*/ /* data index (i:lat,j:lon,k:hgt) --------------------------------------------*/
int dataindex(int i, int j, int k, const int *ndata) int dataindex(int i, int j, int k, const int *ndata)
{ {
if (i < 0 || ndata[0] <= i || j < 0 || ndata[1] <= j || k < 0 || ndata[2] <= k) return -1; if (i < 0 || ndata[0] <= i || j < 0 || ndata[1] <= j || k < 0 || ndata[2] <= k) return -1;
return i + ndata[0] * (j + ndata[1] * k); return i + ndata[0] * (j + ndata[1] * k);
} }
/* add tec data to navigation data -------------------------------------------*/ /* add tec data to navigation data -------------------------------------------*/
tec_t *addtec(const double *lats, const double *lons, const double *hgts, tec_t *addtec(const double *lats, const double *lons, const double *hgts,
double rb, nav_t *nav) double rb, nav_t *nav)
@ -97,9 +100,11 @@ tec_t *addtec(const double *lats, const double *lons, const double *hgts,
ndata[2] = nitem(hgts); ndata[2] = nitem(hgts);
if (ndata[0] <= 1 || ndata[1] <= 1 || ndata[2] <= 0) return NULL; if (ndata[0] <= 1 || ndata[1] <= 1 || ndata[2] <= 0) return NULL;
if (nav->nt>=nav->ntmax) { if (nav->nt >= nav->ntmax)
{
nav->ntmax+=256; nav->ntmax+=256;
if (!(nav_tec=(tec_t *)realloc(nav->tec,sizeof(tec_t)*nav->ntmax))) { if (!(nav_tec = (tec_t *)realloc(nav->tec, sizeof(tec_t)*nav->ntmax)))
{
trace(1, "readionex malloc error ntmax=%d\n", nav->ntmax); trace(1, "readionex malloc error ntmax=%d\n", nav->ntmax);
free(nav->tec); nav->tec = NULL; nav->nt = nav->ntmax = 0; free(nav->tec); nav->tec = NULL; nav->nt = nav->ntmax = 0;
return NULL; return NULL;
@ -109,7 +114,8 @@ tec_t *addtec(const double *lats, const double *lons, const double *hgts,
p = nav->tec+nav->nt; p = nav->tec+nav->nt;
p->time = time0; p->time = time0;
p->rb = rb; p->rb = rb;
for (i=0;i<3;i++) { for (i = 0; i < 3; i++)
{
p->ndata[i] = ndata[i]; p->ndata[i] = ndata[i];
p->lats[i] = lats[i]; p->lats[i] = lats[i];
p->lons[i] = lons[i]; p->lons[i] = lons[i];
@ -118,16 +124,20 @@ tec_t *addtec(const double *lats, const double *lons, const double *hgts,
n = ndata[0] * ndata[1] * ndata[2]; n = ndata[0] * ndata[1] * ndata[2];
if (!(p->data = (double *)malloc(sizeof(double) * n)) || if (!(p->data = (double *)malloc(sizeof(double) * n)) ||
!(p->rms =(float *)malloc(sizeof(float )*n))) { !(p->rms = (float *)malloc(sizeof(float ) * n)))
{
return NULL; return NULL;
} }
for (i=0;i<n;i++) { for (i = 0; i < n; i++)
{
p->data[i] = 0.0; p->data[i] = 0.0;
p->rms [i] = 0.0f; p->rms [i] = 0.0f;
} }
nav->nt++; nav->nt++;
return p; return p;
} }
/* read ionex dcb aux data ----------------------------------------------------*/ /* read ionex dcb aux data ----------------------------------------------------*/
void readionexdcb(FILE *fp, double *dcb, double *rms) void readionexdcb(FILE *fp, double *dcb, double *rms)
{ {
@ -138,15 +148,17 @@ void readionexdcb(FILE *fp, double *dcb, double *rms)
for (i = 0; i < MAXSAT; i++) dcb[i] = rms[i] = 0.0; for (i = 0; i < MAXSAT; i++) dcb[i] = rms[i] = 0.0;
while (fgets(buff,sizeof(buff),fp)) { while (fgets(buff, sizeof(buff), fp))
{
if (strlen(buff) < 60) continue; if (strlen(buff) < 60) continue;
label = buff + 60; label = buff + 60;
if (strstr(label,"PRN / BIAS / RMS")==label) { if (strstr(label, "PRN / BIAS / RMS") == label)
{
strncpy(id, buff+3, 3); id[3] = '\0'; strncpy(id, buff+3, 3); id[3] = '\0';
if (!(sat=satid2no(id))) { if (!(sat = satid2no(id)))
{
trace(2, "ionex invalid satellite: %s\n", id); trace(2, "ionex invalid satellite: %s\n", id);
continue; continue;
} }
@ -156,6 +168,8 @@ void readionexdcb(FILE *fp, double *dcb, double *rms)
else if (strstr(label, "END OF AUX DATA") == label) break; else if (strstr(label, "END OF AUX DATA") == label) break;
} }
} }
/* read ionex header ---------------------------------------------------------*/ /* read ionex header ---------------------------------------------------------*/
double readionexh(FILE *fp, double *lats, double *lons, double *hgts, double readionexh(FILE *fp, double *lats, double *lons, double *hgts,
double *rb, double *nexp, double *dcb, double *rms) double *rb, double *nexp, double *dcb, double *rms)
@ -165,45 +179,56 @@ double readionexh(FILE *fp, double *lats, double *lons, double *hgts,
trace(3, "readionexh:\n"); trace(3, "readionexh:\n");
while (fgets(buff,sizeof(buff),fp)) { while (fgets(buff, sizeof(buff), fp))
{
if (strlen(buff) < 60) continue; if (strlen(buff) < 60) continue;
label = buff + 60; label = buff + 60;
if (strstr(label,"IONEX VERSION / TYPE")==label) { if (strstr(label, "IONEX VERSION / TYPE") == label)
{
if (buff[20] == 'I') ver = str2num(buff, 0, 8); if (buff[20] == 'I') ver = str2num(buff, 0, 8);
} }
else if (strstr(label,"BASE RADIUS")==label) { else if (strstr(label, "BASE RADIUS") == label)
{
*rb = str2num(buff, 0, 8); *rb = str2num(buff, 0, 8);
} }
else if (strstr(label,"HGT1 / HGT2 / DHGT")==label) { else if (strstr(label, "HGT1 / HGT2 / DHGT") == label)
{
hgts[0] = str2num(buff, 2, 6); hgts[0] = str2num(buff, 2, 6);
hgts[1] = str2num(buff, 8, 6); hgts[1] = str2num(buff, 8, 6);
hgts[2] = str2num(buff, 14, 6); hgts[2] = str2num(buff, 14, 6);
} }
else if (strstr(label,"LAT1 / LAT2 / DLAT")==label) { else if (strstr(label, "LAT1 / LAT2 / DLAT") == label)
{
lats[0] = str2num(buff, 2, 6); lats[0] = str2num(buff, 2, 6);
lats[1] = str2num(buff, 8, 6); lats[1] = str2num(buff, 8, 6);
lats[2] = str2num(buff, 14, 6); lats[2] = str2num(buff, 14, 6);
} }
else if (strstr(label,"LON1 / LON2 / DLON")==label) { else if (strstr(label,"LON1 / LON2 / DLON") == label)
{
lons[0] = str2num(buff, 2, 6); lons[0] = str2num(buff, 2, 6);
lons[1] = str2num(buff, 8, 6); lons[1] = str2num(buff, 8, 6);
lons[2] = str2num(buff, 14, 6); lons[2] = str2num(buff, 14, 6);
} }
else if (strstr(label,"EXPONENT")==label) { else if (strstr(label, "EXPONENT") == label)
{
*nexp = str2num(buff, 0, 6); *nexp = str2num(buff, 0, 6);
} }
else if (strstr(label, "START OF AUX DATA") == label && else if (strstr(label, "START OF AUX DATA") == label &&
strstr(buff,"DIFFERENTIAL CODE BIASES")) { strstr(buff, "DIFFERENTIAL CODE BIASES"))
{
readionexdcb(fp, dcb, rms); readionexdcb(fp, dcb, rms);
} }
else if (strstr(label,"END OF HEADER")==label) { else if (strstr(label, "END OF HEADER") == label)
{
return ver; return ver;
} }
} }
return 0.0; return 0.0;
} }
/* read ionex body -----------------------------------------------------------*/ /* read ionex body -----------------------------------------------------------*/
int readionexb(FILE *fp, const double *lats, const double *lons, int readionexb(FILE *fp, const double *lats, const double *lons,
const double *hgts, double rb, double nexp, nav_t *nav) const double *hgts, double rb, double nexp, nav_t *nav)
@ -216,32 +241,40 @@ int readionexb(FILE *fp, const double *lats, const double *lons,
trace(3, "readionexb:\n"); trace(3, "readionexb:\n");
while (fgets(buff,sizeof(buff),fp)) { while (fgets(buff, sizeof(buff), fp))
{
if (strlen(buff) < 60) continue; if (strlen(buff) < 60) continue;
if (strstr(label,"START OF TEC MAP")==label) { if (strstr(label, "START OF TEC MAP") == label)
{
if ((p = addtec(lats, lons, hgts, rb, nav))) type = 1; if ((p = addtec(lats, lons, hgts, rb, nav))) type = 1;
} }
else if (strstr(label,"END OF TEC MAP")==label) { else if (strstr(label, "END OF TEC MAP") == label)
{
type = 0; type = 0;
p = NULL; p = NULL;
} }
else if (strstr(label,"START OF RMS MAP")==label) { else if (strstr(label, "START OF RMS MAP") == label)
{
type = 2; type = 2;
p = NULL; p = NULL;
} }
else if (strstr(label,"END OF RMS MAP")==label) { else if (strstr(label, "END OF RMS MAP") == label)
{
type = 0; type = 0;
p = NULL; p = NULL;
} }
else if (strstr(label,"EPOCH OF CURRENT MAP")==label) { else if (strstr(label, "EPOCH OF CURRENT MAP") == label)
if (str2time(buff,0,36,&time)) { {
if (str2time(buff, 0, 36, &time))
{
trace(2, "ionex epoch invalid: %-36.36s\n", buff); trace(2, "ionex epoch invalid: %-36.36s\n", buff);
continue; continue;
} }
if (type==2) { if (type == 2)
for (i=nav->nt-1;i>=0;i--) { {
for (i = nav->nt-1; i >= 0; i--)
{
if (fabs(timediff(time, nav->tec[i].time)) >= 1.0) continue; if (fabs(timediff(time, nav->tec[i].time)) >= 1.0) continue;
p = nav->tec + i; p = nav->tec + i;
break; break;
@ -249,7 +282,8 @@ int readionexb(FILE *fp, const double *lats, const double *lons,
} }
else if (p) p->time = time; else if (p) p->time = time;
} }
else if (strstr(label,"LAT/LON1/LON2/DLON/H")==label&&p) { else if (strstr(label, "LAT/LON1/LON2/DLON/H") == label && p)
{
lat = str2num(buff, 2, 6); lat = str2num(buff, 2, 6);
lon[0] = str2num(buff, 8, 6); lon[0] = str2num(buff, 8, 6);
lon[1] = str2num(buff, 14, 6); lon[1] = str2num(buff, 14, 6);
@ -260,7 +294,8 @@ int readionexb(FILE *fp, const double *lats, const double *lons,
k = getindex(hgt, p->hgts); k = getindex(hgt, p->hgts);
n = nitem(lon); n = nitem(lon);
for (m=0;m<n;m++) { for (m = 0; m < n; m++)
{
if (m % 16 == 0 && !fgets(buff, sizeof(buff), fp)) break; if (m % 16 == 0 && !fgets(buff, sizeof(buff), fp)) break;
j = getindex(lon[0] + lon[2] * m, p->lons); j = getindex(lon[0] + lon[2] * m, p->lons);
@ -268,13 +303,15 @@ int readionexb(FILE *fp, const double *lats, const double *lons,
if ((x = str2num(buff, m % 16 * 5, 5)) == 9999.0) continue; if ((x = str2num(buff, m % 16 * 5, 5)) == 9999.0) continue;
if (type==1) p->data[index]=x*pow(10.0,nexp); if (type == 1) p->data[index] = x * std::pow(10.0, nexp);
else p->rms[index]=(float)(x*pow(10.0,nexp)); else p->rms[index] = (float)(x * std::pow(10.0, nexp));
} }
} }
} }
return 1; return 1;
} }
/* combine tec grid data -----------------------------------------------------*/ /* combine tec grid data -----------------------------------------------------*/
void combtec(nav_t *nav) void combtec(nav_t *nav)
{ {
@ -283,17 +320,22 @@ void combtec(nav_t *nav)
trace(3, "combtec : nav->nt=%d\n", nav->nt); trace(3, "combtec : nav->nt=%d\n", nav->nt);
for (i=0;i<nav->nt-1;i++) { for (i = 0; i < nav->nt - 1; i++)
for (j=i+1;j<nav->nt;j++) { {
if (timediff(nav->tec[j].time,nav->tec[i].time)<0.0) { for (j = i + 1; j < nav->nt; j++)
{
if (timediff(nav->tec[j].time, nav->tec[i].time) < 0.0)
{
tmp = nav->tec[i]; tmp = nav->tec[i];
nav->tec[i] = nav->tec[j]; nav->tec[i] = nav->tec[j];
nav->tec[j] = tmp; nav->tec[j] = tmp;
} }
} }
} }
for (i=0;i<nav->nt;i++) { for (i = 0; i < nav->nt; i++)
if (i>0&&timediff(nav->tec[i].time,nav->tec[n-1].time)==0.0) { {
if (i > 0 && timediff(nav->tec[i].time, nav->tec[n - 1].time) == 0.0)
{
free(nav->tec[n - 1].data); free(nav->tec[n - 1].data);
free(nav->tec[n - 1].rms ); free(nav->tec[n - 1].rms );
nav->tec[n - 1] = nav->tec[i]; nav->tec[n - 1] = nav->tec[i];
@ -305,6 +347,8 @@ void combtec(nav_t *nav)
trace(4, "combtec : nav->nt=%d\n", nav->nt); trace(4, "combtec : nav->nt=%d\n", nav->nt);
} }
/* read ionex tec grid file ---------------------------------------------------- /* read ionex tec grid file ----------------------------------------------------
* read ionex ionospheric tec grid file * read ionex ionospheric tec grid file
* args : char *file I ionex tec grid file * args : char *file I ionex tec grid file
@ -326,11 +370,16 @@ void readtec(const char *file, nav_t *nav, int opt)
trace(3, "readtec : file=%s\n", file); trace(3, "readtec : file=%s\n", file);
/* clear of tec grid data option */ /* clear of tec grid data option */
if (!opt) { if (!opt)
free(nav->tec); nav->tec=NULL; nav->nt=nav->ntmax=0; {
free(nav->tec);
nav->tec = NULL;
nav->nt = nav->ntmax = 0;
} }
for (i=0;i<MAXEXFILE;i++) { for (i = 0; i < MAXEXFILE; i++)
if (!(efiles[i]=(char *)malloc(1024))) { {
if (!(efiles[i] = (char *)malloc(1024)))
{
for (i--; i >= 0; i--) free(efiles[i]); for (i--; i >= 0; i--) free(efiles[i]);
return; return;
} }
@ -338,13 +387,16 @@ void readtec(const char *file, nav_t *nav, int opt)
/* expand wild card in file path */ /* expand wild card in file path */
n = expath(file, efiles, MAXEXFILE); n = expath(file, efiles, MAXEXFILE);
for (i=0;i<n;i++) { for (i = 0; i < n; i++)
if (!(fp=fopen(efiles[i],"r"))) { {
if (!(fp = fopen(efiles[i], "r")))
{
trace(2, "ionex file open error %s\n", efiles[i]); trace(2, "ionex file open error %s\n", efiles[i]);
continue; continue;
} }
/* read ionex header */ /* read ionex header */
if (readionexh(fp,lats,lons,hgts,&rb,&nexp,dcb,rms)<=0.0) { if (readionexh(fp, lats, lons, hgts, &rb, &nexp, dcb, rms) <= 0.0)
{
trace(2, "ionex file format error %s\n", efiles[i]); trace(2, "ionex file format error %s\n", efiles[i]);
continue; continue;
} }
@ -359,10 +411,13 @@ void readtec(const char *file, nav_t *nav, int opt)
if (nav->nt > 0) combtec(nav); if (nav->nt > 0) combtec(nav);
/* P1-P2 dcb */ /* P1-P2 dcb */
for (i=0;i<MAXSAT;i++) { for (i = 0; i < MAXSAT; i++)
nav->cbias[i][0]=CLIGHT*dcb[i]*1E-9; /* ns->m */ {
nav->cbias[i][0] = SPEED_OF_LIGHT * dcb[i] * 1e-9; /* ns->m */
} }
} }
/* interpolate tec grid data -------------------------------------------------*/ /* interpolate tec grid data -------------------------------------------------*/
int interptec(const tec_t *tec, int k, const double *posp, double *value, int interptec(const tec_t *tec, int k, const double *posp, double *value,
double *rms) double *rms)
@ -382,17 +437,20 @@ int interptec(const tec_t *tec, int k, const double *posp, double *value,
a = dlat / tec->lats[2]; a = dlat / tec->lats[2];
b = dlon / tec->lons[2]; b = dlon / tec->lons[2];
i=(int)floor(a); a-=i; i = (int)floor(a);
j=(int)floor(b); b-=j; a -= i;
j = (int)floor(b);
b -= j;
/* get gridded tec data */ /* get gridded tec data */
for (n=0;n<4;n++) { for (n = 0; n < 4; n++)
{
if ((index = dataindex(i + (n % 2), j + (n < 2 ? 0 : 1), k, tec->ndata)) < 0) continue; if ((index = dataindex(i + (n % 2), j + (n < 2 ? 0 : 1), k, tec->ndata)) < 0) continue;
d[n] = tec->data[index]; d[n] = tec->data[index];
r[n] = tec->rms[index]; r[n] = tec->rms[index];
} }
if (d[0]>0.0&&d[1]>0.0&&d[2]>0.0&&d[3]>0.0) { if (d[0] > 0.0 && d[1] > 0.0 && d[2] > 0.0 && d[3] > 0.0)
{
/* bilinear interpolation (inside of grid) */ /* bilinear interpolation (inside of grid) */
*value = (1.0 - a) * (1.0 - b) * d[0] + a*(1.0 -b) * d[1] + (1.0 - a) * b * d[2] + a * b * d[3]; *value = (1.0 - a) * (1.0 - b) * d[0] + a*(1.0 -b) * d[1] + (1.0 - a) * b * d[2] + a * b * d[3];
*rms = (1.0 - a) * (1.0 - b) * r[0] + a*(1.0 - b) * r[1] + (1.0 - a) * b * r[2] + a * b * r[3]; *rms = (1.0 - a) * (1.0 - b) * r[0] + a*(1.0 - b) * r[1] + (1.0 - a) * b * r[2] + a * b * r[3];
@ -402,14 +460,18 @@ int interptec(const tec_t *tec, int k, const double *posp, double *value,
else if (a > 0.5 && b <= 0.5 && d[1] > 0.0) {*value = d[1]; *rms = r[1];} else if (a > 0.5 && b <= 0.5 && d[1] > 0.0) {*value = d[1]; *rms = r[1];}
else if (a <= 0.5 && b > 0.5 && d[2] > 0.0) {*value = d[2]; *rms = r[2];} else if (a <= 0.5 && b > 0.5 && d[2] > 0.0) {*value = d[2]; *rms = r[2];}
else if (a > 0.5 && b > 0.5 && d[3] > 0.0) {*value = d[3]; *rms = r[3];} else if (a > 0.5 && b > 0.5 && d[3] > 0.0) {*value = d[3]; *rms = r[3];}
else { else
{
i = 0; i = 0;
for (n = 0; n < 4; n++) if (d[n] > 0.0) {i++; *value += d[n]; *rms += r[n];} for (n = 0; n < 4; n++) if (d[n] > 0.0) {i++; *value += d[n]; *rms += r[n];}
if(i == 0) return 0; if(i == 0) return 0;
*value/=i; *rms/=i; *value /= i;
*rms /= i;
} }
return 1; return 1;
} }
/* ionosphere delay by tec grid data -----------------------------------------*/ /* ionosphere delay by tec grid data -----------------------------------------*/
int iondelay(gtime_t time, const tec_t *tec, const double *pos, int iondelay(gtime_t time, const tec_t *tec, const double *pos,
const double *azel, int opt, double *delay, double *var) const double *azel, int opt, double *delay, double *var)
@ -423,19 +485,21 @@ int iondelay(gtime_t time, const tec_t *tec, const double *pos,
*delay = *var = 0.0; *delay = *var = 0.0;
for (i=0;i<tec->ndata[2];i++) { /* for a layer */ for (i = 0;i < tec->ndata[2]; i++)
{ /* for a layer */
hion = tec->hgts[0] + tec->hgts[2] * i; hion = tec->hgts[0] + tec->hgts[2] * i;
/* ionospheric pierce point position */ /* ionospheric pierce point position */
fs = ionppp(pos, azel, tec->rb, hion, posp); fs = ionppp(pos, azel, tec->rb, hion, posp);
if (opt&2) { if (opt&2)
{
/* modified single layer mapping function (M-SLM) ref [2] */ /* modified single layer mapping function (M-SLM) ref [2] */
rp = tec->rb / (tec->rb + hion) * sin(0.9782 * (PI / 2.0 - azel[1])); rp = tec->rb / (tec->rb + hion) * sin(0.9782 * (PI / 2.0 - azel[1]));
fs = 1.0 / sqrt(1.0 - rp * rp); fs = 1.0 / sqrt(1.0 - rp * rp);
} }
if (opt&1) { if (opt&1)
{
/* earth rotation correction (sun-fixed coordinate) */ /* earth rotation correction (sun-fixed coordinate) */
posp[1] += 2.0 * PI * timediff(time, tec->time) / 86400.0; posp[1] += 2.0 * PI * timediff(time, tec->time) / 86400.0;
} }
@ -449,6 +513,8 @@ int iondelay(gtime_t time, const tec_t *tec, const double *pos,
return 1; return 1;
} }
/* ionosphere model by tec grid data ------------------------------------------- /* ionosphere model by tec grid data -------------------------------------------
* compute ionospheric delay by tec grid data * compute ionospheric delay by tec grid data
* args : gtime_t time I time (gpst) * args : gtime_t time I time (gpst)
@ -473,19 +539,23 @@ int iontec(gtime_t time, const nav_t *nav, const double *pos,
trace(3, "iontec : time=%s pos=%.1f %.1f azel=%.1f %.1f\n", time_str(time, 0), trace(3, "iontec : time=%s pos=%.1f %.1f azel=%.1f %.1f\n", time_str(time, 0),
pos[0] * R2D, pos[1] * R2D, azel[0] * R2D, azel[1] * R2D); pos[0] * R2D, pos[1] * R2D, azel[0] * R2D, azel[1] * R2D);
if (azel[1]<MIN_EL||pos[2]<MIN_HGT) { if (azel[1] < MIN_EL || pos[2] < MIN_HGT)
{
*delay = 0.0; *delay = 0.0;
*var = VAR_NOTEC; *var = VAR_NOTEC;
return 1; return 1;
} }
for (i=0;i<nav->nt;i++) { for (i = 0; i < nav->nt; i++)
{
if (timediff(nav->tec[i].time, time) > 0.0) break; if (timediff(nav->tec[i].time, time) > 0.0) break;
} }
if (i==0||i>=nav->nt) { if (i == 0 || i >= nav->nt)
{
trace(2, "%s: tec grid out of period\n", time_str(time, 0)); trace(2, "%s: tec grid out of period\n", time_str(time, 0));
return 0; return 0;
} }
if ((tt=timediff(nav->tec[i].time,nav->tec[i-1].time))==0.0) { if ((tt = timediff(nav->tec[i].time, nav->tec[i-1].time)) == 0.0)
{
trace(2, "tec grid time interval error\n"); trace(2, "tec grid time interval error\n");
return 0; return 0;
} }
@ -493,21 +563,25 @@ int iontec(gtime_t time, const nav_t *nav, const double *pos,
stat[0] = iondelay(time, nav->tec+i-1, pos, azel, opt, dels , vars ); stat[0] = iondelay(time, nav->tec+i-1, pos, azel, opt, dels , vars );
stat[1] = iondelay(time, nav->tec+i , pos, azel, opt, dels+1, vars+1); stat[1] = iondelay(time, nav->tec+i , pos, azel, opt, dels+1, vars+1);
if (!stat[0]&&!stat[1]) { if (!stat[0] && !stat[1])
{
trace(2, "%s: tec grid out of area pos=%6.2f %7.2f azel=%6.1f %5.1f\n", trace(2, "%s: tec grid out of area pos=%6.2f %7.2f azel=%6.1f %5.1f\n",
time_str(time, 0), pos[0] * R2D, pos[1] * R2D, azel[0] * R2D, azel[1] * R2D); time_str(time, 0), pos[0] * R2D, pos[1] * R2D, azel[0] * R2D, azel[1] * R2D);
return 0; return 0;
} }
if (stat[0]&&stat[1]) { /* linear interpolation by time */ if (stat[0] && stat[1])
{ /* linear interpolation by time */
a = timediff(time, nav->tec[i-1].time) / tt; a = timediff(time, nav->tec[i-1].time) / tt;
*delay = dels[0] * (1.0 - a) + dels[1] * a; *delay = dels[0] * (1.0 - a) + dels[1] * a;
*var = vars[0] * (1.0 - a) + vars[1] * a; *var = vars[0] * (1.0 - a) + vars[1] * a;
} }
else if (stat[0]) { /* nearest-neighbour extrapolation by time */ else if (stat[0])
{ /* nearest-neighbour extrapolation by time */
*delay = dels[0]; *delay = dels[0];
*var = vars[0]; *var = vars[0];
} }
else { else
{
*delay = dels[1]; *delay = dels[1];
*var = vars[1]; *var = vars[1];
} }

View File

@ -1,5 +1,5 @@
/*! /*!
* \file rtklib_ionex.cc * \file rtklib_ionex.h
* \brief ionex functions * \brief ionex functions
* \authors <ul> * \authors <ul>
* <li> 2007-2013, T. Takasu * <li> 2007-2013, T. Takasu
@ -48,28 +48,23 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* references: * References:
* [1] S.Schear, W.Gurtner and J.Feltens, IONEX: The IONosphere Map EXchange * [1] S.Schear, W.Gurtner and J.Feltens, IONEX: The IONosphere Map EXchange
* Format Version 1, February 25, 1998 * Format Version 1, February 25, 1998
* [2] S.Schaer, R.Markus, B.Gerhard and A.S.Timon, Daily Global Ionosphere * [2] S.Schaer, R.Markus, B.Gerhard and A.S.Timon, Daily Global Ionosphere
* Maps based on GPS Carrier Phase Data Routinely producted by CODE * Maps based on GPS Carrier Phase Data Routinely producted by CODE
* Analysis Center, Proceeding of the IGS Analysis Center Workshop, 1996 * Analysis Center, Proceeding of the IGS Analysis Center Workshop, 1996
* *
* version : $Revision:$ $Date:$
* history : 2011/03/29 1.0 new
* 2013/03/05 1.1 change api readtec()
* fix problem in case of lat>85deg or lat<-85deg
* 2014/02/22 1.2 fix problem on compiled as C++
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
#ifndef RTKLIB_IONEX_H_
#define RTKLIB_IONEX_H_ #ifndef GNSS_SDR_RTKLIB_IONEX_H_
#define GNSS_SDR_RTKLIB_IONEX_H_
#include "rtklib_rtkcmn.h" #include "rtklib_rtkcmn.h"
#define SQR(x) ((x)*(x)) const double VAR_NOTEC = 30.0 * 30.0; /* variance of no tec */
#define VAR_NOTEC SQR(30.0) /* variance of no tec */ const double MIN_EL = 0.0; /* min elevation angle (rad) */
#define MIN_EL 0.0 /* min elevation angle (rad) */ const double MIN_HGT = -1000.0; /* min user height (m) */
#define MIN_HGT -1000.0 /* min user height (m) */
int getindex(double value, const double *range); int getindex(double value, const double *range);
@ -92,4 +87,4 @@ int iondelay(gtime_t time, const tec_t *tec, const double *pos,
int iontec(gtime_t time, const nav_t *nav, const double *pos, int iontec(gtime_t time, const nav_t *nav, const double *pos,
const double *azel, int opt, double *delay, double *var); const double *azel, int opt, double *delay, double *var);
#endif /* SRC_ALGORITHMS_PVT_LIBS_RTKLIB_IONEX_H_ */ #endif /* GNSS_SDR_RTKLIB_IONEX_H_ */

View File

@ -47,19 +47,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* history : 2010/07/28 1.0 moved from rtkcmn.c *
* changed api:
* pntpos()
* deleted api:
* pntvel()
* 2011/01/12 1.1 add option to include unhealthy satellite
* reject duplicated observation data
* changed api: ionocorr()
* 2011/11/08 1.2 enable snr mask for single-mode (rtklib_2.4.1_p3)
* 2012/12/25 1.3 add variable snr mask
* 2014/05/26 1.4 support galileo and beidou
* 2015/03/19 1.5 fix bug on ionosphere correction for GLO and BDS
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
#include "rtklib_pntpos.h" #include "rtklib_pntpos.h"
@ -68,20 +58,25 @@ double varerr(const prcopt_t *opt, double el, int sys)
{ {
double fact, varr; double fact, varr;
fact = sys == SYS_GLO ? EFACT_GLO : (sys == SYS_SBS ? EFACT_SBS : EFACT_GPS); fact = sys == SYS_GLO ? EFACT_GLO : (sys == SYS_SBS ? EFACT_SBS : EFACT_GPS);
varr=SQR(opt->err[0])*(SQR(opt->err[1])+SQR(opt->err[2])/sin(el)); varr = std::pow(opt->err[0], 2.0) * (std::pow(opt->err[1], 2.0) + std::pow(opt->err[2], 2.0) / sin(el));
if (opt->ionoopt==IONOOPT_IFLC) varr*=SQR(3.0); /* iono-free */ if (opt->ionoopt == IONOOPT_IFLC) varr *= std::pow(2, 3.0); /* iono-free */
return SQR(fact)*varr; return std::pow(fact, 2.0) * varr;
} }
/* get tgd parameter (m) -----------------------------------------------------*/ /* get tgd parameter (m) -----------------------------------------------------*/
double gettgd(int sat, const nav_t *nav) double gettgd(int sat, const nav_t *nav)
{ {
int i; int i;
for (i=0;i<nav->n;i++) { for (i = 0; i < nav->n; i++)
{
if (nav->eph[i].sat != sat) continue; if (nav->eph[i].sat != sat) continue;
return CLIGHT*nav->eph[i].tgd[0]; return SPEED_OF_LIGHT * nav->eph[i].tgd[0];
} }
return 0.0; return 0.0;
} }
/* psendorange with code bias correction -------------------------------------*/ /* psendorange with code bias correction -------------------------------------*/
double prange(const obsd_t *obs, const nav_t *nav, const double *azel, double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
int iter, const prcopt_t *opt, double *var) int iter, const prcopt_t *opt, double *var)
@ -110,13 +105,16 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
} }
/* test snr mask */ /* test snr mask */
if (iter>0) { if (iter>0)
if (testsnr(0,i,azel[1],obs->SNR[i]*0.25,&opt->snrmask)) { {
if (testsnr(0, i, azel[1], obs->SNR[i] * 0.25, &opt->snrmask))
{
trace(4, "snr mask: %s sat=%2d el=%.1f snr=%.1f\n", trace(4, "snr mask: %s sat=%2d el=%.1f snr=%.1f\n",
time_str(obs->time, 0), obs->sat, azel[1] * R2D, obs->SNR[i] * 0.25); time_str(obs->time, 0), obs->sat, azel[1] * R2D, obs->SNR[i] * 0.25);
return 0.0; return 0.0;
} }
if (opt->ionoopt==IONOOPT_IFLC) { if (opt->ionoopt == IONOOPT_IFLC)
{
if (testsnr(0, j, azel[1], obs->SNR[j] * 0.25, &opt->snrmask)) if (testsnr(0, j, azel[1], obs->SNR[j] * 0.25, &opt->snrmask))
{ {
trace(4, "prange: testsnr error\n"); trace(4, "prange: testsnr error\n");
@ -124,7 +122,7 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
} }
} }
} }
gamma=SQR(lam[j])/SQR(lam[i]); /* f1^2/f2^2 */ gamma = std::pow(lam[j], 2.0) / std::pow(lam[i], 2.0); /* f1^2/f2^2 */
P1 = obs->P[i]; P1 = obs->P[i];
P2 = obs->P[j]; P2 = obs->P[j];
P1_P2 = nav->cbias[obs->sat-1][0]; P1_P2 = nav->cbias[obs->sat-1][0];
@ -132,10 +130,12 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
P2_C2 = nav->cbias[obs->sat-1][2]; P2_C2 = nav->cbias[obs->sat-1][2];
/* if no P1-P2 DCB, use TGD instead */ /* if no P1-P2 DCB, use TGD instead */
if (P1_P2==0.0&&(sys&(SYS_GPS|SYS_GAL|SYS_QZS))) { if (P1_P2 == 0.0 && (sys & (SYS_GPS | SYS_GAL | SYS_QZS)))
{
P1_P2 = (1.0 - gamma) * gettgd(obs->sat, nav); P1_P2 = (1.0 - gamma) * gettgd(obs->sat, nav);
} }
if (opt->ionoopt==IONOOPT_IFLC) { /* dual-frequency */ if (opt->ionoopt == IONOOPT_IFLC)
{ /* dual-frequency */
if (P1 == 0.0 || P2 == 0.0) return 0.0; if (P1 == 0.0 || P2 == 0.0) return 0.0;
if (obs->code[i] == CODE_L1C) P1 += P1_C1; /* C1->P1 */ if (obs->code[i] == CODE_L1C) P1 += P1_C1; /* C1->P1 */
@ -144,7 +144,8 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
/* iono-free combination */ /* iono-free combination */
PC = (gamma * P1 - P2) / (gamma - 1.0); PC = (gamma * P1 - P2) / (gamma - 1.0);
} }
else { /* single-frequency */ else
{ /* single-frequency */
if (P1 == 0.0) return 0.0; if (P1 == 0.0) return 0.0;
if (obs->code[i] == CODE_L1C) P1 += P1_C1; /* C1->P1 */ if (obs->code[i] == CODE_L1C) P1 += P1_C1; /* C1->P1 */
@ -152,10 +153,12 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
} }
if (opt->sateph == EPHOPT_SBAS) PC -= P1_C1; /* sbas clock based C1 */ if (opt->sateph == EPHOPT_SBAS) PC -= P1_C1; /* sbas clock based C1 */
*var=SQR(ERR_CBIAS); *var = std::pow(ERR_CBIAS, 2.0);
return PC; return PC;
} }
/* ionospheric correction ------------------------------------------------------ /* ionospheric correction ------------------------------------------------------
* compute ionospheric correction * compute ionospheric correction
* args : gtime_t time I time * args : gtime_t time I time
@ -176,23 +179,27 @@ int ionocorr(gtime_t time, const nav_t *nav, int sat, const double *pos,
azel[1]*R2D); azel[1]*R2D);
/* broadcast model */ /* broadcast model */
if (ionoopt==IONOOPT_BRDC) { if (ionoopt == IONOOPT_BRDC)
{
*ion = ionmodel(time, nav->ion_gps, pos, azel); *ion = ionmodel(time, nav->ion_gps, pos, azel);
*var=SQR(*ion*ERR_BRDCI); *var = std::pow(*ion * ERR_BRDCI, 2.0);
return 1; return 1;
} }
/* sbas ionosphere model */ /* sbas ionosphere model */
if (ionoopt==IONOOPT_SBAS) { if (ionoopt == IONOOPT_SBAS)
{
return sbsioncorr(time, nav, pos, azel, ion, var); return sbsioncorr(time, nav, pos, azel, ion, var);
} }
/* ionex tec model */ /* ionex tec model */
if (ionoopt==IONOOPT_TEC) { if (ionoopt == IONOOPT_TEC)
{
return iontec(time, nav, pos, azel, 1, ion, var); return iontec(time, nav, pos, azel, 1, ion, var);
} }
/* qzss broadcast model */ /* qzss broadcast model */
if (ionoopt==IONOOPT_QZS&&norm(nav->ion_qzs,8)>0.0) { if (ionoopt == IONOOPT_QZS && norm(nav->ion_qzs, 8)>0.0)
{
*ion = ionmodel(time, nav->ion_qzs, pos, azel); *ion = ionmodel(time, nav->ion_qzs, pos, azel);
*var=SQR(*ion*ERR_BRDCI); *var = std::pow(*ion * ERR_BRDCI, 2.0);
return 1; return 1;
} }
/* lex ionosphere model */ /* lex ionosphere model */
@ -200,9 +207,11 @@ int ionocorr(gtime_t time, const nav_t *nav, int sat, const double *pos,
// return lexioncorr(time, nav, pos, azel, ion, var); // return lexioncorr(time, nav, pos, azel, ion, var);
//} //}
*ion = 0.0; *ion = 0.0;
*var=ionoopt==IONOOPT_OFF?SQR(ERR_ION):0.0; *var = ionoopt == IONOOPT_OFF ? std::pow(ERR_ION, 2.0) : 0.0;
return 1; return 1;
} }
/* tropospheric correction ----------------------------------------------------- /* tropospheric correction -----------------------------------------------------
* compute tropospheric correction * compute tropospheric correction
* args : gtime_t time I time * args : gtime_t time I time
@ -214,7 +223,7 @@ int ionocorr(gtime_t time, const nav_t *nav, int sat, const double *pos,
* double *var O tropospheric delay variance (m^2) * double *var O tropospheric delay variance (m^2)
* return : status(1:ok,0:error) * return : status(1:ok,0:error)
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
int tropcorr(gtime_t time, const nav_t *nav, const double *pos, int tropcorr(gtime_t time, const nav_t *nav __attribute__((unused)), const double *pos,
const double *azel, int tropopt, double *trp, double *var) const double *azel, int tropopt, double *trp, double *var)
{ {
trace(4, "tropcorr: time=%s opt=%d pos=%.3f %.3f azel=%.3f %.3f\n", trace(4, "tropcorr: time=%s opt=%d pos=%.3f %.3f azel=%.3f %.3f\n",
@ -222,21 +231,25 @@ int tropcorr(gtime_t time, const nav_t *nav, const double *pos,
azel[1]*R2D); azel[1]*R2D);
/* saastamoinen model */ /* saastamoinen model */
if (tropopt==TROPOPT_SAAS||tropopt==TROPOPT_EST||tropopt==TROPOPT_ESTG) { if (tropopt == TROPOPT_SAAS || tropopt == TROPOPT_EST || tropopt == TROPOPT_ESTG)
{
*trp = tropmodel(time, pos, azel, REL_HUMI); *trp = tropmodel(time, pos, azel, REL_HUMI);
*var=SQR(ERR_SAAS/(sin(azel[1])+0.1)); *var = std::pow(ERR_SAAS / (sin(azel[1]) + 0.1), 2.0);
return 1; return 1;
} }
/* sbas troposphere model */ /* sbas troposphere model */
if (tropopt==TROPOPT_SBAS) { if (tropopt == TROPOPT_SBAS)
{
*trp = sbstropcorr(time, pos, azel, var); *trp = sbstropcorr(time, pos, azel, var);
return 1; return 1;
} }
/* no correction */ /* no correction */
*trp = 0.0; *trp = 0.0;
*var=tropopt==TROPOPT_OFF?SQR(ERR_TROP):0.0; *var = tropopt == TROPOPT_OFF ? std::pow(ERR_TROP, 2.0) : 0.0;
return 1; return 1;
} }
/* pseudorange residuals -----------------------------------------------------*/ /* pseudorange residuals -----------------------------------------------------*/
int rescode(int iter, const obsd_t *obs, int n, const double *rs, int rescode(int iter, const obsd_t *obs, int n, const double *rs,
const double *dts, const double *vare, const int *svh, const double *dts, const double *vare, const int *svh,
@ -249,25 +262,28 @@ int rescode(int iter, const obsd_t *obs, int n, const double *rs,
trace(3, "resprng : n=%d\n", n); trace(3, "resprng : n=%d\n", n);
for (i=0;i<3;i++) rr[i]=x[i]; dtr=x[3]; for (i = 0; i < 3; i++) rr[i] = x[i];
dtr = x[3];
ecef2pos(rr, pos); ecef2pos(rr, pos);
for (i=*ns=0;i<n&&i<MAXOBS;i++) { for (i = *ns = 0; i < n && i < MAXOBS; i++)
vsat[i]=0; azel[i*2]=azel[1+i*2]=resp[i]=0.0; {
vsat[i] = 0;
azel[i*2] = azel[1+i*2] = resp[i] = 0.0;
if (!(sys = satsys(obs[i].sat, NULL))) continue; if (!(sys = satsys(obs[i].sat, NULL))) continue;
/* reject duplicated observation data */ /* reject duplicated observation data */
if (i<n-1&&i<MAXOBS-1&&obs[i].sat==obs[i+1].sat) { if (i < n - 1 && i < MAXOBS - 1 && obs[i].sat == obs[i+1].sat)
{
trace(2, "duplicated observation data %s sat=%2d\n", trace(2, "duplicated observation data %s sat=%2d\n",
time_str(obs[i].time, 3), obs[i].sat); time_str(obs[i].time, 3), obs[i].sat);
i++; i++;
continue; continue;
} }
/* geometric distance/azimuth/elevation angle */ /* geometric distance/azimuth/elevation angle */
if ((r=geodist(rs+i*6,rr,e))<=0.0|| if ((r = geodist(rs + i * 6, rr, e)) <= 0.0 || satazel(pos, e, azel + i * 2) < opt->elmin)
satazel(pos,e,azel+i*2)<opt->elmin)
{ {
trace(4, "geodist / satazel error\n"); trace(4, "geodist / satazel error\n");
continue; continue;
@ -296,17 +312,19 @@ int rescode(int iter, const obsd_t *obs, int n, const double *rs,
} }
/* GPS-L1 -> L1/B1 */ /* GPS-L1 -> L1/B1 */
if ((lam_L1=nav->lam[obs[i].sat-1][0])>0.0) { if ((lam_L1 = nav->lam[obs[i].sat - 1][0]) > 0.0)
dion*=SQR(lam_L1/lam_carr[0]); {
dion *= std::pow(lam_L1 / lam_carr[0], 2.0);
} }
/* tropospheric corrections */ /* tropospheric corrections */
if (!tropcorr(obs[i].time, nav, pos, azel + i*2, if (!tropcorr(obs[i].time, nav, pos, azel + i*2,
iter>0?opt->tropopt:TROPOPT_SAAS,&dtrp,&vtrp)) { iter > 0 ? opt->tropopt : TROPOPT_SAAS, &dtrp, &vtrp))
{
trace(4, "tropocorr error\n"); trace(4, "tropocorr error\n");
continue; continue;
} }
/* pseudorange residual */ /* pseudorange residual */
v[nv]=P-(r+dtr-CLIGHT*dts[i*2]+dion+dtrp); v[nv] = P - (r + dtr - SPEED_OF_LIGHT * dts[i*2] + dion + dtrp);
/* design matrix */ /* design matrix */
for (j = 0; j < NX; j++) H[j + nv * NX] = j < 3 ? - e[j] : (j == 3 ? 1.0 : 0.0); for (j = 0; j < NX; j++) H[j + nv * NX] = j < 3 ? - e[j] : (j == 3 ? 1.0 : 0.0);
@ -314,10 +332,12 @@ int rescode(int iter, const obsd_t *obs, int n, const double *rs,
/* time system and receiver bias offset correction */ /* time system and receiver bias offset correction */
if (sys == SYS_GLO) {v[nv] -= x[4]; H[4+nv*NX] = 1.0; mask[1] = 1;} if (sys == SYS_GLO) {v[nv] -= x[4]; H[4+nv*NX] = 1.0; mask[1] = 1;}
else if (sys == SYS_GAL) {v[nv] -= x[5]; H[5+nv*NX] = 1.0; mask[2] = 1;} else if (sys == SYS_GAL) {v[nv] -= x[5]; H[5+nv*NX] = 1.0; mask[2] = 1;}
else if (sys==SYS_CMP) {v[nv]-=x[6]; H[6+nv*NX]=1.0; mask[3]=1;} else if (sys == SYS_BDS) {v[nv] -= x[6]; H[6+nv*NX] = 1.0; mask[3] = 1;}
else mask[0] = 1; else mask[0] = 1;
vsat[i]=1; resp[i]=v[nv]; (*ns)++; vsat[i] = 1;
resp[i] = v[nv];
(*ns)++;
/* error variance */ /* error variance */
var[nv++] = varerr(opt, azel[1+i*2], sys) + vare[i] + vmeas + vion + vtrp; var[nv++] = varerr(opt, azel[1+i*2], sys) + vare[i] + vmeas + vion + vtrp;
@ -326,7 +346,8 @@ int rescode(int iter, const obsd_t *obs, int n, const double *rs,
azel[i*2] * R2D, azel[1+i*2] * R2D, resp[i], sqrt(var[nv-1])); azel[i*2] * R2D, azel[1+i*2] * R2D, resp[i], sqrt(var[nv-1]));
} }
/* constraint to avoid rank-deficient */ /* constraint to avoid rank-deficient */
for (i=0;i<4;i++) { for (i = 0; i < 4; i++)
{
if (mask[i]) continue; if (mask[i]) continue;
v[nv] = 0.0; v[nv] = 0.0;
for (j = 0; j < NX; j++) H[j + nv * NX] = j == i + 3 ? 1.0 : 0.0; for (j = 0; j < NX; j++) H[j + nv * NX] = j == i + 3 ? 1.0 : 0.0;
@ -334,6 +355,8 @@ int rescode(int iter, const obsd_t *obs, int n, const double *rs,
} }
return nv; return nv;
} }
/* validate solution ---------------------------------------------------------*/ /* validate solution ---------------------------------------------------------*/
int valsol(const double *azel, const int *vsat, int n, int valsol(const double *azel, const int *vsat, int n,
const prcopt_t *opt, const double *v, int nv, int nx, const prcopt_t *opt, const double *v, int nv, int nx,
@ -346,24 +369,29 @@ int valsol(const double *azel, const int *vsat, int n,
/* chi-square validation of residuals */ /* chi-square validation of residuals */
vv = dot(v, v, nv); vv = dot(v, v, nv);
if (nv>nx&&vv>chisqr[nv-nx-1]) { if (nv > nx && vv > chisqr[nv-nx-1])
{
sprintf(msg, "chi-square error nv=%d vv=%.1f cs=%.1f", nv, vv, chisqr[nv-nx-1]); sprintf(msg, "chi-square error nv=%d vv=%.1f cs=%.1f", nv, vv, chisqr[nv-nx-1]);
return 0; return 0;
} }
/* large gdop check */ /* large gdop check */
for (i=ns=0;i<n;i++) { for (i = ns = 0; i < n; i++)
{
if (!vsat[i]) continue; if (!vsat[i]) continue;
azels[ ns*2] = azel[ i*2]; azels[ ns*2] = azel[ i*2];
azels[1+ns*2] = azel[1+i*2]; azels[1+ns*2] = azel[1+i*2];
ns++; ns++;
} }
dops(ns, azels, opt->elmin, dop); dops(ns, azels, opt->elmin, dop);
if (dop[0]<=0.0||dop[0]>opt->maxgdop) { if (dop[0] <= 0.0 || dop[0] > opt->maxgdop)
{
sprintf(msg, "gdop error nv=%d gdop=%.1f", nv, dop[0]); sprintf(msg, "gdop error nv=%d gdop=%.1f", nv, dop[0]);
return 0; return 0;
} }
return 1; return 1;
} }
/* estimate receiver position ------------------------------------------------*/ /* estimate receiver position ------------------------------------------------*/
int estpos(const obsd_t *obs, int n, const double *rs, const double *dts, int estpos(const obsd_t *obs, int n, const double *rs, const double *dts,
const double *vare, const int *svh, const nav_t *nav, const double *vare, const int *svh, const nav_t *nav,
@ -375,40 +403,45 @@ int estpos(const obsd_t *obs, int n, const double *rs, const double *dts,
trace(3, "estpos : n=%d\n", n); trace(3, "estpos : n=%d\n", n);
v=mat(n+4,1); H=mat(NX,n+4); var=mat(n+4,1); v = mat(n + 4, 1);
H = mat(NX, n + 4);
var = mat(n + 4, 1);
for (i = 0; i < 3; i++) x[i] = sol->rr[i]; for (i = 0; i < 3; i++) x[i] = sol->rr[i];
for (i=0;i<MAXITR;i++) { for (i = 0; i < MAXITR; i++)
{
/* pseudorange residuals */ /* pseudorange residuals */
nv=rescode(i,obs,n,rs,dts,vare,svh,nav,x,opt,v,H,var,azel,vsat,resp, nv = rescode(i, obs, n, rs, dts, vare, svh, nav, x, opt, v, H, var, azel, vsat, resp, &ns);
&ns);
if (nv<NX) { if (nv < NX)
{
sprintf(msg, "lack of valid sats ns=%d", nv); sprintf(msg, "lack of valid sats ns=%d", nv);
break; break;
} }
/* weight by variance */ /* weight by variance */
for (j=0;j<nv;j++) { for (j = 0;j < nv; j++)
{
sig = sqrt(var[j]); sig = sqrt(var[j]);
v[j] /= sig; v[j] /= sig;
for (k = 0; k < NX; k++) H[k + j * NX] /= sig; for (k = 0; k < NX; k++) H[k + j * NX] /= sig;
} }
/* least square estimation */ /* least square estimation */
if ((info=lsq(H,v,NX,nv,dx,Q))) { if ((info = lsq(H, v, NX, nv, dx, Q)))
{
sprintf(msg, "lsq error info=%d", info); sprintf(msg, "lsq error info=%d", info);
break; break;
} }
for (j = 0; j < NX; j++) x[j] += dx[j]; for (j = 0; j < NX; j++) x[j] += dx[j];
if (norm(dx,NX)<1E-4) { if (norm(dx, NX) < 1e-4)
{
sol->type = 0; sol->type = 0;
sol->time=timeadd(obs[0].time,-x[3]/CLIGHT); sol->time = timeadd(obs[0].time, -x[3] / SPEED_OF_LIGHT);
sol->dtr[0]=x[3]/CLIGHT; /* receiver clock bias (s) */ sol->dtr[0] = x[3] / SPEED_OF_LIGHT; /* receiver clock bias (s) */
sol->dtr[1]=x[4]/CLIGHT; /* glo-gps time offset (s) */ sol->dtr[1] = x[4] / SPEED_OF_LIGHT; /* glo-gps time offset (s) */
sol->dtr[2]=x[5]/CLIGHT; /* gal-gps time offset (s) */ sol->dtr[2] = x[5] / SPEED_OF_LIGHT; /* gal-gps time offset (s) */
sol->dtr[3]=x[6]/CLIGHT; /* bds-gps time offset (s) */ sol->dtr[3] = x[6] / SPEED_OF_LIGHT; /* bds-gps time offset (s) */
for (j = 0; j < 6; j++) sol->rr[j] = j < 3 ? x[j] : 0.0; for (j = 0; j < 6; j++) sol->rr[j] = j < 3 ? x[j] : 0.0;
for (j = 0; j < 3; j++) sol->qr[j] = (float)Q[j + j * NX]; for (j = 0; j < 3; j++) sol->qr[j] = (float)Q[j + j * NX];
sol->qr[3] = (float)Q[1]; /* cov xy */ sol->qr[3] = (float)Q[1]; /* cov xy */
@ -418,20 +451,27 @@ int estpos(const obsd_t *obs, int n, const double *rs, const double *dts,
sol->age = sol->ratio = 0.0; sol->age = sol->ratio = 0.0;
/* validate solution */ /* validate solution */
if ((stat=valsol(azel,vsat,n,opt,v,nv,NX,msg))) { if ((stat = valsol(azel, vsat, n, opt, v, nv, NX, msg)))
{
sol->stat = opt->sateph == EPHOPT_SBAS ? SOLQ_SBAS : SOLQ_SINGLE; sol->stat = opt->sateph == EPHOPT_SBAS ? SOLQ_SBAS : SOLQ_SINGLE;
} }
free(v); free(H); free(var); free(v);
free(H);
free(var);
return stat; return stat;
} }
} }
if (i >= MAXITR) sprintf(msg, "iteration divergent i=%d", i); if (i >= MAXITR) sprintf(msg, "iteration divergent i=%d", i);
free(v); free(H); free(var); free(v);
free(H);
free(var);
return 0; return 0;
} }
/* raim fde (failure detection and exclution) -------------------------------*/ /* raim fde (failure detection and exclution) -------------------------------*/
int raim_fde(const obsd_t *obs, int n, const double *rs, int raim_fde(const obsd_t *obs, int n, const double *rs,
const double *dts, const double *vare, const int *svh, const double *dts, const double *vare, const int *svh,
@ -447,13 +487,19 @@ int raim_fde(const obsd_t *obs, int n, const double *rs,
trace(3, "raim_fde: %s n=%2d\n", time_str(obs[0].time, 0), n); trace(3, "raim_fde: %s n=%2d\n", time_str(obs[0].time, 0), n);
if (!(obs_e = (obsd_t *)malloc(sizeof(obsd_t) * n))) return 0; if (!(obs_e = (obsd_t *)malloc(sizeof(obsd_t) * n))) return 0;
rs_e = mat(6,n); dts_e = mat(2,n); vare_e=mat(1,n); azel_e=zeros(2,n); rs_e = mat(6, n);
svh_e=imat(1,n); vsat_e=imat(1,n); resp_e=mat(1,n); dts_e = mat(2, n);
vare_e = mat(1, n);
for (i=0;i<n;i++) { azel_e = zeros(2, n);
svh_e = imat(1, n);
vsat_e = imat(1, n);
resp_e = mat(1, n);
for (i = 0; i < n; i++)
{
/* satellite exclution */ /* satellite exclution */
for (j=k=0;j<n;j++) { for (j = k = 0; j < n; j++)
{
if (j == i) continue; if (j == i) continue;
obs_e[k] = obs[j]; obs_e[k] = obs[j];
matcpy(rs_e + 6 * k, rs + 6 * j, 6, 1); matcpy(rs_e + 6 * k, rs + 6 * j, 6, 1);
@ -463,16 +509,19 @@ int raim_fde(const obsd_t *obs, int n, const double *rs,
} }
/* estimate receiver position without a satellite */ /* estimate receiver position without a satellite */
if (!estpos(obs_e, n-1, rs_e, dts_e, vare_e, svh_e, nav, opt, &sol_e, azel_e, if (!estpos(obs_e, n-1, rs_e, dts_e, vare_e, svh_e, nav, opt, &sol_e, azel_e,
vsat_e,resp_e,msg_e)) { vsat_e, resp_e, msg_e))
{
trace(3, "raim_fde: exsat=%2d (%s)\n", obs[i].sat, msg); trace(3, "raim_fde: exsat=%2d (%s)\n", obs[i].sat, msg);
continue; continue;
} }
for (j=nvsat=0,rms_e=0.0;j<n-1;j++) { for (j = nvsat = 0, rms_e = 0.0; j < n - 1; j++)
{
if (!vsat_e[j]) continue; if (!vsat_e[j]) continue;
rms_e+=SQR(resp_e[j]); rms_e += std::pow(resp_e[j], 2.0);
nvsat++; nvsat++;
} }
if (nvsat<5) { if (nvsat < 5)
{
trace(3, "raim_fde: exsat=%2d lack of satellites nvsat=%2d\n", trace(3, "raim_fde: exsat=%2d lack of satellites nvsat=%2d\n",
obs[i].sat, nvsat); obs[i].sat, nvsat);
continue; continue;
@ -484,7 +533,8 @@ int raim_fde(const obsd_t *obs, int n, const double *rs,
if (rms_e > rms) continue; if (rms_e > rms) continue;
/* save result */ /* save result */
for (j=k=0;j<n;j++) { for (j = k = 0; j < n; j++)
{
if (j == i) continue; if (j == i) continue;
matcpy(azel + 2 * j, azel_e + 2 * k, 2, 1); matcpy(azel + 2 * j, azel_e + 2 * k, 2, 1);
vsat[j] = vsat_e[k]; vsat[j] = vsat_e[k];
@ -497,15 +547,24 @@ int raim_fde(const obsd_t *obs, int n, const double *rs,
vsat[i] = 0; vsat[i] = 0;
strcpy(msg, msg_e); strcpy(msg, msg_e);
} }
if (stat) { if (stat)
{
time2str(obs[0].time, tstr, 2); satno2id(sat, name); time2str(obs[0].time, tstr, 2); satno2id(sat, name);
trace(2, "%s: %s excluded by raim\n", tstr + 11, name); trace(2, "%s: %s excluded by raim\n", tstr + 11, name);
} }
free(obs_e); free(obs_e);
free(rs_e ); free(dts_e ); free(vare_e); free(azel_e); free(rs_e);
free(svh_e); free(vsat_e); free(resp_e); free(dts_e);
free(vare_e);
free(azel_e);
free(svh_e);
free(vsat_e);
free(resp_e);
return stat; return stat;
} }
/* doppler residuals ---------------------------------------------------------*/ /* doppler residuals ---------------------------------------------------------*/
int resdop(const obsd_t *obs, int n, const double *rs, const double *dts, int resdop(const obsd_t *obs, int n, const double *rs, const double *dts,
const nav_t *nav, const double *rr, const double *x, const nav_t *nav, const double *rr, const double *x,
@ -516,13 +575,15 @@ int resdop(const obsd_t *obs, int n, const double *rs, const double *dts,
trace(3, "resdop : n=%d\n", n); trace(3, "resdop : n=%d\n", n);
ecef2pos(rr,pos); xyz2enu(pos,E); ecef2pos(rr, pos);
xyz2enu(pos, E);
for (i=0;i<n&&i<MAXOBS;i++) {
for (i = 0; i < n && i < MAXOBS; i++)
{
lam = nav->lam[obs[i].sat-1][0]; lam = nav->lam[obs[i].sat-1][0];
if (obs[i].D[0]==0.0||lam==0.0||!vsat[i]||norm(rs+3+i*6,3)<=0.0) { if (obs[i].D[0] == 0.0 || lam == 0.0 || !vsat[i] || norm(rs + 3 + i * 6, 3) <= 0.0)
{
continue; continue;
} }
/* line-of-sight vector in ecef */ /* line-of-sight vector in ecef */
@ -536,11 +597,11 @@ int resdop(const obsd_t *obs, int n, const double *rs, const double *dts,
for (j = 0; j < 3; j++) vs[j] = rs[j+3+i*6] - x[j]; for (j = 0; j < 3; j++) vs[j] = rs[j+3+i*6] - x[j];
/* range rate with earth rotation correction */ /* range rate with earth rotation correction */
rate=dot(vs,e,3)+OMGE/CLIGHT*(rs[4+i*6]*rr[0]+rs[1+i*6]*x[0]- rate = dot(vs, e, 3) + DEFAULT_OMEGA_EARTH_DOT / SPEED_OF_LIGHT * (rs[4 + i * 6] * rr[0] + rs[1 + i * 6] * x[0]-
rs[3 + i * 6] * rr[1] - rs[i * 6] * x[1]); rs[3 + i * 6] * rr[1] - rs[i * 6] * x[1]);
/* doppler residual */ /* doppler residual */
v[nv]=-lam*obs[i].D[0]-(rate+x[3]-CLIGHT*dts[1+i*2]); v[nv] =- lam * obs[i].D[0] - (rate + x[3] - SPEED_OF_LIGHT * dts[1 + i *2]);
/* design matrix */ /* design matrix */
for (j = 0; j < 4; j++) H[j + nv * 4] = j < 3 ? - e[j] : 1.0; for (j = 0; j < 4; j++) H[j + nv * 4] = j < 3 ? - e[j] : 1.0;
@ -549,9 +610,11 @@ int resdop(const obsd_t *obs, int n, const double *rs, const double *dts,
} }
return nv; return nv;
} }
/* estimate receiver velocity ------------------------------------------------*/ /* estimate receiver velocity ------------------------------------------------*/
void estvel(const obsd_t *obs, int n, const double *rs, const double *dts, void estvel(const obsd_t *obs, int n, const double *rs, const double *dts,
const nav_t *nav, const prcopt_t *opt, sol_t *sol, const nav_t *nav, const prcopt_t *opt __attribute__((unused)), sol_t *sol,
const double *azel, const int *vsat) const double *azel, const int *vsat)
{ {
double x[4] = {0}, dx[4], Q[16], *v, *H; double x[4] = {0}, dx[4], Q[16], *v, *H;
@ -559,12 +622,14 @@ void estvel(const obsd_t *obs, int n, const double *rs, const double *dts,
trace(3, "estvel : n=%d\n", n); trace(3, "estvel : n=%d\n", n);
v=mat(n,1); H=mat(4,n); v = mat(n, 1);
H = mat(4, n);
for (i=0;i<MAXITR;i++) {
for (i = 0; i < MAXITR; i++)
{
/* doppler residuals */ /* doppler residuals */
if ((nv=resdop(obs,n,rs,dts,nav,sol->rr,x,azel,vsat,v,H))<4) { if ((nv = resdop(obs, n, rs, dts, nav, sol->rr, x, azel, vsat, v, H)) < 4)
{
break; break;
} }
/* least square estimation */ /* least square estimation */
@ -572,13 +637,17 @@ void estvel(const obsd_t *obs, int n, const double *rs, const double *dts,
for (j = 0; j < 4; j++) x[j] += dx[j]; for (j = 0; j < 4; j++) x[j] += dx[j];
if (norm(dx,4)<1E-6) { if (norm(dx, 4) < 1e-6)
{
for (i = 0; i < 3; i++) sol->rr[i+3] = x[i]; for (i = 0; i < 3; i++) sol->rr[i+3] = x[i];
break; break;
} }
} }
free(v); free(H); free(v);
free(H);
} }
/* single-point positioning ---------------------------------------------------- /* single-point positioning ----------------------------------------------------
* compute receiver position, velocity, clock bias by single-point positioning * compute receiver position, velocity, clock bias by single-point positioning
* with pseudorange and doppler observables * with pseudorange and doppler observables
@ -656,11 +725,17 @@ int pntpos(const obsd_t *obs, int n, const nav_t *nav,
trace(3, "pntpos : tobs=%s n=%d\n", time_str(obs[0].time, 3), n); trace(3, "pntpos : tobs=%s n=%d\n", time_str(obs[0].time, 3), n);
sol->time=obs[0].time; msg[0]='\0'; sol->time = obs[0].time;
msg[0] = '\0';
rs=mat(6,n); dts=mat(2,n); var=mat(1,n); azel_=zeros(2,n); resp=mat(1,n); rs = mat(6, n);
dts = mat(2, n);
var = mat(1, n);
azel_ = zeros(2, n);
resp = mat(1, n);
if (opt_.mode!=PMODE_SINGLE) { /* for precise positioning */ if (opt_.mode != PMODE_SINGLE)
{ /* for precise positioning */
#if 0 #if 0
opt_.sateph = EPHOPT_BRDC; opt_.sateph = EPHOPT_BRDC;
#endif #endif
@ -674,23 +749,28 @@ int pntpos(const obsd_t *obs, int n, const nav_t *nav,
stat = estpos(obs, n, rs, dts, var, svh, nav, &opt_, sol, azel_, vsat, resp, msg); stat = estpos(obs, n, rs, dts, var, svh, nav, &opt_, sol, azel_, vsat, resp, msg);
/* raim fde */ /* raim fde */
if (!stat&&n>=6&&opt->posopt[4]) { if (!stat && n >= 6 && opt->posopt[4])
{
stat = raim_fde(obs, n, rs, dts, var, svh, nav, &opt_, sol, azel_, vsat, resp, msg); stat = raim_fde(obs, n, rs, dts, var, svh, nav, &opt_, sol, azel_, vsat, resp, msg);
} }
/* estimate receiver velocity with doppler */ /* estimate receiver velocity with doppler */
if (stat) estvel(obs, n, rs, dts, nav, &opt_, sol, azel_, vsat); if (stat) estvel(obs, n, rs, dts, nav, &opt_, sol, azel_, vsat);
if (azel) { if (azel)
{
for (i = 0; i < n * 2; i++) azel[i] = azel_[i]; for (i = 0; i < n * 2; i++) azel[i] = azel_[i];
} }
if (ssat) { if (ssat)
for (i=0;i<MAXSAT;i++) { {
for (i = 0; i < MAXSAT; i++)
{
ssat[i].vs = 0; ssat[i].vs = 0;
ssat[i].azel[0] = ssat[i].azel[1] = 0.0; ssat[i].azel[0] = ssat[i].azel[1] = 0.0;
ssat[i].resp[0] = ssat[i].resc[0] = 0.0; ssat[i].resp[0] = ssat[i].resc[0] = 0.0;
ssat[i].snr[0] = 0; ssat[i].snr[0] = 0;
} }
for (i=0;i<n;i++) { for (i = 0; i < n; i++)
{
ssat[obs[i].sat-1].azel[0] = azel_[ i*2]; ssat[obs[i].sat-1].azel[0] = azel_[ i*2];
ssat[obs[i].sat-1].azel[1] = azel_[1+i*2]; ssat[obs[i].sat-1].azel[1] = azel_[1+i*2];
ssat[obs[i].sat-1].snr[0] = obs[i].SNR[0]; ssat[obs[i].sat-1].snr[0] = obs[i].SNR[0];
@ -699,6 +779,10 @@ int pntpos(const obsd_t *obs, int n, const nav_t *nav,
ssat[obs[i].sat-1].resp[0] = resp[i]; ssat[obs[i].sat-1].resp[0] = resp[i];
} }
} }
free(rs); free(dts); free(var); free(azel_); free(resp); free(rs);
free(dts);
free(var);
free(azel_);
free(resp);
return stat; return stat;
} }

View File

@ -48,22 +48,10 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* history : 2010/07/28 1.0 moved from rtkcmn.c
* changed api:
* pntpos()
* deleted api:
* pntvel()
* 2011/01/12 1.1 add option to include unhealthy satellite
* reject duplicated observation data
* changed api: ionocorr()
* 2011/11/08 1.2 enable snr mask for single-mode (rtklib_2.4.1_p3)
* 2012/12/25 1.3 add variable snr mask
* 2014/05/26 1.4 support galileo and beidou
* 2015/03/19 1.5 fix bug on ionosphere correction for GLO and BDS
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
#ifndef RTKLIB_PNTPOS_H_ #ifndef GNSS_SDR_RTKLIB_PNTPOS_H_
#define RTKLIB_PNTPOS_H_ #define GNSS_SDR_RTKLIB_PNTPOS_H_
#include "rtklib.h" #include "rtklib.h"
#include "rtklib_rtkcmn.h" #include "rtklib_rtkcmn.h"
@ -71,18 +59,15 @@
#include "rtklib_ionex.h" #include "rtklib_ionex.h"
/* constants -----------------------------------------------------------------*/ /* constants -----------------------------------------------------------------*/
const int NX = 4 + 3; //!< # of estimated parameters
#define SQR(x) ((x)*(x)) const int MAXITR = 10; //!< max number of iteration for point pos
const double ERR_ION = 5.0; //!< ionospheric delay std (m)
#define NX (4+3) /* # of estimated parameters */ const double ERR_TROP = 3.0; //!< tropspheric delay std (m)
const double ERR_SAAS = 0.3; //!< saastamoinen model error std (m)
#define MAXITR 10 /* max number of iteration for point pos */ const double ERR_BRDCI = 0.5; //!< broadcast iono model error factor
#define ERR_ION 5.0 /* ionospheric delay std (m) */ const double ERR_CBIAS = 0.3; //!< code bias error std (m)
#define ERR_TROP 3.0 /* tropspheric delay std (m) */ const double REL_HUMI = 0.7; //!< relative humidity for saastamoinen model
#define ERR_SAAS 0.3 /* saastamoinen model error std (m) */
#define ERR_BRDCI 0.5 /* broadcast iono model error factor */
#define ERR_CBIAS 0.3 /* code bias error std (m) */
#define REL_HUMI 0.7 /* relative humidity for saastamoinen model */
/* pseudorange measurement error variance ------------------------------------*/ /* pseudorange measurement error variance ------------------------------------*/
double varerr(const prcopt_t *opt, double el, int sys); double varerr(const prcopt_t *opt, double el, int sys);
@ -177,4 +162,4 @@ int pntpos(const obsd_t *obs, int n, const nav_t *nav,
const prcopt_t *opt, sol_t *sol, double *azel, ssat_t *ssat, const prcopt_t *opt, sol_t *sol, double *azel, ssat_t *ssat,
char *msg); char *msg);
#endif /* RTKLIB_PNTPOS_H_ */ #endif /* GNSS_SDR_RTKLIB_PNTPOS_H_ */

View File

@ -49,7 +49,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* *
* references : * References :
* [1] S.Hilla, The Extended Standard Product 3 Orbit Format (SP3-c), * [1] S.Hilla, The Extended Standard Product 3 Orbit Format (SP3-c),
* 12 February, 2007 * 12 February, 2007
* [2] J.Ray, W.Gurtner, RINEX Extensions to Handle Clock Information, * [2] J.Ray, W.Gurtner, RINEX Extensions to Handle Clock Information,
@ -58,34 +58,6 @@
* [4] D.A.Vallado, Fundamentals of Astrodynamics and Applications 2nd ed, * [4] D.A.Vallado, Fundamentals of Astrodynamics and Applications 2nd ed,
* Space Technology Library, 2004 * Space Technology Library, 2004
* *
* version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $
* history : 2009/01/18 1.0 new
* 2009/01/31 1.1 fix bug on numerical error to read sp3a ephemeris
* 2009/05/15 1.2 support glonass,galileo,qzs
* 2009/12/11 1.3 support wild-card expansion of file path
* 2010/07/21 1.4 added api:
* eci2ecef(),sunmoonpos(),peph2pos(),satantoff(),
* readdcb()
* changed api:
* readsp3()
* deleted api:
* eph2posp()
* 2010/09/09 1.5 fix problem when precise clock outage
* 2011/01/23 1.6 support qzss satellite code
* 2011/09/12 1.7 fix problem on precise clock outage
* move sunmmonpos() to rtkcmn.c
* 2011/12/01 1.8 modify api readsp3()
* precede later ephemeris if ephemeris is NULL
* move eci2ecef() to rtkcmn.c
* 2013/05/08 1.9 fix bug on computing std-dev of precise clocks
* 2013/11/20 1.10 modify option for api readsp3()
* 2014/04/03 1.11 accept extenstion including sp3,eph,SP3,EPH
* 2014/05/23 1.12 add function to read sp3 velocity records
* change api: satantoff()
* 2014/08/31 1.13 add member cov and vco in peph_t sturct
* 2014/10/13 1.14 fix bug on clock error variance in peph2pos()
* 2015/05/10 1.15 add api readfcb()
* modify api readdcb()
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
#include "rtklib_preceph.h" #include "rtklib_preceph.h"
@ -97,10 +69,12 @@ int code2sys(char code)
if (code == 'R') return SYS_GLO; if (code == 'R') return SYS_GLO;
if (code == 'E') return SYS_GAL; /* extension to sp3-c */ if (code == 'E') return SYS_GAL; /* extension to sp3-c */
if (code == 'J') return SYS_QZS; /* extension to sp3-c */ if (code == 'J') return SYS_QZS; /* extension to sp3-c */
if (code=='C') return SYS_CMP; /* extension to sp3-c */ if (code == 'C') return SYS_BDS; /* extension to sp3-c */
if (code == 'L') return SYS_LEO; /* extension to sp3-c */ if (code == 'L') return SYS_LEO; /* extension to sp3-c */
return SYS_NONE; return SYS_NONE;
} }
/* read sp3 header -----------------------------------------------------------*/ /* read sp3 header -----------------------------------------------------------*/
int readsp3h(FILE *fp, gtime_t *time, char *type, int *sats, int readsp3h(FILE *fp, gtime_t *time, char *type, int *sats,
double *bfact, char *tsys) double *bfact, char *tsys)
@ -110,43 +84,56 @@ int readsp3h(FILE *fp, gtime_t *time, char *type, int *sats,
trace(3, "readsp3h:\n"); trace(3, "readsp3h:\n");
for (i=0;i<22;i++) { for (i = 0;i<22;i++)
{
if (!fgets(buff, sizeof(buff), fp)) break; if (!fgets(buff, sizeof(buff), fp)) break;
if (i==0) { if (i == 0)
{
*type = buff[2]; *type = buff[2];
if (str2time(buff, 3, 28, time)) return 0; if (str2time(buff, 3, 28, time)) return 0;
} }
else if (2<=i&&i<=6) { else if (2<=i && i<=6)
if (i==2) { {
if (i == 2)
{
ns = (int)str2num(buff, 4, 2); ns = (int)str2num(buff, 4, 2);
} }
for (j=0;j<17&&k<ns;j++) { for (j = 0;j<17 && k<ns;j++)
{
sys = code2sys(buff[9+3*j]); sys = code2sys(buff[9+3*j]);
prn = (int)str2num(buff, 10+3*j, 2); prn = (int)str2num(buff, 10+3*j, 2);
if (k<MAXSAT) sats[k++] = satno(sys, prn); if (k<MAXSAT) sats[k++] = satno(sys, prn);
} }
} }
else if (i==12) { else if (i == 12)
{
strncpy(tsys, buff+9, 3); tsys[3] = '\0'; strncpy(tsys, buff+9, 3); tsys[3] = '\0';
} }
else if (i==14) { else if (i == 14)
{
bfact[0] = str2num(buff, 3, 10); bfact[0] = str2num(buff, 3, 10);
bfact[1] = str2num(buff, 14, 12); bfact[1] = str2num(buff, 14, 12);
} }
} }
return ns; return ns;
} }
/* add precise ephemeris -----------------------------------------------------*/ /* add precise ephemeris -----------------------------------------------------*/
int addpeph(nav_t *nav, peph_t *peph) int addpeph(nav_t *nav, peph_t *peph)
{ {
peph_t *nav_peph; peph_t *nav_peph;
if (nav->ne>=nav->nemax) { if (nav->ne >= nav->nemax)
{
nav->nemax += 256; nav->nemax += 256;
if (!(nav_peph=(peph_t *)realloc(nav->peph,sizeof(peph_t)*nav->nemax))) { if (!(nav_peph = (peph_t *)realloc(nav->peph, sizeof(peph_t)*nav->nemax)))
{
trace(1, "readsp3b malloc error n=%d\n", nav->nemax); trace(1, "readsp3b malloc error n=%d\n", nav->nemax);
free(nav->peph); nav->peph=NULL; nav->ne=nav->nemax=0; free(nav->peph);
nav->peph = NULL;
nav->ne = nav->nemax = 0;
return 0; return 0;
} }
nav->peph = nav_peph; nav->peph = nav_peph;
@ -154,8 +141,10 @@ int addpeph(nav_t *nav, peph_t *peph)
nav->peph[nav->ne++] = *peph; nav->peph[nav->ne++] = *peph;
return 1; return 1;
} }
/* read sp3 body -------------------------------------------------------------*/ /* read sp3 body -------------------------------------------------------------*/
void readsp3b(FILE *fp, char type, int *sats, int ns, double *bfact, void readsp3b(FILE *fp, char type, int *sats __attribute__((unused)), int ns, double *bfact,
char *tsys, int index, int opt, nav_t *nav) char *tsys, int index, int opt, nav_t *nav)
{ {
peph_t peph; peph_t peph;
@ -166,11 +155,12 @@ void readsp3b(FILE *fp, char type, int *sats, int ns, double *bfact,
trace(3, "readsp3b: type=%c ns=%d index=%d opt=%d\n", type, ns, index, opt); trace(3, "readsp3b: type=%c ns=%d index=%d opt=%d\n", type, ns, index, opt);
while (fgets(buff,sizeof(buff),fp)) { while (fgets(buff, sizeof(buff), fp))
{
if (!strncmp(buff, "EOF", 3)) break; if (!strncmp(buff, "EOF", 3)) break;
if (buff[0]!='*'||str2time(buff,3,28,&time)) { if (buff[0] != '*' || str2time(buff, 3, 28, &time))
{
trace(2, "sp3 invalid epoch %31.31s\n", buff); trace(2, "sp3 invalid epoch %31.31s\n", buff);
continue; continue;
} }
@ -178,20 +168,23 @@ void readsp3b(FILE *fp, char type, int *sats, int ns, double *bfact,
peph.time = time; peph.time = time;
peph.index = index; peph.index = index;
for (i=0;i<MAXSAT;i++) { for (i = 0; i < MAXSAT; i++)
for (j=0;j<4;j++) { {
for (j = 0; j < 4; j++)
{
peph.pos[i][j] = 0.0; peph.pos[i][j] = 0.0;
peph.std[i][j] = 0.0f; peph.std[i][j] = 0.0f;
peph.vel[i][j] = 0.0; peph.vel[i][j] = 0.0;
peph.vst[i][j] = 0.0f; peph.vst[i][j] = 0.0f;
} }
for (j=0;j<3;j++) { for (j = 0; j < 3; j++)
{
peph.cov[i][j] = 0.0f; peph.cov[i][j] = 0.0f;
peph.vco[i][j] = 0.0f; peph.vco[i][j] = 0.0f;
} }
} }
for (i=pred_o=pred_c=v=0;i<n&&fgets(buff,sizeof(buff),fp);i++) { for (i = pred_o = pred_c = v = 0;i<n && fgets(buff, sizeof(buff), fp);i++)
{
if (strlen(buff) < 4 || (buff[0] != 'P' && buff[0] != 'V')) continue; if (strlen(buff) < 4 || (buff[0] != 'P' && buff[0] != 'V')) continue;
sys = buff[1] == ' '?SYS_GPS:code2sys(buff[1]); sys = buff[1] == ' '?SYS_GPS:code2sys(buff[1]);
@ -201,12 +194,13 @@ void readsp3b(FILE *fp, char type, int *sats, int ns, double *bfact,
if (!(sat = satno(sys, prn))) continue; if (!(sat = satno(sys, prn))) continue;
if (buff[0]=='P') { if (buff[0] == 'P')
{
pred_c = strlen(buff) >= 76 && buff[75] == 'P'; pred_c = strlen(buff) >= 76 && buff[75] == 'P';
pred_o = strlen(buff) >= 80 && buff[79] == 'P'; pred_o = strlen(buff) >= 80 && buff[79] == 'P';
} }
for (j=0;j<4;j++) { for (j = 0;j<4;j++)
{
/* read option for predicted value */ /* read option for predicted value */
if (j< 3 && (opt&1) && pred_o) continue; if (j< 3 && (opt&1) && pred_o) continue;
if (j< 3 && (opt&2) && !pred_o) continue; if (j< 3 && (opt&2) && !pred_o) continue;
@ -217,36 +211,45 @@ void readsp3b(FILE *fp, char type, int *sats, int ns, double *bfact,
std = str2num(buff, 61 + j * 3, j < 3 ? 2 : 3); std = str2num(buff, 61 + j * 3, j < 3 ? 2 : 3);
if (buff[0] == 'P') { /* position */ if (buff[0] == 'P') { /* position */
if (val!=0.0&&fabs(val-999999.999999)>=1E-6) { if (val != 0.0 && fabs(val - 999999.999999) >= 1e-6)
peph.pos[sat-1][j]=val*(j<3?1000.0:1E-6); {
peph.pos[sat-1][j] = val*(j < 3 ? 1000.0 : 1e-6);
v = 1; /* valid epoch */ v = 1; /* valid epoch */
} }
if ((base=bfact[j<3?0:1])>0.0&&std>0.0) { if ((base = bfact[j < 3 ? 0 : 1]) > 0.0 && std > 0.0)
peph.std[sat-1][j]=(float)(pow(base,std)*(j<3?1E-3:1E-12)); {
peph.std[sat-1][j] = (float)(std::pow(base, std)*(j < 3 ? 1e-3 : 1e-12));
} }
} }
else if (v) { /* velocity */ else if (v) { /* velocity */
if (val!=0.0&&fabs(val-999999.999999)>=1E-6) { if (val != 0.0 && fabs(val - 999999.999999) >= 1e-6)
peph.vel[sat-1][j]=val*(j<3?0.1:1E-10); {
peph.vel[sat-1][j] = val*(j < 3 ? 0.1 : 1e-10);
} }
if ((base=bfact[j<3?0:1])>0.0&&std>0.0) { if ((base = bfact[j < 3 ? 0 : 1]) > 0.0 && std > 0.0)
peph.vst[sat-1][j]=(float)(pow(base,std)*(j<3?1E-7:1E-16)); {
peph.vst[sat-1][j] = (float)(std::pow(base, std)*(j < 3 ? 1e-7 : 1e-16));
} }
} }
} }
} }
if (v) { if (v)
{
if (!addpeph(nav, &peph)) return; if (!addpeph(nav, &peph)) return;
} }
} }
} }
/* compare precise ephemeris -------------------------------------------------*/ /* compare precise ephemeris -------------------------------------------------*/
int cmppeph(const void *p1, const void *p2) int cmppeph(const void *p1, const void *p2)
{ {
peph_t *q1 = (peph_t *)p1, *q2 = (peph_t *)p2; peph_t *q1 = (peph_t *)p1, *q2 = (peph_t *)p2;
double tt = timediff(q1->time, q2->time); double tt = timediff(q1->time, q2->time);
return tt<-1E-9?-1:(tt>1E-9?1:q1->index-q2->index); return tt < -1e-9 ? -1 : (tt > 1e-9 ? 1 : q1->index - q2->index);
} }
/* combine precise ephemeris -------------------------------------------------*/ /* combine precise ephemeris -------------------------------------------------*/
void combpeph(nav_t *nav, int opt) void combpeph(nav_t *nav, int opt)
{ {
@ -258,11 +261,12 @@ void combpeph(nav_t *nav, int opt)
if (opt&4) return; if (opt&4) return;
for (i=0,j=1;j<nav->ne;j++) { for (i = 0, j = 1; j < nav->ne; j++)
{
if (fabs(timediff(nav->peph[i].time,nav->peph[j].time))<1E-9) { if (fabs(timediff(nav->peph[i].time, nav->peph[j].time)) < 1e-9)
{
for (k=0;k<MAXSAT;k++) { for (k = 0; k < MAXSAT; k++)
{
if (norm(nav->peph[j].pos[k], 4) <= 0.0) continue; if (norm(nav->peph[j].pos[k], 4) <= 0.0) continue;
for (m = 0;m < 4; m++) nav->peph[i].pos[k][m] = nav->peph[j].pos[k][m]; for (m = 0;m < 4; m++) nav->peph[i].pos[k][m] = nav->peph[j].pos[k][m];
for (m = 0;m < 4; m++) nav->peph[i].std[k][m] = nav->peph[j].std[k][m]; for (m = 0;m < 4; m++) nav->peph[i].std[k][m] = nav->peph[j].std[k][m];
@ -276,6 +280,8 @@ void combpeph(nav_t *nav, int opt)
trace(4, "combpeph: ne=%d\n", nav->ne); trace(4, "combpeph: ne=%d\n", nav->ne);
} }
/* read sp3 precise ephemeris file --------------------------------------------- /* read sp3 precise ephemeris file ---------------------------------------------
* read sp3 precise ephemeris/clock files and set them to navigation data * read sp3 precise ephemeris/clock files and set them to navigation data
* args : char *file I sp3-c precise ephemeris file * args : char *file I sp3-c precise ephemeris file
@ -300,8 +306,10 @@ void readsp3(const char *file, nav_t *nav, int opt)
trace(3, "readpephs: file=%s\n", file); trace(3, "readpephs: file=%s\n", file);
for (i=0;i<MAXEXFILE;i++) { for (i = 0; i < MAXEXFILE; i++)
if (!(efiles[i]=(char *)malloc(1024))) { {
if (!(efiles[i] = (char *)malloc(1024)))
{
for (i--; i >= 0; i--) free(efiles[i]); for (i--; i >= 0; i--) free(efiles[i]);
return; return;
} }
@ -309,13 +317,15 @@ void readsp3(const char *file, nav_t *nav, int opt)
/* expand wild card in file path */ /* expand wild card in file path */
n = expath(file, efiles, MAXEXFILE); n = expath(file, efiles, MAXEXFILE);
for (i=j=0;i<n;i++) { for (i = j = 0; i < n; i++)
{
if (!(ext = strrchr(efiles[i], '.'))) continue; if (!(ext = strrchr(efiles[i], '.'))) continue;
if (!strstr(ext + 1, "sp3") && !strstr(ext + 1, ".SP3") && if (!strstr(ext + 1, "sp3") && !strstr(ext + 1, ".SP3") &&
!strstr(ext + 1, "eph") && !strstr(ext + 1, ".EPH")) continue; !strstr(ext + 1, "eph") && !strstr(ext + 1, ".EPH")) continue;
if (!(fp=fopen(efiles[i],"r"))) { if (!(fp = fopen(efiles[i], "r")))
{
trace(2, "sp3 file open error %s\n", efiles[i]); trace(2, "sp3 file open error %s\n", efiles[i]);
continue; continue;
} }
@ -332,6 +342,8 @@ void readsp3(const char *file, nav_t *nav, int opt)
/* combine precise ephemeris */ /* combine precise ephemeris */
if (nav->ne > 0) combpeph(nav, opt); if (nav->ne > 0) combpeph(nav, opt);
} }
/* read satellite antenna parameters ------------------------------------------- /* read satellite antenna parameters -------------------------------------------
* read satellite antenna parameters * read satellite antenna parameters
* args : char *file I antenna parameter file * args : char *file I antenna parameter file
@ -350,13 +362,16 @@ int readsap(const char *file, gtime_t time, nav_t *nav)
if (!readpcv(file, &pcvs)) return 0; if (!readpcv(file, &pcvs)) return 0;
for (i=0;i<MAXSAT;i++) { for (i = 0; i < MAXSAT; i++)
{
pcv = searchpcv(i + 1, "", time, &pcvs); pcv = searchpcv(i + 1, "", time, &pcvs);
nav->pcvs[i] = pcv ? *pcv : pcv0; nav->pcvs[i] = pcv ? *pcv : pcv0;
} }
free(pcvs.pcv); free(pcvs.pcv);
return 1; return 1;
} }
/* read dcb parameters file --------------------------------------------------*/ /* read dcb parameters file --------------------------------------------------*/
int readdcbf(const char *file, nav_t *nav, const sta_t *sta) int readdcbf(const char *file, nav_t *nav, const sta_t *sta)
{ {
@ -367,12 +382,13 @@ int readdcbf(const char *file, nav_t *nav, const sta_t *sta)
trace(3, "readdcbf: file=%s\n", file); trace(3, "readdcbf: file=%s\n", file);
if (!(fp=fopen(file,"r"))) { if (!(fp = fopen(file, "r")))
{
trace(2, "dcb parameters file open error: %s\n", file); trace(2, "dcb parameters file open error: %s\n", file);
return 0; return 0;
} }
while (fgets(buff,sizeof(buff),fp)) { while (fgets(buff, sizeof(buff), fp))
{
if (strstr(buff, "DIFFERENTIAL (P1-P2) CODE BIASES")) type = 1; if (strstr(buff, "DIFFERENTIAL (P1-P2) CODE BIASES")) type = 1;
else if (strstr(buff, "DIFFERENTIAL (P1-C1) CODE BIASES")) type = 2; else if (strstr(buff, "DIFFERENTIAL (P1-C1) CODE BIASES")) type = 2;
else if (strstr(buff, "DIFFERENTIAL (P2-C2) CODE BIASES")) type = 3; else if (strstr(buff, "DIFFERENTIAL (P2-C2) CODE BIASES")) type = 3;
@ -381,23 +397,29 @@ int readdcbf(const char *file, nav_t *nav, const sta_t *sta)
if ((cbias = str2num(buff, 26, 9)) == 0.0) continue; if ((cbias = str2num(buff, 26, 9)) == 0.0) continue;
if (sta&&(!strcmp(str1,"G")||!strcmp(str1,"R"))) { /* receiver dcb */ if (sta && (!strcmp(str1, "G") || !strcmp(str1, "R")))
for (i=0;i<MAXRCV;i++) { { /* receiver dcb */
for (i = 0; i < MAXRCV; i++)
{
if (!strcmp(sta[i].name, str2)) break; if (!strcmp(sta[i].name, str2)) break;
} }
if (i<MAXRCV) { if (i < MAXRCV)
{
j = !strcmp(str1, "G") ? 0 : 1; j = !strcmp(str1, "G") ? 0 : 1;
nav->rbias[i][j][type-1]=cbias*1E-9*CLIGHT; /* ns -> m */ nav->rbias[i][j][type-1] = cbias * 1e-9 * SPEED_OF_LIGHT; /* ns -> m */
} }
} }
else if ((sat=satid2no(str1))) { /* satellite dcb */ else if ((sat = satid2no(str1)))
nav->cbias[sat-1][type-1]=cbias*1E-9*CLIGHT; /* ns -> m */ { /* satellite dcb */
nav->cbias[sat-1][type-1] = cbias * 1e-9 * SPEED_OF_LIGHT; /* ns -> m */
} }
} }
fclose(fp); fclose(fp);
return 1; return 1;
} }
/* read dcb parameters --------------------------------------------------------- /* read dcb parameters ---------------------------------------------------------
* read differential code bias (dcb) parameters * read differential code bias (dcb) parameters
* args : char *file I dcb parameters file (wild-card * expanded) * args : char *file I dcb parameters file (wild-card * expanded)
@ -414,24 +436,30 @@ int readdcb(const char *file, nav_t *nav, const sta_t *sta)
trace(3, "readdcb : file=%s\n", file); trace(3, "readdcb : file=%s\n", file);
for (i=0;i<MAXSAT;i++) for (j=0;j<3;j++) { for (i = 0;i < MAXSAT; i++) for (j = 0; j < 3; j++)
{
nav->cbias[i][j] = 0.0; nav->cbias[i][j] = 0.0;
} }
for (i=0;i<MAXEXFILE;i++) { for (i = 0; i < MAXEXFILE; i++)
if (!(efiles[i]=(char *)malloc(1024))) { {
if (!(efiles[i] = (char *)malloc(1024)))
{
for (i--; i >= 0; i--) free(efiles[i]); for (i--; i >= 0; i--) free(efiles[i]);
return 0; return 0;
} }
} }
n = expath(file, efiles, MAXEXFILE); n = expath(file, efiles, MAXEXFILE);
for (i=0;i<n;i++) { for (i = 0; i < n; i++)
{
readdcbf(efiles[i], nav, sta); readdcbf(efiles[i], nav, sta);
} }
for (i = 0; i < MAXEXFILE;i ++) free(efiles[i]); for (i = 0; i < MAXEXFILE;i ++) free(efiles[i]);
return 1; return 1;
} }
/* add satellite fcb ---------------------------------------------------------*/ /* add satellite fcb ---------------------------------------------------------*/
int addfcb(nav_t *nav, gtime_t ts, gtime_t te, int sat, int addfcb(nav_t *nav, gtime_t ts, gtime_t te, int sat,
const double *bias, const double *std) const double *bias, const double *std)
@ -439,25 +467,32 @@ int addfcb(nav_t *nav, gtime_t ts, gtime_t te, int sat,
fcbd_t *nav_fcb; fcbd_t *nav_fcb;
int i, j; int i, j;
if (nav->nf>0&&fabs(timediff(ts,nav->fcb[nav->nf-1].ts))<=1e-3) { if (nav->nf > 0 && fabs(timediff(ts, nav->fcb[nav->nf-1].ts)) <= 1e-3)
for (i=0;i<3;i++) { {
for (i = 0; i < 3; i++)
{
nav->fcb[nav->nf-1].bias[sat-1][i] = bias[i]; nav->fcb[nav->nf-1].bias[sat-1][i] = bias[i];
nav->fcb[nav->nf-1].std [sat-1][i] = std [i]; nav->fcb[nav->nf-1].std [sat-1][i] = std [i];
} }
return 1; return 1;
} }
if (nav->nf>=nav->nfmax) { if (nav->nf >= nav->nfmax)
{
nav->nfmax = nav->nfmax <= 0 ? 2048 : nav->nfmax * 2; nav->nfmax = nav->nfmax <= 0 ? 2048 : nav->nfmax * 2;
if (!(nav_fcb=(fcbd_t *)realloc(nav->fcb,sizeof(fcbd_t)*nav->nfmax))) { if (!(nav_fcb = (fcbd_t *)realloc(nav->fcb, sizeof(fcbd_t)*nav->nfmax)))
free(nav->fcb); nav->nf=nav->nfmax=0; {
free(nav->fcb);
nav->nf = nav->nfmax = 0;
return 0; return 0;
} }
nav->fcb = nav_fcb; nav->fcb = nav_fcb;
} }
for (i=0;i<MAXSAT;i++) for (j=0;j<3;j++) { for (i = 0; i < MAXSAT; i++) for (j = 0; j < 3; j++)
{
nav->fcb[nav->nf].bias[i][j] = nav->fcb[nav->nf].std[i][j] = 0.0; nav->fcb[nav->nf].bias[i][j] = nav->fcb[nav->nf].std[i][j] = 0.0;
} }
for (i=0;i<3;i++) { for (i = 0; i < 3; i++)
{
nav->fcb[nav->nf].bias[sat-1][i] = bias[i]; nav->fcb[nav->nf].bias[sat-1][i] = bias[i];
nav->fcb[nav->nf].std [sat-1][i] = std [i]; nav->fcb[nav->nf].std [sat-1][i] = std [i];
} }
@ -465,6 +500,8 @@ int addfcb(nav_t *nav, gtime_t ts, gtime_t te, int sat,
nav->fcb[nav->nf++].te = te; nav->fcb[nav->nf++].te = te;
return 1; return 1;
} }
/* read satellite fcb file ---------------------------------------------------*/ /* read satellite fcb file ---------------------------------------------------*/
int readfcbf(const char *file, nav_t *nav) int readfcbf(const char *file, nav_t *nav)
{ {
@ -476,11 +513,13 @@ int readfcbf(const char *file, nav_t *nav)
trace(3, "readfcbf: file=%s\n", file); trace(3, "readfcbf: file=%s\n", file);
if (!(fp=fopen(file,"r"))) { if (!(fp = fopen(file, "r")))
{
trace(2, "fcb parameters file open error: %s\n", file); trace(2, "fcb parameters file open error: %s\n", file);
return 0; return 0;
} }
while (fgets(buff,sizeof(buff),fp)) { while (fgets(buff, sizeof(buff), fp))
{
if ((p = strchr(buff, '#'))) *p = '\0'; if ((p = strchr(buff, '#'))) *p = '\0';
if (sscanf(buff, "%lf/%lf/%lf %lf:%lf:%lf %lf/%lf/%lf %lf:%lf:%lf %s" if (sscanf(buff, "%lf/%lf/%lf %lf:%lf:%lf %lf/%lf/%lf %lf:%lf:%lf %s"
"%lf %lf %lf %lf %lf %lf", ep1, ep1+1, ep1+2, ep1+3, ep1+4, ep1+5, "%lf %lf %lf %lf %lf %lf", ep1, ep1+1, ep1+2, ep1+3, ep1+4, ep1+5,
@ -494,13 +533,17 @@ int readfcbf(const char *file, nav_t *nav)
fclose(fp); fclose(fp);
return 1; return 1;
} }
/* compare satellite fcb -----------------------------------------------------*/ /* compare satellite fcb -----------------------------------------------------*/
int cmpfcb(const void *p1, const void *p2) int cmpfcb(const void *p1, const void *p2)
{ {
fcbd_t *q1 = (fcbd_t *)p1, *q2 = (fcbd_t *)p2; fcbd_t *q1 = (fcbd_t *)p1, *q2 = (fcbd_t *)p2;
double tt = timediff(q1->ts, q2->ts); double tt = timediff(q1->ts, q2->ts);
return tt<-1E-3?-1:(tt>1E-3?1:0); return tt < -1e-3 ? -1 : (tt > 1e-3 ? 1 : 0);
} }
/* read satellite fcb data ----------------------------------------------------- /* read satellite fcb data -----------------------------------------------------
* read satellite fractional cycle bias (dcb) parameters * read satellite fractional cycle bias (dcb) parameters
* args : char *file I fcb parameters file (wild-card * expanded) * args : char *file I fcb parameters file (wild-card * expanded)
@ -515,36 +558,46 @@ int readfcb(const char *file, nav_t *nav)
trace(3, "readfcb : file=%s\n", file); trace(3, "readfcb : file=%s\n", file);
for (i=0;i<MAXEXFILE;i++) { for (i = 0; i < MAXEXFILE; i++)
if (!(efiles[i]=(char *)malloc(1024))) { {
if (!(efiles[i] = (char *)malloc(1024)))
{
for (i--; i >= 0; i--) free(efiles[i]); for (i--; i >= 0; i--) free(efiles[i]);
return 0; return 0;
} }
} }
n = expath(file, efiles, MAXEXFILE); n = expath(file, efiles, MAXEXFILE);
for (i=0;i<n;i++) { for (i = 0; i < n; i++)
{
readfcbf(efiles[i], nav); readfcbf(efiles[i], nav);
} }
for (i = 0; i < MAXEXFILE; i++) free(efiles[i]); for (i = 0; i < MAXEXFILE; i++) free(efiles[i]);
if (nav->nf>1) { if (nav->nf > 1)
{
qsort(nav->fcb, nav->nf, sizeof(fcbd_t), cmpfcb); qsort(nav->fcb, nav->nf, sizeof(fcbd_t), cmpfcb);
} }
return 1; return 1;
} }
/* polynomial interpolation by Neville's algorithm ---------------------------*/ /* polynomial interpolation by Neville's algorithm ---------------------------*/
double interppol(const double *x, double *y, int n) double interppol(const double *x, double *y, int n)
{ {
int i, j; int i, j;
for (j=1;j<n;j++) { for (j = 1; j < n; j++)
for (i=0;i<n-j;i++) { {
for (i = 0; i < n - j; i++)
{
y[i] = (x[i+j] * y[i] - x[i] * y[i+1]) / (x[i+j] - x[i]); y[i] = (x[i+j] * y[i] - x[i] * y[i+1]) / (x[i+j] - x[i]);
} }
} }
return y[0]; return y[0];
} }
/* satellite position by precise ephemeris -----------------------------------*/ /* satellite position by precise ephemeris -----------------------------------*/
int pephpos(gtime_t time, int sat, const nav_t *nav, double *rs, int pephpos(gtime_t time, int sat, const nav_t *nav, double *rs,
double *dts, double *vare, double *varc) double *dts, double *vare, double *varc)
@ -558,12 +611,14 @@ int pephpos(gtime_t time, int sat, const nav_t *nav, double *rs,
if (nav->ne < NMAX + 1 || if (nav->ne < NMAX + 1 ||
timediff(time, nav->peph[0].time) < -MAXDTE || timediff(time, nav->peph[0].time) < -MAXDTE ||
timediff(time,nav->peph[nav->ne-1].time)>MAXDTE) { timediff(time, nav->peph[nav->ne-1].time) > MAXDTE)
{
trace(3, "no prec ephem %s sat=%2d\n", time_str(time, 0), sat); trace(3, "no prec ephem %s sat=%2d\n", time_str(time, 0), sat);
return 0; return 0;
} }
/* binary search */ /* binary search */
for (i=0,j=nav->ne-1;i<j;) { for (i = 0, j = nav->ne - 1; i < j;)
{
k = (i + j) / 2; k = (i + j) / 2;
if (timediff(nav->peph[k].time, time) < 0.0) i = k + 1; else j = k; if (timediff(nav->peph[k].time, time) < 0.0) i = k + 1; else j = k;
} }
@ -573,38 +628,43 @@ int pephpos(gtime_t time, int sat, const nav_t *nav, double *rs,
i = index - (NMAX + 1) / 2; i = index - (NMAX + 1) / 2;
if (i < 0) i = 0; else if (i + NMAX >= nav->ne) i = nav->ne - NMAX - 1; if (i < 0) i = 0; else if (i + NMAX >= nav->ne) i = nav->ne - NMAX - 1;
for (j=0;j<=NMAX;j++) { for (j = 0; j <= NMAX; j++)
{
t[j] = timediff(nav->peph[i+j].time, time); t[j] = timediff(nav->peph[i+j].time, time);
if (norm(nav->peph[i+j].pos[sat-1],3)<=0.0) { if (norm(nav->peph[i+j].pos[sat-1], 3) <= 0.0)
{
trace(3, "prec ephem outage %s sat=%2d\n", time_str(time, 0), sat); trace(3, "prec ephem outage %s sat=%2d\n", time_str(time, 0), sat);
return 0; return 0;
} }
} }
for (j=0;j<=NMAX;j++) { for (j = 0;j<=NMAX;j++)
{
pos = nav->peph[i+j].pos[sat-1]; pos = nav->peph[i+j].pos[sat-1];
#if 0 #if 0
p[0][j] = pos[0]; p[0][j] = pos[0];
p[1][j] = pos[1]; p[1][j] = pos[1];
#else #else
/* correciton for earh rotation ver.2.4.0 */ /* correciton for earh rotation ver.2.4.0 */
sinl=sin(OMGE*t[j]); sinl = sin(DEFAULT_OMEGA_EARTH_DOT * t[j]);
cosl=cos(OMGE*t[j]); cosl = cos(DEFAULT_OMEGA_EARTH_DOT * t[j]);
p[0][j] = cosl * pos[0] - sinl * pos[1]; p[0][j] = cosl * pos[0] - sinl * pos[1];
p[1][j] = sinl * pos[0] + cosl * pos[1]; p[1][j] = sinl * pos[0] + cosl * pos[1];
#endif #endif
p[2][j] = pos[2]; p[2][j] = pos[2];
} }
for (i=0;i<3;i++) { for (i = 0; i < 3; i++)
{
rs[i] = interppol(t, p[i], NMAX + 1); rs[i] = interppol(t, p[i], NMAX + 1);
} }
if (vare) { if (vare)
{
for (i = 0; i < 3; i++) s[i] = nav->peph[index].std[sat-1][i]; for (i = 0; i < 3; i++) s[i] = nav->peph[index].std[sat-1][i];
std = norm(s, 3); std = norm(s, 3);
/* extrapolation error for orbit */ /* extrapolation error for orbit */
if (t[0 ]>0.0) std+=EXTERR_EPH*SQR(t[0 ])/2.0; if (t[0 ] > 0.0) std += EXTERR_EPH * std::pow(t[0 ], 2.0) / 2.0;
else if (t[NMAX]<0.0) std+=EXTERR_EPH*SQR(t[NMAX])/2.0; else if (t[NMAX] < 0.0) std += EXTERR_EPH * std::pow(t[NMAX], 2.0) / 2.0;
*vare=SQR(std); *vare = std::pow(std, 2.0);
} }
/* linear interpolation for clock */ /* linear interpolation for clock */
t[0] = timediff(time, nav->peph[index ].time); t[0] = timediff(time, nav->peph[index ].time);
@ -612,27 +672,35 @@ int pephpos(gtime_t time, int sat, const nav_t *nav, double *rs,
c[0] = nav->peph[index ].pos[sat-1][3]; c[0] = nav->peph[index ].pos[sat-1][3];
c[1] = nav->peph[index+1].pos[sat-1][3]; c[1] = nav->peph[index+1].pos[sat-1][3];
if (t[0]<=0.0) { if (t[0] <= 0.0)
if ((dts[0]=c[0])!=0.0) { {
std=nav->peph[index].std[sat-1][3]*CLIGHT-EXTERR_CLK*t[0]; if ((dts[0] = c[0]) != 0.0)
{
std = nav->peph[index].std[sat-1][3] * SPEED_OF_LIGHT - EXTERR_CLK * t[0];
} }
} }
else if (t[1]>=0.0) { else if (t[1] >= 0.0)
if ((dts[0]=c[1])!=0.0) { {
std=nav->peph[index+1].std[sat-1][3]*CLIGHT+EXTERR_CLK*t[1]; if ((dts[0] = c[1]) != 0.0)
{
std = nav->peph[index+1].std[sat-1][3] * SPEED_OF_LIGHT + EXTERR_CLK * t[1];
} }
} }
else if (c[0]!=0.0&&c[1]!=0.0) { else if (c[0] != 0.0 && c[1] != 0.0)
{
dts[0] = (c[1] * t[0] - c[0] * t[1]) / (t[0] - t[1]); dts[0] = (c[1] * t[0] - c[0] * t[1]) / (t[0] - t[1]);
i = t[0] < -t[1] ? 0: 1; i = t[0] < -t[1] ? 0: 1;
std = nav->peph[index+i].std[sat-1][3] + EXTERR_CLK * fabs(t[i]); std = nav->peph[index+i].std[sat-1][3] + EXTERR_CLK * fabs(t[i]);
} }
else { else
{
dts[0] = 0.0; dts[0] = 0.0;
} }
if (varc) *varc=SQR(std); if (varc) *varc = std::pow(std, 2.0);
return 1; return 1;
} }
/* satellite clock by precise clock ------------------------------------------*/ /* satellite clock by precise clock ------------------------------------------*/
int pephclk(gtime_t time, int sat, const nav_t *nav, double *dts, int pephclk(gtime_t time, int sat, const nav_t *nav, double *dts,
double *varc) double *varc)
@ -644,12 +712,14 @@ int pephclk(gtime_t time, int sat, const nav_t *nav, double *dts,
if (nav->nc < 2 || if (nav->nc < 2 ||
timediff(time, nav->pclk[0].time) < -MAXDTE || timediff(time, nav->pclk[0].time) < -MAXDTE ||
timediff(time,nav->pclk[nav->nc-1].time)>MAXDTE) { timediff(time, nav->pclk[nav->nc-1].time) > MAXDTE)
{
trace(3, "no prec clock %s sat=%2d\n", time_str(time, 0), sat); trace(3, "no prec clock %s sat=%2d\n", time_str(time, 0), sat);
return 1; return 1;
} }
/* binary search */ /* binary search */
for (i=0,j=nav->nc-1;i<j;) { for (i = 0, j = nav->nc - 1; i < j;)
{
k = (i + j) / 2; k = (i + j) / 2;
if (timediff(nav->pclk[k].time, time) < 0.0) i = k + 1; else j = k; if (timediff(nav->pclk[k].time, time) < 0.0) i = k + 1; else j = k;
} }
@ -661,26 +731,32 @@ int pephclk(gtime_t time, int sat, const nav_t *nav, double *dts,
c[0] = nav->pclk[index ].clk[sat-1][0]; c[0] = nav->pclk[index ].clk[sat-1][0];
c[1] = nav->pclk[index+1].clk[sat-1][0]; c[1] = nav->pclk[index+1].clk[sat-1][0];
if (t[0]<=0.0) { if (t[0] <= 0.0)
{
if ((dts[0] = c[0]) == 0.0) return 0; if ((dts[0] = c[0]) == 0.0) return 0;
std=nav->pclk[index].std[sat-1][0]*CLIGHT-EXTERR_CLK*t[0]; std = nav->pclk[index].std[sat-1][0] * SPEED_OF_LIGHT - EXTERR_CLK * t[0];
} }
else if (t[1]>=0.0) { else if (t[1] >= 0.0)
{
if ((dts[0] = c[1]) == 0.0) return 0; if ((dts[0] = c[1]) == 0.0) return 0;
std=nav->pclk[index+1].std[sat-1][0]*CLIGHT+EXTERR_CLK*t[1]; std = nav->pclk[index+1].std[sat-1][0] * SPEED_OF_LIGHT + EXTERR_CLK * t[1];
} }
else if (c[0]!=0.0&&c[1]!=0.0) { else if (c[0] != 0.0 && c[1] != 0.0)
{
dts[0] = (c[1]*t[0]-c[0]*t[1]) / (t[0] - t[1]); dts[0] = (c[1]*t[0]-c[0]*t[1]) / (t[0] - t[1]);
i = t[0] < -t[1] ? 0 : 1; i = t[0] < -t[1] ? 0 : 1;
std=nav->pclk[index+i].std[sat-1][0]*CLIGHT+EXTERR_CLK*fabs(t[i]); std = nav->pclk[index+i].std[sat-1][0] * SPEED_OF_LIGHT + EXTERR_CLK * fabs(t[i]);
} }
else { else
{
trace(3, "prec clock outage %s sat=%2d\n", time_str(time, 0), sat); trace(3, "prec clock outage %s sat=%2d\n", time_str(time, 0), sat);
return 0; return 0;
} }
if (varc) *varc=SQR(std); if (varc) *varc = std::pow(std, 2.0);
return 1; return 1;
} }
/* satellite antenna phase center offset --------------------------------------- /* satellite antenna phase center offset ---------------------------------------
* compute satellite antenna phase center offset in ecef * compute satellite antenna phase center offset in ecef
* args : gtime_t time I time (gpst) * args : gtime_t time I time (gpst)
@ -719,17 +795,20 @@ void satantoff(gtime_t time, const double *rs, int sat, const nav_t *nav,
if (NFREQ < 2 || lam[j] == 0.0 || lam[k] == 0.0) return; if (NFREQ < 2 || lam[j] == 0.0 || lam[k] == 0.0) return;
gamma=SQR(lam[k])/SQR(lam[j]); gamma = std::pow(lam[k], 2.0) / std::pow(lam[j], 2.0);
C1 = gamma / (gamma - 1.0); C1 = gamma / (gamma - 1.0);
C2 = -1.0 / (gamma - 1.0); C2 = -1.0 / (gamma - 1.0);
/* iono-free LC */ /* iono-free LC */
for (i=0;i<3;i++) { for (i = 0; i < 3; i++)
{
dant1 = pcv->off[j][0] * ex[i] + pcv->off[j][1] * ey[i] + pcv->off[j][2] * ez[i]; dant1 = pcv->off[j][0] * ex[i] + pcv->off[j][1] * ey[i] + pcv->off[j][2] * ez[i];
dant2 = pcv->off[k][0] * ex[i] + pcv->off[k][1] * ey[i] + pcv->off[k][2] * ez[i]; dant2 = pcv->off[k][0] * ex[i] + pcv->off[k][1] * ey[i] + pcv->off[k][2] * ez[i];
dant[i] = C1 * dant1 + C2 * dant2; dant[i] = C1 * dant1 + C2 * dant2;
} }
} }
/* satellite position/clock by precise ephemeris/clock ------------------------- /* satellite position/clock by precise ephemeris/clock -------------------------
* compute satellite position/clock with precise ephemeris/clock * compute satellite position/clock with precise ephemeris/clock
* args : gtime_t time I time (gpst) * args : gtime_t time I time (gpst)
@ -751,7 +830,7 @@ void satantoff(gtime_t time, const double *rs, int sat, const nav_t *nav,
int peph2pos(gtime_t time, int sat, const nav_t *nav, int opt, int peph2pos(gtime_t time, int sat, const nav_t *nav, int opt,
double *rs, double *dts, double *var) double *rs, double *dts, double *var)
{ {
double rss[3],rst[3],dtss[1],dtst[1],dant[3]={},vare=0.0,varc=0.0,tt=1E-3; double rss[3], rst[3], dtss[1], dtst[1], dant[3] = {}, vare = 0.0, varc = 0.0, tt = 1e-3;
int i; int i;
trace(4, "peph2pos: time=%s sat=%2d opt=%d\n", time_str(time, 3), sat, opt); trace(4, "peph2pos: time=%s sat=%2d opt=%d\n", time_str(time, 3), sat, opt);
@ -767,19 +846,23 @@ int peph2pos(gtime_t time, int sat, const nav_t *nav, int opt,
!pephclk(time, sat, nav, dtst, NULL)) return 0; !pephclk(time, sat, nav, dtst, NULL)) return 0;
/* satellite antenna offset correction */ /* satellite antenna offset correction */
if (opt) { if (opt)
{
satantoff(time, rss, sat, nav, dant); satantoff(time, rss, sat, nav, dant);
} }
for (i=0;i<3;i++) { for (i = 0;i<3;i++)
{
rs[i ] = rss[i] + dant[i]; rs[i ] = rss[i] + dant[i];
rs[i+3] = (rst[i] - rss[i]) / tt; rs[i+3] = (rst[i] - rss[i]) / tt;
} }
/* relativistic effect correction */ /* relativistic effect correction */
if (dtss[0]!=0.0) { if (dtss[0] != 0.0)
dts[0]=dtss[0]-2.0*dot(rs,rs+3,3)/CLIGHT/CLIGHT; {
dts[0] = dtss[0] - 2.0 * dot(rs, rs+3, 3) / SPEED_OF_LIGHT / SPEED_OF_LIGHT;
dts[1] = (dtst[0] - dtss[0]) / tt; dts[1] = (dtst[0] - dtss[0]) / tt;
} }
else { /* no precise clock */ else
{ /* no precise clock */
dts[0] = dts[1] = 0.0; dts[0] = dts[1] = 0.0;
} }
if (var) *var = vare + varc; if (var) *var = vare + varc;

View File

@ -49,7 +49,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* *
* references : * References :
* [1] S.Hilla, The Extended Standard Product 3 Orbit Format (SP3-c), * [1] S.Hilla, The Extended Standard Product 3 Orbit Format (SP3-c),
* 12 February, 2007 * 12 February, 2007
* [2] J.Ray, W.Gurtner, RINEX Extensions to Handle Clock Information, * [2] J.Ray, W.Gurtner, RINEX Extensions to Handle Clock Information,
@ -58,47 +58,19 @@
* [4] D.A.Vallado, Fundamentals of Astrodynamics and Applications 2nd ed, * [4] D.A.Vallado, Fundamentals of Astrodynamics and Applications 2nd ed,
* Space Technology Library, 2004 * Space Technology Library, 2004
* *
* version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $
* history : 2009/01/18 1.0 new
* 2009/01/31 1.1 fix bug on numerical error to read sp3a ephemeris
* 2009/05/15 1.2 support glonass,galileo,qzs
* 2009/12/11 1.3 support wild-card expansion of file path
* 2010/07/21 1.4 added api:
* eci2ecef(),sunmoonpos(),peph2pos(),satantoff(),
* readdcb()
* changed api:
* readsp3()
* deleted api:
* eph2posp()
* 2010/09/09 1.5 fix problem when precise clock outage
* 2011/01/23 1.6 support qzss satellite code
* 2011/09/12 1.7 fix problem on precise clock outage
* move sunmmonpos() to rtkcmn.c
* 2011/12/01 1.8 modify api readsp3()
* precede later ephemeris if ephemeris is NULL
* move eci2ecef() to rtkcmn.c
* 2013/05/08 1.9 fix bug on computing std-dev of precise clocks
* 2013/11/20 1.10 modify option for api readsp3()
* 2014/04/03 1.11 accept extenstion including sp3,eph,SP3,EPH
* 2014/05/23 1.12 add function to read sp3 velocity records
* change api: satantoff()
* 2014/08/31 1.13 add member cov and vco in peph_t sturct
* 2014/10/13 1.14 fix bug on clock error variance in peph2pos()
* 2015/05/10 1.15 add api readfcb()
* modify api readdcb()
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
#ifndef RTKLIB_PRECEPH_H_
#define RTKLIB_PRECEPH_H_ #ifndef GNSS_SDR_RTKLIB_PRECEPH_H_
#define GNSS_SDR_RTKLIB_PRECEPH_H_
#include "rtklib.h" #include "rtklib.h"
#include "rtklib_rtkcmn.h" #include "rtklib_rtkcmn.h"
#define SQR(x) ((x)*(x))
#define NMAX 10 /* order of polynomial interpolation */ const int NMAX = 10; /* order of polynomial interpolation */
#define MAXDTE 900.0 /* max time difference to ephem time (s) */ const double MAXDTE = 900.0; /* max time difference to ephem time (s) */
#define EXTERR_CLK 1E-3 /* extrapolation error for clock (m/s) */ const double EXTERR_CLK = 1e-3; /* extrapolation error for clock (m/s) */
#define EXTERR_EPH 5E-7 /* extrapolation error for ephem (m/s^2) */ const double EXTERR_EPH = 5e-7; /* extrapolation error for ephem (m/s^2) */
int code2sys(char code); int code2sys(char code);
int readsp3h(FILE *fp, gtime_t *time, char *type, int *sats, int readsp3h(FILE *fp, gtime_t *time, char *type, int *sats,
@ -133,4 +105,4 @@ void satantoff(gtime_t time, const double *rs, int sat, const nav_t *nav,
int peph2pos(gtime_t time, int sat, const nav_t *nav, int opt, int peph2pos(gtime_t time, int sat, const nav_t *nav, int opt,
double *rs, double *dts, double *var); double *rs, double *dts, double *var);
#endif //RTKLIB_PRECEPH_H_ #endif // GNSS_SDR_RTKLIB_PRECEPH_H_

File diff suppressed because it is too large Load Diff

View File

@ -82,98 +82,10 @@
* [10] GLONASS/GPS/Galileo/Compass/SBAS NV08C receiver series BINR interface * [10] GLONASS/GPS/Galileo/Compass/SBAS NV08C receiver series BINR interface
* protocol specification ver.1.3, August, 2012 * protocol specification ver.1.3, August, 2012
* *
* version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $
* history : 2007/01/12 1.0 new
* 2007/03/06 1.1 input initial rover pos of pntpos()
* update only effective states of filter()
* fix bug of atan2() domain error
* 2007/04/11 1.2 add function antmodel()
* add gdop mask for pntpos()
* change constant MAXDTOE value
* 2007/05/25 1.3 add function execcmd(),expandpath()
* 2008/06/21 1.4 add funciton sortobs(),uniqeph(),screent()
* replace geodist() by sagnac correction way
* 2008/10/29 1.5 fix bug of ionosphereic mapping function
* fix bug of seasonal variation term of tropmapf
* 2008/12/27 1.6 add function tickget(), sleepms(), tracenav(),
* xyz2enu(), satposv(), pntvel(), covecef()
* 2009/03/12 1.7 fix bug on error-stop when localtime() returns NULL
* 2009/03/13 1.8 fix bug on time adjustment for summer time
* 2009/04/10 1.9 add function adjgpsweek(),getbits(),getbitu()
* add function geph2pos()
* 2009/06/08 1.10 add function seph2pos()
* 2009/11/28 1.11 change function pntpos()
* add function tracegnav(),tracepeph()
* 2009/12/22 1.12 change default parameter of ionos std
* valid under second for timeget()
* 2010/07/28 1.13 fix bug in tropmapf()
* added api:
* obs2code(),code2obs(),cross3(),normv3(),
* gst2time(),time2gst(),time_str(),timeset(),
* deg2dms(),dms2deg(),searchpcv(),antmodel_s(),
* tracehnav(),tracepclk(),reppath(),reppaths(),
* createdir()
* changed api:
* readpcv(),
* deleted api:
* uniqeph()
* 2010/08/20 1.14 omit to include mkl header files
* fix bug on chi-sqr(n) table
* 2010/12/11 1.15 added api:
* freeobs(),freenav(),ionppp()
* 2011/05/28 1.16 fix bug on half-hour offset by time2epoch()
* added api:
* uniqnav()
* 2012/06/09 1.17 add a leap second after 2012-6-30
* 2012/07/15 1.18 add api setbits(),setbitu(),utc2gmst()
* fix bug on interpolation of antenna pcv
* fix bug on str2num() for string with over 256 char
* add api readblq(),satexclude(),setcodepri(),
* getcodepri()
* change api obs2code(),code2obs(),antmodel()
* 2012/12/25 1.19 fix bug on satwavelen(),code2obs(),obs2code()
* add api testsnr()
* 2013/01/04 1.20 add api gpst2bdt(),bdt2gpst(),bdt2time(),time2bdt()
* readblq(),readerp(),geterp(),crc16()
* change api eci2ecef(),sunmoonpos()
* 2013/03/26 1.21 tickget() uses clock_gettime() for linux
* 2013/05/08 1.22 fix bug on nutation coefficients for ast_args()
* 2013/06/02 1.23 add #ifdef for undefined CLOCK_MONOTONIC_RAW
* 2013/09/01 1.24 fix bug on interpolation of satellite antenna pcv
* 2013/09/06 1.25 fix bug on extrapolation of erp
* 2014/04/27 1.26 add SYS_LEO for satellite system
* add BDS L1 code for RINEX 3.02 and RTCM 3.2
* support BDS L1 in satwavelen()
* 2014/05/29 1.27 fix bug on obs2code() to search obs code table
* 2014/08/26 1.28 fix problem on output of uncompress() for tar file
* add function to swap trace file with keywords
* 2014/10/21 1.29 strtok() -> strtok_r() in expath() for thread-safe
* add bdsmodear in procopt_default
* 2015/03/19 1.30 fix bug on interpolation of erp values in geterp()
* add leap second insertion before 2015/07/01 00:00
* add api read_leaps()
* 2015/05/31 1.31 delte api windupcorr()
* 2015/08/08 1.32 add compile option CPUTIME_IN_GPST
* add api add_fatal()
* support usno leapsec.dat for api read_leaps()
* 2016/01/23 1.33 enable septentrio
* 2016/02/05 1.34 support GLONASS for savenav(), loadnav()
* 2016/06/11 1.35 delete trace() in reppath() to avoid deadlock
* 2016/07/01 1.36 support IRNSS
* add leap second before 2017/1/1 00:00:00
* 2016/07/29 1.37 rename api compress() -> rtk_uncompress()
* rename api crc16() -> rtk_crc16()
* rename api crc24q() -> rtk_crc24q()
* rename api crc32() -> rtk_crc32()
* 2016/08/20 1.38 fix type incompatibility in win64 environment
* change constant _POSIX_C_SOURCE 199309 -> 199506
* 2016/08/21 1.39 fix bug on week overflow in time2gpst()/gpst2time()
* 2016/09/05 1.40 fix bug on invalid nav data read in readnav()
* 2016/09/17 1.41 suppress warnings
* 2016/09/19 1.42 modify api deg2dms() to consider numerical error
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
#ifndef RTKLIB_RTKCMN_H_
#define RTKLIB_RTKCMN_H_ #ifndef GNSS_SDR_RTKLIB_RTKCMN_H_
#define GNSS_SDR_RTKLIB_RTKCMN_H_
#include "rtklib.h" #include "rtklib.h"
@ -307,19 +219,19 @@ int savenav(const char *file, const nav_t *nav);
void freeobs(obs_t *obs); void freeobs(obs_t *obs);
void freenav(nav_t *nav, int opt); void freenav(nav_t *nav, int opt);
void traceopen(const char *file); //void traceopen(const char *file);
void traceclose(void); //void traceclose(void);
void tracelevel(int level); //void tracelevel(int level);
void trace (int level, const char *format, ...); void trace (int level, const char *format, ...);
void tracet (int level, const char *format, ...); //void tracet (int level, const char *format, ...);
void tracemat(int level, const double *A, int n, int m, int p, int q); //void tracemat(int level, const double *A, int n, int m, int p, int q);
void traceobs(int level, const obsd_t *obs, int n); //void traceobs(int level, const obsd_t *obs, int n);
void tracenav(int level, const nav_t *nav); //void tracenav(int level, const nav_t *nav);
void tracegnav(int level, const nav_t *nav); //void tracegnav(int level, const nav_t *nav);
void tracehnav(int level, const nav_t *nav); //void tracehnav(int level, const nav_t *nav);
void tracepeph(int level, const nav_t *nav); //void tracepeph(int level, const nav_t *nav);
void tracepclk(int level, const nav_t *nav); //void tracepclk(int level, const nav_t *nav);
void traceb (int level, const unsigned char *p, int n); //void traceb (int level, const unsigned char *p, int n);
int execcmd(const char *cmd); int execcmd(const char *cmd);
void createdir(const char *path); void createdir(const char *path);
@ -360,4 +272,4 @@ void csmooth(obs_t *obs, int ns);
int rtk_uncompress(const char *file, char *uncfile); int rtk_uncompress(const char *file, char *uncfile);
int expath(const char *path, char *paths[], int nmax); int expath(const char *path, char *paths[], int nmax);
#endif /* RTKLIB_RTKCMN_H_ */ #endif /* GNSS_SDR_RTKLIB_RTKCMN_H_ */

View File

@ -51,7 +51,7 @@
* *
* option : -DRRCENA enable rrc correction * option : -DRRCENA enable rrc correction
* *
* references : * References :
* [1] RTCA/DO-229C, Minimum operational performanc standards for global * [1] RTCA/DO-229C, Minimum operational performanc standards for global
* positioning system/wide area augmentation system airborne equipment, * positioning system/wide area augmentation system airborne equipment,
* RTCA inc, November 28, 2001 * RTCA inc, November 28, 2001
@ -59,28 +59,6 @@
* Interface Specification for QZSS, Japan Aerospace Exploration Agency, * Interface Specification for QZSS, Japan Aerospace Exploration Agency,
* July 31, 2009 * July 31, 2009
* *
* version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $
* history : 2007/10/14 1.0 new
* 2009/01/24 1.1 modify sbspntpos() api
* improve fast/ion correction update
* 2009/04/08 1.2 move function crc24q() to rcvlog.c
* support glonass, galileo and qzss
* 2009/06/08 1.3 modify sbsupdatestat()
* delete sbssatpos()
* 2009/12/12 1.4 support glonass
* 2010/01/22 1.5 support ems (egnos message service) format
* 2010/06/10 1.6 added api:
* sbssatcorr(),sbstropcorr(),sbsioncorr(),
* sbsupdatecorr()
* changed api:
* sbsreadmsgt(),sbsreadmsg()
* deleted api:
* sbspntpos(),sbsupdatestat()
* 2010/08/16 1.7 not reject udre==14 or give==15 correction message
* (2.4.0_p4)
* 2011/01/15 1.8 use api ionppp()
* add prn mask of qzss for qzss L1SAIF
* 2016/07/29 1.9 crc24q() -> rtk_crc24q()
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
#include "rtklib_sbas.h" #include "rtklib_sbas.h"
@ -91,6 +69,8 @@ char *getfield(char *p, int pos)
for (pos--; pos > 0 ; pos--, p++) if (!(p = strchr(p, ','))) return NULL; for (pos--; pos > 0 ; pos--, p++) if (!(p = strchr(p, ','))) return NULL;
return p; return p;
} }
/* variance of fast correction (udre=UDRE+1) ---------------------------------*/ /* variance of fast correction (udre=UDRE+1) ---------------------------------*/
double varfcorr(int udre) double varfcorr(int udre)
{ {
@ -100,6 +80,8 @@ double varfcorr(int udre)
}; };
return 0 < udre && udre <= 14 ? var[udre-1] : 0.0; return 0 < udre && udre <= 14 ? var[udre-1] : 0.0;
} }
/* variance of ionosphere correction (give=GIVEI+1) --------------------------*/ /* variance of ionosphere correction (give=GIVEI+1) --------------------------*/
double varicorr(int give) double varicorr(int give)
{ {
@ -109,6 +91,8 @@ double varicorr(int give)
}; };
return 0 < give && give <= 15 ? var[give-1] : 0.0; return 0 < give && give <= 15 ? var[give-1] : 0.0;
} }
/* fast correction degradation -----------------------------------------------*/ /* fast correction degradation -----------------------------------------------*/
double degfcorr(int ai) double degfcorr(int ai)
{ {
@ -118,6 +102,8 @@ double degfcorr(int ai)
}; };
return 0 < ai && ai <= 15 ? degf[ai] : 0.0058; return 0 < ai && ai <= 15 ? degf[ai] : 0.0058;
} }
/* decode type 1: prn masks --------------------------------------------------*/ /* decode type 1: prn masks --------------------------------------------------*/
int decode_sbstype1(const sbsmsg_t *msg, sbssat_t *sbssat) int decode_sbstype1(const sbsmsg_t *msg, sbssat_t *sbssat)
{ {
@ -125,8 +111,10 @@ int decode_sbstype1(const sbsmsg_t *msg, sbssat_t *sbssat)
trace(4, "decode_sbstype1:\n"); trace(4, "decode_sbstype1:\n");
for (i=1,n=0;i<=210&&n<MAXSAT;i++) { for (i = 1, n = 0;i<=210 && n<MAXSAT;i++)
if (getbitu(msg->msg,13+i,1)) { {
if (getbitu(msg->msg, 13+i, 1))
{
if (i<= 37) sat = satno(SYS_GPS, i); /* 0- 37: gps */ if (i<= 37) sat = satno(SYS_GPS, i); /* 0- 37: gps */
else if (i<= 61) sat = satno(SYS_GLO, i-37); /* 38- 61: glonass */ else if (i<= 61) sat = satno(SYS_GLO, i-37); /* 38- 61: glonass */
else if (i<=119) sat = 0; /* 62-119: future gnss */ else if (i<=119) sat = 0; /* 62-119: future gnss */
@ -144,6 +132,8 @@ int decode_sbstype1(const sbsmsg_t *msg, sbssat_t *sbssat)
trace(5, "decode_sbstype1: nprn=%d iodp=%d\n", n, sbssat->iodp); trace(5, "decode_sbstype1: nprn=%d iodp=%d\n", n, sbssat->iodp);
return 1; return 1;
} }
/* decode type 2-5,0: fast corrections ---------------------------------------*/ /* decode type 2-5,0: fast corrections ---------------------------------------*/
int decode_sbstype2(const sbsmsg_t *msg, sbssat_t *sbssat) int decode_sbstype2(const sbsmsg_t *msg, sbssat_t *sbssat)
{ {
@ -158,7 +148,8 @@ int decode_sbstype2(const sbsmsg_t *msg, sbssat_t *sbssat)
type = getbitu(msg->msg, 8, 6); type = getbitu(msg->msg, 8, 6);
iodf = getbitu(msg->msg, 14, 2); iodf = getbitu(msg->msg, 14, 2);
for (i=0;i<13;i++) { for (i = 0; i < 13; i++)
{
if ((j = 13 * ((type == 0 ? 2 : type) - 2) + i) >= sbssat->nsat) break; if ((j = 13 * ((type == 0 ? 2 : type) - 2) + i) >= sbssat->nsat) break;
udre = getbitu(msg->msg, 174+4*i, 4); udre = getbitu(msg->msg, 174+4*i, 4);
t0 = sbssat->sat[j].fcorr.t0; t0 = sbssat->sat[j].fcorr.t0;
@ -167,11 +158,13 @@ int decode_sbstype2(const sbsmsg_t *msg, sbssat_t *sbssat)
sbssat->sat[j].fcorr.prc = getbits(msg->msg, 18 + i * 12, 12) * 0.125f; sbssat->sat[j].fcorr.prc = getbits(msg->msg, 18 + i * 12, 12) * 0.125f;
sbssat->sat[j].fcorr.udre = udre + 1; sbssat->sat[j].fcorr.udre = udre + 1;
dt = timediff(sbssat->sat[j].fcorr.t0, t0); dt = timediff(sbssat->sat[j].fcorr.t0, t0);
if (t0.time==0||dt<=0.0||18.0<dt||sbssat->sat[j].fcorr.ai==0) { if (t0.time == 0||dt <= 0.0 || 18.0 < dt || sbssat->sat[j].fcorr.ai == 0)
{
sbssat->sat[j].fcorr.rrc = 0.0; sbssat->sat[j].fcorr.rrc = 0.0;
sbssat->sat[j].fcorr.dt = 0.0; sbssat->sat[j].fcorr.dt = 0.0;
} }
else { else
{
sbssat->sat[j].fcorr.rrc = (sbssat->sat[j].fcorr.prc-prc) / dt; sbssat->sat[j].fcorr.rrc = (sbssat->sat[j].fcorr.prc-prc) / dt;
sbssat->sat[j].fcorr.dt = dt; sbssat->sat[j].fcorr.dt = dt;
} }
@ -180,6 +173,8 @@ int decode_sbstype2(const sbsmsg_t *msg, sbssat_t *sbssat)
trace(5, "decode_sbstype2: type=%d iodf=%d\n", type, iodf); trace(5, "decode_sbstype2: type=%d iodf=%d\n", type, iodf);
return 1; return 1;
} }
/* decode type 6: integrity info ---------------------------------------------*/ /* decode type 6: integrity info ---------------------------------------------*/
int decode_sbstype6(const sbsmsg_t *msg, sbssat_t *sbssat) int decode_sbstype6(const sbsmsg_t *msg, sbssat_t *sbssat)
{ {
@ -187,10 +182,12 @@ int decode_sbstype6(const sbsmsg_t *msg, sbssat_t *sbssat)
trace(4, "decode_sbstype6:\n"); trace(4, "decode_sbstype6:\n");
for (i=0;i<4;i++) { for (i = 0;i<4;i++)
{
iodf[i] = getbitu(msg->msg, 14+i*2, 2); iodf[i] = getbitu(msg->msg, 14+i*2, 2);
} }
for (i=0;i<sbssat->nsat&&i<MAXSAT;i++) { for (i = 0;i<sbssat->nsat && i<MAXSAT;i++)
{
if (sbssat->sat[i].fcorr.iodf != iodf[i/13]) continue; if (sbssat->sat[i].fcorr.iodf != iodf[i/13]) continue;
udre = getbitu(msg->msg, 22+i*4, 4); udre = getbitu(msg->msg, 22+i*4, 4);
sbssat->sat[i].fcorr.udre = udre+1; sbssat->sat[i].fcorr.udre = udre+1;
@ -198,6 +195,8 @@ int decode_sbstype6(const sbsmsg_t *msg, sbssat_t *sbssat)
trace(5, "decode_sbstype6: iodf=%d %d %d %d\n", iodf[0], iodf[1], iodf[2], iodf[3]); trace(5, "decode_sbstype6: iodf=%d %d %d %d\n", iodf[0], iodf[1], iodf[2], iodf[3]);
return 1; return 1;
} }
/* decode type 7: fast correction degradation factor -------------------------*/ /* decode type 7: fast correction degradation factor -------------------------*/
int decode_sbstype7(const sbsmsg_t *msg, sbssat_t *sbssat) int decode_sbstype7(const sbsmsg_t *msg, sbssat_t *sbssat)
{ {
@ -209,11 +208,14 @@ int decode_sbstype7(const sbsmsg_t *msg, sbssat_t *sbssat)
sbssat->tlat = getbitu(msg->msg, 14, 4); sbssat->tlat = getbitu(msg->msg, 14, 4);
for (i=0;i<sbssat->nsat&&i<MAXSAT;i++) { for (i = 0;i<sbssat->nsat && i<MAXSAT;i++)
{
sbssat->sat[i].fcorr.ai = getbitu(msg->msg, 22+i*4, 4); sbssat->sat[i].fcorr.ai = getbitu(msg->msg, 22+i*4, 4);
} }
return 1; return 1;
} }
/* decode type 9: geo navigation message -------------------------------------*/ /* decode type 9: geo navigation message -------------------------------------*/
int decode_sbstype9(const sbsmsg_t *msg, nav_t *nav) int decode_sbstype9(const sbsmsg_t *msg, nav_t *nav)
{ {
@ -222,7 +224,8 @@ int decode_sbstype9(const sbsmsg_t *msg, nav_t *nav)
trace(4, "decode_sbstype9:\n"); trace(4, "decode_sbstype9:\n");
if (!(sat=satno(SYS_SBS,msg->prn))) { if (!(sat = satno(SYS_SBS, msg->prn)))
{
trace(2, "invalid prn in sbas type 9: prn=%3d\n", msg->prn); trace(2, "invalid prn in sbas type 9: prn=%3d\n", msg->prn);
return 0; return 0;
} }
@ -245,11 +248,12 @@ int decode_sbstype9(const sbsmsg_t *msg, nav_t *nav)
seph.acc[1] = getbits(msg->msg, 186, 10)*0.0000125; seph.acc[1] = getbits(msg->msg, 186, 10)*0.0000125;
seph.acc[2] = getbits(msg->msg, 196, 10)*0.0000625; seph.acc[2] = getbits(msg->msg, 196, 10)*0.0000625;
seph.af0=getbits(msg->msg,206,12)*P2_31; seph.af0 = getbits(msg->msg, 206, 12)*TWO_N31;
seph.af1=getbits(msg->msg,218, 8)*P2_39/2.0; seph.af1 = getbits(msg->msg, 218, 8)*TWO_N39/2.0;
i = msg->prn-MINPRNSBS; i = msg->prn-MINPRNSBS;
if (!nav->seph||fabs(timediff(nav->seph[i].t0,seph.t0))<1E-3) { /* not change */ if (!nav->seph||fabs(timediff(nav->seph[i].t0, seph.t0))<1e-3)
{ /* not change */
return 0; return 0;
} }
nav->seph[NSATSBS+i] = nav->seph[i]; /* previous */ nav->seph[NSATSBS+i] = nav->seph[i]; /* previous */
@ -258,6 +262,8 @@ int decode_sbstype9(const sbsmsg_t *msg, nav_t *nav)
trace(5, "decode_sbstype9: prn=%d\n", msg->prn); trace(5, "decode_sbstype9: prn=%d\n", msg->prn);
return 1; return 1;
} }
/* decode type 18: ionospheric grid point masks ------------------------------*/ /* decode type 18: ionospheric grid point masks ------------------------------*/
int decode_sbstype18(const sbsmsg_t *msg, sbsion_t *sbsion) int decode_sbstype18(const sbsmsg_t *msg, sbsion_t *sbsion)
{ {
@ -272,9 +278,11 @@ int decode_sbstype18(const sbsmsg_t *msg, sbsion_t *sbsion)
sbsion[band].iodi = (short)getbitu(msg->msg, 22, 2); sbsion[band].iodi = (short)getbitu(msg->msg, 22, 2);
for (i=1,n=0;i<=201;i++) { for (i = 1, n = 0; i<= 201;i++)
{
if (!getbitu(msg->msg , 23 + i, 1)) continue; if (!getbitu(msg->msg , 23 + i, 1)) continue;
for (j=0;j<m;j++) { for (j = 0; j < m; j++)
{
if (i < p[j].bits || p[j].bite < i) continue; if (i < p[j].bits || p[j].bite < i) continue;
sbsion[band].igp[n].lat = band <= 8 ? p[j].y[i - p[j].bits] : p[j].x; sbsion[band].igp[n].lat = band <= 8 ? p[j].y[i - p[j].bits] : p[j].x;
sbsion[band].igp[n++].lon = band <= 8 ? p[j].x : p[j].y[i - p[j].bits]; sbsion[band].igp[n++].lon = band <= 8 ? p[j].x : p[j].y[i - p[j].bits];
@ -286,6 +294,8 @@ int decode_sbstype18(const sbsmsg_t *msg, sbsion_t *sbsion)
trace(5, "decode_sbstype18: band=%d nigp=%d\n", band, n); trace(5, "decode_sbstype18: band=%d nigp=%d\n", band, n);
return 1; return 1;
} }
/* decode half long term correction (vel code=0) -----------------------------*/ /* decode half long term correction (vel code=0) -----------------------------*/
int decode_longcorr0(const sbsmsg_t *msg, int p, sbssat_t *sbssat) int decode_longcorr0(const sbsmsg_t *msg, int p, sbssat_t *sbssat)
{ {
@ -297,17 +307,20 @@ int decode_longcorr0(const sbsmsg_t *msg, int p, sbssat_t *sbssat)
sbssat->sat[n-1].lcorr.iode = getbitu(msg->msg, p+6, 8); sbssat->sat[n-1].lcorr.iode = getbitu(msg->msg, p+6, 8);
for (i=0;i<3;i++) { for (i = 0;i<3;i++)
{
sbssat->sat[n-1].lcorr.dpos[i] = getbits(msg->msg, p+14+9*i, 9)*0.125; sbssat->sat[n-1].lcorr.dpos[i] = getbits(msg->msg, p+14+9*i, 9)*0.125;
sbssat->sat[n-1].lcorr.dvel[i] = 0.0; sbssat->sat[n-1].lcorr.dvel[i] = 0.0;
} }
sbssat->sat[n-1].lcorr.daf0=getbits(msg->msg,p+41,10)*P2_31; sbssat->sat[n-1].lcorr.daf0 = getbits(msg->msg, p + 41, 10) * TWO_N31;
sbssat->sat[n-1].lcorr.daf1 = 0.0; sbssat->sat[n-1].lcorr.daf1 = 0.0;
sbssat->sat[n-1].lcorr.t0 = gpst2time(msg->week, msg->tow); sbssat->sat[n-1].lcorr.t0 = gpst2time(msg->week, msg->tow);
trace(5, "decode_longcorr0:sat=%2d\n", sbssat->sat[n-1].sat); trace(5, "decode_longcorr0:sat=%2d\n", sbssat->sat[n-1].sat);
return 1; return 1;
} }
/* decode half long term correction (vel code=1) -----------------------------*/ /* decode half long term correction (vel code=1) -----------------------------*/
int decode_longcorr1(const sbsmsg_t *msg, int p, sbssat_t *sbssat) int decode_longcorr1(const sbsmsg_t *msg, int p, sbssat_t *sbssat)
{ {
@ -319,12 +332,13 @@ int decode_longcorr1(const sbsmsg_t *msg, int p, sbssat_t *sbssat)
sbssat->sat[n-1].lcorr.iode = getbitu(msg->msg, p+6, 8); sbssat->sat[n-1].lcorr.iode = getbitu(msg->msg, p+6, 8);
for (i=0;i<3;i++) { for (i = 0;i<3;i++)
{
sbssat->sat[n-1].lcorr.dpos[i] = getbits(msg->msg, p + 14 + i * 11, 11) * 0.125; sbssat->sat[n-1].lcorr.dpos[i] = getbits(msg->msg, p + 14 + i * 11, 11) * 0.125;
sbssat->sat[n-1].lcorr.dvel[i]=getbits(msg->msg,p+58+i* 8, 8)*P2_11; sbssat->sat[n-1].lcorr.dvel[i] = getbits(msg->msg, p + 58 + i * 8, 8) * TWO_N11;
} }
sbssat->sat[n-1].lcorr.daf0=getbits(msg->msg,p+47,11)*P2_31; sbssat->sat[n-1].lcorr.daf0 = getbits(msg->msg, p+47, 11) * TWO_N31;
sbssat->sat[n-1].lcorr.daf1=getbits(msg->msg,p+82, 8)*P2_39; sbssat->sat[n-1].lcorr.daf1 = getbits(msg->msg, p+82, 8) * TWO_N39;
t = (int)getbitu(msg->msg, p+90, 13)*16-(int)msg->tow%86400; t = (int)getbitu(msg->msg, p+90, 13)*16-(int)msg->tow%86400;
if (t<=-43200) t+=86400; if (t<=-43200) t+=86400;
else if (t> 43200) t-=86400; else if (t> 43200) t-=86400;
@ -333,22 +347,28 @@ int decode_longcorr1(const sbsmsg_t *msg, int p, sbssat_t *sbssat)
trace(5, "decode_longcorr1: sat=%2d\n", sbssat->sat[n-1].sat); trace(5, "decode_longcorr1: sat=%2d\n", sbssat->sat[n-1].sat);
return 1; return 1;
} }
/* decode half long term correction ------------------------------------------*/ /* decode half long term correction ------------------------------------------*/
int decode_longcorrh(const sbsmsg_t *msg, int p, sbssat_t *sbssat) int decode_longcorrh(const sbsmsg_t *msg, int p, sbssat_t *sbssat)
{ {
trace(4, "decode_longcorrh:\n"); trace(4, "decode_longcorrh:\n");
if (getbitu(msg->msg, p, 1) == 0) { /* vel code=0 */ if (getbitu(msg->msg, p, 1) == 0) { /* vel code=0 */
if (sbssat->iodp==(int)getbitu(msg->msg,p+103,2)) { if (sbssat->iodp == (int)getbitu(msg->msg, p+103, 2))
{
return decode_longcorr0(msg, p+ 1, sbssat) && return decode_longcorr0(msg, p+ 1, sbssat) &&
decode_longcorr0(msg, p+52, sbssat); decode_longcorr0(msg, p+52, sbssat);
} }
} }
else if (sbssat->iodp==(int)getbitu(msg->msg,p+104,2)) { else if (sbssat->iodp == (int)getbitu(msg->msg, p+104, 2))
{
return decode_longcorr1(msg, p+1, sbssat); return decode_longcorr1(msg, p+1, sbssat);
} }
return 0; return 0;
} }
/* decode type 24: mixed fast/long term correction ---------------------------*/ /* decode type 24: mixed fast/long term correction ---------------------------*/
int decode_sbstype24(const sbsmsg_t *msg, sbssat_t *sbssat) int decode_sbstype24(const sbsmsg_t *msg, sbssat_t *sbssat)
{ {
@ -361,7 +381,8 @@ int decode_sbstype24(const sbsmsg_t *msg, sbssat_t *sbssat)
blk = getbitu(msg->msg, 112, 2); blk = getbitu(msg->msg, 112, 2);
iodf = getbitu(msg->msg, 114, 2); iodf = getbitu(msg->msg, 114, 2);
for (i=0;i<6;i++) { for (i = 0;i<6;i++)
{
if ((j = 13*blk+i)>=sbssat->nsat) break; if ((j = 13*blk+i)>=sbssat->nsat) break;
udre = getbitu(msg->msg, 86+4*i, 4); udre = getbitu(msg->msg, 86+4*i, 4);
@ -372,6 +393,8 @@ int decode_sbstype24(const sbsmsg_t *msg, sbssat_t *sbssat)
} }
return decode_longcorrh(msg, 120, sbssat); return decode_longcorrh(msg, 120, sbssat);
} }
/* decode type 25: long term satellite error correction ----------------------*/ /* decode type 25: long term satellite error correction ----------------------*/
int decode_sbstype25(const sbsmsg_t *msg, sbssat_t *sbssat) int decode_sbstype25(const sbsmsg_t *msg, sbssat_t *sbssat)
{ {
@ -379,6 +402,8 @@ int decode_sbstype25(const sbsmsg_t *msg, sbssat_t *sbssat)
return decode_longcorrh(msg, 14, sbssat) && decode_longcorrh(msg, 120, sbssat); return decode_longcorrh(msg, 14, sbssat) && decode_longcorrh(msg, 120, sbssat);
} }
/* decode type 26: ionospheric deley corrections -----------------------------*/ /* decode type 26: ionospheric deley corrections -----------------------------*/
int decode_sbstype26(const sbsmsg_t *msg, sbsion_t *sbsion) int decode_sbstype26(const sbsmsg_t *msg, sbsion_t *sbsion)
{ {
@ -390,7 +415,8 @@ int decode_sbstype26(const sbsmsg_t *msg, sbsion_t *sbsion)
block = getbitu(msg->msg, 18, 4); block = getbitu(msg->msg, 18, 4);
for (i=0;i<15;i++) { for (i = 0;i<15;i++)
{
if ((j = block*15+i) >= sbsion[band].nigp) continue; if ((j = block*15+i) >= sbsion[band].nigp) continue;
give = getbitu(msg->msg, 22+i*13+9, 4); give = getbitu(msg->msg, 22+i*13+9, 4);
@ -399,13 +425,16 @@ int decode_sbstype26(const sbsmsg_t *msg, sbsion_t *sbsion)
sbsion[band].igp[j].delay = delay == 0x1FF ? 0.0f : delay * 0.125f; sbsion[band].igp[j].delay = delay == 0x1FF ? 0.0f : delay * 0.125f;
sbsion[band].igp[j].give = give+1; sbsion[band].igp[j].give = give+1;
if (sbsion[band].igp[j].give>=16) { if (sbsion[band].igp[j].give>=16)
{
sbsion[band].igp[j].give = 0; sbsion[band].igp[j].give = 0;
} }
} }
trace(5, "decode_sbstype26: band=%d block=%d\n", band, block); trace(5, "decode_sbstype26: band=%d block=%d\n", band, block);
return 1; return 1;
} }
/* update sbas corrections ----------------------------------------------------- /* update sbas corrections -----------------------------------------------------
* update sbas correction parameters in navigation data with a sbas message * update sbas correction parameters in navigation data with a sbas message
* args : sbsmg_t *msg I sbas message * args : sbsmg_t *msg I sbas message
@ -423,7 +452,8 @@ int sbsupdatecorr(const sbsmsg_t *msg, nav_t *nav)
if (msg->week == 0) return -1; if (msg->week == 0) return -1;
switch (type) { switch (type)
{
case 0: stat = decode_sbstype2 (msg, &nav->sbssat); break; case 0: stat = decode_sbstype2 (msg, &nav->sbssat); break;
case 1: stat = decode_sbstype1 (msg, &nav->sbssat); break; case 1: stat = decode_sbstype1 (msg, &nav->sbssat); break;
case 2: case 2:
@ -443,6 +473,8 @@ int sbsupdatecorr(const sbsmsg_t *msg, nav_t *nav)
} }
return stat ? type : -1; return stat ? type : -1;
} }
/* read sbas log file --------------------------------------------------------*/ /* read sbas log file --------------------------------------------------------*/
void readmsgs(const char *file, int sel, gtime_t ts, gtime_t te, void readmsgs(const char *file, int sel, gtime_t ts, gtime_t te,
sbs_t *sbs) sbs_t *sbs)
@ -457,29 +489,35 @@ void readmsgs(const char *file, int sel, gtime_t ts, gtime_t te,
trace(3, "readmsgs: file=%s sel=%d\n", file, sel); trace(3, "readmsgs: file=%s sel=%d\n", file, sel);
if (!(fp=fopen(file,"r"))) { if (!(fp = fopen(file, "r")))
{
trace(2, "sbas message file open error: %s\n", file); trace(2, "sbas message file open error: %s\n", file);
return; return;
} }
while (fgets(buff,sizeof(buff),fp)) { while (fgets(buff, sizeof(buff), fp))
if (sscanf(buff,"%d %lf %d",&week,&tow,&prn)==3&&(p=strstr(buff,": "))) { {
if (sscanf(buff, "%d %lf %d", &week, &tow, &prn) == 3 && (p = strstr(buff, ": ")))
{
p+=2; /* rtklib form */ p+=2; /* rtklib form */
} }
else if (sscanf(buff, "%d %lf %lf %lf %lf %lf %lf %d", else if (sscanf(buff, "%d %lf %lf %lf %lf %lf %lf %d",
&prn,ep,ep+1,ep+2,ep+3,ep+4,ep+5,&msg)==8) { &prn, ep, ep+1, ep+2, ep+3, ep+4, ep+5, &msg) == 8)
{
/* ems (EGNOS Message Service) form */ /* ems (EGNOS Message Service) form */
ep[0] += ep[0] < 70.0 ? 2000.0 : 1900.0; ep[0] += ep[0] < 70.0 ? 2000.0 : 1900.0;
tow = time2gpst(epoch2time(ep), &week); tow = time2gpst(epoch2time(ep), &week);
p = buff + (msg >= 10 ? 25 : 24); p = buff + (msg >= 10 ? 25 : 24);
} }
else if (!strncmp(buff,"#RAWWAASFRAMEA",14)) { /* NovAtel OEM4/V */ else if (!strncmp(buff,"#RAWWAASFRAMEA",14))
{ /* NovAtel OEM4/V */
if (!(p = getfield(buff,6))) continue; if (!(p = getfield(buff,6))) continue;
if (sscanf(p,"%d,%lf", &week, &tow) < 2) continue; if (sscanf(p,"%d,%lf", &week, &tow) < 2) continue;
if (!(p = strchr(++p, ';'))) continue; if (!(p = strchr(++p, ';'))) continue;
if (sscanf(++p, "%d,%d", &ch, &prn) < 2) continue; if (sscanf(++p, "%d,%d", &ch, &prn) < 2) continue;
if (!(p = getfield(p, 4))) continue; if (!(p = getfield(p, 4))) continue;
} }
else if (!strncmp(buff,"$FRMA",5)) { /* NovAtel OEM3 */ else if (!strncmp(buff,"$FRMA",5))
{ /* NovAtel OEM3 */
if (!(p = getfield(buff,2))) continue; if (!(p = getfield(buff,2))) continue;
if (sscanf(p, "%d,%lf,%d", &week, &tow, &prn) < 3) continue; if (sscanf(p, "%d,%lf,%d", &week, &tow, &prn) < 3) continue;
if (!(p = getfield(p, 6))) continue; if (!(p = getfield(p, 6))) continue;
@ -493,9 +531,11 @@ void readmsgs(const char *file, int sel, gtime_t ts, gtime_t te,
if (!screent(time, ts,te,0.0)) continue; if (!screent(time, ts,te,0.0)) continue;
if (sbs->n>=sbs->nmax) { if (sbs->n>=sbs->nmax)
{
sbs->nmax = sbs->nmax == 0 ? 1024 : sbs->nmax * 2; sbs->nmax = sbs->nmax == 0 ? 1024 : sbs->nmax * 2;
if (!(sbs_msgs=(sbsmsg_t *)realloc(sbs->msgs,sbs->nmax*sizeof(sbsmsg_t)))) { if (!(sbs_msgs = (sbsmsg_t *)realloc(sbs->msgs, sbs->nmax * sizeof(sbsmsg_t))))
{
trace(1, "readsbsmsg malloc error: nmax=%d\n", sbs->nmax); trace(1, "readsbsmsg malloc error: nmax=%d\n", sbs->nmax);
free(sbs->msgs); sbs->msgs = NULL; sbs->n = sbs->nmax = 0; free(sbs->msgs); sbs->msgs = NULL; sbs->n = sbs->nmax = 0;
return; return;
@ -506,13 +546,16 @@ void readmsgs(const char *file, int sel, gtime_t ts, gtime_t te,
sbs->msgs[sbs->n].tow = (int)(tow + 0.5); sbs->msgs[sbs->n].tow = (int)(tow + 0.5);
sbs->msgs[sbs->n].prn = prn; sbs->msgs[sbs->n].prn = prn;
for (i = 0; i < 29; i++) sbs->msgs[sbs->n].msg[i] = 0; for (i = 0; i < 29; i++) sbs->msgs[sbs->n].msg[i] = 0;
for (i=0;*(p-1)&&*p&&i<29;p+=2,i++) { for (i = 0; *(p-1) && *p && i < 29; p += 2, i++)
{
if (sscanf(p, "%2X", &b) == 1) sbs->msgs[sbs->n].msg[i] = (unsigned char)b; if (sscanf(p, "%2X", &b) == 1) sbs->msgs[sbs->n].msg[i] = (unsigned char)b;
} }
sbs->msgs[sbs->n++].msg[28] &= 0xC0; sbs->msgs[sbs->n++].msg[28] &= 0xC0;
} }
fclose(fp); fclose(fp);
} }
/* compare sbas messages -----------------------------------------------------*/ /* compare sbas messages -----------------------------------------------------*/
int cmpmsgs(const void *p1, const void *p2) int cmpmsgs(const void *p1, const void *p2)
{ {
@ -520,6 +563,8 @@ int cmpmsgs(const void *p1, const void *p2)
return q1->week != q2->week ? q1->week-q2->week : return q1->week != q2->week ? q1->week-q2->week :
(q1->tow < q2->tow ? -1 : (q1->tow > q2->tow ? 1 : q1->prn - q2->prn)); (q1->tow < q2->tow ? -1 : (q1->tow > q2->tow ? 1 : q1->prn - q2->prn));
} }
/* read sbas message file ------------------------------------------------------ /* read sbas message file ------------------------------------------------------
* read sbas message file * read sbas message file
* args : char *file I sbas message file (wind-card * is expanded) * args : char *file I sbas message file (wind-card * is expanded)
@ -543,8 +588,10 @@ int sbsreadmsgt(const char *file, int sel, gtime_t ts, gtime_t te,
trace(3,"sbsreadmsgt: file=%s sel=%d\n",file,sel); trace(3,"sbsreadmsgt: file=%s sel=%d\n",file,sel);
for (i=0;i<MAXEXFILE;i++) { for (i = 0; i < MAXEXFILE ; i++)
if (!(efiles[i]=(char *)malloc(1024))) { {
if (!(efiles[i] = (char *)malloc(1024)))
{
for (i--; i >= 0; i--) free(efiles[i]); for (i--; i >= 0; i--) free(efiles[i]);
return 0; return 0;
} }
@ -552,7 +599,8 @@ int sbsreadmsgt(const char *file, int sel, gtime_t ts, gtime_t te,
/* expand wild card in file path */ /* expand wild card in file path */
n = expath(file,efiles,MAXEXFILE); n = expath(file,efiles,MAXEXFILE);
for (i=0;i<n;i++) { for (i = 0; i < n; i++)
{
if (!(ext = strrchr(efiles[i],'.'))) continue; if (!(ext = strrchr(efiles[i],'.'))) continue;
if (strcmp(ext, ".sbs") && strcmp(ext, ".SBS") && if (strcmp(ext, ".sbs") && strcmp(ext, ".SBS") &&
strcmp(ext, ".ems") && strcmp(ext, ".EMS")) continue; strcmp(ext, ".ems") && strcmp(ext, ".EMS")) continue;
@ -562,11 +610,14 @@ int sbsreadmsgt(const char *file, int sel, gtime_t ts, gtime_t te,
for (i = 0; i < MAXEXFILE; i++) free(efiles[i]); for (i = 0; i < MAXEXFILE; i++) free(efiles[i]);
/* sort messages */ /* sort messages */
if (sbs->n>0) { if (sbs->n >0)
{
qsort(sbs->msgs, sbs->n, sizeof(sbsmsg_t), cmpmsgs); qsort(sbs->msgs, sbs->n, sizeof(sbsmsg_t), cmpmsgs);
} }
return sbs->n; return sbs->n;
} }
int sbsreadmsg(const char *file, int sel, sbs_t *sbs) int sbsreadmsg(const char *file, int sel, sbs_t *sbs)
{ {
gtime_t ts = {}, te = {}; gtime_t ts = {}, te = {};
@ -575,6 +626,8 @@ int sbsreadmsg(const char *file, int sel, sbs_t *sbs)
return sbsreadmsgt(file, sel, ts, te, sbs); return sbsreadmsgt(file, sel, ts, te, sbs);
} }
/* output sbas messages -------------------------------------------------------- /* output sbas messages --------------------------------------------------------
* output sbas message record to output file in rtklib sbas log format * output sbas message record to output file in rtklib sbas log format
* args : FILE *fp I output file pointer * args : FILE *fp I output file pointer
@ -591,8 +644,10 @@ void sbsoutmsg(FILE *fp, sbsmsg_t *sbsmsg)
for (i = 0; i < 29; i++) fprintf(fp, "%02X", sbsmsg->msg[i]); for (i = 0; i < 29; i++) fprintf(fp, "%02X", sbsmsg->msg[i]);
fprintf(fp,"\n"); fprintf(fp,"\n");
} }
/* search igps ---------------------------------------------------------------*/ /* search igps ---------------------------------------------------------------*/
void searchigp(gtime_t time, const double *pos, const sbsion_t *ion, void searchigp(gtime_t time __attribute__((unused)), const double *pos, const sbsion_t *ion,
const sbsigp_t **igp, double *x, double *y) const sbsigp_t **igp, double *x, double *y)
{ {
int i,latp[2],lonp[4]; int i,latp[2],lonp[4];
@ -602,7 +657,8 @@ void searchigp(gtime_t time, const double *pos, const sbsion_t *ion,
trace(4,"searchigp: pos=%.3f %.3f\n",pos[0] * R2D, pos[1] * R2D); trace(4,"searchigp: pos=%.3f %.3f\n",pos[0] * R2D, pos[1] * R2D);
if (lon >= 180.0) lon -= 360.0; if (lon >= 180.0) lon -= 360.0;
if (-55.0<=lat&&lat<55.0) { if (-55.0 <= lat && lat < 55.0)
{
latp[0] = (int)floor(lat / 5.0) * 5; latp[0] = (int)floor(lat / 5.0) * 5;
latp[1] = latp[0] + 5; latp[1] = latp[0] + 5;
lonp[0] = lonp[1] = (int)floor(lon / 5.0) * 5; lonp[0] = lonp[1] = (int)floor(lon / 5.0) * 5;
@ -610,31 +666,38 @@ void searchigp(gtime_t time, const double *pos, const sbsion_t *ion,
*x = (lon - lonp[0]) / 5.0; *x = (lon - lonp[0]) / 5.0;
*y = (lat - latp[0]) / 5.0; *y = (lat - latp[0]) / 5.0;
} }
else { else
{
latp[0] = (int)floor((lat-5.0) / 10.0) * 10 + 5; latp[0] = (int)floor((lat-5.0) / 10.0) * 10 + 5;
latp[1] = latp[0] + 10; latp[1] = latp[0] + 10;
lonp[0] = lonp[1] = (int)floor(lon / 10.0) * 10; lonp[0] = lonp[1] = (int)floor(lon / 10.0) * 10;
lonp[2] = lonp[3] = lonp[0] + 10; lonp[2] = lonp[3] = lonp[0] + 10;
*x = (lon - lonp[0]) / 10.0; *x = (lon - lonp[0]) / 10.0;
*y = (lat - latp[0]) / 10.0; *y = (lat - latp[0]) / 10.0;
if (75.0<=lat&&lat<85.0) { if (75.0 <= lat && lat < 85.0)
{
lonp[1] = (int)floor(lon / 90.0) * 90; lonp[1] = (int)floor(lon / 90.0) * 90;
lonp[3] = lonp[1] + 90; lonp[3] = lonp[1] + 90;
} }
else if (-85.0<=lat&&lat<-75.0) { else if (-85.0 <= lat && lat < -75.0)
{
lonp[0] = (int)floor((lon - 50.0) / 90.0) * 90 + 40; lonp[0] = (int)floor((lon - 50.0) / 90.0) * 90 + 40;
lonp[2] = lonp[0] + 90; lonp[2] = lonp[0] + 90;
} }
else if (lat>=85.0) { else if (lat >= 85.0)
{
for (i = 0; i < 4; i++) lonp[i] = (int)floor(lon / 90.0) * 90; for (i = 0; i < 4; i++) lonp[i] = (int)floor(lon / 90.0) * 90;
} }
else if (lat<-85.0) { else if (lat < -85.0)
{
for (i = 0; i < 4; i++) lonp[i] = (int)floor((lon - 50.0) / 90.0) * 90 + 40; for (i = 0; i < 4; i++) lonp[i] = (int)floor((lon - 50.0) / 90.0) * 90 + 40;
} }
} }
for (i = 0; i < 4; i++) if (lonp[i] == 180) lonp[i] = -180; for (i = 0; i < 4; i++) if (lonp[i] == 180) lonp[i] = -180;
for (i=0;i<=MAXBAND;i++) { for (i = 0; i <= MAXBAND; i++)
for (p=ion[i].igp;p<ion[i].igp+ion[i].nigp;p++) { {
for (p = ion[i].igp; p < ion[i].igp + ion[i].nigp; p++)
{
if (p->t0.time == 0) continue; if (p->t0.time == 0) continue;
if (p->lat == latp[0] && p->lon == lonp[0] && p->give > 0) igp[0] = p; if (p->lat == latp[0] && p->lon == lonp[0] && p->give > 0) igp[0] = p;
else if (p->lat == latp[1] && p->lon == lonp[1] && p->give > 0) igp[1] = p; else if (p->lat == latp[1] && p->lon == lonp[1] && p->give > 0) igp[1] = p;
@ -644,6 +707,8 @@ void searchigp(gtime_t time, const double *pos, const sbsion_t *ion,
} }
} }
} }
/* sbas ionospheric delay correction ------------------------------------------- /* sbas ionospheric delay correction -------------------------------------------
* compute sbas ionosphric delay correction * compute sbas ionosphric delay correction
* args : gtime_t time I time * args : gtime_t time I time
@ -678,43 +743,55 @@ int sbsioncorr(gtime_t time, const nav_t *nav, const double *pos,
searchigp(time,posp,nav->sbsion,igp,&x,&y); searchigp(time,posp,nav->sbsion,igp,&x,&y);
/* weight of igps */ /* weight of igps */
if (igp[0]&&igp[1]&&igp[2]&&igp[3]) { if (igp[0] && igp[1] && igp[2] && igp[3])
w[0]=(1.0-x)*(1.0-y); w[1]=(1.0-x)*y; w[2]=x*(1.0-y); w[3]=x*y; {
w[0] = (1.0 - x) * (1.0 - y);
w[1] = (1.0 - x) * y;
w[2] = x * (1.0 - y);
w[3] = x * y;
} }
else if (igp[0]&&igp[1]&&igp[2]) { else if (igp[0] && igp[1] && igp[2])
{
w[1] = y; w[2] = x; w[1] = y; w[2] = x;
if ((w[0] = 1.0- w[1] - w[2]) < 0.0) err = 1; if ((w[0] = 1.0- w[1] - w[2]) < 0.0) err = 1;
} }
else if (igp[0]&&igp[2]&&igp[3]) { else if (igp[0] && igp[2] && igp[3])
{
w[0] = 1.0 - x; w[3] = y; w[0] = 1.0 - x; w[3] = y;
if ((w[2] = 1.0 - w[0] - w[3]) < 0.0) err = 1; if ((w[2] = 1.0 - w[0] - w[3]) < 0.0) err = 1;
} }
else if (igp[0]&&igp[1]&&igp[3]) { else if (igp[0] && igp[1] && igp[3])
{
w[0] = 1.0 - y; w[3] = x; w[0] = 1.0 - y; w[3] = x;
if ((w[1] = 1.0 - w[0] - w[3]) < 0.0) err = 1; if ((w[1] = 1.0 - w[0] - w[3]) < 0.0) err = 1;
} }
else if (igp[1]&&igp[2]&&igp[3]) { else if (igp[1] && igp[2] && igp[3])
{
w[1] = 1.0-x; w[2] = 1.0-y; w[1] = 1.0-x; w[2] = 1.0-y;
if ((w[3] = 1.0 - w[1] - w[2]) < 0.0) err = 1; if ((w[3] = 1.0 - w[1] - w[2]) < 0.0) err = 1;
} }
else err = 1; else err = 1;
if (err) { if (err)
{
trace(2, "no sbas iono correction: lat=%3.0f lon=%4.0f\n", posp[0] * R2D, trace(2, "no sbas iono correction: lat=%3.0f lon=%4.0f\n", posp[0] * R2D,
posp[1] * R2D); posp[1] * R2D);
return 0; return 0;
} }
for (i=0;i<4;i++) { for (i = 0; i < 4; i++)
{
if (!igp[i]) continue; if (!igp[i]) continue;
t = timediff(time,igp[i]->t0); t = timediff(time,igp[i]->t0);
*delay += w[i] * igp[i]->delay; *delay += w[i] * igp[i]->delay;
*var+=w[i]*varicorr(igp[i]->give)*9E-8*fabs(t); *var += w[i] * varicorr(igp[i]->give) * 9e-8 * fabs(t);
} }
*delay *= fp; *var *= fp * fp; *delay *= fp; *var *= fp * fp;
trace(5,"sbsioncorr: dion=%7.2f sig=%7.2f\n",*delay,sqrt(*var)); trace(5,"sbsioncorr: dion=%7.2f sig=%7.2f\n",*delay,sqrt(*var));
return 1; return 1;
} }
/* get meterological parameters ----------------------------------------------*/ /* get meterological parameters ----------------------------------------------*/
void getmet(double lat, double *met) void getmet(double lat, double *met)
{ {
@ -730,11 +807,14 @@ void getmet(double lat, double *met)
lat = fabs(lat); lat = fabs(lat);
if (lat <= 15.0) for (i = 0;i<10;i++) met[i] = metprm[0][i]; if (lat <= 15.0) for (i = 0;i<10;i++) met[i] = metprm[0][i];
else if (lat >= 75.0) for (i = 0;i<10;i++) met[i] = metprm[4][i]; else if (lat >= 75.0) for (i = 0;i<10;i++) met[i] = metprm[4][i];
else { else
{
j = (int)(lat / 15.0); a = (lat - j * 15.0) / 15.0; j = (int)(lat / 15.0); a = (lat - j * 15.0) / 15.0;
for (i = 0; i < 10; i++) met[i] = (1.0 - a) * metprm[j-1][i] + a * metprm[j][i]; for (i = 0; i < 10; i++) met[i] = (1.0 - a) * metprm[j-1][i] + a * metprm[j][i];
} }
} }
/* tropospheric delay correction ----------------------------------------------- /* tropospheric delay correction -----------------------------------------------
* compute sbas tropospheric delay correction (mops model) * compute sbas tropospheric delay correction (mops model)
* args : gtime_t time I time * args : gtime_t time I time
@ -754,17 +834,19 @@ double sbstropcorr(gtime_t time, const double *pos, const double *azel,
trace(4, "sbstropcorr: pos=%.3f %.3f azel=%.3f %.3f\n", pos[0] * R2D, pos[1] * R2D, trace(4, "sbstropcorr: pos=%.3f %.3f azel=%.3f %.3f\n", pos[0] * R2D, pos[1] * R2D,
azel[0] * R2D, azel[1] * R2D); azel[0] * R2D, azel[1] * R2D);
if (pos[2]<-100.0||10000.0<pos[2]||azel[1]<=0) { if (pos[2] < -100.0 || 10000.0 < pos[2] || azel[1] <= 0)
{
*var = 0.0; *var = 0.0;
return 0.0; return 0.0;
} }
if (zh==0.0||fabs(pos[0]-pos_[0])>1E-7||fabs(pos[1]-pos_[1])>1E-7|| if (zh == 0.0 || fabs(pos[0] - pos_[0]) > 1e-7 || fabs(pos[1] - pos_[1]) > 1e-7 ||
fabs(pos[2]-pos_[2])>1.0) { fabs(pos[2] - pos_[2]) > 1.0)
{
getmet(pos[0] * R2D,met); getmet(pos[0] * R2D,met);
c = cos(2.0 * PI * (time2doy(time) - (pos[0] >= 0.0 ? 28.0 : 211.0)) / 365.25); c = cos(2.0 * PI * (time2doy(time) - (pos[0] >= 0.0 ? 28.0 : 211.0)) / 365.25);
for (i = 0; i < 5;i++) met[i] -= met[i+5] * c; for (i = 0; i < 5;i++) met[i] -= met[i+5] * c;
zh=1E-6*k1*rd*met[0]/gm; zh = 1e-6 * k1 * rd * met[0] / gm;
zw=1E-6*k2*rd/(gm*(met[4]+1.0)-met[3]*rd)*met[2]/met[1]; zw = 1e-6 * k2 * rd / (gm * (met[4] + 1.0) - met[3] * rd) * met[2] / met[1];
zh *= pow(1.0 - met[3] * h / met[1], g / (rd * met[3])); zh *= pow(1.0 - met[3] * h / met[1], g / (rd * met[3]));
zw *= pow(1.0 - met[3] * h / met[1], (met[4] + 1.0) * g / (rd * met[3]) - 1.0); zw *= pow(1.0 - met[3] * h / met[1], (met[4] + 1.0) * g / (rd * met[3]) - 1.0);
for (i = 0; i < 3; i++) pos_[i] = pos[i]; for (i = 0; i < 3; i++) pos_[i] = pos[i];
@ -773,6 +855,8 @@ double sbstropcorr(gtime_t time, const double *pos, const double *azel,
*var = 0.12*0.12*m*m; *var = 0.12*0.12*m*m;
return (zh+zw)*m; return (zh+zw)*m;
} }
/* long term correction ------------------------------------------------------*/ /* long term correction ------------------------------------------------------*/
int sbslongcorr(gtime_t time, int sat, const sbssat_t *sbssat, int sbslongcorr(gtime_t time, int sat, const sbssat_t *sbssat,
double *drs, double *ddts) double *drs, double *ddts)
@ -783,10 +867,12 @@ int sbslongcorr(gtime_t time, int sat, const sbssat_t *sbssat,
trace(3,"sbslongcorr: sat=%2d\n",sat); trace(3,"sbslongcorr: sat=%2d\n",sat);
for (p=sbssat->sat;p<sbssat->sat+sbssat->nsat;p++) { for (p = sbssat->sat;p<sbssat->sat+sbssat->nsat;p++)
{
if (p->sat != sat || p->lcorr.t0.time == 0) continue; if (p->sat != sat || p->lcorr.t0.time == 0) continue;
t = timediff(time, p->lcorr.t0); t = timediff(time, p->lcorr.t0);
if (fabs(t)>MAXSBSAGEL) { if (fabs(t) > MAXSBSAGEL)
{
trace(2,"sbas long-term correction expired: %s sat=%2d t=%5.0f\n", trace(2,"sbas long-term correction expired: %s sat=%2d t=%5.0f\n",
time_str(time,0), sat, t); time_str(time,0), sat, t);
return 0; return 0;
@ -795,7 +881,7 @@ int sbslongcorr(gtime_t time, int sat, const sbssat_t *sbssat,
*ddts = p->lcorr.daf0 + p->lcorr.daf1 * t; *ddts = p->lcorr.daf0 + p->lcorr.daf1 * t;
trace(5,"sbslongcorr: sat=%2d drs=%7.2f%7.2f%7.2f ddts=%7.2f\n", trace(5,"sbslongcorr: sat=%2d drs=%7.2f%7.2f%7.2f ddts=%7.2f\n",
sat,drs[0],drs[1],drs[2],*ddts*CLIGHT); sat, drs[0], drs[1], drs[2], *ddts * SPEED_OF_LIGHT);
return 1; return 1;
} }
@ -805,6 +891,8 @@ int sbslongcorr(gtime_t time, int sat, const sbssat_t *sbssat,
trace(2,"no sbas long-term correction: %s sat=%2d\n",time_str(time,0),sat); trace(2,"no sbas long-term correction: %s sat=%2d\n",time_str(time,0),sat);
return 0; return 0;
} }
/* fast correction -----------------------------------------------------------*/ /* fast correction -----------------------------------------------------------*/
int sbsfastcorr(gtime_t time, int sat, const sbssat_t *sbssat, int sbsfastcorr(gtime_t time, int sat, const sbssat_t *sbssat,
double *prc, double *var) double *prc, double *var)
@ -814,7 +902,8 @@ int sbsfastcorr(gtime_t time, int sat, const sbssat_t *sbssat,
trace(3,"sbsfastcorr: sat=%2d\n",sat); trace(3,"sbsfastcorr: sat=%2d\n",sat);
for (p=sbssat->sat;p<sbssat->sat+sbssat->nsat;p++) { for (p = sbssat->sat;p<sbssat->sat+sbssat->nsat;p++)
{
if (p->sat!=sat) continue; if (p->sat!=sat) continue;
if (p->fcorr.t0.time == 0) break; if (p->fcorr.t0.time == 0) break;
t = timediff(time, p->fcorr.t0) + sbssat->tlat; t = timediff(time, p->fcorr.t0) + sbssat->tlat;
@ -823,7 +912,8 @@ int sbsfastcorr(gtime_t time, int sat, const sbssat_t *sbssat,
if (fabs(t) > MAXSBSAGEF || p->fcorr.udre >= 15) continue; if (fabs(t) > MAXSBSAGEF || p->fcorr.udre >= 15) continue;
*prc = p->fcorr.prc; *prc = p->fcorr.prc;
#ifdef RRCENA #ifdef RRCENA
if (p->fcorr.ai>0&&fabs(t)<=8.0*p->fcorr.dt) { if (p->fcorr.ai > 0 && fabs(t) <= 8.0 * p->fcorr.dt)
{
*prc += p->fcorr.rrc * t; *prc += p->fcorr.rrc * t;
} }
#endif #endif
@ -836,6 +926,8 @@ int sbsfastcorr(gtime_t time, int sat, const sbssat_t *sbssat,
trace(2,"no sbas fast correction: %s sat=%2d\n", time_str(time, 0), sat); trace(2,"no sbas fast correction: %s sat=%2d\n", time_str(time, 0), sat);
return 0; return 0;
} }
/* sbas satellite ephemeris and clock correction ------------------------------- /* sbas satellite ephemeris and clock correction -------------------------------
* correct satellite position and clock bias with sbas satellite corrections * correct satellite position and clock bias with sbas satellite corrections
* args : gtime_t time I reception time * args : gtime_t time I reception time
@ -862,22 +954,26 @@ int sbssatcorr(gtime_t time, int sat, const nav_t *nav, double *rs,
trace(3,"sbssatcorr : sat=%2d\n",sat); trace(3,"sbssatcorr : sat=%2d\n",sat);
/* sbas long term corrections */ /* sbas long term corrections */
if (!sbslongcorr(time,sat,&nav->sbssat,drs,&dclk)) { if (!sbslongcorr(time, sat, &nav->sbssat, drs, &dclk))
{
return 0; return 0;
} }
/* sbas fast corrections */ /* sbas fast corrections */
if (!sbsfastcorr(time,sat,&nav->sbssat,&prc,var)) { if (!sbsfastcorr(time, sat, &nav->sbssat, &prc, var))
{
return 0; return 0;
} }
for (i = 0; i < 3; i++) rs[i] += drs[i]; for (i = 0; i < 3; i++) rs[i] += drs[i];
dts[0]+=dclk+prc/CLIGHT; dts[0] += dclk + prc / SPEED_OF_LIGHT;
trace(5,"sbssatcorr: sat=%2d drs=%6.3f %6.3f %6.3f dclk=%.3f %.3f var=%.3f\n", trace(5,"sbssatcorr: sat=%2d drs=%6.3f %6.3f %6.3f dclk=%.3f %.3f var=%.3f\n",
sat,drs[0],drs[1],drs[2],dclk,prc/CLIGHT,*var); sat, drs[0], drs[1], drs[2], dclk, prc / SPEED_OF_LIGHT, *var);
return 1; return 1;
} }
/* decode sbas message --------------------------------------------------------- /* decode sbas message ---------------------------------------------------------
* decode sbas message frame words and check crc * decode sbas message frame words and check crc
* args : gtime_t time I reception time * args : gtime_t time I reception time
@ -899,7 +995,8 @@ int sbsdecodemsg(gtime_t time, int prn, const unsigned int *words,
tow = time2gpst(time,&sbsmsg->week); tow = time2gpst(time,&sbsmsg->week);
sbsmsg->tow = (int)(tow + DTTOL); sbsmsg->tow = (int)(tow + DTTOL);
sbsmsg->prn = prn; sbsmsg->prn = prn;
for (i=0;i<7;i++) for (j=0;j<4;j++) { for (i = 0; i < 7; i++) for (j = 0; j < 4; j++)
{
sbsmsg->msg[i*4+j] = (unsigned char)(words[i] >> ((3-j)*8)); sbsmsg->msg[i*4+j] = (unsigned char)(words[i] >> ((3-j)*8));
} }
sbsmsg->msg[28] = (unsigned char)(words[7] >> 18 ) & 0xC0; sbsmsg->msg[28] = (unsigned char)(words[7] >> 18 ) & 0xC0;

View File

@ -51,7 +51,7 @@
* *
* option : -DRRCENA enable rrc correction * option : -DRRCENA enable rrc correction
* *
* references : * References :
* [1] RTCA/DO-229C, Minimum operational performanc standards for global * [1] RTCA/DO-229C, Minimum operational performanc standards for global
* positioning system/wide area augmentation system airborne equipment, * positioning system/wide area augmentation system airborne equipment,
* RTCA inc, November 28, 2001 * RTCA inc, November 28, 2001
@ -59,32 +59,10 @@
* Interface Specification for QZSS, Japan Aerospace Exploration Agency, * Interface Specification for QZSS, Japan Aerospace Exploration Agency,
* July 31, 2009 * July 31, 2009
* *
* version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $
* history : 2007/10/14 1.0 new
* 2009/01/24 1.1 modify sbspntpos() api
* improve fast/ion correction update
* 2009/04/08 1.2 move function crc24q() to rcvlog.c
* support glonass, galileo and qzss
* 2009/06/08 1.3 modify sbsupdatestat()
* delete sbssatpos()
* 2009/12/12 1.4 support glonass
* 2010/01/22 1.5 support ems (egnos message service) format
* 2010/06/10 1.6 added api:
* sbssatcorr(),sbstropcorr(),sbsioncorr(),
* sbsupdatecorr()
* changed api:
* sbsreadmsgt(),sbsreadmsg()
* deleted api:
* sbspntpos(),sbsupdatestat()
* 2010/08/16 1.7 not reject udre==14 or give==15 correction message
* (2.4.0_p4)
* 2011/01/15 1.8 use api ionppp()
* add prn mask of qzss for qzss L1SAIF
* 2016/07/29 1.9 crc24q() -> rtk_crc24q()
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
#ifndef RTKLIB_SBAS_H_ #ifndef GNSS_SDR_RTKLIB_SBAS_H_
#define RTKLIB_SBAS_H_ #define GNSS_SDR_RTKLIB_SBAS_H_
#include "rtklib.h" #include "rtklib.h"
#include "rtklib_rtkcmn.h" #include "rtklib_rtkcmn.h"
@ -146,6 +124,7 @@ char *getfield(char *p, int pos);
double varfcorr(int udre); double varfcorr(int udre);
double varicorr(int give); double varicorr(int give);
double degfcorr(int ai); double degfcorr(int ai);
int decode_sbstype1(const sbsmsg_t *msg, sbssat_t *sbssat); int decode_sbstype1(const sbsmsg_t *msg, sbssat_t *sbssat);
int decode_sbstype2(const sbsmsg_t *msg, sbssat_t *sbssat); int decode_sbstype2(const sbsmsg_t *msg, sbssat_t *sbssat);
int decode_sbstype6(const sbsmsg_t *msg, sbssat_t *sbssat); int decode_sbstype6(const sbsmsg_t *msg, sbssat_t *sbssat);
@ -158,6 +137,7 @@ int decode_longcorrh(const sbsmsg_t *msg, int p, sbssat_t *sbssat);
int decode_sbstype24(const sbsmsg_t *msg, sbssat_t *sbssat); int decode_sbstype24(const sbsmsg_t *msg, sbssat_t *sbssat);
int decode_sbstype25(const sbsmsg_t *msg, sbssat_t *sbssat); int decode_sbstype25(const sbsmsg_t *msg, sbssat_t *sbssat);
int decode_sbstype26(const sbsmsg_t *msg, sbsion_t *sbsion); int decode_sbstype26(const sbsmsg_t *msg, sbsion_t *sbsion);
int sbsupdatecorr(const sbsmsg_t *msg, nav_t *nav); int sbsupdatecorr(const sbsmsg_t *msg, nav_t *nav);
void readmsgs(const char *file, int sel, gtime_t ts, gtime_t te,sbs_t *sbs); void readmsgs(const char *file, int sel, gtime_t ts, gtime_t te,sbs_t *sbs);
int cmpmsgs(const void *p1, const void *p2); int cmpmsgs(const void *p1, const void *p2);
@ -184,4 +164,4 @@ int sbsdecodemsg(gtime_t time, int prn, const unsigned int *words,
sbsmsg_t *sbsmsg); sbsmsg_t *sbsmsg);
#endif /* RTKLIB_SBAS_H_ */ #endif /* GNSS_SDR_RTKLIB_SBAS_H_ */

View File

@ -76,6 +76,14 @@ if(MSVC)
add_compile_options(/wo4838) add_compile_options(/wo4838)
endif(MSVC) endif(MSVC)
# allow 'large' files in 32 bit builds
if(UNIX)
add_definitions( -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64
-D_LARGE_FILES
)
endif(UNIX)
######################################################################## ########################################################################
# Dependencies setup # Dependencies setup
######################################################################## ########################################################################

View File

@ -1,26 +1,56 @@
# Welcome to VOLK_GNSSSDR, the Vector-Optimized Library of Kernels for GNSS-SDR # Welcome to VOLK_GNSSSDR, the Vector-Optimized Library of Kernels for GNSS-SDR
VOLK_GNSSSDR is a sub-project of GNSS-SDR. This library provides a set of extra kernels that can be used stand-alone or in combination with VOLK's. Please see http://libvolk.org for documentation, source code, and contact information about the original VOLK library. VOLK_GNSSSDR is a sub-project of GNSS-SDR. This library provides a set
of extra kernels that can be used stand-alone or in combination with
VOLK's. Please see http://libvolk.org for documentation, source code,
and contact information about the original VOLK library.
The boilerplate of this code was initially generated with ```volk_modtool```, an application provided by VOLK that creates the skeleton than can then be filled with custom kernels. Some modifications were added to accomodate the specificities of Global Navigation Satellite Systems (GNSS) signal processing. Those changes are clearly indicated in the source code, and do not break compatibility. The boilerplate of this code was initially generated with
```volk_modtool```, an application provided by VOLK that creates the
skeleton than can then be filled with custom kernels. Some modifications
were added to accomodate the specificities of Global Navigation
Satellite Systems (GNSS) signal processing. Those changes are clearly
indicated in the source code, and do not break compatibility.
This library contains kernels of hand-written SIMD code for different mathematical operations, mainly with 8-bit and 16-bit real and complex data types, offering a platform/architecture agnostic version that will run in all machines, plus other versions for different SIMD instruction sets. Then, the application ```volk_gnsssdr_profile``` runs some iterations of all versions that your machine can execute and annotates which is the fastest, which will then be selected at runtime when executing GNSS-SDR. In this way, we can address at the same time portability (by creating executables that will run in nearly all processor architectures) and efficiency (by providing custom implementations specially designed to take advantage of the specific processor that is running the code). This library contains kernels of hand-written SIMD code for different
mathematical operations, mainly with 8-bit and 16-bit real and complex
data types, offering a platform/architecture agnostic version that will
run in all machines, plus other versions for different SIMD instruction
sets. Then, the application ```volk_gnsssdr_profile``` runs some
iterations of all versions that your machine can execute and annotates
which is the fastest, which will then be selected at runtime when
executing GNSS-SDR. In this way, we can address at the same time
[portability](http://gnss-sdr.org/design-forces/portability/) (by
creating executables that will run in nearly all processor
architectures) and
[efficiency](http://gnss-sdr.org/design-forces/efficiency/) (by
providing custom implementations specially designed to take advantage of
the specific processor that is running the code).
These kernels have some specific features (e.g. saturation arithmetics) that are aimed to GNSS signal processing, but could make them not suitable for its general use in other applications. Check out the documentation generated by Doxygen and the *generic* (that is, plain C) implementation to see what each kernel is actually doing. These kernels have some specific features (e.g. saturation arithmetics)
that are aimed to GNSS signal processing, but could make them not
suitable for its general use in other applications. Check out the
documentation generated by Doxygen and the *generic* (that is, plain C)
implementation to see what each kernel is actually doing.
## How to use VOLK_GNSSSDR: ## How to use VOLK_GNSSSDR:
This library is automatically built and installed along with GNSS-SDR if it is not found by CMake on your system at configure time. This library is automatically built and installed along with GNSS-SDR if
it is not found by CMake on your system at configure time.
However, you can install and use VOLK_GNSSSDR kernels as you use VOLK's, independently from GNSS-SDR. However, you can install and use VOLK_GNSSSDR kernels as you use VOLK's,
independently from GNSS-SDR.
First, make sure that the required dependencies are installed in you machine: First, make sure that the required dependencies are installed in your
machine:
~~~~~~ ~~~~~~
$ sudo apt-get install git cmake python-mako python-six libboost-dev libbbost-filesystem $ sudo apt-get install cmake python-mako python-six libboost-dev \
libboost-filesystem-dev libboost-system-dev libboost-program-options-dev
~~~~~~ ~~~~~~
In order to build and install the library, go to the base folder of the source code and do: In order to build and install the library, go to the base folder of the
source code and do:
~~~~~~ ~~~~~~
$ mkdir build $ mkdir build
@ -32,15 +62,20 @@ $ sudo make install
That's it! That's it!
Before its first use, please execute ```volk_gnsssdr_profile``` to let your system know which is the fastest available implementation. This only has to be done once: Before its first use, please execute ```volk_gnsssdr_profile``` to let
your system know which is the fastest available implementation. This
only has to be done once:
~~~~~~ ~~~~~~
$ volk_gnsssdr_profile $ volk_gnsssdr_profile
~~~~~~ ~~~~~~
From now on, GNSS-SDR (and any other program of your own that makes use of VOLK_GNSSSDR) will benefit from the acceleration provided by SIMD instructions available in your processor. From now on, GNSS-SDR (and any other program of your own that makes use
of VOLK_GNSSSDR) will benefit from the acceleration provided by SIMD
instructions available in your processor.
The execution of ```volk_gnsssdr_profile``` can be set automatically after building, leaving your system ready to use: The execution of ```volk_gnsssdr_profile``` can be set automatically
after building, leaving your system ready to use:
~~~~~~ ~~~~~~
$ cmake -DENABLE_PROFILING=ON ../ $ cmake -DENABLE_PROFILING=ON ../
@ -49,22 +84,35 @@ $ sudo make install
~~~~~~ ~~~~~~
This figure shows the role of some VOLK_GNSSSDR kernels in the context of a GNSS baseband processor: This figure shows the role of some VOLK_GNSSSDR kernels in the context
of a GNSS baseband processor:
![Example of VOLK_GNSSSDR usage.](./docs/images/VOLK_GNSSSDR_Usage_Example.png) ![Example of VOLK_GNSSSDR
usage.](./docs/images/VOLK_GNSSSDR_Usage_Example.png)
If you use VOLK_GNSSSDR in your research and/or software, please cite the following paper: If you use VOLK_GNSSSDR in your research and/or software, please cite
the following paper:
* C. Fern&aacute;ndez-Prades, J. Arribas, P. Closas, [*Accelerating GNSS Software Receivers*](https://zenodo.org/record/266493), in Proc. of the ION GNSS+ 2016 Conference, pp. 44-61, Portland, Oregon, Sept. 12-16, 2016. * C. Fernández-Prades, J. Arribas, P. Closas, [*Accelerating
GNSS Software Receivers*](https://zenodo.org/record/266493), in Proc. of
the ION GNSS+ 2016 Conference, pp. 44-61, Portland, Oregon, Sept. 12-16, 2016.
Citations are useful for the continued development and maintenance of the library. Citations are useful for the continued development and maintenance of
the library.
___ ___
VOLK_GNSSSDR was originally created by Andres Cecilia Luque in the framework of the [Summer Of Code In Space (SOCIS 2014)](http://sophia.estec.esa.int/socis2014/?q=about "SOCIS 2014 webpage") program organized by the European Space Agency, and then evolved and maintained by Carles Fern&aacute;ndez-Prades and Javier Arribas. This software is released under the GNU General Public License version 3, see the file COPYING. VOLK_GNSSSDR was originally created by Andres Cecilia Luque in the
framework of the [Summer Of Code In Space (SOCIS
2014)](http://sophia.estec.esa.int/socis2014/?q=about "SOCIS 2014
webpage") program organized by the European Space Agency, and then
evolved and maintained by Carles Fernández-Prades and Javier
Arribas. This software is released under the GNU General Public License
version 3, see the file COPYING.
This project is managed by [Centre Tecnologic de Telecomunicacions de Catalunya](http://www.cttc.es "CTTC webpage"). This project is managed by [Centre Tecnologic de Telecomunicacions de
Catalunya](http://www.cttc.es "CTTC webpage").

View File

@ -101,8 +101,8 @@ static inline void volk_gnsssdr_16ic_x2_dot_prod_16ic_a_sse2(lv_16sc_t* out, con
realcacc = _mm_setzero_si128(); realcacc = _mm_setzero_si128();
imagcacc = _mm_setzero_si128(); imagcacc = _mm_setzero_si128();
mask_imag = _mm_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); mask_imag = _mm_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
mask_real = _mm_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); mask_real = _mm_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
for(number = 0; number < sse_iters; number++) for(number = 0; number < sse_iters; number++)
{ {
@ -179,8 +179,8 @@ static inline void volk_gnsssdr_16ic_x2_dot_prod_16ic_u_sse2(lv_16sc_t* out, con
realcacc = _mm_setzero_si128(); realcacc = _mm_setzero_si128();
imagcacc = _mm_setzero_si128(); imagcacc = _mm_setzero_si128();
mask_imag = _mm_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); mask_imag = _mm_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
mask_real = _mm_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); mask_real = _mm_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
for(number = 0; number < sse_iters; number++) for(number = 0; number < sse_iters; number++)
{ {
@ -258,8 +258,8 @@ static inline void volk_gnsssdr_16ic_x2_dot_prod_16ic_u_axv2(lv_16sc_t* out, con
realcacc = _mm256_setzero_si256(); realcacc = _mm256_setzero_si256();
imagcacc = _mm256_setzero_si256(); imagcacc = _mm256_setzero_si256();
mask_imag = _mm256_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); mask_imag = _mm256_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
mask_real = _mm256_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); mask_real = _mm256_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
for(number = 0; number < avx_iters; number++) for(number = 0; number < avx_iters; number++)
{ {
@ -335,8 +335,8 @@ static inline void volk_gnsssdr_16ic_x2_dot_prod_16ic_a_axv2(lv_16sc_t* out, con
realcacc = _mm256_setzero_si256(); realcacc = _mm256_setzero_si256();
imagcacc = _mm256_setzero_si256(); imagcacc = _mm256_setzero_si256();
mask_imag = _mm256_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); mask_imag = _mm256_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
mask_real = _mm256_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); mask_real = _mm256_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
for(number = 0; number < avx_iters; number++) for(number = 0; number < avx_iters; number++)
{ {

View File

@ -138,8 +138,8 @@ static inline void volk_gnsssdr_16ic_x2_dot_prod_16ic_xn_a_sse2(lv_16sc_t* resul
__m128i a, b, c, c_sr, mask_imag, mask_real, real, imag; __m128i a, b, c, c_sr, mask_imag, mask_real, real, imag;
mask_imag = _mm_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); mask_imag = _mm_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
mask_real = _mm_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); mask_real = _mm_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
for(index = 0; index < sse_iters; index++) for(index = 0; index < sse_iters; index++)
{ {
@ -232,8 +232,8 @@ static inline void volk_gnsssdr_16ic_x2_dot_prod_16ic_xn_u_sse2(lv_16sc_t* resul
__m128i a, b, c, c_sr, mask_imag, mask_real, real, imag; __m128i a, b, c, c_sr, mask_imag, mask_real, real, imag;
mask_imag = _mm_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); mask_imag = _mm_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
mask_real = _mm_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); mask_real = _mm_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
for(index = 0; index < sse_iters; index++) for(index = 0; index < sse_iters; index++)
{ {
@ -326,8 +326,8 @@ static inline void volk_gnsssdr_16ic_x2_dot_prod_16ic_xn_a_avx2(lv_16sc_t* resul
__m256i a, b, c, c_sr, mask_imag, mask_real, real, imag; __m256i a, b, c, c_sr, mask_imag, mask_real, real, imag;
mask_imag = _mm256_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); mask_imag = _mm256_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
mask_real = _mm256_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); mask_real = _mm256_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
for(index = 0; index < sse_iters; index++) for(index = 0; index < sse_iters; index++)
{ {
@ -420,8 +420,8 @@ static inline void volk_gnsssdr_16ic_x2_dot_prod_16ic_xn_u_avx2(lv_16sc_t* resul
__m256i a, b, c, c_sr, mask_imag, mask_real, real, imag; __m256i a, b, c, c_sr, mask_imag, mask_real, real, imag;
mask_imag = _mm256_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); mask_imag = _mm256_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
mask_real = _mm256_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); mask_real = _mm256_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
for(index = 0; index < sse_iters; index++) for(index = 0; index < sse_iters; index++)
{ {

View File

@ -85,8 +85,8 @@ static inline void volk_gnsssdr_16ic_x2_multiply_16ic_a_sse2(lv_16sc_t* out, con
unsigned int number; unsigned int number;
__m128i a, b, c, c_sr, mask_imag, mask_real, real, imag, imag1, imag2, b_sl, a_sl, result; __m128i a, b, c, c_sr, mask_imag, mask_real, real, imag, imag1, imag2, b_sl, a_sl, result;
mask_imag = _mm_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); mask_imag = _mm_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
mask_real = _mm_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); mask_real = _mm_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
const lv_16sc_t* _in_a = in_a; const lv_16sc_t* _in_a = in_a;
const lv_16sc_t* _in_b = in_b; const lv_16sc_t* _in_b = in_b;
@ -139,8 +139,8 @@ static inline void volk_gnsssdr_16ic_x2_multiply_16ic_u_sse2(lv_16sc_t* out, con
unsigned int number; unsigned int number;
__m128i a, b, c, c_sr, mask_imag, mask_real, real, imag, imag1,imag2, b_sl, a_sl, result; __m128i a, b, c, c_sr, mask_imag, mask_real, real, imag, imag1,imag2, b_sl, a_sl, result;
mask_imag = _mm_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); mask_imag = _mm_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
mask_real = _mm_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); mask_real = _mm_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
const lv_16sc_t* _in_a = in_a; const lv_16sc_t* _in_a = in_a;
const lv_16sc_t* _in_b = in_b; const lv_16sc_t* _in_b = in_b;
@ -198,8 +198,8 @@ static inline void volk_gnsssdr_16ic_x2_multiply_16ic_u_avx2(lv_16sc_t* out, con
__m256i a, b, c, c_sr, real, imag, imag1, imag2, b_sl, a_sl, result; __m256i a, b, c, c_sr, real, imag, imag1, imag2, b_sl, a_sl, result;
const __m256i mask_imag = _mm256_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); const __m256i mask_imag = _mm256_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
const __m256i mask_real = _mm256_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); const __m256i mask_real = _mm256_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
for(;number < avx2_points; number++) for(;number < avx2_points; number++)
{ {
@ -252,8 +252,8 @@ static inline void volk_gnsssdr_16ic_x2_multiply_16ic_a_avx2(lv_16sc_t* out, con
__m256i a, b, c, c_sr, real, imag, imag1, imag2, b_sl, a_sl, result; __m256i a, b, c, c_sr, real, imag, imag1, imag2, b_sl, a_sl, result;
const __m256i mask_imag = _mm256_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); const __m256i mask_imag = _mm256_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
const __m256i mask_real = _mm256_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); const __m256i mask_real = _mm256_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
for(;number < avx2_points; number++) for(;number < avx2_points; number++)
{ {

View File

@ -205,8 +205,8 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dot_prod_16ic_xn_a_sse3(lv_16sc_
__m128i a, b, c, c_sr, mask_imag, mask_real, real, imag, imag1, imag2, b_sl, a_sl; __m128i a, b, c, c_sr, mask_imag, mask_real, real, imag, imag1, imag2, b_sl, a_sl;
mask_imag = _mm_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); mask_imag = _mm_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
mask_real = _mm_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); mask_real = _mm_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
// phase rotation registers // phase rotation registers
__m128 pa, pb, two_phase_acc_reg, two_phase_inc_reg; __m128 pa, pb, two_phase_acc_reg, two_phase_inc_reg;
@ -383,8 +383,8 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dot_prod_16ic_xn_a_sse3_reload(l
__m128i a, b, c, c_sr, mask_imag, mask_real, real, imag, imag1, imag2, b_sl, a_sl; __m128i a, b, c, c_sr, mask_imag, mask_real, real, imag, imag1, imag2, b_sl, a_sl;
mask_imag = _mm_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); mask_imag = _mm_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
mask_real = _mm_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); mask_real = _mm_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
// phase rotation registers // phase rotation registers
__m128 pa, pb, two_phase_acc_reg, two_phase_inc_reg; __m128 pa, pb, two_phase_acc_reg, two_phase_inc_reg;
@ -629,8 +629,8 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dot_prod_16ic_xn_u_sse3(lv_16sc_
__m128i a, b, c, c_sr, mask_imag, mask_real, real, imag, imag1, imag2, b_sl, a_sl; __m128i a, b, c, c_sr, mask_imag, mask_real, real, imag, imag1, imag2, b_sl, a_sl;
mask_imag = _mm_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); mask_imag = _mm_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
mask_real = _mm_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); mask_real = _mm_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
// phase rotation registers // phase rotation registers
__m128 pa, pb, two_phase_acc_reg, two_phase_inc_reg; __m128 pa, pb, two_phase_acc_reg, two_phase_inc_reg;
@ -794,8 +794,8 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dot_prod_16ic_xn_a_avx2(lv_16sc_
imagcacc[n_vec] = _mm256_setzero_si256(); imagcacc[n_vec] = _mm256_setzero_si256();
} }
const __m256i mask_imag = _mm256_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); const __m256i mask_imag = _mm256_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
const __m256i mask_real = _mm256_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); const __m256i mask_real = _mm256_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
__m128 a, b, two_phase_acc_reg, two_phase_inc_reg; __m128 a, b, two_phase_acc_reg, two_phase_inc_reg;
__m128i c1, c2, result1, result2; __m128i c1, c2, result1, result2;
@ -1002,8 +1002,8 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dot_prod_16ic_xn_a_avx2_reload(l
imagcacc[n_vec] = _mm256_setzero_si256(); imagcacc[n_vec] = _mm256_setzero_si256();
} }
const __m256i mask_imag = _mm256_set_epi8(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); const __m256i mask_imag = _mm256_set_epi8(0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0);
const __m256i mask_real = _mm256_set_epi8(0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255); const __m256i mask_real = _mm256_set_epi8(0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF, 0, 0, 0xFF, 0xFF);
__m128 a, b, two_phase_acc_reg, two_phase_inc_reg; __m128 a, b, two_phase_acc_reg, two_phase_inc_reg;
__m128i c1, c2, result1, result2; __m128i c1, c2, result1, result2;

View File

@ -71,7 +71,7 @@ static inline void volk_gnsssdr_8ic_conjugate_8ic_u_avx(lv_8sc_t* cVector, const
__m256 tmp; __m256 tmp;
__m128i tmp128lo, tmp128hi; __m128i tmp128lo, tmp128hi;
__m256 conjugator1 = _mm256_castsi256_ps(_mm256_setr_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255)); __m256 conjugator1 = _mm256_castsi256_ps(_mm256_setr_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF));
__m128i conjugator2 = _mm_setr_epi8(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1); __m128i conjugator2 = _mm_setr_epi8(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1);
for (i = 0; i < sse_iters; ++i) for (i = 0; i < sse_iters; ++i)
@ -140,7 +140,7 @@ static inline void volk_gnsssdr_8ic_conjugate_8ic_u_sse3(lv_8sc_t* cVector, cons
const lv_8sc_t* a = aVector; const lv_8sc_t* a = aVector;
__m128i tmp; __m128i tmp;
__m128i conjugator1 = _mm_setr_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); __m128i conjugator1 = _mm_setr_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
__m128i conjugator2 = _mm_setr_epi8(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1); __m128i conjugator2 = _mm_setr_epi8(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1);
for (i = 0; i < sse_iters; ++i) for (i = 0; i < sse_iters; ++i)
@ -190,7 +190,7 @@ static inline void volk_gnsssdr_8ic_conjugate_8ic_a_avx(lv_8sc_t* cVector, const
__m256 tmp; __m256 tmp;
__m128i tmp128lo, tmp128hi; __m128i tmp128lo, tmp128hi;
__m256 conjugator1 = _mm256_castsi256_ps(_mm256_setr_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255)); __m256 conjugator1 = _mm256_castsi256_ps(_mm256_setr_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF));
__m128i conjugator2 = _mm_setr_epi8(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1); __m128i conjugator2 = _mm_setr_epi8(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1);
for (i = 0; i < sse_iters; ++i) for (i = 0; i < sse_iters; ++i)
@ -257,7 +257,7 @@ static inline void volk_gnsssdr_8ic_conjugate_8ic_a_sse3(lv_8sc_t* cVector, cons
const lv_8sc_t* a = aVector; const lv_8sc_t* a = aVector;
__m128i tmp; __m128i tmp;
__m128i conjugator1 = _mm_setr_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); __m128i conjugator1 = _mm_setr_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
__m128i conjugator2 = _mm_setr_epi8(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1); __m128i conjugator2 = _mm_setr_epi8(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1);
for (i = 0; i < sse_iters; ++i) for (i = 0; i < sse_iters; ++i)

View File

@ -73,7 +73,7 @@ static inline void volk_gnsssdr_8ic_s8ic_multiply_8ic_u_sse3(lv_8sc_t* cVector,
lv_8sc_t* c = cVector; lv_8sc_t* c = cVector;
const lv_8sc_t* a = aVector; const lv_8sc_t* a = aVector;
mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); mult1 = _mm_set_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
y = _mm_set1_epi16(*(short*)&scalar); y = _mm_set1_epi16(*(short*)&scalar);
imagy = _mm_srli_si128(y, 1); imagy = _mm_srli_si128(y, 1);
@ -166,7 +166,7 @@ static inline void volk_gnsssdr_8ic_s8ic_multiply_8ic_a_sse3(lv_8sc_t* cVector,
lv_8sc_t* c = cVector; lv_8sc_t* c = cVector;
const lv_8sc_t* a = aVector; const lv_8sc_t* a = aVector;
mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); mult1 = _mm_set_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
y = _mm_set1_epi16(*(short*)&scalar); y = _mm_set1_epi16(*(short*)&scalar);
imagy = _mm_srli_si128(y, 1); imagy = _mm_srli_si128(y, 1);

View File

@ -127,7 +127,7 @@ static inline void volk_gnsssdr_8ic_x2_dot_prod_8ic_u_sse2(lv_8sc_t* result, con
{ {
__m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc, realcacc, imagcacc; __m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc, realcacc, imagcacc;
mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); mult1 = _mm_set_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
realcacc = _mm_setzero_si128(); realcacc = _mm_setzero_si128();
imagcacc = _mm_setzero_si128(); imagcacc = _mm_setzero_si128();
@ -204,7 +204,7 @@ static inline void volk_gnsssdr_8ic_x2_dot_prod_8ic_u_sse4_1(lv_8sc_t* result, c
{ {
__m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc, realcacc, imagcacc; __m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc, realcacc, imagcacc;
mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); mult1 = _mm_set_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
realcacc = _mm_setzero_si128(); realcacc = _mm_setzero_si128();
imagcacc = _mm_setzero_si128(); imagcacc = _mm_setzero_si128();
@ -279,7 +279,7 @@ static inline void volk_gnsssdr_8ic_x2_dot_prod_8ic_a_sse2(lv_8sc_t* result, con
{ {
__m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc, realcacc, imagcacc; __m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc, realcacc, imagcacc;
mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); mult1 = _mm_set_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
realcacc = _mm_setzero_si128(); realcacc = _mm_setzero_si128();
imagcacc = _mm_setzero_si128(); imagcacc = _mm_setzero_si128();
@ -355,7 +355,7 @@ static inline void volk_gnsssdr_8ic_x2_dot_prod_8ic_a_sse4_1(lv_8sc_t* result, c
{ {
__m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc, realcacc, imagcacc; __m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc, realcacc, imagcacc;
mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); mult1 = _mm_set_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
realcacc = _mm_setzero_si128(); realcacc = _mm_setzero_si128();
imagcacc = _mm_setzero_si128(); imagcacc = _mm_setzero_si128();

View File

@ -73,7 +73,7 @@ static inline void volk_gnsssdr_8ic_x2_multiply_8ic_u_sse2(lv_8sc_t* cVector, co
const lv_8sc_t* a = aVector; const lv_8sc_t* a = aVector;
const lv_8sc_t* b = bVector; const lv_8sc_t* b = bVector;
mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); mult1 = _mm_set_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
for(number = 0; number < sse_iters; number++) for(number = 0; number < sse_iters; number++)
{ {
@ -131,7 +131,7 @@ static inline void volk_gnsssdr_8ic_x2_multiply_8ic_u_sse4_1(lv_8sc_t* cVector,
const lv_8sc_t* b = bVector; const lv_8sc_t* b = bVector;
_mm_setzero_si128(); _mm_setzero_si128();
mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); mult1 = _mm_set_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
for(number = 0; number < sse_iters; number++) for(number = 0; number < sse_iters; number++)
{ {
@ -202,7 +202,7 @@ static inline void volk_gnsssdr_8ic_x2_multiply_8ic_a_sse2(lv_8sc_t* cVector, co
const lv_8sc_t* a = aVector; const lv_8sc_t* a = aVector;
const lv_8sc_t* b = bVector; const lv_8sc_t* b = bVector;
mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); mult1 = _mm_set_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
for(number = 0; number < sse_iters; number++) for(number = 0; number < sse_iters; number++)
{ {
@ -260,7 +260,7 @@ static inline void volk_gnsssdr_8ic_x2_multiply_8ic_a_sse4_1(lv_8sc_t* cVector,
const lv_8sc_t* b = bVector; const lv_8sc_t* b = bVector;
_mm_setzero_si128(); _mm_setzero_si128();
mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); mult1 = _mm_set_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
for(number = 0; number < sse_iters; number++) for(number = 0; number < sse_iters; number++)
{ {

View File

@ -78,7 +78,7 @@ static inline void volk_gnsssdr_8u_x2_multiply_8u_u_sse3(unsigned char* cChar, c
x = _mm_lddqu_si128((__m128i*)a); x = _mm_lddqu_si128((__m128i*)a);
y = _mm_lddqu_si128((__m128i*)b); y = _mm_lddqu_si128((__m128i*)b);
mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); mult1 = _mm_set_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
x1 = _mm_srli_si128(x, 1); x1 = _mm_srli_si128(x, 1);
x1 = _mm_and_si128(x1, mult1); x1 = _mm_and_si128(x1, mult1);
x2 = _mm_and_si128(x, mult1); x2 = _mm_and_si128(x, mult1);
@ -144,7 +144,7 @@ static inline void volk_gnsssdr_8u_x2_multiply_8u_a_sse3(unsigned char* cChar, c
x = _mm_load_si128((__m128i*)a); x = _mm_load_si128((__m128i*)a);
y = _mm_load_si128((__m128i*)b); y = _mm_load_si128((__m128i*)b);
mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); mult1 = _mm_set_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
x1 = _mm_srli_si128(x, 1); x1 = _mm_srli_si128(x, 1);
x1 = _mm_and_si128(x1, mult1); x1 = _mm_and_si128(x1, mult1);
x2 = _mm_and_si128(x, mult1); x2 = _mm_and_si128(x, mult1);

View File

@ -16,6 +16,9 @@
# along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. # along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
# #
file(GLOB SIGNAL_SOURCE_ADAPTER_HEADERS "*.h")
list(SORT SIGNAL_SOURCE_ADAPTER_HEADERS)
# Optional drivers # Optional drivers
if(ENABLE_GN3S) if(ENABLE_GN3S)
@ -72,11 +75,11 @@ if(ENABLE_OSMOSDR)
################################################################################ ################################################################################
# OsmoSDR - http://sdr.osmocom.org/trac/ # OsmoSDR - http://sdr.osmocom.org/trac/
################################################################################ ################################################################################
find_package(GrOsmoSDR REQUIRED)
if(NOT GROSMOSDR_FOUND) if(NOT GROSMOSDR_FOUND)
message(FATAL_ERROR "gr-osmosdr required to build gnss-sdr with the optional OSMOSDR driver") if(ENABLE_PACKAGING)
endif(NOT GROSMOSDR_FOUND) list(REMOVE_ITEM SIGNAL_SOURCE_ADAPTER_HEADERS ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/adapters/osmosdr_signal_source.h)
endif(ENABLE_PACKAGING)
else(NOT GROSMOSDR_FOUND)
# set OSMO include dirs # set OSMO include dirs
set(OSMO_DRIVER_INCLUDE_DIRS set(OSMO_DRIVER_INCLUDE_DIRS
${OPT_DRIVER_INCLUDE_DIRS} ${OPT_DRIVER_INCLUDE_DIRS}
@ -85,13 +88,16 @@ if(ENABLE_OSMOSDR)
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} osmosdr_signal_source.cc) set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} osmosdr_signal_source.cc)
set(OPT_LIBRARIES ${OPT_LIBRARIES} ${GROSMOSDR_LIBRARIES}) set(OPT_LIBRARIES ${OPT_LIBRARIES} ${GROSMOSDR_LIBRARIES})
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${OSMO_DRIVER_INCLUDE_DIRS}) set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${OSMO_DRIVER_INCLUDE_DIRS})
endif(NOT GROSMOSDR_FOUND)
endif(ENABLE_OSMOSDR) endif(ENABLE_OSMOSDR)
if(ENABLE_UHD) if(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd)
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} uhd_signal_source.cc) set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} uhd_signal_source.cc)
set(OPT_LIBRARIES ${OPT_LIBRARIES} ${UHD_LIBRARIES} ${GNURADIO_UHD_LIBRARIES}) set(OPT_LIBRARIES ${OPT_LIBRARIES} ${UHD_LIBRARIES} ${GNURADIO_UHD_LIBRARIES})
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${UHD_INCLUDE_DIRS}) set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${UHD_INCLUDE_DIRS})
endif(ENABLE_UHD) else(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd)
list(REMOVE_ITEM SIGNAL_SOURCE_ADAPTER_HEADERS ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/adapters/uhd_signal_source.h)
endif(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd)
set(SIGNAL_SOURCE_ADAPTER_SOURCES file_signal_source.cc set(SIGNAL_SOURCE_ADAPTER_SOURCES file_signal_source.cc
@ -129,8 +135,6 @@ endif(ARCH_64BITS)
add_definitions(-DGNSSSDR_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}") add_definitions(-DGNSSSDR_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}")
file(GLOB SIGNAL_SOURCE_ADAPTER_HEADERS "*.h")
list(SORT SIGNAL_SOURCE_ADAPTER_HEADERS)
add_library(signal_source_adapters ${SIGNAL_SOURCE_ADAPTER_SOURCES} ${SIGNAL_SOURCE_ADAPTER_HEADERS}) add_library(signal_source_adapters ${SIGNAL_SOURCE_ADAPTER_SOURCES} ${SIGNAL_SOURCE_ADAPTER_HEADERS})
source_group(Headers FILES ${SIGNAL_SOURCE_ADAPTER_HEADERS}) source_group(Headers FILES ${SIGNAL_SOURCE_ADAPTER_HEADERS})
target_link_libraries(signal_source_adapters signal_source_gr_blocks target_link_libraries(signal_source_adapters signal_source_gr_blocks
@ -140,4 +144,3 @@ target_link_libraries(signal_source_adapters signal_source_gr_blocks
${OPT_LIBRARIES} ${OPT_LIBRARIES}
gnss_sp_libs gnss_sp_libs
) )

View File

@ -102,12 +102,14 @@ if(ENABLE_FLEXIBAND)
endif(ENABLE_FLEXIBAND) endif(ENABLE_FLEXIBAND)
if(ENABLE_OSMOSDR) if(ENABLE_OSMOSDR)
if(GROSMOSDR_FOUND)
add_definitions(-DOSMOSDR_DRIVER=1) add_definitions(-DOSMOSDR_DRIVER=1)
endif(GROSMOSDR_FOUND)
endif(ENABLE_OSMOSDR) endif(ENABLE_OSMOSDR)
if(ENABLE_UHD) if(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd)
add_definitions(-DUHD_DRIVER=1) add_definitions(-DUHD_DRIVER=1)
endif(ENABLE_UHD) endif(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd)
#Enable OpenCL if found in the system #Enable OpenCL if found in the system
if(OPENCL_FOUND) if(OPENCL_FOUND)

View File

@ -35,19 +35,20 @@
#include <vector> #include <vector>
#include <utility> // std::pair #include <utility> // std::pair
#include "MATH_CONSTANTS.h" #include "MATH_CONSTANTS.h"
#include "gnss_frequencies.h"
// Physical constants // Physical constants
const double GPS_C_m_s = 299792458.0; //!< The speed of light, [m/s] const double GPS_C_m_s = SPEED_OF_LIGHT; //!< The speed of light, [m/s]
const double GPS_C_m_ms = 299792.4580; //!< The speed of light, [m/ms] const double GPS_C_m_ms = 299792.4580; //!< The speed of light, [m/ms]
const double GPS_PI = 3.1415926535898; //!< Pi as defined in IS-GPS-200E const double GPS_PI = 3.1415926535898; //!< Pi as defined in IS-GPS-200E
const double GPS_TWO_PI = 6.283185307179586;//!< 2Pi as defined in IS-GPS-200E const double GPS_TWO_PI = 6.283185307179586;//!< 2Pi as defined in IS-GPS-200E
const double OMEGA_EARTH_DOT = 7.2921151467e-5; //!< Earth rotation rate, [rad/s] const double OMEGA_EARTH_DOT = DEFAULT_OMEGA_EARTH_DOT; //!< Earth rotation rate, [rad/s]
const double GM = 3.986005e14; //!< Universal gravitational constant times the mass of the Earth, [m^3/s^2] const double GM = 3.986005e14; //!< Universal gravitational constant times the mass of the Earth, [m^3/s^2]
const double F = -4.442807633e-10; //!< Constant, [s/(m)^(1/2)] const double F = -4.442807633e-10; //!< Constant, [s/(m)^(1/2)]
// carrier and code frequencies // carrier and code frequencies
const double GPS_L1_FREQ_HZ = 1.57542e9; //!< L1 [Hz] const double GPS_L1_FREQ_HZ = FREQ1; //!< L1 [Hz]
const double GPS_L1_CA_CODE_RATE_HZ = 1.023e6; //!< GPS L1 C/A code rate [chips/s] const double GPS_L1_CA_CODE_RATE_HZ = 1.023e6; //!< GPS L1 C/A code rate [chips/s]
const double GPS_L1_CA_CODE_LENGTH_CHIPS = 1023.0; //!< GPS L1 C/A code length [chips] const double GPS_L1_CA_CODE_LENGTH_CHIPS = 1023.0; //!< GPS L1 C/A code length [chips]
const double GPS_L1_CA_CODE_PERIOD = 0.001; //!< GPS L1 C/A code period [seconds] const double GPS_L1_CA_CODE_PERIOD = 0.001; //!< GPS L1 C/A code period [seconds]

View File

@ -36,6 +36,7 @@
#include <vector> #include <vector>
#include <utility> // std::pair #include <utility> // std::pair
#include "MATH_CONSTANTS.h" #include "MATH_CONSTANTS.h"
#include "gnss_frequencies.h"
// Physical constants // Physical constants
const double GPS_L2_C_m_s = 299792458.0; //!< The speed of light, [m/s] const double GPS_L2_C_m_s = 299792458.0; //!< The speed of light, [m/s]
@ -48,7 +49,7 @@ const double GPS_L2_F = -4.442807633e-10; //!< Constant, [s/(m)^(1
// carrier and code frequencies // carrier and code frequencies
const double GPS_L2_FREQ_HZ = 1.2276e9; //!< L2 [Hz] const double GPS_L2_FREQ_HZ = FREQ2; //!< L2 [Hz]
const double GPS_L2_M_CODE_RATE_HZ = 0.5115e6; //!< GPS L2 M code rate [chips/s] const double GPS_L2_M_CODE_RATE_HZ = 0.5115e6; //!< GPS L2 M code rate [chips/s]
const int GPS_L2_M_CODE_LENGTH_CHIPS = 10230; //!< GPS L2 M code length [chips] const int GPS_L2_M_CODE_LENGTH_CHIPS = 10230; //!< GPS L2 M code length [chips]

View File

@ -37,6 +37,7 @@
#include <vector> #include <vector>
#include <utility> // std::pair #include <utility> // std::pair
#include "MATH_CONSTANTS.h" #include "MATH_CONSTANTS.h"
#include "gnss_frequencies.h"
// Physical constants // Physical constants
const double GALILEO_PI = 3.1415926535898; //!< Pi as defined in GALILEO ICD const double GALILEO_PI = 3.1415926535898; //!< Pi as defined in GALILEO ICD
@ -48,7 +49,7 @@ const double GALILEO_C_m_ms = 299792.4580; //!< The speed of light, [m/ms]
const double GALILEO_F = -4.442807309e-10; //!< Constant, [s/(m)^(1/2)] const double GALILEO_F = -4.442807309e-10; //!< Constant, [s/(m)^(1/2)]
// carrier and code frequencies // carrier and code frequencies
const double Galileo_E1_FREQ_HZ = 1.57542e9; //!< Galileo E1 carrier frequency [Hz] const double Galileo_E1_FREQ_HZ = FREQ1; //!< Galileo E1 carrier frequency [Hz]
const double Galileo_E1_CODE_CHIP_RATE_HZ = 1.023e6; //!< Galileo E1 code rate [chips/s] const double Galileo_E1_CODE_CHIP_RATE_HZ = 1.023e6; //!< Galileo E1 code rate [chips/s]
const double Galileo_E1_CODE_PERIOD = 0.004; //!< Galileo E1 code period [s] const double Galileo_E1_CODE_PERIOD = 0.004; //!< Galileo E1 code period [s]
const double Galileo_E1_SUB_CARRIER_A_RATE_HZ = 1.023e6; //!< Galileo E1 sub-carrier 'a' rate [Hz] const double Galileo_E1_SUB_CARRIER_A_RATE_HZ = 1.023e6; //!< Galileo E1 sub-carrier 'a' rate [Hz]

View File

@ -35,11 +35,11 @@
#include <vector> #include <vector>
#include <utility> // std::pair #include <utility> // std::pair
#include "MATH_CONSTANTS.h" #include "MATH_CONSTANTS.h"
#include "gnss_frequencies.h"
// Physical constants already defined in E1
// Carrier and code frequencies // Carrier and code frequencies
const double Galileo_E5a_FREQ_HZ = 1.176450e9; //!< Galileo E5a carrier frequency [Hz] const double Galileo_E5a_FREQ_HZ = FREQ5; //!< Galileo E5a carrier frequency [Hz]
const double Galileo_E5a_CODE_CHIP_RATE_HZ = 1.023e7; //!< Galileo E5a code rate [chips/s] const double Galileo_E5a_CODE_CHIP_RATE_HZ = 1.023e7; //!< Galileo E5a code rate [chips/s]
const double Galileo_E5a_I_TIERED_CODE_PERIOD = 0.020; //!< Galileo E5a-I tiered code period [s] const double Galileo_E5a_I_TIERED_CODE_PERIOD = 0.020; //!< Galileo E5a-I tiered code period [s]
const double Galileo_E5a_Q_TIERED_CODE_PERIOD = 0.100; //!< Galileo E5a-Q tiered code period [s] const double Galileo_E5a_Q_TIERED_CODE_PERIOD = 0.100; //!< Galileo E5a-Q tiered code period [s]

View File

@ -40,6 +40,9 @@
PI_TWO_PX ==> Pi*2^X PI_TWO_PX ==> Pi*2^X
ONE_PI_TWO_PX = (1/Pi)*2^X ONE_PI_TWO_PX = (1/Pi)*2^X
*/ */
const double PI = 3.1415926535897932; //!< pi
const double TWO_P4 = (16); //!< 2^4 const double TWO_P4 = (16); //!< 2^4
const double TWO_P11 = (2048); //!< 2^11 const double TWO_P11 = (2048); //!< 2^11
const double TWO_P12 = (4096); //!< 2^12 const double TWO_P12 = (4096); //!< 2^12
@ -53,6 +56,7 @@ const double TWO_P57 = (1.441151880758559e+017); //!< 2^57
const double TWO_N2 = (0.25); //!< 2^-2 const double TWO_N2 = (0.25); //!< 2^-2
const double TWO_N5 = (0.03125); //!< 2^-5 const double TWO_N5 = (0.03125); //!< 2^-5
const double TWO_N6 = (0.015625); //!< 2^-6
const double TWO_N8 = (0.00390625); //!< 2^-8 const double TWO_N8 = (0.00390625); //!< 2^-8
const double TWO_N9 = (0.001953125); //!< 2^-9 const double TWO_N9 = (0.001953125); //!< 2^-9
const double TWO_N10 = (0.0009765625); //!< 2^-10 const double TWO_N10 = (0.0009765625); //!< 2^-10
@ -60,9 +64,11 @@ const double TWO_N11 = (4.882812500000000e-004); //!< 2^-11
const double TWO_N14 = (0.00006103515625); //!< 2^-14 const double TWO_N14 = (0.00006103515625); //!< 2^-14
const double TWO_N15 = (0.00003051757813); //!< 2^-15 const double TWO_N15 = (0.00003051757813); //!< 2^-15
const double TWO_N16 = (0.0000152587890625); //!< 2^-16 const double TWO_N16 = (0.0000152587890625); //!< 2^-16
const double TWO_N17 = (7.629394531250000e-006); //!< 2^-17
const double TWO_N19 = (1.907348632812500e-006); //!< 2^-19 const double TWO_N19 = (1.907348632812500e-006); //!< 2^-19
const double TWO_N20 = (9.536743164062500e-007); //!< 2^-20 const double TWO_N20 = (9.536743164062500e-007); //!< 2^-20
const double TWO_N21 = (4.768371582031250e-007); //!< 2^-21 const double TWO_N21 = (4.768371582031250e-007); //!< 2^-21
const double TWO_N23 = (1.192092895507810e-007); //!< 2^-23
const double TWO_N24 = (5.960464477539063e-008); //!< 2^-24 const double TWO_N24 = (5.960464477539063e-008); //!< 2^-24
const double TWO_N25 = (2.980232238769531e-008); //!< 2^-25 const double TWO_N25 = (2.980232238769531e-008); //!< 2^-25
const double TWO_N27 = (7.450580596923828e-009); //!< 2^-27 const double TWO_N27 = (7.450580596923828e-009); //!< 2^-27
@ -73,8 +79,9 @@ const double TWO_N32 = (2.328306436538696e-010); //!< 2^-32
const double TWO_N33 = (1.164153218269348e-010); //!< 2^-33 const double TWO_N33 = (1.164153218269348e-010); //!< 2^-33
const double TWO_N34 = (5.82076609134674e-011); //!< 2^-34 const double TWO_N34 = (5.82076609134674e-011); //!< 2^-34
const double TWO_N35 = (2.91038304567337e-011); //!< 2^-35 const double TWO_N35 = (2.91038304567337e-011); //!< 2^-35
const double TWO_N38 = (3.637978807091713e-012); //!< 2^-38 const double TWO_N38 = (3.637978807091713e-012); //!< 2^-38
const double TWO_N39 = (1.818989403545856e-012); //!< 2^-39
const double TWO_N40 = (9.094947017729280e-013); //!< 2^-40
const double TWO_N43 = (1.136868377216160e-013); //!< 2^-43 const double TWO_N43 = (1.136868377216160e-013); //!< 2^-43
const double TWO_N44 = (5.684341886080802e-14); //!< 2^-44 const double TWO_N44 = (5.684341886080802e-14); //!< 2^-44
const double TWO_N46 = (1.4210854715202e-014); //!< 2^-46 const double TWO_N46 = (1.4210854715202e-014); //!< 2^-46
@ -95,4 +102,13 @@ const double PI_TWO_N31 = (1.462918079267160e-009); //!< Pi*2^-31
const double PI_TWO_N38 = (1.142904749427469e-011); //!< Pi*2^-38 const double PI_TWO_N38 = (1.142904749427469e-011); //!< Pi*2^-38
const double PI_TWO_N23 = (3.745070282923929e-007); //!< Pi*2^-23 const double PI_TWO_N23 = (3.745070282923929e-007); //!< Pi*2^-23
const double D2R = (PI/180.0); //!< deg to rad
const double R2D = (180.0/PI); //!< rad to deg
const double SC2RAD = 3.1415926535898; //!< semi-circle to radian (IS-GPS)
const double AS2R = (D2R / 3600.0); //!< arc sec to radian
const double DEFAULT_OMEGA_EARTH_DOT = 7.2921151467e-5; //!< Default Earth rotation rate, [rad/s]
const double SPEED_OF_LIGHT = 299792458.0; //!< [m/s]
const double AU = 149597870691.0; //!< 1 Astronomical Unit AU (m) distance from Earth to the Sun.
#endif /* GNSS_SDR_MATH_CONSTANTS_H_ */ #endif /* GNSS_SDR_MATH_CONSTANTS_H_ */

View File

@ -0,0 +1,53 @@
/*!
* \file gnss_frequencies.h
* \brief GNSS Frequencies
* \author Carles Fernandez, 2017. cfernandez(at)cttc.es
*
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_GNSS_FREQUENCIES_H_
#define GNSS_SDR_GNSS_FREQUENCIES_H_
const double FREQ1 = 1.57542e9; //!< L1/E1 frequency (Hz)
const double FREQ2 = 1.22760e9; //!< L2 frequency (Hz)
const double FREQ5 = 1.17645e9; //!< L5/E5a frequency (Hz)
const double FREQ6 = 1.27875e9; //!< E6/LEX frequency (Hz)
const double FREQ7 = 1.20714e9; //!< E5b frequency (Hz)
const double FREQ8 = 1.191795e9; //!< E5a+b frequency (Hz)
const double FREQ9 = 2.492028e9; //!< S frequency (Hz)
const double FREQ1_GLO = 1.60200e9; //!< GLONASS G1 base frequency (Hz)
const double DFRQ1_GLO = 0.56250e6; //!< GLONASS G1 bias frequency (Hz/n)
const double FREQ2_GLO = 1.24600e9; //!< GLONASS G2 base frequency (Hz)
const double DFRQ2_GLO = 0.43750e6; //!< GLONASS G2 bias frequency (Hz/n)
const double FREQ3_GLO = 1.202025e9; //!< GLONASS G3 frequency (Hz)
const double FREQ1_BDS = 1.561098e9; //!< BeiDou B1 frequency (Hz)
const double FREQ2_BDS = 1.20714e9; //!< BeiDou B2 frequency (Hz)
const double FREQ3_BDS = 1.26852e9; //!< BeiDou B3 frequency (Hz)
#endif

View File

@ -0,0 +1,97 @@
/*!
* \file gnss_obs_codes.h
* \brief GNSS Observable codes
* \author Carles Fernandez, 2017. cfernandez(at)cttc.es
*
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_GNSS_OBS_CODES_H_
#define GNSS_SDR_GNSS_OBS_CODES_H_
const unsigned int CODE_NONE = 0; //!< obs code: none or unknown
const unsigned int CODE_L1C = 1; //!< obs code: L1C/A,G1C/A,E1C (GPS,GLO,GAL,QZS,SBS)
const unsigned int CODE_L1P = 2; //!< obs code: L1P,G1P (GPS,GLO)
const unsigned int CODE_L1W = 3; //!< obs code: L1 Z-track (GPS)
const unsigned int CODE_L1Y = 4; //!< obs code: L1Y (GPS)
const unsigned int CODE_L1M = 5; //!< obs code: L1M (GPS)
const unsigned int CODE_L1N = 6; //!< obs code: L1codeless (GPS)
const unsigned int CODE_L1S = 7; //!< obs code: L1C(D) (GPS,QZS)
const unsigned int CODE_L1L = 8; //!< obs code: L1C(P) (GPS,QZS)
const unsigned int CODE_L1E = 9; //!< (not used)
const unsigned int CODE_L1A = 10; //!< obs code: E1A (GAL)
const unsigned int CODE_L1B = 11; //!< obs code: E1B (GAL)
const unsigned int CODE_L1X = 12; //!< obs code: E1B+C,L1C(D+P) (GAL,QZS)
const unsigned int CODE_L1Z = 13; //!< obs code: E1A+B+C,L1SAIF (GAL,QZS)
const unsigned int CODE_L2C = 14; //!< obs code: L2C/A,G1C/A (GPS,GLO)
const unsigned int CODE_L2D = 15; //!< obs code: L2 L1C/A-(P2-P1) (GPS)
const unsigned int CODE_L2S = 16; //!< obs code: L2C(M) (GPS,QZS)
const unsigned int CODE_L2L = 17; //!< obs code: L2C(L) (GPS,QZS)
const unsigned int CODE_L2X = 18; //!< obs code: L2C(M+L),B1I+Q (GPS,QZS,BDS)
const unsigned int CODE_L2P = 19; //!< obs code: L2P,G2P (GPS,GLO)
const unsigned int CODE_L2W = 20; //!< obs code: L2 Z-track (GPS)
const unsigned int CODE_L2Y = 21; //!< obs code: L2Y (GPS)
const unsigned int CODE_L2M = 22; //!< obs code: L2M (GPS)
const unsigned int CODE_L2N = 23; //!< obs code: L2codeless (GPS)
const unsigned int CODE_L5I = 24; //!< obs code: L5/E5aI (GPS,GAL,QZS,SBS)
const unsigned int CODE_L5Q = 25; //!< obs code: L5/E5aQ (GPS,GAL,QZS,SBS)
const unsigned int CODE_L5X = 26; //!< obs code: L5/E5aI+Q/L5B+C (GPS,GAL,QZS,IRN,SBS)
const unsigned int CODE_L7I = 27; //!< obs code: E5bI,B2I (GAL,BDS)
const unsigned int CODE_L7Q = 28; //!< obs code: E5bQ,B2Q (GAL,BDS)
const unsigned int CODE_L7X = 29; //!< obs code: E5bI+Q,B2I+Q (GAL,BDS)
const unsigned int CODE_L6A = 30; //!< obs code: E6A (GAL)
const unsigned int CODE_L6B = 31; //!< obs code: E6B (GAL)
const unsigned int CODE_L6C = 32; //!< obs code: E6C (GAL)
const unsigned int CODE_L6X = 33; //!< obs code: E6B+C,LEXS+L,B3I+Q (GAL,QZS,BDS)
const unsigned int CODE_L6Z = 34; //!< obs code: E6A+B+C (GAL)
const unsigned int CODE_L6S = 35; //!< obs code: LEXS (QZS)
const unsigned int CODE_L6L = 36; //!< obs code: LEXL (QZS)
const unsigned int CODE_L8I = 37; //!< obs code: E5(a+b)I (GAL)
const unsigned int CODE_L8Q = 38; //!< obs code: E5(a+b)Q (GAL)
const unsigned int CODE_L8X = 39; //!< obs code: E5(a+b)I+Q (GAL)
const unsigned int CODE_L2I = 40; //!< obs code: B1I (BDS)
const unsigned int CODE_L2Q = 41; //!< obs code: B1Q (BDS)
const unsigned int CODE_L6I = 42; //!< obs code: B3I (BDS)
const unsigned int CODE_L6Q = 43; //!< obs code: B3Q (BDS)
const unsigned int CODE_L3I = 44; //!< obs code: G3I (GLO)
const unsigned int CODE_L3Q = 45; //!< obs code: G3Q (GLO)
const unsigned int CODE_L3X = 46; //!< obs code: G3I+Q (GLO)
const unsigned int CODE_L1I = 47; //!< obs code: B1I (BDS)
const unsigned int CODE_L1Q = 48; //!< obs code: B1Q (BDS)
const unsigned int CODE_L5A = 49; //!< obs code: L5A SPS (IRN)
const unsigned int CODE_L5B = 50; //!< obs code: L5B RS(D) (IRN)
const unsigned int CODE_L5C = 51; //!< obs code: L5C RS(P) (IRN)
const unsigned int CODE_L9A = 52; //!< obs code: SA SPS (IRN)
const unsigned int CODE_L9B = 53; //!< obs code: SB RS(D) (IRN)
const unsigned int CODE_L9C = 54; //!< obs code: SC RS(P) (IRN)
const unsigned int CODE_L9X = 55; //!< obs code: SB+C (IRN)
const unsigned int MAXCODE = 55; //!< max number of obs code
#endif

View File

@ -28,10 +28,10 @@ if(ENABLE_GPERFTOOLS)
endif(GPERFTOOLS_FOUND) endif(GPERFTOOLS_FOUND)
endif(ENABLE_GPERFTOOLS) endif(ENABLE_GPERFTOOLS)
if(ENABLE_UHD) if(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd)
set(GNSS_SDR_OPTIONAL_LIBS ${GNSS_SDR_OPTIONAL_LIBS} ${UHD_LIBRARIES} ${GNURADIO_UHD_LIBRARIES}) set(GNSS_SDR_OPTIONAL_LIBS ${GNSS_SDR_OPTIONAL_LIBS} ${UHD_LIBRARIES} ${GNURADIO_UHD_LIBRARIES})
set(GNSS_SDR_OPTIONAL_HEADERS ${GNSS_SDR_OPTIONAL_HEADERS} ${UHD_INCLUDE_DIRS}) set(GNSS_SDR_OPTIONAL_HEADERS ${GNSS_SDR_OPTIONAL_HEADERS} ${UHD_INCLUDE_DIRS})
endif(ENABLE_UHD) endif(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd)
if(OPENSSL_FOUND) if(OPENSSL_FOUND)
add_definitions( -DUSE_OPENSSL_FALLBACK=1 ) add_definitions( -DUSE_OPENSSL_FALLBACK=1 )
@ -130,6 +130,12 @@ if(NOT GZIP_NOTFOUND)
WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_FILE "${CMAKE_BINARY_DIR}/gnss-sdr.1.gz") WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_FILE "${CMAKE_BINARY_DIR}/gnss-sdr.1.gz")
install(FILES ${CMAKE_BINARY_DIR}/gnss-sdr.1.gz DESTINATION share/man/man1) install(FILES ${CMAKE_BINARY_DIR}/gnss-sdr.1.gz DESTINATION share/man/man1)
execute_process(COMMAND gzip -9 -c ${CMAKE_SOURCE_DIR}/docs/changelog
WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_FILE "${CMAKE_BINARY_DIR}/changelog.gz")
install(FILES ${CMAKE_BINARY_DIR}/changelog.gz DESTINATION share/doc/gnss-sdr)
if(NOT VOLK_GNSSSDR_FOUND) if(NOT VOLK_GNSSSDR_FOUND)
execute_process(COMMAND gzip -9 -c ${CMAKE_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr_profile-manpage execute_process(COMMAND gzip -9 -c ${CMAKE_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr_profile-manpage
WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_FILE "${CMAKE_BINARY_DIR}/volk_gnsssdr_profile.1.gz") WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_FILE "${CMAKE_BINARY_DIR}/volk_gnsssdr_profile.1.gz")

View File

@ -392,6 +392,7 @@ if(ENABLE_SYSTEM_TESTING)
gnss_rx gnss_rx
gnss_system_parameters gnss_system_parameters
) )
if(ENABLE_INSTALL_TESTS) if(ENABLE_INSTALL_TESTS)
if(EXISTS ${CMAKE_SOURCE_DIR}/install/ttff) if(EXISTS ${CMAKE_SOURCE_DIR}/install/ttff)
file(REMOVE ${CMAKE_SOURCE_DIR}/install/ttff) file(REMOVE ${CMAKE_SOURCE_DIR}/install/ttff)
@ -404,6 +405,39 @@ if(ENABLE_SYSTEM_TESTING)
endif(ENABLE_INSTALL_TESTS) endif(ENABLE_INSTALL_TESTS)
if(ENABLE_SYSTEM_TESTING_EXTRA) if(ENABLE_SYSTEM_TESTING_EXTRA)
add_executable(position_test
${CMAKE_CURRENT_SOURCE_DIR}/system-tests/position_test.cc )
if(NOT ${GTEST_DIR_LOCAL})
add_dependencies(position_test gtest-${gtest_RELEASE})
else(NOT ${GTEST_DIR_LOCAL})
add_dependencies(position_test gtest)
endif(NOT ${GTEST_DIR_LOCAL})
target_link_libraries(position_test
${Boost_LIBRARIES}
${GFlags_LIBS}
${GLOG_LIBRARIES}
${GTEST_LIBRARIES}
${GNURADIO_RUNTIME_LIBRARIES}
${GNURADIO_BLOCKS_LIBRARIES}
${GNURADIO_FILTER_LIBRARIES}
${GNURADIO_ANALOG_LIBRARIES}
${VOLK_GNSSSDR_LIBRARIES}
gnss_sp_libs
gnss_rx
gnss_system_parameters
)
if(ENABLE_INSTALL_TESTS)
if(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test)
file(REMOVE ${CMAKE_SOURCE_DIR}/install/position_test)
endif(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test)
install(TARGETS position_test RUNTIME DESTINATION bin COMPONENT "position_test")
else(ENABLE_INSTALL_TESTS)
add_custom_command(TARGET position_test POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:position_test>
${CMAKE_SOURCE_DIR}/install/$<TARGET_FILE_NAME:position_test> )
endif(ENABLE_INSTALL_TESTS)
if(GPSTK_FOUND OR OWN_GPSTK) if(GPSTK_FOUND OR OWN_GPSTK)
add_executable(obs_gps_l1_system_test ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_gps_l1_system_test.cc) add_executable(obs_gps_l1_system_test ${CMAKE_CURRENT_SOURCE_DIR}/system-tests/obs_gps_l1_system_test.cc)
if(NOT ${GTEST_DIR_LOCAL}) if(NOT ${GTEST_DIR_LOCAL})
@ -418,6 +452,7 @@ if(ENABLE_SYSTEM_TESTING)
gnss_sp_libs gnss_sp_libs
gnss_rx gnss_rx
${gpstk_libs}) ${gpstk_libs})
if(ENABLE_INSTALL_TESTS) if(ENABLE_INSTALL_TESTS)
if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test)
@ -430,6 +465,7 @@ if(ENABLE_SYSTEM_TESTING)
endif(ENABLE_INSTALL_TESTS) endif(ENABLE_INSTALL_TESTS)
endif(GPSTK_FOUND OR OWN_GPSTK) endif(GPSTK_FOUND OR OWN_GPSTK)
endif(ENABLE_SYSTEM_TESTING_EXTRA) endif(ENABLE_SYSTEM_TESTING_EXTRA)
endif(ENABLE_SYSTEM_TESTING) endif(ENABLE_SYSTEM_TESTING)
@ -439,15 +475,11 @@ endif(ENABLE_SYSTEM_TESTING)
set(CMAKE_CTEST_COMMAND ctest -V) set(CMAKE_CTEST_COMMAND ctest -V)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
add_executable(control_thread_test if(NOT ${ENABLE_PACKAGING})
${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc add_executable(control_thread_test ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc
${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/control_message_factory_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/control_message_factory_test.cc
${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/control_thread_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/control_thread_test.cc
) )
if(NOT ${ENABLE_PACKAGING})
set_property(TARGET control_thread_test PROPERTY EXCLUDE_FROM_ALL TRUE)
endif(NOT ${ENABLE_PACKAGING})
target_link_libraries(control_thread_test ${Boost_LIBRARIES} target_link_libraries(control_thread_test ${Boost_LIBRARIES}
${GFlags_LIBS} ${GFlags_LIBS}
${GLOG_LIBRARIES} ${GLOG_LIBRARIES}
@ -457,7 +489,6 @@ target_link_libraries(control_thread_test ${Boost_LIBRARIES}
gnss_rx gnss_rx
${VOLK_GNSSSDR_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES}
) )
add_test(control_thread_test control_thread_test) add_test(control_thread_test control_thread_test)
if(NOT ${GTEST_DIR_LOCAL}) if(NOT ${GTEST_DIR_LOCAL})
add_dependencies(control_thread_test gtest-${gtest_RELEASE}) add_dependencies(control_thread_test gtest-${gtest_RELEASE})
@ -465,15 +496,13 @@ else(NOT ${GTEST_DIR_LOCAL})
add_dependencies(control_thread_test gtest) add_dependencies(control_thread_test gtest)
endif(NOT ${GTEST_DIR_LOCAL}) endif(NOT ${GTEST_DIR_LOCAL})
set_property(TEST control_thread_test PROPERTY TIMEOUT 30) set_property(TEST control_thread_test PROPERTY TIMEOUT 30)
set_property(TARGET control_thread_test PROPERTY EXCLUDE_FROM_ALL TRUE)
add_executable(flowgraph_test #########################################################
${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc
${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/gnss_flowgraph_test.cc add_executable(flowgraph_test ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc
) ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/gnss_flowgraph_test.cc )
if(NOT ${ENABLE_PACKAGING})
set_property(TARGET flowgraph_test PROPERTY EXCLUDE_FROM_ALL TRUE) set_property(TARGET flowgraph_test PROPERTY EXCLUDE_FROM_ALL TRUE)
endif(NOT ${ENABLE_PACKAGING})
target_link_libraries(flowgraph_test ${Boost_LIBRARIES} target_link_libraries(flowgraph_test ${Boost_LIBRARIES}
${GFlags_LIBS} ${GFlags_LIBS}
${GLOG_LIBRARIES} ${GLOG_LIBRARIES}
@ -481,9 +510,7 @@ target_link_libraries(flowgraph_test ${Boost_LIBRARIES}
gnss_sp_libs gnss_sp_libs
gnss_rx gnss_rx
gnss_system_parameters gnss_system_parameters
${VOLK_GNSSSDR_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} )
)
add_test(flowgraph_test flowgraph_test) add_test(flowgraph_test flowgraph_test)
if(NOT ${GTEST_DIR_LOCAL}) if(NOT ${GTEST_DIR_LOCAL})
add_dependencies(flowgraph_test gtest-${gtest_RELEASE}) add_dependencies(flowgraph_test gtest-${gtest_RELEASE})
@ -491,18 +518,17 @@ else(NOT ${GTEST_DIR_LOCAL})
add_dependencies(flowgraph_test gtest) add_dependencies(flowgraph_test gtest)
endif(NOT ${GTEST_DIR_LOCAL}) endif(NOT ${GTEST_DIR_LOCAL})
set_property(TEST flowgraph_test PROPERTY TIMEOUT 30) set_property(TEST flowgraph_test PROPERTY TIMEOUT 30)
set_property(TARGET flowgraph_test PROPERTY EXCLUDE_FROM_ALL TRUE)
add_executable(gnss_block_test #########################################################
${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc
add_executable(gnss_block_test ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc
${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/sources/file_signal_source_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/sources/file_signal_source_test.cc
${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc
${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/adapter/pass_through_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/adapter/pass_through_test.cc
${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/gnss_block_factory_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/gnss_block_factory_test.cc
) )
if(NOT ${ENABLE_PACKAGING})
set_property(TARGET gnss_block_test PROPERTY EXCLUDE_FROM_ALL TRUE) set_property(TARGET gnss_block_test PROPERTY EXCLUDE_FROM_ALL TRUE)
endif(NOT ${ENABLE_PACKAGING})
target_link_libraries(gnss_block_test ${Boost_LIBRARIES} target_link_libraries(gnss_block_test ${Boost_LIBRARIES}
${GFlags_LIBS} ${GFlags_LIBS}
${GLOG_LIBRARIES} ${GLOG_LIBRARIES}
@ -514,25 +540,20 @@ target_link_libraries(gnss_block_test ${Boost_LIBRARIES}
gnss_sp_libs gnss_sp_libs
gnss_rx gnss_rx
gnss_system_parameters gnss_system_parameters
# signal_generator_blocks
${VOLK_GNSSSDR_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES}
) )
add_test(gnss_block_test gnss_block_test) add_test(gnss_block_test gnss_block_test)
if(NOT ${GTEST_DIR_LOCAL}) if(NOT ${GTEST_DIR_LOCAL})
add_dependencies(gnss_block_test gtest-${gtest_RELEASE}) add_dependencies(gnss_block_test gtest-${gtest_RELEASE})
else(NOT ${GTEST_DIR_LOCAL}) else(NOT ${GTEST_DIR_LOCAL})
add_dependencies(gnss_block_test gtest) add_dependencies(gnss_block_test gtest)
endif(NOT ${GTEST_DIR_LOCAL}) endif(NOT ${GTEST_DIR_LOCAL})
add_executable(gnuradio_block_test
${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc
${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc
)
if(NOT ${ENABLE_PACKAGING})
set_property(TARGET gnuradio_block_test PROPERTY EXCLUDE_FROM_ALL TRUE)
endif(NOT ${ENABLE_PACKAGING}) endif(NOT ${ENABLE_PACKAGING})
add_executable(gnuradio_block_test ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc
${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc
)
target_link_libraries(gnuradio_block_test ${Boost_LIBRARIES} target_link_libraries(gnuradio_block_test ${Boost_LIBRARIES}
${GFlags_LIBS} ${GFlags_LIBS}
${GLOG_LIBRARIES} ${GLOG_LIBRARIES}
@ -544,10 +565,8 @@ target_link_libraries(gnuradio_block_test ${Boost_LIBRARIES}
gnss_sp_libs gnss_sp_libs
gnss_rx gnss_rx
gnss_system_parameters gnss_system_parameters
# signal_generator_blocks
${VOLK_GNSSSDR_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES}
) )
add_test(gnuradio_block_test gnuradio_block_test) add_test(gnuradio_block_test gnuradio_block_test)
if(NOT ${GTEST_DIR_LOCAL}) if(NOT ${GTEST_DIR_LOCAL})
add_dependencies(gnuradio_block_test gtest-${gtest_RELEASE}) add_dependencies(gnuradio_block_test gtest-${gtest_RELEASE})
@ -576,16 +595,10 @@ endif(NOT ${GTEST_DIR_LOCAL})
# ) # )
# add_test(acq_test acq_test) # add_test(acq_test acq_test)
add_executable(trk_test add_executable(trk_test ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc
${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc
${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc
${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc
) )
if(NOT ${ENABLE_PACKAGING})
set_property(TARGET trk_test PROPERTY EXCLUDE_FROM_ALL TRUE)
endif(NOT ${ENABLE_PACKAGING})
target_link_libraries(trk_test ${Boost_LIBRARIES} target_link_libraries(trk_test ${Boost_LIBRARIES}
${GFlags_LIBS} ${GFlags_LIBS}
${GLOG_LIBRARIES} ${GLOG_LIBRARIES}
@ -607,5 +620,10 @@ else(NOT ${GTEST_DIR_LOCAL})
add_dependencies(trk_test gtest) add_dependencies(trk_test gtest)
endif(NOT ${GTEST_DIR_LOCAL}) endif(NOT ${GTEST_DIR_LOCAL})
if(${ENABLE_PACKAGING})
add_dependencies(check gnuradio_block_test trk_test)
else(${ENABLE_PACKAGING})
add_dependencies(check control_thread_test flowgraph_test gnss_block_test add_dependencies(check control_thread_test flowgraph_test gnss_block_test
gnuradio_block_test trk_test) gnuradio_block_test trk_test)
endif(${ENABLE_PACKAGING})

View File

@ -48,10 +48,10 @@
#include "gps_ref_location.h" #include "gps_ref_location.h"
#include "gps_ref_time.h" #include "gps_ref_time.h"
#include "galileo_navigation_message.h" #include "galileo_navigation_message.h"
#include "sbas_ionospheric_correction.h" //#include "sbas_ionospheric_correction.h"
#include "sbas_telemetry_data.h" //#include "sbas_telemetry_data.h"
#include "sbas_ephemeris.h" //#include "sbas_ephemeris.h"
#include "sbas_satellite_correction.h" //#include "sbas_satellite_correction.h"
concurrent_queue<Gps_Acq_Assist> global_gps_acq_assist_queue; concurrent_queue<Gps_Acq_Assist> global_gps_acq_assist_queue;

View File

@ -33,10 +33,12 @@
#include <exception> #include <exception>
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
#include <chrono>
#include <numeric> #include <numeric>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <thread>
#include <unistd.h> #include <unistd.h>
#include <gflags/gflags.h> #include <gflags/gflags.h>
#include <glog/logging.h> #include <glog/logging.h>
@ -57,6 +59,7 @@
concurrent_queue<Gps_Acq_Assist> global_gps_acq_assist_queue; concurrent_queue<Gps_Acq_Assist> global_gps_acq_assist_queue;
concurrent_map<Gps_Acq_Assist> global_gps_acq_assist_map; concurrent_map<Gps_Acq_Assist> global_gps_acq_assist_map;
class Obs_Gps_L1_System_Test: public ::testing::Test class Obs_Gps_L1_System_Test: public ::testing::Test
{ {
public: public:
@ -71,7 +74,7 @@ public:
std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_rinex_obs = FLAGS_filename_rinex_obs;
std::string filename_raw_data = FLAGS_filename_raw_data; std::string filename_raw_data = FLAGS_filename_raw_data;
std::string generated_rinex_obs;
int configure_generator(); int configure_generator();
int generate_signal(); int generate_signal();
int configure_receiver(); int configure_receiver();
@ -82,7 +85,6 @@ public:
double compute_stdev(const std::vector<double> & vec); double compute_stdev(const std::vector<double> & vec);
std::shared_ptr<InMemoryConfiguration> config; std::shared_ptr<InMemoryConfiguration> config;
std::string generated_rinex_obs;
}; };
@ -341,6 +343,7 @@ int Obs_Gps_L1_System_Test::run_receiver()
std::cout << "STD exception: " << ex.what(); std::cout << "STD exception: " << ex.what();
} }
// Get the name of the RINEX obs file generated by the receiver // Get the name of the RINEX obs file generated by the receiver
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
FILE *fp; FILE *fp;
std::string argum2 = std::string("/bin/ls *O | grep GSDR | tail -1"); std::string argum2 = std::string("/bin/ls *O | grep GSDR | tail -1");
char buffer[1035]; char buffer[1035];
@ -350,15 +353,12 @@ int Obs_Gps_L1_System_Test::run_receiver()
std::cout << "Failed to run command: " << argum2 << std::endl; std::cout << "Failed to run command: " << argum2 << std::endl;
return -1; return -1;
} }
char * without_trailing = (char*)"0";
while (fgets(buffer, sizeof(buffer), fp) != NULL) while (fgets(buffer, sizeof(buffer), fp) != NULL)
{ {
std::string aux = std::string(buffer); std::string aux = std::string(buffer);
without_trailing = strtok(&aux[0], "\n"); Obs_Gps_L1_System_Test::generated_rinex_obs = aux.erase(aux.length() - 1, 1);
} }
generated_rinex_obs = std::string(without_trailing);
pclose(fp); pclose(fp);
return 0; return 0;
} }
@ -436,7 +436,7 @@ void Obs_Gps_L1_System_Test::check_results()
try try
{ {
std::string arg2_gen = std::string("./") + generated_rinex_obs; std::string arg2_gen = std::string("./") + Obs_Gps_L1_System_Test::generated_rinex_obs;
gpstk::Rinex3ObsStream r_meas(arg2_gen); gpstk::Rinex3ObsStream r_meas(arg2_gen);
r_meas.exceptions(std::ios::failbit); r_meas.exceptions(std::ios::failbit);
gpstk::Rinex3ObsData r_meas_data; gpstk::Rinex3ObsData r_meas_data;
@ -685,9 +685,9 @@ TEST_F(Obs_Gps_L1_System_Test, Observables_system_test)
// Run the receiver // Run the receiver
EXPECT_EQ( run_receiver(), 0) << "Problem executing the software-defined signal generator"; EXPECT_EQ( run_receiver(), 0) << "Problem executing the software-defined signal generator";
std::cout << "Validating RINEX obs file obtained by GNSS-SDR: " << generated_rinex_obs << " ..." << std::endl; std::cout << "Validating RINEX obs file obtained by GNSS-SDR: " << Obs_Gps_L1_System_Test::generated_rinex_obs << " ..." << std::endl;
is_gen_rinex_obs_valid = check_valid_rinex_obs( "./" + generated_rinex_obs); is_gen_rinex_obs_valid = check_valid_rinex_obs( "./" + Obs_Gps_L1_System_Test::generated_rinex_obs);
EXPECT_EQ(true, is_gen_rinex_obs_valid) << "The RINEX observation file " << generated_rinex_obs << ", generated by GNSS-SDR, is not well formed."; EXPECT_EQ(true, is_gen_rinex_obs_valid) << "The RINEX observation file " << Obs_Gps_L1_System_Test::generated_rinex_obs << ", generated by GNSS-SDR, is not well formed.";
std::cout << "The file is valid." << std::endl; std::cout << "The file is valid." << std::endl;
// Check results // Check results

View File

@ -0,0 +1,557 @@
/*!
* \file position_test.cc
* \brief This class implements a test for the validation of computed position.
* \author Carles Fernandez-Prades, 2016. cfernandez(at)cttc.es
*
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include <cmath>
#include <numeric>
#include <thread>
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <gtest/gtest.h>
#include "concurrent_map.h"
#include "concurrent_queue.h"
#include "control_thread.h"
#include "in_memory_configuration.h"
#include "signal_generator_flags.h"
// For GPS NAVIGATION (L1)
concurrent_queue<Gps_Acq_Assist> global_gps_acq_assist_queue;
concurrent_map<Gps_Acq_Assist> global_gps_acq_assist_map;
class Position_Gps_L1_System_Test: public ::testing::Test
{
public:
std::string generator_binary;
std::string p1;
std::string p2;
std::string p3;
std::string p4;
std::string p5;
const double baseband_sampling_freq = 2.6e6;
std::string filename_rinex_obs = FLAGS_filename_rinex_obs;
std::string filename_raw_data = FLAGS_filename_raw_data;
int configure_generator();
int generate_signal();
int configure_receiver();
int run_receiver();
void check_results();
double compute_stdev_precision(const std::vector<double> & vec);
double compute_stdev_accuracy(const std::vector<double> & vec, double ref);
void geodetic2Enu(const double latitude, const double longitude, const double altitude,
double* east, double* north, double* up);
std::shared_ptr<InMemoryConfiguration> config;
std::string generated_kml_file;
private:
void geodetic2Ecef(const double latitude, const double longitude, const double altitude,
double* x, double* y, double* z);
};
void Position_Gps_L1_System_Test::geodetic2Ecef(const double latitude, const double longitude, const double altitude,
double* x, double* y, double* z)
{
const double a = 6378137.0; // WGS84
const double b = 6356752.314245; // WGS84
double aux_x, aux_y, aux_z;
// Convert to ECEF (See https://en.wikipedia.org/wiki/Geographic_coordinate_conversion#From_geodetic_to_ECEF_coordinates )
double N = std::pow(a, 2.0) / sqrt( std::pow(a, 2.0) * std::pow(cos(latitude), 2.0) + std::pow(b, 2.0) * std::pow(sin(latitude), 2.0));
aux_x = (N + altitude) * cos(latitude) * cos(longitude);
aux_y = (N + altitude) * cos(latitude) * sin(longitude);
aux_z = ((std::pow(b, 2.0) / std::pow(a, 2.0)) * N + altitude) * sin(latitude);
*x = aux_x;
*y = aux_y;
*z = aux_z;
}
void Position_Gps_L1_System_Test::geodetic2Enu(const double latitude, const double longitude, const double altitude,
double* east, double* north, double* up)
{
// Reference : https://github.com/ethz-asl/geodetic_utils/blob/master/include/geodetic_utils/geodetic_conv.hpp
double x, y, z;
const double d2r = 3.1415926535898 / 180.0;
geodetic2Ecef(latitude * d2r, longitude * d2r, altitude, &x, &y, &z);
double aux_north, aux_east, aux_down;
std::istringstream iss2(FLAGS_static_position);
std::string str_aux;
std::getline(iss2, str_aux, ',');
double ref_long = std::stod(str_aux);
std::getline(iss2, str_aux, ',');
double ref_lat = std::stod(str_aux);
std::getline(iss2, str_aux, '\n');
double ref_h = std::stod(str_aux);
double ref_x, ref_y, ref_z;
geodetic2Ecef(ref_lat * d2r, ref_long * d2r, ref_h, &ref_x, &ref_y, &ref_z);
double aux_x = x - ref_x;
double aux_y = y - ref_y;
double aux_z = z - ref_z;
// ECEF to NED matrix
double phiP = atan2(ref_z, sqrt(std::pow(ref_x, 2.0) + std::pow(ref_y, 2.0)));
const double sLat = sin(phiP);
const double sLon = sin(ref_long * d2r);
const double cLat = cos(phiP);
const double cLon = cos(ref_long * d2r);
aux_north = -aux_x * sLat * cLon - aux_y * sLon + aux_z * cLat * cLon;
aux_east = -aux_x * sLat * sLon + aux_y * cLon + aux_z * cLat * sLon;
aux_down = aux_x * cLat + aux_z * sLat;
*east = aux_east;
*north = aux_north;
*up = -aux_down;
}
double Position_Gps_L1_System_Test::compute_stdev_precision(const std::vector<double> & vec)
{
double sum__ = std::accumulate(vec.begin(), vec.end(), 0.0);
double mean__ = sum__ / vec.size();
double accum__ = 0.0;
std::for_each (std::begin(vec), std::end(vec), [&](const double d) {
accum__ += (d - mean__) * (d - mean__);
});
double stdev__ = std::sqrt(accum__ / (vec.size() - 1));
return stdev__;
}
double Position_Gps_L1_System_Test::compute_stdev_accuracy(const std::vector<double> & vec, double ref)
{
double mean__ = ref;
double accum__ = 0.0;
std::for_each (std::begin(vec), std::end(vec), [&](const double d) {
accum__ += (d - mean__) * (d - mean__);
});
double stdev__ = std::sqrt(accum__ / (vec.size() - 1));
return stdev__;
}
int Position_Gps_L1_System_Test::configure_generator()
{
// Configure signal generator
generator_binary = FLAGS_generator_binary;
p1 = std::string("-rinex_nav_file=") + FLAGS_rinex_nav_file;
if(FLAGS_dynamic_position.empty())
{
p2 = std::string("-static_position=") + FLAGS_static_position + std::string(",") + std::to_string(std::min(FLAGS_duration * 10, 3000));
if(FLAGS_duration > 300) std::cout << "WARNING: Duration has been set to its maximum value of 300 s" << std::endl;
}
else
{
p2 = std::string("-obs_pos_file=") + std::string(FLAGS_dynamic_position);
}
p3 = std::string("-rinex_obs_file=") + FLAGS_filename_rinex_obs; // RINEX 2.10 observation file output
p4 = std::string("-sig_out_file=") + FLAGS_filename_raw_data; // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples
p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); //Baseband sampling frequency [MSps]
return 0;
}
int Position_Gps_L1_System_Test::generate_signal()
{
pid_t wait_result;
int child_status;
char *const parmList[] = { &generator_binary[0], &generator_binary[0], &p1[0], &p2[0], &p3[0], &p4[0], &p5[0], NULL };
int pid;
if ((pid = fork()) == -1)
perror("fork error");
else if (pid == 0)
{
execv(&generator_binary[0], parmList);
std::cout << "Return not expected. Must be an execv error." << std::endl;
std::terminate();
}
wait_result = waitpid(pid, &child_status, 0);
if (wait_result == -1) perror("waitpid error");
return 0;
}
int Position_Gps_L1_System_Test::configure_receiver()
{
config = std::make_shared<InMemoryConfiguration>();
const int sampling_rate_internal = baseband_sampling_freq;
const int number_of_taps = 11;
const int number_of_bands = 2;
const float band1_begin = 0.0;
const float band1_end = 0.48;
const float band2_begin = 0.52;
const float band2_end = 1.0;
const float ampl1_begin = 1.0;
const float ampl1_end = 1.0;
const float ampl2_begin = 0.0;
const float ampl2_end = 0.0;
const float band1_error = 1.0;
const float band2_error = 1.0;
const int grid_density = 16;
const int decimation_factor = 1;
const float zero = 0.0;
const int number_of_channels = 8;
const int in_acquisition = 1;
const float threshold = 0.01;
const float doppler_max = 8000.0;
const float doppler_step = 500.0;
const int max_dwells = 1;
const int tong_init_val = 2;
const int tong_max_val = 10;
const int tong_max_dwells = 30;
const int coherent_integration_time_ms = 1;
const float pll_bw_hz = 30.0;
const float dll_bw_hz = 4.0;
const float early_late_space_chips = 0.5;
const float pll_bw_narrow_hz = 20.0;
const float dll_bw_narrow_hz = 2.0;
const int extend_correlation_ms = 1;
const int display_rate_ms = 500;
const int output_rate_ms = 1000;
const int averaging_depth = 1;
config->set_property("GNSS-SDR.internal_fs_hz", std::to_string(sampling_rate_internal));
// Set the assistance system parameters
config->set_property("GNSS-SDR.SUPL_read_gps_assistance_xml", "false");
config->set_property("GNSS-SDR.SUPL_gps_enabled", "false");
config->set_property("GNSS-SDR.SUPL_gps_ephemeris_server", "supl.google.com");
config->set_property("GNSS-SDR.SUPL_gps_ephemeris_port", std::to_string(7275));
config->set_property("GNSS-SDR.SUPL_gps_acquisition_server", "supl.google.com");
config->set_property("GNSS-SDR.SUPL_gps_acquisition_port", std::to_string(7275));
config->set_property("GNSS-SDR.SUPL_MCC", std::to_string(244));
config->set_property("GNSS-SDR.SUPL_MNS", std::to_string(5));
config->set_property("GNSS-SDR.SUPL_LAC", "0x59e2");
config->set_property("GNSS-SDR.SUPL_CI", "0x31b0");
// Set the Signal Source
config->set_property("SignalSource.implementation", "File_Signal_Source");
config->set_property("SignalSource.filename", "./" + filename_raw_data);
config->set_property("SignalSource.sampling_frequency", std::to_string(sampling_rate_internal));
config->set_property("SignalSource.item_type", "ibyte");
config->set_property("SignalSource.samples", std::to_string(zero));
// Set the Signal Conditioner
config->set_property("SignalConditioner.implementation", "Signal_Conditioner");
config->set_property("DataTypeAdapter.implementation", "Ibyte_To_Complex");
config->set_property("InputFilter.implementation", "Fir_Filter");
config->set_property("InputFilter.dump", "false");
config->set_property("InputFilter.input_item_type", "gr_complex");
config->set_property("InputFilter.output_item_type", "gr_complex");
config->set_property("InputFilter.taps_item_type", "float");
config->set_property("InputFilter.number_of_taps", std::to_string(number_of_taps));
config->set_property("InputFilter.number_of_bands", std::to_string(number_of_bands));
config->set_property("InputFilter.band1_begin", std::to_string(band1_begin));
config->set_property("InputFilter.band1_end", std::to_string(band1_end));
config->set_property("InputFilter.band2_begin", std::to_string(band2_begin));
config->set_property("InputFilter.band2_end", std::to_string(band2_end));
config->set_property("InputFilter.ampl1_begin", std::to_string(ampl1_begin));
config->set_property("InputFilter.ampl1_end", std::to_string(ampl1_end));
config->set_property("InputFilter.ampl2_begin", std::to_string(ampl2_begin));
config->set_property("InputFilter.ampl2_end", std::to_string(ampl2_end));
config->set_property("InputFilter.band1_error", std::to_string(band1_error));
config->set_property("InputFilter.band2_error", std::to_string(band2_error));
config->set_property("InputFilter.filter_type", "bandpass");
config->set_property("InputFilter.grid_density", std::to_string(grid_density));
config->set_property("InputFilter.sampling_frequency", std::to_string(sampling_rate_internal));
config->set_property("InputFilter.IF", std::to_string(zero));
config->set_property("Resampler.implementation", "Pass_Through");
config->set_property("Resampler.dump", "false");
config->set_property("Resampler.item_type", "gr_complex");
config->set_property("Resampler.sample_freq_in", std::to_string(sampling_rate_internal));
config->set_property("Resampler.sample_freq_out", std::to_string(sampling_rate_internal));
// Set the number of Channels
config->set_property("Channels_1C.count", std::to_string(number_of_channels));
config->set_property("Channels.in_acquisition", std::to_string(in_acquisition));
config->set_property("Channel.signal", "1C");
// Set Acquisition
config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Tong_Acquisition");
config->set_property("Acquisition_1C.item_type", "gr_complex");
config->set_property("Acquisition_1C.if", std::to_string(zero));
config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms));
config->set_property("Acquisition_1C.threshold", std::to_string(threshold));
config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max));
config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step));
config->set_property("Acquisition_1C.bit_transition_flag", "false");
config->set_property("Acquisition_1C.max_dwells", std::to_string(max_dwells));
config->set_property("Acquisition_1C.tong_init_val", std::to_string(tong_init_val));
config->set_property("Acquisition_1C.tong_max_val", std::to_string(tong_max_val));
config->set_property("Acquisition_1C.tong_max_dwells", std::to_string(tong_max_dwells));
// Set Tracking
config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_Tracking");
//config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_C_Aid_Tracking");
config->set_property("Tracking_1C.item_type", "gr_complex");
config->set_property("Tracking_1C.if", std::to_string(zero));
config->set_property("Tracking_1C.dump", "false");
config->set_property("Tracking_1C.dump_filename", "./tracking_ch_");
config->set_property("Tracking_1C.pll_bw_hz", std::to_string(pll_bw_hz));
config->set_property("Tracking_1C.dll_bw_hz", std::to_string(dll_bw_hz));
config->set_property("Tracking_1C.early_late_space_chips", std::to_string(early_late_space_chips));
config->set_property("Tracking_1C.pll_bw_narrow_hz", std::to_string(pll_bw_narrow_hz));
config->set_property("Tracking_1C.dll_bw_narrow_hz", std::to_string(dll_bw_narrow_hz));
config->set_property("Tracking_1C.extend_correlation_ms", std::to_string(extend_correlation_ms));
// Set Telemetry
config->set_property("TelemetryDecoder_1C.implementation", "GPS_L1_CA_Telemetry_Decoder");
config->set_property("TelemetryDecoder_1C.dump", "false");
config->set_property("TelemetryDecoder_1C.decimation_factor", std::to_string(decimation_factor));
// Set Observables
config->set_property("Observables.implementation", "Hybrid_Observables");
config->set_property("Observables.dump", "false");
config->set_property("Observables.dump_filename", "./observables.dat");
config->set_property("Observables.averaging_depth", std::to_string(100));
// Set PVT
config->set_property("PVT.implementation", "RTKLIB_PVT");
//config->set_property("PVT.implementation", "Hybrid_PVT");
config->set_property("PVT.averaging_depth", std::to_string(averaging_depth));
config->set_property("PVT.flag_averaging", "false");
config->set_property("PVT.output_rate_ms", std::to_string(output_rate_ms));
config->set_property("PVT.display_rate_ms", std::to_string(display_rate_ms));
config->set_property("PVT.dump_filename", "./PVT");
config->set_property("PVT.nmea_dump_filename", "./gnss_sdr_pvt.nmea");
config->set_property("PVT.flag_nmea_tty_port", "false");
config->set_property("PVT.nmea_dump_devname", "/dev/pts/4");
config->set_property("PVT.flag_rtcm_server", "false");
config->set_property("PVT.flag_rtcm_tty_port", "false");
config->set_property("PVT.rtcm_dump_devname", "/dev/pts/1");
config->set_property("PVT.dump", "false");
config->set_property("PVT.rinex_version", std::to_string(2));
return 0;
}
int Position_Gps_L1_System_Test::run_receiver()
{
std::shared_ptr<ControlThread> control_thread;
control_thread = std::make_shared<ControlThread>(config);
// start receiver
try
{
control_thread->run();
}
catch( boost::exception & e )
{
std::cout << "Boost exception: " << boost::diagnostic_information(e);
}
catch(std::exception const& ex)
{
std::cout << "STD exception: " << ex.what();
}
// Get the name of the KML file generated by the receiver
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
FILE *fp;
std::string argum2 = std::string("/bin/ls *kml | tail -1");
char buffer[1035];
fp = popen(&argum2[0], "r");
if (fp == NULL)
{
std::cout << "Failed to run command: " << argum2 << std::endl;
return -1;
}
while (fgets(buffer, sizeof(buffer), fp) != NULL)
{
std::string aux = std::string(buffer);
EXPECT_EQ(aux.empty(), false);
Position_Gps_L1_System_Test::generated_kml_file = aux.erase(aux.length() - 1, 1);
}
pclose(fp);
EXPECT_EQ(Position_Gps_L1_System_Test::generated_kml_file.empty(), false);
return 0;
}
void Position_Gps_L1_System_Test::check_results()
{
std::fstream myfile(Position_Gps_L1_System_Test::generated_kml_file, std::ios_base::in);
std::string line;
std::vector<double> pos_e;
std::vector<double> pos_n;
std::vector<double> pos_u;
// Skip header
std::getline(myfile, line);
bool is_header = true;
while(is_header)
{
std::getline(myfile, line);
std::size_t found = line.find("<coordinates>");
if (found != std::string::npos) is_header = false;
}
bool is_data = true;
//read data
while(is_data)
{
std::getline(myfile, line);
std::size_t found = line.find("</coordinates>");
if (found != std::string::npos) is_data = false;
else
{
std::string str2;
std::istringstream iss(line);
double value;
double lat, longitude, h;
for (int i = 0; i < 3; i++)
{
std::getline(iss, str2, ',');
value = std::stod(str2);
if(i == 0) lat = value;
if(i == 1) longitude = value;
if(i == 2) h = value;
}
double north, east, up;
geodetic2Enu(lat, longitude, h, &east, &north, &up);
//std::cout << "E = " << east << ", N = " << north << " U = " << up << std::endl;
pos_e.push_back(east);
pos_n.push_back(north);
pos_u.push_back(up);
}
}
myfile.close();
double sigma_E_2_precision = std::pow(compute_stdev_precision(pos_e), 2.0);
double sigma_N_2_precision = std::pow(compute_stdev_precision(pos_n), 2.0);
double sigma_U_2_precision = std::pow(compute_stdev_precision(pos_u), 2.0);
double sigma_E_2_accuracy = std::pow(compute_stdev_accuracy(pos_e, 0.0), 2.0);
double sigma_N_2_accuracy = std::pow(compute_stdev_accuracy(pos_n, 0.0), 2.0);
double sigma_U_2_accuracy = std::pow(compute_stdev_accuracy(pos_u, 0.0), 2.0);
std::cout << "---- ACCURACY ----" << std::endl;
std::cout << "2DRMS = " << 2 * sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl;
std::cout << "DRMS = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl;
std::cout << "CEP = " << 0.62 * compute_stdev_accuracy(pos_n, 0.0) + 0.56 * compute_stdev_accuracy(pos_e, 0.0) << " [m]" << std::endl;
std::cout << "99% SAS = " << 1.122 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
std::cout << "90% SAS = " << 0.833 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
std::cout << "MRSE = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
std::cout << "SEP = " << 0.51 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl;
std::cout << std::endl;
std::cout << "---- PRECISION ----" << std::endl;
std::cout << "2DRMS = " << 2 * sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl;
std::cout << "DRMS = " << sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl;
std::cout << "CEP = " << 0.62 * compute_stdev_precision(pos_n) + 0.56 * compute_stdev_precision(pos_e) << " [m]" << std::endl;
std::cout << "99% SAS = " << 1.122 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl;
std::cout << "90% SAS = " << 0.833 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl;
std::cout << "MRSE = " << sqrt(sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl;
std::cout << "SEP = " << 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl;
// Sanity Check
double precision_SEP = 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision);
ASSERT_LT(precision_SEP, 20.0);
}
TEST_F(Position_Gps_L1_System_Test, Position_system_test)
{
// Configure the signal generator
configure_generator();
// Generate signal raw signal samples and observations RINEX file
if(!FLAGS_disable_generator)
{
generate_signal();
}
// Configure receiver
configure_receiver();
// Run the receiver
EXPECT_EQ( run_receiver(), 0) << "Problem executing the software-defined signal generator";
// Check results
check_results();
}
int main(int argc, char **argv)
{
std::cout << "Running Position precision test..." << std::endl;
int res = 0;
try
{
testing::InitGoogleTest(&argc, argv);
}
catch(...) {} // catch the "testing::internal::<unnamed>::ClassUniqueToAlwaysTrue" from gtest
google::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
// Run the Tests
try
{
res = RUN_ALL_TESTS();
}
catch(...)
{
LOG(WARNING) << "Unexpected catch";
}
google::ShutDownCommandLineFlags();
return res;
}