diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000000..ae13da549f --- /dev/null +++ b/.flake8 @@ -0,0 +1 @@ +max-line-length = 120 diff --git a/.travis.yml b/.travis.yml index c8add7de51..5a16a241b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,15 +22,27 @@ cache: matrix: include: - env: - - TRAVIS_TARGET=python + - TRAVIS_TARGET=python-haskell language: python python: 3.7-dev before_install: - sudo apt-get -qq update - sudo apt-get install python2.7 python2.7-dev - sudo apt-get install python3.5 python3.5-dev + - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce - sudo pip install tox - script: make test-python + - git clone https://github.com/swift-nav/piksi_tools.git ../piksi_tools + - git -C ../piksi_tools fetch + - git -C ../piksi_tools checkout silverjam/sbp2json + script: | + pushd haskell + docker build -t sbp2json . + docker run --rm --name sbp2json sbp2json >sbp_linux_tools.tar + tar xf sbp_linux_tools.tar + gzip sbp_linux_tools.tar + ls -l + popd + make test-python - env: - TRAVIS_TARGET=default JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 before_install: @@ -54,18 +66,6 @@ matrix: - npm install -g mocha - npm install script: make test-c test-haskell test-java test-javascript - - env: - - TRAVIS_TARGET=haskell-tools - before_install: | - sudo apt-get update - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce - script: | - pushd haskell - docker build -t sbp2json . - docker run --rm --name sbp2json sbp2json >sbp_linux_tools.tar - gzip sbp_linux_tools.tar - ls -l - popd deploy: provider: releases diff --git a/Makefile b/Makefile index 199af30fda..183811e011 100644 --- a/Makefile +++ b/Makefile @@ -61,6 +61,7 @@ docs: verify-prereq-docs pdf html c: deps-c gen-c test-c python: deps-python gen-python test-python +pythonNG: deps-python gen-pythonNG javascript: deps-javascript gen-javascript test-javascript java: deps-java gen-java test-java haskell: deps-haskell gen-haskell test-haskell @@ -144,6 +145,15 @@ gen-python: --python $(call announce-end,"Finished generating Python bindings. Please check $(SWIFTNAV_ROOT)/python/sbp") +gen-pythonNG: + $(call announce-begin,"Generating Python bindings") + cd $(SWIFTNAV_ROOT)/generator; \ + $(SBP_GEN_BIN) -i $(SBP_SPEC_DIR) \ + -o $(SWIFTNAV_ROOT)/python/sbp/jit \ + -r $(SBP_MAJOR_VERSION).$(SBP_MINOR_VERSION).$(SBP_PATCH_VERSION) \ + --pythonNG + $(call announce-end,"Finished generating Python bindings. Please check $(SWIFTNAV_ROOT)/python/sbp") + gen-javascript: $(call announce-begin,"Generating JavaScript bindings") cd $(SWIFTNAV_ROOT)/generator; \ @@ -206,7 +216,7 @@ test-c: test-python: $(call announce-begin,"Running Python tests") ifdef TRAVIS_TARGET - cd $(SWIFTNAV_ROOT)/python/ && tox + cd $(SWIFTNAV_ROOT)/python/ && tox -- $(SWIFTNAV_ROOT)/haskell else cd $(SWIFTNAV_ROOT)/python/ && tox --skip-missing-interpreters endif diff --git a/generator/sbpg/generator.py b/generator/sbpg/generator.py index 8b6760382a..49cf7ac13b 100755 --- a/generator/sbpg/generator.py +++ b/generator/sbpg/generator.py @@ -25,6 +25,7 @@ import sbpg.targets.haskell as hs import sbpg.targets.protobuf as pb import sbpg.targets.python as py +import sbpg.targets.pythonNG as pyNG import sbpg.targets.javascript as js def get_args(): @@ -42,6 +43,9 @@ def get_args(): parser.add_argument('--python', action="store_true", help='Target language: Python.') + parser.add_argument('--pythonNG', + action="store_true", + help='Target language: Python.') parser.add_argument('--javascript', action="store_true", help='Target language: JavaScript.') @@ -80,7 +84,7 @@ def main(): # Parse and validate arguments. args = get_args().parse_args() verbose = args.verbose - assert args.python or args.javascript or args.c or args.test_c or args.haskell or args.latex or args.protobuf or args.java, \ + assert args.pythonNG or args.python or args.javascript or args.c or args.test_c or args.haskell or args.latex or args.protobuf or args.java, \ "Please specify a target language." input_file = os.path.abspath(args.input_file[0]) assert len(args.input_file) == 1 @@ -122,6 +126,8 @@ def main(): continue if args.python: py.render_source(output_dir, parsed) + if args.pythonNG: + pyNG.render_source(output_dir, parsed) elif args.javascript: js.render_source(output_dir, parsed) elif args.c: diff --git a/generator/sbpg/targets/pythonNG.py b/generator/sbpg/targets/pythonNG.py new file mode 100755 index 0000000000..a6730c03ae --- /dev/null +++ b/generator/sbpg/targets/pythonNG.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python +# Copyright (C) 2015 Swift Navigation Inc. +# Contact: Bhaskar Mookerji +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + +"""Generator for Python target. + +This module consumes the YAML spec and generates some message class +files. + +""" + +from sbpg.targets.templating import JENV, ACRONYMS +from sbpg.utils import comment_links +import copy + +TEMPLATE_NAME = "sbp_numba.py.j2" + +NUMBA_TYPE = { + 'u8': 'u1', + 'u16': 'u2', + 'u32': 'u4', + 'u64': 'u8', + 's8': 'i1', + 's16': 'i2', + 's32': 'i4', + 's64': 'i8', + 'float': 'f4', + 'double': 'f8', +} + +NUMBA_GET_FN = { + 'u8': 'get_u8', + 'u16': 'get_u16', + 'u32': 'get_u32', + 'u64': 'get_u64', + 's8': 'get_s8', + 's16': 'get_s16', + 's32': 'get_s32', + 's64': 'get_s64', + 'float': 'get_f32', + 'double': 'get_f64', +} + +NUMBA_TY_BYTES = { + 'u8': 1, + 'u16': 2, + 'u32': 4, + 'u64': 8, + 's8': 1, + 's16': 2, + 's32': 4, + 's64': 8, + 'float': 4, + 'double': 8, +} + +PYDOC_CODE = { + 'u8': 'int', + 'u16': 'int', + 'u32': 'int', + 'u64': 'int', + 's8': 'int', + 's16': 'int', + 's32': 'int', + 's64': 'int', + 'float': 'float', + 'double': 'double', +} + + +def is_array(): + return False + + +def numba_type(f): + if f.type_id == 'float': + return 'judicious_round(nb.' + NUMBA_TYPE[f.type_id] + \ + '(__' + f.identifier + ')) if SBP.judicious_rounding else __' + f.identifier + else: + return '__' + f.identifier + + +def numba_size(f): + # the worst case 255 - 6 (header) - 2 (crc) + UNKNOWN_LEN = 255 - 6 - 2 + + if f.type_id in NUMBA_TY_BYTES: + return NUMBA_TY_BYTES[f.type_id] + elif f.type_id == 'string': + if f.options.get('size', None) is not None: + return f.options.get('size', None).value + return UNKNOWN_LEN + elif f.type_id == 'array': + # NOTE: arrays of arrays are not supported + t = f.options['fill'].value + count = f.options.get('size', None) + if count: + if t in NUMBA_TY_BYTES: + return "%d * %d" % (NUMBA_TY_BYTES[t], count.value) + else: + return t + "._payload_size() * %d" % (count.value) + else: + return UNKNOWN_LEN + else: + return f.type_id + '._payload_size()' + + +def numba_format(f): + if NUMBA_GET_FN.get(f.type_id, None): + return NUMBA_GET_FN.get(f.type_id) + elif f.type_id == 'string' and f.identifier == 'setting' and not f.options.get('size', None): + # setting string with null delimiters as a special case + return 'get_setting' + elif f.type_id == 'string' and f.options.get('size', None): + s = f.options.get('size', None).value + return 'get_fixed_string(%d)' % (s,) + elif f.type_id == 'string' and not f.options.get('size', None): + return 'get_string' + elif f.type_id == 'array' and f.options.get('size', None): + count = f.options.get('size', None).value + t = f.options['fill'].value + if t in NUMBA_GET_FN: + fill_func = NUMBA_GET_FN[t] + el_size = NUMBA_TY_BYTES[t] + if f.options['fill'].value == 'float': + return "get_fixed_array(%s, %d, %d, %s if SBP.judicious_rounding else None)" \ + % (fill_func, count, el_size, 'nb.f4') + else: + return "get_fixed_array(%s, %d, %d)" % (fill_func, count, el_size) + else: + fill_func = f.options['fill'].value + '._unpack_members' + el_size = f.options['fill'].value + '._payload_size()' + return "get_fixed_array(%s, %d, %s)" % (fill_func, count, el_size) + elif f.type_id == 'array': + fill = f.options['fill'].value + f_ = copy.copy(f) + f_.type_id = fill + return "get_array(%s)" % (numba_format(f_),) + else: + return '%s.parse_members' % (f.type_id) + raise NotImplementedError() + + +def pydoc_format(type_id, pydoc=PYDOC_CODE): + """ + Formats type for pydoc. + """ + return pydoc.get(type_id, type_id) + + +def classnameify(s): + """ + Makes a classname. + """ + return ''.join(w if w in ACRONYMS else w.title() for w in s.split('_')) + + +JENV.filters['numba_py'] = numba_format +JENV.filters['numba_type'] = numba_type +JENV.filters['numba_size'] = numba_size +JENV.filters['classnameify'] = classnameify +JENV.filters['pydoc'] = pydoc_format +JENV.filters['comment_links'] = comment_links + + +def render_source(output_dir, package_spec, jenv=JENV): + """ + Render and output + """ + path, name = package_spec.filepath + directory = output_dir + destination_filename = "%s/%s.py" % (directory, name) + py_template = jenv.get_template(TEMPLATE_NAME) + module_path = ".".join(package_spec.identifier.split(".")[1:-1]) + includes = [".".join(i.split(".")[:-1]) for i in package_spec.includes] + includes = [i for i in includes if i != "types"] + print(destination_filename, includes) + with open(destination_filename, 'w') as f: + f.write(py_template.render(msgs=package_spec.definitions, + filepath="/".join(package_spec.filepath) + ".yaml", + module_path=module_path, + include=includes, + timestamp=package_spec.creation_timestamp, + description=package_spec.description)) diff --git a/generator/sbpg/targets/resources/sbp_numba.py.j2 b/generator/sbpg/targets/resources/sbp_numba.py.j2 new file mode 100755 index 0000000000..c0436a5f9f --- /dev/null +++ b/generator/sbpg/targets/resources/sbp_numba.py.j2 @@ -0,0 +1,109 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +(((description|comment_links))) +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +((*- for i in include *)) +from (((module_path))).jit.(((i))) import * +((*- endfor *)) + +# Automatically generated from piksi/yaml/(((filepath))) with generate.py. +# Please do not hand edit! + +((*- for m in msgs *)) +((*- if m.static *)) + +((*- if m.sbp_id *)) +SBP_(((m.identifier))) = ((('0x%04X'|format(m.sbp_id)))) +((*- endif *)) + +((*- if m.sbp_id *)) +class ((( m.identifier | classnameify )))(SBP): + """SBP class for message (((m.identifier))) ((('(0x%04X)'|format(m.sbp_id)))). +((*- else *)) +class ((( m.identifier )))(object): + """SBP class for message (((m.identifier))) +((*- endif *)) + + You can have (((m.identifier))) inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + ((* if m.desc *)) + (((m.desc))) + ((*- endif *)) + + """ + ((*- if m.fields *)) + __slots__ = [((*- for f in m.fields *))'((( f.identifier )))', + ((* endfor *))] + ((*- else *)) + __slots__ = [] + ((*- endif *)) + + ((*- if m.fields *)) + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + ((*- for f in m.fields *)) + (__(((f.identifier))), offset, length) = ((( f | numba_py )))(buf, offset, length) + ret['(((f.identifier)))'] = ((( f | numba_type ))) + ((*- endfor *)) + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + ((*- for f in m.fields *)) + self.(((f.identifier))) = res['(((f.identifier)))'] + ((*- endfor *)) + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + ((*- for f in m.fields *)) + # (((f.identifier))): (((f.type_id))) ((*- if f.options['fill'] *)) of (((f.options['fill'].value))) ((*- endif *)) + ret += (((f | numba_size))) + ((*- endfor *)) + return ret + ((* else *)) + def _unpack_members(self, buf, offset, length): + return {}, offset, length + + def _payload_size(self): + return 0 + ((* endif *)) +((*- endif *)) +((*- endfor *)) + +msg_classes = { +((*- for m in msgs *)) + ((*- if m.sbp_id *)) + ((('0x%04X'|format(m.sbp_id)))): ((( m.identifier | classnameify ))), + ((*- endif*)) +((*- endfor *)) +} diff --git a/haskell/Dockerfile b/haskell/Dockerfile index a760b13ced..04232aa33e 100644 --- a/haskell/Dockerfile +++ b/haskell/Dockerfile @@ -12,6 +12,7 @@ RUN \ CMD \ tar -C $(find .stack-work/install -name bin) -cf - \ sbp2json \ + sbp2prettyjson \ sbp2yaml \ json2sbp \ json2json diff --git a/python/bench/crc.py b/python/bench/crc.py new file mode 100755 index 0000000000..7ca6a9e007 --- /dev/null +++ b/python/bench/crc.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python + +# Copyright (C) 2019 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + +import random +import timeit + +from sbp.msg import crc16, crc16_nojit + +blob_count = 5000 +blob_size = 256 + +blobs = [] + +print("Start: building random data...") + +for _ in range(blob_count): + blob = bytes(b'').join( + (chr(int(0xFF * random.random()) & 0xFF)) for X in range(blob_size)) + blobs.append(blob) + +print("End: building random data.") + + +def run_crc(): + for blob in blobs: + crc16(blob) + + +def run_crc2(): + for blob in blobs: + crc16_nojit(blob) + + +def main(): + t = timeit.Timer('run_crc()', 'from __main__ import run_crc').timeit(100) + print(t) + t = timeit.Timer('run_crc2()', 'from __main__ import run_crc2').timeit(100) + print(t) + + +if __name__ == '__main__': + main() diff --git a/python/requirements.txt b/python/requirements.txt index de9e140b13..befd25a028 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -6,3 +6,5 @@ requests>=2.8.1 llvmlite==0.26.0 numpy==1.16.2 numba==0.41.0 +pybase64 +cffi diff --git a/python/sbp/client/framer.py b/python/sbp/client/framer.py index bfc52bdd18..4d4305f8b4 100644 --- a/python/sbp/client/framer.py +++ b/python/sbp/client/framer.py @@ -102,14 +102,8 @@ def _readall(self, size): data = b"" while len(data) < size: d = self._read(size - len(data)) - if self._broken: + if not d or self._broken: raise StopIteration - if not d: - # NOTE (Buro/jgross): Force a yield here to another thread. In - # case the stream fails midstream, the spinning here causes - # the UI thread to lock up without yielding. - time.sleep(0) - continue data += d return data diff --git a/python/sbp/client/handler.py b/python/sbp/client/handler.py index 85103a27d6..021f09fdd0 100644 --- a/python/sbp/client/handler.py +++ b/python/sbp/client/handler.py @@ -12,6 +12,7 @@ SBP message handling. """ +import warnings import collections import threading import weakref @@ -209,9 +210,13 @@ def stop(self): try: self._source.breakiter() self._receive_thread.join(0.1) - except: + except Exception as exc: + warnings.warn("Handler stop error: %s" % (exc,)) pass + def join(self, timeout=None): + self._receive_thread.join(timeout) + def is_alive(self): """ Return whether the processes thread is alive. diff --git a/python/sbp/jit/RELEASE-VERSION b/python/sbp/jit/RELEASE-VERSION new file mode 100644 index 0000000000..a6c4b4a24a --- /dev/null +++ b/python/sbp/jit/RELEASE-VERSION @@ -0,0 +1 @@ +2.4.10 \ No newline at end of file diff --git a/python/sbp/jit/__init__.py b/python/sbp/jit/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python/sbp/jit/acquisition.py b/python/sbp/jit/acquisition.py new file mode 100644 index 0000000000..103e20078b --- /dev/null +++ b/python/sbp/jit/acquisition.py @@ -0,0 +1,531 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Satellite acquisition messages from the device. +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array +from sbp.jit.gnss import * + +# Automatically generated from piksi/yaml/swiftnav/sbp/acquisition.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_ACQ_RESULT = 0x002F +class MsgAcqResult(SBP): + """SBP class for message MSG_ACQ_RESULT (0x002F). + + You can have MSG_ACQ_RESULT inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message describes the results from an attempted GPS signal +acquisition search for a satellite PRN over a code phase/carrier +frequency range. It contains the parameters of the point in the +acquisition search space with the best carrier-to-noise (CN/0) +ratio. + + + """ + __slots__ = ['cn0', + 'cp', + 'cf', + 'sid', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__cn0, offset, length) = get_f32(buf, offset, length) + ret['cn0'] = judicious_round(nb.f4(__cn0)) if SBP.judicious_rounding else __cn0 + (__cp, offset, length) = get_f32(buf, offset, length) + ret['cp'] = judicious_round(nb.f4(__cp)) if SBP.judicious_rounding else __cp + (__cf, offset, length) = get_f32(buf, offset, length) + ret['cf'] = judicious_round(nb.f4(__cf)) if SBP.judicious_rounding else __cf + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.cn0 = res['cn0'] + self.cp = res['cp'] + self.cf = res['cf'] + self.sid = res['sid'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # cn0: float + ret += 4 + # cp: float + ret += 4 + # cf: float + ret += 4 + # sid: GnssSignal + ret += GnssSignal._payload_size() + return ret + +SBP_MSG_ACQ_RESULT_DEP_C = 0x001F +class MsgAcqResultDepC(SBP): + """SBP class for message MSG_ACQ_RESULT_DEP_C (0x001F). + + You can have MSG_ACQ_RESULT_DEP_C inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['cn0', + 'cp', + 'cf', + 'sid', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__cn0, offset, length) = get_f32(buf, offset, length) + ret['cn0'] = judicious_round(nb.f4(__cn0)) if SBP.judicious_rounding else __cn0 + (__cp, offset, length) = get_f32(buf, offset, length) + ret['cp'] = judicious_round(nb.f4(__cp)) if SBP.judicious_rounding else __cp + (__cf, offset, length) = get_f32(buf, offset, length) + ret['cf'] = judicious_round(nb.f4(__cf)) if SBP.judicious_rounding else __cf + (__sid, offset, length) = GnssSignalDep.parse_members(buf, offset, length) + ret['sid'] = __sid + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.cn0 = res['cn0'] + self.cp = res['cp'] + self.cf = res['cf'] + self.sid = res['sid'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # cn0: float + ret += 4 + # cp: float + ret += 4 + # cf: float + ret += 4 + # sid: GnssSignalDep + ret += GnssSignalDep._payload_size() + return ret + +SBP_MSG_ACQ_RESULT_DEP_B = 0x0014 +class MsgAcqResultDepB(SBP): + """SBP class for message MSG_ACQ_RESULT_DEP_B (0x0014). + + You can have MSG_ACQ_RESULT_DEP_B inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['snr', + 'cp', + 'cf', + 'sid', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__snr, offset, length) = get_f32(buf, offset, length) + ret['snr'] = judicious_round(nb.f4(__snr)) if SBP.judicious_rounding else __snr + (__cp, offset, length) = get_f32(buf, offset, length) + ret['cp'] = judicious_round(nb.f4(__cp)) if SBP.judicious_rounding else __cp + (__cf, offset, length) = get_f32(buf, offset, length) + ret['cf'] = judicious_round(nb.f4(__cf)) if SBP.judicious_rounding else __cf + (__sid, offset, length) = GnssSignalDep.parse_members(buf, offset, length) + ret['sid'] = __sid + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.snr = res['snr'] + self.cp = res['cp'] + self.cf = res['cf'] + self.sid = res['sid'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # snr: float + ret += 4 + # cp: float + ret += 4 + # cf: float + ret += 4 + # sid: GnssSignalDep + ret += GnssSignalDep._payload_size() + return ret + +SBP_MSG_ACQ_RESULT_DEP_A = 0x0015 +class MsgAcqResultDepA(SBP): + """SBP class for message MSG_ACQ_RESULT_DEP_A (0x0015). + + You can have MSG_ACQ_RESULT_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['snr', + 'cp', + 'cf', + 'prn', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__snr, offset, length) = get_f32(buf, offset, length) + ret['snr'] = judicious_round(nb.f4(__snr)) if SBP.judicious_rounding else __snr + (__cp, offset, length) = get_f32(buf, offset, length) + ret['cp'] = judicious_round(nb.f4(__cp)) if SBP.judicious_rounding else __cp + (__cf, offset, length) = get_f32(buf, offset, length) + ret['cf'] = judicious_round(nb.f4(__cf)) if SBP.judicious_rounding else __cf + (__prn, offset, length) = get_u8(buf, offset, length) + ret['prn'] = __prn + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.snr = res['snr'] + self.cp = res['cp'] + self.cf = res['cf'] + self.prn = res['prn'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # snr: float + ret += 4 + # cp: float + ret += 4 + # cf: float + ret += 4 + # prn: u8 + ret += 1 + return ret + +class AcqSvProfile(object): + """SBP class for message AcqSvProfile + + You can have AcqSvProfile inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Profile for a specific SV for debugging purposes +The message describes SV profile during acquisition time. +The message is used to debug and measure the performance. + + + """ + __slots__ = ['job_type', + 'status', + 'cn0', + 'int_time', + 'sid', + 'bin_width', + 'timestamp', + 'time_spent', + 'cf_min', + 'cf_max', + 'cf', + 'cp', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__job_type, offset, length) = get_u8(buf, offset, length) + ret['job_type'] = __job_type + (__status, offset, length) = get_u8(buf, offset, length) + ret['status'] = __status + (__cn0, offset, length) = get_u16(buf, offset, length) + ret['cn0'] = __cn0 + (__int_time, offset, length) = get_u8(buf, offset, length) + ret['int_time'] = __int_time + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__bin_width, offset, length) = get_u16(buf, offset, length) + ret['bin_width'] = __bin_width + (__timestamp, offset, length) = get_u32(buf, offset, length) + ret['timestamp'] = __timestamp + (__time_spent, offset, length) = get_u32(buf, offset, length) + ret['time_spent'] = __time_spent + (__cf_min, offset, length) = get_s32(buf, offset, length) + ret['cf_min'] = __cf_min + (__cf_max, offset, length) = get_s32(buf, offset, length) + ret['cf_max'] = __cf_max + (__cf, offset, length) = get_s32(buf, offset, length) + ret['cf'] = __cf + (__cp, offset, length) = get_u32(buf, offset, length) + ret['cp'] = __cp + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.job_type = res['job_type'] + self.status = res['status'] + self.cn0 = res['cn0'] + self.int_time = res['int_time'] + self.sid = res['sid'] + self.bin_width = res['bin_width'] + self.timestamp = res['timestamp'] + self.time_spent = res['time_spent'] + self.cf_min = res['cf_min'] + self.cf_max = res['cf_max'] + self.cf = res['cf'] + self.cp = res['cp'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # job_type: u8 + ret += 1 + # status: u8 + ret += 1 + # cn0: u16 + ret += 2 + # int_time: u8 + ret += 1 + # sid: GnssSignal + ret += GnssSignal._payload_size() + # bin_width: u16 + ret += 2 + # timestamp: u32 + ret += 4 + # time_spent: u32 + ret += 4 + # cf_min: s32 + ret += 4 + # cf_max: s32 + ret += 4 + # cf: s32 + ret += 4 + # cp: u32 + ret += 4 + return ret + +class AcqSvProfileDep(object): + """SBP class for message AcqSvProfileDep + + You can have AcqSvProfileDep inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['job_type', + 'status', + 'cn0', + 'int_time', + 'sid', + 'bin_width', + 'timestamp', + 'time_spent', + 'cf_min', + 'cf_max', + 'cf', + 'cp', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__job_type, offset, length) = get_u8(buf, offset, length) + ret['job_type'] = __job_type + (__status, offset, length) = get_u8(buf, offset, length) + ret['status'] = __status + (__cn0, offset, length) = get_u16(buf, offset, length) + ret['cn0'] = __cn0 + (__int_time, offset, length) = get_u8(buf, offset, length) + ret['int_time'] = __int_time + (__sid, offset, length) = GnssSignalDep.parse_members(buf, offset, length) + ret['sid'] = __sid + (__bin_width, offset, length) = get_u16(buf, offset, length) + ret['bin_width'] = __bin_width + (__timestamp, offset, length) = get_u32(buf, offset, length) + ret['timestamp'] = __timestamp + (__time_spent, offset, length) = get_u32(buf, offset, length) + ret['time_spent'] = __time_spent + (__cf_min, offset, length) = get_s32(buf, offset, length) + ret['cf_min'] = __cf_min + (__cf_max, offset, length) = get_s32(buf, offset, length) + ret['cf_max'] = __cf_max + (__cf, offset, length) = get_s32(buf, offset, length) + ret['cf'] = __cf + (__cp, offset, length) = get_u32(buf, offset, length) + ret['cp'] = __cp + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.job_type = res['job_type'] + self.status = res['status'] + self.cn0 = res['cn0'] + self.int_time = res['int_time'] + self.sid = res['sid'] + self.bin_width = res['bin_width'] + self.timestamp = res['timestamp'] + self.time_spent = res['time_spent'] + self.cf_min = res['cf_min'] + self.cf_max = res['cf_max'] + self.cf = res['cf'] + self.cp = res['cp'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # job_type: u8 + ret += 1 + # status: u8 + ret += 1 + # cn0: u16 + ret += 2 + # int_time: u8 + ret += 1 + # sid: GnssSignalDep + ret += GnssSignalDep._payload_size() + # bin_width: u16 + ret += 2 + # timestamp: u32 + ret += 4 + # time_spent: u32 + ret += 4 + # cf_min: s32 + ret += 4 + # cf_max: s32 + ret += 4 + # cf: s32 + ret += 4 + # cp: u32 + ret += 4 + return ret + +SBP_MSG_ACQ_SV_PROFILE = 0x002E +class MsgAcqSvProfile(SBP): + """SBP class for message MSG_ACQ_SV_PROFILE (0x002E). + + You can have MSG_ACQ_SV_PROFILE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The message describes all SV profiles during acquisition time. +The message is used to debug and measure the performance. + + + """ + __slots__ = ['acq_sv_profile', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__acq_sv_profile, offset, length) = get_array(AcqSvProfile.parse_members)(buf, offset, length) + ret['acq_sv_profile'] = __acq_sv_profile + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.acq_sv_profile = res['acq_sv_profile'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # acq_sv_profile: array of AcqSvProfile + ret += 247 + return ret + +SBP_MSG_ACQ_SV_PROFILE_DEP = 0x001E +class MsgAcqSvProfileDep(SBP): + """SBP class for message MSG_ACQ_SV_PROFILE_DEP (0x001E). + + You can have MSG_ACQ_SV_PROFILE_DEP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['acq_sv_profile', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__acq_sv_profile, offset, length) = get_array(AcqSvProfileDep.parse_members)(buf, offset, length) + ret['acq_sv_profile'] = __acq_sv_profile + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.acq_sv_profile = res['acq_sv_profile'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # acq_sv_profile: array of AcqSvProfileDep + ret += 247 + return ret + + +msg_classes = { + 0x002F: MsgAcqResult, + 0x001F: MsgAcqResultDepC, + 0x0014: MsgAcqResultDepB, + 0x0015: MsgAcqResultDepA, + 0x002E: MsgAcqSvProfile, + 0x001E: MsgAcqSvProfileDep, +} \ No newline at end of file diff --git a/python/sbp/jit/bootload.py b/python/sbp/jit/bootload.py new file mode 100644 index 0000000000..5d64d6928a --- /dev/null +++ b/python/sbp/jit/bootload.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Messages for the bootloading configuration of a Piksi 2.3.1. This message +group does not apply to Piksi Multi. + +Note that some of these messages share the same message type ID for both the +host request and the device response. + +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +# Automatically generated from piksi/yaml/swiftnav/sbp/bootload.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_BOOTLOADER_HANDSHAKE_REQ = 0x00B3 +class MsgBootloaderHandshakeReq(SBP): + """SBP class for message MSG_BOOTLOADER_HANDSHAKE_REQ (0x00B3). + + You can have MSG_BOOTLOADER_HANDSHAKE_REQ inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The handshake message request from the host establishes a +handshake between the device bootloader and the host. The +response from the device is MSG_BOOTLOADER_HANDSHAKE_RESP. + + + """ + __slots__ = [] + def _unpack_members(self, buf, offset, length): + return {}, offset, length + + def _payload_size(self): + return 0 + +SBP_MSG_BOOTLOADER_HANDSHAKE_RESP = 0x00B4 +class MsgBootloaderHandshakeResp(SBP): + """SBP class for message MSG_BOOTLOADER_HANDSHAKE_RESP (0x00B4). + + You can have MSG_BOOTLOADER_HANDSHAKE_RESP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The handshake message response from the device establishes a +handshake between the device bootloader and the host. The +request from the host is MSG_BOOTLOADER_HANDSHAKE_REQ. The +payload contains the bootloader version number and the SBP +protocol version number. + + + """ + __slots__ = ['flags', + 'version', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__flags, offset, length) = get_u32(buf, offset, length) + ret['flags'] = __flags + (__version, offset, length) = get_string(buf, offset, length) + ret['version'] = __version + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.flags = res['flags'] + self.version = res['version'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # flags: u32 + ret += 4 + # version: string + ret += 247 + return ret + +SBP_MSG_BOOTLOADER_JUMP_TO_APP = 0x00B1 +class MsgBootloaderJumpToApp(SBP): + """SBP class for message MSG_BOOTLOADER_JUMP_TO_APP (0x00B1). + + You can have MSG_BOOTLOADER_JUMP_TO_APP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The host initiates the bootloader to jump to the application. + + + """ + __slots__ = ['jump', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__jump, offset, length) = get_u8(buf, offset, length) + ret['jump'] = __jump + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.jump = res['jump'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # jump: u8 + ret += 1 + return ret + +SBP_MSG_NAP_DEVICE_DNA_REQ = 0x00DE +class MsgNapDeviceDnaReq(SBP): + """SBP class for message MSG_NAP_DEVICE_DNA_REQ (0x00DE). + + You can have MSG_NAP_DEVICE_DNA_REQ inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The device message from the host reads a unique device +identifier from the SwiftNAP, an FPGA. The host requests the ID +by sending a MSG_NAP_DEVICE_DNA_REQ message. The device +responds with a MSG_NAP_DEVICE_DNA_RESP message with the +device ID in the payload. Note that this ID is tied to the FPGA, +and not related to the Piksi's serial number. + + + """ + __slots__ = [] + def _unpack_members(self, buf, offset, length): + return {}, offset, length + + def _payload_size(self): + return 0 + +SBP_MSG_NAP_DEVICE_DNA_RESP = 0x00DD +class MsgNapDeviceDnaResp(SBP): + """SBP class for message MSG_NAP_DEVICE_DNA_RESP (0x00DD). + + You can have MSG_NAP_DEVICE_DNA_RESP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The device message from the host reads a unique device +identifier from the SwiftNAP, an FPGA. The host requests the ID +by sending a MSG_NAP_DEVICE_DNA_REQ message. The device +responds with a MSG_NAP_DEVICE_DNA_RESP messagage with the +device ID in the payload. Note that this ID is tied to the FPGA, +and not related to the Piksi's serial number. + + + """ + __slots__ = ['dna', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__dna, offset, length) = get_fixed_array(get_u8, 8, 1)(buf, offset, length) + ret['dna'] = __dna + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.dna = res['dna'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # dna: array of u8 + ret += 1 * 8 + return ret + +SBP_MSG_BOOTLOADER_HANDSHAKE_DEP_A = 0x00B0 +class MsgBootloaderHandshakeDepA(SBP): + """SBP class for message MSG_BOOTLOADER_HANDSHAKE_DEP_A (0x00B0). + + You can have MSG_BOOTLOADER_HANDSHAKE_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['handshake', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__handshake, offset, length) = get_array(get_u8)(buf, offset, length) + ret['handshake'] = __handshake + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.handshake = res['handshake'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # handshake: array of u8 + ret += 247 + return ret + + +msg_classes = { + 0x00B3: MsgBootloaderHandshakeReq, + 0x00B4: MsgBootloaderHandshakeResp, + 0x00B1: MsgBootloaderJumpToApp, + 0x00DE: MsgNapDeviceDnaReq, + 0x00DD: MsgNapDeviceDnaResp, + 0x00B0: MsgBootloaderHandshakeDepA, +} \ No newline at end of file diff --git a/python/sbp/jit/ext_events.py b/python/sbp/jit/ext_events.py new file mode 100644 index 0000000000..2d755f06f1 --- /dev/null +++ b/python/sbp/jit/ext_events.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Messages reporting accurately-timestamped external events, +e.g. camera shutter time. + +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +# Automatically generated from piksi/yaml/swiftnav/sbp/ext_events.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_EXT_EVENT = 0x0101 +class MsgExtEvent(SBP): + """SBP class for message MSG_EXT_EVENT (0x0101). + + You can have MSG_EXT_EVENT inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Reports detection of an external event, the GPS time it occurred, +which pin it was and whether it was rising or falling. + + + """ + __slots__ = ['wn', + 'tow', + 'ns_residual', + 'flags', + 'pin', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__wn, offset, length) = get_u16(buf, offset, length) + ret['wn'] = __wn + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__ns_residual, offset, length) = get_s32(buf, offset, length) + ret['ns_residual'] = __ns_residual + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + (__pin, offset, length) = get_u8(buf, offset, length) + ret['pin'] = __pin + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.wn = res['wn'] + self.tow = res['tow'] + self.ns_residual = res['ns_residual'] + self.flags = res['flags'] + self.pin = res['pin'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # wn: u16 + ret += 2 + # tow: u32 + ret += 4 + # ns_residual: s32 + ret += 4 + # flags: u8 + ret += 1 + # pin: u8 + ret += 1 + return ret + + +msg_classes = { + 0x0101: MsgExtEvent, +} \ No newline at end of file diff --git a/python/sbp/jit/file_io.py b/python/sbp/jit/file_io.py new file mode 100644 index 0000000000..024888644b --- /dev/null +++ b/python/sbp/jit/file_io.py @@ -0,0 +1,496 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Messages for using device's onboard flash filesystem +functionality. This allows data to be stored persistently in the +device's program flash with wear-levelling using a simple filesystem +interface. The file system interface (CFS) defines an abstract API +for reading directories and for reading and writing files. + +Note that some of these messages share the same message type ID for both the +host request and the device response. + +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +# Automatically generated from piksi/yaml/swiftnav/sbp/file_io.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_FILEIO_READ_REQ = 0x00A8 +class MsgFileioReadReq(SBP): + """SBP class for message MSG_FILEIO_READ_REQ (0x00A8). + + You can have MSG_FILEIO_READ_REQ inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The file read message reads a certain length (up to 255 bytes) +from a given offset into a file, and returns the data in a +MSG_FILEIO_READ_RESP message where the message length field +indicates how many bytes were succesfully read.The sequence +number in the request will be returned in the response. +If the message is invalid, a followup MSG_PRINT message will +print "Invalid fileio read message". A device will only respond +to this message when it is received from sender ID 0x42. + + + """ + __slots__ = ['sequence', + 'offset', + 'chunk_size', + 'filename', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sequence, offset, length) = get_u32(buf, offset, length) + ret['sequence'] = __sequence + (__offset, offset, length) = get_u32(buf, offset, length) + ret['offset'] = __offset + (__chunk_size, offset, length) = get_u8(buf, offset, length) + ret['chunk_size'] = __chunk_size + (__filename, offset, length) = get_string(buf, offset, length) + ret['filename'] = __filename + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sequence = res['sequence'] + self.offset = res['offset'] + self.chunk_size = res['chunk_size'] + self.filename = res['filename'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sequence: u32 + ret += 4 + # offset: u32 + ret += 4 + # chunk_size: u8 + ret += 1 + # filename: string + ret += 247 + return ret + +SBP_MSG_FILEIO_READ_RESP = 0x00A3 +class MsgFileioReadResp(SBP): + """SBP class for message MSG_FILEIO_READ_RESP (0x00A3). + + You can have MSG_FILEIO_READ_RESP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The file read message reads a certain length (up to 255 bytes) +from a given offset into a file, and returns the data in a +message where the message length field indicates how many bytes +were succesfully read. The sequence number in the response is +preserved from the request. + + + """ + __slots__ = ['sequence', + 'contents', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sequence, offset, length) = get_u32(buf, offset, length) + ret['sequence'] = __sequence + (__contents, offset, length) = get_array(get_u8)(buf, offset, length) + ret['contents'] = __contents + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sequence = res['sequence'] + self.contents = res['contents'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sequence: u32 + ret += 4 + # contents: array of u8 + ret += 247 + return ret + +SBP_MSG_FILEIO_READ_DIR_REQ = 0x00A9 +class MsgFileioReadDirReq(SBP): + """SBP class for message MSG_FILEIO_READ_DIR_REQ (0x00A9). + + You can have MSG_FILEIO_READ_DIR_REQ inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The read directory message lists the files in a directory on the +device's onboard flash file system. The offset parameter can be +used to skip the first n elements of the file list. Returns a +MSG_FILEIO_READ_DIR_RESP message containing the directory +listings as a NULL delimited list. The listing is chunked over +multiple SBP packets. The sequence number in the request will be +returned in the response. If message is invalid, a followup +MSG_PRINT message will print "Invalid fileio read message". +A device will only respond to this message when it is received +from sender ID 0x42. + + + """ + __slots__ = ['sequence', + 'offset', + 'dirname', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sequence, offset, length) = get_u32(buf, offset, length) + ret['sequence'] = __sequence + (__offset, offset, length) = get_u32(buf, offset, length) + ret['offset'] = __offset + (__dirname, offset, length) = get_string(buf, offset, length) + ret['dirname'] = __dirname + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sequence = res['sequence'] + self.offset = res['offset'] + self.dirname = res['dirname'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sequence: u32 + ret += 4 + # offset: u32 + ret += 4 + # dirname: string + ret += 247 + return ret + +SBP_MSG_FILEIO_READ_DIR_RESP = 0x00AA +class MsgFileioReadDirResp(SBP): + """SBP class for message MSG_FILEIO_READ_DIR_RESP (0x00AA). + + You can have MSG_FILEIO_READ_DIR_RESP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The read directory message lists the files in a directory on the +device's onboard flash file system. Message contains the directory +listings as a NULL delimited list. The listing is chunked over +multiple SBP packets and the end of the list is identified by an +entry containing just the character 0xFF. The sequence number in +the response is preserved from the request. + + + """ + __slots__ = ['sequence', + 'contents', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sequence, offset, length) = get_u32(buf, offset, length) + ret['sequence'] = __sequence + (__contents, offset, length) = get_array(get_u8)(buf, offset, length) + ret['contents'] = __contents + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sequence = res['sequence'] + self.contents = res['contents'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sequence: u32 + ret += 4 + # contents: array of u8 + ret += 247 + return ret + +SBP_MSG_FILEIO_REMOVE = 0x00AC +class MsgFileioRemove(SBP): + """SBP class for message MSG_FILEIO_REMOVE (0x00AC). + + You can have MSG_FILEIO_REMOVE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The file remove message deletes a file from the file system. +If the message is invalid, a followup MSG_PRINT message will +print "Invalid fileio remove message". A device will only +process this message when it is received from sender ID 0x42. + + + """ + __slots__ = ['filename', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__filename, offset, length) = get_string(buf, offset, length) + ret['filename'] = __filename + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.filename = res['filename'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # filename: string + ret += 247 + return ret + +SBP_MSG_FILEIO_WRITE_REQ = 0x00AD +class MsgFileioWriteReq(SBP): + """SBP class for message MSG_FILEIO_WRITE_REQ (0x00AD). + + You can have MSG_FILEIO_WRITE_REQ inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The file write message writes a certain length (up to 255 bytes) +of data to a file at a given offset. Returns a copy of the +original MSG_FILEIO_WRITE_RESP message to check integrity of +the write. The sequence number in the request will be returned +in the response. If message is invalid, a followup MSG_PRINT +message will print "Invalid fileio write message". A device will +only process this message when it is received from sender ID +0x42. + + + """ + __slots__ = ['sequence', + 'offset', + 'filename', + 'data', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sequence, offset, length) = get_u32(buf, offset, length) + ret['sequence'] = __sequence + (__offset, offset, length) = get_u32(buf, offset, length) + ret['offset'] = __offset + (__filename, offset, length) = get_string(buf, offset, length) + ret['filename'] = __filename + (__data, offset, length) = get_array(get_u8)(buf, offset, length) + ret['data'] = __data + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sequence = res['sequence'] + self.offset = res['offset'] + self.filename = res['filename'] + self.data = res['data'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sequence: u32 + ret += 4 + # offset: u32 + ret += 4 + # filename: string + ret += 247 + # data: array of u8 + ret += 247 + return ret + +SBP_MSG_FILEIO_WRITE_RESP = 0x00AB +class MsgFileioWriteResp(SBP): + """SBP class for message MSG_FILEIO_WRITE_RESP (0x00AB). + + You can have MSG_FILEIO_WRITE_RESP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The file write message writes a certain length (up to 255 bytes) +of data to a file at a given offset. The message is a copy of the +original MSG_FILEIO_WRITE_REQ message to check integrity of the +write. The sequence number in the response is preserved from the +request. + + + """ + __slots__ = ['sequence', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sequence, offset, length) = get_u32(buf, offset, length) + ret['sequence'] = __sequence + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sequence = res['sequence'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sequence: u32 + ret += 4 + return ret + +SBP_MSG_FILEIO_CONFIG_REQ = 0x1001 +class MsgFileioConfigReq(SBP): + """SBP class for message MSG_FILEIO_CONFIG_REQ (0x1001). + + You can have MSG_FILEIO_CONFIG_REQ inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Requests advice on the optimal configuration for a FileIO +transfer. Newer version of FileIO can support greater +throughput by supporting a large window of FileIO data +that can be in-flight during read or write operations. + + + """ + __slots__ = ['sequence', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sequence, offset, length) = get_u32(buf, offset, length) + ret['sequence'] = __sequence + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sequence = res['sequence'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sequence: u32 + ret += 4 + return ret + +SBP_MSG_FILEIO_CONFIG_RESP = 0x1002 +class MsgFileioConfigResp(SBP): + """SBP class for message MSG_FILEIO_CONFIG_RESP (0x1002). + + You can have MSG_FILEIO_CONFIG_RESP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The advice on the optimal configuration for a FileIO +transfer. Newer version of FileIO can support greater +throughput by supporting a large window of FileIO data +that can be in-flight during read or write operations. + + + """ + __slots__ = ['sequence', + 'window_size', + 'batch_size', + 'fileio_version', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sequence, offset, length) = get_u32(buf, offset, length) + ret['sequence'] = __sequence + (__window_size, offset, length) = get_u32(buf, offset, length) + ret['window_size'] = __window_size + (__batch_size, offset, length) = get_u32(buf, offset, length) + ret['batch_size'] = __batch_size + (__fileio_version, offset, length) = get_u32(buf, offset, length) + ret['fileio_version'] = __fileio_version + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sequence = res['sequence'] + self.window_size = res['window_size'] + self.batch_size = res['batch_size'] + self.fileio_version = res['fileio_version'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sequence: u32 + ret += 4 + # window_size: u32 + ret += 4 + # batch_size: u32 + ret += 4 + # fileio_version: u32 + ret += 4 + return ret + + +msg_classes = { + 0x00A8: MsgFileioReadReq, + 0x00A3: MsgFileioReadResp, + 0x00A9: MsgFileioReadDirReq, + 0x00AA: MsgFileioReadDirResp, + 0x00AC: MsgFileioRemove, + 0x00AD: MsgFileioWriteReq, + 0x00AB: MsgFileioWriteResp, + 0x1001: MsgFileioConfigReq, + 0x1002: MsgFileioConfigResp, +} \ No newline at end of file diff --git a/python/sbp/jit/flash.py b/python/sbp/jit/flash.py new file mode 100644 index 0000000000..fa02fb1ee9 --- /dev/null +++ b/python/sbp/jit/flash.py @@ -0,0 +1,472 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Messages for reading/writing the device's onboard flash memory. Many +of these messages target specific flash memory peripherals used in +Swift Navigation devices: the STM32 flash and the M25Pxx FPGA +configuration flash from Piksi 2.3.1. This module does not apply +to Piksi Multi. + +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +# Automatically generated from piksi/yaml/swiftnav/sbp/flash.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_FLASH_PROGRAM = 0x00E6 +class MsgFlashProgram(SBP): + """SBP class for message MSG_FLASH_PROGRAM (0x00E6). + + You can have MSG_FLASH_PROGRAM inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The flash program message programs a set of addresses of either +the STM or M25 flash. The device replies with either a +MSG_FLASH_DONE message containing the return code FLASH_OK (0) +on success, or FLASH_INVALID_LEN (2) if the maximum write size +is exceeded. Note that the sector-containing addresses must be +erased before addresses can be programmed. + + + """ + __slots__ = ['target', + 'addr_start', + 'addr_len', + 'data', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__target, offset, length) = get_u8(buf, offset, length) + ret['target'] = __target + (__addr_start, offset, length) = get_fixed_array(get_u8, 3, 1)(buf, offset, length) + ret['addr_start'] = __addr_start + (__addr_len, offset, length) = get_u8(buf, offset, length) + ret['addr_len'] = __addr_len + (__data, offset, length) = get_array(get_u8)(buf, offset, length) + ret['data'] = __data + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.target = res['target'] + self.addr_start = res['addr_start'] + self.addr_len = res['addr_len'] + self.data = res['data'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # target: u8 + ret += 1 + # addr_start: array of u8 + ret += 1 * 3 + # addr_len: u8 + ret += 1 + # data: array of u8 + ret += 247 + return ret + +SBP_MSG_FLASH_DONE = 0x00E0 +class MsgFlashDone(SBP): + """SBP class for message MSG_FLASH_DONE (0x00E0). + + You can have MSG_FLASH_DONE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message defines success or failure codes for a variety of +flash memory requests from the host to the device. Flash read +and write messages, such as MSG_FLASH_READ_REQ, or +MSG_FLASH_PROGRAM, may return this message on failure. + + + """ + __slots__ = ['response', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__response, offset, length) = get_u8(buf, offset, length) + ret['response'] = __response + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.response = res['response'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # response: u8 + ret += 1 + return ret + +SBP_MSG_FLASH_READ_REQ = 0x00E7 +class MsgFlashReadReq(SBP): + """SBP class for message MSG_FLASH_READ_REQ (0x00E7). + + You can have MSG_FLASH_READ_REQ inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The flash read message reads a set of addresses of either the +STM or M25 onboard flash. The device replies with a +MSG_FLASH_READ_RESP message containing either the read data on +success or a MSG_FLASH_DONE message containing the return code +FLASH_INVALID_LEN (2) if the maximum read size is exceeded or +FLASH_INVALID_ADDR (3) if the address is outside of the allowed +range. + + + """ + __slots__ = ['target', + 'addr_start', + 'addr_len', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__target, offset, length) = get_u8(buf, offset, length) + ret['target'] = __target + (__addr_start, offset, length) = get_fixed_array(get_u8, 3, 1)(buf, offset, length) + ret['addr_start'] = __addr_start + (__addr_len, offset, length) = get_u8(buf, offset, length) + ret['addr_len'] = __addr_len + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.target = res['target'] + self.addr_start = res['addr_start'] + self.addr_len = res['addr_len'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # target: u8 + ret += 1 + # addr_start: array of u8 + ret += 1 * 3 + # addr_len: u8 + ret += 1 + return ret + +SBP_MSG_FLASH_READ_RESP = 0x00E1 +class MsgFlashReadResp(SBP): + """SBP class for message MSG_FLASH_READ_RESP (0x00E1). + + You can have MSG_FLASH_READ_RESP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The flash read message reads a set of addresses of either the +STM or M25 onboard flash. The device replies with a +MSG_FLASH_READ_RESP message containing either the read data on +success or a MSG_FLASH_DONE message containing the return code +FLASH_INVALID_LEN (2) if the maximum read size is exceeded or +FLASH_INVALID_ADDR (3) if the address is outside of the allowed +range. + + + """ + __slots__ = ['target', + 'addr_start', + 'addr_len', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__target, offset, length) = get_u8(buf, offset, length) + ret['target'] = __target + (__addr_start, offset, length) = get_fixed_array(get_u8, 3, 1)(buf, offset, length) + ret['addr_start'] = __addr_start + (__addr_len, offset, length) = get_u8(buf, offset, length) + ret['addr_len'] = __addr_len + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.target = res['target'] + self.addr_start = res['addr_start'] + self.addr_len = res['addr_len'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # target: u8 + ret += 1 + # addr_start: array of u8 + ret += 1 * 3 + # addr_len: u8 + ret += 1 + return ret + +SBP_MSG_FLASH_ERASE = 0x00E2 +class MsgFlashErase(SBP): + """SBP class for message MSG_FLASH_ERASE (0x00E2). + + You can have MSG_FLASH_ERASE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The flash erase message from the host erases a sector of either +the STM or M25 onboard flash memory. The device will reply with a +MSG_FLASH_DONE message containing the return code - FLASH_OK (0) +on success or FLASH_INVALID_FLASH (1) if the flash specified is +invalid. + + + """ + __slots__ = ['target', + 'sector_num', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__target, offset, length) = get_u8(buf, offset, length) + ret['target'] = __target + (__sector_num, offset, length) = get_u32(buf, offset, length) + ret['sector_num'] = __sector_num + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.target = res['target'] + self.sector_num = res['sector_num'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # target: u8 + ret += 1 + # sector_num: u32 + ret += 4 + return ret + +SBP_MSG_STM_FLASH_LOCK_SECTOR = 0x00E3 +class MsgStmFlashLockSector(SBP): + """SBP class for message MSG_STM_FLASH_LOCK_SECTOR (0x00E3). + + You can have MSG_STM_FLASH_LOCK_SECTOR inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The flash lock message locks a sector of the STM flash +memory. The device replies with a MSG_FLASH_DONE message. + + + """ + __slots__ = ['sector', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sector, offset, length) = get_u32(buf, offset, length) + ret['sector'] = __sector + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sector = res['sector'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sector: u32 + ret += 4 + return ret + +SBP_MSG_STM_FLASH_UNLOCK_SECTOR = 0x00E4 +class MsgStmFlashUnlockSector(SBP): + """SBP class for message MSG_STM_FLASH_UNLOCK_SECTOR (0x00E4). + + You can have MSG_STM_FLASH_UNLOCK_SECTOR inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The flash unlock message unlocks a sector of the STM flash +memory. The device replies with a MSG_FLASH_DONE message. + + + """ + __slots__ = ['sector', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sector, offset, length) = get_u32(buf, offset, length) + ret['sector'] = __sector + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sector = res['sector'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sector: u32 + ret += 4 + return ret + +SBP_MSG_STM_UNIQUE_ID_REQ = 0x00E8 +class MsgStmUniqueIdReq(SBP): + """SBP class for message MSG_STM_UNIQUE_ID_REQ (0x00E8). + + You can have MSG_STM_UNIQUE_ID_REQ inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reads the device's hardcoded unique ID. The host +requests the ID by sending a MSG_STM_UNIQUE_ID_REQ. The device +responds with a MSG_STM_UNIQUE_ID_RESP with the 12-byte unique +ID in the payload. + + + """ + __slots__ = [] + def _unpack_members(self, buf, offset, length): + return {}, offset, length + + def _payload_size(self): + return 0 + +SBP_MSG_STM_UNIQUE_ID_RESP = 0x00E5 +class MsgStmUniqueIdResp(SBP): + """SBP class for message MSG_STM_UNIQUE_ID_RESP (0x00E5). + + You can have MSG_STM_UNIQUE_ID_RESP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reads the device's hardcoded unique ID. The host +requests the ID by sending a MSG_STM_UNIQUE_ID_REQ. The device +responds with a MSG_STM_UNIQUE_ID_RESP with the 12-byte unique +ID in the payload.. + + + """ + __slots__ = ['stm_id', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__stm_id, offset, length) = get_fixed_array(get_u8, 12, 1)(buf, offset, length) + ret['stm_id'] = __stm_id + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.stm_id = res['stm_id'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # stm_id: array of u8 + ret += 1 * 12 + return ret + +SBP_MSG_M25_FLASH_WRITE_STATUS = 0x00F3 +class MsgM25FlashWriteStatus(SBP): + """SBP class for message MSG_M25_FLASH_WRITE_STATUS (0x00F3). + + You can have MSG_M25_FLASH_WRITE_STATUS inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The flash status message writes to the 8-bit M25 flash status +register. The device replies with a MSG_FLASH_DONE message. + + + """ + __slots__ = ['status', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__status, offset, length) = get_fixed_array(get_u8, 1, 1)(buf, offset, length) + ret['status'] = __status + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.status = res['status'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # status: array of u8 + ret += 1 * 1 + return ret + + +msg_classes = { + 0x00E6: MsgFlashProgram, + 0x00E0: MsgFlashDone, + 0x00E7: MsgFlashReadReq, + 0x00E1: MsgFlashReadResp, + 0x00E2: MsgFlashErase, + 0x00E3: MsgStmFlashLockSector, + 0x00E4: MsgStmFlashUnlockSector, + 0x00E8: MsgStmUniqueIdReq, + 0x00E5: MsgStmUniqueIdResp, + 0x00F3: MsgM25FlashWriteStatus, +} \ No newline at end of file diff --git a/python/sbp/jit/gnss.py b/python/sbp/jit/gnss.py new file mode 100644 index 0000000000..c681acd927 --- /dev/null +++ b/python/sbp/jit/gnss.py @@ -0,0 +1,299 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Various structs shared between modules +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +# Automatically generated from piksi/yaml/swiftnav/sbp/gnss.yaml with generate.py. +# Please do not hand edit! +class GnssSignal(object): + """SBP class for message GnssSignal + + You can have GnssSignal inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Signal identifier containing constellation, band, and satellite identifier + + + """ + __slots__ = ['sat', + 'code', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sat, offset, length) = get_u8(buf, offset, length) + ret['sat'] = __sat + (__code, offset, length) = get_u8(buf, offset, length) + ret['code'] = __code + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sat = res['sat'] + self.code = res['code'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sat: u8 + ret += 1 + # code: u8 + ret += 1 + return ret + +class GnssSignalDep(object): + """SBP class for message GnssSignalDep + + You can have GnssSignalDep inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['sat', + 'code', + 'reserved', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sat, offset, length) = get_u16(buf, offset, length) + ret['sat'] = __sat + (__code, offset, length) = get_u8(buf, offset, length) + ret['code'] = __code + (__reserved, offset, length) = get_u8(buf, offset, length) + ret['reserved'] = __reserved + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sat = res['sat'] + self.code = res['code'] + self.reserved = res['reserved'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sat: u16 + ret += 2 + # code: u8 + ret += 1 + # reserved: u8 + ret += 1 + return ret + +class GPSTimeDep(object): + """SBP class for message GPSTimeDep + + You can have GPSTimeDep inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + A wire-appropriate GPS time, defined as the number of +milliseconds since beginning of the week on the Saturday/Sunday +transition. + + + """ + __slots__ = ['tow', + 'wn', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__wn, offset, length) = get_u16(buf, offset, length) + ret['wn'] = __wn + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.wn = res['wn'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # wn: u16 + ret += 2 + return ret + +class GPSTimeSec(object): + """SBP class for message GPSTimeSec + + You can have GPSTimeSec inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + A GPS time, defined as the number of +seconds since beginning of the week on the Saturday/Sunday +transition. + + + """ + __slots__ = ['tow', + 'wn', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__wn, offset, length) = get_u16(buf, offset, length) + ret['wn'] = __wn + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.wn = res['wn'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # wn: u16 + ret += 2 + return ret + +class GPSTime(object): + """SBP class for message GPSTime + + You can have GPSTime inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + A wire-appropriate receiver clock time, defined as the time +since the beginning of the week on the Saturday/Sunday +transition. In most cases, observations are epoch aligned +so ns field will be 0. + + + """ + __slots__ = ['tow', + 'ns_residual', + 'wn', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__ns_residual, offset, length) = get_s32(buf, offset, length) + ret['ns_residual'] = __ns_residual + (__wn, offset, length) = get_u16(buf, offset, length) + ret['wn'] = __wn + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.ns_residual = res['ns_residual'] + self.wn = res['wn'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # ns_residual: s32 + ret += 4 + # wn: u16 + ret += 2 + return ret + +class CarrierPhase(object): + """SBP class for message CarrierPhase + + You can have CarrierPhase inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Carrier phase measurement in cycles represented as a 40-bit +fixed point number with Q32.8 layout, i.e. 32-bits of whole +cycles and 8-bits of fractional cycles. This phase has the +same sign as the pseudorange. + + + """ + __slots__ = ['i', + 'f', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__i, offset, length) = get_s32(buf, offset, length) + ret['i'] = __i + (__f, offset, length) = get_u8(buf, offset, length) + ret['f'] = __f + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.i = res['i'] + self.f = res['f'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # i: s32 + ret += 4 + # f: u8 + ret += 1 + return ret + + +msg_classes = { +} \ No newline at end of file diff --git a/python/sbp/jit/imu.py b/python/sbp/jit/imu.py new file mode 100644 index 0000000000..d255e1bb21 --- /dev/null +++ b/python/sbp/jit/imu.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Inertial Measurement Unit (IMU) messages. +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +# Automatically generated from piksi/yaml/swiftnav/sbp/imu.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_IMU_RAW = 0x0900 +class MsgImuRaw(SBP): + """SBP class for message MSG_IMU_RAW (0x0900). + + You can have MSG_IMU_RAW inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Raw data from the Inertial Measurement Unit, containing accelerometer and +gyroscope readings. The sense of the measurements are to be aligned with +the indications on the device itself. Measurement units, which are specific to the +device hardware and settings, are communicated via the MSG_IMU_AUX message. + + + """ + __slots__ = ['tow', + 'tow_f', + 'acc_x', + 'acc_y', + 'acc_z', + 'gyr_x', + 'gyr_y', + 'gyr_z', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__tow_f, offset, length) = get_u8(buf, offset, length) + ret['tow_f'] = __tow_f + (__acc_x, offset, length) = get_s16(buf, offset, length) + ret['acc_x'] = __acc_x + (__acc_y, offset, length) = get_s16(buf, offset, length) + ret['acc_y'] = __acc_y + (__acc_z, offset, length) = get_s16(buf, offset, length) + ret['acc_z'] = __acc_z + (__gyr_x, offset, length) = get_s16(buf, offset, length) + ret['gyr_x'] = __gyr_x + (__gyr_y, offset, length) = get_s16(buf, offset, length) + ret['gyr_y'] = __gyr_y + (__gyr_z, offset, length) = get_s16(buf, offset, length) + ret['gyr_z'] = __gyr_z + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.tow_f = res['tow_f'] + self.acc_x = res['acc_x'] + self.acc_y = res['acc_y'] + self.acc_z = res['acc_z'] + self.gyr_x = res['gyr_x'] + self.gyr_y = res['gyr_y'] + self.gyr_z = res['gyr_z'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # tow_f: u8 + ret += 1 + # acc_x: s16 + ret += 2 + # acc_y: s16 + ret += 2 + # acc_z: s16 + ret += 2 + # gyr_x: s16 + ret += 2 + # gyr_y: s16 + ret += 2 + # gyr_z: s16 + ret += 2 + return ret + +SBP_MSG_IMU_AUX = 0x0901 +class MsgImuAux(SBP): + """SBP class for message MSG_IMU_AUX (0x0901). + + You can have MSG_IMU_AUX inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Auxiliary data specific to a particular IMU. The `imu_type` field will +always be consistent but the rest of the payload is device specific and +depends on the value of `imu_type`. + + + """ + __slots__ = ['imu_type', + 'temp', + 'imu_conf', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__imu_type, offset, length) = get_u8(buf, offset, length) + ret['imu_type'] = __imu_type + (__temp, offset, length) = get_s16(buf, offset, length) + ret['temp'] = __temp + (__imu_conf, offset, length) = get_u8(buf, offset, length) + ret['imu_conf'] = __imu_conf + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.imu_type = res['imu_type'] + self.temp = res['temp'] + self.imu_conf = res['imu_conf'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # imu_type: u8 + ret += 1 + # temp: s16 + ret += 2 + # imu_conf: u8 + ret += 1 + return ret + + +msg_classes = { + 0x0900: MsgImuRaw, + 0x0901: MsgImuAux, +} \ No newline at end of file diff --git a/python/sbp/jit/linux.py b/python/sbp/jit/linux.py new file mode 100644 index 0000000000..fcf6fc07ec --- /dev/null +++ b/python/sbp/jit/linux.py @@ -0,0 +1,523 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Linux state monitoring. + +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +# Automatically generated from piksi/yaml/swiftnav/sbp/linux.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_LINUX_CPU_STATE = 0x7F00 +class MsgLinuxCpuState(SBP): + """SBP class for message MSG_LINUX_CPU_STATE (0x7F00). + + You can have MSG_LINUX_CPU_STATE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message indicates the process state of the top 10 heaviest +consumers of CPU on the system. + + + """ + __slots__ = ['index', + 'pid', + 'pcpu', + 'tname', + 'cmdline', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__index, offset, length) = get_u8(buf, offset, length) + ret['index'] = __index + (__pid, offset, length) = get_u16(buf, offset, length) + ret['pid'] = __pid + (__pcpu, offset, length) = get_u8(buf, offset, length) + ret['pcpu'] = __pcpu + (__tname, offset, length) = get_fixed_string(15)(buf, offset, length) + ret['tname'] = __tname + (__cmdline, offset, length) = get_string(buf, offset, length) + ret['cmdline'] = __cmdline + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.index = res['index'] + self.pid = res['pid'] + self.pcpu = res['pcpu'] + self.tname = res['tname'] + self.cmdline = res['cmdline'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # index: u8 + ret += 1 + # pid: u16 + ret += 2 + # pcpu: u8 + ret += 1 + # tname: string + ret += 15 + # cmdline: string + ret += 247 + return ret + +SBP_MSG_LINUX_MEM_STATE = 0x7F01 +class MsgLinuxMemState(SBP): + """SBP class for message MSG_LINUX_MEM_STATE (0x7F01). + + You can have MSG_LINUX_MEM_STATE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message indicates the process state of the top 10 heaviest +consumers of memory on the system. + + + """ + __slots__ = ['index', + 'pid', + 'pmem', + 'tname', + 'cmdline', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__index, offset, length) = get_u8(buf, offset, length) + ret['index'] = __index + (__pid, offset, length) = get_u16(buf, offset, length) + ret['pid'] = __pid + (__pmem, offset, length) = get_u8(buf, offset, length) + ret['pmem'] = __pmem + (__tname, offset, length) = get_fixed_string(15)(buf, offset, length) + ret['tname'] = __tname + (__cmdline, offset, length) = get_string(buf, offset, length) + ret['cmdline'] = __cmdline + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.index = res['index'] + self.pid = res['pid'] + self.pmem = res['pmem'] + self.tname = res['tname'] + self.cmdline = res['cmdline'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # index: u8 + ret += 1 + # pid: u16 + ret += 2 + # pmem: u8 + ret += 1 + # tname: string + ret += 15 + # cmdline: string + ret += 247 + return ret + +SBP_MSG_LINUX_SYS_STATE = 0x7F02 +class MsgLinuxSysState(SBP): + """SBP class for message MSG_LINUX_SYS_STATE (0x7F02). + + You can have MSG_LINUX_SYS_STATE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This presents a summary of CPU and memory utilization. + + + """ + __slots__ = ['mem_total', + 'pcpu', + 'pmem', + 'procs_starting', + 'procs_stopping', + 'pid_count', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__mem_total, offset, length) = get_u16(buf, offset, length) + ret['mem_total'] = __mem_total + (__pcpu, offset, length) = get_u8(buf, offset, length) + ret['pcpu'] = __pcpu + (__pmem, offset, length) = get_u8(buf, offset, length) + ret['pmem'] = __pmem + (__procs_starting, offset, length) = get_u16(buf, offset, length) + ret['procs_starting'] = __procs_starting + (__procs_stopping, offset, length) = get_u16(buf, offset, length) + ret['procs_stopping'] = __procs_stopping + (__pid_count, offset, length) = get_u16(buf, offset, length) + ret['pid_count'] = __pid_count + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.mem_total = res['mem_total'] + self.pcpu = res['pcpu'] + self.pmem = res['pmem'] + self.procs_starting = res['procs_starting'] + self.procs_stopping = res['procs_stopping'] + self.pid_count = res['pid_count'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # mem_total: u16 + ret += 2 + # pcpu: u8 + ret += 1 + # pmem: u8 + ret += 1 + # procs_starting: u16 + ret += 2 + # procs_stopping: u16 + ret += 2 + # pid_count: u16 + ret += 2 + return ret + +SBP_MSG_LINUX_PROCESS_SOCKET_COUNTS = 0x7F03 +class MsgLinuxProcessSocketCounts(SBP): + """SBP class for message MSG_LINUX_PROCESS_SOCKET_COUNTS (0x7F03). + + You can have MSG_LINUX_PROCESS_SOCKET_COUNTS inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Top 10 list of processes with high socket counts. + + + """ + __slots__ = ['index', + 'pid', + 'socket_count', + 'socket_types', + 'socket_states', + 'cmdline', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__index, offset, length) = get_u8(buf, offset, length) + ret['index'] = __index + (__pid, offset, length) = get_u16(buf, offset, length) + ret['pid'] = __pid + (__socket_count, offset, length) = get_u16(buf, offset, length) + ret['socket_count'] = __socket_count + (__socket_types, offset, length) = get_u16(buf, offset, length) + ret['socket_types'] = __socket_types + (__socket_states, offset, length) = get_u16(buf, offset, length) + ret['socket_states'] = __socket_states + (__cmdline, offset, length) = get_string(buf, offset, length) + ret['cmdline'] = __cmdline + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.index = res['index'] + self.pid = res['pid'] + self.socket_count = res['socket_count'] + self.socket_types = res['socket_types'] + self.socket_states = res['socket_states'] + self.cmdline = res['cmdline'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # index: u8 + ret += 1 + # pid: u16 + ret += 2 + # socket_count: u16 + ret += 2 + # socket_types: u16 + ret += 2 + # socket_states: u16 + ret += 2 + # cmdline: string + ret += 247 + return ret + +SBP_MSG_LINUX_PROCESS_SOCKET_QUEUES = 0x7F04 +class MsgLinuxProcessSocketQueues(SBP): + """SBP class for message MSG_LINUX_PROCESS_SOCKET_QUEUES (0x7F04). + + You can have MSG_LINUX_PROCESS_SOCKET_QUEUES inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Top 10 list of sockets with deep queues. + + + """ + __slots__ = ['index', + 'pid', + 'recv_queued', + 'send_queued', + 'socket_types', + 'socket_states', + 'address_of_largest', + 'cmdline', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__index, offset, length) = get_u8(buf, offset, length) + ret['index'] = __index + (__pid, offset, length) = get_u16(buf, offset, length) + ret['pid'] = __pid + (__recv_queued, offset, length) = get_u16(buf, offset, length) + ret['recv_queued'] = __recv_queued + (__send_queued, offset, length) = get_u16(buf, offset, length) + ret['send_queued'] = __send_queued + (__socket_types, offset, length) = get_u16(buf, offset, length) + ret['socket_types'] = __socket_types + (__socket_states, offset, length) = get_u16(buf, offset, length) + ret['socket_states'] = __socket_states + (__address_of_largest, offset, length) = get_fixed_string(64)(buf, offset, length) + ret['address_of_largest'] = __address_of_largest + (__cmdline, offset, length) = get_string(buf, offset, length) + ret['cmdline'] = __cmdline + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.index = res['index'] + self.pid = res['pid'] + self.recv_queued = res['recv_queued'] + self.send_queued = res['send_queued'] + self.socket_types = res['socket_types'] + self.socket_states = res['socket_states'] + self.address_of_largest = res['address_of_largest'] + self.cmdline = res['cmdline'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # index: u8 + ret += 1 + # pid: u16 + ret += 2 + # recv_queued: u16 + ret += 2 + # send_queued: u16 + ret += 2 + # socket_types: u16 + ret += 2 + # socket_states: u16 + ret += 2 + # address_of_largest: string + ret += 64 + # cmdline: string + ret += 247 + return ret + +SBP_MSG_LINUX_SOCKET_USAGE = 0x7F05 +class MsgLinuxSocketUsage(SBP): + """SBP class for message MSG_LINUX_SOCKET_USAGE (0x7F05). + + You can have MSG_LINUX_SOCKET_USAGE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Summaries the socket usage across the system. + + + """ + __slots__ = ['avg_queue_depth', + 'max_queue_depth', + 'socket_state_counts', + 'socket_type_counts', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__avg_queue_depth, offset, length) = get_u32(buf, offset, length) + ret['avg_queue_depth'] = __avg_queue_depth + (__max_queue_depth, offset, length) = get_u32(buf, offset, length) + ret['max_queue_depth'] = __max_queue_depth + (__socket_state_counts, offset, length) = get_fixed_array(get_u16, 16, 2)(buf, offset, length) + ret['socket_state_counts'] = __socket_state_counts + (__socket_type_counts, offset, length) = get_fixed_array(get_u16, 16, 2)(buf, offset, length) + ret['socket_type_counts'] = __socket_type_counts + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.avg_queue_depth = res['avg_queue_depth'] + self.max_queue_depth = res['max_queue_depth'] + self.socket_state_counts = res['socket_state_counts'] + self.socket_type_counts = res['socket_type_counts'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # avg_queue_depth: u32 + ret += 4 + # max_queue_depth: u32 + ret += 4 + # socket_state_counts: array of u16 + ret += 2 * 16 + # socket_type_counts: array of u16 + ret += 2 * 16 + return ret + +SBP_MSG_LINUX_PROCESS_FD_COUNT = 0x7F06 +class MsgLinuxProcessFdCount(SBP): + """SBP class for message MSG_LINUX_PROCESS_FD_COUNT (0x7F06). + + You can have MSG_LINUX_PROCESS_FD_COUNT inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Top 10 list of processes with a large number of open file descriptors. + + + """ + __slots__ = ['index', + 'pid', + 'fd_count', + 'cmdline', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__index, offset, length) = get_u8(buf, offset, length) + ret['index'] = __index + (__pid, offset, length) = get_u16(buf, offset, length) + ret['pid'] = __pid + (__fd_count, offset, length) = get_u16(buf, offset, length) + ret['fd_count'] = __fd_count + (__cmdline, offset, length) = get_string(buf, offset, length) + ret['cmdline'] = __cmdline + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.index = res['index'] + self.pid = res['pid'] + self.fd_count = res['fd_count'] + self.cmdline = res['cmdline'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # index: u8 + ret += 1 + # pid: u16 + ret += 2 + # fd_count: u16 + ret += 2 + # cmdline: string + ret += 247 + return ret + +SBP_MSG_LINUX_PROCESS_FD_SUMMARY = 0x7F07 +class MsgLinuxProcessFdSummary(SBP): + """SBP class for message MSG_LINUX_PROCESS_FD_SUMMARY (0x7F07). + + You can have MSG_LINUX_PROCESS_FD_SUMMARY inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Summary of open file descriptors on the system. + + + """ + __slots__ = ['sys_fd_count', + 'most_opened', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sys_fd_count, offset, length) = get_u32(buf, offset, length) + ret['sys_fd_count'] = __sys_fd_count + (__most_opened, offset, length) = get_string(buf, offset, length) + ret['most_opened'] = __most_opened + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sys_fd_count = res['sys_fd_count'] + self.most_opened = res['most_opened'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sys_fd_count: u32 + ret += 4 + # most_opened: string + ret += 247 + return ret + + +msg_classes = { + 0x7F00: MsgLinuxCpuState, + 0x7F01: MsgLinuxMemState, + 0x7F02: MsgLinuxSysState, + 0x7F03: MsgLinuxProcessSocketCounts, + 0x7F04: MsgLinuxProcessSocketQueues, + 0x7F05: MsgLinuxSocketUsage, + 0x7F06: MsgLinuxProcessFdCount, + 0x7F07: MsgLinuxProcessFdSummary, +} \ No newline at end of file diff --git a/python/sbp/jit/logging.py b/python/sbp/jit/logging.py new file mode 100644 index 0000000000..a2787c4e57 --- /dev/null +++ b/python/sbp/jit/logging.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Logging and debugging messages from the device. + +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +# Automatically generated from piksi/yaml/swiftnav/sbp/logging.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_LOG = 0x0401 +class MsgLog(SBP): + """SBP class for message MSG_LOG (0x0401). + + You can have MSG_LOG inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message contains a human-readable payload string from the +device containing errors, warnings and informational messages at +ERROR, WARNING, DEBUG, INFO logging levels. + + + """ + __slots__ = ['level', + 'text', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__level, offset, length) = get_u8(buf, offset, length) + ret['level'] = __level + (__text, offset, length) = get_string(buf, offset, length) + ret['text'] = __text + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.level = res['level'] + self.text = res['text'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # level: u8 + ret += 1 + # text: string + ret += 247 + return ret + +SBP_MSG_FWD = 0x0402 +class MsgFwd(SBP): + """SBP class for message MSG_FWD (0x0402). + + You can have MSG_FWD inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message provides the ability to forward messages over SBP. This may take the form +of wrapping up SBP messages received by Piksi for logging purposes or wrapping +another protocol with SBP. + +The source identifier indicates from what interface a forwarded stream derived. +The protocol identifier identifies what the expected protocol the forwarded msg contains. +Protocol 0 represents SBP and the remaining values are implementation defined. + + + """ + __slots__ = ['source', + 'protocol', + 'fwd_payload', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__source, offset, length) = get_u8(buf, offset, length) + ret['source'] = __source + (__protocol, offset, length) = get_u8(buf, offset, length) + ret['protocol'] = __protocol + (__fwd_payload, offset, length) = get_string(buf, offset, length) + ret['fwd_payload'] = __fwd_payload + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.source = res['source'] + self.protocol = res['protocol'] + self.fwd_payload = res['fwd_payload'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # source: u8 + ret += 1 + # protocol: u8 + ret += 1 + # fwd_payload: string + ret += 247 + return ret + +SBP_MSG_PRINT_DEP = 0x0010 +class MsgPrintDep(SBP): + """SBP class for message MSG_PRINT_DEP (0x0010). + + You can have MSG_PRINT_DEP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['text', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__text, offset, length) = get_string(buf, offset, length) + ret['text'] = __text + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.text = res['text'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # text: string + ret += 247 + return ret + + +msg_classes = { + 0x0401: MsgLog, + 0x0402: MsgFwd, + 0x0010: MsgPrintDep, +} \ No newline at end of file diff --git a/python/sbp/jit/mag.py b/python/sbp/jit/mag.py new file mode 100644 index 0000000000..419a018851 --- /dev/null +++ b/python/sbp/jit/mag.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Magnetometer (mag) messages. +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +# Automatically generated from piksi/yaml/swiftnav/sbp/mag.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_MAG_RAW = 0x0902 +class MsgMagRaw(SBP): + """SBP class for message MSG_MAG_RAW (0x0902). + + You can have MSG_MAG_RAW inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Raw data from the magnetometer. + + + """ + __slots__ = ['tow', + 'tow_f', + 'mag_x', + 'mag_y', + 'mag_z', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__tow_f, offset, length) = get_u8(buf, offset, length) + ret['tow_f'] = __tow_f + (__mag_x, offset, length) = get_s16(buf, offset, length) + ret['mag_x'] = __mag_x + (__mag_y, offset, length) = get_s16(buf, offset, length) + ret['mag_y'] = __mag_y + (__mag_z, offset, length) = get_s16(buf, offset, length) + ret['mag_z'] = __mag_z + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.tow_f = res['tow_f'] + self.mag_x = res['mag_x'] + self.mag_y = res['mag_y'] + self.mag_z = res['mag_z'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # tow_f: u8 + ret += 1 + # mag_x: s16 + ret += 2 + # mag_y: s16 + ret += 2 + # mag_z: s16 + ret += 2 + return ret + + +msg_classes = { + 0x0902: MsgMagRaw, +} \ No newline at end of file diff --git a/python/sbp/jit/msg.py b/python/sbp/jit/msg.py new file mode 100644 index 0000000000..5f5a6053e0 --- /dev/null +++ b/python/sbp/jit/msg.py @@ -0,0 +1,342 @@ +#!/usr/bin/env python + +# Copyright (C) 2019 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + +from pybase64 import standard_b64encode + +import decimal as dec + +import numpy as np +import numba as nb + +import numba.cffi_support + +from sbp.msg import crc16jit +from sbp.msg import SENDER_ID as _SENDER_ID +from sbp.msg import SBP_PREAMBLE as _SBP_PREAMBLE + +from sbp.jit import parse_float +from sbp.jit import parse_float_c + + +numba.cffi_support.register_module(parse_float_c) + +_get_f32 = parse_float_c.lib.get_f32 +_get_f64 = parse_float_c.lib.get_f64 + +SENDER_ID = _SENDER_ID +SBP_PREAMBLE = _SBP_PREAMBLE + + +@nb.jit('Tuple((u1,u4,u4))(u1[:],u4,u4)', nopython=True, nogil=True) +def get_u8(buf, offset, length): + if length < 1: + return (0, offset, length) + return buf[offset], offset + 1, length - 1 + + +@nb.jit('Tuple((u2,u4,u4))(u1[:],u4,u4)', nopython=True, nogil=True) +def get_u16(buf, offset, length): + if length < 2: + return (0, offset, length) + msb = nb.u2(buf[offset + 1]) << 8 + lsb = nb.u2(buf[offset + 0]) << 0 + return msb | lsb, offset + 2, length - 2 + + +@nb.jit('Tuple((u4,u4,u4))(u1[:],u4,u4)', nopython=True, nogil=True) +def get_u32(buf, offset, length): + if length < 4: + return (0, offset, length) + a = nb.u4(buf[offset + 3]) << 24 + b = nb.u4(buf[offset + 2]) << 16 + c = nb.u4(buf[offset + 1]) << 8 + d = nb.u4(buf[offset + 0]) << 0 + return a | b | c | d, offset + 4, length - 4 + + +@nb.jit('Tuple((u8,u4,u4))(u1[:],u4,u4)', nopython=True, nogil=True) +def get_u64(buf, offset, length): + if length < 8: + return (0, offset, length) + a = nb.u8(buf[offset + 7]) << 54 + b = nb.u8(buf[offset + 6]) << 48 + c = nb.u8(buf[offset + 5]) << 40 + d = nb.u8(buf[offset + 4]) << 32 + e = nb.u8(buf[offset + 3]) << 24 + f = nb.u8(buf[offset + 2]) << 16 + g = nb.u8(buf[offset + 1]) << 8 + h = nb.u8(buf[offset + 0]) << 0 + return a | b | c | d | e | f | g | h, offset + 8, length - 8 + + +@nb.jit('Tuple((i1,u4,u4))(u1[:],u4,u4)', nopython=True, nogil=True) +def get_s8(buf, offset, length): + if length < 1: + return (0, offset, length) + return buf[offset], offset + 1, length - 1 + + +@nb.jit('Tuple((i2,u4,u4))(u1[:],u4,u4)', nopython=True, nogil=True) +def get_s16(buf, offset, length): + if length < 2: + return (0, offset, length) + msb = nb.i2(buf[offset + 1]) << 8 + lsb = nb.i2(buf[offset + 0]) << 0 + return msb | lsb, offset + 2, length - 2 + + +@nb.jit('Tuple((i4,u4,u4))(u1[:],u4,u4)', nopython=True, nogil=True) +def get_s32(buf, offset, length): + if length < 4: + return (0, offset, length) + a = nb.i4(buf[offset + 3]) << 24 + b = nb.i4(buf[offset + 2]) << 16 + c = nb.i4(buf[offset + 1]) << 8 + d = nb.i4(buf[offset + 0]) << 0 + return a | b | c | d, offset + 4, length - 4 + + +@nb.jit('Tuple((i8,u4,u4))(u1[:],u4,u4)', nopython=True, nogil=True) +def get_s64(buf, offset, length): + if length < 8: + return (0, offset, length) + a = nb.i8(buf[offset + 7]) << 54 + b = nb.i8(buf[offset + 6]) << 48 + c = nb.i8(buf[offset + 5]) << 40 + d = nb.i8(buf[offset + 4]) << 32 + e = nb.i8(buf[offset + 3]) << 24 + f = nb.i8(buf[offset + 2]) << 16 + g = nb.i8(buf[offset + 1]) << 8 + h = nb.i8(buf[offset + 0]) << 0 + return a | b | c | d | e | f | g | h, offset + 8, length - 8 + + +@nb.jit('Tuple((f4,u4,u4))(u1[:],u4,u4)', nopython=True, nogil=True) +def get_f32(buf, offset, length): + if length < 4: + return (0, offset, length) + res = _get_f32(buf[offset + 0], + buf[offset + 1], + buf[offset + 2], + buf[offset + 3]) + return res, offset + 4, length - 4 + + +@nb.jit('Tuple((f8,u4,u4))(u1[:],u4,u4)', nopython=True, nogil=True) +def get_f64(buf, offset, length): + if length < 8: + return (0, offset, length) + res = _get_f64(buf[offset + 0], + buf[offset + 1], + buf[offset + 2], + buf[offset + 3], + buf[offset + 4], + buf[offset + 5], + buf[offset + 6], + buf[offset + 7]) + return res, offset + 8, length - 8 + + +@nb.jit('Tuple((u1[:],u4,u4))(u1[:],u4,u4,b1)', nopython=True, nogil=True) +def _get_string(buf_in, offset, length, check_null): + buf_out = np.zeros(256, dtype=np.uint8) + i = nb.u4(0) + null_term = False + while i < length: + if check_null and buf_in[offset + i] == 0: + null_term = True + break + buf_out[i] = buf_in[offset + i] + i = nb.u4(i + nb.u4(1)) + if null_term: + return buf_out[:i], offset + i + 1, i + 1 + else: + return buf_out[:i], offset + i, i + + +def judicious_round(f): + # Let numpy's judicious rounding tell us the amount of digits we + # want as it seems to align with Haskell's output + d = dec.Decimal(np.format_float_positional(f, precision=None, unique=True, trim='0')) + # Round it using correct rounding strategy and return it as native float + # NOTE: Can't this be done already on libsbp side? + return float(round(dec.Decimal(float(f)), abs(d.as_tuple().exponent))) + + +def get_string(buf, offset, length): + buf, offset, length = _get_string(buf, offset, length, True) + return buf.tobytes().decode('ascii'), offset, length + + +def get_fixed_string(size): + def func(buf, offset_in, length): + if length < size: + return '', offset_in, length + buf, offset, length = _get_string(buf, offset_in, size, False) + return buf.tobytes().decode('ascii'), offset_in + size, length + return func + + +def get_setting(buf, offset, length): + buf, offset, length = _get_string(buf, offset, length, False) + return buf.tobytes().decode('ascii'), offset, length + + +def get_array(getter): + def func(buf, offset, length): + # TODO verify this function + arr = [] + while length > 0: + o_1, (res, offset, length) = offset, getter(buf, offset, length) + if o_1 == offset: + return arr, offset, length + arr.append(res) + return arr, offset, length + return func + + +def get_fixed_array(getter, count, el_size, nb_type=None): + def func(buf, offset, length): + offset_start = offset + total_size = count * el_size + if length < total_size: + return [], offset_start, length + arr = [] + while total_size > 0: + o_1, (res, offset, length) = offset, getter(buf, offset, length) + if o_1 == offset: + return [], offset_start, length + arr.append(judicious_round(nb_type(res)) if nb_type else res) + total_size -= el_size + return arr, offset, length + return func + + +class SBP(object): + """Swift Binary Protocol container. """ + + # Class variable for controlling the rounding. + # False: Only Python native float context will be used, this is faster + # but does not distuingish 32 and 64 bit floats. In practise this + # means that 32 bit float value reprentations will have higher + # precision than they actually have. + # True: Floating point values are handled internally as numpy.float32 and + # numpy.float64. This is slower but doesn't add arbitrary precision + # to the 32 bit values. In practise only 32 bit values are rounded + # as the effect of rounding 64 bit values is lost immediately when + # stored back to Python native float. + judicious_rounding = False + + __slots__ = ['preamble', + 'msg_type', + 'sender', + 'length', + 'payload', + 'crc'] + + def __init__(self, + msg_type=None, + sender=SENDER_ID, + length=None, + payload=None, + crc=None): + self.preamble = SBP_PREAMBLE + self.msg_type = msg_type + self.sender = sender + self.length = length + self.payload = payload + self.crc = crc + + def __eq__(self, other): + try: + if self is other: + return True + elif not isinstance(self, type(other)): + return False + elif self.__slots__ != other.__slots__: + return False + else: + return all(getattr(self, s) == getattr(other, s) + for s in self.__slots__) + except AttributeError: + return False + + @staticmethod + @nb.jit('Tuple((u4, u2, u2, u2, u2, b1))(u1[:], u4, u4)', + nopython=True, nogil=True) + def unpack_payload(buf, offset, length): + crc_fail = False + crc = 0 + payload_len = 0 + msg_type = 0 + sender = 0 + offset_start = offset + pkt_len = 0 + + preamble_len = 1 + if length < preamble_len: + return (pkt_len, payload_len, msg_type, sender, crc, crc_fail) + + preamble, offset, length = get_u8(buf, offset, length) + if preamble != SBP_PREAMBLE: + return (preamble_len, payload_len, msg_type, sender, crc, crc_fail) + + header_len = 5 + if length < header_len: + return (pkt_len, payload_len, msg_type, sender, crc, crc_fail) + + typ, offset, length = get_u16(buf, offset, length) + sender, offset, length = get_u16(buf, offset, length) + payload_len, offset, length = get_u8(buf, offset, length) + + if length < payload_len: + return (pkt_len, payload_len, msg_type, sender, crc, crc_fail) + + # Consume payload + offset += payload_len + length -= payload_len + + crc_len = 2 + if length < crc_len: + return (pkt_len, payload_len, msg_type, sender, crc, crc_fail) + + msg_type = typ + + crc, offset, length = get_u16(buf, offset, length) + buf_start = offset_start + 1 + buf_end = offset_start + 1 + (preamble_len + header_len - 1) + payload_len + + calc_crc = crc16jit(buf, buf_start, 0, buf_end - buf_start) + if calc_crc != crc: + crc_fail = True + + pkt_len = preamble_len + header_len + payload_len + crc_len + return (pkt_len, payload_len, msg_type, sender, crc, crc_fail) + + @classmethod + def parse_members(cls, buf, offset, length): + raise NotImplementedError() + + def _unpack_members(self, buf, offset, length): + raise NotImplementedError(self.msg_type) + + def unpack(self, payload, offset, length): + res, offset, length = self._unpack_members(payload, offset, length) + + res['preamble'] = self.preamble + res['msg_type'] = self.msg_type + res['sender'] = self.sender + if self.payload is not None: + res['payload'] = standard_b64encode(self.payload.tobytes()).decode('ascii') + res['crc'] = self.crc + res['length'] = self.length + return res, offset, length diff --git a/python/sbp/jit/navigation.py b/python/sbp/jit/navigation.py new file mode 100644 index 0000000000..d88fd3968d --- /dev/null +++ b/python/sbp/jit/navigation.py @@ -0,0 +1,2028 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Geodetic navigation messages reporting GPS time, position, velocity, +and baseline position solutions. For position solutions, these +messages define several different position solutions: single-point +(SPP), RTK, and pseudo-absolute position solutions. + +The SPP is the standalone, absolute GPS position solution using only +a single receiver. The RTK solution is the differential GPS +solution, which can use either a fixed/integer or floating carrier +phase ambiguity. The pseudo-absolute position solution uses a +user-provided, well-surveyed base station position (if available) +and the RTK solution in tandem. + +When the inertial navigation mode indicates that the IMU is used, +all messages are reported in the vehicle body frame as defined by +device settings. By default, the vehicle body frame is configured to be +coincident with the antenna phase center. When there is no inertial +navigation, the solution will be reported at the phase center of the antenna. +There is no inertial navigation capability on Piksi Multi or Duro. + +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +# Automatically generated from piksi/yaml/swiftnav/sbp/navigation.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_GPS_TIME = 0x0102 +class MsgGPSTime(SBP): + """SBP class for message MSG_GPS_TIME (0x0102). + + You can have MSG_GPS_TIME inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the GPS time, representing the time since +the GPS epoch began on midnight January 6, 1980 UTC. GPS time +counts the weeks and seconds of the week. The weeks begin at the +Saturday/Sunday transition. GPS week 0 began at the beginning of +the GPS time scale. + +Within each week number, the GPS time of the week is between +between 0 and 604800 seconds (=60*60*24*7). Note that GPS time +does not accumulate leap seconds, and as of now, has a small +offset from UTC. In a message stream, this message precedes a +set of other navigation messages referenced to the same time +(but lacking the ns field) and indicates a more precise time of +these messages. + + + """ + __slots__ = ['wn', + 'tow', + 'ns_residual', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__wn, offset, length) = get_u16(buf, offset, length) + ret['wn'] = __wn + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__ns_residual, offset, length) = get_s32(buf, offset, length) + ret['ns_residual'] = __ns_residual + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.wn = res['wn'] + self.tow = res['tow'] + self.ns_residual = res['ns_residual'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # wn: u16 + ret += 2 + # tow: u32 + ret += 4 + # ns_residual: s32 + ret += 4 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_UTC_TIME = 0x0103 +class MsgUtcTime(SBP): + """SBP class for message MSG_UTC_TIME (0x0103). + + You can have MSG_UTC_TIME inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the Universal Coordinated Time (UTC). Note the flags +which indicate the source of the UTC offset value and source of the time fix. + + + """ + __slots__ = ['flags', + 'tow', + 'year', + 'month', + 'day', + 'hours', + 'minutes', + 'seconds', + 'ns', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__year, offset, length) = get_u16(buf, offset, length) + ret['year'] = __year + (__month, offset, length) = get_u8(buf, offset, length) + ret['month'] = __month + (__day, offset, length) = get_u8(buf, offset, length) + ret['day'] = __day + (__hours, offset, length) = get_u8(buf, offset, length) + ret['hours'] = __hours + (__minutes, offset, length) = get_u8(buf, offset, length) + ret['minutes'] = __minutes + (__seconds, offset, length) = get_u8(buf, offset, length) + ret['seconds'] = __seconds + (__ns, offset, length) = get_u32(buf, offset, length) + ret['ns'] = __ns + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.flags = res['flags'] + self.tow = res['tow'] + self.year = res['year'] + self.month = res['month'] + self.day = res['day'] + self.hours = res['hours'] + self.minutes = res['minutes'] + self.seconds = res['seconds'] + self.ns = res['ns'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # flags: u8 + ret += 1 + # tow: u32 + ret += 4 + # year: u16 + ret += 2 + # month: u8 + ret += 1 + # day: u8 + ret += 1 + # hours: u8 + ret += 1 + # minutes: u8 + ret += 1 + # seconds: u8 + ret += 1 + # ns: u32 + ret += 4 + return ret + +SBP_MSG_DOPS = 0x0208 +class MsgDops(SBP): + """SBP class for message MSG_DOPS (0x0208). + + You can have MSG_DOPS inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This dilution of precision (DOP) message describes the effect of +navigation satellite geometry on positional measurement +precision. The flags field indicated whether the DOP reported +corresponds to differential or SPP solution. + + + """ + __slots__ = ['tow', + 'gdop', + 'pdop', + 'tdop', + 'hdop', + 'vdop', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__gdop, offset, length) = get_u16(buf, offset, length) + ret['gdop'] = __gdop + (__pdop, offset, length) = get_u16(buf, offset, length) + ret['pdop'] = __pdop + (__tdop, offset, length) = get_u16(buf, offset, length) + ret['tdop'] = __tdop + (__hdop, offset, length) = get_u16(buf, offset, length) + ret['hdop'] = __hdop + (__vdop, offset, length) = get_u16(buf, offset, length) + ret['vdop'] = __vdop + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.gdop = res['gdop'] + self.pdop = res['pdop'] + self.tdop = res['tdop'] + self.hdop = res['hdop'] + self.vdop = res['vdop'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # gdop: u16 + ret += 2 + # pdop: u16 + ret += 2 + # tdop: u16 + ret += 2 + # hdop: u16 + ret += 2 + # vdop: u16 + ret += 2 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_POS_ECEF = 0x0209 +class MsgPosECEF(SBP): + """SBP class for message MSG_POS_ECEF (0x0209). + + You can have MSG_POS_ECEF inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The position solution message reports absolute Earth Centered +Earth Fixed (ECEF) coordinates and the status (single point vs +pseudo-absolute RTK) of the position solution. If the rover +receiver knows the surveyed position of the base station and has +an RTK solution, this reports a pseudo-absolute position +solution using the base station position and the rover's RTK +baseline vector. The full GPS time is given by the preceding +MSG_GPS_TIME with the matching time-of-week (tow). + + + """ + __slots__ = ['tow', + 'x', + 'y', + 'z', + 'accuracy', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__x, offset, length) = get_f64(buf, offset, length) + ret['x'] = __x + (__y, offset, length) = get_f64(buf, offset, length) + ret['y'] = __y + (__z, offset, length) = get_f64(buf, offset, length) + ret['z'] = __z + (__accuracy, offset, length) = get_u16(buf, offset, length) + ret['accuracy'] = __accuracy + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.x = res['x'] + self.y = res['y'] + self.z = res['z'] + self.accuracy = res['accuracy'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # x: double + ret += 8 + # y: double + ret += 8 + # z: double + ret += 8 + # accuracy: u16 + ret += 2 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_POS_ECEF_COV = 0x0214 +class MsgPosECEFCov(SBP): + """SBP class for message MSG_POS_ECEF_COV (0x0214). + + You can have MSG_POS_ECEF_COV inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The position solution message reports absolute Earth Centered +Earth Fixed (ECEF) coordinates and the status (single point vs +pseudo-absolute RTK) of the position solution. The message also +reports the upper triangular portion of the 3x3 covariance matrix. +If the receiver knows the surveyed position of the base station and has +an RTK solution, this reports a pseudo-absolute position +solution using the base station position and the rover's RTK +baseline vector. The full GPS time is given by the preceding +MSG_GPS_TIME with the matching time-of-week (tow). + + + """ + __slots__ = ['tow', + 'x', + 'y', + 'z', + 'cov_x_x', + 'cov_x_y', + 'cov_x_z', + 'cov_y_y', + 'cov_y_z', + 'cov_z_z', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__x, offset, length) = get_f64(buf, offset, length) + ret['x'] = __x + (__y, offset, length) = get_f64(buf, offset, length) + ret['y'] = __y + (__z, offset, length) = get_f64(buf, offset, length) + ret['z'] = __z + (__cov_x_x, offset, length) = get_f32(buf, offset, length) + ret['cov_x_x'] = judicious_round(nb.f4(__cov_x_x)) if SBP.judicious_rounding else __cov_x_x + (__cov_x_y, offset, length) = get_f32(buf, offset, length) + ret['cov_x_y'] = judicious_round(nb.f4(__cov_x_y)) if SBP.judicious_rounding else __cov_x_y + (__cov_x_z, offset, length) = get_f32(buf, offset, length) + ret['cov_x_z'] = judicious_round(nb.f4(__cov_x_z)) if SBP.judicious_rounding else __cov_x_z + (__cov_y_y, offset, length) = get_f32(buf, offset, length) + ret['cov_y_y'] = judicious_round(nb.f4(__cov_y_y)) if SBP.judicious_rounding else __cov_y_y + (__cov_y_z, offset, length) = get_f32(buf, offset, length) + ret['cov_y_z'] = judicious_round(nb.f4(__cov_y_z)) if SBP.judicious_rounding else __cov_y_z + (__cov_z_z, offset, length) = get_f32(buf, offset, length) + ret['cov_z_z'] = judicious_round(nb.f4(__cov_z_z)) if SBP.judicious_rounding else __cov_z_z + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.x = res['x'] + self.y = res['y'] + self.z = res['z'] + self.cov_x_x = res['cov_x_x'] + self.cov_x_y = res['cov_x_y'] + self.cov_x_z = res['cov_x_z'] + self.cov_y_y = res['cov_y_y'] + self.cov_y_z = res['cov_y_z'] + self.cov_z_z = res['cov_z_z'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # x: double + ret += 8 + # y: double + ret += 8 + # z: double + ret += 8 + # cov_x_x: float + ret += 4 + # cov_x_y: float + ret += 4 + # cov_x_z: float + ret += 4 + # cov_y_y: float + ret += 4 + # cov_y_z: float + ret += 4 + # cov_z_z: float + ret += 4 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_POS_LLH = 0x020A +class MsgPosLLH(SBP): + """SBP class for message MSG_POS_LLH (0x020A). + + You can have MSG_POS_LLH inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This position solution message reports the absolute geodetic +coordinates and the status (single point vs pseudo-absolute RTK) +of the position solution. If the rover receiver knows the +surveyed position of the base station and has an RTK solution, +this reports a pseudo-absolute position solution using the base +station position and the rover's RTK baseline vector. The full +GPS time is given by the preceding MSG_GPS_TIME with the +matching time-of-week (tow). + + + """ + __slots__ = ['tow', + 'lat', + 'lon', + 'height', + 'h_accuracy', + 'v_accuracy', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__lat, offset, length) = get_f64(buf, offset, length) + ret['lat'] = __lat + (__lon, offset, length) = get_f64(buf, offset, length) + ret['lon'] = __lon + (__height, offset, length) = get_f64(buf, offset, length) + ret['height'] = __height + (__h_accuracy, offset, length) = get_u16(buf, offset, length) + ret['h_accuracy'] = __h_accuracy + (__v_accuracy, offset, length) = get_u16(buf, offset, length) + ret['v_accuracy'] = __v_accuracy + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.lat = res['lat'] + self.lon = res['lon'] + self.height = res['height'] + self.h_accuracy = res['h_accuracy'] + self.v_accuracy = res['v_accuracy'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # lat: double + ret += 8 + # lon: double + ret += 8 + # height: double + ret += 8 + # h_accuracy: u16 + ret += 2 + # v_accuracy: u16 + ret += 2 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_POS_LLH_COV = 0x0211 +class MsgPosLLHCov(SBP): + """SBP class for message MSG_POS_LLH_COV (0x0211). + + You can have MSG_POS_LLH_COV inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This position solution message reports the absolute geodetic +coordinates and the status (single point vs pseudo-absolute RTK) +of the position solution as well as the upper triangle of the 3x3 +covariance matrix. The position information and Fix Mode flags should +follow the MSG_POS_LLH message. Since the covariance matrix is computed +in the local-level North, East, Down frame, the covariance terms follow +with that convention. Thus, covariances are reported against the "downward" +measurement and care should be taken with the sign convention. + + + """ + __slots__ = ['tow', + 'lat', + 'lon', + 'height', + 'cov_n_n', + 'cov_n_e', + 'cov_n_d', + 'cov_e_e', + 'cov_e_d', + 'cov_d_d', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__lat, offset, length) = get_f64(buf, offset, length) + ret['lat'] = __lat + (__lon, offset, length) = get_f64(buf, offset, length) + ret['lon'] = __lon + (__height, offset, length) = get_f64(buf, offset, length) + ret['height'] = __height + (__cov_n_n, offset, length) = get_f32(buf, offset, length) + ret['cov_n_n'] = judicious_round(nb.f4(__cov_n_n)) if SBP.judicious_rounding else __cov_n_n + (__cov_n_e, offset, length) = get_f32(buf, offset, length) + ret['cov_n_e'] = judicious_round(nb.f4(__cov_n_e)) if SBP.judicious_rounding else __cov_n_e + (__cov_n_d, offset, length) = get_f32(buf, offset, length) + ret['cov_n_d'] = judicious_round(nb.f4(__cov_n_d)) if SBP.judicious_rounding else __cov_n_d + (__cov_e_e, offset, length) = get_f32(buf, offset, length) + ret['cov_e_e'] = judicious_round(nb.f4(__cov_e_e)) if SBP.judicious_rounding else __cov_e_e + (__cov_e_d, offset, length) = get_f32(buf, offset, length) + ret['cov_e_d'] = judicious_round(nb.f4(__cov_e_d)) if SBP.judicious_rounding else __cov_e_d + (__cov_d_d, offset, length) = get_f32(buf, offset, length) + ret['cov_d_d'] = judicious_round(nb.f4(__cov_d_d)) if SBP.judicious_rounding else __cov_d_d + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.lat = res['lat'] + self.lon = res['lon'] + self.height = res['height'] + self.cov_n_n = res['cov_n_n'] + self.cov_n_e = res['cov_n_e'] + self.cov_n_d = res['cov_n_d'] + self.cov_e_e = res['cov_e_e'] + self.cov_e_d = res['cov_e_d'] + self.cov_d_d = res['cov_d_d'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # lat: double + ret += 8 + # lon: double + ret += 8 + # height: double + ret += 8 + # cov_n_n: float + ret += 4 + # cov_n_e: float + ret += 4 + # cov_n_d: float + ret += 4 + # cov_e_e: float + ret += 4 + # cov_e_d: float + ret += 4 + # cov_d_d: float + ret += 4 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_BASELINE_ECEF = 0x020B +class MsgBaselineECEF(SBP): + """SBP class for message MSG_BASELINE_ECEF (0x020B). + + You can have MSG_BASELINE_ECEF inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the baseline solution in Earth Centered +Earth Fixed (ECEF) coordinates. This baseline is the relative +vector distance from the base station to the rover receiver. The +full GPS time is given by the preceding MSG_GPS_TIME with the +matching time-of-week (tow). + + + """ + __slots__ = ['tow', + 'x', + 'y', + 'z', + 'accuracy', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__x, offset, length) = get_s32(buf, offset, length) + ret['x'] = __x + (__y, offset, length) = get_s32(buf, offset, length) + ret['y'] = __y + (__z, offset, length) = get_s32(buf, offset, length) + ret['z'] = __z + (__accuracy, offset, length) = get_u16(buf, offset, length) + ret['accuracy'] = __accuracy + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.x = res['x'] + self.y = res['y'] + self.z = res['z'] + self.accuracy = res['accuracy'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # x: s32 + ret += 4 + # y: s32 + ret += 4 + # z: s32 + ret += 4 + # accuracy: u16 + ret += 2 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_BASELINE_NED = 0x020C +class MsgBaselineNED(SBP): + """SBP class for message MSG_BASELINE_NED (0x020C). + + You can have MSG_BASELINE_NED inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the baseline solution in North East Down +(NED) coordinates. This baseline is the relative vector distance +from the base station to the rover receiver, and NED coordinate +system is defined at the local WGS84 tangent plane centered at the +base station position. The full GPS time is given by the +preceding MSG_GPS_TIME with the matching time-of-week (tow). + + + """ + __slots__ = ['tow', + 'n', + 'e', + 'd', + 'h_accuracy', + 'v_accuracy', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__n, offset, length) = get_s32(buf, offset, length) + ret['n'] = __n + (__e, offset, length) = get_s32(buf, offset, length) + ret['e'] = __e + (__d, offset, length) = get_s32(buf, offset, length) + ret['d'] = __d + (__h_accuracy, offset, length) = get_u16(buf, offset, length) + ret['h_accuracy'] = __h_accuracy + (__v_accuracy, offset, length) = get_u16(buf, offset, length) + ret['v_accuracy'] = __v_accuracy + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.n = res['n'] + self.e = res['e'] + self.d = res['d'] + self.h_accuracy = res['h_accuracy'] + self.v_accuracy = res['v_accuracy'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # n: s32 + ret += 4 + # e: s32 + ret += 4 + # d: s32 + ret += 4 + # h_accuracy: u16 + ret += 2 + # v_accuracy: u16 + ret += 2 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_VEL_ECEF = 0x020D +class MsgVelECEF(SBP): + """SBP class for message MSG_VEL_ECEF (0x020D). + + You can have MSG_VEL_ECEF inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the velocity in Earth Centered Earth Fixed +(ECEF) coordinates. The full GPS time is given by the preceding +MSG_GPS_TIME with the matching time-of-week (tow). + + + """ + __slots__ = ['tow', + 'x', + 'y', + 'z', + 'accuracy', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__x, offset, length) = get_s32(buf, offset, length) + ret['x'] = __x + (__y, offset, length) = get_s32(buf, offset, length) + ret['y'] = __y + (__z, offset, length) = get_s32(buf, offset, length) + ret['z'] = __z + (__accuracy, offset, length) = get_u16(buf, offset, length) + ret['accuracy'] = __accuracy + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.x = res['x'] + self.y = res['y'] + self.z = res['z'] + self.accuracy = res['accuracy'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # x: s32 + ret += 4 + # y: s32 + ret += 4 + # z: s32 + ret += 4 + # accuracy: u16 + ret += 2 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_VEL_ECEF_COV = 0x0215 +class MsgVelECEFCov(SBP): + """SBP class for message MSG_VEL_ECEF_COV (0x0215). + + You can have MSG_VEL_ECEF_COV inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the velocity in Earth Centered Earth Fixed +(ECEF) coordinates. The full GPS time is given by the preceding +MSG_GPS_TIME with the matching time-of-week (tow). + + + """ + __slots__ = ['tow', + 'x', + 'y', + 'z', + 'cov_x_x', + 'cov_x_y', + 'cov_x_z', + 'cov_y_y', + 'cov_y_z', + 'cov_z_z', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__x, offset, length) = get_s32(buf, offset, length) + ret['x'] = __x + (__y, offset, length) = get_s32(buf, offset, length) + ret['y'] = __y + (__z, offset, length) = get_s32(buf, offset, length) + ret['z'] = __z + (__cov_x_x, offset, length) = get_f32(buf, offset, length) + ret['cov_x_x'] = judicious_round(nb.f4(__cov_x_x)) if SBP.judicious_rounding else __cov_x_x + (__cov_x_y, offset, length) = get_f32(buf, offset, length) + ret['cov_x_y'] = judicious_round(nb.f4(__cov_x_y)) if SBP.judicious_rounding else __cov_x_y + (__cov_x_z, offset, length) = get_f32(buf, offset, length) + ret['cov_x_z'] = judicious_round(nb.f4(__cov_x_z)) if SBP.judicious_rounding else __cov_x_z + (__cov_y_y, offset, length) = get_f32(buf, offset, length) + ret['cov_y_y'] = judicious_round(nb.f4(__cov_y_y)) if SBP.judicious_rounding else __cov_y_y + (__cov_y_z, offset, length) = get_f32(buf, offset, length) + ret['cov_y_z'] = judicious_round(nb.f4(__cov_y_z)) if SBP.judicious_rounding else __cov_y_z + (__cov_z_z, offset, length) = get_f32(buf, offset, length) + ret['cov_z_z'] = judicious_round(nb.f4(__cov_z_z)) if SBP.judicious_rounding else __cov_z_z + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.x = res['x'] + self.y = res['y'] + self.z = res['z'] + self.cov_x_x = res['cov_x_x'] + self.cov_x_y = res['cov_x_y'] + self.cov_x_z = res['cov_x_z'] + self.cov_y_y = res['cov_y_y'] + self.cov_y_z = res['cov_y_z'] + self.cov_z_z = res['cov_z_z'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # x: s32 + ret += 4 + # y: s32 + ret += 4 + # z: s32 + ret += 4 + # cov_x_x: float + ret += 4 + # cov_x_y: float + ret += 4 + # cov_x_z: float + ret += 4 + # cov_y_y: float + ret += 4 + # cov_y_z: float + ret += 4 + # cov_z_z: float + ret += 4 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_VEL_NED = 0x020E +class MsgVelNED(SBP): + """SBP class for message MSG_VEL_NED (0x020E). + + You can have MSG_VEL_NED inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the velocity in local North East Down (NED) +coordinates. The NED coordinate system is defined as the local WGS84 +tangent plane centered at the current position. The full GPS time is +given by the preceding MSG_GPS_TIME with the matching time-of-week (tow). + + + """ + __slots__ = ['tow', + 'n', + 'e', + 'd', + 'h_accuracy', + 'v_accuracy', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__n, offset, length) = get_s32(buf, offset, length) + ret['n'] = __n + (__e, offset, length) = get_s32(buf, offset, length) + ret['e'] = __e + (__d, offset, length) = get_s32(buf, offset, length) + ret['d'] = __d + (__h_accuracy, offset, length) = get_u16(buf, offset, length) + ret['h_accuracy'] = __h_accuracy + (__v_accuracy, offset, length) = get_u16(buf, offset, length) + ret['v_accuracy'] = __v_accuracy + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.n = res['n'] + self.e = res['e'] + self.d = res['d'] + self.h_accuracy = res['h_accuracy'] + self.v_accuracy = res['v_accuracy'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # n: s32 + ret += 4 + # e: s32 + ret += 4 + # d: s32 + ret += 4 + # h_accuracy: u16 + ret += 2 + # v_accuracy: u16 + ret += 2 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_VEL_NED_COV = 0x0212 +class MsgVelNEDCov(SBP): + """SBP class for message MSG_VEL_NED_COV (0x0212). + + You can have MSG_VEL_NED_COV inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the velocity in local North East Down (NED) +coordinates. The NED coordinate system is defined as the local WGS84 +tangent plane centered at the current position. The full GPS time is +given by the preceding MSG_GPS_TIME with the matching time-of-week (tow). +This message is similar to the MSG_VEL_NED, but it includes the upper triangular +portion of the 3x3 covariance matrix. + + + """ + __slots__ = ['tow', + 'n', + 'e', + 'd', + 'cov_n_n', + 'cov_n_e', + 'cov_n_d', + 'cov_e_e', + 'cov_e_d', + 'cov_d_d', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__n, offset, length) = get_s32(buf, offset, length) + ret['n'] = __n + (__e, offset, length) = get_s32(buf, offset, length) + ret['e'] = __e + (__d, offset, length) = get_s32(buf, offset, length) + ret['d'] = __d + (__cov_n_n, offset, length) = get_f32(buf, offset, length) + ret['cov_n_n'] = judicious_round(nb.f4(__cov_n_n)) if SBP.judicious_rounding else __cov_n_n + (__cov_n_e, offset, length) = get_f32(buf, offset, length) + ret['cov_n_e'] = judicious_round(nb.f4(__cov_n_e)) if SBP.judicious_rounding else __cov_n_e + (__cov_n_d, offset, length) = get_f32(buf, offset, length) + ret['cov_n_d'] = judicious_round(nb.f4(__cov_n_d)) if SBP.judicious_rounding else __cov_n_d + (__cov_e_e, offset, length) = get_f32(buf, offset, length) + ret['cov_e_e'] = judicious_round(nb.f4(__cov_e_e)) if SBP.judicious_rounding else __cov_e_e + (__cov_e_d, offset, length) = get_f32(buf, offset, length) + ret['cov_e_d'] = judicious_round(nb.f4(__cov_e_d)) if SBP.judicious_rounding else __cov_e_d + (__cov_d_d, offset, length) = get_f32(buf, offset, length) + ret['cov_d_d'] = judicious_round(nb.f4(__cov_d_d)) if SBP.judicious_rounding else __cov_d_d + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.n = res['n'] + self.e = res['e'] + self.d = res['d'] + self.cov_n_n = res['cov_n_n'] + self.cov_n_e = res['cov_n_e'] + self.cov_n_d = res['cov_n_d'] + self.cov_e_e = res['cov_e_e'] + self.cov_e_d = res['cov_e_d'] + self.cov_d_d = res['cov_d_d'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # n: s32 + ret += 4 + # e: s32 + ret += 4 + # d: s32 + ret += 4 + # cov_n_n: float + ret += 4 + # cov_n_e: float + ret += 4 + # cov_n_d: float + ret += 4 + # cov_e_e: float + ret += 4 + # cov_e_d: float + ret += 4 + # cov_d_d: float + ret += 4 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_VEL_BODY = 0x0213 +class MsgVelBody(SBP): + """SBP class for message MSG_VEL_BODY (0x0213). + + You can have MSG_VEL_BODY inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the velocity in the Vehicle Body Frame. By convention, +the x-axis should point out the nose of the vehicle and represent the forward +direction, while as the y-axis should point out the right hand side of the vehicle. +Since this is a right handed system, z should point out the bottom of the vehicle. +The orientation and origin of the Vehicle Body Frame are specified via the device settings. +The full GPS time is given by the preceding MSG_GPS_TIME with the +matching time-of-week (tow). This message is only produced by inertial versions of Swift +products and is not available from Piksi Multi or Duro. + + + """ + __slots__ = ['tow', + 'x', + 'y', + 'z', + 'cov_x_x', + 'cov_x_y', + 'cov_x_z', + 'cov_y_y', + 'cov_y_z', + 'cov_z_z', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__x, offset, length) = get_s32(buf, offset, length) + ret['x'] = __x + (__y, offset, length) = get_s32(buf, offset, length) + ret['y'] = __y + (__z, offset, length) = get_s32(buf, offset, length) + ret['z'] = __z + (__cov_x_x, offset, length) = get_f32(buf, offset, length) + ret['cov_x_x'] = judicious_round(nb.f4(__cov_x_x)) if SBP.judicious_rounding else __cov_x_x + (__cov_x_y, offset, length) = get_f32(buf, offset, length) + ret['cov_x_y'] = judicious_round(nb.f4(__cov_x_y)) if SBP.judicious_rounding else __cov_x_y + (__cov_x_z, offset, length) = get_f32(buf, offset, length) + ret['cov_x_z'] = judicious_round(nb.f4(__cov_x_z)) if SBP.judicious_rounding else __cov_x_z + (__cov_y_y, offset, length) = get_f32(buf, offset, length) + ret['cov_y_y'] = judicious_round(nb.f4(__cov_y_y)) if SBP.judicious_rounding else __cov_y_y + (__cov_y_z, offset, length) = get_f32(buf, offset, length) + ret['cov_y_z'] = judicious_round(nb.f4(__cov_y_z)) if SBP.judicious_rounding else __cov_y_z + (__cov_z_z, offset, length) = get_f32(buf, offset, length) + ret['cov_z_z'] = judicious_round(nb.f4(__cov_z_z)) if SBP.judicious_rounding else __cov_z_z + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.x = res['x'] + self.y = res['y'] + self.z = res['z'] + self.cov_x_x = res['cov_x_x'] + self.cov_x_y = res['cov_x_y'] + self.cov_x_z = res['cov_x_z'] + self.cov_y_y = res['cov_y_y'] + self.cov_y_z = res['cov_y_z'] + self.cov_z_z = res['cov_z_z'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # x: s32 + ret += 4 + # y: s32 + ret += 4 + # z: s32 + ret += 4 + # cov_x_x: float + ret += 4 + # cov_x_y: float + ret += 4 + # cov_x_z: float + ret += 4 + # cov_y_y: float + ret += 4 + # cov_y_z: float + ret += 4 + # cov_z_z: float + ret += 4 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_AGE_CORRECTIONS = 0x0210 +class MsgAgeCorrections(SBP): + """SBP class for message MSG_AGE_CORRECTIONS (0x0210). + + You can have MSG_AGE_CORRECTIONS inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the Age of the corrections used for the current +Differential solution + + + """ + __slots__ = ['tow', + 'age', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__age, offset, length) = get_u16(buf, offset, length) + ret['age'] = __age + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.age = res['age'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # age: u16 + ret += 2 + return ret + +SBP_MSG_GPS_TIME_DEP_A = 0x0100 +class MsgGPSTimeDepA(SBP): + """SBP class for message MSG_GPS_TIME_DEP_A (0x0100). + + You can have MSG_GPS_TIME_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the GPS time, representing the time since +the GPS epoch began on midnight January 6, 1980 UTC. GPS time +counts the weeks and seconds of the week. The weeks begin at the +Saturday/Sunday transition. GPS week 0 began at the beginning of +the GPS time scale. + +Within each week number, the GPS time of the week is between +between 0 and 604800 seconds (=60*60*24*7). Note that GPS time +does not accumulate leap seconds, and as of now, has a small +offset from UTC. In a message stream, this message precedes a +set of other navigation messages referenced to the same time +(but lacking the ns field) and indicates a more precise time of +these messages. + + + """ + __slots__ = ['wn', + 'tow', + 'ns_residual', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__wn, offset, length) = get_u16(buf, offset, length) + ret['wn'] = __wn + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__ns_residual, offset, length) = get_s32(buf, offset, length) + ret['ns_residual'] = __ns_residual + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.wn = res['wn'] + self.tow = res['tow'] + self.ns_residual = res['ns_residual'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # wn: u16 + ret += 2 + # tow: u32 + ret += 4 + # ns_residual: s32 + ret += 4 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_DOPS_DEP_A = 0x0206 +class MsgDopsDepA(SBP): + """SBP class for message MSG_DOPS_DEP_A (0x0206). + + You can have MSG_DOPS_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This dilution of precision (DOP) message describes the effect of +navigation satellite geometry on positional measurement +precision. + + + """ + __slots__ = ['tow', + 'gdop', + 'pdop', + 'tdop', + 'hdop', + 'vdop', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__gdop, offset, length) = get_u16(buf, offset, length) + ret['gdop'] = __gdop + (__pdop, offset, length) = get_u16(buf, offset, length) + ret['pdop'] = __pdop + (__tdop, offset, length) = get_u16(buf, offset, length) + ret['tdop'] = __tdop + (__hdop, offset, length) = get_u16(buf, offset, length) + ret['hdop'] = __hdop + (__vdop, offset, length) = get_u16(buf, offset, length) + ret['vdop'] = __vdop + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.gdop = res['gdop'] + self.pdop = res['pdop'] + self.tdop = res['tdop'] + self.hdop = res['hdop'] + self.vdop = res['vdop'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # gdop: u16 + ret += 2 + # pdop: u16 + ret += 2 + # tdop: u16 + ret += 2 + # hdop: u16 + ret += 2 + # vdop: u16 + ret += 2 + return ret + +SBP_MSG_POS_ECEF_DEP_A = 0x0200 +class MsgPosECEFDepA(SBP): + """SBP class for message MSG_POS_ECEF_DEP_A (0x0200). + + You can have MSG_POS_ECEF_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The position solution message reports absolute Earth Centered +Earth Fixed (ECEF) coordinates and the status (single point vs +pseudo-absolute RTK) of the position solution. If the rover +receiver knows the surveyed position of the base station and has +an RTK solution, this reports a pseudo-absolute position +solution using the base station position and the rover's RTK +baseline vector. The full GPS time is given by the preceding +MSG_GPS_TIME with the matching time-of-week (tow). + + + """ + __slots__ = ['tow', + 'x', + 'y', + 'z', + 'accuracy', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__x, offset, length) = get_f64(buf, offset, length) + ret['x'] = __x + (__y, offset, length) = get_f64(buf, offset, length) + ret['y'] = __y + (__z, offset, length) = get_f64(buf, offset, length) + ret['z'] = __z + (__accuracy, offset, length) = get_u16(buf, offset, length) + ret['accuracy'] = __accuracy + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.x = res['x'] + self.y = res['y'] + self.z = res['z'] + self.accuracy = res['accuracy'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # x: double + ret += 8 + # y: double + ret += 8 + # z: double + ret += 8 + # accuracy: u16 + ret += 2 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_POS_LLH_DEP_A = 0x0201 +class MsgPosLLHDepA(SBP): + """SBP class for message MSG_POS_LLH_DEP_A (0x0201). + + You can have MSG_POS_LLH_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This position solution message reports the absolute geodetic +coordinates and the status (single point vs pseudo-absolute RTK) +of the position solution. If the rover receiver knows the +surveyed position of the base station and has an RTK solution, +this reports a pseudo-absolute position solution using the base +station position and the rover's RTK baseline vector. The full +GPS time is given by the preceding MSG_GPS_TIME with the +matching time-of-week (tow). + + + """ + __slots__ = ['tow', + 'lat', + 'lon', + 'height', + 'h_accuracy', + 'v_accuracy', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__lat, offset, length) = get_f64(buf, offset, length) + ret['lat'] = __lat + (__lon, offset, length) = get_f64(buf, offset, length) + ret['lon'] = __lon + (__height, offset, length) = get_f64(buf, offset, length) + ret['height'] = __height + (__h_accuracy, offset, length) = get_u16(buf, offset, length) + ret['h_accuracy'] = __h_accuracy + (__v_accuracy, offset, length) = get_u16(buf, offset, length) + ret['v_accuracy'] = __v_accuracy + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.lat = res['lat'] + self.lon = res['lon'] + self.height = res['height'] + self.h_accuracy = res['h_accuracy'] + self.v_accuracy = res['v_accuracy'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # lat: double + ret += 8 + # lon: double + ret += 8 + # height: double + ret += 8 + # h_accuracy: u16 + ret += 2 + # v_accuracy: u16 + ret += 2 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_BASELINE_ECEF_DEP_A = 0x0202 +class MsgBaselineECEFDepA(SBP): + """SBP class for message MSG_BASELINE_ECEF_DEP_A (0x0202). + + You can have MSG_BASELINE_ECEF_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the baseline solution in Earth Centered +Earth Fixed (ECEF) coordinates. This baseline is the relative +vector distance from the base station to the rover receiver. The +full GPS time is given by the preceding MSG_GPS_TIME with the +matching time-of-week (tow). + + + """ + __slots__ = ['tow', + 'x', + 'y', + 'z', + 'accuracy', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__x, offset, length) = get_s32(buf, offset, length) + ret['x'] = __x + (__y, offset, length) = get_s32(buf, offset, length) + ret['y'] = __y + (__z, offset, length) = get_s32(buf, offset, length) + ret['z'] = __z + (__accuracy, offset, length) = get_u16(buf, offset, length) + ret['accuracy'] = __accuracy + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.x = res['x'] + self.y = res['y'] + self.z = res['z'] + self.accuracy = res['accuracy'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # x: s32 + ret += 4 + # y: s32 + ret += 4 + # z: s32 + ret += 4 + # accuracy: u16 + ret += 2 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_BASELINE_NED_DEP_A = 0x0203 +class MsgBaselineNEDDepA(SBP): + """SBP class for message MSG_BASELINE_NED_DEP_A (0x0203). + + You can have MSG_BASELINE_NED_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the baseline solution in North East Down +(NED) coordinates. This baseline is the relative vector distance +from the base station to the rover receiver, and NED coordinate +system is defined at the local WGS84 tangent plane centered at the +base station position. The full GPS time is given by the +preceding MSG_GPS_TIME with the matching time-of-week (tow). + + + """ + __slots__ = ['tow', + 'n', + 'e', + 'd', + 'h_accuracy', + 'v_accuracy', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__n, offset, length) = get_s32(buf, offset, length) + ret['n'] = __n + (__e, offset, length) = get_s32(buf, offset, length) + ret['e'] = __e + (__d, offset, length) = get_s32(buf, offset, length) + ret['d'] = __d + (__h_accuracy, offset, length) = get_u16(buf, offset, length) + ret['h_accuracy'] = __h_accuracy + (__v_accuracy, offset, length) = get_u16(buf, offset, length) + ret['v_accuracy'] = __v_accuracy + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.n = res['n'] + self.e = res['e'] + self.d = res['d'] + self.h_accuracy = res['h_accuracy'] + self.v_accuracy = res['v_accuracy'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # n: s32 + ret += 4 + # e: s32 + ret += 4 + # d: s32 + ret += 4 + # h_accuracy: u16 + ret += 2 + # v_accuracy: u16 + ret += 2 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_VEL_ECEF_DEP_A = 0x0204 +class MsgVelECEFDepA(SBP): + """SBP class for message MSG_VEL_ECEF_DEP_A (0x0204). + + You can have MSG_VEL_ECEF_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the velocity in Earth Centered Earth Fixed +(ECEF) coordinates. The full GPS time is given by the preceding +MSG_GPS_TIME with the matching time-of-week (tow). + + + """ + __slots__ = ['tow', + 'x', + 'y', + 'z', + 'accuracy', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__x, offset, length) = get_s32(buf, offset, length) + ret['x'] = __x + (__y, offset, length) = get_s32(buf, offset, length) + ret['y'] = __y + (__z, offset, length) = get_s32(buf, offset, length) + ret['z'] = __z + (__accuracy, offset, length) = get_u16(buf, offset, length) + ret['accuracy'] = __accuracy + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.x = res['x'] + self.y = res['y'] + self.z = res['z'] + self.accuracy = res['accuracy'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # x: s32 + ret += 4 + # y: s32 + ret += 4 + # z: s32 + ret += 4 + # accuracy: u16 + ret += 2 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_VEL_NED_DEP_A = 0x0205 +class MsgVelNEDDepA(SBP): + """SBP class for message MSG_VEL_NED_DEP_A (0x0205). + + You can have MSG_VEL_NED_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the velocity in local North East Down (NED) +coordinates. The NED coordinate system is defined as the local WGS84 +tangent plane centered at the current position. The full GPS time is +given by the preceding MSG_GPS_TIME with the matching time-of-week (tow). + + + """ + __slots__ = ['tow', + 'n', + 'e', + 'd', + 'h_accuracy', + 'v_accuracy', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__n, offset, length) = get_s32(buf, offset, length) + ret['n'] = __n + (__e, offset, length) = get_s32(buf, offset, length) + ret['e'] = __e + (__d, offset, length) = get_s32(buf, offset, length) + ret['d'] = __d + (__h_accuracy, offset, length) = get_u16(buf, offset, length) + ret['h_accuracy'] = __h_accuracy + (__v_accuracy, offset, length) = get_u16(buf, offset, length) + ret['v_accuracy'] = __v_accuracy + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.n = res['n'] + self.e = res['e'] + self.d = res['d'] + self.h_accuracy = res['h_accuracy'] + self.v_accuracy = res['v_accuracy'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # n: s32 + ret += 4 + # e: s32 + ret += 4 + # d: s32 + ret += 4 + # h_accuracy: u16 + ret += 2 + # v_accuracy: u16 + ret += 2 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_BASELINE_HEADING_DEP_A = 0x0207 +class MsgBaselineHeadingDepA(SBP): + """SBP class for message MSG_BASELINE_HEADING_DEP_A (0x0207). + + You can have MSG_BASELINE_HEADING_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the baseline heading pointing from the base station +to the rover relative to True North. The full GPS time is given by the +preceding MSG_GPS_TIME with the matching time-of-week (tow). + + + """ + __slots__ = ['tow', + 'heading', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__heading, offset, length) = get_u32(buf, offset, length) + ret['heading'] = __heading + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.heading = res['heading'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # heading: u32 + ret += 4 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + + +msg_classes = { + 0x0102: MsgGPSTime, + 0x0103: MsgUtcTime, + 0x0208: MsgDops, + 0x0209: MsgPosECEF, + 0x0214: MsgPosECEFCov, + 0x020A: MsgPosLLH, + 0x0211: MsgPosLLHCov, + 0x020B: MsgBaselineECEF, + 0x020C: MsgBaselineNED, + 0x020D: MsgVelECEF, + 0x0215: MsgVelECEFCov, + 0x020E: MsgVelNED, + 0x0212: MsgVelNEDCov, + 0x0213: MsgVelBody, + 0x0210: MsgAgeCorrections, + 0x0100: MsgGPSTimeDepA, + 0x0206: MsgDopsDepA, + 0x0200: MsgPosECEFDepA, + 0x0201: MsgPosLLHDepA, + 0x0202: MsgBaselineECEFDepA, + 0x0203: MsgBaselineNEDDepA, + 0x0204: MsgVelECEFDepA, + 0x0205: MsgVelNEDDepA, + 0x0207: MsgBaselineHeadingDepA, +} \ No newline at end of file diff --git a/python/sbp/jit/ndb.py b/python/sbp/jit/ndb.py new file mode 100644 index 0000000000..e10f3290ef --- /dev/null +++ b/python/sbp/jit/ndb.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Messages for logging NDB events. + +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array +from sbp.jit.gnss import * + +# Automatically generated from piksi/yaml/swiftnav/sbp/ndb.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_NDB_EVENT = 0x0400 +class MsgNdbEvent(SBP): + """SBP class for message MSG_NDB_EVENT (0x0400). + + You can have MSG_NDB_EVENT inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message is sent out when an object is stored into NDB. If needed +message could also be sent out when fetching an object from NDB. + + + """ + __slots__ = ['recv_time', + 'event', + 'object_type', + 'result', + 'data_source', + 'object_sid', + 'src_sid', + 'original_sender', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__recv_time, offset, length) = get_u64(buf, offset, length) + ret['recv_time'] = __recv_time + (__event, offset, length) = get_u8(buf, offset, length) + ret['event'] = __event + (__object_type, offset, length) = get_u8(buf, offset, length) + ret['object_type'] = __object_type + (__result, offset, length) = get_u8(buf, offset, length) + ret['result'] = __result + (__data_source, offset, length) = get_u8(buf, offset, length) + ret['data_source'] = __data_source + (__object_sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['object_sid'] = __object_sid + (__src_sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['src_sid'] = __src_sid + (__original_sender, offset, length) = get_u16(buf, offset, length) + ret['original_sender'] = __original_sender + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.recv_time = res['recv_time'] + self.event = res['event'] + self.object_type = res['object_type'] + self.result = res['result'] + self.data_source = res['data_source'] + self.object_sid = res['object_sid'] + self.src_sid = res['src_sid'] + self.original_sender = res['original_sender'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # recv_time: u64 + ret += 8 + # event: u8 + ret += 1 + # object_type: u8 + ret += 1 + # result: u8 + ret += 1 + # data_source: u8 + ret += 1 + # object_sid: GnssSignal + ret += GnssSignal._payload_size() + # src_sid: GnssSignal + ret += GnssSignal._payload_size() + # original_sender: u16 + ret += 2 + return ret + + +msg_classes = { + 0x0400: MsgNdbEvent, +} \ No newline at end of file diff --git a/python/sbp/jit/observation.py b/python/sbp/jit/observation.py new file mode 100644 index 0000000000..89494748c9 --- /dev/null +++ b/python/sbp/jit/observation.py @@ -0,0 +1,4440 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Satellite observation messages from the device. +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array +from sbp.jit.gnss import * + +# Automatically generated from piksi/yaml/swiftnav/sbp/observation.yaml with generate.py. +# Please do not hand edit! +class ObservationHeader(object): + """SBP class for message ObservationHeader + + You can have ObservationHeader inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Header of a GNSS observation message. + + """ + __slots__ = ['t', + 'n_obs', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__t, offset, length) = GPSTime.parse_members(buf, offset, length) + ret['t'] = __t + (__n_obs, offset, length) = get_u8(buf, offset, length) + ret['n_obs'] = __n_obs + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.t = res['t'] + self.n_obs = res['n_obs'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # t: GPSTime + ret += GPSTime._payload_size() + # n_obs: u8 + ret += 1 + return ret + +class Doppler(object): + """SBP class for message Doppler + + You can have Doppler inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Doppler measurement in Hz represented as a 24-bit +fixed point number with Q16.8 layout, i.e. 16-bits of whole +doppler and 8-bits of fractional doppler. This doppler is defined +as positive for approaching satellites. + + + """ + __slots__ = ['i', + 'f', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__i, offset, length) = get_s16(buf, offset, length) + ret['i'] = __i + (__f, offset, length) = get_u8(buf, offset, length) + ret['f'] = __f + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.i = res['i'] + self.f = res['f'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # i: s16 + ret += 2 + # f: u8 + ret += 1 + return ret + +class PackedObsContent(object): + """SBP class for message PackedObsContent + + You can have PackedObsContent inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Pseudorange and carrier phase observation for a satellite being tracked. +The observations are interoperable with 3rd party receivers and conform with +typical RTCM 3.1 message GPS/GLO observations. + +Carrier phase observations are not guaranteed to be aligned to the RINEX 3 +or RTCM 3.3 MSM reference signal and no 1/4 cycle adjustments are currently +peformed. + + + """ + __slots__ = ['P', + 'L', + 'D', + 'cn0', + 'lock', + 'flags', + 'sid', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__P, offset, length) = get_u32(buf, offset, length) + ret['P'] = __P + (__L, offset, length) = CarrierPhase.parse_members(buf, offset, length) + ret['L'] = __L + (__D, offset, length) = Doppler.parse_members(buf, offset, length) + ret['D'] = __D + (__cn0, offset, length) = get_u8(buf, offset, length) + ret['cn0'] = __cn0 + (__lock, offset, length) = get_u8(buf, offset, length) + ret['lock'] = __lock + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.P = res['P'] + self.L = res['L'] + self.D = res['D'] + self.cn0 = res['cn0'] + self.lock = res['lock'] + self.flags = res['flags'] + self.sid = res['sid'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # P: u32 + ret += 4 + # L: CarrierPhase + ret += CarrierPhase._payload_size() + # D: Doppler + ret += Doppler._payload_size() + # cn0: u8 + ret += 1 + # lock: u8 + ret += 1 + # flags: u8 + ret += 1 + # sid: GnssSignal + ret += GnssSignal._payload_size() + return ret + +class PackedOsrContent(object): + """SBP class for message PackedOsrContent + + You can have PackedOsrContent inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Pseudorange and carrier phase network corrections for a satellite signal. + + + """ + __slots__ = ['P', + 'L', + 'lock', + 'flags', + 'sid', + 'iono_std', + 'tropo_std', + 'range_std', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__P, offset, length) = get_u32(buf, offset, length) + ret['P'] = __P + (__L, offset, length) = CarrierPhase.parse_members(buf, offset, length) + ret['L'] = __L + (__lock, offset, length) = get_u8(buf, offset, length) + ret['lock'] = __lock + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__iono_std, offset, length) = get_u16(buf, offset, length) + ret['iono_std'] = __iono_std + (__tropo_std, offset, length) = get_u16(buf, offset, length) + ret['tropo_std'] = __tropo_std + (__range_std, offset, length) = get_u16(buf, offset, length) + ret['range_std'] = __range_std + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.P = res['P'] + self.L = res['L'] + self.lock = res['lock'] + self.flags = res['flags'] + self.sid = res['sid'] + self.iono_std = res['iono_std'] + self.tropo_std = res['tropo_std'] + self.range_std = res['range_std'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # P: u32 + ret += 4 + # L: CarrierPhase + ret += CarrierPhase._payload_size() + # lock: u8 + ret += 1 + # flags: u8 + ret += 1 + # sid: GnssSignal + ret += GnssSignal._payload_size() + # iono_std: u16 + ret += 2 + # tropo_std: u16 + ret += 2 + # range_std: u16 + ret += 2 + return ret + +SBP_MSG_OBS = 0x004A +class MsgObs(SBP): + """SBP class for message MSG_OBS (0x004A). + + You can have MSG_OBS inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The GPS observations message reports all the raw pseudorange and +carrier phase observations for the satellites being tracked by +the device. Carrier phase observation here is represented as a +40-bit fixed point number with Q32.8 layout (i.e. 32-bits of +whole cycles and 8-bits of fractional cycles). The observations +are be interoperable with 3rd party receivers and conform +with typical RTCMv3 GNSS observations. + + + """ + __slots__ = ['header', + 'obs', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__header, offset, length) = ObservationHeader.parse_members(buf, offset, length) + ret['header'] = __header + (__obs, offset, length) = get_array(PackedObsContent.parse_members)(buf, offset, length) + ret['obs'] = __obs + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.header = res['header'] + self.obs = res['obs'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # header: ObservationHeader + ret += ObservationHeader._payload_size() + # obs: array of PackedObsContent + ret += 247 + return ret + +SBP_MSG_BASE_POS_LLH = 0x0044 +class MsgBasePosLLH(SBP): + """SBP class for message MSG_BASE_POS_LLH (0x0044). + + You can have MSG_BASE_POS_LLH inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The base station position message is the position reported by +the base station itself. It is used for pseudo-absolute RTK +positioning, and is required to be a high-accuracy surveyed +location of the base station. Any error here will result in an +error in the pseudo-absolute position output. + + + """ + __slots__ = ['lat', + 'lon', + 'height', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__lat, offset, length) = get_f64(buf, offset, length) + ret['lat'] = __lat + (__lon, offset, length) = get_f64(buf, offset, length) + ret['lon'] = __lon + (__height, offset, length) = get_f64(buf, offset, length) + ret['height'] = __height + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.lat = res['lat'] + self.lon = res['lon'] + self.height = res['height'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # lat: double + ret += 8 + # lon: double + ret += 8 + # height: double + ret += 8 + return ret + +SBP_MSG_BASE_POS_ECEF = 0x0048 +class MsgBasePosECEF(SBP): + """SBP class for message MSG_BASE_POS_ECEF (0x0048). + + You can have MSG_BASE_POS_ECEF inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The base station position message is the position reported by +the base station itself in absolute Earth Centered Earth Fixed +coordinates. It is used for pseudo-absolute RTK positioning, and +is required to be a high-accuracy surveyed location of the base +station. Any error here will result in an error in the +pseudo-absolute position output. + + + """ + __slots__ = ['x', + 'y', + 'z', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__x, offset, length) = get_f64(buf, offset, length) + ret['x'] = __x + (__y, offset, length) = get_f64(buf, offset, length) + ret['y'] = __y + (__z, offset, length) = get_f64(buf, offset, length) + ret['z'] = __z + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.x = res['x'] + self.y = res['y'] + self.z = res['z'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # x: double + ret += 8 + # y: double + ret += 8 + # z: double + ret += 8 + return ret + +class EphemerisCommonContent(object): + """SBP class for message EphemerisCommonContent + + You can have EphemerisCommonContent inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + + """ + __slots__ = ['sid', + 'toe', + 'ura', + 'fit_interval', + 'valid', + 'health_bits', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__toe, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['toe'] = __toe + (__ura, offset, length) = get_f32(buf, offset, length) + ret['ura'] = judicious_round(nb.f4(__ura)) if SBP.judicious_rounding else __ura + (__fit_interval, offset, length) = get_u32(buf, offset, length) + ret['fit_interval'] = __fit_interval + (__valid, offset, length) = get_u8(buf, offset, length) + ret['valid'] = __valid + (__health_bits, offset, length) = get_u8(buf, offset, length) + ret['health_bits'] = __health_bits + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sid = res['sid'] + self.toe = res['toe'] + self.ura = res['ura'] + self.fit_interval = res['fit_interval'] + self.valid = res['valid'] + self.health_bits = res['health_bits'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sid: GnssSignal + ret += GnssSignal._payload_size() + # toe: GPSTimeSec + ret += GPSTimeSec._payload_size() + # ura: float + ret += 4 + # fit_interval: u32 + ret += 4 + # valid: u8 + ret += 1 + # health_bits: u8 + ret += 1 + return ret + +class EphemerisCommonContentDepB(object): + """SBP class for message EphemerisCommonContentDepB + + You can have EphemerisCommonContentDepB inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + + """ + __slots__ = ['sid', + 'toe', + 'ura', + 'fit_interval', + 'valid', + 'health_bits', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__toe, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['toe'] = __toe + (__ura, offset, length) = get_f64(buf, offset, length) + ret['ura'] = __ura + (__fit_interval, offset, length) = get_u32(buf, offset, length) + ret['fit_interval'] = __fit_interval + (__valid, offset, length) = get_u8(buf, offset, length) + ret['valid'] = __valid + (__health_bits, offset, length) = get_u8(buf, offset, length) + ret['health_bits'] = __health_bits + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sid = res['sid'] + self.toe = res['toe'] + self.ura = res['ura'] + self.fit_interval = res['fit_interval'] + self.valid = res['valid'] + self.health_bits = res['health_bits'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sid: GnssSignal + ret += GnssSignal._payload_size() + # toe: GPSTimeSec + ret += GPSTimeSec._payload_size() + # ura: double + ret += 8 + # fit_interval: u32 + ret += 4 + # valid: u8 + ret += 1 + # health_bits: u8 + ret += 1 + return ret + +class EphemerisCommonContentDepA(object): + """SBP class for message EphemerisCommonContentDepA + + You can have EphemerisCommonContentDepA inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + + """ + __slots__ = ['sid', + 'toe', + 'ura', + 'fit_interval', + 'valid', + 'health_bits', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sid, offset, length) = GnssSignalDep.parse_members(buf, offset, length) + ret['sid'] = __sid + (__toe, offset, length) = GPSTimeDep.parse_members(buf, offset, length) + ret['toe'] = __toe + (__ura, offset, length) = get_f64(buf, offset, length) + ret['ura'] = __ura + (__fit_interval, offset, length) = get_u32(buf, offset, length) + ret['fit_interval'] = __fit_interval + (__valid, offset, length) = get_u8(buf, offset, length) + ret['valid'] = __valid + (__health_bits, offset, length) = get_u8(buf, offset, length) + ret['health_bits'] = __health_bits + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sid = res['sid'] + self.toe = res['toe'] + self.ura = res['ura'] + self.fit_interval = res['fit_interval'] + self.valid = res['valid'] + self.health_bits = res['health_bits'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sid: GnssSignalDep + ret += GnssSignalDep._payload_size() + # toe: GPSTimeDep + ret += GPSTimeDep._payload_size() + # ura: double + ret += 8 + # fit_interval: u32 + ret += 4 + # valid: u8 + ret += 1 + # health_bits: u8 + ret += 1 + return ret + +SBP_MSG_EPHEMERIS_GPS_DEP_E = 0x0081 +class MsgEphemerisGPSDepE(SBP): + """SBP class for message MSG_EPHEMERIS_GPS_DEP_E (0x0081). + + You can have MSG_EPHEMERIS_GPS_DEP_E inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The ephemeris message returns a set of satellite orbit +parameters that is used to calculate GPS satellite position, +velocity, and clock offset. Please see the Navstar GPS +Space Segment/Navigation user interfaces (ICD-GPS-200, Table +20-III) for more details. + + + """ + __slots__ = ['common', + 'tgd', + 'c_rs', + 'c_rc', + 'c_uc', + 'c_us', + 'c_ic', + 'c_is', + 'dn', + 'm0', + 'ecc', + 'sqrta', + 'omega0', + 'omegadot', + 'w', + 'inc', + 'inc_dot', + 'af0', + 'af1', + 'af2', + 'toc', + 'iode', + 'iodc', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = EphemerisCommonContentDepA.parse_members(buf, offset, length) + ret['common'] = __common + (__tgd, offset, length) = get_f64(buf, offset, length) + ret['tgd'] = __tgd + (__c_rs, offset, length) = get_f64(buf, offset, length) + ret['c_rs'] = __c_rs + (__c_rc, offset, length) = get_f64(buf, offset, length) + ret['c_rc'] = __c_rc + (__c_uc, offset, length) = get_f64(buf, offset, length) + ret['c_uc'] = __c_uc + (__c_us, offset, length) = get_f64(buf, offset, length) + ret['c_us'] = __c_us + (__c_ic, offset, length) = get_f64(buf, offset, length) + ret['c_ic'] = __c_ic + (__c_is, offset, length) = get_f64(buf, offset, length) + ret['c_is'] = __c_is + (__dn, offset, length) = get_f64(buf, offset, length) + ret['dn'] = __dn + (__m0, offset, length) = get_f64(buf, offset, length) + ret['m0'] = __m0 + (__ecc, offset, length) = get_f64(buf, offset, length) + ret['ecc'] = __ecc + (__sqrta, offset, length) = get_f64(buf, offset, length) + ret['sqrta'] = __sqrta + (__omega0, offset, length) = get_f64(buf, offset, length) + ret['omega0'] = __omega0 + (__omegadot, offset, length) = get_f64(buf, offset, length) + ret['omegadot'] = __omegadot + (__w, offset, length) = get_f64(buf, offset, length) + ret['w'] = __w + (__inc, offset, length) = get_f64(buf, offset, length) + ret['inc'] = __inc + (__inc_dot, offset, length) = get_f64(buf, offset, length) + ret['inc_dot'] = __inc_dot + (__af0, offset, length) = get_f64(buf, offset, length) + ret['af0'] = __af0 + (__af1, offset, length) = get_f64(buf, offset, length) + ret['af1'] = __af1 + (__af2, offset, length) = get_f64(buf, offset, length) + ret['af2'] = __af2 + (__toc, offset, length) = GPSTimeDep.parse_members(buf, offset, length) + ret['toc'] = __toc + (__iode, offset, length) = get_u8(buf, offset, length) + ret['iode'] = __iode + (__iodc, offset, length) = get_u16(buf, offset, length) + ret['iodc'] = __iodc + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.tgd = res['tgd'] + self.c_rs = res['c_rs'] + self.c_rc = res['c_rc'] + self.c_uc = res['c_uc'] + self.c_us = res['c_us'] + self.c_ic = res['c_ic'] + self.c_is = res['c_is'] + self.dn = res['dn'] + self.m0 = res['m0'] + self.ecc = res['ecc'] + self.sqrta = res['sqrta'] + self.omega0 = res['omega0'] + self.omegadot = res['omegadot'] + self.w = res['w'] + self.inc = res['inc'] + self.inc_dot = res['inc_dot'] + self.af0 = res['af0'] + self.af1 = res['af1'] + self.af2 = res['af2'] + self.toc = res['toc'] + self.iode = res['iode'] + self.iodc = res['iodc'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: EphemerisCommonContentDepA + ret += EphemerisCommonContentDepA._payload_size() + # tgd: double + ret += 8 + # c_rs: double + ret += 8 + # c_rc: double + ret += 8 + # c_uc: double + ret += 8 + # c_us: double + ret += 8 + # c_ic: double + ret += 8 + # c_is: double + ret += 8 + # dn: double + ret += 8 + # m0: double + ret += 8 + # ecc: double + ret += 8 + # sqrta: double + ret += 8 + # omega0: double + ret += 8 + # omegadot: double + ret += 8 + # w: double + ret += 8 + # inc: double + ret += 8 + # inc_dot: double + ret += 8 + # af0: double + ret += 8 + # af1: double + ret += 8 + # af2: double + ret += 8 + # toc: GPSTimeDep + ret += GPSTimeDep._payload_size() + # iode: u8 + ret += 1 + # iodc: u16 + ret += 2 + return ret + +SBP_MSG_EPHEMERIS_GPS_DEP_F = 0x0086 +class MsgEphemerisGPSDepF(SBP): + """SBP class for message MSG_EPHEMERIS_GPS_DEP_F (0x0086). + + You can have MSG_EPHEMERIS_GPS_DEP_F inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This observation message has been deprecated in favor of +ephemeris message using floats for size reduction. + + + """ + __slots__ = ['common', + 'tgd', + 'c_rs', + 'c_rc', + 'c_uc', + 'c_us', + 'c_ic', + 'c_is', + 'dn', + 'm0', + 'ecc', + 'sqrta', + 'omega0', + 'omegadot', + 'w', + 'inc', + 'inc_dot', + 'af0', + 'af1', + 'af2', + 'toc', + 'iode', + 'iodc', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = EphemerisCommonContentDepB.parse_members(buf, offset, length) + ret['common'] = __common + (__tgd, offset, length) = get_f64(buf, offset, length) + ret['tgd'] = __tgd + (__c_rs, offset, length) = get_f64(buf, offset, length) + ret['c_rs'] = __c_rs + (__c_rc, offset, length) = get_f64(buf, offset, length) + ret['c_rc'] = __c_rc + (__c_uc, offset, length) = get_f64(buf, offset, length) + ret['c_uc'] = __c_uc + (__c_us, offset, length) = get_f64(buf, offset, length) + ret['c_us'] = __c_us + (__c_ic, offset, length) = get_f64(buf, offset, length) + ret['c_ic'] = __c_ic + (__c_is, offset, length) = get_f64(buf, offset, length) + ret['c_is'] = __c_is + (__dn, offset, length) = get_f64(buf, offset, length) + ret['dn'] = __dn + (__m0, offset, length) = get_f64(buf, offset, length) + ret['m0'] = __m0 + (__ecc, offset, length) = get_f64(buf, offset, length) + ret['ecc'] = __ecc + (__sqrta, offset, length) = get_f64(buf, offset, length) + ret['sqrta'] = __sqrta + (__omega0, offset, length) = get_f64(buf, offset, length) + ret['omega0'] = __omega0 + (__omegadot, offset, length) = get_f64(buf, offset, length) + ret['omegadot'] = __omegadot + (__w, offset, length) = get_f64(buf, offset, length) + ret['w'] = __w + (__inc, offset, length) = get_f64(buf, offset, length) + ret['inc'] = __inc + (__inc_dot, offset, length) = get_f64(buf, offset, length) + ret['inc_dot'] = __inc_dot + (__af0, offset, length) = get_f64(buf, offset, length) + ret['af0'] = __af0 + (__af1, offset, length) = get_f64(buf, offset, length) + ret['af1'] = __af1 + (__af2, offset, length) = get_f64(buf, offset, length) + ret['af2'] = __af2 + (__toc, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['toc'] = __toc + (__iode, offset, length) = get_u8(buf, offset, length) + ret['iode'] = __iode + (__iodc, offset, length) = get_u16(buf, offset, length) + ret['iodc'] = __iodc + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.tgd = res['tgd'] + self.c_rs = res['c_rs'] + self.c_rc = res['c_rc'] + self.c_uc = res['c_uc'] + self.c_us = res['c_us'] + self.c_ic = res['c_ic'] + self.c_is = res['c_is'] + self.dn = res['dn'] + self.m0 = res['m0'] + self.ecc = res['ecc'] + self.sqrta = res['sqrta'] + self.omega0 = res['omega0'] + self.omegadot = res['omegadot'] + self.w = res['w'] + self.inc = res['inc'] + self.inc_dot = res['inc_dot'] + self.af0 = res['af0'] + self.af1 = res['af1'] + self.af2 = res['af2'] + self.toc = res['toc'] + self.iode = res['iode'] + self.iodc = res['iodc'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: EphemerisCommonContentDepB + ret += EphemerisCommonContentDepB._payload_size() + # tgd: double + ret += 8 + # c_rs: double + ret += 8 + # c_rc: double + ret += 8 + # c_uc: double + ret += 8 + # c_us: double + ret += 8 + # c_ic: double + ret += 8 + # c_is: double + ret += 8 + # dn: double + ret += 8 + # m0: double + ret += 8 + # ecc: double + ret += 8 + # sqrta: double + ret += 8 + # omega0: double + ret += 8 + # omegadot: double + ret += 8 + # w: double + ret += 8 + # inc: double + ret += 8 + # inc_dot: double + ret += 8 + # af0: double + ret += 8 + # af1: double + ret += 8 + # af2: double + ret += 8 + # toc: GPSTimeSec + ret += GPSTimeSec._payload_size() + # iode: u8 + ret += 1 + # iodc: u16 + ret += 2 + return ret + +SBP_MSG_EPHEMERIS_GPS = 0x008A +class MsgEphemerisGPS(SBP): + """SBP class for message MSG_EPHEMERIS_GPS (0x008A). + + You can have MSG_EPHEMERIS_GPS inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The ephemeris message returns a set of satellite orbit +parameters that is used to calculate GPS satellite position, +velocity, and clock offset. Please see the Navstar GPS +Space Segment/Navigation user interfaces (ICD-GPS-200, Table +20-III) for more details. + + + """ + __slots__ = ['common', + 'tgd', + 'c_rs', + 'c_rc', + 'c_uc', + 'c_us', + 'c_ic', + 'c_is', + 'dn', + 'm0', + 'ecc', + 'sqrta', + 'omega0', + 'omegadot', + 'w', + 'inc', + 'inc_dot', + 'af0', + 'af1', + 'af2', + 'toc', + 'iode', + 'iodc', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = EphemerisCommonContent.parse_members(buf, offset, length) + ret['common'] = __common + (__tgd, offset, length) = get_f32(buf, offset, length) + ret['tgd'] = judicious_round(nb.f4(__tgd)) if SBP.judicious_rounding else __tgd + (__c_rs, offset, length) = get_f32(buf, offset, length) + ret['c_rs'] = judicious_round(nb.f4(__c_rs)) if SBP.judicious_rounding else __c_rs + (__c_rc, offset, length) = get_f32(buf, offset, length) + ret['c_rc'] = judicious_round(nb.f4(__c_rc)) if SBP.judicious_rounding else __c_rc + (__c_uc, offset, length) = get_f32(buf, offset, length) + ret['c_uc'] = judicious_round(nb.f4(__c_uc)) if SBP.judicious_rounding else __c_uc + (__c_us, offset, length) = get_f32(buf, offset, length) + ret['c_us'] = judicious_round(nb.f4(__c_us)) if SBP.judicious_rounding else __c_us + (__c_ic, offset, length) = get_f32(buf, offset, length) + ret['c_ic'] = judicious_round(nb.f4(__c_ic)) if SBP.judicious_rounding else __c_ic + (__c_is, offset, length) = get_f32(buf, offset, length) + ret['c_is'] = judicious_round(nb.f4(__c_is)) if SBP.judicious_rounding else __c_is + (__dn, offset, length) = get_f64(buf, offset, length) + ret['dn'] = __dn + (__m0, offset, length) = get_f64(buf, offset, length) + ret['m0'] = __m0 + (__ecc, offset, length) = get_f64(buf, offset, length) + ret['ecc'] = __ecc + (__sqrta, offset, length) = get_f64(buf, offset, length) + ret['sqrta'] = __sqrta + (__omega0, offset, length) = get_f64(buf, offset, length) + ret['omega0'] = __omega0 + (__omegadot, offset, length) = get_f64(buf, offset, length) + ret['omegadot'] = __omegadot + (__w, offset, length) = get_f64(buf, offset, length) + ret['w'] = __w + (__inc, offset, length) = get_f64(buf, offset, length) + ret['inc'] = __inc + (__inc_dot, offset, length) = get_f64(buf, offset, length) + ret['inc_dot'] = __inc_dot + (__af0, offset, length) = get_f32(buf, offset, length) + ret['af0'] = judicious_round(nb.f4(__af0)) if SBP.judicious_rounding else __af0 + (__af1, offset, length) = get_f32(buf, offset, length) + ret['af1'] = judicious_round(nb.f4(__af1)) if SBP.judicious_rounding else __af1 + (__af2, offset, length) = get_f32(buf, offset, length) + ret['af2'] = judicious_round(nb.f4(__af2)) if SBP.judicious_rounding else __af2 + (__toc, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['toc'] = __toc + (__iode, offset, length) = get_u8(buf, offset, length) + ret['iode'] = __iode + (__iodc, offset, length) = get_u16(buf, offset, length) + ret['iodc'] = __iodc + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.tgd = res['tgd'] + self.c_rs = res['c_rs'] + self.c_rc = res['c_rc'] + self.c_uc = res['c_uc'] + self.c_us = res['c_us'] + self.c_ic = res['c_ic'] + self.c_is = res['c_is'] + self.dn = res['dn'] + self.m0 = res['m0'] + self.ecc = res['ecc'] + self.sqrta = res['sqrta'] + self.omega0 = res['omega0'] + self.omegadot = res['omegadot'] + self.w = res['w'] + self.inc = res['inc'] + self.inc_dot = res['inc_dot'] + self.af0 = res['af0'] + self.af1 = res['af1'] + self.af2 = res['af2'] + self.toc = res['toc'] + self.iode = res['iode'] + self.iodc = res['iodc'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: EphemerisCommonContent + ret += EphemerisCommonContent._payload_size() + # tgd: float + ret += 4 + # c_rs: float + ret += 4 + # c_rc: float + ret += 4 + # c_uc: float + ret += 4 + # c_us: float + ret += 4 + # c_ic: float + ret += 4 + # c_is: float + ret += 4 + # dn: double + ret += 8 + # m0: double + ret += 8 + # ecc: double + ret += 8 + # sqrta: double + ret += 8 + # omega0: double + ret += 8 + # omegadot: double + ret += 8 + # w: double + ret += 8 + # inc: double + ret += 8 + # inc_dot: double + ret += 8 + # af0: float + ret += 4 + # af1: float + ret += 4 + # af2: float + ret += 4 + # toc: GPSTimeSec + ret += GPSTimeSec._payload_size() + # iode: u8 + ret += 1 + # iodc: u16 + ret += 2 + return ret + +SBP_MSG_EPHEMERIS_BDS = 0x0089 +class MsgEphemerisBds(SBP): + """SBP class for message MSG_EPHEMERIS_BDS (0x0089). + + You can have MSG_EPHEMERIS_BDS inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The ephemeris message returns a set of satellite orbit +parameters that is used to calculate BDS satellite position, +velocity, and clock offset. Please see the BeiDou Navigation +Satellite System SIS-ICD Version 2.1, Table 5-9 for more details. + + + """ + __slots__ = ['common', + 'tgd1', + 'tgd2', + 'c_rs', + 'c_rc', + 'c_uc', + 'c_us', + 'c_ic', + 'c_is', + 'dn', + 'm0', + 'ecc', + 'sqrta', + 'omega0', + 'omegadot', + 'w', + 'inc', + 'inc_dot', + 'af0', + 'af1', + 'af2', + 'toc', + 'iode', + 'iodc', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = EphemerisCommonContent.parse_members(buf, offset, length) + ret['common'] = __common + (__tgd1, offset, length) = get_f32(buf, offset, length) + ret['tgd1'] = judicious_round(nb.f4(__tgd1)) if SBP.judicious_rounding else __tgd1 + (__tgd2, offset, length) = get_f32(buf, offset, length) + ret['tgd2'] = judicious_round(nb.f4(__tgd2)) if SBP.judicious_rounding else __tgd2 + (__c_rs, offset, length) = get_f32(buf, offset, length) + ret['c_rs'] = judicious_round(nb.f4(__c_rs)) if SBP.judicious_rounding else __c_rs + (__c_rc, offset, length) = get_f32(buf, offset, length) + ret['c_rc'] = judicious_round(nb.f4(__c_rc)) if SBP.judicious_rounding else __c_rc + (__c_uc, offset, length) = get_f32(buf, offset, length) + ret['c_uc'] = judicious_round(nb.f4(__c_uc)) if SBP.judicious_rounding else __c_uc + (__c_us, offset, length) = get_f32(buf, offset, length) + ret['c_us'] = judicious_round(nb.f4(__c_us)) if SBP.judicious_rounding else __c_us + (__c_ic, offset, length) = get_f32(buf, offset, length) + ret['c_ic'] = judicious_round(nb.f4(__c_ic)) if SBP.judicious_rounding else __c_ic + (__c_is, offset, length) = get_f32(buf, offset, length) + ret['c_is'] = judicious_round(nb.f4(__c_is)) if SBP.judicious_rounding else __c_is + (__dn, offset, length) = get_f64(buf, offset, length) + ret['dn'] = __dn + (__m0, offset, length) = get_f64(buf, offset, length) + ret['m0'] = __m0 + (__ecc, offset, length) = get_f64(buf, offset, length) + ret['ecc'] = __ecc + (__sqrta, offset, length) = get_f64(buf, offset, length) + ret['sqrta'] = __sqrta + (__omega0, offset, length) = get_f64(buf, offset, length) + ret['omega0'] = __omega0 + (__omegadot, offset, length) = get_f64(buf, offset, length) + ret['omegadot'] = __omegadot + (__w, offset, length) = get_f64(buf, offset, length) + ret['w'] = __w + (__inc, offset, length) = get_f64(buf, offset, length) + ret['inc'] = __inc + (__inc_dot, offset, length) = get_f64(buf, offset, length) + ret['inc_dot'] = __inc_dot + (__af0, offset, length) = get_f64(buf, offset, length) + ret['af0'] = __af0 + (__af1, offset, length) = get_f32(buf, offset, length) + ret['af1'] = judicious_round(nb.f4(__af1)) if SBP.judicious_rounding else __af1 + (__af2, offset, length) = get_f32(buf, offset, length) + ret['af2'] = judicious_round(nb.f4(__af2)) if SBP.judicious_rounding else __af2 + (__toc, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['toc'] = __toc + (__iode, offset, length) = get_u8(buf, offset, length) + ret['iode'] = __iode + (__iodc, offset, length) = get_u16(buf, offset, length) + ret['iodc'] = __iodc + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.tgd1 = res['tgd1'] + self.tgd2 = res['tgd2'] + self.c_rs = res['c_rs'] + self.c_rc = res['c_rc'] + self.c_uc = res['c_uc'] + self.c_us = res['c_us'] + self.c_ic = res['c_ic'] + self.c_is = res['c_is'] + self.dn = res['dn'] + self.m0 = res['m0'] + self.ecc = res['ecc'] + self.sqrta = res['sqrta'] + self.omega0 = res['omega0'] + self.omegadot = res['omegadot'] + self.w = res['w'] + self.inc = res['inc'] + self.inc_dot = res['inc_dot'] + self.af0 = res['af0'] + self.af1 = res['af1'] + self.af2 = res['af2'] + self.toc = res['toc'] + self.iode = res['iode'] + self.iodc = res['iodc'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: EphemerisCommonContent + ret += EphemerisCommonContent._payload_size() + # tgd1: float + ret += 4 + # tgd2: float + ret += 4 + # c_rs: float + ret += 4 + # c_rc: float + ret += 4 + # c_uc: float + ret += 4 + # c_us: float + ret += 4 + # c_ic: float + ret += 4 + # c_is: float + ret += 4 + # dn: double + ret += 8 + # m0: double + ret += 8 + # ecc: double + ret += 8 + # sqrta: double + ret += 8 + # omega0: double + ret += 8 + # omegadot: double + ret += 8 + # w: double + ret += 8 + # inc: double + ret += 8 + # inc_dot: double + ret += 8 + # af0: double + ret += 8 + # af1: float + ret += 4 + # af2: float + ret += 4 + # toc: GPSTimeSec + ret += GPSTimeSec._payload_size() + # iode: u8 + ret += 1 + # iodc: u16 + ret += 2 + return ret + +SBP_MSG_EPHEMERIS_GAL = 0x0095 +class MsgEphemerisGal(SBP): + """SBP class for message MSG_EPHEMERIS_GAL (0x0095). + + You can have MSG_EPHEMERIS_GAL inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The ephemeris message returns a set of satellite orbit +parameters that is used to calculate Galileo satellite position, +velocity, and clock offset. Please see the Signal In Space ICD +OS SIS ICD, Issue 1.3, December 2016 for more details. + + + """ + __slots__ = ['common', + 'bgd_e1e5a', + 'bgd_e1e5b', + 'c_rs', + 'c_rc', + 'c_uc', + 'c_us', + 'c_ic', + 'c_is', + 'dn', + 'm0', + 'ecc', + 'sqrta', + 'omega0', + 'omegadot', + 'w', + 'inc', + 'inc_dot', + 'af0', + 'af1', + 'af2', + 'toc', + 'iode', + 'iodc', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = EphemerisCommonContent.parse_members(buf, offset, length) + ret['common'] = __common + (__bgd_e1e5a, offset, length) = get_f32(buf, offset, length) + ret['bgd_e1e5a'] = judicious_round(nb.f4(__bgd_e1e5a)) if SBP.judicious_rounding else __bgd_e1e5a + (__bgd_e1e5b, offset, length) = get_f32(buf, offset, length) + ret['bgd_e1e5b'] = judicious_round(nb.f4(__bgd_e1e5b)) if SBP.judicious_rounding else __bgd_e1e5b + (__c_rs, offset, length) = get_f32(buf, offset, length) + ret['c_rs'] = judicious_round(nb.f4(__c_rs)) if SBP.judicious_rounding else __c_rs + (__c_rc, offset, length) = get_f32(buf, offset, length) + ret['c_rc'] = judicious_round(nb.f4(__c_rc)) if SBP.judicious_rounding else __c_rc + (__c_uc, offset, length) = get_f32(buf, offset, length) + ret['c_uc'] = judicious_round(nb.f4(__c_uc)) if SBP.judicious_rounding else __c_uc + (__c_us, offset, length) = get_f32(buf, offset, length) + ret['c_us'] = judicious_round(nb.f4(__c_us)) if SBP.judicious_rounding else __c_us + (__c_ic, offset, length) = get_f32(buf, offset, length) + ret['c_ic'] = judicious_round(nb.f4(__c_ic)) if SBP.judicious_rounding else __c_ic + (__c_is, offset, length) = get_f32(buf, offset, length) + ret['c_is'] = judicious_round(nb.f4(__c_is)) if SBP.judicious_rounding else __c_is + (__dn, offset, length) = get_f64(buf, offset, length) + ret['dn'] = __dn + (__m0, offset, length) = get_f64(buf, offset, length) + ret['m0'] = __m0 + (__ecc, offset, length) = get_f64(buf, offset, length) + ret['ecc'] = __ecc + (__sqrta, offset, length) = get_f64(buf, offset, length) + ret['sqrta'] = __sqrta + (__omega0, offset, length) = get_f64(buf, offset, length) + ret['omega0'] = __omega0 + (__omegadot, offset, length) = get_f64(buf, offset, length) + ret['omegadot'] = __omegadot + (__w, offset, length) = get_f64(buf, offset, length) + ret['w'] = __w + (__inc, offset, length) = get_f64(buf, offset, length) + ret['inc'] = __inc + (__inc_dot, offset, length) = get_f64(buf, offset, length) + ret['inc_dot'] = __inc_dot + (__af0, offset, length) = get_f64(buf, offset, length) + ret['af0'] = __af0 + (__af1, offset, length) = get_f64(buf, offset, length) + ret['af1'] = __af1 + (__af2, offset, length) = get_f32(buf, offset, length) + ret['af2'] = judicious_round(nb.f4(__af2)) if SBP.judicious_rounding else __af2 + (__toc, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['toc'] = __toc + (__iode, offset, length) = get_u16(buf, offset, length) + ret['iode'] = __iode + (__iodc, offset, length) = get_u16(buf, offset, length) + ret['iodc'] = __iodc + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.bgd_e1e5a = res['bgd_e1e5a'] + self.bgd_e1e5b = res['bgd_e1e5b'] + self.c_rs = res['c_rs'] + self.c_rc = res['c_rc'] + self.c_uc = res['c_uc'] + self.c_us = res['c_us'] + self.c_ic = res['c_ic'] + self.c_is = res['c_is'] + self.dn = res['dn'] + self.m0 = res['m0'] + self.ecc = res['ecc'] + self.sqrta = res['sqrta'] + self.omega0 = res['omega0'] + self.omegadot = res['omegadot'] + self.w = res['w'] + self.inc = res['inc'] + self.inc_dot = res['inc_dot'] + self.af0 = res['af0'] + self.af1 = res['af1'] + self.af2 = res['af2'] + self.toc = res['toc'] + self.iode = res['iode'] + self.iodc = res['iodc'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: EphemerisCommonContent + ret += EphemerisCommonContent._payload_size() + # bgd_e1e5a: float + ret += 4 + # bgd_e1e5b: float + ret += 4 + # c_rs: float + ret += 4 + # c_rc: float + ret += 4 + # c_uc: float + ret += 4 + # c_us: float + ret += 4 + # c_ic: float + ret += 4 + # c_is: float + ret += 4 + # dn: double + ret += 8 + # m0: double + ret += 8 + # ecc: double + ret += 8 + # sqrta: double + ret += 8 + # omega0: double + ret += 8 + # omegadot: double + ret += 8 + # w: double + ret += 8 + # inc: double + ret += 8 + # inc_dot: double + ret += 8 + # af0: double + ret += 8 + # af1: double + ret += 8 + # af2: float + ret += 4 + # toc: GPSTimeSec + ret += GPSTimeSec._payload_size() + # iode: u16 + ret += 2 + # iodc: u16 + ret += 2 + return ret + +SBP_MSG_EPHEMERIS_SBAS_DEP_A = 0x0082 +class MsgEphemerisSbasDepA(SBP): + """SBP class for message MSG_EPHEMERIS_SBAS_DEP_A (0x0082). + + You can have MSG_EPHEMERIS_SBAS_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + + """ + __slots__ = ['common', + 'pos', + 'vel', + 'acc', + 'a_gf0', + 'a_gf1', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = EphemerisCommonContentDepA.parse_members(buf, offset, length) + ret['common'] = __common + (__pos, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['pos'] = __pos + (__vel, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['vel'] = __vel + (__acc, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['acc'] = __acc + (__a_gf0, offset, length) = get_f64(buf, offset, length) + ret['a_gf0'] = __a_gf0 + (__a_gf1, offset, length) = get_f64(buf, offset, length) + ret['a_gf1'] = __a_gf1 + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.pos = res['pos'] + self.vel = res['vel'] + self.acc = res['acc'] + self.a_gf0 = res['a_gf0'] + self.a_gf1 = res['a_gf1'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: EphemerisCommonContentDepA + ret += EphemerisCommonContentDepA._payload_size() + # pos: array of double + ret += 8 * 3 + # vel: array of double + ret += 8 * 3 + # acc: array of double + ret += 8 * 3 + # a_gf0: double + ret += 8 + # a_gf1: double + ret += 8 + return ret + +SBP_MSG_EPHEMERIS_GLO_DEP_A = 0x0083 +class MsgEphemerisGloDepA(SBP): + """SBP class for message MSG_EPHEMERIS_GLO_DEP_A (0x0083). + + You can have MSG_EPHEMERIS_GLO_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The ephemeris message returns a set of satellite orbit +parameters that is used to calculate GLO satellite position, +velocity, and clock offset. Please see the GLO ICD 5.1 "Table 4.5 +Characteristics of words of immediate information (ephemeris parameters)" +for more details. + + + """ + __slots__ = ['common', + 'gamma', + 'tau', + 'pos', + 'vel', + 'acc', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = EphemerisCommonContentDepA.parse_members(buf, offset, length) + ret['common'] = __common + (__gamma, offset, length) = get_f64(buf, offset, length) + ret['gamma'] = __gamma + (__tau, offset, length) = get_f64(buf, offset, length) + ret['tau'] = __tau + (__pos, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['pos'] = __pos + (__vel, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['vel'] = __vel + (__acc, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['acc'] = __acc + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.gamma = res['gamma'] + self.tau = res['tau'] + self.pos = res['pos'] + self.vel = res['vel'] + self.acc = res['acc'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: EphemerisCommonContentDepA + ret += EphemerisCommonContentDepA._payload_size() + # gamma: double + ret += 8 + # tau: double + ret += 8 + # pos: array of double + ret += 8 * 3 + # vel: array of double + ret += 8 * 3 + # acc: array of double + ret += 8 * 3 + return ret + +SBP_MSG_EPHEMERIS_SBAS_DEP_B = 0x0084 +class MsgEphemerisSbasDepB(SBP): + """SBP class for message MSG_EPHEMERIS_SBAS_DEP_B (0x0084). + + You can have MSG_EPHEMERIS_SBAS_DEP_B inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This observation message has been deprecated in favor of +ephemeris message using floats for size reduction. + + + """ + __slots__ = ['common', + 'pos', + 'vel', + 'acc', + 'a_gf0', + 'a_gf1', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = EphemerisCommonContentDepB.parse_members(buf, offset, length) + ret['common'] = __common + (__pos, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['pos'] = __pos + (__vel, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['vel'] = __vel + (__acc, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['acc'] = __acc + (__a_gf0, offset, length) = get_f64(buf, offset, length) + ret['a_gf0'] = __a_gf0 + (__a_gf1, offset, length) = get_f64(buf, offset, length) + ret['a_gf1'] = __a_gf1 + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.pos = res['pos'] + self.vel = res['vel'] + self.acc = res['acc'] + self.a_gf0 = res['a_gf0'] + self.a_gf1 = res['a_gf1'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: EphemerisCommonContentDepB + ret += EphemerisCommonContentDepB._payload_size() + # pos: array of double + ret += 8 * 3 + # vel: array of double + ret += 8 * 3 + # acc: array of double + ret += 8 * 3 + # a_gf0: double + ret += 8 + # a_gf1: double + ret += 8 + return ret + +SBP_MSG_EPHEMERIS_SBAS = 0x008C +class MsgEphemerisSbas(SBP): + """SBP class for message MSG_EPHEMERIS_SBAS (0x008C). + + You can have MSG_EPHEMERIS_SBAS inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + + """ + __slots__ = ['common', + 'pos', + 'vel', + 'acc', + 'a_gf0', + 'a_gf1', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = EphemerisCommonContent.parse_members(buf, offset, length) + ret['common'] = __common + (__pos, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['pos'] = __pos + (__vel, offset, length) = get_fixed_array(get_f32, 3, 4, nb.f4 if SBP.judicious_rounding else None)(buf, offset, length) + ret['vel'] = __vel + (__acc, offset, length) = get_fixed_array(get_f32, 3, 4, nb.f4 if SBP.judicious_rounding else None)(buf, offset, length) + ret['acc'] = __acc + (__a_gf0, offset, length) = get_f32(buf, offset, length) + ret['a_gf0'] = judicious_round(nb.f4(__a_gf0)) if SBP.judicious_rounding else __a_gf0 + (__a_gf1, offset, length) = get_f32(buf, offset, length) + ret['a_gf1'] = judicious_round(nb.f4(__a_gf1)) if SBP.judicious_rounding else __a_gf1 + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.pos = res['pos'] + self.vel = res['vel'] + self.acc = res['acc'] + self.a_gf0 = res['a_gf0'] + self.a_gf1 = res['a_gf1'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: EphemerisCommonContent + ret += EphemerisCommonContent._payload_size() + # pos: array of double + ret += 8 * 3 + # vel: array of float + ret += 4 * 3 + # acc: array of float + ret += 4 * 3 + # a_gf0: float + ret += 4 + # a_gf1: float + ret += 4 + return ret + +SBP_MSG_EPHEMERIS_GLO_DEP_B = 0x0085 +class MsgEphemerisGloDepB(SBP): + """SBP class for message MSG_EPHEMERIS_GLO_DEP_B (0x0085). + + You can have MSG_EPHEMERIS_GLO_DEP_B inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The ephemeris message returns a set of satellite orbit +parameters that is used to calculate GLO satellite position, +velocity, and clock offset. Please see the GLO ICD 5.1 "Table 4.5 +Characteristics of words of immediate information (ephemeris parameters)" +for more details. + + + """ + __slots__ = ['common', + 'gamma', + 'tau', + 'pos', + 'vel', + 'acc', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = EphemerisCommonContentDepB.parse_members(buf, offset, length) + ret['common'] = __common + (__gamma, offset, length) = get_f64(buf, offset, length) + ret['gamma'] = __gamma + (__tau, offset, length) = get_f64(buf, offset, length) + ret['tau'] = __tau + (__pos, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['pos'] = __pos + (__vel, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['vel'] = __vel + (__acc, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['acc'] = __acc + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.gamma = res['gamma'] + self.tau = res['tau'] + self.pos = res['pos'] + self.vel = res['vel'] + self.acc = res['acc'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: EphemerisCommonContentDepB + ret += EphemerisCommonContentDepB._payload_size() + # gamma: double + ret += 8 + # tau: double + ret += 8 + # pos: array of double + ret += 8 * 3 + # vel: array of double + ret += 8 * 3 + # acc: array of double + ret += 8 * 3 + return ret + +SBP_MSG_EPHEMERIS_GLO_DEP_C = 0x0087 +class MsgEphemerisGloDepC(SBP): + """SBP class for message MSG_EPHEMERIS_GLO_DEP_C (0x0087). + + You can have MSG_EPHEMERIS_GLO_DEP_C inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The ephemeris message returns a set of satellite orbit +parameters that is used to calculate GLO satellite position, +velocity, and clock offset. Please see the GLO ICD 5.1 "Table 4.5 +Characteristics of words of immediate information (ephemeris parameters)" +for more details. + + + """ + __slots__ = ['common', + 'gamma', + 'tau', + 'd_tau', + 'pos', + 'vel', + 'acc', + 'fcn', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = EphemerisCommonContentDepB.parse_members(buf, offset, length) + ret['common'] = __common + (__gamma, offset, length) = get_f64(buf, offset, length) + ret['gamma'] = __gamma + (__tau, offset, length) = get_f64(buf, offset, length) + ret['tau'] = __tau + (__d_tau, offset, length) = get_f64(buf, offset, length) + ret['d_tau'] = __d_tau + (__pos, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['pos'] = __pos + (__vel, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['vel'] = __vel + (__acc, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['acc'] = __acc + (__fcn, offset, length) = get_u8(buf, offset, length) + ret['fcn'] = __fcn + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.gamma = res['gamma'] + self.tau = res['tau'] + self.d_tau = res['d_tau'] + self.pos = res['pos'] + self.vel = res['vel'] + self.acc = res['acc'] + self.fcn = res['fcn'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: EphemerisCommonContentDepB + ret += EphemerisCommonContentDepB._payload_size() + # gamma: double + ret += 8 + # tau: double + ret += 8 + # d_tau: double + ret += 8 + # pos: array of double + ret += 8 * 3 + # vel: array of double + ret += 8 * 3 + # acc: array of double + ret += 8 * 3 + # fcn: u8 + ret += 1 + return ret + +SBP_MSG_EPHEMERIS_GLO_DEP_D = 0x0088 +class MsgEphemerisGloDepD(SBP): + """SBP class for message MSG_EPHEMERIS_GLO_DEP_D (0x0088). + + You can have MSG_EPHEMERIS_GLO_DEP_D inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This observation message has been deprecated in favor of +ephemeris message using floats for size reduction. + + + """ + __slots__ = ['common', + 'gamma', + 'tau', + 'd_tau', + 'pos', + 'vel', + 'acc', + 'fcn', + 'iod', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = EphemerisCommonContentDepB.parse_members(buf, offset, length) + ret['common'] = __common + (__gamma, offset, length) = get_f64(buf, offset, length) + ret['gamma'] = __gamma + (__tau, offset, length) = get_f64(buf, offset, length) + ret['tau'] = __tau + (__d_tau, offset, length) = get_f64(buf, offset, length) + ret['d_tau'] = __d_tau + (__pos, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['pos'] = __pos + (__vel, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['vel'] = __vel + (__acc, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['acc'] = __acc + (__fcn, offset, length) = get_u8(buf, offset, length) + ret['fcn'] = __fcn + (__iod, offset, length) = get_u8(buf, offset, length) + ret['iod'] = __iod + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.gamma = res['gamma'] + self.tau = res['tau'] + self.d_tau = res['d_tau'] + self.pos = res['pos'] + self.vel = res['vel'] + self.acc = res['acc'] + self.fcn = res['fcn'] + self.iod = res['iod'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: EphemerisCommonContentDepB + ret += EphemerisCommonContentDepB._payload_size() + # gamma: double + ret += 8 + # tau: double + ret += 8 + # d_tau: double + ret += 8 + # pos: array of double + ret += 8 * 3 + # vel: array of double + ret += 8 * 3 + # acc: array of double + ret += 8 * 3 + # fcn: u8 + ret += 1 + # iod: u8 + ret += 1 + return ret + +SBP_MSG_EPHEMERIS_GLO = 0x008B +class MsgEphemerisGlo(SBP): + """SBP class for message MSG_EPHEMERIS_GLO (0x008B). + + You can have MSG_EPHEMERIS_GLO inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The ephemeris message returns a set of satellite orbit +parameters that is used to calculate GLO satellite position, +velocity, and clock offset. Please see the GLO ICD 5.1 "Table 4.5 +Characteristics of words of immediate information (ephemeris parameters)" +for more details. + + + """ + __slots__ = ['common', + 'gamma', + 'tau', + 'd_tau', + 'pos', + 'vel', + 'acc', + 'fcn', + 'iod', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = EphemerisCommonContent.parse_members(buf, offset, length) + ret['common'] = __common + (__gamma, offset, length) = get_f32(buf, offset, length) + ret['gamma'] = judicious_round(nb.f4(__gamma)) if SBP.judicious_rounding else __gamma + (__tau, offset, length) = get_f32(buf, offset, length) + ret['tau'] = judicious_round(nb.f4(__tau)) if SBP.judicious_rounding else __tau + (__d_tau, offset, length) = get_f32(buf, offset, length) + ret['d_tau'] = judicious_round(nb.f4(__d_tau)) if SBP.judicious_rounding else __d_tau + (__pos, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['pos'] = __pos + (__vel, offset, length) = get_fixed_array(get_f64, 3, 8)(buf, offset, length) + ret['vel'] = __vel + (__acc, offset, length) = get_fixed_array(get_f32, 3, 4, nb.f4 if SBP.judicious_rounding else None)(buf, offset, length) + ret['acc'] = __acc + (__fcn, offset, length) = get_u8(buf, offset, length) + ret['fcn'] = __fcn + (__iod, offset, length) = get_u8(buf, offset, length) + ret['iod'] = __iod + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.gamma = res['gamma'] + self.tau = res['tau'] + self.d_tau = res['d_tau'] + self.pos = res['pos'] + self.vel = res['vel'] + self.acc = res['acc'] + self.fcn = res['fcn'] + self.iod = res['iod'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: EphemerisCommonContent + ret += EphemerisCommonContent._payload_size() + # gamma: float + ret += 4 + # tau: float + ret += 4 + # d_tau: float + ret += 4 + # pos: array of double + ret += 8 * 3 + # vel: array of double + ret += 8 * 3 + # acc: array of float + ret += 4 * 3 + # fcn: u8 + ret += 1 + # iod: u8 + ret += 1 + return ret + +SBP_MSG_EPHEMERIS_DEP_D = 0x0080 +class MsgEphemerisDepD(SBP): + """SBP class for message MSG_EPHEMERIS_DEP_D (0x0080). + + You can have MSG_EPHEMERIS_DEP_D inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The ephemeris message returns a set of satellite orbit +parameters that is used to calculate GPS satellite position, +velocity, and clock offset. Please see the Navstar GPS +Space Segment/Navigation user interfaces (ICD-GPS-200, Table +20-III) for more details. + + + """ + __slots__ = ['tgd', + 'c_rs', + 'c_rc', + 'c_uc', + 'c_us', + 'c_ic', + 'c_is', + 'dn', + 'm0', + 'ecc', + 'sqrta', + 'omega0', + 'omegadot', + 'w', + 'inc', + 'inc_dot', + 'af0', + 'af1', + 'af2', + 'toe_tow', + 'toe_wn', + 'toc_tow', + 'toc_wn', + 'valid', + 'healthy', + 'sid', + 'iode', + 'iodc', + 'reserved', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tgd, offset, length) = get_f64(buf, offset, length) + ret['tgd'] = __tgd + (__c_rs, offset, length) = get_f64(buf, offset, length) + ret['c_rs'] = __c_rs + (__c_rc, offset, length) = get_f64(buf, offset, length) + ret['c_rc'] = __c_rc + (__c_uc, offset, length) = get_f64(buf, offset, length) + ret['c_uc'] = __c_uc + (__c_us, offset, length) = get_f64(buf, offset, length) + ret['c_us'] = __c_us + (__c_ic, offset, length) = get_f64(buf, offset, length) + ret['c_ic'] = __c_ic + (__c_is, offset, length) = get_f64(buf, offset, length) + ret['c_is'] = __c_is + (__dn, offset, length) = get_f64(buf, offset, length) + ret['dn'] = __dn + (__m0, offset, length) = get_f64(buf, offset, length) + ret['m0'] = __m0 + (__ecc, offset, length) = get_f64(buf, offset, length) + ret['ecc'] = __ecc + (__sqrta, offset, length) = get_f64(buf, offset, length) + ret['sqrta'] = __sqrta + (__omega0, offset, length) = get_f64(buf, offset, length) + ret['omega0'] = __omega0 + (__omegadot, offset, length) = get_f64(buf, offset, length) + ret['omegadot'] = __omegadot + (__w, offset, length) = get_f64(buf, offset, length) + ret['w'] = __w + (__inc, offset, length) = get_f64(buf, offset, length) + ret['inc'] = __inc + (__inc_dot, offset, length) = get_f64(buf, offset, length) + ret['inc_dot'] = __inc_dot + (__af0, offset, length) = get_f64(buf, offset, length) + ret['af0'] = __af0 + (__af1, offset, length) = get_f64(buf, offset, length) + ret['af1'] = __af1 + (__af2, offset, length) = get_f64(buf, offset, length) + ret['af2'] = __af2 + (__toe_tow, offset, length) = get_f64(buf, offset, length) + ret['toe_tow'] = __toe_tow + (__toe_wn, offset, length) = get_u16(buf, offset, length) + ret['toe_wn'] = __toe_wn + (__toc_tow, offset, length) = get_f64(buf, offset, length) + ret['toc_tow'] = __toc_tow + (__toc_wn, offset, length) = get_u16(buf, offset, length) + ret['toc_wn'] = __toc_wn + (__valid, offset, length) = get_u8(buf, offset, length) + ret['valid'] = __valid + (__healthy, offset, length) = get_u8(buf, offset, length) + ret['healthy'] = __healthy + (__sid, offset, length) = GnssSignalDep.parse_members(buf, offset, length) + ret['sid'] = __sid + (__iode, offset, length) = get_u8(buf, offset, length) + ret['iode'] = __iode + (__iodc, offset, length) = get_u16(buf, offset, length) + ret['iodc'] = __iodc + (__reserved, offset, length) = get_u32(buf, offset, length) + ret['reserved'] = __reserved + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tgd = res['tgd'] + self.c_rs = res['c_rs'] + self.c_rc = res['c_rc'] + self.c_uc = res['c_uc'] + self.c_us = res['c_us'] + self.c_ic = res['c_ic'] + self.c_is = res['c_is'] + self.dn = res['dn'] + self.m0 = res['m0'] + self.ecc = res['ecc'] + self.sqrta = res['sqrta'] + self.omega0 = res['omega0'] + self.omegadot = res['omegadot'] + self.w = res['w'] + self.inc = res['inc'] + self.inc_dot = res['inc_dot'] + self.af0 = res['af0'] + self.af1 = res['af1'] + self.af2 = res['af2'] + self.toe_tow = res['toe_tow'] + self.toe_wn = res['toe_wn'] + self.toc_tow = res['toc_tow'] + self.toc_wn = res['toc_wn'] + self.valid = res['valid'] + self.healthy = res['healthy'] + self.sid = res['sid'] + self.iode = res['iode'] + self.iodc = res['iodc'] + self.reserved = res['reserved'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tgd: double + ret += 8 + # c_rs: double + ret += 8 + # c_rc: double + ret += 8 + # c_uc: double + ret += 8 + # c_us: double + ret += 8 + # c_ic: double + ret += 8 + # c_is: double + ret += 8 + # dn: double + ret += 8 + # m0: double + ret += 8 + # ecc: double + ret += 8 + # sqrta: double + ret += 8 + # omega0: double + ret += 8 + # omegadot: double + ret += 8 + # w: double + ret += 8 + # inc: double + ret += 8 + # inc_dot: double + ret += 8 + # af0: double + ret += 8 + # af1: double + ret += 8 + # af2: double + ret += 8 + # toe_tow: double + ret += 8 + # toe_wn: u16 + ret += 2 + # toc_tow: double + ret += 8 + # toc_wn: u16 + ret += 2 + # valid: u8 + ret += 1 + # healthy: u8 + ret += 1 + # sid: GnssSignalDep + ret += GnssSignalDep._payload_size() + # iode: u8 + ret += 1 + # iodc: u16 + ret += 2 + # reserved: u32 + ret += 4 + return ret + +SBP_MSG_EPHEMERIS_DEP_A = 0x001A +class MsgEphemerisDepA(SBP): + """SBP class for message MSG_EPHEMERIS_DEP_A (0x001A). + + You can have MSG_EPHEMERIS_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['tgd', + 'c_rs', + 'c_rc', + 'c_uc', + 'c_us', + 'c_ic', + 'c_is', + 'dn', + 'm0', + 'ecc', + 'sqrta', + 'omega0', + 'omegadot', + 'w', + 'inc', + 'inc_dot', + 'af0', + 'af1', + 'af2', + 'toe_tow', + 'toe_wn', + 'toc_tow', + 'toc_wn', + 'valid', + 'healthy', + 'prn', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tgd, offset, length) = get_f64(buf, offset, length) + ret['tgd'] = __tgd + (__c_rs, offset, length) = get_f64(buf, offset, length) + ret['c_rs'] = __c_rs + (__c_rc, offset, length) = get_f64(buf, offset, length) + ret['c_rc'] = __c_rc + (__c_uc, offset, length) = get_f64(buf, offset, length) + ret['c_uc'] = __c_uc + (__c_us, offset, length) = get_f64(buf, offset, length) + ret['c_us'] = __c_us + (__c_ic, offset, length) = get_f64(buf, offset, length) + ret['c_ic'] = __c_ic + (__c_is, offset, length) = get_f64(buf, offset, length) + ret['c_is'] = __c_is + (__dn, offset, length) = get_f64(buf, offset, length) + ret['dn'] = __dn + (__m0, offset, length) = get_f64(buf, offset, length) + ret['m0'] = __m0 + (__ecc, offset, length) = get_f64(buf, offset, length) + ret['ecc'] = __ecc + (__sqrta, offset, length) = get_f64(buf, offset, length) + ret['sqrta'] = __sqrta + (__omega0, offset, length) = get_f64(buf, offset, length) + ret['omega0'] = __omega0 + (__omegadot, offset, length) = get_f64(buf, offset, length) + ret['omegadot'] = __omegadot + (__w, offset, length) = get_f64(buf, offset, length) + ret['w'] = __w + (__inc, offset, length) = get_f64(buf, offset, length) + ret['inc'] = __inc + (__inc_dot, offset, length) = get_f64(buf, offset, length) + ret['inc_dot'] = __inc_dot + (__af0, offset, length) = get_f64(buf, offset, length) + ret['af0'] = __af0 + (__af1, offset, length) = get_f64(buf, offset, length) + ret['af1'] = __af1 + (__af2, offset, length) = get_f64(buf, offset, length) + ret['af2'] = __af2 + (__toe_tow, offset, length) = get_f64(buf, offset, length) + ret['toe_tow'] = __toe_tow + (__toe_wn, offset, length) = get_u16(buf, offset, length) + ret['toe_wn'] = __toe_wn + (__toc_tow, offset, length) = get_f64(buf, offset, length) + ret['toc_tow'] = __toc_tow + (__toc_wn, offset, length) = get_u16(buf, offset, length) + ret['toc_wn'] = __toc_wn + (__valid, offset, length) = get_u8(buf, offset, length) + ret['valid'] = __valid + (__healthy, offset, length) = get_u8(buf, offset, length) + ret['healthy'] = __healthy + (__prn, offset, length) = get_u8(buf, offset, length) + ret['prn'] = __prn + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tgd = res['tgd'] + self.c_rs = res['c_rs'] + self.c_rc = res['c_rc'] + self.c_uc = res['c_uc'] + self.c_us = res['c_us'] + self.c_ic = res['c_ic'] + self.c_is = res['c_is'] + self.dn = res['dn'] + self.m0 = res['m0'] + self.ecc = res['ecc'] + self.sqrta = res['sqrta'] + self.omega0 = res['omega0'] + self.omegadot = res['omegadot'] + self.w = res['w'] + self.inc = res['inc'] + self.inc_dot = res['inc_dot'] + self.af0 = res['af0'] + self.af1 = res['af1'] + self.af2 = res['af2'] + self.toe_tow = res['toe_tow'] + self.toe_wn = res['toe_wn'] + self.toc_tow = res['toc_tow'] + self.toc_wn = res['toc_wn'] + self.valid = res['valid'] + self.healthy = res['healthy'] + self.prn = res['prn'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tgd: double + ret += 8 + # c_rs: double + ret += 8 + # c_rc: double + ret += 8 + # c_uc: double + ret += 8 + # c_us: double + ret += 8 + # c_ic: double + ret += 8 + # c_is: double + ret += 8 + # dn: double + ret += 8 + # m0: double + ret += 8 + # ecc: double + ret += 8 + # sqrta: double + ret += 8 + # omega0: double + ret += 8 + # omegadot: double + ret += 8 + # w: double + ret += 8 + # inc: double + ret += 8 + # inc_dot: double + ret += 8 + # af0: double + ret += 8 + # af1: double + ret += 8 + # af2: double + ret += 8 + # toe_tow: double + ret += 8 + # toe_wn: u16 + ret += 2 + # toc_tow: double + ret += 8 + # toc_wn: u16 + ret += 2 + # valid: u8 + ret += 1 + # healthy: u8 + ret += 1 + # prn: u8 + ret += 1 + return ret + +SBP_MSG_EPHEMERIS_DEP_B = 0x0046 +class MsgEphemerisDepB(SBP): + """SBP class for message MSG_EPHEMERIS_DEP_B (0x0046). + + You can have MSG_EPHEMERIS_DEP_B inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['tgd', + 'c_rs', + 'c_rc', + 'c_uc', + 'c_us', + 'c_ic', + 'c_is', + 'dn', + 'm0', + 'ecc', + 'sqrta', + 'omega0', + 'omegadot', + 'w', + 'inc', + 'inc_dot', + 'af0', + 'af1', + 'af2', + 'toe_tow', + 'toe_wn', + 'toc_tow', + 'toc_wn', + 'valid', + 'healthy', + 'prn', + 'iode', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tgd, offset, length) = get_f64(buf, offset, length) + ret['tgd'] = __tgd + (__c_rs, offset, length) = get_f64(buf, offset, length) + ret['c_rs'] = __c_rs + (__c_rc, offset, length) = get_f64(buf, offset, length) + ret['c_rc'] = __c_rc + (__c_uc, offset, length) = get_f64(buf, offset, length) + ret['c_uc'] = __c_uc + (__c_us, offset, length) = get_f64(buf, offset, length) + ret['c_us'] = __c_us + (__c_ic, offset, length) = get_f64(buf, offset, length) + ret['c_ic'] = __c_ic + (__c_is, offset, length) = get_f64(buf, offset, length) + ret['c_is'] = __c_is + (__dn, offset, length) = get_f64(buf, offset, length) + ret['dn'] = __dn + (__m0, offset, length) = get_f64(buf, offset, length) + ret['m0'] = __m0 + (__ecc, offset, length) = get_f64(buf, offset, length) + ret['ecc'] = __ecc + (__sqrta, offset, length) = get_f64(buf, offset, length) + ret['sqrta'] = __sqrta + (__omega0, offset, length) = get_f64(buf, offset, length) + ret['omega0'] = __omega0 + (__omegadot, offset, length) = get_f64(buf, offset, length) + ret['omegadot'] = __omegadot + (__w, offset, length) = get_f64(buf, offset, length) + ret['w'] = __w + (__inc, offset, length) = get_f64(buf, offset, length) + ret['inc'] = __inc + (__inc_dot, offset, length) = get_f64(buf, offset, length) + ret['inc_dot'] = __inc_dot + (__af0, offset, length) = get_f64(buf, offset, length) + ret['af0'] = __af0 + (__af1, offset, length) = get_f64(buf, offset, length) + ret['af1'] = __af1 + (__af2, offset, length) = get_f64(buf, offset, length) + ret['af2'] = __af2 + (__toe_tow, offset, length) = get_f64(buf, offset, length) + ret['toe_tow'] = __toe_tow + (__toe_wn, offset, length) = get_u16(buf, offset, length) + ret['toe_wn'] = __toe_wn + (__toc_tow, offset, length) = get_f64(buf, offset, length) + ret['toc_tow'] = __toc_tow + (__toc_wn, offset, length) = get_u16(buf, offset, length) + ret['toc_wn'] = __toc_wn + (__valid, offset, length) = get_u8(buf, offset, length) + ret['valid'] = __valid + (__healthy, offset, length) = get_u8(buf, offset, length) + ret['healthy'] = __healthy + (__prn, offset, length) = get_u8(buf, offset, length) + ret['prn'] = __prn + (__iode, offset, length) = get_u8(buf, offset, length) + ret['iode'] = __iode + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tgd = res['tgd'] + self.c_rs = res['c_rs'] + self.c_rc = res['c_rc'] + self.c_uc = res['c_uc'] + self.c_us = res['c_us'] + self.c_ic = res['c_ic'] + self.c_is = res['c_is'] + self.dn = res['dn'] + self.m0 = res['m0'] + self.ecc = res['ecc'] + self.sqrta = res['sqrta'] + self.omega0 = res['omega0'] + self.omegadot = res['omegadot'] + self.w = res['w'] + self.inc = res['inc'] + self.inc_dot = res['inc_dot'] + self.af0 = res['af0'] + self.af1 = res['af1'] + self.af2 = res['af2'] + self.toe_tow = res['toe_tow'] + self.toe_wn = res['toe_wn'] + self.toc_tow = res['toc_tow'] + self.toc_wn = res['toc_wn'] + self.valid = res['valid'] + self.healthy = res['healthy'] + self.prn = res['prn'] + self.iode = res['iode'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tgd: double + ret += 8 + # c_rs: double + ret += 8 + # c_rc: double + ret += 8 + # c_uc: double + ret += 8 + # c_us: double + ret += 8 + # c_ic: double + ret += 8 + # c_is: double + ret += 8 + # dn: double + ret += 8 + # m0: double + ret += 8 + # ecc: double + ret += 8 + # sqrta: double + ret += 8 + # omega0: double + ret += 8 + # omegadot: double + ret += 8 + # w: double + ret += 8 + # inc: double + ret += 8 + # inc_dot: double + ret += 8 + # af0: double + ret += 8 + # af1: double + ret += 8 + # af2: double + ret += 8 + # toe_tow: double + ret += 8 + # toe_wn: u16 + ret += 2 + # toc_tow: double + ret += 8 + # toc_wn: u16 + ret += 2 + # valid: u8 + ret += 1 + # healthy: u8 + ret += 1 + # prn: u8 + ret += 1 + # iode: u8 + ret += 1 + return ret + +SBP_MSG_EPHEMERIS_DEP_C = 0x0047 +class MsgEphemerisDepC(SBP): + """SBP class for message MSG_EPHEMERIS_DEP_C (0x0047). + + You can have MSG_EPHEMERIS_DEP_C inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The ephemeris message returns a set of satellite orbit +parameters that is used to calculate GPS satellite position, +velocity, and clock offset. Please see the Navstar GPS +Space Segment/Navigation user interfaces (ICD-GPS-200, Table +20-III) for more details. + + + """ + __slots__ = ['tgd', + 'c_rs', + 'c_rc', + 'c_uc', + 'c_us', + 'c_ic', + 'c_is', + 'dn', + 'm0', + 'ecc', + 'sqrta', + 'omega0', + 'omegadot', + 'w', + 'inc', + 'inc_dot', + 'af0', + 'af1', + 'af2', + 'toe_tow', + 'toe_wn', + 'toc_tow', + 'toc_wn', + 'valid', + 'healthy', + 'sid', + 'iode', + 'iodc', + 'reserved', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tgd, offset, length) = get_f64(buf, offset, length) + ret['tgd'] = __tgd + (__c_rs, offset, length) = get_f64(buf, offset, length) + ret['c_rs'] = __c_rs + (__c_rc, offset, length) = get_f64(buf, offset, length) + ret['c_rc'] = __c_rc + (__c_uc, offset, length) = get_f64(buf, offset, length) + ret['c_uc'] = __c_uc + (__c_us, offset, length) = get_f64(buf, offset, length) + ret['c_us'] = __c_us + (__c_ic, offset, length) = get_f64(buf, offset, length) + ret['c_ic'] = __c_ic + (__c_is, offset, length) = get_f64(buf, offset, length) + ret['c_is'] = __c_is + (__dn, offset, length) = get_f64(buf, offset, length) + ret['dn'] = __dn + (__m0, offset, length) = get_f64(buf, offset, length) + ret['m0'] = __m0 + (__ecc, offset, length) = get_f64(buf, offset, length) + ret['ecc'] = __ecc + (__sqrta, offset, length) = get_f64(buf, offset, length) + ret['sqrta'] = __sqrta + (__omega0, offset, length) = get_f64(buf, offset, length) + ret['omega0'] = __omega0 + (__omegadot, offset, length) = get_f64(buf, offset, length) + ret['omegadot'] = __omegadot + (__w, offset, length) = get_f64(buf, offset, length) + ret['w'] = __w + (__inc, offset, length) = get_f64(buf, offset, length) + ret['inc'] = __inc + (__inc_dot, offset, length) = get_f64(buf, offset, length) + ret['inc_dot'] = __inc_dot + (__af0, offset, length) = get_f64(buf, offset, length) + ret['af0'] = __af0 + (__af1, offset, length) = get_f64(buf, offset, length) + ret['af1'] = __af1 + (__af2, offset, length) = get_f64(buf, offset, length) + ret['af2'] = __af2 + (__toe_tow, offset, length) = get_f64(buf, offset, length) + ret['toe_tow'] = __toe_tow + (__toe_wn, offset, length) = get_u16(buf, offset, length) + ret['toe_wn'] = __toe_wn + (__toc_tow, offset, length) = get_f64(buf, offset, length) + ret['toc_tow'] = __toc_tow + (__toc_wn, offset, length) = get_u16(buf, offset, length) + ret['toc_wn'] = __toc_wn + (__valid, offset, length) = get_u8(buf, offset, length) + ret['valid'] = __valid + (__healthy, offset, length) = get_u8(buf, offset, length) + ret['healthy'] = __healthy + (__sid, offset, length) = GnssSignalDep.parse_members(buf, offset, length) + ret['sid'] = __sid + (__iode, offset, length) = get_u8(buf, offset, length) + ret['iode'] = __iode + (__iodc, offset, length) = get_u16(buf, offset, length) + ret['iodc'] = __iodc + (__reserved, offset, length) = get_u32(buf, offset, length) + ret['reserved'] = __reserved + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tgd = res['tgd'] + self.c_rs = res['c_rs'] + self.c_rc = res['c_rc'] + self.c_uc = res['c_uc'] + self.c_us = res['c_us'] + self.c_ic = res['c_ic'] + self.c_is = res['c_is'] + self.dn = res['dn'] + self.m0 = res['m0'] + self.ecc = res['ecc'] + self.sqrta = res['sqrta'] + self.omega0 = res['omega0'] + self.omegadot = res['omegadot'] + self.w = res['w'] + self.inc = res['inc'] + self.inc_dot = res['inc_dot'] + self.af0 = res['af0'] + self.af1 = res['af1'] + self.af2 = res['af2'] + self.toe_tow = res['toe_tow'] + self.toe_wn = res['toe_wn'] + self.toc_tow = res['toc_tow'] + self.toc_wn = res['toc_wn'] + self.valid = res['valid'] + self.healthy = res['healthy'] + self.sid = res['sid'] + self.iode = res['iode'] + self.iodc = res['iodc'] + self.reserved = res['reserved'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tgd: double + ret += 8 + # c_rs: double + ret += 8 + # c_rc: double + ret += 8 + # c_uc: double + ret += 8 + # c_us: double + ret += 8 + # c_ic: double + ret += 8 + # c_is: double + ret += 8 + # dn: double + ret += 8 + # m0: double + ret += 8 + # ecc: double + ret += 8 + # sqrta: double + ret += 8 + # omega0: double + ret += 8 + # omegadot: double + ret += 8 + # w: double + ret += 8 + # inc: double + ret += 8 + # inc_dot: double + ret += 8 + # af0: double + ret += 8 + # af1: double + ret += 8 + # af2: double + ret += 8 + # toe_tow: double + ret += 8 + # toe_wn: u16 + ret += 2 + # toc_tow: double + ret += 8 + # toc_wn: u16 + ret += 2 + # valid: u8 + ret += 1 + # healthy: u8 + ret += 1 + # sid: GnssSignalDep + ret += GnssSignalDep._payload_size() + # iode: u8 + ret += 1 + # iodc: u16 + ret += 2 + # reserved: u32 + ret += 4 + return ret + +class ObservationHeaderDep(object): + """SBP class for message ObservationHeaderDep + + You can have ObservationHeaderDep inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Header of a GPS observation message. + + """ + __slots__ = ['t', + 'n_obs', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__t, offset, length) = GPSTimeDep.parse_members(buf, offset, length) + ret['t'] = __t + (__n_obs, offset, length) = get_u8(buf, offset, length) + ret['n_obs'] = __n_obs + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.t = res['t'] + self.n_obs = res['n_obs'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # t: GPSTimeDep + ret += GPSTimeDep._payload_size() + # n_obs: u8 + ret += 1 + return ret + +class CarrierPhaseDepA(object): + """SBP class for message CarrierPhaseDepA + + You can have CarrierPhaseDepA inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Carrier phase measurement in cycles represented as a 40-bit +fixed point number with Q32.8 layout, i.e. 32-bits of whole +cycles and 8-bits of fractional cycles. This has the opposite +sign convention than a typical GPS receiver and the phase has +the opposite sign as the pseudorange. + + + """ + __slots__ = ['i', + 'f', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__i, offset, length) = get_s32(buf, offset, length) + ret['i'] = __i + (__f, offset, length) = get_u8(buf, offset, length) + ret['f'] = __f + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.i = res['i'] + self.f = res['f'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # i: s32 + ret += 4 + # f: u8 + ret += 1 + return ret + +class PackedObsContentDepA(object): + """SBP class for message PackedObsContentDepA + + You can have PackedObsContentDepA inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['P', + 'L', + 'cn0', + 'lock', + 'prn', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__P, offset, length) = get_u32(buf, offset, length) + ret['P'] = __P + (__L, offset, length) = CarrierPhaseDepA.parse_members(buf, offset, length) + ret['L'] = __L + (__cn0, offset, length) = get_u8(buf, offset, length) + ret['cn0'] = __cn0 + (__lock, offset, length) = get_u16(buf, offset, length) + ret['lock'] = __lock + (__prn, offset, length) = get_u8(buf, offset, length) + ret['prn'] = __prn + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.P = res['P'] + self.L = res['L'] + self.cn0 = res['cn0'] + self.lock = res['lock'] + self.prn = res['prn'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # P: u32 + ret += 4 + # L: CarrierPhaseDepA + ret += CarrierPhaseDepA._payload_size() + # cn0: u8 + ret += 1 + # lock: u16 + ret += 2 + # prn: u8 + ret += 1 + return ret + +class PackedObsContentDepB(object): + """SBP class for message PackedObsContentDepB + + You can have PackedObsContentDepB inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Pseudorange and carrier phase observation for a satellite being +tracked. Pseudoranges are referenced to a nominal pseudorange. + + + """ + __slots__ = ['P', + 'L', + 'cn0', + 'lock', + 'sid', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__P, offset, length) = get_u32(buf, offset, length) + ret['P'] = __P + (__L, offset, length) = CarrierPhaseDepA.parse_members(buf, offset, length) + ret['L'] = __L + (__cn0, offset, length) = get_u8(buf, offset, length) + ret['cn0'] = __cn0 + (__lock, offset, length) = get_u16(buf, offset, length) + ret['lock'] = __lock + (__sid, offset, length) = GnssSignalDep.parse_members(buf, offset, length) + ret['sid'] = __sid + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.P = res['P'] + self.L = res['L'] + self.cn0 = res['cn0'] + self.lock = res['lock'] + self.sid = res['sid'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # P: u32 + ret += 4 + # L: CarrierPhaseDepA + ret += CarrierPhaseDepA._payload_size() + # cn0: u8 + ret += 1 + # lock: u16 + ret += 2 + # sid: GnssSignalDep + ret += GnssSignalDep._payload_size() + return ret + +class PackedObsContentDepC(object): + """SBP class for message PackedObsContentDepC + + You can have PackedObsContentDepC inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Pseudorange and carrier phase observation for a satellite being +tracked. The observations are be interoperable with 3rd party +receivers and conform with typical RTCMv3 GNSS observations. + + + """ + __slots__ = ['P', + 'L', + 'cn0', + 'lock', + 'sid', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__P, offset, length) = get_u32(buf, offset, length) + ret['P'] = __P + (__L, offset, length) = CarrierPhase.parse_members(buf, offset, length) + ret['L'] = __L + (__cn0, offset, length) = get_u8(buf, offset, length) + ret['cn0'] = __cn0 + (__lock, offset, length) = get_u16(buf, offset, length) + ret['lock'] = __lock + (__sid, offset, length) = GnssSignalDep.parse_members(buf, offset, length) + ret['sid'] = __sid + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.P = res['P'] + self.L = res['L'] + self.cn0 = res['cn0'] + self.lock = res['lock'] + self.sid = res['sid'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # P: u32 + ret += 4 + # L: CarrierPhase + ret += CarrierPhase._payload_size() + # cn0: u8 + ret += 1 + # lock: u16 + ret += 2 + # sid: GnssSignalDep + ret += GnssSignalDep._payload_size() + return ret + +SBP_MSG_OBS_DEP_A = 0x0045 +class MsgObsDepA(SBP): + """SBP class for message MSG_OBS_DEP_A (0x0045). + + You can have MSG_OBS_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['header', + 'obs', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__header, offset, length) = ObservationHeaderDep.parse_members(buf, offset, length) + ret['header'] = __header + (__obs, offset, length) = get_array(PackedObsContentDepA.parse_members)(buf, offset, length) + ret['obs'] = __obs + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.header = res['header'] + self.obs = res['obs'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # header: ObservationHeaderDep + ret += ObservationHeaderDep._payload_size() + # obs: array of PackedObsContentDepA + ret += 247 + return ret + +SBP_MSG_OBS_DEP_B = 0x0043 +class MsgObsDepB(SBP): + """SBP class for message MSG_OBS_DEP_B (0x0043). + + You can have MSG_OBS_DEP_B inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This observation message has been deprecated in favor of +observations that are more interoperable. This message +should be used for observations referenced to +a nominal pseudorange which are not interoperable with +most 3rd party GNSS receievers or typical RTCMv3 +observations. + + + """ + __slots__ = ['header', + 'obs', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__header, offset, length) = ObservationHeaderDep.parse_members(buf, offset, length) + ret['header'] = __header + (__obs, offset, length) = get_array(PackedObsContentDepB.parse_members)(buf, offset, length) + ret['obs'] = __obs + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.header = res['header'] + self.obs = res['obs'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # header: ObservationHeaderDep + ret += ObservationHeaderDep._payload_size() + # obs: array of PackedObsContentDepB + ret += 247 + return ret + +SBP_MSG_OBS_DEP_C = 0x0049 +class MsgObsDepC(SBP): + """SBP class for message MSG_OBS_DEP_C (0x0049). + + You can have MSG_OBS_DEP_C inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The GPS observations message reports all the raw pseudorange and +carrier phase observations for the satellites being tracked by +the device. Carrier phase observation here is represented as a +40-bit fixed point number with Q32.8 layout (i.e. 32-bits of +whole cycles and 8-bits of fractional cycles). The observations +are interoperable with 3rd party receivers and conform +with typical RTCMv3 GNSS observations. + + + """ + __slots__ = ['header', + 'obs', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__header, offset, length) = ObservationHeaderDep.parse_members(buf, offset, length) + ret['header'] = __header + (__obs, offset, length) = get_array(PackedObsContentDepC.parse_members)(buf, offset, length) + ret['obs'] = __obs + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.header = res['header'] + self.obs = res['obs'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # header: ObservationHeaderDep + ret += ObservationHeaderDep._payload_size() + # obs: array of PackedObsContentDepC + ret += 247 + return ret + +SBP_MSG_IONO = 0x0090 +class MsgIono(SBP): + """SBP class for message MSG_IONO (0x0090). + + You can have MSG_IONO inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The ionospheric parameters which allow the "L1 only" or "L2 only" user to +utilize the ionospheric model for computation of the ionospheric delay. +Please see ICD-GPS-200 (Chapter 20.3.3.5.1.7) for more details. + + + """ + __slots__ = ['t_nmct', + 'a0', + 'a1', + 'a2', + 'a3', + 'b0', + 'b1', + 'b2', + 'b3', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__t_nmct, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['t_nmct'] = __t_nmct + (__a0, offset, length) = get_f64(buf, offset, length) + ret['a0'] = __a0 + (__a1, offset, length) = get_f64(buf, offset, length) + ret['a1'] = __a1 + (__a2, offset, length) = get_f64(buf, offset, length) + ret['a2'] = __a2 + (__a3, offset, length) = get_f64(buf, offset, length) + ret['a3'] = __a3 + (__b0, offset, length) = get_f64(buf, offset, length) + ret['b0'] = __b0 + (__b1, offset, length) = get_f64(buf, offset, length) + ret['b1'] = __b1 + (__b2, offset, length) = get_f64(buf, offset, length) + ret['b2'] = __b2 + (__b3, offset, length) = get_f64(buf, offset, length) + ret['b3'] = __b3 + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.t_nmct = res['t_nmct'] + self.a0 = res['a0'] + self.a1 = res['a1'] + self.a2 = res['a2'] + self.a3 = res['a3'] + self.b0 = res['b0'] + self.b1 = res['b1'] + self.b2 = res['b2'] + self.b3 = res['b3'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # t_nmct: GPSTimeSec + ret += GPSTimeSec._payload_size() + # a0: double + ret += 8 + # a1: double + ret += 8 + # a2: double + ret += 8 + # a3: double + ret += 8 + # b0: double + ret += 8 + # b1: double + ret += 8 + # b2: double + ret += 8 + # b3: double + ret += 8 + return ret + +SBP_MSG_SV_CONFIGURATION_GPS_DEP = 0x0091 +class MsgSvConfigurationGPSDep(SBP): + """SBP class for message MSG_SV_CONFIGURATION_GPS_DEP (0x0091). + + You can have MSG_SV_CONFIGURATION_GPS_DEP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Please see ICD-GPS-200 (Chapter 20.3.3.5.1.4) for more details. + + + """ + __slots__ = ['t_nmct', + 'l2c_mask', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__t_nmct, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['t_nmct'] = __t_nmct + (__l2c_mask, offset, length) = get_u32(buf, offset, length) + ret['l2c_mask'] = __l2c_mask + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.t_nmct = res['t_nmct'] + self.l2c_mask = res['l2c_mask'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # t_nmct: GPSTimeSec + ret += GPSTimeSec._payload_size() + # l2c_mask: u32 + ret += 4 + return ret + +class GnssCapb(object): + """SBP class for message GnssCapb + + You can have GnssCapb inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + + """ + __slots__ = ['gps_active', + 'gps_l2c', + 'gps_l5', + 'glo_active', + 'glo_l2of', + 'glo_l3', + 'sbas_active', + 'sbas_l5', + 'bds_active', + 'bds_d2nav', + 'bds_b2', + 'bds_b2a', + 'qzss_active', + 'gal_active', + 'gal_e5', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__gps_active, offset, length) = get_u64(buf, offset, length) + ret['gps_active'] = __gps_active + (__gps_l2c, offset, length) = get_u64(buf, offset, length) + ret['gps_l2c'] = __gps_l2c + (__gps_l5, offset, length) = get_u64(buf, offset, length) + ret['gps_l5'] = __gps_l5 + (__glo_active, offset, length) = get_u32(buf, offset, length) + ret['glo_active'] = __glo_active + (__glo_l2of, offset, length) = get_u32(buf, offset, length) + ret['glo_l2of'] = __glo_l2of + (__glo_l3, offset, length) = get_u32(buf, offset, length) + ret['glo_l3'] = __glo_l3 + (__sbas_active, offset, length) = get_u64(buf, offset, length) + ret['sbas_active'] = __sbas_active + (__sbas_l5, offset, length) = get_u64(buf, offset, length) + ret['sbas_l5'] = __sbas_l5 + (__bds_active, offset, length) = get_u64(buf, offset, length) + ret['bds_active'] = __bds_active + (__bds_d2nav, offset, length) = get_u64(buf, offset, length) + ret['bds_d2nav'] = __bds_d2nav + (__bds_b2, offset, length) = get_u64(buf, offset, length) + ret['bds_b2'] = __bds_b2 + (__bds_b2a, offset, length) = get_u64(buf, offset, length) + ret['bds_b2a'] = __bds_b2a + (__qzss_active, offset, length) = get_u32(buf, offset, length) + ret['qzss_active'] = __qzss_active + (__gal_active, offset, length) = get_u64(buf, offset, length) + ret['gal_active'] = __gal_active + (__gal_e5, offset, length) = get_u64(buf, offset, length) + ret['gal_e5'] = __gal_e5 + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.gps_active = res['gps_active'] + self.gps_l2c = res['gps_l2c'] + self.gps_l5 = res['gps_l5'] + self.glo_active = res['glo_active'] + self.glo_l2of = res['glo_l2of'] + self.glo_l3 = res['glo_l3'] + self.sbas_active = res['sbas_active'] + self.sbas_l5 = res['sbas_l5'] + self.bds_active = res['bds_active'] + self.bds_d2nav = res['bds_d2nav'] + self.bds_b2 = res['bds_b2'] + self.bds_b2a = res['bds_b2a'] + self.qzss_active = res['qzss_active'] + self.gal_active = res['gal_active'] + self.gal_e5 = res['gal_e5'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # gps_active: u64 + ret += 8 + # gps_l2c: u64 + ret += 8 + # gps_l5: u64 + ret += 8 + # glo_active: u32 + ret += 4 + # glo_l2of: u32 + ret += 4 + # glo_l3: u32 + ret += 4 + # sbas_active: u64 + ret += 8 + # sbas_l5: u64 + ret += 8 + # bds_active: u64 + ret += 8 + # bds_d2nav: u64 + ret += 8 + # bds_b2: u64 + ret += 8 + # bds_b2a: u64 + ret += 8 + # qzss_active: u32 + ret += 4 + # gal_active: u64 + ret += 8 + # gal_e5: u64 + ret += 8 + return ret + +SBP_MSG_GNSS_CAPB = 0x0096 +class MsgGnssCapb(SBP): + """SBP class for message MSG_GNSS_CAPB (0x0096). + + You can have MSG_GNSS_CAPB inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + + """ + __slots__ = ['t_nmct', + 'gc', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__t_nmct, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['t_nmct'] = __t_nmct + (__gc, offset, length) = GnssCapb.parse_members(buf, offset, length) + ret['gc'] = __gc + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.t_nmct = res['t_nmct'] + self.gc = res['gc'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # t_nmct: GPSTimeSec + ret += GPSTimeSec._payload_size() + # gc: GnssCapb + ret += GnssCapb._payload_size() + return ret + +SBP_MSG_GROUP_DELAY_DEP_A = 0x0092 +class MsgGroupDelayDepA(SBP): + """SBP class for message MSG_GROUP_DELAY_DEP_A (0x0092). + + You can have MSG_GROUP_DELAY_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Please see ICD-GPS-200 (30.3.3.3.1.1) for more details. + + """ + __slots__ = ['t_op', + 'prn', + 'valid', + 'tgd', + 'isc_l1ca', + 'isc_l2c', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__t_op, offset, length) = GPSTimeDep.parse_members(buf, offset, length) + ret['t_op'] = __t_op + (__prn, offset, length) = get_u8(buf, offset, length) + ret['prn'] = __prn + (__valid, offset, length) = get_u8(buf, offset, length) + ret['valid'] = __valid + (__tgd, offset, length) = get_s16(buf, offset, length) + ret['tgd'] = __tgd + (__isc_l1ca, offset, length) = get_s16(buf, offset, length) + ret['isc_l1ca'] = __isc_l1ca + (__isc_l2c, offset, length) = get_s16(buf, offset, length) + ret['isc_l2c'] = __isc_l2c + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.t_op = res['t_op'] + self.prn = res['prn'] + self.valid = res['valid'] + self.tgd = res['tgd'] + self.isc_l1ca = res['isc_l1ca'] + self.isc_l2c = res['isc_l2c'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # t_op: GPSTimeDep + ret += GPSTimeDep._payload_size() + # prn: u8 + ret += 1 + # valid: u8 + ret += 1 + # tgd: s16 + ret += 2 + # isc_l1ca: s16 + ret += 2 + # isc_l2c: s16 + ret += 2 + return ret + +SBP_MSG_GROUP_DELAY_DEP_B = 0x0093 +class MsgGroupDelayDepB(SBP): + """SBP class for message MSG_GROUP_DELAY_DEP_B (0x0093). + + You can have MSG_GROUP_DELAY_DEP_B inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Please see ICD-GPS-200 (30.3.3.3.1.1) for more details. + + """ + __slots__ = ['t_op', + 'sid', + 'valid', + 'tgd', + 'isc_l1ca', + 'isc_l2c', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__t_op, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['t_op'] = __t_op + (__sid, offset, length) = GnssSignalDep.parse_members(buf, offset, length) + ret['sid'] = __sid + (__valid, offset, length) = get_u8(buf, offset, length) + ret['valid'] = __valid + (__tgd, offset, length) = get_s16(buf, offset, length) + ret['tgd'] = __tgd + (__isc_l1ca, offset, length) = get_s16(buf, offset, length) + ret['isc_l1ca'] = __isc_l1ca + (__isc_l2c, offset, length) = get_s16(buf, offset, length) + ret['isc_l2c'] = __isc_l2c + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.t_op = res['t_op'] + self.sid = res['sid'] + self.valid = res['valid'] + self.tgd = res['tgd'] + self.isc_l1ca = res['isc_l1ca'] + self.isc_l2c = res['isc_l2c'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # t_op: GPSTimeSec + ret += GPSTimeSec._payload_size() + # sid: GnssSignalDep + ret += GnssSignalDep._payload_size() + # valid: u8 + ret += 1 + # tgd: s16 + ret += 2 + # isc_l1ca: s16 + ret += 2 + # isc_l2c: s16 + ret += 2 + return ret + +SBP_MSG_GROUP_DELAY = 0x0094 +class MsgGroupDelay(SBP): + """SBP class for message MSG_GROUP_DELAY (0x0094). + + You can have MSG_GROUP_DELAY inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Please see ICD-GPS-200 (30.3.3.3.1.1) for more details. + + """ + __slots__ = ['t_op', + 'sid', + 'valid', + 'tgd', + 'isc_l1ca', + 'isc_l2c', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__t_op, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['t_op'] = __t_op + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__valid, offset, length) = get_u8(buf, offset, length) + ret['valid'] = __valid + (__tgd, offset, length) = get_s16(buf, offset, length) + ret['tgd'] = __tgd + (__isc_l1ca, offset, length) = get_s16(buf, offset, length) + ret['isc_l1ca'] = __isc_l1ca + (__isc_l2c, offset, length) = get_s16(buf, offset, length) + ret['isc_l2c'] = __isc_l2c + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.t_op = res['t_op'] + self.sid = res['sid'] + self.valid = res['valid'] + self.tgd = res['tgd'] + self.isc_l1ca = res['isc_l1ca'] + self.isc_l2c = res['isc_l2c'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # t_op: GPSTimeSec + ret += GPSTimeSec._payload_size() + # sid: GnssSignal + ret += GnssSignal._payload_size() + # valid: u8 + ret += 1 + # tgd: s16 + ret += 2 + # isc_l1ca: s16 + ret += 2 + # isc_l2c: s16 + ret += 2 + return ret + +class AlmanacCommonContent(object): + """SBP class for message AlmanacCommonContent + + You can have AlmanacCommonContent inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + + """ + __slots__ = ['sid', + 'toa', + 'ura', + 'fit_interval', + 'valid', + 'health_bits', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__toa, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['toa'] = __toa + (__ura, offset, length) = get_f64(buf, offset, length) + ret['ura'] = __ura + (__fit_interval, offset, length) = get_u32(buf, offset, length) + ret['fit_interval'] = __fit_interval + (__valid, offset, length) = get_u8(buf, offset, length) + ret['valid'] = __valid + (__health_bits, offset, length) = get_u8(buf, offset, length) + ret['health_bits'] = __health_bits + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sid = res['sid'] + self.toa = res['toa'] + self.ura = res['ura'] + self.fit_interval = res['fit_interval'] + self.valid = res['valid'] + self.health_bits = res['health_bits'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sid: GnssSignal + ret += GnssSignal._payload_size() + # toa: GPSTimeSec + ret += GPSTimeSec._payload_size() + # ura: double + ret += 8 + # fit_interval: u32 + ret += 4 + # valid: u8 + ret += 1 + # health_bits: u8 + ret += 1 + return ret + +class AlmanacCommonContentDep(object): + """SBP class for message AlmanacCommonContentDep + + You can have AlmanacCommonContentDep inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + + """ + __slots__ = ['sid', + 'toa', + 'ura', + 'fit_interval', + 'valid', + 'health_bits', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sid, offset, length) = GnssSignalDep.parse_members(buf, offset, length) + ret['sid'] = __sid + (__toa, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['toa'] = __toa + (__ura, offset, length) = get_f64(buf, offset, length) + ret['ura'] = __ura + (__fit_interval, offset, length) = get_u32(buf, offset, length) + ret['fit_interval'] = __fit_interval + (__valid, offset, length) = get_u8(buf, offset, length) + ret['valid'] = __valid + (__health_bits, offset, length) = get_u8(buf, offset, length) + ret['health_bits'] = __health_bits + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sid = res['sid'] + self.toa = res['toa'] + self.ura = res['ura'] + self.fit_interval = res['fit_interval'] + self.valid = res['valid'] + self.health_bits = res['health_bits'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sid: GnssSignalDep + ret += GnssSignalDep._payload_size() + # toa: GPSTimeSec + ret += GPSTimeSec._payload_size() + # ura: double + ret += 8 + # fit_interval: u32 + ret += 4 + # valid: u8 + ret += 1 + # health_bits: u8 + ret += 1 + return ret + +SBP_MSG_ALMANAC_GPS_DEP = 0x0070 +class MsgAlmanacGPSDep(SBP): + """SBP class for message MSG_ALMANAC_GPS_DEP (0x0070). + + You can have MSG_ALMANAC_GPS_DEP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The almanac message returns a set of satellite orbit parameters. Almanac +data is not very precise and is considered valid for up to several months. +Please see the Navstar GPS Space Segment/Navigation user interfaces +(ICD-GPS-200, Chapter 20.3.3.5.1.2 Almanac Data) for more details. + + + """ + __slots__ = ['common', + 'm0', + 'ecc', + 'sqrta', + 'omega0', + 'omegadot', + 'w', + 'inc', + 'af0', + 'af1', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = AlmanacCommonContentDep.parse_members(buf, offset, length) + ret['common'] = __common + (__m0, offset, length) = get_f64(buf, offset, length) + ret['m0'] = __m0 + (__ecc, offset, length) = get_f64(buf, offset, length) + ret['ecc'] = __ecc + (__sqrta, offset, length) = get_f64(buf, offset, length) + ret['sqrta'] = __sqrta + (__omega0, offset, length) = get_f64(buf, offset, length) + ret['omega0'] = __omega0 + (__omegadot, offset, length) = get_f64(buf, offset, length) + ret['omegadot'] = __omegadot + (__w, offset, length) = get_f64(buf, offset, length) + ret['w'] = __w + (__inc, offset, length) = get_f64(buf, offset, length) + ret['inc'] = __inc + (__af0, offset, length) = get_f64(buf, offset, length) + ret['af0'] = __af0 + (__af1, offset, length) = get_f64(buf, offset, length) + ret['af1'] = __af1 + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.m0 = res['m0'] + self.ecc = res['ecc'] + self.sqrta = res['sqrta'] + self.omega0 = res['omega0'] + self.omegadot = res['omegadot'] + self.w = res['w'] + self.inc = res['inc'] + self.af0 = res['af0'] + self.af1 = res['af1'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: AlmanacCommonContentDep + ret += AlmanacCommonContentDep._payload_size() + # m0: double + ret += 8 + # ecc: double + ret += 8 + # sqrta: double + ret += 8 + # omega0: double + ret += 8 + # omegadot: double + ret += 8 + # w: double + ret += 8 + # inc: double + ret += 8 + # af0: double + ret += 8 + # af1: double + ret += 8 + return ret + +SBP_MSG_ALMANAC_GPS = 0x0072 +class MsgAlmanacGPS(SBP): + """SBP class for message MSG_ALMANAC_GPS (0x0072). + + You can have MSG_ALMANAC_GPS inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The almanac message returns a set of satellite orbit parameters. Almanac +data is not very precise and is considered valid for up to several months. +Please see the Navstar GPS Space Segment/Navigation user interfaces +(ICD-GPS-200, Chapter 20.3.3.5.1.2 Almanac Data) for more details. + + + """ + __slots__ = ['common', + 'm0', + 'ecc', + 'sqrta', + 'omega0', + 'omegadot', + 'w', + 'inc', + 'af0', + 'af1', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = AlmanacCommonContent.parse_members(buf, offset, length) + ret['common'] = __common + (__m0, offset, length) = get_f64(buf, offset, length) + ret['m0'] = __m0 + (__ecc, offset, length) = get_f64(buf, offset, length) + ret['ecc'] = __ecc + (__sqrta, offset, length) = get_f64(buf, offset, length) + ret['sqrta'] = __sqrta + (__omega0, offset, length) = get_f64(buf, offset, length) + ret['omega0'] = __omega0 + (__omegadot, offset, length) = get_f64(buf, offset, length) + ret['omegadot'] = __omegadot + (__w, offset, length) = get_f64(buf, offset, length) + ret['w'] = __w + (__inc, offset, length) = get_f64(buf, offset, length) + ret['inc'] = __inc + (__af0, offset, length) = get_f64(buf, offset, length) + ret['af0'] = __af0 + (__af1, offset, length) = get_f64(buf, offset, length) + ret['af1'] = __af1 + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.m0 = res['m0'] + self.ecc = res['ecc'] + self.sqrta = res['sqrta'] + self.omega0 = res['omega0'] + self.omegadot = res['omegadot'] + self.w = res['w'] + self.inc = res['inc'] + self.af0 = res['af0'] + self.af1 = res['af1'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: AlmanacCommonContent + ret += AlmanacCommonContent._payload_size() + # m0: double + ret += 8 + # ecc: double + ret += 8 + # sqrta: double + ret += 8 + # omega0: double + ret += 8 + # omegadot: double + ret += 8 + # w: double + ret += 8 + # inc: double + ret += 8 + # af0: double + ret += 8 + # af1: double + ret += 8 + return ret + +SBP_MSG_ALMANAC_GLO_DEP = 0x0071 +class MsgAlmanacGloDep(SBP): + """SBP class for message MSG_ALMANAC_GLO_DEP (0x0071). + + You can have MSG_ALMANAC_GLO_DEP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The almanac message returns a set of satellite orbit parameters. Almanac +data is not very precise and is considered valid for up to several months. +Please see the GLO ICD 5.1 "Chapter 4.5 Non-immediate information and +almanac" for details. + + + """ + __slots__ = ['common', + 'lambda_na', + 't_lambda_na', + 'i', + 't', + 't_dot', + 'epsilon', + 'omega', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = AlmanacCommonContentDep.parse_members(buf, offset, length) + ret['common'] = __common + (__lambda_na, offset, length) = get_f64(buf, offset, length) + ret['lambda_na'] = __lambda_na + (__t_lambda_na, offset, length) = get_f64(buf, offset, length) + ret['t_lambda_na'] = __t_lambda_na + (__i, offset, length) = get_f64(buf, offset, length) + ret['i'] = __i + (__t, offset, length) = get_f64(buf, offset, length) + ret['t'] = __t + (__t_dot, offset, length) = get_f64(buf, offset, length) + ret['t_dot'] = __t_dot + (__epsilon, offset, length) = get_f64(buf, offset, length) + ret['epsilon'] = __epsilon + (__omega, offset, length) = get_f64(buf, offset, length) + ret['omega'] = __omega + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.lambda_na = res['lambda_na'] + self.t_lambda_na = res['t_lambda_na'] + self.i = res['i'] + self.t = res['t'] + self.t_dot = res['t_dot'] + self.epsilon = res['epsilon'] + self.omega = res['omega'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: AlmanacCommonContentDep + ret += AlmanacCommonContentDep._payload_size() + # lambda_na: double + ret += 8 + # t_lambda_na: double + ret += 8 + # i: double + ret += 8 + # t: double + ret += 8 + # t_dot: double + ret += 8 + # epsilon: double + ret += 8 + # omega: double + ret += 8 + return ret + +SBP_MSG_ALMANAC_GLO = 0x0073 +class MsgAlmanacGlo(SBP): + """SBP class for message MSG_ALMANAC_GLO (0x0073). + + You can have MSG_ALMANAC_GLO inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The almanac message returns a set of satellite orbit parameters. Almanac +data is not very precise and is considered valid for up to several months. +Please see the GLO ICD 5.1 "Chapter 4.5 Non-immediate information and +almanac" for details. + + + """ + __slots__ = ['common', + 'lambda_na', + 't_lambda_na', + 'i', + 't', + 't_dot', + 'epsilon', + 'omega', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__common, offset, length) = AlmanacCommonContent.parse_members(buf, offset, length) + ret['common'] = __common + (__lambda_na, offset, length) = get_f64(buf, offset, length) + ret['lambda_na'] = __lambda_na + (__t_lambda_na, offset, length) = get_f64(buf, offset, length) + ret['t_lambda_na'] = __t_lambda_na + (__i, offset, length) = get_f64(buf, offset, length) + ret['i'] = __i + (__t, offset, length) = get_f64(buf, offset, length) + ret['t'] = __t + (__t_dot, offset, length) = get_f64(buf, offset, length) + ret['t_dot'] = __t_dot + (__epsilon, offset, length) = get_f64(buf, offset, length) + ret['epsilon'] = __epsilon + (__omega, offset, length) = get_f64(buf, offset, length) + ret['omega'] = __omega + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.common = res['common'] + self.lambda_na = res['lambda_na'] + self.t_lambda_na = res['t_lambda_na'] + self.i = res['i'] + self.t = res['t'] + self.t_dot = res['t_dot'] + self.epsilon = res['epsilon'] + self.omega = res['omega'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # common: AlmanacCommonContent + ret += AlmanacCommonContent._payload_size() + # lambda_na: double + ret += 8 + # t_lambda_na: double + ret += 8 + # i: double + ret += 8 + # t: double + ret += 8 + # t_dot: double + ret += 8 + # epsilon: double + ret += 8 + # omega: double + ret += 8 + return ret + +SBP_MSG_GLO_BIASES = 0x0075 +class MsgGloBiases(SBP): + """SBP class for message MSG_GLO_BIASES (0x0075). + + You can have MSG_GLO_BIASES inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The GLONASS L1/L2 Code-Phase biases allows to perform +GPS+GLONASS integer ambiguity resolution for baselines +with mixed receiver types (e.g. receiver of different +manufacturers) + + + """ + __slots__ = ['mask', + 'l1ca_bias', + 'l1p_bias', + 'l2ca_bias', + 'l2p_bias', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__mask, offset, length) = get_u8(buf, offset, length) + ret['mask'] = __mask + (__l1ca_bias, offset, length) = get_s16(buf, offset, length) + ret['l1ca_bias'] = __l1ca_bias + (__l1p_bias, offset, length) = get_s16(buf, offset, length) + ret['l1p_bias'] = __l1p_bias + (__l2ca_bias, offset, length) = get_s16(buf, offset, length) + ret['l2ca_bias'] = __l2ca_bias + (__l2p_bias, offset, length) = get_s16(buf, offset, length) + ret['l2p_bias'] = __l2p_bias + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.mask = res['mask'] + self.l1ca_bias = res['l1ca_bias'] + self.l1p_bias = res['l1p_bias'] + self.l2ca_bias = res['l2ca_bias'] + self.l2p_bias = res['l2p_bias'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # mask: u8 + ret += 1 + # l1ca_bias: s16 + ret += 2 + # l1p_bias: s16 + ret += 2 + # l2ca_bias: s16 + ret += 2 + # l2p_bias: s16 + ret += 2 + return ret + +class SvAzEl(object): + """SBP class for message SvAzEl + + You can have SvAzEl inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Satellite azimuth and elevation. + + """ + __slots__ = ['sid', + 'az', + 'el', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__az, offset, length) = get_u8(buf, offset, length) + ret['az'] = __az + (__el, offset, length) = get_s8(buf, offset, length) + ret['el'] = __el + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sid = res['sid'] + self.az = res['az'] + self.el = res['el'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sid: GnssSignal + ret += GnssSignal._payload_size() + # az: u8 + ret += 1 + # el: s8 + ret += 1 + return ret + +SBP_MSG_SV_AZ_EL = 0x0097 +class MsgSvAzEl(SBP): + """SBP class for message MSG_SV_AZ_EL (0x0097). + + You can have MSG_SV_AZ_EL inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Azimuth and elevation angles of all the visible satellites +that the device does have ephemeris or almanac for. + + + """ + __slots__ = ['azel', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__azel, offset, length) = get_array(SvAzEl.parse_members)(buf, offset, length) + ret['azel'] = __azel + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.azel = res['azel'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # azel: array of SvAzEl + ret += 247 + return ret + +SBP_MSG_OSR = 0x0640 +class MsgOsr(SBP): + """SBP class for message MSG_OSR (0x0640). + + You can have MSG_OSR inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The OSR message contains network corrections in an observation-like format + + + """ + __slots__ = ['header', + 'obs', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__header, offset, length) = ObservationHeader.parse_members(buf, offset, length) + ret['header'] = __header + (__obs, offset, length) = get_array(PackedOsrContent.parse_members)(buf, offset, length) + ret['obs'] = __obs + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.header = res['header'] + self.obs = res['obs'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # header: ObservationHeader + ret += ObservationHeader._payload_size() + # obs: array of PackedOsrContent + ret += 247 + return ret + + +msg_classes = { + 0x004A: MsgObs, + 0x0044: MsgBasePosLLH, + 0x0048: MsgBasePosECEF, + 0x0081: MsgEphemerisGPSDepE, + 0x0086: MsgEphemerisGPSDepF, + 0x008A: MsgEphemerisGPS, + 0x0089: MsgEphemerisBds, + 0x0095: MsgEphemerisGal, + 0x0082: MsgEphemerisSbasDepA, + 0x0083: MsgEphemerisGloDepA, + 0x0084: MsgEphemerisSbasDepB, + 0x008C: MsgEphemerisSbas, + 0x0085: MsgEphemerisGloDepB, + 0x0087: MsgEphemerisGloDepC, + 0x0088: MsgEphemerisGloDepD, + 0x008B: MsgEphemerisGlo, + 0x0080: MsgEphemerisDepD, + 0x001A: MsgEphemerisDepA, + 0x0046: MsgEphemerisDepB, + 0x0047: MsgEphemerisDepC, + 0x0045: MsgObsDepA, + 0x0043: MsgObsDepB, + 0x0049: MsgObsDepC, + 0x0090: MsgIono, + 0x0091: MsgSvConfigurationGPSDep, + 0x0096: MsgGnssCapb, + 0x0092: MsgGroupDelayDepA, + 0x0093: MsgGroupDelayDepB, + 0x0094: MsgGroupDelay, + 0x0070: MsgAlmanacGPSDep, + 0x0072: MsgAlmanacGPS, + 0x0071: MsgAlmanacGloDep, + 0x0073: MsgAlmanacGlo, + 0x0075: MsgGloBiases, + 0x0097: MsgSvAzEl, + 0x0640: MsgOsr, +} \ No newline at end of file diff --git a/python/sbp/jit/orientation.py b/python/sbp/jit/orientation.py new file mode 100644 index 0000000000..5ed7f4cbc8 --- /dev/null +++ b/python/sbp/jit/orientation.py @@ -0,0 +1,337 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Orientation Messages +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +# Automatically generated from piksi/yaml/swiftnav/sbp/orientation.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_BASELINE_HEADING = 0x020F +class MsgBaselineHeading(SBP): + """SBP class for message MSG_BASELINE_HEADING (0x020F). + + You can have MSG_BASELINE_HEADING inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the baseline heading pointing from the base station +to the rover relative to True North. The full GPS time is given by the +preceding MSG_GPS_TIME with the matching time-of-week (tow). It is intended +that time-matched RTK mode is used when the base station is moving. + + + """ + __slots__ = ['tow', + 'heading', + 'n_sats', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__heading, offset, length) = get_u32(buf, offset, length) + ret['heading'] = __heading + (__n_sats, offset, length) = get_u8(buf, offset, length) + ret['n_sats'] = __n_sats + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.heading = res['heading'] + self.n_sats = res['n_sats'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # heading: u32 + ret += 4 + # n_sats: u8 + ret += 1 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_ORIENT_QUAT = 0x0220 +class MsgOrientQuat(SBP): + """SBP class for message MSG_ORIENT_QUAT (0x0220). + + You can have MSG_ORIENT_QUAT inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the quaternion vector describing the vehicle body frame's orientation +with respect to a local-level NED frame. The components of the vector should sum to a unit +vector assuming that the LSB of each component as a value of 2^-31. This message will only +be available in future INS versions of Swift Products and is not produced by Piksi Multi +or Duro. + + + """ + __slots__ = ['tow', + 'w', + 'x', + 'y', + 'z', + 'w_accuracy', + 'x_accuracy', + 'y_accuracy', + 'z_accuracy', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__w, offset, length) = get_s32(buf, offset, length) + ret['w'] = __w + (__x, offset, length) = get_s32(buf, offset, length) + ret['x'] = __x + (__y, offset, length) = get_s32(buf, offset, length) + ret['y'] = __y + (__z, offset, length) = get_s32(buf, offset, length) + ret['z'] = __z + (__w_accuracy, offset, length) = get_f32(buf, offset, length) + ret['w_accuracy'] = judicious_round(nb.f4(__w_accuracy)) if SBP.judicious_rounding else __w_accuracy + (__x_accuracy, offset, length) = get_f32(buf, offset, length) + ret['x_accuracy'] = judicious_round(nb.f4(__x_accuracy)) if SBP.judicious_rounding else __x_accuracy + (__y_accuracy, offset, length) = get_f32(buf, offset, length) + ret['y_accuracy'] = judicious_round(nb.f4(__y_accuracy)) if SBP.judicious_rounding else __y_accuracy + (__z_accuracy, offset, length) = get_f32(buf, offset, length) + ret['z_accuracy'] = judicious_round(nb.f4(__z_accuracy)) if SBP.judicious_rounding else __z_accuracy + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.w = res['w'] + self.x = res['x'] + self.y = res['y'] + self.z = res['z'] + self.w_accuracy = res['w_accuracy'] + self.x_accuracy = res['x_accuracy'] + self.y_accuracy = res['y_accuracy'] + self.z_accuracy = res['z_accuracy'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # w: s32 + ret += 4 + # x: s32 + ret += 4 + # y: s32 + ret += 4 + # z: s32 + ret += 4 + # w_accuracy: float + ret += 4 + # x_accuracy: float + ret += 4 + # y_accuracy: float + ret += 4 + # z_accuracy: float + ret += 4 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_ORIENT_EULER = 0x0221 +class MsgOrientEuler(SBP): + """SBP class for message MSG_ORIENT_EULER (0x0221). + + You can have MSG_ORIENT_EULER inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the yaw, pitch, and roll angles of the vehicle body frame. +The rotations should applied intrinsically in the order yaw, pitch, and roll +in order to rotate the from a frame aligned with the local-level NED frame +to the vehicle body frame. This message will only be available in future +INS versions of Swift Products and is not produced by Piksi Multi or Duro. + + + """ + __slots__ = ['tow', + 'roll', + 'pitch', + 'yaw', + 'roll_accuracy', + 'pitch_accuracy', + 'yaw_accuracy', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__roll, offset, length) = get_s32(buf, offset, length) + ret['roll'] = __roll + (__pitch, offset, length) = get_s32(buf, offset, length) + ret['pitch'] = __pitch + (__yaw, offset, length) = get_s32(buf, offset, length) + ret['yaw'] = __yaw + (__roll_accuracy, offset, length) = get_f32(buf, offset, length) + ret['roll_accuracy'] = judicious_round(nb.f4(__roll_accuracy)) if SBP.judicious_rounding else __roll_accuracy + (__pitch_accuracy, offset, length) = get_f32(buf, offset, length) + ret['pitch_accuracy'] = judicious_round(nb.f4(__pitch_accuracy)) if SBP.judicious_rounding else __pitch_accuracy + (__yaw_accuracy, offset, length) = get_f32(buf, offset, length) + ret['yaw_accuracy'] = judicious_round(nb.f4(__yaw_accuracy)) if SBP.judicious_rounding else __yaw_accuracy + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.roll = res['roll'] + self.pitch = res['pitch'] + self.yaw = res['yaw'] + self.roll_accuracy = res['roll_accuracy'] + self.pitch_accuracy = res['pitch_accuracy'] + self.yaw_accuracy = res['yaw_accuracy'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # roll: s32 + ret += 4 + # pitch: s32 + ret += 4 + # yaw: s32 + ret += 4 + # roll_accuracy: float + ret += 4 + # pitch_accuracy: float + ret += 4 + # yaw_accuracy: float + ret += 4 + # flags: u8 + ret += 1 + return ret + +SBP_MSG_ANGULAR_RATE = 0x0222 +class MsgAngularRate(SBP): + """SBP class for message MSG_ANGULAR_RATE (0x0222). + + You can have MSG_ANGULAR_RATE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the orientation rates in the vehicle body frame. +The values represent the measurements a strapped down gyroscope would +make and are not equivalent to the time derivative of the Euler angles. +The orientation and origin of the user frame is specified via device settings. +By convention, the vehicle x-axis is expected to be aligned with the forward +direction, while the vehicle y-axis is expected to be aligned with the right +direction, and the vehicle z-axis should be aligned with the down direction. +This message will only be available in future INS versions of Swift Products +and is not produced by Piksi Multi or Duro. + + + """ + __slots__ = ['tow', + 'x', + 'y', + 'z', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__x, offset, length) = get_s32(buf, offset, length) + ret['x'] = __x + (__y, offset, length) = get_s32(buf, offset, length) + ret['y'] = __y + (__z, offset, length) = get_s32(buf, offset, length) + ret['z'] = __z + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.x = res['x'] + self.y = res['y'] + self.z = res['z'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # x: s32 + ret += 4 + # y: s32 + ret += 4 + # z: s32 + ret += 4 + # flags: u8 + ret += 1 + return ret + + +msg_classes = { + 0x020F: MsgBaselineHeading, + 0x0220: MsgOrientQuat, + 0x0221: MsgOrientEuler, + 0x0222: MsgAngularRate, +} \ No newline at end of file diff --git a/python/sbp/jit/parse_float.py b/python/sbp/jit/parse_float.py new file mode 100644 index 0000000000..c011031265 --- /dev/null +++ b/python/sbp/jit/parse_float.py @@ -0,0 +1,49 @@ +import cffi + +import glob +import ntpath +import os +import shutil + +ffi = cffi.FFI() +ffi.cdef(""" +float get_f32(unsigned char a, unsigned char b, unsigned char c, unsigned char d); +double get_f64(unsigned char a, unsigned char b, unsigned char c, unsigned char d, + unsigned char e, unsigned char f, unsigned char g, unsigned char h); +""") + +source = """ +float get_f32(unsigned char a, unsigned char b, unsigned char c, unsigned char d) { + union { unsigned char buf[4]; float f; } u; + u.buf[0] = a; + u.buf[1] = b; + u.buf[2] = c; + u.buf[3] = d; + return u.f; +} + +double get_f64(unsigned char a, unsigned char b, unsigned char c, unsigned char d, + unsigned char e, unsigned char f, unsigned char g, unsigned char h) { + union { unsigned char buf[8]; double d; } u; + u.buf[0] = a; + u.buf[1] = b; + u.buf[2] = c; + u.buf[3] = d; + u.buf[4] = e; + u.buf[5] = f; + u.buf[6] = g; + u.buf[7] = h; + return u.d; +} +""" + +module_name = "parse_float_c" + +ffi.set_source(module_name=module_name, source=source) + +ffi.compile() + +# Move deliverables to same dir as the script +dest_dir = os.path.dirname(os.path.realpath(__file__)) +for f in glob.glob(os.path.join(os.getcwd(), module_name + '.*')): + shutil.move(f, os.path.join(dest_dir, ntpath.basename(f))) diff --git a/python/sbp/jit/piksi.py b/python/sbp/jit/piksi.py new file mode 100644 index 0000000000..8175df26aa --- /dev/null +++ b/python/sbp/jit/piksi.py @@ -0,0 +1,1377 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +System health, configuration, and diagnostic messages specific to +the Piksi L1 receiver, including a variety of legacy messages that +may no longer be used. + +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array +from sbp.jit.gnss import * + +# Automatically generated from piksi/yaml/swiftnav/sbp/piksi.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_ALMANAC = 0x0069 +class MsgAlmanac(SBP): + """SBP class for message MSG_ALMANAC (0x0069). + + You can have MSG_ALMANAC inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This is a legacy message for sending and loading a satellite +alamanac onto the Piksi's flash memory from the host. + + + """ + __slots__ = [] + def _unpack_members(self, buf, offset, length): + return {}, offset, length + + def _payload_size(self): + return 0 + +SBP_MSG_SET_TIME = 0x0068 +class MsgSetTime(SBP): + """SBP class for message MSG_SET_TIME (0x0068). + + You can have MSG_SET_TIME inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message sets up timing functionality using a coarse GPS +time estimate sent by the host. + + + """ + __slots__ = [] + def _unpack_members(self, buf, offset, length): + return {}, offset, length + + def _payload_size(self): + return 0 + +SBP_MSG_RESET = 0x00B6 +class MsgReset(SBP): + """SBP class for message MSG_RESET (0x00B6). + + You can have MSG_RESET inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message from the host resets the Piksi back into the +bootloader. + + + """ + __slots__ = ['flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__flags, offset, length) = get_u32(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # flags: u32 + ret += 4 + return ret + +SBP_MSG_RESET_DEP = 0x00B2 +class MsgResetDep(SBP): + """SBP class for message MSG_RESET_DEP (0x00B2). + + You can have MSG_RESET_DEP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message from the host resets the Piksi back into the +bootloader. + + + """ + __slots__ = [] + def _unpack_members(self, buf, offset, length): + return {}, offset, length + + def _payload_size(self): + return 0 + +SBP_MSG_CW_RESULTS = 0x00C0 +class MsgCwResults(SBP): + """SBP class for message MSG_CW_RESULTS (0x00C0). + + You can have MSG_CW_RESULTS inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This is an unused legacy message for result reporting from the +CW interference channel on the SwiftNAP. This message will be +removed in a future release. + + + """ + __slots__ = [] + def _unpack_members(self, buf, offset, length): + return {}, offset, length + + def _payload_size(self): + return 0 + +SBP_MSG_CW_START = 0x00C1 +class MsgCwStart(SBP): + """SBP class for message MSG_CW_START (0x00C1). + + You can have MSG_CW_START inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This is an unused legacy message from the host for starting +the CW interference channel on the SwiftNAP. This message will +be removed in a future release. + + + """ + __slots__ = [] + def _unpack_members(self, buf, offset, length): + return {}, offset, length + + def _payload_size(self): + return 0 + +SBP_MSG_RESET_FILTERS = 0x0022 +class MsgResetFilters(SBP): + """SBP class for message MSG_RESET_FILTERS (0x0022). + + You can have MSG_RESET_FILTERS inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message resets either the DGNSS Kalman filters or Integer +Ambiguity Resolution (IAR) process. + + + """ + __slots__ = ['filter', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__filter, offset, length) = get_u8(buf, offset, length) + ret['filter'] = __filter + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.filter = res['filter'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # filter: u8 + ret += 1 + return ret + +SBP_MSG_INIT_BASE = 0x0023 +class MsgInitBase(SBP): + """SBP class for message MSG_INIT_BASE (0x0023). + + You can have MSG_INIT_BASE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message initializes the integer ambiguity resolution (IAR) +process on the Piksi to use an assumed baseline position between +the base station and rover receivers. Warns via MSG_PRINT if +there aren't a shared minimum number (4) of satellite +observations between the two. + + + """ + __slots__ = [] + def _unpack_members(self, buf, offset, length): + return {}, offset, length + + def _payload_size(self): + return 0 + +SBP_MSG_THREAD_STATE = 0x0017 +class MsgThreadState(SBP): + """SBP class for message MSG_THREAD_STATE (0x0017). + + You can have MSG_THREAD_STATE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The thread usage message from the device reports real-time +operating system (RTOS) thread usage statistics for the named +thread. The reported percentage values must be normalized. + + + """ + __slots__ = ['name', + 'cpu', + 'stack_free', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__name, offset, length) = get_fixed_string(20)(buf, offset, length) + ret['name'] = __name + (__cpu, offset, length) = get_u16(buf, offset, length) + ret['cpu'] = __cpu + (__stack_free, offset, length) = get_u32(buf, offset, length) + ret['stack_free'] = __stack_free + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.name = res['name'] + self.cpu = res['cpu'] + self.stack_free = res['stack_free'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # name: string + ret += 20 + # cpu: u16 + ret += 2 + # stack_free: u32 + ret += 4 + return ret + +class UARTChannel(object): + """SBP class for message UARTChannel + + You can have UARTChannel inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Throughput, utilization, and error counts on the RX/TX buffers +of this UART channel. The reported percentage values must +be normalized. + + + """ + __slots__ = ['tx_throughput', + 'rx_throughput', + 'crc_error_count', + 'io_error_count', + 'tx_buffer_level', + 'rx_buffer_level', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tx_throughput, offset, length) = get_f32(buf, offset, length) + ret['tx_throughput'] = judicious_round(nb.f4(__tx_throughput)) if SBP.judicious_rounding else __tx_throughput + (__rx_throughput, offset, length) = get_f32(buf, offset, length) + ret['rx_throughput'] = judicious_round(nb.f4(__rx_throughput)) if SBP.judicious_rounding else __rx_throughput + (__crc_error_count, offset, length) = get_u16(buf, offset, length) + ret['crc_error_count'] = __crc_error_count + (__io_error_count, offset, length) = get_u16(buf, offset, length) + ret['io_error_count'] = __io_error_count + (__tx_buffer_level, offset, length) = get_u8(buf, offset, length) + ret['tx_buffer_level'] = __tx_buffer_level + (__rx_buffer_level, offset, length) = get_u8(buf, offset, length) + ret['rx_buffer_level'] = __rx_buffer_level + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tx_throughput = res['tx_throughput'] + self.rx_throughput = res['rx_throughput'] + self.crc_error_count = res['crc_error_count'] + self.io_error_count = res['io_error_count'] + self.tx_buffer_level = res['tx_buffer_level'] + self.rx_buffer_level = res['rx_buffer_level'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tx_throughput: float + ret += 4 + # rx_throughput: float + ret += 4 + # crc_error_count: u16 + ret += 2 + # io_error_count: u16 + ret += 2 + # tx_buffer_level: u8 + ret += 1 + # rx_buffer_level: u8 + ret += 1 + return ret + +class Period(object): + """SBP class for message Period + + You can have Period inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Statistics on the period of observations received from the base +station. As complete observation sets are received, their time +of reception is compared with the prior set''s time of reception. +This measurement provides a proxy for link quality as incomplete +or missing sets will increase the period. Long periods +can cause momentary RTK solution outages. + + + """ + __slots__ = ['avg', + 'pmin', + 'pmax', + 'current', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__avg, offset, length) = get_s32(buf, offset, length) + ret['avg'] = __avg + (__pmin, offset, length) = get_s32(buf, offset, length) + ret['pmin'] = __pmin + (__pmax, offset, length) = get_s32(buf, offset, length) + ret['pmax'] = __pmax + (__current, offset, length) = get_s32(buf, offset, length) + ret['current'] = __current + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.avg = res['avg'] + self.pmin = res['pmin'] + self.pmax = res['pmax'] + self.current = res['current'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # avg: s32 + ret += 4 + # pmin: s32 + ret += 4 + # pmax: s32 + ret += 4 + # current: s32 + ret += 4 + return ret + +class Latency(object): + """SBP class for message Latency + + You can have Latency inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Statistics on the latency of observations received from the base +station. As observation packets are received their GPS time is +compared to the current GPS time calculated locally by the +receiver to give a precise measurement of the end-to-end +communication latency in the system. + + + """ + __slots__ = ['avg', + 'lmin', + 'lmax', + 'current', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__avg, offset, length) = get_s32(buf, offset, length) + ret['avg'] = __avg + (__lmin, offset, length) = get_s32(buf, offset, length) + ret['lmin'] = __lmin + (__lmax, offset, length) = get_s32(buf, offset, length) + ret['lmax'] = __lmax + (__current, offset, length) = get_s32(buf, offset, length) + ret['current'] = __current + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.avg = res['avg'] + self.lmin = res['lmin'] + self.lmax = res['lmax'] + self.current = res['current'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # avg: s32 + ret += 4 + # lmin: s32 + ret += 4 + # lmax: s32 + ret += 4 + # current: s32 + ret += 4 + return ret + +SBP_MSG_UART_STATE = 0x001D +class MsgUartState(SBP): + """SBP class for message MSG_UART_STATE (0x001D). + + You can have MSG_UART_STATE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The UART message reports data latency and throughput of the UART +channels providing SBP I/O. On the default Piksi configuration, +UARTs A and B are used for telemetry radios, but can also be +host access ports for embedded hosts, or other interfaces in +future. The reported percentage values must be normalized. +Observations latency and period can be used to assess the +health of the differential corrections link. Latency provides +the timeliness of received base observations while the +period indicates their likelihood of transmission. + + + """ + __slots__ = ['uart_a', + 'uart_b', + 'uart_ftdi', + 'latency', + 'obs_period', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__uart_a, offset, length) = UARTChannel.parse_members(buf, offset, length) + ret['uart_a'] = __uart_a + (__uart_b, offset, length) = UARTChannel.parse_members(buf, offset, length) + ret['uart_b'] = __uart_b + (__uart_ftdi, offset, length) = UARTChannel.parse_members(buf, offset, length) + ret['uart_ftdi'] = __uart_ftdi + (__latency, offset, length) = Latency.parse_members(buf, offset, length) + ret['latency'] = __latency + (__obs_period, offset, length) = Period.parse_members(buf, offset, length) + ret['obs_period'] = __obs_period + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.uart_a = res['uart_a'] + self.uart_b = res['uart_b'] + self.uart_ftdi = res['uart_ftdi'] + self.latency = res['latency'] + self.obs_period = res['obs_period'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # uart_a: UARTChannel + ret += UARTChannel._payload_size() + # uart_b: UARTChannel + ret += UARTChannel._payload_size() + # uart_ftdi: UARTChannel + ret += UARTChannel._payload_size() + # latency: Latency + ret += Latency._payload_size() + # obs_period: Period + ret += Period._payload_size() + return ret + +SBP_MSG_UART_STATE_DEPA = 0x0018 +class MsgUartStateDepa(SBP): + """SBP class for message MSG_UART_STATE_DEPA (0x0018). + + You can have MSG_UART_STATE_DEPA inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated + + """ + __slots__ = ['uart_a', + 'uart_b', + 'uart_ftdi', + 'latency', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__uart_a, offset, length) = UARTChannel.parse_members(buf, offset, length) + ret['uart_a'] = __uart_a + (__uart_b, offset, length) = UARTChannel.parse_members(buf, offset, length) + ret['uart_b'] = __uart_b + (__uart_ftdi, offset, length) = UARTChannel.parse_members(buf, offset, length) + ret['uart_ftdi'] = __uart_ftdi + (__latency, offset, length) = Latency.parse_members(buf, offset, length) + ret['latency'] = __latency + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.uart_a = res['uart_a'] + self.uart_b = res['uart_b'] + self.uart_ftdi = res['uart_ftdi'] + self.latency = res['latency'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # uart_a: UARTChannel + ret += UARTChannel._payload_size() + # uart_b: UARTChannel + ret += UARTChannel._payload_size() + # uart_ftdi: UARTChannel + ret += UARTChannel._payload_size() + # latency: Latency + ret += Latency._payload_size() + return ret + +SBP_MSG_IAR_STATE = 0x0019 +class MsgIarState(SBP): + """SBP class for message MSG_IAR_STATE (0x0019). + + You can have MSG_IAR_STATE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message reports the state of the Integer Ambiguity +Resolution (IAR) process, which resolves unknown integer +ambiguities from double-differenced carrier-phase measurements +from satellite observations. + + + """ + __slots__ = ['num_hyps', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__num_hyps, offset, length) = get_u32(buf, offset, length) + ret['num_hyps'] = __num_hyps + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.num_hyps = res['num_hyps'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # num_hyps: u32 + ret += 4 + return ret + +SBP_MSG_MASK_SATELLITE = 0x002B +class MsgMaskSatellite(SBP): + """SBP class for message MSG_MASK_SATELLITE (0x002B). + + You can have MSG_MASK_SATELLITE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message allows setting a mask to prevent a particular satellite +from being used in various Piksi subsystems. + + + """ + __slots__ = ['mask', + 'sid', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__mask, offset, length) = get_u8(buf, offset, length) + ret['mask'] = __mask + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.mask = res['mask'] + self.sid = res['sid'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # mask: u8 + ret += 1 + # sid: GnssSignal + ret += GnssSignal._payload_size() + return ret + +SBP_MSG_MASK_SATELLITE_DEP = 0x001B +class MsgMaskSatelliteDep(SBP): + """SBP class for message MSG_MASK_SATELLITE_DEP (0x001B). + + You can have MSG_MASK_SATELLITE_DEP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['mask', + 'sid', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__mask, offset, length) = get_u8(buf, offset, length) + ret['mask'] = __mask + (__sid, offset, length) = GnssSignalDep.parse_members(buf, offset, length) + ret['sid'] = __sid + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.mask = res['mask'] + self.sid = res['sid'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # mask: u8 + ret += 1 + # sid: GnssSignalDep + ret += GnssSignalDep._payload_size() + return ret + +SBP_MSG_DEVICE_MONITOR = 0x00B5 +class MsgDeviceMonitor(SBP): + """SBP class for message MSG_DEVICE_MONITOR (0x00B5). + + You can have MSG_DEVICE_MONITOR inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message contains temperature and voltage level measurements from the +processor's monitoring system and the RF frontend die temperature if +available. + + + """ + __slots__ = ['dev_vin', + 'cpu_vint', + 'cpu_vaux', + 'cpu_temperature', + 'fe_temperature', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__dev_vin, offset, length) = get_s16(buf, offset, length) + ret['dev_vin'] = __dev_vin + (__cpu_vint, offset, length) = get_s16(buf, offset, length) + ret['cpu_vint'] = __cpu_vint + (__cpu_vaux, offset, length) = get_s16(buf, offset, length) + ret['cpu_vaux'] = __cpu_vaux + (__cpu_temperature, offset, length) = get_s16(buf, offset, length) + ret['cpu_temperature'] = __cpu_temperature + (__fe_temperature, offset, length) = get_s16(buf, offset, length) + ret['fe_temperature'] = __fe_temperature + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.dev_vin = res['dev_vin'] + self.cpu_vint = res['cpu_vint'] + self.cpu_vaux = res['cpu_vaux'] + self.cpu_temperature = res['cpu_temperature'] + self.fe_temperature = res['fe_temperature'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # dev_vin: s16 + ret += 2 + # cpu_vint: s16 + ret += 2 + # cpu_vaux: s16 + ret += 2 + # cpu_temperature: s16 + ret += 2 + # fe_temperature: s16 + ret += 2 + return ret + +SBP_MSG_COMMAND_REQ = 0x00B8 +class MsgCommandReq(SBP): + """SBP class for message MSG_COMMAND_REQ (0x00B8). + + You can have MSG_COMMAND_REQ inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Request the recipient to execute an command. +Output will be sent in MSG_LOG messages, and the exit +code will be returned with MSG_COMMAND_RESP. + + + """ + __slots__ = ['sequence', + 'command', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sequence, offset, length) = get_u32(buf, offset, length) + ret['sequence'] = __sequence + (__command, offset, length) = get_string(buf, offset, length) + ret['command'] = __command + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sequence = res['sequence'] + self.command = res['command'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sequence: u32 + ret += 4 + # command: string + ret += 247 + return ret + +SBP_MSG_COMMAND_RESP = 0x00B9 +class MsgCommandResp(SBP): + """SBP class for message MSG_COMMAND_RESP (0x00B9). + + You can have MSG_COMMAND_RESP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The response to MSG_COMMAND_REQ with the return code of +the command. A return code of zero indicates success. + + + """ + __slots__ = ['sequence', + 'code', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sequence, offset, length) = get_u32(buf, offset, length) + ret['sequence'] = __sequence + (__code, offset, length) = get_s32(buf, offset, length) + ret['code'] = __code + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sequence = res['sequence'] + self.code = res['code'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sequence: u32 + ret += 4 + # code: s32 + ret += 4 + return ret + +SBP_MSG_COMMAND_OUTPUT = 0x00BC +class MsgCommandOutput(SBP): + """SBP class for message MSG_COMMAND_OUTPUT (0x00BC). + + You can have MSG_COMMAND_OUTPUT inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Returns the standard output and standard error of the +command requested by MSG_COMMAND_REQ. +The sequence number can be used to filter for filtering +the correct command. + + + """ + __slots__ = ['sequence', + 'line', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sequence, offset, length) = get_u32(buf, offset, length) + ret['sequence'] = __sequence + (__line, offset, length) = get_string(buf, offset, length) + ret['line'] = __line + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sequence = res['sequence'] + self.line = res['line'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sequence: u32 + ret += 4 + # line: string + ret += 247 + return ret + +SBP_MSG_NETWORK_STATE_REQ = 0x00BA +class MsgNetworkStateReq(SBP): + """SBP class for message MSG_NETWORK_STATE_REQ (0x00BA). + + You can have MSG_NETWORK_STATE_REQ inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Request state of Piksi network interfaces. +Output will be sent in MSG_NETWORK_STATE_RESP messages + + + """ + __slots__ = [] + def _unpack_members(self, buf, offset, length): + return {}, offset, length + + def _payload_size(self): + return 0 + +SBP_MSG_NETWORK_STATE_RESP = 0x00BB +class MsgNetworkStateResp(SBP): + """SBP class for message MSG_NETWORK_STATE_RESP (0x00BB). + + You can have MSG_NETWORK_STATE_RESP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The state of a network interface on the Piksi. +Data is made to reflect output of ifaddrs struct returned by getifaddrs +in c. + + + """ + __slots__ = ['ipv4_address', + 'ipv4_mask_size', + 'ipv6_address', + 'ipv6_mask_size', + 'rx_bytes', + 'tx_bytes', + 'interface_name', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__ipv4_address, offset, length) = get_fixed_array(get_u8, 4, 1)(buf, offset, length) + ret['ipv4_address'] = __ipv4_address + (__ipv4_mask_size, offset, length) = get_u8(buf, offset, length) + ret['ipv4_mask_size'] = __ipv4_mask_size + (__ipv6_address, offset, length) = get_fixed_array(get_u8, 16, 1)(buf, offset, length) + ret['ipv6_address'] = __ipv6_address + (__ipv6_mask_size, offset, length) = get_u8(buf, offset, length) + ret['ipv6_mask_size'] = __ipv6_mask_size + (__rx_bytes, offset, length) = get_u32(buf, offset, length) + ret['rx_bytes'] = __rx_bytes + (__tx_bytes, offset, length) = get_u32(buf, offset, length) + ret['tx_bytes'] = __tx_bytes + (__interface_name, offset, length) = get_fixed_string(16)(buf, offset, length) + ret['interface_name'] = __interface_name + (__flags, offset, length) = get_u32(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.ipv4_address = res['ipv4_address'] + self.ipv4_mask_size = res['ipv4_mask_size'] + self.ipv6_address = res['ipv6_address'] + self.ipv6_mask_size = res['ipv6_mask_size'] + self.rx_bytes = res['rx_bytes'] + self.tx_bytes = res['tx_bytes'] + self.interface_name = res['interface_name'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # ipv4_address: array of u8 + ret += 1 * 4 + # ipv4_mask_size: u8 + ret += 1 + # ipv6_address: array of u8 + ret += 1 * 16 + # ipv6_mask_size: u8 + ret += 1 + # rx_bytes: u32 + ret += 4 + # tx_bytes: u32 + ret += 4 + # interface_name: string + ret += 16 + # flags: u32 + ret += 4 + return ret + +class NetworkUsage(object): + """SBP class for message NetworkUsage + + You can have NetworkUsage inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The bandwidth usage for each interface can be reported +within this struct and utilize multiple fields to fully +specify the type of traffic that is being tracked. As +either the interval of collection or the collection time +may vary, both a timestamp and period field is provided, +though may not necessarily be populated with a value. + + + """ + __slots__ = ['duration', + 'total_bytes', + 'rx_bytes', + 'tx_bytes', + 'interface_name', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__duration, offset, length) = get_u64(buf, offset, length) + ret['duration'] = __duration + (__total_bytes, offset, length) = get_u64(buf, offset, length) + ret['total_bytes'] = __total_bytes + (__rx_bytes, offset, length) = get_u32(buf, offset, length) + ret['rx_bytes'] = __rx_bytes + (__tx_bytes, offset, length) = get_u32(buf, offset, length) + ret['tx_bytes'] = __tx_bytes + (__interface_name, offset, length) = get_fixed_string(16)(buf, offset, length) + ret['interface_name'] = __interface_name + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.duration = res['duration'] + self.total_bytes = res['total_bytes'] + self.rx_bytes = res['rx_bytes'] + self.tx_bytes = res['tx_bytes'] + self.interface_name = res['interface_name'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # duration: u64 + ret += 8 + # total_bytes: u64 + ret += 8 + # rx_bytes: u32 + ret += 4 + # tx_bytes: u32 + ret += 4 + # interface_name: string + ret += 16 + return ret + +SBP_MSG_NETWORK_BANDWIDTH_USAGE = 0x00BD +class MsgNetworkBandwidthUsage(SBP): + """SBP class for message MSG_NETWORK_BANDWIDTH_USAGE (0x00BD). + + You can have MSG_NETWORK_BANDWIDTH_USAGE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The bandwidth usage, a list of usage by interface. + + + """ + __slots__ = ['interfaces', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__interfaces, offset, length) = get_array(NetworkUsage.parse_members)(buf, offset, length) + ret['interfaces'] = __interfaces + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.interfaces = res['interfaces'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # interfaces: array of NetworkUsage + ret += 247 + return ret + +SBP_MSG_CELL_MODEM_STATUS = 0x00BE +class MsgCellModemStatus(SBP): + """SBP class for message MSG_CELL_MODEM_STATUS (0x00BE). + + You can have MSG_CELL_MODEM_STATUS inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + If a cell modem is present on a piksi device, this message +will be send periodically to update the host on the status +of the modem and its various parameters. + + + """ + __slots__ = ['signal_strength', + 'signal_error_rate', + 'reserved', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__signal_strength, offset, length) = get_s8(buf, offset, length) + ret['signal_strength'] = __signal_strength + (__signal_error_rate, offset, length) = get_f32(buf, offset, length) + ret['signal_error_rate'] = judicious_round(nb.f4(__signal_error_rate)) if SBP.judicious_rounding else __signal_error_rate + (__reserved, offset, length) = get_array(get_u8)(buf, offset, length) + ret['reserved'] = __reserved + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.signal_strength = res['signal_strength'] + self.signal_error_rate = res['signal_error_rate'] + self.reserved = res['reserved'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # signal_strength: s8 + ret += 1 + # signal_error_rate: float + ret += 4 + # reserved: array of u8 + ret += 247 + return ret + +SBP_MSG_SPECAN_DEP = 0x0050 +class MsgSpecanDep(SBP): + """SBP class for message MSG_SPECAN_DEP (0x0050). + + You can have MSG_SPECAN_DEP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['channel_tag', + 't', + 'freq_ref', + 'freq_step', + 'amplitude_ref', + 'amplitude_unit', + 'amplitude_value', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__channel_tag, offset, length) = get_u16(buf, offset, length) + ret['channel_tag'] = __channel_tag + (__t, offset, length) = GPSTimeDep.parse_members(buf, offset, length) + ret['t'] = __t + (__freq_ref, offset, length) = get_f32(buf, offset, length) + ret['freq_ref'] = judicious_round(nb.f4(__freq_ref)) if SBP.judicious_rounding else __freq_ref + (__freq_step, offset, length) = get_f32(buf, offset, length) + ret['freq_step'] = judicious_round(nb.f4(__freq_step)) if SBP.judicious_rounding else __freq_step + (__amplitude_ref, offset, length) = get_f32(buf, offset, length) + ret['amplitude_ref'] = judicious_round(nb.f4(__amplitude_ref)) if SBP.judicious_rounding else __amplitude_ref + (__amplitude_unit, offset, length) = get_f32(buf, offset, length) + ret['amplitude_unit'] = judicious_round(nb.f4(__amplitude_unit)) if SBP.judicious_rounding else __amplitude_unit + (__amplitude_value, offset, length) = get_array(get_u8)(buf, offset, length) + ret['amplitude_value'] = __amplitude_value + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.channel_tag = res['channel_tag'] + self.t = res['t'] + self.freq_ref = res['freq_ref'] + self.freq_step = res['freq_step'] + self.amplitude_ref = res['amplitude_ref'] + self.amplitude_unit = res['amplitude_unit'] + self.amplitude_value = res['amplitude_value'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # channel_tag: u16 + ret += 2 + # t: GPSTimeDep + ret += GPSTimeDep._payload_size() + # freq_ref: float + ret += 4 + # freq_step: float + ret += 4 + # amplitude_ref: float + ret += 4 + # amplitude_unit: float + ret += 4 + # amplitude_value: array of u8 + ret += 247 + return ret + +SBP_MSG_SPECAN = 0x0051 +class MsgSpecan(SBP): + """SBP class for message MSG_SPECAN (0x0051). + + You can have MSG_SPECAN inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Spectrum analyzer packet. + + + """ + __slots__ = ['channel_tag', + 't', + 'freq_ref', + 'freq_step', + 'amplitude_ref', + 'amplitude_unit', + 'amplitude_value', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__channel_tag, offset, length) = get_u16(buf, offset, length) + ret['channel_tag'] = __channel_tag + (__t, offset, length) = GPSTime.parse_members(buf, offset, length) + ret['t'] = __t + (__freq_ref, offset, length) = get_f32(buf, offset, length) + ret['freq_ref'] = judicious_round(nb.f4(__freq_ref)) if SBP.judicious_rounding else __freq_ref + (__freq_step, offset, length) = get_f32(buf, offset, length) + ret['freq_step'] = judicious_round(nb.f4(__freq_step)) if SBP.judicious_rounding else __freq_step + (__amplitude_ref, offset, length) = get_f32(buf, offset, length) + ret['amplitude_ref'] = judicious_round(nb.f4(__amplitude_ref)) if SBP.judicious_rounding else __amplitude_ref + (__amplitude_unit, offset, length) = get_f32(buf, offset, length) + ret['amplitude_unit'] = judicious_round(nb.f4(__amplitude_unit)) if SBP.judicious_rounding else __amplitude_unit + (__amplitude_value, offset, length) = get_array(get_u8)(buf, offset, length) + ret['amplitude_value'] = __amplitude_value + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.channel_tag = res['channel_tag'] + self.t = res['t'] + self.freq_ref = res['freq_ref'] + self.freq_step = res['freq_step'] + self.amplitude_ref = res['amplitude_ref'] + self.amplitude_unit = res['amplitude_unit'] + self.amplitude_value = res['amplitude_value'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # channel_tag: u16 + ret += 2 + # t: GPSTime + ret += GPSTime._payload_size() + # freq_ref: float + ret += 4 + # freq_step: float + ret += 4 + # amplitude_ref: float + ret += 4 + # amplitude_unit: float + ret += 4 + # amplitude_value: array of u8 + ret += 247 + return ret + +SBP_MSG_FRONT_END_GAIN = 0x00BF +class MsgFrontEndGain(SBP): + """SBP class for message MSG_FRONT_END_GAIN (0x00BF). + + You can have MSG_FRONT_END_GAIN inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message describes the gain of each channel in the receiver frontend. Each +gain is encoded as a non-dimensional percentage relative to the maximum range +possible for the gain stage of the frontend. By convention, each gain array +has 8 entries and the index of the array corresponding to the index of the rf channel +in the frontend. A gain of 127 percent encodes that rf channel is not present in the hardware. +A negative value implies an error for the particular gain stage as reported by the frontend. + + + """ + __slots__ = ['rf_gain', + 'if_gain', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__rf_gain, offset, length) = get_fixed_array(get_s8, 8, 1)(buf, offset, length) + ret['rf_gain'] = __rf_gain + (__if_gain, offset, length) = get_fixed_array(get_s8, 8, 1)(buf, offset, length) + ret['if_gain'] = __if_gain + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.rf_gain = res['rf_gain'] + self.if_gain = res['if_gain'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # rf_gain: array of s8 + ret += 1 * 8 + # if_gain: array of s8 + ret += 1 * 8 + return ret + + +msg_classes = { + 0x0069: MsgAlmanac, + 0x0068: MsgSetTime, + 0x00B6: MsgReset, + 0x00B2: MsgResetDep, + 0x00C0: MsgCwResults, + 0x00C1: MsgCwStart, + 0x0022: MsgResetFilters, + 0x0023: MsgInitBase, + 0x0017: MsgThreadState, + 0x001D: MsgUartState, + 0x0018: MsgUartStateDepa, + 0x0019: MsgIarState, + 0x002B: MsgMaskSatellite, + 0x001B: MsgMaskSatelliteDep, + 0x00B5: MsgDeviceMonitor, + 0x00B8: MsgCommandReq, + 0x00B9: MsgCommandResp, + 0x00BC: MsgCommandOutput, + 0x00BA: MsgNetworkStateReq, + 0x00BB: MsgNetworkStateResp, + 0x00BD: MsgNetworkBandwidthUsage, + 0x00BE: MsgCellModemStatus, + 0x0050: MsgSpecanDep, + 0x0051: MsgSpecan, + 0x00BF: MsgFrontEndGain, +} \ No newline at end of file diff --git a/python/sbp/jit/sbas.py b/python/sbp/jit/sbas.py new file mode 100644 index 0000000000..44a8641d22 --- /dev/null +++ b/python/sbp/jit/sbas.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +SBAS data +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array +from sbp.jit.gnss import * + +# Automatically generated from piksi/yaml/swiftnav/sbp/sbas.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_SBAS_RAW = 0x7777 +class MsgSbasRaw(SBP): + """SBP class for message MSG_SBAS_RAW (0x7777). + + You can have MSG_SBAS_RAW inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message is sent once per second per SBAS satellite. ME checks the +parity of the data block and sends only blocks that pass the check. + + + """ + __slots__ = ['sid', + 'tow', + 'message_type', + 'data', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__message_type, offset, length) = get_u8(buf, offset, length) + ret['message_type'] = __message_type + (__data, offset, length) = get_fixed_array(get_u8, 27, 1)(buf, offset, length) + ret['data'] = __data + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sid = res['sid'] + self.tow = res['tow'] + self.message_type = res['message_type'] + self.data = res['data'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sid: GnssSignal + ret += GnssSignal._payload_size() + # tow: u32 + ret += 4 + # message_type: u8 + ret += 1 + # data: array of u8 + ret += 1 * 27 + return ret + + +msg_classes = { + 0x7777: MsgSbasRaw, +} \ No newline at end of file diff --git a/python/sbp/jit/settings.py b/python/sbp/jit/settings.py new file mode 100644 index 0000000000..34775f9ee8 --- /dev/null +++ b/python/sbp/jit/settings.py @@ -0,0 +1,456 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" + +Messages for reading, writing, and discovering device settings. Settings +with a "string" field have multiple values in this field delimited with a +null character (the c style null terminator). For instance, when querying +the 'firmware_version' setting in the 'system_info' section, the following +array of characters needs to be sent for the string field in +MSG_SETTINGS_READ: "system_info\0firmware_version\0", where the delimiting +null characters are specified with the escape sequence '\0' and all +quotation marks should be omitted. + + +In the message descriptions below, the generic strings SECTION_SETTING and +SETTING are used to refer to the two strings that comprise the identifier +of an individual setting.In firmware_version example above, SECTION_SETTING +is the 'system_info', and the SETTING portion is 'firmware_version'. + +See the "Software Settings Manual" on support.swiftnav.com for detailed +documentation about all settings and sections available for each Swift +firmware version. Settings manuals are available for each firmware version +at the following link: https://support.swiftnav.com/customer/en/portal/articles/2628580-piksi-multi-specifications#settings. +The latest settings document is also available at the following link: +http://swiftnav.com/latest/piksi-multi-settings . +See lastly https://github.com/swift-nav/piksi_tools/blob/master/piksi_tools/settings.py , +the open source python command line utility for reading, writing, and +saving settings in the piksi_tools repository on github as a helpful +reference and example. + +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +# Automatically generated from piksi/yaml/swiftnav/sbp/settings.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_SETTINGS_SAVE = 0x00A1 +class MsgSettingsSave(SBP): + """SBP class for message MSG_SETTINGS_SAVE (0x00A1). + + You can have MSG_SETTINGS_SAVE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The save settings message persists the device's current settings +configuration to its onboard flash memory file system. + + + """ + __slots__ = [] + def _unpack_members(self, buf, offset, length): + return {}, offset, length + + def _payload_size(self): + return 0 + +SBP_MSG_SETTINGS_WRITE = 0x00A0 +class MsgSettingsWrite(SBP): + """SBP class for message MSG_SETTINGS_WRITE (0x00A0). + + You can have MSG_SETTINGS_WRITE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The setting message writes the device configuration for a particular +setting via A NULL-terminated and NULL-delimited string with contents +"SECTION_SETTING\0SETTING\0VALUE\0" where the '\0' escape sequence denotes +the NULL character and where quotation marks are omitted. A device will +only process to this message when it is received from sender ID 0x42. +An example string that could be sent to a device is +"solution\0soln_freq\010\0". + + + """ + __slots__ = ['setting', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__setting, offset, length) = get_setting(buf, offset, length) + ret['setting'] = __setting + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.setting = res['setting'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # setting: string + ret += 247 + return ret + +SBP_MSG_SETTINGS_WRITE_RESP = 0x00AF +class MsgSettingsWriteResp(SBP): + """SBP class for message MSG_SETTINGS_WRITE_RESP (0x00AF). + + You can have MSG_SETTINGS_WRITE_RESP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Return the status of a write request with the new value of the +setting. If the requested value is rejected, the current value +will be returned. The string field is a NULL-terminated and NULL-delimited +string with contents "SECTION_SETTING\0SETTING\0VALUE\0" where the '\0' +escape sequence denotes the NULL character and where quotation marks +are omitted. An example string that could be sent from device is +"solution\0soln_freq\010\0". + + + """ + __slots__ = ['status', + 'setting', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__status, offset, length) = get_u8(buf, offset, length) + ret['status'] = __status + (__setting, offset, length) = get_setting(buf, offset, length) + ret['setting'] = __setting + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.status = res['status'] + self.setting = res['setting'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # status: u8 + ret += 1 + # setting: string + ret += 247 + return ret + +SBP_MSG_SETTINGS_READ_REQ = 0x00A4 +class MsgSettingsReadReq(SBP): + """SBP class for message MSG_SETTINGS_READ_REQ (0x00A4). + + You can have MSG_SETTINGS_READ_REQ inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The setting message that reads the device configuration. The string +field is a NULL-terminated and NULL-delimited string with contents +"SECTION_SETTING\0SETTING\0" where the '\0' escape sequence denotes the +NULL character and where quotation marks are omitted. An example +string that could be sent to a device is "solution\0soln_freq\0". A +device will only respond to this message when it is received from +sender ID 0x42. A device should respond with a MSG_SETTINGS_READ_RESP +message (msg_id 0x00A5). + + + """ + __slots__ = ['setting', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__setting, offset, length) = get_setting(buf, offset, length) + ret['setting'] = __setting + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.setting = res['setting'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # setting: string + ret += 247 + return ret + +SBP_MSG_SETTINGS_READ_RESP = 0x00A5 +class MsgSettingsReadResp(SBP): + """SBP class for message MSG_SETTINGS_READ_RESP (0x00A5). + + You can have MSG_SETTINGS_READ_RESP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The setting message wich which the device responds after a +MSG_SETTING_READ_REQ is sent to device. The string field is a +NULL-terminated and NULL-delimited string with contents +"SECTION_SETTING\0SETTING\0VALUE\0" where the '\0' escape sequence +denotes the NULL character and where quotation marks are omitted. An +example string that could be sent from device is +"solution\0soln_freq\010\0". + + + """ + __slots__ = ['setting', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__setting, offset, length) = get_setting(buf, offset, length) + ret['setting'] = __setting + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.setting = res['setting'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # setting: string + ret += 247 + return ret + +SBP_MSG_SETTINGS_READ_BY_INDEX_REQ = 0x00A2 +class MsgSettingsReadByIndexReq(SBP): + """SBP class for message MSG_SETTINGS_READ_BY_INDEX_REQ (0x00A2). + + You can have MSG_SETTINGS_READ_BY_INDEX_REQ inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The settings message for iterating through the settings +values. A device will respond to this message with a +"MSG_SETTINGS_READ_BY_INDEX_RESP". + + + """ + __slots__ = ['index', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__index, offset, length) = get_u16(buf, offset, length) + ret['index'] = __index + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.index = res['index'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # index: u16 + ret += 2 + return ret + +SBP_MSG_SETTINGS_READ_BY_INDEX_RESP = 0x00A7 +class MsgSettingsReadByIndexResp(SBP): + """SBP class for message MSG_SETTINGS_READ_BY_INDEX_RESP (0x00A7). + + You can have MSG_SETTINGS_READ_BY_INDEX_RESP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The settings message that reports the value of a setting at an index. + +In the string field, it reports NULL-terminated and delimited string +with contents "SECTION_SETTING\0SETTING\0VALUE\0FORMAT_TYPE\0". where +the '\0' escape sequence denotes the NULL character and where quotation +marks are omitted. The FORMAT_TYPE field is optional and denotes +possible string values of the setting as a hint to the user. If +included, the format type portion of the string has the format +"enum:value1,value2,value3". An example string that could be sent from +the device is "simulator\0enabled\0True\0enum:True,False\0" + + + """ + __slots__ = ['index', + 'setting', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__index, offset, length) = get_u16(buf, offset, length) + ret['index'] = __index + (__setting, offset, length) = get_setting(buf, offset, length) + ret['setting'] = __setting + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.index = res['index'] + self.setting = res['setting'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # index: u16 + ret += 2 + # setting: string + ret += 247 + return ret + +SBP_MSG_SETTINGS_READ_BY_INDEX_DONE = 0x00A6 +class MsgSettingsReadByIndexDone(SBP): + """SBP class for message MSG_SETTINGS_READ_BY_INDEX_DONE (0x00A6). + + You can have MSG_SETTINGS_READ_BY_INDEX_DONE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The settings message for indicating end of the settings values. + + + """ + __slots__ = [] + def _unpack_members(self, buf, offset, length): + return {}, offset, length + + def _payload_size(self): + return 0 + +SBP_MSG_SETTINGS_REGISTER = 0x00AE +class MsgSettingsRegister(SBP): + """SBP class for message MSG_SETTINGS_REGISTER (0x00AE). + + You can have MSG_SETTINGS_REGISTER inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message registers the presence and default value of a setting +with a settings daemon. The host should reply with MSG_SETTINGS_WRITE +for this setting to set the initial value. + + + """ + __slots__ = ['setting', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__setting, offset, length) = get_setting(buf, offset, length) + ret['setting'] = __setting + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.setting = res['setting'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # setting: string + ret += 247 + return ret + +SBP_MSG_SETTINGS_REGISTER_RESP = 0x01AF +class MsgSettingsRegisterResp(SBP): + """SBP class for message MSG_SETTINGS_REGISTER_RESP (0x01AF). + + You can have MSG_SETTINGS_REGISTER_RESP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message responds to setting registration with the effective value. +The effective value shall differ from the given default value if setting +was already registered or is available in the permanent setting storage +and had a different value. + + + """ + __slots__ = ['status', + 'setting', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__status, offset, length) = get_u8(buf, offset, length) + ret['status'] = __status + (__setting, offset, length) = get_setting(buf, offset, length) + ret['setting'] = __setting + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.status = res['status'] + self.setting = res['setting'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # status: u8 + ret += 1 + # setting: string + ret += 247 + return ret + + +msg_classes = { + 0x00A1: MsgSettingsSave, + 0x00A0: MsgSettingsWrite, + 0x00AF: MsgSettingsWriteResp, + 0x00A4: MsgSettingsReadReq, + 0x00A5: MsgSettingsReadResp, + 0x00A2: MsgSettingsReadByIndexReq, + 0x00A7: MsgSettingsReadByIndexResp, + 0x00A6: MsgSettingsReadByIndexDone, + 0x00AE: MsgSettingsRegister, + 0x01AF: MsgSettingsRegisterResp, +} \ No newline at end of file diff --git a/python/sbp/jit/ssr.py b/python/sbp/jit/ssr.py new file mode 100644 index 0000000000..47808affdf --- /dev/null +++ b/python/sbp/jit/ssr.py @@ -0,0 +1,525 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Precise State Space Representation (SSR) corrections format +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array +from sbp.jit.gnss import * + +# Automatically generated from piksi/yaml/swiftnav/sbp/ssr.yaml with generate.py. +# Please do not hand edit! +class CodeBiasesContent(object): + """SBP class for message CodeBiasesContent + + You can have CodeBiasesContent inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Code biases are to be added to pseudorange. +The corrections are conform with typical RTCMv3 MT1059 and 1065. + + + """ + __slots__ = ['code', + 'value', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__code, offset, length) = get_u8(buf, offset, length) + ret['code'] = __code + (__value, offset, length) = get_s16(buf, offset, length) + ret['value'] = __value + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.code = res['code'] + self.value = res['value'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # code: u8 + ret += 1 + # value: s16 + ret += 2 + return ret + +class PhaseBiasesContent(object): + """SBP class for message PhaseBiasesContent + + You can have PhaseBiasesContent inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Phase biases are to be added to carrier phase measurements. +The corrections are conform with typical RTCMv3 MT1059 and 1065. + + + """ + __slots__ = ['code', + 'integer_indicator', + 'widelane_integer_indicator', + 'discontinuity_counter', + 'bias', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__code, offset, length) = get_u8(buf, offset, length) + ret['code'] = __code + (__integer_indicator, offset, length) = get_u8(buf, offset, length) + ret['integer_indicator'] = __integer_indicator + (__widelane_integer_indicator, offset, length) = get_u8(buf, offset, length) + ret['widelane_integer_indicator'] = __widelane_integer_indicator + (__discontinuity_counter, offset, length) = get_u8(buf, offset, length) + ret['discontinuity_counter'] = __discontinuity_counter + (__bias, offset, length) = get_s32(buf, offset, length) + ret['bias'] = __bias + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.code = res['code'] + self.integer_indicator = res['integer_indicator'] + self.widelane_integer_indicator = res['widelane_integer_indicator'] + self.discontinuity_counter = res['discontinuity_counter'] + self.bias = res['bias'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # code: u8 + ret += 1 + # integer_indicator: u8 + ret += 1 + # widelane_integer_indicator: u8 + ret += 1 + # discontinuity_counter: u8 + ret += 1 + # bias: s32 + ret += 4 + return ret + +SBP_MSG_SSR_ORBIT_CLOCK = 0x05DD +class MsgSsrOrbitClock(SBP): + """SBP class for message MSG_SSR_ORBIT_CLOCK (0x05DD). + + You can have MSG_SSR_ORBIT_CLOCK inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The precise orbit and clock correction message is +to be applied as a delta correction to broadcast +ephemeris and is typically an equivalent to the 1060 +and 1066 RTCM message types + + + """ + __slots__ = ['time', + 'sid', + 'update_interval', + 'iod_ssr', + 'iod', + 'radial', + 'along', + 'cross', + 'dot_radial', + 'dot_along', + 'dot_cross', + 'c0', + 'c1', + 'c2', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__time, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['time'] = __time + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__update_interval, offset, length) = get_u8(buf, offset, length) + ret['update_interval'] = __update_interval + (__iod_ssr, offset, length) = get_u8(buf, offset, length) + ret['iod_ssr'] = __iod_ssr + (__iod, offset, length) = get_u32(buf, offset, length) + ret['iod'] = __iod + (__radial, offset, length) = get_s32(buf, offset, length) + ret['radial'] = __radial + (__along, offset, length) = get_s32(buf, offset, length) + ret['along'] = __along + (__cross, offset, length) = get_s32(buf, offset, length) + ret['cross'] = __cross + (__dot_radial, offset, length) = get_s32(buf, offset, length) + ret['dot_radial'] = __dot_radial + (__dot_along, offset, length) = get_s32(buf, offset, length) + ret['dot_along'] = __dot_along + (__dot_cross, offset, length) = get_s32(buf, offset, length) + ret['dot_cross'] = __dot_cross + (__c0, offset, length) = get_s32(buf, offset, length) + ret['c0'] = __c0 + (__c1, offset, length) = get_s32(buf, offset, length) + ret['c1'] = __c1 + (__c2, offset, length) = get_s32(buf, offset, length) + ret['c2'] = __c2 + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.time = res['time'] + self.sid = res['sid'] + self.update_interval = res['update_interval'] + self.iod_ssr = res['iod_ssr'] + self.iod = res['iod'] + self.radial = res['radial'] + self.along = res['along'] + self.cross = res['cross'] + self.dot_radial = res['dot_radial'] + self.dot_along = res['dot_along'] + self.dot_cross = res['dot_cross'] + self.c0 = res['c0'] + self.c1 = res['c1'] + self.c2 = res['c2'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # time: GPSTimeSec + ret += GPSTimeSec._payload_size() + # sid: GnssSignal + ret += GnssSignal._payload_size() + # update_interval: u8 + ret += 1 + # iod_ssr: u8 + ret += 1 + # iod: u32 + ret += 4 + # radial: s32 + ret += 4 + # along: s32 + ret += 4 + # cross: s32 + ret += 4 + # dot_radial: s32 + ret += 4 + # dot_along: s32 + ret += 4 + # dot_cross: s32 + ret += 4 + # c0: s32 + ret += 4 + # c1: s32 + ret += 4 + # c2: s32 + ret += 4 + return ret + +SBP_MSG_SSR_ORBIT_CLOCK_DEP_A = 0x05DC +class MsgSsrOrbitClockDepA(SBP): + """SBP class for message MSG_SSR_ORBIT_CLOCK_DEP_A (0x05DC). + + You can have MSG_SSR_ORBIT_CLOCK_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The precise orbit and clock correction message is +to be applied as a delta correction to broadcast +ephemeris and is typically an equivalent to the 1060 +and 1066 RTCM message types + + + """ + __slots__ = ['time', + 'sid', + 'update_interval', + 'iod_ssr', + 'iod', + 'radial', + 'along', + 'cross', + 'dot_radial', + 'dot_along', + 'dot_cross', + 'c0', + 'c1', + 'c2', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__time, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['time'] = __time + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__update_interval, offset, length) = get_u8(buf, offset, length) + ret['update_interval'] = __update_interval + (__iod_ssr, offset, length) = get_u8(buf, offset, length) + ret['iod_ssr'] = __iod_ssr + (__iod, offset, length) = get_u8(buf, offset, length) + ret['iod'] = __iod + (__radial, offset, length) = get_s32(buf, offset, length) + ret['radial'] = __radial + (__along, offset, length) = get_s32(buf, offset, length) + ret['along'] = __along + (__cross, offset, length) = get_s32(buf, offset, length) + ret['cross'] = __cross + (__dot_radial, offset, length) = get_s32(buf, offset, length) + ret['dot_radial'] = __dot_radial + (__dot_along, offset, length) = get_s32(buf, offset, length) + ret['dot_along'] = __dot_along + (__dot_cross, offset, length) = get_s32(buf, offset, length) + ret['dot_cross'] = __dot_cross + (__c0, offset, length) = get_s32(buf, offset, length) + ret['c0'] = __c0 + (__c1, offset, length) = get_s32(buf, offset, length) + ret['c1'] = __c1 + (__c2, offset, length) = get_s32(buf, offset, length) + ret['c2'] = __c2 + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.time = res['time'] + self.sid = res['sid'] + self.update_interval = res['update_interval'] + self.iod_ssr = res['iod_ssr'] + self.iod = res['iod'] + self.radial = res['radial'] + self.along = res['along'] + self.cross = res['cross'] + self.dot_radial = res['dot_radial'] + self.dot_along = res['dot_along'] + self.dot_cross = res['dot_cross'] + self.c0 = res['c0'] + self.c1 = res['c1'] + self.c2 = res['c2'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # time: GPSTimeSec + ret += GPSTimeSec._payload_size() + # sid: GnssSignal + ret += GnssSignal._payload_size() + # update_interval: u8 + ret += 1 + # iod_ssr: u8 + ret += 1 + # iod: u8 + ret += 1 + # radial: s32 + ret += 4 + # along: s32 + ret += 4 + # cross: s32 + ret += 4 + # dot_radial: s32 + ret += 4 + # dot_along: s32 + ret += 4 + # dot_cross: s32 + ret += 4 + # c0: s32 + ret += 4 + # c1: s32 + ret += 4 + # c2: s32 + ret += 4 + return ret + +SBP_MSG_SSR_CODE_BIASES = 0x05E1 +class MsgSsrCodeBiases(SBP): + """SBP class for message MSG_SSR_CODE_BIASES (0x05E1). + + You can have MSG_SSR_CODE_BIASES inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The precise code biases message is to be added +to the pseudorange of the corresponding signal +to get corrected pseudorange. It is typically +an equivalent to the 1059 and 1065 RTCM message types + + + """ + __slots__ = ['time', + 'sid', + 'update_interval', + 'iod_ssr', + 'biases', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__time, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['time'] = __time + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__update_interval, offset, length) = get_u8(buf, offset, length) + ret['update_interval'] = __update_interval + (__iod_ssr, offset, length) = get_u8(buf, offset, length) + ret['iod_ssr'] = __iod_ssr + (__biases, offset, length) = get_array(CodeBiasesContent.parse_members)(buf, offset, length) + ret['biases'] = __biases + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.time = res['time'] + self.sid = res['sid'] + self.update_interval = res['update_interval'] + self.iod_ssr = res['iod_ssr'] + self.biases = res['biases'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # time: GPSTimeSec + ret += GPSTimeSec._payload_size() + # sid: GnssSignal + ret += GnssSignal._payload_size() + # update_interval: u8 + ret += 1 + # iod_ssr: u8 + ret += 1 + # biases: array of CodeBiasesContent + ret += 247 + return ret + +SBP_MSG_SSR_PHASE_BIASES = 0x05E6 +class MsgSsrPhaseBiases(SBP): + """SBP class for message MSG_SSR_PHASE_BIASES (0x05E6). + + You can have MSG_SSR_PHASE_BIASES inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The precise phase biases message contains the biases +to be added to the carrier phase of the corresponding +signal to get corrected carrier phase measurement, as +well as the satellite yaw angle to be applied to compute +the phase wind-up correction. +It is typically an equivalent to the 1265 RTCM message types + + + """ + __slots__ = ['time', + 'sid', + 'update_interval', + 'iod_ssr', + 'dispersive_bias', + 'mw_consistency', + 'yaw', + 'yaw_rate', + 'biases', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__time, offset, length) = GPSTimeSec.parse_members(buf, offset, length) + ret['time'] = __time + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__update_interval, offset, length) = get_u8(buf, offset, length) + ret['update_interval'] = __update_interval + (__iod_ssr, offset, length) = get_u8(buf, offset, length) + ret['iod_ssr'] = __iod_ssr + (__dispersive_bias, offset, length) = get_u8(buf, offset, length) + ret['dispersive_bias'] = __dispersive_bias + (__mw_consistency, offset, length) = get_u8(buf, offset, length) + ret['mw_consistency'] = __mw_consistency + (__yaw, offset, length) = get_u16(buf, offset, length) + ret['yaw'] = __yaw + (__yaw_rate, offset, length) = get_s8(buf, offset, length) + ret['yaw_rate'] = __yaw_rate + (__biases, offset, length) = get_array(PhaseBiasesContent.parse_members)(buf, offset, length) + ret['biases'] = __biases + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.time = res['time'] + self.sid = res['sid'] + self.update_interval = res['update_interval'] + self.iod_ssr = res['iod_ssr'] + self.dispersive_bias = res['dispersive_bias'] + self.mw_consistency = res['mw_consistency'] + self.yaw = res['yaw'] + self.yaw_rate = res['yaw_rate'] + self.biases = res['biases'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # time: GPSTimeSec + ret += GPSTimeSec._payload_size() + # sid: GnssSignal + ret += GnssSignal._payload_size() + # update_interval: u8 + ret += 1 + # iod_ssr: u8 + ret += 1 + # dispersive_bias: u8 + ret += 1 + # mw_consistency: u8 + ret += 1 + # yaw: u16 + ret += 2 + # yaw_rate: s8 + ret += 1 + # biases: array of PhaseBiasesContent + ret += 247 + return ret + + +msg_classes = { + 0x05DD: MsgSsrOrbitClock, + 0x05DC: MsgSsrOrbitClockDepA, + 0x05E1: MsgSsrCodeBiases, + 0x05E6: MsgSsrPhaseBiases, +} \ No newline at end of file diff --git a/python/sbp/jit/system.py b/python/sbp/jit/system.py new file mode 100644 index 0000000000..670601d1d4 --- /dev/null +++ b/python/sbp/jit/system.py @@ -0,0 +1,315 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Standardized system messages from Swift Navigation devices. +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +# Automatically generated from piksi/yaml/swiftnav/sbp/system.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_STARTUP = 0xFF00 +class MsgStartup(SBP): + """SBP class for message MSG_STARTUP (0xFF00). + + You can have MSG_STARTUP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The system start-up message is sent once on system +start-up. It notifies the host or other attached devices that +the system has started and is now ready to respond to commands +or configuration requests. + + + """ + __slots__ = ['cause', + 'startup_type', + 'reserved', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__cause, offset, length) = get_u8(buf, offset, length) + ret['cause'] = __cause + (__startup_type, offset, length) = get_u8(buf, offset, length) + ret['startup_type'] = __startup_type + (__reserved, offset, length) = get_u16(buf, offset, length) + ret['reserved'] = __reserved + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.cause = res['cause'] + self.startup_type = res['startup_type'] + self.reserved = res['reserved'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # cause: u8 + ret += 1 + # startup_type: u8 + ret += 1 + # reserved: u16 + ret += 2 + return ret + +SBP_MSG_DGNSS_STATUS = 0xFF02 +class MsgDgnssStatus(SBP): + """SBP class for message MSG_DGNSS_STATUS (0xFF02). + + You can have MSG_DGNSS_STATUS inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message provides information about the receipt of Differential +corrections. It is expected to be sent with each receipt of a complete +corrections packet. + + + """ + __slots__ = ['flags', + 'latency', + 'num_signals', + 'source', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + (__latency, offset, length) = get_u16(buf, offset, length) + ret['latency'] = __latency + (__num_signals, offset, length) = get_u8(buf, offset, length) + ret['num_signals'] = __num_signals + (__source, offset, length) = get_string(buf, offset, length) + ret['source'] = __source + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.flags = res['flags'] + self.latency = res['latency'] + self.num_signals = res['num_signals'] + self.source = res['source'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # flags: u8 + ret += 1 + # latency: u16 + ret += 2 + # num_signals: u8 + ret += 1 + # source: string + ret += 247 + return ret + +SBP_MSG_HEARTBEAT = 0xFFFF +class MsgHeartbeat(SBP): + """SBP class for message MSG_HEARTBEAT (0xFFFF). + + You can have MSG_HEARTBEAT inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The heartbeat message is sent periodically to inform the host +or other attached devices that the system is running. It is +used to monitor system malfunctions. It also contains status +flags that indicate to the host the status of the system and +whether it is operating correctly. Currently, the expected +heartbeat interval is 1 sec. + +The system error flag is used to indicate that an error has +occurred in the system. To determine the source of the error, +the remaining error flags should be inspected. + + + """ + __slots__ = ['flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__flags, offset, length) = get_u32(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # flags: u32 + ret += 4 + return ret + +SBP_MSG_INS_STATUS = 0xFF03 +class MsgInsStatus(SBP): + """SBP class for message MSG_INS_STATUS (0xFF03). + + You can have MSG_INS_STATUS inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The INS status message describes the state of the operation +and initialization of the inertial navigation system. + + + """ + __slots__ = ['flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__flags, offset, length) = get_u32(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # flags: u32 + ret += 4 + return ret + +SBP_MSG_CSAC_TELEMETRY = 0xFF04 +class MsgCsacTelemetry(SBP): + """SBP class for message MSG_CSAC_TELEMETRY (0xFF04). + + You can have MSG_CSAC_TELEMETRY inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The CSAC telemetry message has an implementation defined telemetry string +from a device. It is not produced or available on general Swift Products. +It is intended to be a low rate message for status purposes. + + + """ + __slots__ = ['id', + 'telemetry', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__id, offset, length) = get_u8(buf, offset, length) + ret['id'] = __id + (__telemetry, offset, length) = get_string(buf, offset, length) + ret['telemetry'] = __telemetry + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.id = res['id'] + self.telemetry = res['telemetry'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # id: u8 + ret += 1 + # telemetry: string + ret += 247 + return ret + +SBP_MSG_CSAC_TELEMETRY_LABELS = 0xFF05 +class MsgCsacTelemetryLabels(SBP): + """SBP class for message MSG_CSAC_TELEMETRY_LABELS (0xFF05). + + You can have MSG_CSAC_TELEMETRY_LABELS inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The CSAC telemetry message provides labels for each member of the string +produced by MSG_CSAC_TELEMETRY. It should be provided by a device at a lower +rate than the MSG_CSAC_TELEMETRY. + + + """ + __slots__ = ['id', + 'telemetry_labels', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__id, offset, length) = get_u8(buf, offset, length) + ret['id'] = __id + (__telemetry_labels, offset, length) = get_string(buf, offset, length) + ret['telemetry_labels'] = __telemetry_labels + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.id = res['id'] + self.telemetry_labels = res['telemetry_labels'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # id: u8 + ret += 1 + # telemetry_labels: string + ret += 247 + return ret + + +msg_classes = { + 0xFF00: MsgStartup, + 0xFF02: MsgDgnssStatus, + 0xFFFF: MsgHeartbeat, + 0xFF03: MsgInsStatus, + 0xFF04: MsgCsacTelemetry, + 0xFF05: MsgCsacTelemetryLabels, +} \ No newline at end of file diff --git a/python/sbp/jit/table.py b/python/sbp/jit/table.py new file mode 100755 index 0000000000..22dc20ca55 --- /dev/null +++ b/python/sbp/jit/table.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# Copyright (C) 2011-2014 Swift Navigation Inc. +# Contact: Bhaskar Mookerji +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + +""" +Single dispatch of available SBP messages, keyed by msg_type. + +""" + +from sbp.jit import acquisition as acq +from sbp.jit import bootload as boot +from sbp.jit import file_io as file_io +from sbp.jit import flash as flash +from sbp.jit import linux as linux +from sbp.jit import logging as log +from sbp.jit import navigation as nav +from sbp.jit import observation as obs +from sbp.jit import piksi as piksi +from sbp.jit import settings as settings +from sbp.jit import system as sys +from sbp.jit import tracking as trac +from sbp.jit import ext_events as ext_events +from sbp.jit import user as user +from sbp.jit import imu as imu +from sbp.jit import mag as mag +from sbp.jit import ndb as ndb +from sbp.jit import vehicle as vehicle +from sbp.jit import orientation as orientation +from sbp.jit import sbas as sbas +from sbp.jit import ssr as ssr + + +_SBP_TABLE = dict(list(acq.msg_classes.items()) + + list(boot.msg_classes.items()) + + list(file_io.msg_classes.items()) + + list(flash.msg_classes.items()) + + list(linux.msg_classes.items()) + + list(log.msg_classes.items()) + + list(nav.msg_classes.items()) + + list(obs.msg_classes.items()) + + list(piksi.msg_classes.items()) + + list(settings.msg_classes.items()) + + list(sys.msg_classes.items()) + + list(trac.msg_classes.items()) + + list(user.msg_classes.items()) + + list(imu.msg_classes.items()) + + list(mag.msg_classes.items()) + + list(ext_events.msg_classes.items()) + + list(ndb.msg_classes.items()) + + list(vehicle.msg_classes.items()) + + list(orientation.msg_classes.items()) + + list(sbas.msg_classes.items()) + + list(ssr.msg_classes.items()) + ) + + +class InvalidSBPMessageType(NotImplementedError): + """ + Base exception for messages with invalid message types. + """ + + +def dispatch(msg_type, table=_SBP_TABLE): + """ + Dispatch an SBP message type based on its `msg_type` and parse its + payload. + + Parameters + ---------- + driver : :class:`SBP` + A parsed SBP object. + table : dict + Any table mapping unique SBP message type IDs to SBP message + constructors. + + Returns + ---------- + SBP message with a parsed payload. + + """ + return table[msg_type] diff --git a/python/sbp/jit/tracking.py b/python/sbp/jit/tracking.py new file mode 100644 index 0000000000..09245d1cad --- /dev/null +++ b/python/sbp/jit/tracking.py @@ -0,0 +1,913 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Satellite code and carrier-phase tracking messages from the device. + +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array +from sbp.jit.gnss import * + +# Automatically generated from piksi/yaml/swiftnav/sbp/tracking.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_TRACKING_STATE_DETAILED_DEP_A = 0x0021 +class MsgTrackingStateDetailedDepA(SBP): + """SBP class for message MSG_TRACKING_STATE_DETAILED_DEP_A (0x0021). + + You can have MSG_TRACKING_STATE_DETAILED_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The tracking message returns a set tracking channel parameters for a +single tracking channel useful for debugging issues. + + + """ + __slots__ = ['recv_time', + 'tot', + 'P', + 'P_std', + 'L', + 'cn0', + 'lock', + 'sid', + 'doppler', + 'doppler_std', + 'uptime', + 'clock_offset', + 'clock_drift', + 'corr_spacing', + 'acceleration', + 'sync_flags', + 'tow_flags', + 'track_flags', + 'nav_flags', + 'pset_flags', + 'misc_flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__recv_time, offset, length) = get_u64(buf, offset, length) + ret['recv_time'] = __recv_time + (__tot, offset, length) = GPSTime.parse_members(buf, offset, length) + ret['tot'] = __tot + (__P, offset, length) = get_u32(buf, offset, length) + ret['P'] = __P + (__P_std, offset, length) = get_u16(buf, offset, length) + ret['P_std'] = __P_std + (__L, offset, length) = CarrierPhase.parse_members(buf, offset, length) + ret['L'] = __L + (__cn0, offset, length) = get_u8(buf, offset, length) + ret['cn0'] = __cn0 + (__lock, offset, length) = get_u16(buf, offset, length) + ret['lock'] = __lock + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__doppler, offset, length) = get_s32(buf, offset, length) + ret['doppler'] = __doppler + (__doppler_std, offset, length) = get_u16(buf, offset, length) + ret['doppler_std'] = __doppler_std + (__uptime, offset, length) = get_u32(buf, offset, length) + ret['uptime'] = __uptime + (__clock_offset, offset, length) = get_s16(buf, offset, length) + ret['clock_offset'] = __clock_offset + (__clock_drift, offset, length) = get_s16(buf, offset, length) + ret['clock_drift'] = __clock_drift + (__corr_spacing, offset, length) = get_u16(buf, offset, length) + ret['corr_spacing'] = __corr_spacing + (__acceleration, offset, length) = get_s8(buf, offset, length) + ret['acceleration'] = __acceleration + (__sync_flags, offset, length) = get_u8(buf, offset, length) + ret['sync_flags'] = __sync_flags + (__tow_flags, offset, length) = get_u8(buf, offset, length) + ret['tow_flags'] = __tow_flags + (__track_flags, offset, length) = get_u8(buf, offset, length) + ret['track_flags'] = __track_flags + (__nav_flags, offset, length) = get_u8(buf, offset, length) + ret['nav_flags'] = __nav_flags + (__pset_flags, offset, length) = get_u8(buf, offset, length) + ret['pset_flags'] = __pset_flags + (__misc_flags, offset, length) = get_u8(buf, offset, length) + ret['misc_flags'] = __misc_flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.recv_time = res['recv_time'] + self.tot = res['tot'] + self.P = res['P'] + self.P_std = res['P_std'] + self.L = res['L'] + self.cn0 = res['cn0'] + self.lock = res['lock'] + self.sid = res['sid'] + self.doppler = res['doppler'] + self.doppler_std = res['doppler_std'] + self.uptime = res['uptime'] + self.clock_offset = res['clock_offset'] + self.clock_drift = res['clock_drift'] + self.corr_spacing = res['corr_spacing'] + self.acceleration = res['acceleration'] + self.sync_flags = res['sync_flags'] + self.tow_flags = res['tow_flags'] + self.track_flags = res['track_flags'] + self.nav_flags = res['nav_flags'] + self.pset_flags = res['pset_flags'] + self.misc_flags = res['misc_flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # recv_time: u64 + ret += 8 + # tot: GPSTime + ret += GPSTime._payload_size() + # P: u32 + ret += 4 + # P_std: u16 + ret += 2 + # L: CarrierPhase + ret += CarrierPhase._payload_size() + # cn0: u8 + ret += 1 + # lock: u16 + ret += 2 + # sid: GnssSignal + ret += GnssSignal._payload_size() + # doppler: s32 + ret += 4 + # doppler_std: u16 + ret += 2 + # uptime: u32 + ret += 4 + # clock_offset: s16 + ret += 2 + # clock_drift: s16 + ret += 2 + # corr_spacing: u16 + ret += 2 + # acceleration: s8 + ret += 1 + # sync_flags: u8 + ret += 1 + # tow_flags: u8 + ret += 1 + # track_flags: u8 + ret += 1 + # nav_flags: u8 + ret += 1 + # pset_flags: u8 + ret += 1 + # misc_flags: u8 + ret += 1 + return ret + +SBP_MSG_TRACKING_STATE_DETAILED_DEP = 0x0011 +class MsgTrackingStateDetailedDep(SBP): + """SBP class for message MSG_TRACKING_STATE_DETAILED_DEP (0x0011). + + You can have MSG_TRACKING_STATE_DETAILED_DEP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['recv_time', + 'tot', + 'P', + 'P_std', + 'L', + 'cn0', + 'lock', + 'sid', + 'doppler', + 'doppler_std', + 'uptime', + 'clock_offset', + 'clock_drift', + 'corr_spacing', + 'acceleration', + 'sync_flags', + 'tow_flags', + 'track_flags', + 'nav_flags', + 'pset_flags', + 'misc_flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__recv_time, offset, length) = get_u64(buf, offset, length) + ret['recv_time'] = __recv_time + (__tot, offset, length) = GPSTimeDep.parse_members(buf, offset, length) + ret['tot'] = __tot + (__P, offset, length) = get_u32(buf, offset, length) + ret['P'] = __P + (__P_std, offset, length) = get_u16(buf, offset, length) + ret['P_std'] = __P_std + (__L, offset, length) = CarrierPhase.parse_members(buf, offset, length) + ret['L'] = __L + (__cn0, offset, length) = get_u8(buf, offset, length) + ret['cn0'] = __cn0 + (__lock, offset, length) = get_u16(buf, offset, length) + ret['lock'] = __lock + (__sid, offset, length) = GnssSignalDep.parse_members(buf, offset, length) + ret['sid'] = __sid + (__doppler, offset, length) = get_s32(buf, offset, length) + ret['doppler'] = __doppler + (__doppler_std, offset, length) = get_u16(buf, offset, length) + ret['doppler_std'] = __doppler_std + (__uptime, offset, length) = get_u32(buf, offset, length) + ret['uptime'] = __uptime + (__clock_offset, offset, length) = get_s16(buf, offset, length) + ret['clock_offset'] = __clock_offset + (__clock_drift, offset, length) = get_s16(buf, offset, length) + ret['clock_drift'] = __clock_drift + (__corr_spacing, offset, length) = get_u16(buf, offset, length) + ret['corr_spacing'] = __corr_spacing + (__acceleration, offset, length) = get_s8(buf, offset, length) + ret['acceleration'] = __acceleration + (__sync_flags, offset, length) = get_u8(buf, offset, length) + ret['sync_flags'] = __sync_flags + (__tow_flags, offset, length) = get_u8(buf, offset, length) + ret['tow_flags'] = __tow_flags + (__track_flags, offset, length) = get_u8(buf, offset, length) + ret['track_flags'] = __track_flags + (__nav_flags, offset, length) = get_u8(buf, offset, length) + ret['nav_flags'] = __nav_flags + (__pset_flags, offset, length) = get_u8(buf, offset, length) + ret['pset_flags'] = __pset_flags + (__misc_flags, offset, length) = get_u8(buf, offset, length) + ret['misc_flags'] = __misc_flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.recv_time = res['recv_time'] + self.tot = res['tot'] + self.P = res['P'] + self.P_std = res['P_std'] + self.L = res['L'] + self.cn0 = res['cn0'] + self.lock = res['lock'] + self.sid = res['sid'] + self.doppler = res['doppler'] + self.doppler_std = res['doppler_std'] + self.uptime = res['uptime'] + self.clock_offset = res['clock_offset'] + self.clock_drift = res['clock_drift'] + self.corr_spacing = res['corr_spacing'] + self.acceleration = res['acceleration'] + self.sync_flags = res['sync_flags'] + self.tow_flags = res['tow_flags'] + self.track_flags = res['track_flags'] + self.nav_flags = res['nav_flags'] + self.pset_flags = res['pset_flags'] + self.misc_flags = res['misc_flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # recv_time: u64 + ret += 8 + # tot: GPSTimeDep + ret += GPSTimeDep._payload_size() + # P: u32 + ret += 4 + # P_std: u16 + ret += 2 + # L: CarrierPhase + ret += CarrierPhase._payload_size() + # cn0: u8 + ret += 1 + # lock: u16 + ret += 2 + # sid: GnssSignalDep + ret += GnssSignalDep._payload_size() + # doppler: s32 + ret += 4 + # doppler_std: u16 + ret += 2 + # uptime: u32 + ret += 4 + # clock_offset: s16 + ret += 2 + # clock_drift: s16 + ret += 2 + # corr_spacing: u16 + ret += 2 + # acceleration: s8 + ret += 1 + # sync_flags: u8 + ret += 1 + # tow_flags: u8 + ret += 1 + # track_flags: u8 + ret += 1 + # nav_flags: u8 + ret += 1 + # pset_flags: u8 + ret += 1 + # misc_flags: u8 + ret += 1 + return ret + +class TrackingChannelState(object): + """SBP class for message TrackingChannelState + + You can have TrackingChannelState inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Tracking channel state for a specific satellite signal and +measured signal power. + + + """ + __slots__ = ['sid', + 'fcn', + 'cn0', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__fcn, offset, length) = get_u8(buf, offset, length) + ret['fcn'] = __fcn + (__cn0, offset, length) = get_u8(buf, offset, length) + ret['cn0'] = __cn0 + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.sid = res['sid'] + self.fcn = res['fcn'] + self.cn0 = res['cn0'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # sid: GnssSignal + ret += GnssSignal._payload_size() + # fcn: u8 + ret += 1 + # cn0: u8 + ret += 1 + return ret + +SBP_MSG_TRACKING_STATE = 0x0041 +class MsgTrackingState(SBP): + """SBP class for message MSG_TRACKING_STATE (0x0041). + + You can have MSG_TRACKING_STATE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The tracking message returns a variable-length array of tracking +channel states. It reports status and carrier-to-noise density +measurements for all tracked satellites. + + + """ + __slots__ = ['states', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__states, offset, length) = get_array(TrackingChannelState.parse_members)(buf, offset, length) + ret['states'] = __states + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.states = res['states'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # states: array of TrackingChannelState + ret += 247 + return ret + +class MeasurementState(object): + """SBP class for message MeasurementState + + You can have MeasurementState inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Measurement Engine tracking channel state for a specific satellite signal +and measured signal power. +The mesid field for Glonass can either +carry the FCN as 100 + FCN where FCN is in [-7, +6] or +the Slot ID (from 1 to 28) + + + """ + __slots__ = ['mesid', + 'cn0', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__mesid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['mesid'] = __mesid + (__cn0, offset, length) = get_u8(buf, offset, length) + ret['cn0'] = __cn0 + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.mesid = res['mesid'] + self.cn0 = res['cn0'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # mesid: GnssSignal + ret += GnssSignal._payload_size() + # cn0: u8 + ret += 1 + return ret + +SBP_MSG_MEASUREMENT_STATE = 0x0061 +class MsgMeasurementState(SBP): + """SBP class for message MSG_MEASUREMENT_STATE (0x0061). + + You can have MSG_MEASUREMENT_STATE inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + The tracking message returns a variable-length array of tracking +channel states. It reports status and carrier-to-noise density +measurements for all tracked satellites. + + + """ + __slots__ = ['states', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__states, offset, length) = get_array(MeasurementState.parse_members)(buf, offset, length) + ret['states'] = __states + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.states = res['states'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # states: array of MeasurementState + ret += 247 + return ret + +class TrackingChannelCorrelation(object): + """SBP class for message TrackingChannelCorrelation + + You can have TrackingChannelCorrelation inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Structure containing in-phase and quadrature correlation components. + + + """ + __slots__ = ['I', + 'Q', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__I, offset, length) = get_s16(buf, offset, length) + ret['I'] = __I + (__Q, offset, length) = get_s16(buf, offset, length) + ret['Q'] = __Q + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.I = res['I'] + self.Q = res['Q'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # I: s16 + ret += 2 + # Q: s16 + ret += 2 + return ret + +SBP_MSG_TRACKING_IQ = 0x002D +class MsgTrackingIq(SBP): + """SBP class for message MSG_TRACKING_IQ (0x002D). + + You can have MSG_TRACKING_IQ inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + When enabled, a tracking channel can output the correlations at each +update interval. + + + """ + __slots__ = ['channel', + 'sid', + 'corrs', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__channel, offset, length) = get_u8(buf, offset, length) + ret['channel'] = __channel + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__corrs, offset, length) = get_fixed_array(TrackingChannelCorrelation._unpack_members, 3, TrackingChannelCorrelation._payload_size())(buf, offset, length) + ret['corrs'] = __corrs + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.channel = res['channel'] + self.sid = res['sid'] + self.corrs = res['corrs'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # channel: u8 + ret += 1 + # sid: GnssSignal + ret += GnssSignal._payload_size() + # corrs: array of TrackingChannelCorrelation + ret += TrackingChannelCorrelation._payload_size() * 3 + return ret + +class TrackingChannelCorrelationDep(object): + """SBP class for message TrackingChannelCorrelationDep + + You can have TrackingChannelCorrelationDep inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Structure containing in-phase and quadrature correlation components. + + + """ + __slots__ = ['I', + 'Q', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__I, offset, length) = get_s32(buf, offset, length) + ret['I'] = __I + (__Q, offset, length) = get_s32(buf, offset, length) + ret['Q'] = __Q + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.I = res['I'] + self.Q = res['Q'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # I: s32 + ret += 4 + # Q: s32 + ret += 4 + return ret + +SBP_MSG_TRACKING_IQ_DEP_B = 0x002C +class MsgTrackingIqDepB(SBP): + """SBP class for message MSG_TRACKING_IQ_DEP_B (0x002C). + + You can have MSG_TRACKING_IQ_DEP_B inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + When enabled, a tracking channel can output the correlations at each +update interval. + + + """ + __slots__ = ['channel', + 'sid', + 'corrs', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__channel, offset, length) = get_u8(buf, offset, length) + ret['channel'] = __channel + (__sid, offset, length) = GnssSignal.parse_members(buf, offset, length) + ret['sid'] = __sid + (__corrs, offset, length) = get_fixed_array(TrackingChannelCorrelationDep._unpack_members, 3, TrackingChannelCorrelationDep._payload_size())(buf, offset, length) + ret['corrs'] = __corrs + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.channel = res['channel'] + self.sid = res['sid'] + self.corrs = res['corrs'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # channel: u8 + ret += 1 + # sid: GnssSignal + ret += GnssSignal._payload_size() + # corrs: array of TrackingChannelCorrelationDep + ret += TrackingChannelCorrelationDep._payload_size() * 3 + return ret + +SBP_MSG_TRACKING_IQ_DEP_A = 0x001C +class MsgTrackingIqDepA(SBP): + """SBP class for message MSG_TRACKING_IQ_DEP_A (0x001C). + + You can have MSG_TRACKING_IQ_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['channel', + 'sid', + 'corrs', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__channel, offset, length) = get_u8(buf, offset, length) + ret['channel'] = __channel + (__sid, offset, length) = GnssSignalDep.parse_members(buf, offset, length) + ret['sid'] = __sid + (__corrs, offset, length) = get_fixed_array(TrackingChannelCorrelationDep._unpack_members, 3, TrackingChannelCorrelationDep._payload_size())(buf, offset, length) + ret['corrs'] = __corrs + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.channel = res['channel'] + self.sid = res['sid'] + self.corrs = res['corrs'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # channel: u8 + ret += 1 + # sid: GnssSignalDep + ret += GnssSignalDep._payload_size() + # corrs: array of TrackingChannelCorrelationDep + ret += TrackingChannelCorrelationDep._payload_size() * 3 + return ret + +class TrackingChannelStateDepA(object): + """SBP class for message TrackingChannelStateDepA + + You can have TrackingChannelStateDepA inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['state', + 'prn', + 'cn0', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__state, offset, length) = get_u8(buf, offset, length) + ret['state'] = __state + (__prn, offset, length) = get_u8(buf, offset, length) + ret['prn'] = __prn + (__cn0, offset, length) = get_f32(buf, offset, length) + ret['cn0'] = judicious_round(nb.f4(__cn0)) if SBP.judicious_rounding else __cn0 + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.state = res['state'] + self.prn = res['prn'] + self.cn0 = res['cn0'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # state: u8 + ret += 1 + # prn: u8 + ret += 1 + # cn0: float + ret += 4 + return ret + +SBP_MSG_TRACKING_STATE_DEP_A = 0x0016 +class MsgTrackingStateDepA(SBP): + """SBP class for message MSG_TRACKING_STATE_DEP_A (0x0016). + + You can have MSG_TRACKING_STATE_DEP_A inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['states', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__states, offset, length) = get_array(TrackingChannelStateDepA.parse_members)(buf, offset, length) + ret['states'] = __states + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.states = res['states'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # states: array of TrackingChannelStateDepA + ret += 247 + return ret + +class TrackingChannelStateDepB(object): + """SBP class for message TrackingChannelStateDepB + + You can have TrackingChannelStateDepB inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['state', + 'sid', + 'cn0', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__state, offset, length) = get_u8(buf, offset, length) + ret['state'] = __state + (__sid, offset, length) = GnssSignalDep.parse_members(buf, offset, length) + ret['sid'] = __sid + (__cn0, offset, length) = get_f32(buf, offset, length) + ret['cn0'] = judicious_round(nb.f4(__cn0)) if SBP.judicious_rounding else __cn0 + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.state = res['state'] + self.sid = res['sid'] + self.cn0 = res['cn0'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # state: u8 + ret += 1 + # sid: GnssSignalDep + ret += GnssSignalDep._payload_size() + # cn0: float + ret += 4 + return ret + +SBP_MSG_TRACKING_STATE_DEP_B = 0x0013 +class MsgTrackingStateDepB(SBP): + """SBP class for message MSG_TRACKING_STATE_DEP_B (0x0013). + + You can have MSG_TRACKING_STATE_DEP_B inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Deprecated. + + """ + __slots__ = ['states', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__states, offset, length) = get_array(TrackingChannelStateDepB.parse_members)(buf, offset, length) + ret['states'] = __states + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.states = res['states'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # states: array of TrackingChannelStateDepB + ret += 247 + return ret + + +msg_classes = { + 0x0021: MsgTrackingStateDetailedDepA, + 0x0011: MsgTrackingStateDetailedDep, + 0x0041: MsgTrackingState, + 0x0061: MsgMeasurementState, + 0x002D: MsgTrackingIq, + 0x002C: MsgTrackingIqDepB, + 0x001C: MsgTrackingIqDepA, + 0x0016: MsgTrackingStateDepA, + 0x0013: MsgTrackingStateDepB, +} \ No newline at end of file diff --git a/python/sbp/jit/user.py b/python/sbp/jit/user.py new file mode 100644 index 0000000000..e9fa94aa63 --- /dev/null +++ b/python/sbp/jit/user.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Messages reserved for use by the user. + +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +# Automatically generated from piksi/yaml/swiftnav/sbp/user.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_USER_DATA = 0x0800 +class MsgUserData(SBP): + """SBP class for message MSG_USER_DATA (0x0800). + + You can have MSG_USER_DATA inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + This message can contain any application specific user data up to a +maximum length of 255 bytes per message. + + + """ + __slots__ = ['contents', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__contents, offset, length) = get_array(get_u8)(buf, offset, length) + ret['contents'] = __contents + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.contents = res['contents'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # contents: array of u8 + ret += 247 + return ret + + +msg_classes = { + 0x0800: MsgUserData, +} \ No newline at end of file diff --git a/python/sbp/jit/vehicle.py b/python/sbp/jit/vehicle.py new file mode 100644 index 0000000000..a4795b4771 --- /dev/null +++ b/python/sbp/jit/vehicle.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +# Copyright (C) 2015-2018 Swift Navigation Inc. +# Contact: Swift Navigation +# +# This source is subject to the license found in the file 'LICENSE' which must +# be be distributed together with this source. All other rights reserved. +# +# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + + +""" +Messages from a vehicle. +""" + +import json + +import numba as nb + +from sbp.jit.msg import SBP, SENDER_ID +from sbp.jit.msg import get_u8, get_u16, get_u32, get_u64 +from sbp.jit.msg import get_s8, get_s16, get_s32, get_s64 +from sbp.jit.msg import get_f32, get_f64, judicious_round +from sbp.jit.msg import get_string, get_fixed_string, get_setting +from sbp.jit.msg import get_array, get_fixed_array + +# Automatically generated from piksi/yaml/swiftnav/sbp/vehicle.yaml with generate.py. +# Please do not hand edit! +SBP_MSG_ODOMETRY = 0x0903 +class MsgOdometry(SBP): + """SBP class for message MSG_ODOMETRY (0x0903). + + You can have MSG_ODOMETRY inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Message representing the x component of vehicle velocity in the user frame at the odometry +reference point(s) specified by the user. The offset for the odometry reference point and +the definition and origin of the user frame are defined through the device settings interface. +There are 4 possible user-defined sources of this message which are labeled arbitrarily +source 0 through 3. + + + """ + __slots__ = ['tow', + 'velocity', + 'flags', + ] + @classmethod + def parse_members(cls, buf, offset, length): + ret = {} + (__tow, offset, length) = get_u32(buf, offset, length) + ret['tow'] = __tow + (__velocity, offset, length) = get_s32(buf, offset, length) + ret['velocity'] = __velocity + (__flags, offset, length) = get_u8(buf, offset, length) + ret['flags'] = __flags + return ret, offset, length + + def _unpack_members(self, buf, offset, length): + res, off, length = self.parse_members(buf, offset, length) + if off == offset: + return {}, offset, length + self.tow = res['tow'] + self.velocity = res['velocity'] + self.flags = res['flags'] + return res, off, length + + @classmethod + def _payload_size(self): + ret = 0 + # tow: u32 + ret += 4 + # velocity: s32 + ret += 4 + # flags: u8 + ret += 1 + return ret + + +msg_classes = { + 0x0903: MsgOdometry, +} \ No newline at end of file diff --git a/python/test_requirements.txt b/python/test_requirements.txt index 2a815661a3..1b472e32ab 100644 --- a/python/test_requirements.txt +++ b/python/test_requirements.txt @@ -4,3 +4,4 @@ cov-core==1.15.0 coverage==4.4.1 tox ruamel.yaml +ujson diff --git a/python/tests/sbp/client/test_driver.py b/python/tests/sbp/client/test_driver.py index 7c4f269fd1..e596506f1e 100755 --- a/python/tests/sbp/client/test_driver.py +++ b/python/tests/sbp/client/test_driver.py @@ -43,7 +43,7 @@ def test_tcp_logger(): baud = 115200 t0 = time.time() sleep = 0.1 - timeout = 1.0 + timeout = 5.0 cb_context = {'assert_logger_called': False} def assert_logger(s, **metadata): cb_context['assert_logger_called'] = True diff --git a/python/tests/sbp/test_numba.py b/python/tests/sbp/test_numba.py new file mode 100644 index 0000000000..ab2ba285c1 --- /dev/null +++ b/python/tests/sbp/test_numba.py @@ -0,0 +1,96 @@ +import numba as nb +import numpy as np + +from sbp.file_io import MsgFileioWriteReq + +from sbp.jit.msg import SBP + +from sbp.jit.msg import get_string +from sbp.jit.msg import get_fixed_string + +from sbp.jit.table import dispatch + + +def _mk_string(val, null='\x00'): + ba = bytearray(val + (null if null is not None else ''), 'ascii') + return np.array(ba, dtype=np.uint8) + + +def test_get_string(): + s = _mk_string('thisisastring') + out, offset, length = get_string(s, 0, len(s)) + assert len(out) == len('thisisastring') + assert out == 'thisisastring' + + +def test_get_string_no_null(): + s = _mk_string('thisisastring', null=None) + out, offset, length = get_string(s, 0, len(s)) + assert len(out) == len('thisisastring') + assert out == 'thisisastring' + + +def test_get_string_offset_no_null(): + s = _mk_string('________thisisastring', null=None) + out, offset, length = get_string(s, 8, len(s) - 8) + assert len(out) == len('thisisastring') + assert out == 'thisisastring' + + +def test_get_string_offset(): + s = _mk_string('________thisisastring') + out, offset, length = get_string(s, 8, len(s)) + assert len(out) == len('thisisastring') + assert out == 'thisisastring' + + +def test_get_fixed_string(): + s = 'main\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + a = np.fromstring(s, dtype=np.uint8) + out, offset, length = get_fixed_string(len(s))(a, 0, len(a)) + assert len(out) == len(s) + assert out == s + + +def test_get_fixed_string_offset(): + s = _mk_string('________thisisastring') + out, offset, length = get_fixed_string(6)(s, 8, len(s)) + assert len(out) == len('thisis') + assert out == 'thisis' + + +def test_parse(): + + header_len = 6 + data = b'floofydata' + + m = MsgFileioWriteReq( + sequence=123, + offset=42, + filename=b'floof.bin\0' + data, + data=b'') + + buf = np.fromstring(m.to_binary(), dtype=np.uint8) + + assert len(buf) > 0 + + pkt_len, payload_len, msg_type, sender, crc, crc_fail = SBP.unpack_payload(buf, 0, len(buf)) + assert not crc_fail + + m = dispatch(msg_type)(msg_type) + res, offset, length = m.unpack(buf, header_len, payload_len) + + assert res is not None + + assert res['sequence'] == 123 + assert res['offset'] == 42 + assert res['filename'] == 'floof.bin' + + assert bytearray(res['data']) == bytearray(data) + + +def test_jit(): + @nb.jit('Tuple((Tuple((u2,u2)),u2))()', nopython=True, nogil=True) + def func(): + return ((123, 321), 42) + ((x, y), z) = func() diff --git a/python/tox.ini b/python/tox.ini index 1b9e608f17..bb47b36b96 100644 --- a/python/tox.ini +++ b/python/tox.ini @@ -5,5 +5,9 @@ minversion = 1.7.2 [testenv] deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test_requirements.txt -commands = py.test -v tests/ {posargs} +commands = + python {toxinidir}/sbp/jit/parse_float.py + py.test -v tests/ + py35,py37: {toxinidir}/../test_data/format-test.sh {posargs} + {toxinidir}/../test_data/benchmark.sh {posargs} sitepackages = False diff --git a/test_data/benchmark.sh b/test_data/benchmark.sh new file mode 100755 index 0000000000..f74b9e3625 --- /dev/null +++ b/test_data/benchmark.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +if [ "$#" -ne 1 ]; then + echo "Skipping benchmark.sh, enable by providing a full path to Haskell SBP tools" + exit 0 +fi + +set -e + +TESTDATA_ROOT=$(git rev-parse --show-toplevel)/test_data +echo "Running benchmark, please wait.." + +# http://mywiki.wooledge.org/BashFAQ/032 +time_py=$(TIMEFORMAT="%R"; { time PYTHONPATH=$TESTDATA_ROOT/../python/ \ + python $TESTDATA_ROOT/../../piksi_tools/piksi_tools/sbp2json.py \ + < $TESTDATA_ROOT/long.sbp --mode ujson > $TESTDATA_ROOT/long_py.json; } 2>&1) +echo "Python" $time_py + +time_hs=$(TIMEFORMAT="%R"; { time $1/sbp2json < $TESTDATA_ROOT/long.sbp > $TESTDATA_ROOT/long_hask.json; } 2>&1) +echo "Haskell" $time_hs + +threshold=1.8 +perf_diff=$(echo "$time_py / $time_hs" | bc -l) + +if (( $(echo "$perf_diff > $threshold" | bc -l) )); then + printf "\e[31mFAIL\e[0m: Python was %.2f times slower than Haskell. Threshold is < %.2f.\n" $perf_diff $threshold + exit 1 +fi + +printf "\e[32mSUCCESS\e[0m: Python/Haskell performance ratio was %.2f. Threshold is < %.2f.\n" $perf_diff $threshold diff --git a/test_data/format-test.sh b/test_data/format-test.sh new file mode 100755 index 0000000000..f514660be6 --- /dev/null +++ b/test_data/format-test.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +if [ "$#" -ne 1 ]; then + echo "Skipping format-test.sh, enable by providing a full path to Haskell SBP tools" + exit 0 +fi + +set -e + +TESTDATA_ROOT=$(git rev-parse --show-toplevel)/test_data +INPUT_SHORT=$TESTDATA_ROOT/short.sbp +OUTPUT_SHORT_HS=$TESTDATA_ROOT/short_hask_pretty.json +OUTPUT_SHORT_PY=$TESTDATA_ROOT/short_py_pretty.json + +INPUT_LONG=$TESTDATA_ROOT/long.sbp +OUTPUT_LONG_HS=$TESTDATA_ROOT/long_hask_pretty.json +OUTPUT_LONG_PY=$TESTDATA_ROOT/long_py_pretty.json + +PYTHONPATH=$TESTDATA_ROOT/../python/ \ + python $TESTDATA_ROOT/../../piksi_tools/piksi_tools/sbp2json.py \ + < $INPUT_SHORT --mode json --sort-keys --judicious-rounding > $OUTPUT_SHORT_PY + +if [ ! -f $OUTPUT_SHORT_HS ]; then + $1/sbp2prettyjson < $INPUT_SHORT > $OUTPUT_SHORT_HS +fi + +diff $OUTPUT_SHORT_HS $OUTPUT_SHORT_PY || exit 1 + +echo -e "Sanity check \e[32mOK\e[0m, please wait for format test.." + +PYTHONPATH=$TESTDATA_ROOT/../python/ \ + python $TESTDATA_ROOT/../../piksi_tools/piksi_tools/sbp2json.py \ + < $INPUT_LONG --mode json --sort-keys --judicious-rounding > $OUTPUT_LONG_PY + +if [ ! -f $OUTPUT_LONG_HS ]; then + $1/sbp2prettyjson < $INPUT_LONG > $OUTPUT_LONG_HS +fi + +diff $OUTPUT_LONG_HS $OUTPUT_LONG_PY || exit 1 + +echo -e "Format check \e[32mOK\e[0m" diff --git a/test_data/long.sbp b/test_data/long.sbp new file mode 100644 index 0000000000..b623a7058a Binary files /dev/null and b/test_data/long.sbp differ diff --git a/test_data/short.sbp b/test_data/short.sbp new file mode 100644 index 0000000000..71f129cbb0 Binary files /dev/null and b/test_data/short.sbp differ