Skip to content
This repository was archived by the owner on Apr 13, 2021. It is now read-only.

Commit baba16f

Browse files
GLONASS: added Python bindings for GLONASS message decoder
Added Python bindings for GLONASS message decoder operations.
1 parent d901fdb commit baba16f

File tree

5 files changed

+302
-50
lines changed

5 files changed

+302
-50
lines changed

python/setup.py

Lines changed: 46 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,30 @@
22
from version import get_git_version
33

44
setup_args = dict(
5-
name = 'swiftnav',
6-
version = get_git_version(),
7-
description = 'Python bindings to the libswiftnav library.',
8-
license = 'LGPLv3',
9-
url = 'http://www.swiftnav.com',
10-
author = 'Swift Navigation Inc.',
11-
author_email = '[email protected]',
12-
maintainer = 'Swift Navigation',
13-
maintainer_email = '[email protected]',
14-
packages = ['swiftnav'],
5+
name='swiftnav',
6+
version=get_git_version(),
7+
description='Python bindings to the libswiftnav library.',
8+
license='LGPLv3',
9+
url='http://www.swiftnav.com',
10+
author='Swift Navigation Inc.',
11+
author_email='[email protected]',
12+
maintainer='Swift Navigation',
13+
maintainer_email='[email protected]',
14+
packages=['swiftnav'],
1515
)
1616

1717
if __name__ == "__main__":
1818
import numpy as np
19-
import os, sys
19+
import os
20+
import sys
2021
from setuptools import setup, Extension
2122
try:
2223
from Cython.Distutils import build_ext
2324
except:
2425
print "You don't seem to have Cython installed."
2526
sys.exit(1)
2627
os.environ['ARCHFLAGS'] = ""
28+
2729
def make_extension(ext_name):
2830
ext_path = ext_name.replace('.', os.path.sep) + '.pyx'
2931
library_dirs = []
@@ -32,40 +34,41 @@ def make_extension(ext_name):
3234
if 'LD_LIBRARY_PATH' in os.environ:
3335
library_dirs.append(os.environ['LD_LIBRARY_PATH'])
3436
return Extension(
35-
ext_name, [ext_path],
36-
include_dirs = [np.get_include(), '.', '../include/'],
37-
extra_compile_args = ['-O0', '-g'],
38-
extra_link_args = ['-g'],
39-
libraries = ['m', 'swiftnav'],
40-
library_dirs = library_dirs,
37+
ext_name, [ext_path],
38+
include_dirs=[np.get_include(), '.', '../include/'],
39+
extra_compile_args=['-O0', '-g'],
40+
extra_link_args=['-g'],
41+
libraries=['m', 'swiftnav'],
42+
library_dirs=library_dirs,
4143
)
4244
ext_names = [
43-
'swiftnav.edc',
44-
'swiftnav.signal',
45-
'swiftnav.coord_system',
46-
'swiftnav.constants',
47-
'swiftnav.nav_msg',
48-
'swiftnav.pvt',
49-
'swiftnav.correlate',
50-
'swiftnav.track',
51-
'swiftnav.almanac',
52-
'swiftnav.lambda_',
53-
'swiftnav.ephemeris',
54-
'swiftnav.linear_algebra',
55-
'swiftnav.amb_kf',
56-
'swiftnav.time',
57-
'swiftnav.observation',
58-
'swiftnav.dgnss_management',
59-
'swiftnav.ambiguity_test',
60-
'swiftnav.baseline',
61-
'swiftnav.bits',
62-
'swiftnav.filter_utils',
63-
'swiftnav.memory_pool',
64-
'swiftnav.prns',
65-
'swiftnav.sats_management',
66-
'swiftnav.tropo',
67-
'swiftnav.set',
68-
'swiftnav.bit_sync',
45+
'swiftnav.edc',
46+
'swiftnav.signal',
47+
'swiftnav.coord_system',
48+
'swiftnav.constants',
49+
'swiftnav.nav_msg',
50+
'swiftnav.nav_msg_glo',
51+
'swiftnav.pvt',
52+
'swiftnav.correlate',
53+
'swiftnav.track',
54+
'swiftnav.almanac',
55+
'swiftnav.lambda_',
56+
'swiftnav.ephemeris',
57+
'swiftnav.linear_algebra',
58+
'swiftnav.amb_kf',
59+
'swiftnav.time',
60+
'swiftnav.observation',
61+
'swiftnav.dgnss_management',
62+
'swiftnav.ambiguity_test',
63+
'swiftnav.baseline',
64+
'swiftnav.bits',
65+
'swiftnav.filter_utils',
66+
'swiftnav.memory_pool',
67+
'swiftnav.prns',
68+
'swiftnav.sats_management',
69+
'swiftnav.tropo',
70+
'swiftnav.set',
71+
'swiftnav.bit_sync',
6972
]
7073
extensions = [make_extension(name) for name in ext_names]
7174
setup_args['ext_modules'] = extensions

