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

Commit 54c6c61

Browse files
committed
Merge pull request #311 from swift-nav/peregrine_updates
Peregrine updates
2 parents 1c19883 + 460d431 commit 54c6c61

File tree

4 files changed

+154
-28
lines changed

4 files changed

+154
-28
lines changed

python/requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
cython>=0.17
2-
numpy>=1.9
1+
cython==0.23.4
2+
numpy==1.10.4
33
flake8==2.3.0
44
pep8==1.5.7
55
pytest==2.6.4

python/swiftnav/nav_msg.pyx

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ cdef class NavMsg:
3131
def from_dict(self, d):
3232
self._thisptr = d
3333

34+
def __reduce__(self):
35+
return (rebuild_NavMsg, tuple(self.to_dict().items()))
36+
3437
def update(self, bit_val):
3538
return nav_msg_update(&self._thisptr, bit_val)
3639

@@ -40,3 +43,59 @@ cdef class NavMsg:
4043
def process_subframe(self, e):
4144
cdef ephemeris_t tmp = e._thisptr
4245
return process_subframe(&self._thisptr, &tmp)
46+
47+
def __richcmp__(self, other, op):
48+
"""
49+
Weird Cython comparison method. See
50+
http://docs.cython.org/src/userguide/special_methods.html.
51+
"""
52+
if op == 2:
53+
return self._equal(other)
54+
elif op == 3:
55+
return not self._equal(other)
56+
else:
57+
raise NotImplementedError
58+
59+
def _equal(self, other):
60+
"""
61+
Compare equality between self and another :class:`NavMsg` object.
62+
63+
Parameters
64+
----------
65+
other : :class:`NavMsg` object
66+
The :class:`NavMsg` to test equality against.
67+
68+
Return
69+
------
70+
out : bool
71+
True if the passed :class:`NavMsg` object is identical.
72+
73+
"""
74+
if self.to_dict().keys() != other.to_dict().keys():
75+
return False
76+
77+
for k in self.to_dict().keys():
78+
if self.to_dict()[k] != other.to_dict()[k]:
79+
return False
80+
81+
return True
82+
83+
84+
def rebuild_NavMsg(reduced):
85+
"""
86+
Rebuild NavMsg for unpickling.
87+
88+
Parameters
89+
----------
90+
reduced: tuple
91+
Tuple of dict of NavMsg nav_msg_t struct fields
92+
93+
Returns
94+
-------
95+
out: :class:`NavMsg` instance
96+
Rebuilt :class:`NavMsg` instance
97+
"""
98+
nm = NavMsg()
99+
nm.from_dict(dict(reduced))
100+
return nm
101+

python/swiftnav/track.pyx

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ from libc.stdlib cimport malloc, free
2525
from libc.string cimport memset, memcpy
2626
from signal cimport GNSSSignal
2727
from signal import GNSSSignal
28+
from numpy import real, imag
2829

2930
# Discriminators
3031

