Skip to content

Commit 2d2fec4

Browse files
committed
add frame_handler util function and change xyz_points to order by columns
1 parent a31cb16 commit 2d2fec4

File tree

1 file changed

+110
-4
lines changed

1 file changed

+110
-4
lines changed

os1/utils.py

Lines changed: 110 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
import math
2+
import struct
3+
import sys
24

35
from os1.packet import (
46
AZIMUTH_BLOCK_COUNT,
57
CHANNEL_BLOCK_COUNT,
68
azimuth_angle,
79
azimuth_block,
10+
azimuth_measurement_id,
11+
azimuth_timestamp,
812
azimuth_valid,
913
channel_block,
1014
channel_range,
1115
unpack,
1216
)
1317

18+
# The OS-16 will still contain 64 channels in the packet, but only
19+
# every 4th channel starting at the 2nd will contain data .
20+
OS_16_CHANNELS = (2, 6, 10, 14, 18, 22, 26, 30, 34, 42, 46, 50, 54, 58, 62)
21+
OS_64_CHANNELS = tuple(i for i in range(CHANNEL_BLOCK_COUNT))
22+
1423

1524
class UninitializedTrigTable(Exception):
1625
def __init__(self):
@@ -49,11 +58,21 @@ def xyz_point(channel_n, azimuth_block):
4958
y = range * table_entry[1] * math.sin(adjusted_angle)
5059
z = range * table_entry[0]
5160

52-
return x, y, z
61+
return [x, y, z]
5362

5463

55-
def xyz_points(packet):
56-
"""3D cartesian x, y, z coordinates."""
64+
def xyz_points(packet, os16=False):
65+
"""
66+
Returns a tuple of x, y, z points where each x, y, z is a list of
67+
all the x, y or z points in the packet
68+
69+
(
70+
[x1, x2, ...],
71+
[y1, y2, ...],
72+
[z1, z2, ...],
73+
)
74+
"""
75+
channels = OS_16_CHANNELS if os16 else OS_64_CHANNELS
5776
if not isinstance(packet, tuple):
5877
packet = unpack(packet)
5978

@@ -67,9 +86,96 @@ def xyz_points(packet):
6786
if not azimuth_valid(block):
6887
continue
6988

70-
for c in range(CHANNEL_BLOCK_COUNT):
89+
for c in channels:
7190
point = xyz_point(c, block)
7291
x.append(point[0])
7392
y.append(point[1])
7493
z.append(point[2])
7594
return x, y, z
95+
96+
97+
def xyz_columns(packet, os16=False):
98+
"""
99+
Similar to xyz_points except the x, y, z values are ordered by
100+
column. This is convenient if you only want to render a specific
101+
column.
102+
103+
The structure of it will be be columns containing channels. It
104+
looks like...
105+
106+
[
107+
# column 1
108+
[
109+
[channel1_x, channel2_x, ...],
110+
[channel1_y, channel2_y, ...],
111+
[channel1_z, channel2_z, ...],
112+
],
113+
# column 2
114+
[
115+
[channel1_x, channel2_x, ...],
116+
[channel1_y, channel2_y, ...],
117+
[channel1_z, channel2_z, ...],
118+
],
119+
]
120+
"""
121+
channels = OS_16_CHANNELS if os16 else OS_64_CHANNELS
122+
if not isinstance(packet, tuple):
123+
packet = unpack(packet)
124+
125+
points = []
126+
for b in range(AZIMUTH_BLOCK_COUNT):
127+
block = azimuth_block(b, packet)
128+
x = []
129+
y = []
130+
z = []
131+
132+
for channel in channels:
133+
point = xyz_point(channel, block)
134+
x.append(point[0])
135+
y.append(point[1])
136+
z.append(point[2])
137+
points.append([x, y, z])
138+
return points
139+
140+
141+
_unpack = struct.Struct("<I").unpack
142+
143+
144+
def peek_encoder_count(packet):
145+
return _unpack(packet[12:16])[0]
146+
147+
148+
def frame_handler(queue):
149+
"""
150+
Handler that buffers packets until it has a full frame then puts
151+
them into a queue. Queue must have a put method.
152+
153+
The data put into the queue will be a dict that contains a buffer
154+
of packets making up a frame and the rotation number.
155+
156+
{
157+
'buffer': [packet1, packet2, ...],
158+
'rotation': 1
159+
}
160+
"""
161+
buffer = []
162+
rotation_num = 0
163+
sentinel = None
164+
last = None
165+
166+
def handler(packet):
167+
nonlocal rotation_num, sentinel, last, buffer
168+
169+
encoder_count = peek_encoder_count(packet)
170+
if sentinel is None:
171+
sentinel = encoder_count
172+
173+
if buffer and last and encoder_count >= sentinel and last <= sentinel:
174+
rotation_num += 1
175+
queue.put({"buffer": buffer, "rotation": rotation_num})
176+
buffer = []
177+
178+
buffer.append(packet)
179+
last = encoder_count
180+
181+
return handler

0 commit comments

Comments
 (0)