python/swiftnav/ephemeris.pyx

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (C) 2015 Swift Navigation Inc.
1+
# Copyright (C) 2015-2016 Swift Navigation Inc.
22
#
33
# This source is subject to the license found in the file 'LICENSE' which must
44
# be be distributed together with this source. All other rights reserved.
@@ -24,12 +24,18 @@ cdef class Ephemeris:
2424

2525
def __init__(self, **kwargs):
2626
memset(&self._thisptr, 0, sizeof(ephemeris_t))
27-
self._thisptr.sid = kwargs.pop('sid')
28-
self._thisptr.toe = kwargs.pop('toe')
29-
self._thisptr.ura = kwargs.pop('ura')
30-
self._thisptr.fit_interval = kwargs.pop('fit_interval')
31-
self._thisptr.valid = kwargs.pop('valid')
32-
self._thisptr.healthy = kwargs.pop('healthy')
27+
if 'sid' in kwargs:
28+
self._thisptr.sid = kwargs.pop('sid')
29+
if 'toe' in kwargs:
30+
self._thisptr.toe = kwargs.pop('toe')
31+
if 'ura' in kwargs:
32+
self._thisptr.ura = kwargs.pop('ura')
33+
if 'fit_interval' in kwargs:
34+
self._thisptr.fit_interval = kwargs.pop('fit_interval')
35+
if 'valid' in kwargs:
36+
self._thisptr.valid = kwargs.pop('valid')
37+
if 'healthy' in kwargs:
38+
self._thisptr.healthy = kwargs.pop('healthy')
3339
if 'kepler' in kwargs:
3440
self._thisptr.kepler = kwargs.pop('kepler')
3541
elif 'xyz' in kwargs:

python/swiftnav/nav_msg_glo.pxd

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Copyright (C) 2016 Swift Navigation Inc.
2+
#
3+
# This source is subject to the license found in the file 'LICENSE' which must
4+
# be be distributed together with this source. All other rights reserved.
5+
#
6+
# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
7+
# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
8+
# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
9+
10+
# cython: embedsignature=True
11+
12+
from common cimport *
13+
from ephemeris cimport *
14+
from libcpp cimport bool
15+
from signal cimport gnss_signal_t
16+
17+
cdef extern from "libswiftnav/nav_msg_glo.h":
18+
enum:
19+
NAV_MSG_GLO_STRING_BITS_LEN
20+
GLO_TM
21+
GLO_TM_LEN
22+
23+
ctypedef enum glo_receive_machine:
24+
INVALID
25+
SYNC_TM
26+
GET_DATA_BIT
27+
28+
ctypedef struct nav_msg_glo_t:
29+
u32 string_bits[NAV_MSG_GLO_STRING_BITS_LEN]
30+
u16 current_head_bit_index
31+
u16 nt
32+
u8 next_string_id
33+
u8 n4
34+
u8 hrs
35+
u8 min
36+
u8 sec
37+
glo_receive_machine state
38+
u8 meander_bits_cnt
39+
u8 manchester
40+
u8 decode_done
41+
42+
void nav_msg_init_glo(nav_msg_glo_t *n)
43+
s8 process_string_glo(nav_msg_glo_t *n, ephemeris_t *e)
44+
s8 nav_msg_update_glo(nav_msg_glo_t *n, bool bit_val)
45+
double nav_msg_get_tow_glo(nav_msg_glo_t *n)
46+
s8 error_detection_glo(nav_msg_glo_t *n)
47+
48+
cdef class NavMsgGlo:
49+
cdef nav_msg_glo_t _thisptr