@@ -236,19 +237,18 @@ cdef class AidedTrackingLoop:
236237
"""
237238

238239
def __cinit__(self, **kwargs):
239-
self._thisptr = kwargs
240240
aided_tl_init(&self._thisptr,
241-
self._thisptr.loop_freq,
242-
self._thisptr.code_freq,
243-
self._thisptr.code_bw,
244-
self._thisptr.code_zeta,
245-
self._thisptr.code_k,
246-
self._thisptr.carr_to_code,
247-
self._thisptr.carr_freq,
248-
self._thisptr.carr_bw,
249-
self._thisptr.carr_zeta,
250-
self._thisptr.carr_k,
251-
self._thisptr.carr_freq_b1)
241+
kwargs['loop_freq'],
242+
kwargs['code_freq'],
243+
kwargs['code_bw'],
244+
kwargs['code_zeta'],
245+
kwargs['code_k'],
246+
kwargs['carr_to_code'],
247+
kwargs['carr_freq'],
248+
kwargs['carr_bw'],
249+
kwargs['carr_zeta'],
250+
kwargs['carr_k'],
251+
kwargs['carr_freq_b1'])
252252

253253

254254
def retune(self, code_params, carr_params, loop_freq, carr_freq_igain, carr_to_code):
@@ -277,16 +277,18 @@ cdef class AidedTrackingLoop:
277277
self.carr_bw, self.carr_zeta, self.carr_k,
278278
self.carr_freq_igain)
279279

280-
def update(self, cs):
280+
def update(self, E, P, L):
281281
"""
282282
Wraps the function :libswiftnav:`aided_tl_update`.
283283
284284
Parameters
285285
----------
286-
cs : [complex], :math:`I_E + Q_E j`
287-
The early correlation. The real component contains the in-phase
288-
correlation and the imaginary component contains the quadrature
289-
correlation. The prompt correlation. The late correlation.
286+
E : [complex], :math:`I_E + Q_E j`
287+
Complex Early Correlation
288+
P : [complex], :math:`I_P + Q_P j`
289+
Complex Prompt Correlation
290+
L : [complex], :math:`I_L + Q_L j`
291+
Complex Late Correlation
290292
291293
Returns
292294
-------
@@ -295,11 +297,17 @@ cdef class AidedTrackingLoop:
295297
296298
"""
297299
cdef correlation_t cs_[3]
298-
cs_[0] = cs[0]._thisptr
299-
cs_[1] = cs[1]._thisptr
300-
cs_[2] = cs[2]._thisptr
300+
cs_[0].I = real(E)
301+
cs_[0].Q = imag(E)
302+
cs_[1].I = real(P)
303+
cs_[1].Q = imag(P)
304+
cs_[2].I = real(L)
305+
cs_[2].Q = imag(L)
301306
aided_tl_update(&self._thisptr, cs_)
302-
return (self.code_freq, self.carr_freq)
307+
return (self._thisptr.code_freq, self._thisptr.carr_freq)
308+
309+
def to_dict(self):
310+
return self._thisptr
303311

304312
cdef class CompTrackingLoop:
305313
"""
@@ -396,10 +404,10 @@ cdef class CN0Estimator:
396404

397405
def __cinit__(self, **kwargs):
398406
cn0_est_init(&self._thisptr,
399-
self._thisptr.bw,
400-
self._thisptr.cn0_0,
401-
self._thisptr.cutoff_freq,
402-
self._thisptr.loop_freq)
407+
kwargs['bw'],
408+
kwargs['cn0_0'],
409+
kwargs['cutoff_freq'],
410+
kwargs['loop_freq'])
403411

404412
def update(self, I, Q):
405413
"""

python/tests/test_nav_msg.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,63 @@ def test_imports():
1515
"""Verify that distributed packages survive setuptools installation.
1616
1717
"""
18-
assert True
18+
assert True
19+
20+
def build_nav_msg():
21+
""" Instantiate NavMsg with known attribute values. """
22+
nm = swiftnav.nav_msg.NavMsg()
23+
nm.from_dict(
24+
{
25+
'bit_polarity': -1,
26+
'frame_words': [[0, 0, 0, 0, 0, 0, 0, 0],
27+
[0, 0, 0, 0, 0, 0, 0, 0],
28+
[0, 0, 0, 0, 0, 0, 0, 0]],
29+
'next_subframe_id': 1,
30+
'overrun': False,
31+
'subframe_bit_index': 0,
32+
'subframe_bits': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
33+
'subframe_start_index': 0
34+
}
35+
)
36+
return nm
37+
38+
def test_instantiate():
39+
nm = swiftnav.nav_msg.NavMsg()
40+
41+
def test_build_nav_msg():
42+
build_nav_msg()
43+
44+
def test_equal():
45+
nm_a = build_nav_msg()
46+
nm_b = build_nav_msg()
47+
48+
# Change nm_b's fields slightly.
49+
nm_b_dict = nm_b.to_dict()
50+
nm_b_dict['bit_polarity'] = 1
51+
nm_b.from_dict(nm_b_dict)
52+
53+
assert nm_a._equal(nm_a)
54+
assert nm_b._equal(nm_b)
55+
assert not nm_a._equal(nm_b)
56+
assert not nm_b._equal(nm_a)
57+
58+
def test_richcmp():
59+
nm_a = build_nav_msg()
60+
nm_b = build_nav_msg()
61+
62+
# Change nm_b's fields slightly.
63+
nm_b_dict = nm_b.to_dict()
64+
nm_b_dict['bit_polarity'] = 1
65+
nm_b.from_dict(nm_b_dict)
66+
67+
assert nm_a == nm_a
68+
assert not(nm_a != nm_a)
69+
assert nm_a != nm_b
70+
assert not(nm_a == nm_b)
71+
72+
def test_rebuild():
73+
nm = build_nav_msg()
74+
75+
rebuild, args = nm.__reduce__()
76+
77+
assert rebuild(args) == nm

0 commit comments

Comments
 (0)