mapillary-tools 0.13.1__py3-none-any.whl → 0.13.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mapillary_tools/__init__.py +1 -1
- mapillary_tools/camm/camm_builder.py +62 -14
- mapillary_tools/camm/camm_parser.py +73 -292
- mapillary_tools/telemetry.py +8 -20
- mapillary_tools/upload.py +3 -2
- {mapillary_tools-0.13.1.dist-info → mapillary_tools-0.13.2.dist-info}/METADATA +1 -1
- {mapillary_tools-0.13.1.dist-info → mapillary_tools-0.13.2.dist-info}/RECORD +11 -11
- {mapillary_tools-0.13.1.dist-info → mapillary_tools-0.13.2.dist-info}/LICENSE +0 -0
- {mapillary_tools-0.13.1.dist-info → mapillary_tools-0.13.2.dist-info}/WHEEL +0 -0
- {mapillary_tools-0.13.1.dist-info → mapillary_tools-0.13.2.dist-info}/entry_points.txt +0 -0
- {mapillary_tools-0.13.1.dist-info → mapillary_tools-0.13.2.dist-info}/top_level.txt +0 -0
mapillary_tools/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
VERSION = "0.13.
|
|
1
|
+
VERSION = "0.13.2"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import io
|
|
2
2
|
import typing as T
|
|
3
3
|
|
|
4
|
-
from .. import geo, types
|
|
4
|
+
from .. import geo, telemetry, types
|
|
5
5
|
from ..mp4 import (
|
|
6
6
|
construct_mp4_parser as cparser,
|
|
7
7
|
mp4_sample_parser as sample_parser,
|
|
@@ -11,11 +11,62 @@ from ..mp4 import (
|
|
|
11
11
|
from . import camm_parser
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
TelemetryMeasurement = T.Union[
|
|
15
|
+
geo.Point,
|
|
16
|
+
telemetry.TelemetryMeasurement,
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _build_camm_sample(measurement: TelemetryMeasurement) -> bytes:
|
|
21
|
+
if isinstance(measurement, geo.Point):
|
|
22
|
+
return camm_parser.CAMMSampleData.build(
|
|
23
|
+
{
|
|
24
|
+
"type": camm_parser.CAMMType.MIN_GPS.value,
|
|
25
|
+
"data": [
|
|
26
|
+
measurement.lat,
|
|
27
|
+
measurement.lon,
|
|
28
|
+
-1.0 if measurement.alt is None else measurement.alt,
|
|
29
|
+
],
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
elif isinstance(measurement, telemetry.AccelerationData):
|
|
33
|
+
# Accelerometer reading in meters/second^2 along XYZ axes of the camera.
|
|
34
|
+
return camm_parser.CAMMSampleData.build(
|
|
35
|
+
{
|
|
36
|
+
"type": camm_parser.CAMMType.ACCELERATION.value,
|
|
37
|
+
"data": [
|
|
38
|
+
measurement.x,
|
|
39
|
+
measurement.y,
|
|
40
|
+
measurement.z,
|
|
41
|
+
],
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
elif isinstance(measurement, telemetry.GyroscopeData):
|
|
45
|
+
# Gyroscope signal in radians/seconds around XYZ axes of the camera. Rotation is positive in the counterclockwise direction.
|
|
46
|
+
return camm_parser.CAMMSampleData.build(
|
|
47
|
+
{
|
|
48
|
+
"type": camm_parser.CAMMType.GYRO.value,
|
|
49
|
+
"data": [
|
|
50
|
+
measurement.x,
|
|
51
|
+
measurement.y,
|
|
52
|
+
measurement.z,
|
|
53
|
+
],
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
elif isinstance(measurement, telemetry.MagnetometerData):
|
|
57
|
+
# Ambient magnetic field.
|
|
58
|
+
return camm_parser.CAMMSampleData.build(
|
|
59
|
+
{
|
|
60
|
+
"type": camm_parser.CAMMType.MAGNETIC_FIELD.value,
|
|
61
|
+
"data": [
|
|
62
|
+
measurement.x,
|
|
63
|
+
measurement.y,
|
|
64
|
+
measurement.z,
|
|
65
|
+
],
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
else:
|
|
69
|
+
raise ValueError(f"unexpected measurement type {type(measurement)}")
|
|
19
70
|
|
|
20
71
|
|
|
21
72
|
def _create_edit_list_from_points(
|
|
@@ -70,19 +121,16 @@ def _create_edit_list_from_points(
|
|
|
70
121
|
|
|
71
122
|
def _multiplex(
|
|
72
123
|
points: T.Sequence[geo.Point],
|
|
73
|
-
measurements: T.Optional[T.List[
|
|
74
|
-
) -> T.List[
|
|
75
|
-
mutiplexed: T.List[
|
|
76
|
-
*points,
|
|
77
|
-
*(measurements or []),
|
|
78
|
-
]
|
|
124
|
+
measurements: T.Optional[T.List[telemetry.TelemetryMeasurement]] = None,
|
|
125
|
+
) -> T.List[TelemetryMeasurement]:
|
|
126
|
+
mutiplexed: T.List[TelemetryMeasurement] = [*points, *(measurements or [])]
|
|
79
127
|
mutiplexed.sort(key=lambda m: m.time)
|
|
80
128
|
|
|
81
129
|
return mutiplexed
|
|
82
130
|
|
|
83
131
|
|
|
84
132
|
def convert_telemetry_to_raw_samples(
|
|
85
|
-
measurements: T.Sequence[
|
|
133
|
+
measurements: T.Sequence[TelemetryMeasurement],
|
|
86
134
|
timescale: int,
|
|
87
135
|
) -> T.Generator[sample_parser.RawSample, None, None]:
|
|
88
136
|
for idx, measurement in enumerate(measurements):
|
|
@@ -235,7 +283,7 @@ def create_camm_trak(
|
|
|
235
283
|
|
|
236
284
|
def camm_sample_generator2(
|
|
237
285
|
video_metadata: types.VideoMetadata,
|
|
238
|
-
telemetry_measurements: T.Optional[T.List[
|
|
286
|
+
telemetry_measurements: T.Optional[T.List[telemetry.TelemetryMeasurement]] = None,
|
|
239
287
|
):
|
|
240
288
|
def _f(
|
|
241
289
|
fp: T.BinaryIO,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# pyre-ignore-all-errors[5, 11, 16, 21, 24, 58]
|
|
2
2
|
|
|
3
|
-
import abc
|
|
4
3
|
import dataclasses
|
|
5
4
|
import io
|
|
6
5
|
import logging
|
|
@@ -20,7 +19,9 @@ LOG = logging.getLogger(__name__)
|
|
|
20
19
|
|
|
21
20
|
TelemetryMeasurement = T.Union[
|
|
22
21
|
geo.Point,
|
|
23
|
-
telemetry.
|
|
22
|
+
telemetry.AccelerationData,
|
|
23
|
+
telemetry.GyroscopeData,
|
|
24
|
+
telemetry.MagnetometerData,
|
|
24
25
|
]
|
|
25
26
|
|
|
26
27
|
|
|
@@ -35,305 +36,51 @@ class CAMMType(Enum):
|
|
|
35
36
|
GPS = 6
|
|
36
37
|
MAGNETIC_FIELD = 7
|
|
37
38
|
|
|
38
|
-
# Mapillary extensions are offset by 1024
|
|
39
|
-
# GoPro GPS is not compatible with CAMMType.GPS,
|
|
40
|
-
# so we use a new type to represent it
|
|
41
|
-
MLY_GOPRO_GPS = 1024 + 6
|
|
42
|
-
|
|
43
39
|
|
|
44
40
|
# All fields are little-endian
|
|
45
41
|
Float = C.Float32l
|
|
46
42
|
Double = C.Float64l
|
|
47
43
|
|
|
48
|
-
|
|
49
|
-
TTelemetry = T.TypeVar("TTelemetry", bound=TelemetryMeasurement)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
class CAMMSampleEntry(abc.ABC, T.Generic[TTelemetry]):
|
|
53
|
-
camm_type: CAMMType
|
|
54
|
-
|
|
55
|
-
construct: C.Struct
|
|
56
|
-
|
|
57
|
-
telemetry_cls: T.Type[TTelemetry]
|
|
58
|
-
|
|
59
|
-
@classmethod
|
|
60
|
-
def serializable(cls, data: T.Any, throw: bool = False) -> bool:
|
|
61
|
-
# Use "is" for exact type match, instead of isinstance
|
|
62
|
-
if type(data) is cls.telemetry_cls:
|
|
63
|
-
return True
|
|
64
|
-
|
|
65
|
-
if throw:
|
|
66
|
-
raise TypeError(
|
|
67
|
-
f"{cls} can not serialize {type(data)}: expect {cls.telemetry_cls}"
|
|
68
|
-
)
|
|
69
|
-
return False
|
|
70
|
-
|
|
71
|
-
@classmethod
|
|
72
|
-
@abc.abstractmethod
|
|
73
|
-
def serialize(cls, data: TTelemetry) -> bytes:
|
|
74
|
-
raise NotImplementedError
|
|
75
|
-
|
|
76
|
-
@classmethod
|
|
77
|
-
@abc.abstractmethod
|
|
78
|
-
def deserialize(cls, sample: Sample, data: T.Any) -> TTelemetry:
|
|
79
|
-
raise NotImplementedError
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
class MinGPSSampleEntry(CAMMSampleEntry):
|
|
83
|
-
camm_type = CAMMType.MIN_GPS
|
|
84
|
-
|
|
85
|
-
construct = Double[3] # type: ignore
|
|
86
|
-
|
|
87
|
-
telemetry_cls = geo.Point
|
|
88
|
-
|
|
89
|
-
@classmethod
|
|
90
|
-
def deserialize(cls, sample: Sample, data: T.Any) -> geo.Point:
|
|
91
|
-
return geo.Point(
|
|
92
|
-
time=sample.exact_time,
|
|
93
|
-
lat=data[0],
|
|
94
|
-
lon=data[1],
|
|
95
|
-
alt=data[2],
|
|
96
|
-
angle=None,
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
@classmethod
|
|
100
|
-
def serialize(cls, data: geo.Point) -> bytes:
|
|
101
|
-
cls.serializable(data, throw=True)
|
|
102
|
-
|
|
103
|
-
return CAMMSampleData.build(
|
|
104
|
-
{
|
|
105
|
-
"type": cls.camm_type.value,
|
|
106
|
-
"data": [
|
|
107
|
-
data.lat,
|
|
108
|
-
data.lon,
|
|
109
|
-
-1.0 if data.alt is None else data.alt,
|
|
110
|
-
],
|
|
111
|
-
}
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
class GPSSampleEntry(CAMMSampleEntry):
|
|
116
|
-
camm_type: CAMMType = CAMMType.GPS
|
|
117
|
-
|
|
118
|
-
construct = C.Struct(
|
|
119
|
-
"time_gps_epoch" / Double, # type: ignore
|
|
120
|
-
"gps_fix_type" / C.Int32sl, # type: ignore
|
|
121
|
-
"latitude" / Double, # type: ignore
|
|
122
|
-
"longitude" / Double, # type: ignore
|
|
123
|
-
"altitude" / Float, # type: ignore
|
|
124
|
-
"horizontal_accuracy" / Float, # type: ignore
|
|
125
|
-
"vertical_accuracy" / Float, # type: ignore
|
|
126
|
-
"velocity_east" / Float, # type: ignore
|
|
127
|
-
"velocity_north" / Float, # type: ignore
|
|
128
|
-
"velocity_up" / Float, # type: ignore
|
|
129
|
-
"speed_accuracy" / Float, # type: ignore
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
telemetry_cls = telemetry.CAMMGPSPoint
|
|
133
|
-
|
|
134
|
-
@classmethod
|
|
135
|
-
def deserialize(cls, sample: Sample, data: T.Any) -> telemetry.CAMMGPSPoint:
|
|
136
|
-
return telemetry.CAMMGPSPoint(
|
|
137
|
-
time=sample.exact_time,
|
|
138
|
-
lat=data.latitude,
|
|
139
|
-
lon=data.longitude,
|
|
140
|
-
alt=data.altitude,
|
|
141
|
-
angle=None,
|
|
142
|
-
time_gps_epoch=data.time_gps_epoch,
|
|
143
|
-
gps_fix_type=data.gps_fix_type,
|
|
144
|
-
horizontal_accuracy=data.horizontal_accuracy,
|
|
145
|
-
vertical_accuracy=data.vertical_accuracy,
|
|
146
|
-
velocity_east=data.velocity_east,
|
|
147
|
-
velocity_north=data.velocity_north,
|
|
148
|
-
velocity_up=data.velocity_up,
|
|
149
|
-
speed_accuracy=data.speed_accuracy,
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
@classmethod
|
|
153
|
-
def serialize(cls, data: telemetry.CAMMGPSPoint) -> bytes:
|
|
154
|
-
cls.serializable(data, throw=True)
|
|
155
|
-
|
|
156
|
-
return CAMMSampleData.build(
|
|
157
|
-
{
|
|
158
|
-
"type": cls.camm_type.value,
|
|
159
|
-
"data": {
|
|
160
|
-
"time_gps_epoch": data.time_gps_epoch,
|
|
161
|
-
"gps_fix_type": data.gps_fix_type,
|
|
162
|
-
"latitude": data.lat,
|
|
163
|
-
"longitude": data.lon,
|
|
164
|
-
"altitude": -1.0 if data.alt is None else data.alt,
|
|
165
|
-
"horizontal_accuracy": data.horizontal_accuracy,
|
|
166
|
-
"vertical_accuracy": data.vertical_accuracy,
|
|
167
|
-
"velocity_east": data.velocity_east,
|
|
168
|
-
"velocity_north": data.velocity_north,
|
|
169
|
-
"velocity_up": data.velocity_up,
|
|
170
|
-
"speed_accuracy": data.speed_accuracy,
|
|
171
|
-
},
|
|
172
|
-
}
|
|
173
|
-
)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
class GoProGPSSampleEntry(CAMMSampleEntry):
|
|
177
|
-
camm_type: CAMMType = CAMMType.MLY_GOPRO_GPS
|
|
178
|
-
|
|
179
|
-
construct = C.Struct(
|
|
180
|
-
"latitude" / Double, # type: ignore
|
|
181
|
-
"longitude" / Double, # type: ignore
|
|
182
|
-
"altitude" / Float, # type: ignore
|
|
183
|
-
"epoch_time" / Double, # type: ignore
|
|
184
|
-
"fix" / C.Int32sl, # type: ignore
|
|
185
|
-
"precision" / Float, # type: ignore
|
|
186
|
-
"ground_speed" / Float, # type: ignore
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
telemetry_cls = telemetry.GPSPoint
|
|
190
|
-
|
|
191
|
-
@classmethod
|
|
192
|
-
def deserialize(cls, sample: Sample, data: T.Any) -> telemetry.GPSPoint:
|
|
193
|
-
return telemetry.GPSPoint(
|
|
194
|
-
time=sample.exact_time,
|
|
195
|
-
lat=data.latitude,
|
|
196
|
-
lon=data.longitude,
|
|
197
|
-
alt=data.altitude,
|
|
198
|
-
angle=None,
|
|
199
|
-
epoch_time=data.epoch_time,
|
|
200
|
-
fix=telemetry.GPSFix(data.fix),
|
|
201
|
-
precision=data.precision,
|
|
202
|
-
ground_speed=data.ground_speed,
|
|
203
|
-
)
|
|
204
|
-
|
|
205
|
-
@classmethod
|
|
206
|
-
def serialize(cls, data: telemetry.GPSPoint) -> bytes:
|
|
207
|
-
cls.serializable(data, throw=True)
|
|
208
|
-
|
|
209
|
-
if data.fix is None:
|
|
210
|
-
gps_fix = telemetry.GPSFix.NO_FIX.value
|
|
211
|
-
else:
|
|
212
|
-
gps_fix = data.fix.value
|
|
213
|
-
|
|
214
|
-
return CAMMSampleData.build(
|
|
215
|
-
{
|
|
216
|
-
"type": cls.camm_type.value,
|
|
217
|
-
"data": {
|
|
218
|
-
"latitude": data.lat,
|
|
219
|
-
"longitude": data.lon,
|
|
220
|
-
"altitude": -1.0 if data.alt is None else data.alt,
|
|
221
|
-
"epoch_time": data.epoch_time,
|
|
222
|
-
"fix": gps_fix,
|
|
223
|
-
"precision": data.precision,
|
|
224
|
-
"ground_speed": data.ground_speed,
|
|
225
|
-
},
|
|
226
|
-
}
|
|
227
|
-
)
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
class AccelerationSampleEntry(CAMMSampleEntry):
|
|
231
|
-
camm_type: CAMMType = CAMMType.ACCELERATION
|
|
232
|
-
|
|
233
|
-
construct: C.Struct = Float[3] # type: ignore
|
|
234
|
-
|
|
235
|
-
telemetry_cls = telemetry.AccelerationData
|
|
236
|
-
|
|
237
|
-
@classmethod
|
|
238
|
-
def deserialize(cls, sample: Sample, data: T.Any) -> telemetry.AccelerationData:
|
|
239
|
-
return telemetry.AccelerationData(
|
|
240
|
-
time=sample.exact_time,
|
|
241
|
-
x=data[0],
|
|
242
|
-
y=data[1],
|
|
243
|
-
z=data[2],
|
|
244
|
-
)
|
|
245
|
-
|
|
246
|
-
@classmethod
|
|
247
|
-
def serialize(cls, data: telemetry.AccelerationData) -> bytes:
|
|
248
|
-
cls.serializable(data, throw=True)
|
|
249
|
-
|
|
250
|
-
return CAMMSampleData.build(
|
|
251
|
-
{
|
|
252
|
-
"type": cls.camm_type.value,
|
|
253
|
-
"data": [data.x, data.y, data.z],
|
|
254
|
-
}
|
|
255
|
-
)
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
class GyroscopeSampleEntry(CAMMSampleEntry):
|
|
259
|
-
camm_type: CAMMType = CAMMType.GYRO
|
|
260
|
-
|
|
261
|
-
construct: C.Struct = Float[3] # type: ignore
|
|
262
|
-
|
|
263
|
-
telemetry_cls = telemetry.GyroscopeData
|
|
264
|
-
|
|
265
|
-
@classmethod
|
|
266
|
-
def deserialize(cls, sample: Sample, data: T.Any) -> telemetry.GyroscopeData:
|
|
267
|
-
return telemetry.GyroscopeData(
|
|
268
|
-
time=sample.exact_time,
|
|
269
|
-
x=data[0],
|
|
270
|
-
y=data[1],
|
|
271
|
-
z=data[2],
|
|
272
|
-
)
|
|
273
|
-
|
|
274
|
-
@classmethod
|
|
275
|
-
def serialize(cls, data: telemetry.GyroscopeData) -> bytes:
|
|
276
|
-
cls.serializable(data)
|
|
277
|
-
|
|
278
|
-
return CAMMSampleData.build(
|
|
279
|
-
{
|
|
280
|
-
"type": cls.camm_type.value,
|
|
281
|
-
"data": [data.x, data.y, data.z],
|
|
282
|
-
}
|
|
283
|
-
)
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
class MagnetometerSampleEntry(CAMMSampleEntry):
|
|
287
|
-
camm_type: CAMMType = CAMMType.MAGNETIC_FIELD
|
|
288
|
-
|
|
289
|
-
construct: C.Struct = Float[3] # type: ignore
|
|
290
|
-
|
|
291
|
-
telemetry_cls = telemetry.MagnetometerData
|
|
292
|
-
|
|
293
|
-
@classmethod
|
|
294
|
-
def deserialize(cls, sample: Sample, data: T.Any) -> telemetry.MagnetometerData:
|
|
295
|
-
return telemetry.MagnetometerData(
|
|
296
|
-
time=sample.exact_time,
|
|
297
|
-
x=data[0],
|
|
298
|
-
y=data[1],
|
|
299
|
-
z=data[2],
|
|
300
|
-
)
|
|
301
|
-
|
|
302
|
-
@classmethod
|
|
303
|
-
def serialize(cls, data: telemetry.MagnetometerData) -> bytes:
|
|
304
|
-
cls.serializable(data)
|
|
305
|
-
|
|
306
|
-
return CAMMSampleData.build(
|
|
307
|
-
{
|
|
308
|
-
"type": cls.camm_type.value,
|
|
309
|
-
"data": [data.x, data.y, data.z],
|
|
310
|
-
}
|
|
311
|
-
)
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
SAMPLE_ENTRY_CLS_BY_CAMM_TYPE = {
|
|
315
|
-
sample_entry_cls.camm_type: sample_entry_cls
|
|
316
|
-
for sample_entry_cls in CAMMSampleEntry.__subclasses__()
|
|
317
|
-
}
|
|
318
|
-
assert len(SAMPLE_ENTRY_CLS_BY_CAMM_TYPE) == 6, SAMPLE_ENTRY_CLS_BY_CAMM_TYPE.keys()
|
|
319
|
-
|
|
320
|
-
|
|
321
44
|
_SWITCH: T.Dict[int, C.Struct] = {
|
|
322
45
|
# angle_axis
|
|
323
|
-
CAMMType.ANGLE_AXIS.value: Float[3],
|
|
46
|
+
CAMMType.ANGLE_AXIS.value: Float[3],
|
|
324
47
|
CAMMType.EXPOSURE_TIME.value: C.Struct(
|
|
325
|
-
"pixel_exposure_time" / C.Int32sl,
|
|
326
|
-
"rolling_shutter_skew_time" / C.Int32sl,
|
|
48
|
+
"pixel_exposure_time" / C.Int32sl,
|
|
49
|
+
"rolling_shutter_skew_time" / C.Int32sl,
|
|
327
50
|
),
|
|
51
|
+
# gyro
|
|
52
|
+
CAMMType.GYRO.value: Float[3],
|
|
53
|
+
# acceleration
|
|
54
|
+
CAMMType.ACCELERATION.value: Float[3],
|
|
328
55
|
# position
|
|
329
|
-
CAMMType.POSITION.value: Float[3],
|
|
330
|
-
|
|
56
|
+
CAMMType.POSITION.value: Float[3],
|
|
57
|
+
# lat, lon, alt
|
|
58
|
+
CAMMType.MIN_GPS.value: Double[3],
|
|
59
|
+
CAMMType.GPS.value: C.Struct(
|
|
60
|
+
"time_gps_epoch" / Double,
|
|
61
|
+
"gps_fix_type" / C.Int32sl,
|
|
62
|
+
"latitude" / Double,
|
|
63
|
+
"longitude" / Double,
|
|
64
|
+
"altitude" / Float,
|
|
65
|
+
"horizontal_accuracy" / Float,
|
|
66
|
+
"vertical_accuracy" / Float,
|
|
67
|
+
"velocity_east" / Float,
|
|
68
|
+
"velocity_north" / Float,
|
|
69
|
+
"velocity_up" / Float,
|
|
70
|
+
"speed_accuracy" / Float,
|
|
71
|
+
),
|
|
72
|
+
# magnetic_field
|
|
73
|
+
CAMMType.MAGNETIC_FIELD.value: Float[3],
|
|
331
74
|
}
|
|
332
75
|
|
|
333
76
|
CAMMSampleData = C.Struct(
|
|
334
77
|
C.Padding(2),
|
|
335
78
|
"type" / C.Int16ul,
|
|
336
|
-
"data"
|
|
79
|
+
"data"
|
|
80
|
+
/ C.Switch(
|
|
81
|
+
C.this.type,
|
|
82
|
+
_SWITCH,
|
|
83
|
+
),
|
|
337
84
|
)
|
|
338
85
|
|
|
339
86
|
|
|
@@ -343,12 +90,46 @@ def _parse_telemetry_from_sample(
|
|
|
343
90
|
fp.seek(sample.raw_sample.offset, io.SEEK_SET)
|
|
344
91
|
data = fp.read(sample.raw_sample.size)
|
|
345
92
|
box = CAMMSampleData.parse(data)
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
93
|
+
if box.type == CAMMType.MIN_GPS.value:
|
|
94
|
+
return geo.Point(
|
|
95
|
+
time=sample.exact_time,
|
|
96
|
+
lat=box.data[0],
|
|
97
|
+
lon=box.data[1],
|
|
98
|
+
alt=box.data[2],
|
|
99
|
+
angle=None,
|
|
100
|
+
)
|
|
101
|
+
elif box.type == CAMMType.GPS.value:
|
|
102
|
+
# Not using box.data.time_gps_epoch as the point timestamp
|
|
103
|
+
# because it is from another clock
|
|
104
|
+
return geo.Point(
|
|
105
|
+
time=sample.exact_time,
|
|
106
|
+
lat=box.data.latitude,
|
|
107
|
+
lon=box.data.longitude,
|
|
108
|
+
alt=box.data.altitude,
|
|
109
|
+
angle=None,
|
|
110
|
+
)
|
|
111
|
+
elif box.type == CAMMType.ACCELERATION.value:
|
|
112
|
+
return telemetry.AccelerationData(
|
|
113
|
+
time=sample.exact_time,
|
|
114
|
+
x=box.data[0],
|
|
115
|
+
y=box.data[1],
|
|
116
|
+
z=box.data[2],
|
|
117
|
+
)
|
|
118
|
+
elif box.type == CAMMType.GYRO.value:
|
|
119
|
+
return telemetry.GyroscopeData(
|
|
120
|
+
time=sample.exact_time,
|
|
121
|
+
x=box.data[0],
|
|
122
|
+
y=box.data[1],
|
|
123
|
+
z=box.data[2],
|
|
124
|
+
)
|
|
125
|
+
elif box.type == CAMMType.MAGNETIC_FIELD.value:
|
|
126
|
+
return telemetry.MagnetometerData(
|
|
127
|
+
time=sample.exact_time,
|
|
128
|
+
x=box.data[0],
|
|
129
|
+
y=box.data[1],
|
|
130
|
+
z=box.data[2],
|
|
131
|
+
)
|
|
132
|
+
return None
|
|
352
133
|
|
|
353
134
|
|
|
354
135
|
def _filter_telemetry_by_elst_segments(
|
mapillary_tools/telemetry.py
CHANGED
|
@@ -12,6 +12,14 @@ class GPSFix(Enum):
|
|
|
12
12
|
FIX_3D = 3
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
@dataclasses.dataclass
|
|
16
|
+
class GPSPoint(Point):
|
|
17
|
+
epoch_time: T.Optional[float]
|
|
18
|
+
fix: T.Optional[GPSFix]
|
|
19
|
+
precision: T.Optional[float]
|
|
20
|
+
ground_speed: T.Optional[float]
|
|
21
|
+
|
|
22
|
+
|
|
15
23
|
@dataclasses.dataclass(order=True)
|
|
16
24
|
class TelemetryMeasurement:
|
|
17
25
|
"""Base class for all telemetry measurements.
|
|
@@ -24,26 +32,6 @@ class TelemetryMeasurement:
|
|
|
24
32
|
time: float
|
|
25
33
|
|
|
26
34
|
|
|
27
|
-
@dataclasses.dataclass
|
|
28
|
-
class GPSPoint(TelemetryMeasurement, Point):
|
|
29
|
-
epoch_time: T.Optional[float]
|
|
30
|
-
fix: T.Optional[GPSFix]
|
|
31
|
-
precision: T.Optional[float]
|
|
32
|
-
ground_speed: T.Optional[float]
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@dataclasses.dataclass
|
|
36
|
-
class CAMMGPSPoint(TelemetryMeasurement, Point):
|
|
37
|
-
time_gps_epoch: float
|
|
38
|
-
gps_fix_type: int
|
|
39
|
-
horizontal_accuracy: float
|
|
40
|
-
vertical_accuracy: float
|
|
41
|
-
velocity_east: float
|
|
42
|
-
velocity_north: float
|
|
43
|
-
velocity_up: float
|
|
44
|
-
speed_accuracy: float
|
|
45
|
-
|
|
46
|
-
|
|
47
35
|
@dataclasses.dataclass(order=True)
|
|
48
36
|
class GyroscopeData(TelemetryMeasurement):
|
|
49
37
|
"""Gyroscope signal in radians/seconds around XYZ axes of the camera."""
|
mapillary_tools/upload.py
CHANGED
|
@@ -18,13 +18,14 @@ from . import (
|
|
|
18
18
|
exceptions,
|
|
19
19
|
history,
|
|
20
20
|
ipc,
|
|
21
|
+
telemetry,
|
|
21
22
|
types,
|
|
22
23
|
upload_api_v4,
|
|
23
24
|
uploader,
|
|
24
25
|
utils,
|
|
25
26
|
VERSION,
|
|
26
27
|
)
|
|
27
|
-
from .camm import camm_builder
|
|
28
|
+
from .camm import camm_builder
|
|
28
29
|
from .geotag import gpmf_parser
|
|
29
30
|
from .mp4 import simple_mp4_builder
|
|
30
31
|
from .types import FileType
|
|
@@ -615,7 +616,7 @@ def upload(
|
|
|
615
616
|
assert isinstance(video_metadata.md5sum, str), "md5sum should be updated"
|
|
616
617
|
|
|
617
618
|
# extract telemetry measurements from GoPro videos
|
|
618
|
-
telemetry_measurements: T.List[
|
|
619
|
+
telemetry_measurements: T.List[telemetry.TelemetryMeasurement] = []
|
|
619
620
|
if MAPILLARY__EXPERIMENTAL_ENABLE_IMU == "YES":
|
|
620
621
|
if video_metadata.filetype is FileType.GOPRO:
|
|
621
622
|
with video_metadata.filename.open("rb") as fp:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
mapillary_tools/__init__.py,sha256=
|
|
1
|
+
mapillary_tools/__init__.py,sha256=0qmTgs4HlmMGWxh_Upl_6EAbqBbUzX-Mw8rXWm5EO-U,19
|
|
2
2
|
mapillary_tools/api_v4.py,sha256=zhRtgx3EnzgqtjziRhvFq3ONvsPaB9hROsuKFcf_pFo,5197
|
|
3
3
|
mapillary_tools/authenticate.py,sha256=LCFcs6LqZmXaYkTUEKgGfmqytWdh5v_L3KXB48ojOZ4,3090
|
|
4
4
|
mapillary_tools/config.py,sha256=jCjaK4jJaTY4AV4qf_b_tcxn5LA_uPsEWlGIdm2zw6g,2103
|
|
@@ -15,14 +15,14 @@ mapillary_tools/ipc.py,sha256=DwWQb9hNshx0bg0Fo5NjY0mXjs-FkbR6tIQmjMgMtmg,1089
|
|
|
15
15
|
mapillary_tools/process_geotag_properties.py,sha256=w4hhv_c4sRydCK9QCO50sT2yo2zeVlY7dSdXQ93InFc,23159
|
|
16
16
|
mapillary_tools/process_sequence_properties.py,sha256=5oYEjz9crnLVQtCkxbwn57TkeuHFbBh_zQXQSA4ENWg,11561
|
|
17
17
|
mapillary_tools/sample_video.py,sha256=dpdX7bUNEmcrz-3gh3Y3awnTDX66pChbTKuF8qGfeCI,14400
|
|
18
|
-
mapillary_tools/telemetry.py,sha256=
|
|
18
|
+
mapillary_tools/telemetry.py,sha256=WpBGPF_GMPjM_EFqXIutFtpDFL9wj7yEzGNGnfQZUo8,1255
|
|
19
19
|
mapillary_tools/types.py,sha256=6kww2UdKM6YzabYbc862BYzEWtxL2hhxCRFfeDiUtF0,22074
|
|
20
|
-
mapillary_tools/upload.py,sha256=
|
|
20
|
+
mapillary_tools/upload.py,sha256=8dQ3ZWsjau1_xZN3ssjGGkBnLKbKIhjC91-zWstYlD8,24439
|
|
21
21
|
mapillary_tools/upload_api_v4.py,sha256=1WvoUis92KDXbqfoyvyyDmiCqwXezYkMJZhnYaVm3BA,8560
|
|
22
22
|
mapillary_tools/uploader.py,sha256=VieDKi51wdXTIhN7x_mcuQeHESUyFlF5cgB-TAnF4g0,14093
|
|
23
23
|
mapillary_tools/utils.py,sha256=VNtK1tAb3Hh8y3P5e5Y3iewREkIoLDa3C2myRYcF2lY,5970
|
|
24
|
-
mapillary_tools/camm/camm_builder.py,sha256=
|
|
25
|
-
mapillary_tools/camm/camm_parser.py,sha256=
|
|
24
|
+
mapillary_tools/camm/camm_builder.py,sha256=TXZfhu3xGjtrLEWnB14D7aSOrHOoSJef24YSLApiIfY,10631
|
|
25
|
+
mapillary_tools/camm/camm_parser.py,sha256=RaCWeLvS_AyHD6B6wDUu9DAsdfByVHMAPTqEqjtFibE,9734
|
|
26
26
|
mapillary_tools/commands/__init__.py,sha256=41CFrPLGlG3566uhxssEF3TGAtSpADFPPcDMHbViU0E,171
|
|
27
27
|
mapillary_tools/commands/__main__.py,sha256=VdWkx1ekPH-88Ybe78IcO9FWpZ5cUhsbGRw7LuzQObU,4832
|
|
28
28
|
mapillary_tools/commands/authenticate.py,sha256=4aVvAQal_mqtm2NEMBt5aKLahi0iRdO8b7WSBf6jokA,1136
|
|
@@ -67,9 +67,9 @@ mapillary_tools/video_data_extraction/extractors/generic_video_parser.py,sha256=
|
|
|
67
67
|
mapillary_tools/video_data_extraction/extractors/gopro_parser.py,sha256=IVnTyquSraTUaG9rxbJfVWc1-drdY5PaHn5urh3IBk4,1325
|
|
68
68
|
mapillary_tools/video_data_extraction/extractors/gpx_parser.py,sha256=FNrdnXl48k8I1I5fGwYsClhfFEHVsooRLRboUYECv3I,3811
|
|
69
69
|
mapillary_tools/video_data_extraction/extractors/nmea_parser.py,sha256=raSXavBvP-0LJCB_TwLL0mOv2uHSsB744igTsaKAaGc,658
|
|
70
|
-
mapillary_tools-0.13.
|
|
71
|
-
mapillary_tools-0.13.
|
|
72
|
-
mapillary_tools-0.13.
|
|
73
|
-
mapillary_tools-0.13.
|
|
74
|
-
mapillary_tools-0.13.
|
|
75
|
-
mapillary_tools-0.13.
|
|
70
|
+
mapillary_tools-0.13.2.dist-info/LICENSE,sha256=l2D8cKfFmmJq_wcVq_JElPJrlvWQOzNWx7gMLINucxc,1292
|
|
71
|
+
mapillary_tools-0.13.2.dist-info/METADATA,sha256=2tmLjwx7V2QhrErmOK9uL1McwGYAaHqXDw-wTIS1N3w,19758
|
|
72
|
+
mapillary_tools-0.13.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
73
|
+
mapillary_tools-0.13.2.dist-info/entry_points.txt,sha256=A3f3LP-BO_P-U8Y29QfpT4jx6Mjk3sXjTi2Yew4bvj8,75
|
|
74
|
+
mapillary_tools-0.13.2.dist-info/top_level.txt,sha256=FbDkMgOrt1S70ho1WSBrOwzKOSkJFDwwqFOoY5-527s,16
|
|
75
|
+
mapillary_tools-0.13.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|