python/swiftnav/nav_msg_glo.pyx

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Copyright (C) 2016 Swift Navigation Inc.
2+
#
3+
# This source is subject to the license found in the file 'LICENSE' which must
4+
# be be distributed together with this source. All other rights reserved.
5+
#
6+
# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
7+
# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
8+
# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
9+
10+
# cython: embedsignature=True
11+
12+
from ephemeris cimport ephemeris_t
13+
from fmt_utils import fmt_repr
14+
from time cimport gps_time_t
15+
from signal cimport gnss_signal_t
16+
from swiftnav.ephemeris import Ephemeris
17+
18+
19+
cdef class NavMsgGlo:
20+
21+
def __cinit__(self):
22+
nav_msg_init_glo(&self._thisptr)
23+
24+
def __getattr__(self, k):
25+
return self._thisptr.get(k)
26+
27+
def __repr__(self):
28+
return fmt_repr(self)
29+
30+
def to_dict(self):
31+
return self._thisptr
32+
33+
def from_dict(self, d):
34+
self._thisptr = d
35+
36+
def __reduce__(self):
37+
return (rebuild_NavMsgGlo, tuple(self.to_dict().items()))
38+
39+
def updateEphemeris(self, Ephemeris e):
40+
return process_string_glo(&self._thisptr, &e._thisptr)
41+
42+
def update(self, bit_val):
43+
return nav_msg_update_glo(&self._thisptr, bit_val)
44+
45+
def getTow(self):
46+
return nav_msg_get_tow_glo(&self._thisptr)
47+
48+
def detectError(self):
49+
return error_detection_glo(&self._thisptr)
50+
51+
def isDecodeDone(self):
52+
return self._thisptr.decode_done != 0
53+
54+
def __richcmp__(self, other, op):
55+
"""
56+
Weird Cython comparison method. See
57+
http://docs.cython.org/src/userguide/special_methods.html.
58+
"""
59+
if op == 2:
60+
return self._equal(other)
61+
elif op == 3:
62+
return not self._equal(other)
63+
else:
64+
raise NotImplementedError
65+
66+
def _equal(self, other):
67+
"""
68+
Compare equality between self and another :class:`NavMsg` object.
69+
70+
Parameters
71+
----------
72+
other : :class:`NavMsgGlo` object
73+
The :class:`NavMsgGlo` to test equality against.
74+
75+
Return
76+
------
77+
out : bool
78+
True if the passed :class:`NavMsg` object is identical.
79+
80+
"""
81+
if self.to_dict().keys() != other.to_dict().keys():
82+
return False
83+
84+
for k in self.to_dict().keys():
85+
if self.to_dict()[k] != other.to_dict()[k]:
86+
return False
87+
88+
return True
89+
90+
91+
def rebuild_NavMsgGlo(*reduced):
92+
"""
93+
Rebuild NavMsg for unpickling.
94+
95+
Parameters
96+
----------
97+
reduced: tuple
98+
Tuple of dict of NavMsg nav_msg_t struct fields
99+
100+
Returns
101+
-------
102+
out: :class:`NavMsg` instance
103+
Rebuilt :class:`NavMsg` instance
104+
"""
105+
nm = NavMsgGlo()
106+
nm.from_dict(dict(reduced))
107+
return nm
108+

python/tests/test_nav_msg_glo.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
2+
3+
from swiftnav.nav_msg_glo import NavMsgGlo
4+
from swiftnav.ephemeris import Ephemeris
5+
import numpy
6+
7+
8+
def test_imports():
9+
"""Verify that distributed packages survive setuptools installation.
10+
11+
"""
12+
pass
13+
14+
GLO_STRINGS = numpy.asanyarray([[1, 1, 1], # dummy words
15+
# 01074396999b05c3a850b5
16+
[0x010743, 0x96999b05, 0xc3a850b5],
17+
# 021760a5256204d9c15f66
18+
[0x021760, 0xa5256204, 0xd9c15f66],
19+
# 0380269d60899a6d0e3123
20+
[0x038026, 0x6d0e3123, 0x9d60899a],
21+
# 04865d1cc0000000344918
22+
[0x04865d, 0x00344918, 0x1cc00000],
23+
# 050d100000000340000895
24+
[0x050d10, 0x3, 0x40000895]
25+
],
26+
dtype=numpy.dtype('>u4'))
27+
GLO_STRING_BITS = [numpy.unpackbits(s.view(numpy.uint8))[-85:]
28+
for s in GLO_STRINGS]
29+
30+
GLO_TM = numpy.asanyarray([0x3E375096], dtype=numpy.dtype('>u4'))
31+
GLO_TM_BITS = numpy.unpackbits(GLO_TM.view(numpy.uint8))[-30:]
32+
33+
34+
def test_init():
35+
'''
36+
Object construction test
37+
'''
38+
msg = NavMsgGlo()
39+
assert msg.isDecodeDone() == False
40+
assert msg.getTow() == -1.
41+
42+
43+
def test_update():
44+
'''
45+
Object update test
46+
'''
47+
msg = NavMsgGlo()
48+
assert msg.update(0) == -1
49+
assert msg.update(0) == -1
50+
assert msg.update(0) == -1
51+
assert msg.update(1) == -1
52+
53+
assert msg.isDecodeDone() == False
54+
assert msg.getTow() == -1.
55+
56+
57+
def test_decode():
58+
'''
59+
Ephemeris and ToW decoding test.
60+
'''
61+
msg = NavMsgGlo()
62+
n_strings = 0
63+
n_tow = 0
64+
tow = -1
65+
e = Ephemeris()
66+
print GLO_STRING_BITS
67+
for bit_string in GLO_STRING_BITS:
68+
print bit_string
69+
for bit in bit_string:
70+
assert msg.update(bit ^ 1) == -1
71+
if msg.update(bit) == 1:
72+
n_strings += 1
73+
if msg.updateEphemeris(e) == 1:
74+
n_tow += 1
75+
tow = msg.getTow()
76+
77+
# now pass time mark bit by bit to receiver (MSB first), no line code
78+
# needed
79+
for bit in GLO_TM_BITS:
80+
assert msg.update(bit) == -1
81+
82+
assert n_strings == 5
83+
assert n_tow == 1
84+
assert isinstance(tow, float)
85+
assert tow == 262707.0
86+
assert e.toe['tow'] == 262707.0 - 10.

0 commit comments

Comments
 (0)