mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-10-31 19:13:47 +08:00
dragonpilot beta3
date: 2023-07-26T22:20:36 commit: c6d842c412052be1985b63d683c63be9dcb2b0eb
This commit is contained in:
Binary file not shown.
@@ -43,10 +43,10 @@ def yuv_to_rgb(y, u, v):
|
||||
return rgb.astype(np.uint8)
|
||||
|
||||
|
||||
def extract_image(buf, w, h, stride, uv_offset):
|
||||
y = np.array(buf[:uv_offset], dtype=np.uint8).reshape((-1, stride))[:h, :w]
|
||||
u = np.array(buf[uv_offset::2], dtype=np.uint8).reshape((-1, stride//2))[:h//2, :w//2]
|
||||
v = np.array(buf[uv_offset+1::2], dtype=np.uint8).reshape((-1, stride//2))[:h//2, :w//2]
|
||||
def extract_image(buf):
|
||||
y = np.array(buf.data[:buf.uv_offset], dtype=np.uint8).reshape((-1, buf.stride))[:buf.height, :buf.width]
|
||||
u = np.array(buf.data[buf.uv_offset::2], dtype=np.uint8).reshape((-1, buf.stride//2))[:buf.height//2, :buf.width//2]
|
||||
v = np.array(buf.data[buf.uv_offset+1::2], dtype=np.uint8).reshape((-1, buf.stride//2))[:buf.height//2, :buf.width//2]
|
||||
|
||||
return yuv_to_rgb(y, u, v)
|
||||
|
||||
@@ -67,10 +67,10 @@ def get_snapshots(frame="roadCameraState", front_frame="driverCameraState"):
|
||||
rear, front = None, None
|
||||
if frame is not None:
|
||||
c = vipc_clients[frame]
|
||||
rear = extract_image(c.recv(), c.width, c.height, c.stride, c.uv_offset)
|
||||
rear = extract_image(c.recv())
|
||||
if front_frame is not None:
|
||||
c = vipc_clients[front_frame]
|
||||
front = extract_image(c.recv(), c.width, c.height, c.stride, c.uv_offset)
|
||||
front = extract_image(c.recv())
|
||||
return rear, front
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
@@ -1,19 +1,19 @@
|
||||
[
|
||||
{
|
||||
"name": "boot",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/boot-7d953f5e1bc606984e4d49c6f957421a4172f72b4ebd359baa689ef43b7e911c.img.xz",
|
||||
"hash": "7d953f5e1bc606984e4d49c6f957421a4172f72b4ebd359baa689ef43b7e911c",
|
||||
"hash_raw": "7d953f5e1bc606984e4d49c6f957421a4172f72b4ebd359baa689ef43b7e911c",
|
||||
"size": 15153152,
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/boot-8d8d8620de8b2687f3a8fffdb81b2abd1fe2ead5bc831361a1a212e5589ac279.img.xz",
|
||||
"hash": "8d8d8620de8b2687f3a8fffdb81b2abd1fe2ead5bc831361a1a212e5589ac279",
|
||||
"hash_raw": "8d8d8620de8b2687f3a8fffdb81b2abd1fe2ead5bc831361a1a212e5589ac279",
|
||||
"size": 15636480,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true
|
||||
},
|
||||
{
|
||||
"name": "abl",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/abl-50329ac734ff7a6c20c3f552dce9b13f84b3eb2e73faa64b9810049d9b406602.img.xz",
|
||||
"hash": "50329ac734ff7a6c20c3f552dce9b13f84b3eb2e73faa64b9810049d9b406602",
|
||||
"hash_raw": "50329ac734ff7a6c20c3f552dce9b13f84b3eb2e73faa64b9810049d9b406602",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/abl-0084fcf79fea067632a1c2d9519b6445ad484aa8b09f49f22e6b45b4dccacd2d.img.xz",
|
||||
"hash": "0084fcf79fea067632a1c2d9519b6445ad484aa8b09f49f22e6b45b4dccacd2d",
|
||||
"hash_raw": "0084fcf79fea067632a1c2d9519b6445ad484aa8b09f49f22e6b45b4dccacd2d",
|
||||
"size": 274432,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
@@ -21,9 +21,9 @@
|
||||
},
|
||||
{
|
||||
"name": "xbl",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/xbl-dc297986b38f50c47584bd8549b188b37b1d6a0c77b3255859dd675c177b5c15.img.xz",
|
||||
"hash": "dc297986b38f50c47584bd8549b188b37b1d6a0c77b3255859dd675c177b5c15",
|
||||
"hash_raw": "dc297986b38f50c47584bd8549b188b37b1d6a0c77b3255859dd675c177b5c15",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/xbl-942b9b2914d89c2a70fdf27380b59e04b549ac2fd53ecb29d6549d1a9c8daeaa.img.xz",
|
||||
"hash": "942b9b2914d89c2a70fdf27380b59e04b549ac2fd53ecb29d6549d1a9c8daeaa",
|
||||
"hash_raw": "942b9b2914d89c2a70fdf27380b59e04b549ac2fd53ecb29d6549d1a9c8daeaa",
|
||||
"size": 3282672,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
@@ -31,9 +31,9 @@
|
||||
},
|
||||
{
|
||||
"name": "xbl_config",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/xbl_config-b73fbbb42934aabc6d4f16ce84ac6c8c0205bc70e0a85412a771f3cc1d62cc40.img.xz",
|
||||
"hash": "b73fbbb42934aabc6d4f16ce84ac6c8c0205bc70e0a85412a771f3cc1d62cc40",
|
||||
"hash_raw": "b73fbbb42934aabc6d4f16ce84ac6c8c0205bc70e0a85412a771f3cc1d62cc40",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/xbl_config-6881d94599f65d94c13bcc0bd860184dfba2dfe96ec776d08fb35ac5b5f85bbf.img.xz",
|
||||
"hash": "6881d94599f65d94c13bcc0bd860184dfba2dfe96ec776d08fb35ac5b5f85bbf",
|
||||
"hash_raw": "6881d94599f65d94c13bcc0bd860184dfba2dfe96ec776d08fb35ac5b5f85bbf",
|
||||
"size": 98124,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
@@ -41,9 +41,9 @@
|
||||
},
|
||||
{
|
||||
"name": "devcfg",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/devcfg-2d3063d106813006ac9ceeaf8818a31d4b33996873e81178ac5129f5e1b82bca.img.xz",
|
||||
"hash": "2d3063d106813006ac9ceeaf8818a31d4b33996873e81178ac5129f5e1b82bca",
|
||||
"hash_raw": "2d3063d106813006ac9ceeaf8818a31d4b33996873e81178ac5129f5e1b82bca",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/devcfg-9bbf168baff6101f4890c5c95c118e30813c2610cfb35b8e19e363f04a32a262.img.xz",
|
||||
"hash": "9bbf168baff6101f4890c5c95c118e30813c2610cfb35b8e19e363f04a32a262",
|
||||
"hash_raw": "9bbf168baff6101f4890c5c95c118e30813c2610cfb35b8e19e363f04a32a262",
|
||||
"size": 40336,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
@@ -51,9 +51,9 @@
|
||||
},
|
||||
{
|
||||
"name": "aop",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/aop-d69450d5438b3e5e2ba5b77db1ae49e1cf9cab17836f563aa57192b5b3a4ac3e.img.xz",
|
||||
"hash": "d69450d5438b3e5e2ba5b77db1ae49e1cf9cab17836f563aa57192b5b3a4ac3e",
|
||||
"hash_raw": "d69450d5438b3e5e2ba5b77db1ae49e1cf9cab17836f563aa57192b5b3a4ac3e",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/aop-c1d9d712980f6b2a4b12196597f4d1bf3fe4fec6c59edf29ae63ef21f11b8222.img.xz",
|
||||
"hash": "c1d9d712980f6b2a4b12196597f4d1bf3fe4fec6c59edf29ae63ef21f11b8222",
|
||||
"hash_raw": "c1d9d712980f6b2a4b12196597f4d1bf3fe4fec6c59edf29ae63ef21f11b8222",
|
||||
"size": 184364,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
@@ -61,9 +61,9 @@
|
||||
},
|
||||
{
|
||||
"name": "system",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/system-4a8311dd591006e0c2a6f60060d6ef579ceec9b3d688e8438a9aef4e230ae028.img.xz",
|
||||
"hash": "23c9f111f81fc3ee83f85016cb320e03a46aad6721a85e1b4a3f04b6a764e934",
|
||||
"hash_raw": "4a8311dd591006e0c2a6f60060d6ef579ceec9b3d688e8438a9aef4e230ae028",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/system-e1fa3018bce9bad01c6967e5e21f1141cf5c8f02d2edfaed51c738f74a32a432.img.xz",
|
||||
"hash": "611011f3e3f147bc24f371105a9dd3760ec11ba424c56d4a442a66b098c784c0",
|
||||
"hash_raw": "e1fa3018bce9bad01c6967e5e21f1141cf5c8f02d2edfaed51c738f74a32a432",
|
||||
"size": 10737418240,
|
||||
"sparse": true,
|
||||
"full_check": false,
|
||||
|
||||
@@ -8,7 +8,7 @@ from functools import cached_property, lru_cache
|
||||
from pathlib import Path
|
||||
|
||||
from cereal import log
|
||||
from common.gpio import gpio_set, gpio_init, get_irq_for_action
|
||||
from common.gpio import gpio_set, gpio_init, get_irqs_for_action
|
||||
from system.hardware.base import HardwareBase, ThermalConfig
|
||||
from system.hardware.tici import iwlist
|
||||
from system.hardware.tici.pins import GPIO
|
||||
@@ -61,17 +61,27 @@ MM_MODEM_ACCESS_TECHNOLOGY_LTE = 1 << 14
|
||||
|
||||
|
||||
def sudo_write(val, path):
|
||||
os.system(f"sudo su -c 'echo {val} > {path}'")
|
||||
try:
|
||||
with open(path, 'w') as f:
|
||||
f.write(str(val))
|
||||
except PermissionError:
|
||||
os.system(f"sudo chmod a+w {path}")
|
||||
try:
|
||||
with open(path, 'w') as f:
|
||||
f.write(str(val))
|
||||
except PermissionError:
|
||||
# fallback for debugfs files
|
||||
os.system(f"sudo su -c 'echo {val} > {path}'")
|
||||
|
||||
|
||||
def affine_irq(val, action):
|
||||
irq = get_irq_for_action(action)
|
||||
if len(irq) == 0:
|
||||
irqs = get_irqs_for_action(action)
|
||||
if len(irqs) == 0:
|
||||
print(f"No IRQs found for '{action}'")
|
||||
return
|
||||
for i in irq:
|
||||
sudo_write(str(val), f"/proc/irq/{i}/smp_affinity_list")
|
||||
|
||||
for i in irqs:
|
||||
sudo_write(str(val), f"/proc/irq/{i}/smp_affinity_list")
|
||||
|
||||
class Tici(HardwareBase):
|
||||
@cached_property
|
||||
@@ -438,17 +448,17 @@ class Tici(HardwareBase):
|
||||
|
||||
# *** IRQ config ***
|
||||
|
||||
# GPU
|
||||
affine_irq(5, "kgsl-3d0")
|
||||
|
||||
# boardd core
|
||||
affine_irq(4, "spi_geni") # SPI
|
||||
affine_irq(4, "xhci-hcd:usb3") # aux panda USB (or potentially anything else on USB)
|
||||
if "tici" in self.get_device_type():
|
||||
affine_irq(4, "xhci-hcd:usb1") # internal panda USB
|
||||
affine_irq(4, "xhci-hcd:usb1") # internal panda USB (also modem)
|
||||
|
||||
# GPU
|
||||
affine_irq(5, "kgsl-3d0")
|
||||
|
||||
# camerad core
|
||||
camera_irqs = ("cci", "cpas_camnoc", "cpas-cdm", "csid", "ife", "csid", "csid-lite", "ife-lite")
|
||||
camera_irqs = ("cci", "cpas_camnoc", "cpas-cdm", "csid", "ife", "csid-lite", "ife-lite")
|
||||
for n in camera_irqs:
|
||||
affine_irq(5, n)
|
||||
|
||||
@@ -472,14 +482,14 @@ class Tici(HardwareBase):
|
||||
|
||||
# *** IRQ config ***
|
||||
|
||||
# move these off the default core
|
||||
affine_irq(1, "msm_drm")
|
||||
affine_irq(1, "msm_vidc")
|
||||
affine_irq(1, "i2c_geni")
|
||||
|
||||
# mask off big cluster from default affinity
|
||||
sudo_write("f", "/proc/irq/default_smp_affinity")
|
||||
|
||||
# move these off the default core
|
||||
affine_irq(1, "msm_drm") # display
|
||||
affine_irq(1, "msm_vidc") # encoders
|
||||
affine_irq(1, "i2c_geni") # sensors
|
||||
|
||||
# *** GPU config ***
|
||||
# https://github.com/commaai/agnos-kernel-sdm845/blob/master/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi#L216
|
||||
sudo_write("1", "/sys/class/kgsl/kgsl-3d0/min_pwrlevel")
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -5,7 +5,7 @@ from system.hardware import PC
|
||||
if os.environ.get('LOG_ROOT', False):
|
||||
ROOT = os.environ['LOG_ROOT']
|
||||
elif PC:
|
||||
ROOT = os.path.join(str(Path.home()), ".comma", "media", "0", "realdata")
|
||||
ROOT = str(Path.home() / ".comma" / "media" / "0" / "realdata")
|
||||
else:
|
||||
ROOT = '/data/media/0/realdata/'
|
||||
|
||||
@@ -16,7 +16,7 @@ SEGMENT_LENGTH = 60
|
||||
STATS_DIR_FILE_LIMIT = 10000
|
||||
STATS_SOCKET = "ipc:///tmp/stats"
|
||||
if PC:
|
||||
STATS_DIR = os.path.join(str(Path.home()), ".comma", "stats")
|
||||
STATS_DIR = str(Path.home() / ".comma" / "stats")
|
||||
else:
|
||||
STATS_DIR = "/data/stats/"
|
||||
STATS_FLUSH_TIME_S = 60
|
||||
|
||||
@@ -2,15 +2,48 @@
|
||||
import os
|
||||
import shutil
|
||||
import threading
|
||||
from typing import List
|
||||
|
||||
from system.swaglog import cloudlog
|
||||
from system.loggerd.config import ROOT, get_available_bytes, get_available_percent
|
||||
from system.loggerd.uploader import listdir_by_creation
|
||||
from system.loggerd.xattr_cache import getxattr
|
||||
|
||||
MIN_BYTES = 5 * 1024 * 1024 * 1024
|
||||
MIN_PERCENT = 10
|
||||
|
||||
DELETE_LAST = ['boot', 'crash']
|
||||
|
||||
PRESERVE_ATTR_NAME = 'user.preserve'
|
||||
PRESERVE_ATTR_VALUE = b'1'
|
||||
PRESERVE_COUNT = 5
|
||||
|
||||
|
||||
def has_preserve_xattr(d: str) -> bool:
|
||||
return getxattr(os.path.join(ROOT, d), PRESERVE_ATTR_NAME) == PRESERVE_ATTR_VALUE
|
||||
|
||||
|
||||
def get_preserved_segments(dirs_by_creation: List[str]) -> List[str]:
|
||||
preserved = []
|
||||
for n, d in enumerate(filter(has_preserve_xattr, reversed(dirs_by_creation))):
|
||||
if n == PRESERVE_COUNT:
|
||||
break
|
||||
date_str, _, seg_str = d.rpartition("--")
|
||||
|
||||
# ignore non-segment directories
|
||||
if not date_str:
|
||||
continue
|
||||
try:
|
||||
seg_num = int(seg_str)
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
# preserve segment and its prior
|
||||
preserved.append(d)
|
||||
preserved.append(f"{date_str}--{seg_num - 1}")
|
||||
|
||||
return preserved
|
||||
|
||||
|
||||
def deleter_thread(exit_event):
|
||||
while not exit_event.is_set():
|
||||
@@ -18,9 +51,13 @@ def deleter_thread(exit_event):
|
||||
out_of_percent = get_available_percent(default=MIN_PERCENT + 1) < MIN_PERCENT
|
||||
|
||||
if out_of_percent or out_of_bytes:
|
||||
dirs = listdir_by_creation(ROOT)
|
||||
|
||||
# skip deleting most recent N preserved segments (and their prior segment)
|
||||
preserved_dirs = get_preserved_segments(dirs)
|
||||
|
||||
# remove the earliest directory we can
|
||||
dirs = sorted(listdir_by_creation(ROOT), key=lambda x: x in DELETE_LAST)
|
||||
for delete_dir in dirs:
|
||||
for delete_dir in sorted(dirs, key=lambda d: (d in DELETE_LAST, d in preserved_dirs)):
|
||||
delete_path = os.path.join(ROOT, delete_dir)
|
||||
|
||||
if any(name.endswith(".lock") for name in os.listdir(delete_path)):
|
||||
|
||||
@@ -8,40 +8,27 @@
|
||||
#include "cereal/visionipc/visionipc.h"
|
||||
#include "common/queue.h"
|
||||
#include "system/camerad/cameras/camera_common.h"
|
||||
#include "system/loggerd/loggerd.h"
|
||||
|
||||
#define V4L2_BUF_FLAG_KEYFRAME 8
|
||||
|
||||
class VideoEncoder {
|
||||
public:
|
||||
VideoEncoder(const char* filename, CameraType type, int in_width, int in_height, int fps,
|
||||
int bitrate, cereal::EncodeIndex::Type codec, int out_width, int out_height,
|
||||
const char* publish_name)
|
||||
: filename(filename), type(type), in_width(in_width), in_height(in_height), fps(fps),
|
||||
bitrate(bitrate), codec(codec), out_width(out_width), out_height(out_height),
|
||||
publish_name(publish_name) { }
|
||||
virtual ~VideoEncoder();
|
||||
VideoEncoder(const EncoderInfo &encoder_info, int in_width, int in_height);
|
||||
virtual ~VideoEncoder() {};
|
||||
virtual int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra) = 0;
|
||||
virtual void encoder_open(const char* path) = 0;
|
||||
virtual void encoder_close() = 0;
|
||||
|
||||
void publisher_init();
|
||||
static void publisher_publish(VideoEncoder *e, int segment_num, uint32_t idx, VisionIpcBufExtra &extra, unsigned int flags, kj::ArrayPtr<capnp::byte> header, kj::ArrayPtr<capnp::byte> dat);
|
||||
|
||||
|
||||
protected:
|
||||
const char* filename;
|
||||
const char* publish_name;
|
||||
int in_width, in_height;
|
||||
int out_width, out_height, fps;
|
||||
int bitrate;
|
||||
cereal::EncodeIndex::Type codec;
|
||||
CameraType type;
|
||||
const EncoderInfo encoder_info;
|
||||
|
||||
private:
|
||||
// total frames encoded
|
||||
int cnt = 0;
|
||||
|
||||
// publishing
|
||||
std::unique_ptr<PubMaster> pm;
|
||||
const char *service_name;
|
||||
};
|
||||
|
||||
@@ -15,14 +15,9 @@ extern "C" {
|
||||
#include "system/loggerd/loggerd.h"
|
||||
|
||||
class FfmpegEncoder : public VideoEncoder {
|
||||
public:
|
||||
FfmpegEncoder(const char* filename, CameraType type, int in_width, int in_height, int fps,
|
||||
|
||||
int bitrate, cereal::EncodeIndex::Type codec, int out_width, int out_height,
|
||||
const char* publish_name) :
|
||||
VideoEncoder(filename, type, in_width, in_height, fps, bitrate, cereal::EncodeIndex::Type::BIG_BOX_LOSSLESS, out_width, out_height, publish_name) { encoder_init(); }
|
||||
public:
|
||||
FfmpegEncoder(const EncoderInfo &encoder_info, int in_width, int in_height);
|
||||
~FfmpegEncoder();
|
||||
void encoder_init();
|
||||
int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra);
|
||||
void encoder_open(const char* path);
|
||||
void encoder_close();
|
||||
|
||||
@@ -8,11 +8,8 @@
|
||||
|
||||
class V4LEncoder : public VideoEncoder {
|
||||
public:
|
||||
V4LEncoder(const char* filename, CameraType type, int in_width, int in_height, int fps,
|
||||
int bitrate, cereal::EncodeIndex::Type codec, int out_width, int out_height, const char* publish_name) :
|
||||
VideoEncoder(filename, type, in_width, in_height, fps, bitrate, codec, out_width, out_height, publish_name) { encoder_init(); }
|
||||
V4LEncoder(const EncoderInfo &encoder_info, int in_width, int in_height);
|
||||
~V4LEncoder();
|
||||
void encoder_init();
|
||||
int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra);
|
||||
void encoder_open(const char* path);
|
||||
void encoder_close();
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+34
-51
@@ -1,46 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <cerrno>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
#include "cereal/messaging/messaging.h"
|
||||
#include "cereal/services.h"
|
||||
#include "cereal/visionipc/visionipc.h"
|
||||
#include "cereal/visionipc/visionipc_client.h"
|
||||
#include "system/camerad/cameras/camera_common.h"
|
||||
#include "system/hardware/hw.h"
|
||||
#include "common/params.h"
|
||||
#include "common/swaglog.h"
|
||||
#include "common/timing.h"
|
||||
#include "common/util.h"
|
||||
#include "system/hardware/hw.h"
|
||||
|
||||
#include "system/loggerd/encoder/encoder.h"
|
||||
#include "system/loggerd/logger.h"
|
||||
#ifdef QCOM2
|
||||
#include "system/loggerd/encoder/v4l_encoder.h"
|
||||
#define Encoder V4LEncoder
|
||||
#else
|
||||
#include "system/loggerd/encoder/ffmpeg_encoder.h"
|
||||
#define Encoder FfmpegEncoder
|
||||
#endif
|
||||
|
||||
constexpr int MAIN_FPS = 20;
|
||||
const int MAIN_BITRATE = 10000000;
|
||||
|
||||
#define NO_CAMERA_PATIENCE 500 // fall back to time-based rotation if all cameras are dead
|
||||
#define NO_CAMERA_PATIENCE 500 // fall back to time-based rotation if all cameras are dead
|
||||
|
||||
#define INIT_ENCODE_FUNCTIONS(encode_type) \
|
||||
.get_encode_data_func = &cereal::Event::Reader::get##encode_type##Data, \
|
||||
.set_encode_idx_func = &cereal::Event::Builder::set##encode_type##Idx, \
|
||||
.init_encode_data_func = &cereal::Event::Builder::init##encode_type##Data
|
||||
|
||||
const bool LOGGERD_TEST = getenv("LOGGERD_TEST");
|
||||
const int SEGMENT_LENGTH = LOGGERD_TEST ? atoi(getenv("LOGGERD_SEGMENT_LENGTH")) : 60;
|
||||
|
||||
constexpr char PRESERVE_ATTR_NAME[] = "user.preserve";
|
||||
constexpr char PRESERVE_ATTR_VALUE = '1';
|
||||
|
||||
class EncoderInfo {
|
||||
public:
|
||||
const char *publish_name;
|
||||
@@ -50,9 +36,11 @@ public:
|
||||
int frame_height = 1208;
|
||||
int fps = MAIN_FPS;
|
||||
int bitrate = MAIN_BITRATE;
|
||||
cereal::EncodeIndex::Type encode_type = cereal::EncodeIndex::Type::FULL_H_E_V_C;
|
||||
cereal::EncodeIndex::Type encode_type = Hardware::PC() ? cereal::EncodeIndex::Type::BIG_BOX_LOSSLESS
|
||||
: cereal::EncodeIndex::Type::FULL_H_E_V_C;
|
||||
::cereal::EncodeData::Reader (cereal::Event::Reader::*get_encode_data_func)() const;
|
||||
void (cereal::Event::Builder::*set_encode_idx_func)(::cereal::EncodeIndex::Reader);
|
||||
cereal::EncodeData::Builder (cereal::Event::Builder::*init_encode_data_func)();
|
||||
};
|
||||
|
||||
class LogCameraInfo {
|
||||
@@ -67,21 +55,18 @@ public:
|
||||
const EncoderInfo main_road_encoder_info = {
|
||||
.publish_name = "roadEncodeData",
|
||||
.filename = "fcamera.hevc",
|
||||
.get_encode_data_func = &cereal::Event::Reader::getRoadEncodeData,
|
||||
.set_encode_idx_func = &cereal::Event::Builder::setRoadEncodeIdx,
|
||||
INIT_ENCODE_FUNCTIONS(RoadEncode),
|
||||
};
|
||||
const EncoderInfo main_wide_road_encoder_info = {
|
||||
.publish_name = "wideRoadEncodeData",
|
||||
.filename = "ecamera.hevc",
|
||||
.get_encode_data_func = &cereal::Event::Reader::getWideRoadEncodeData,
|
||||
.set_encode_idx_func = &cereal::Event::Builder::setWideRoadEncodeIdx,
|
||||
INIT_ENCODE_FUNCTIONS(WideRoadEncode),
|
||||
};
|
||||
const EncoderInfo main_driver_encoder_info = {
|
||||
.publish_name = "driverEncodeData",
|
||||
.publish_name = "driverEncodeData",
|
||||
.filename = "dcamera.hevc",
|
||||
.record = Params().getBool("RecordFront"),
|
||||
.get_encode_data_func = &cereal::Event::Reader::getDriverEncodeData,
|
||||
.set_encode_idx_func = &cereal::Event::Builder::setDriverEncodeIdx,
|
||||
INIT_ENCODE_FUNCTIONS(DriverEncode),
|
||||
};
|
||||
|
||||
const EncoderInfo qcam_encoder_info = {
|
||||
@@ -91,31 +76,29 @@ const EncoderInfo qcam_encoder_info = {
|
||||
.encode_type = cereal::EncodeIndex::Type::QCAMERA_H264,
|
||||
.frame_width = 526,
|
||||
.frame_height = 330,
|
||||
.get_encode_data_func = &cereal::Event::Reader::getQRoadEncodeData,
|
||||
.set_encode_idx_func = &cereal::Event::Builder::setQRoadEncodeIdx,
|
||||
INIT_ENCODE_FUNCTIONS(QRoadEncode),
|
||||
};
|
||||
|
||||
|
||||
const LogCameraInfo road_camera_info{
|
||||
.thread_name = "road_cam_encoder",
|
||||
.type = RoadCam,
|
||||
.stream_type = VISION_STREAM_ROAD,
|
||||
.encoder_infos = {main_road_encoder_info, qcam_encoder_info}
|
||||
};
|
||||
.thread_name = "road_cam_encoder",
|
||||
.type = RoadCam,
|
||||
.stream_type = VISION_STREAM_ROAD,
|
||||
.encoder_infos = {main_road_encoder_info, qcam_encoder_info}
|
||||
};
|
||||
|
||||
const LogCameraInfo wide_road_camera_info{
|
||||
.thread_name = "wide_road_cam_encoder",
|
||||
.type = WideRoadCam,
|
||||
.stream_type = VISION_STREAM_WIDE_ROAD,
|
||||
.encoder_infos = {main_wide_road_encoder_info}
|
||||
};
|
||||
|
||||
.thread_name = "wide_road_cam_encoder",
|
||||
.type = WideRoadCam,
|
||||
.stream_type = VISION_STREAM_WIDE_ROAD,
|
||||
.encoder_infos = {main_wide_road_encoder_info}
|
||||
};
|
||||
|
||||
const LogCameraInfo driver_camera_info{
|
||||
.thread_name = "driver_cam_encoder",
|
||||
.type = DriverCam,
|
||||
.stream_type = VISION_STREAM_DRIVER,
|
||||
.encoder_infos = {main_driver_encoder_info}
|
||||
};
|
||||
.thread_name = "driver_cam_encoder",
|
||||
.type = DriverCam,
|
||||
.stream_type = VISION_STREAM_DRIVER,
|
||||
.encoder_infos = {main_driver_encoder_info}
|
||||
};
|
||||
|
||||
const LogCameraInfo cameras_logged[] = {road_camera_info, wide_road_camera_info, driver_camera_info};
|
||||
|
||||
|
||||
@@ -88,9 +88,6 @@ class Uploader:
|
||||
self.immediate_folders = ["crash/", "boot/"]
|
||||
self.immediate_priority = {"qlog": 0, "qlog.bz2": 0, "qcamera.ts": 1}
|
||||
|
||||
# dp
|
||||
self.update_onced = False
|
||||
|
||||
def get_upload_sort(self, name: str) -> int:
|
||||
if name in self.immediate_priority:
|
||||
return self.immediate_priority[name]
|
||||
@@ -216,10 +213,6 @@ class Uploader:
|
||||
self.last_speed = (content_length / 1e6) / self.last_time
|
||||
cloudlog.event("upload_success", key=key, fn=fn, sz=sz, content_length=content_length, network_type=network_type, metered=metered, speed=self.last_speed)
|
||||
success = True
|
||||
if not self.update_onced and stat.status_code != 412:
|
||||
Params().put_bool('dp_upload_ignored', False)
|
||||
self.update_onced = True
|
||||
cloudlog.event("upload_success" if stat.status_code != 412 else "upload_ignored", key=key, fn=fn, sz=sz, network_type=network_type, metered=metered)
|
||||
else:
|
||||
success = False
|
||||
cloudlog.event("upload_failed", stat=stat, exc=self.last_exc, key=key, fn=fn, sz=sz, network_type=network_type, metered=metered)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import os
|
||||
import errno
|
||||
from typing import Dict, Tuple, Optional
|
||||
from typing import Dict, Optional, Tuple
|
||||
|
||||
_cached_attributes: Dict[Tuple, Optional[bytes]] = {}
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -56,7 +56,7 @@ if __name__ == "__main__":
|
||||
pr_err /= len(car)
|
||||
speed_err /= len(car)
|
||||
print("avg psuedorange err %f avg speed err %f" % (pr_err, speed_err))
|
||||
for c in sorted(car, key=lambda x: abs(x[1] - x[3] - pr_err)): # type: ignore
|
||||
for c in sorted(car, key=lambda x: abs(x[1] - x[3] - pr_err)):
|
||||
svid, ublox_psuedorange, ublox_speed, qcom_psuedorange, qcom_speed, cno = c
|
||||
print("svid: %3d pseudorange: %10.2f m speed: %8.2f m/s meas: %12.2f speed: %10.2f meas_err: %10.3f speed_err: %8.3f cno: %d" %
|
||||
(svid, ublox_psuedorange, ublox_speed, qcom_psuedorange, qcom_speed,
|
||||
|
||||
@@ -8,13 +8,16 @@ import time
|
||||
import pycurl
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
from multiprocessing import Process, Event
|
||||
from typing import NoReturn, Optional
|
||||
from struct import unpack_from, calcsize, pack
|
||||
|
||||
from cereal import log
|
||||
import cereal.messaging as messaging
|
||||
from common.gpio import gpio_init, gpio_set
|
||||
from laika.gps_time import GPSTime
|
||||
from laika.gps_time import GPSTime, utc_to_gpst, get_leap_seconds
|
||||
from laika.helpers import get_prn_from_nmea_id
|
||||
from laika.constants import SECS_IN_HR, SECS_IN_DAY, SECS_IN_WEEK
|
||||
from system.hardware.tici.pins import GPIO
|
||||
from system.swaglog import cloudlog
|
||||
from system.sensord.rawgps.modemdiag import ModemDiag, DIAG_LOG_F, setup_logs, send_recv
|
||||
@@ -27,6 +30,9 @@ from system.sensord.rawgps.structs import (dict_unpacker, position_report, relis
|
||||
LOG_GNSS_OEMDRE_SVPOLY_REPORT)
|
||||
|
||||
DEBUG = int(os.getenv("DEBUG", "0"))==1
|
||||
ASSIST_DATA_FILE = '/tmp/xtra3grc.bin'
|
||||
ASSIST_DATA_FILE_DOWNLOAD = ASSIST_DATA_FILE + '.download'
|
||||
ASSISTANCE_URL = 'http://xtrapath3.izatcloud.net/xtra3grc.bin'
|
||||
|
||||
LOG_TYPES = [
|
||||
LOG_GNSS_GPS_MEASUREMENT_REPORT,
|
||||
@@ -82,21 +88,23 @@ measurementStatusGlonassFields = {
|
||||
|
||||
|
||||
def try_setup_logs(diag, log_types):
|
||||
for _ in range(5):
|
||||
for _ in range(10):
|
||||
try:
|
||||
setup_logs(diag, log_types)
|
||||
break
|
||||
except Exception:
|
||||
cloudlog.exception("setup logs failed, trying again")
|
||||
time.sleep(1.0)
|
||||
else:
|
||||
raise Exception(f"setup logs failed, {log_types=}")
|
||||
|
||||
def at_cmd(cmd: str) -> Optional[str]:
|
||||
for _ in range(5):
|
||||
for _ in range(3):
|
||||
try:
|
||||
return subprocess.check_output(f"mmcli -m any --timeout 30 --command='{cmd}'", shell=True, encoding='utf8')
|
||||
except subprocess.CalledProcessError:
|
||||
cloudlog.exception("rawgps.mmcli_command_failed")
|
||||
time.sleep(1.0)
|
||||
raise Exception(f"failed to execute mmcli command {cmd=}")
|
||||
|
||||
|
||||
@@ -107,41 +115,46 @@ def gps_enabled() -> bool:
|
||||
except subprocess.CalledProcessError as exc:
|
||||
raise Exception("failed to execute QGPS mmcli command") from exc
|
||||
|
||||
def download_and_inject_assistance():
|
||||
assist_data_file = '/tmp/xtra3grc.bin'
|
||||
assistance_url = 'http://xtrapath3.izatcloud.net/xtra3grc.bin'
|
||||
|
||||
def download_assistance():
|
||||
try:
|
||||
# download assistance
|
||||
try:
|
||||
c = pycurl.Curl()
|
||||
c.setopt(pycurl.URL, assistance_url)
|
||||
c.setopt(pycurl.NOBODY, 1)
|
||||
c.setopt(pycurl.CONNECTTIMEOUT, 2)
|
||||
c.perform()
|
||||
bytes_n = c.getinfo(pycurl.CONTENT_LENGTH_DOWNLOAD)
|
||||
c.close()
|
||||
if bytes_n > 1e5:
|
||||
cloudlog.error("Qcom assistance data larger than expected")
|
||||
return
|
||||
|
||||
with open(assist_data_file, 'wb') as fp:
|
||||
c = pycurl.Curl()
|
||||
c.setopt(pycurl.URL, assistance_url)
|
||||
c.setopt(pycurl.CONNECTTIMEOUT, 5)
|
||||
|
||||
c.setopt(pycurl.WRITEDATA, fp)
|
||||
c.perform()
|
||||
c.close()
|
||||
except pycurl.error:
|
||||
cloudlog.exception("Failed to download assistance file")
|
||||
c = pycurl.Curl()
|
||||
c.setopt(pycurl.URL, ASSISTANCE_URL)
|
||||
c.setopt(pycurl.NOBODY, 1)
|
||||
c.setopt(pycurl.CONNECTTIMEOUT, 2)
|
||||
c.perform()
|
||||
bytes_n = c.getinfo(pycurl.CONTENT_LENGTH_DOWNLOAD)
|
||||
c.close()
|
||||
if bytes_n > 1e5:
|
||||
cloudlog.error("Qcom assistance data larger than expected")
|
||||
return
|
||||
|
||||
# inject into module
|
||||
with open(ASSIST_DATA_FILE_DOWNLOAD, 'wb') as fp:
|
||||
c = pycurl.Curl()
|
||||
c.setopt(pycurl.URL, ASSISTANCE_URL)
|
||||
c.setopt(pycurl.CONNECTTIMEOUT, 5)
|
||||
|
||||
c.setopt(pycurl.WRITEDATA, fp)
|
||||
c.perform()
|
||||
c.close()
|
||||
os.rename(ASSIST_DATA_FILE_DOWNLOAD, ASSIST_DATA_FILE)
|
||||
except pycurl.error:
|
||||
cloudlog.exception("Failed to download assistance file")
|
||||
return
|
||||
|
||||
def downloader_loop(event):
|
||||
if os.path.exists(ASSIST_DATA_FILE):
|
||||
os.remove(ASSIST_DATA_FILE)
|
||||
while not os.path.exists(ASSIST_DATA_FILE) and not event.is_set():
|
||||
download_assistance()
|
||||
time.sleep(10)
|
||||
|
||||
def inject_assistance():
|
||||
for _ in range(5):
|
||||
try:
|
||||
cmd = f"mmcli -m any --timeout 30 --location-inject-assistance-data={assist_data_file}"
|
||||
cmd = f"mmcli -m any --timeout 30 --location-inject-assistance-data={ASSIST_DATA_FILE}"
|
||||
subprocess.check_output(cmd, stderr=subprocess.PIPE, shell=True)
|
||||
cloudlog.info("successfully loaded assistance data")
|
||||
return
|
||||
except subprocess.CalledProcessError as e:
|
||||
cloudlog.event(
|
||||
"rawgps.assistance_loading_failed",
|
||||
@@ -150,12 +163,12 @@ def download_and_inject_assistance():
|
||||
output=e.output,
|
||||
returncode=e.returncode
|
||||
)
|
||||
finally:
|
||||
if os.path.exists(assist_data_file):
|
||||
os.remove(assist_data_file)
|
||||
time.sleep(0.2)
|
||||
cloudlog.error("failed to load assistance after retry")
|
||||
|
||||
def setup_quectel(diag: ModemDiag) -> bool:
|
||||
ret = False
|
||||
|
||||
def setup_quectel(diag: ModemDiag):
|
||||
# enable OEMDRE in the NV
|
||||
# TODO: it has to reboot for this to take effect
|
||||
DIAG_NV_READ_F = 38
|
||||
@@ -164,7 +177,7 @@ def setup_quectel(diag: ModemDiag):
|
||||
send_recv(diag, DIAG_NV_WRITE_F, pack('<HI', NV_GNSS_OEM_FEATURE_MASK, 1))
|
||||
send_recv(diag, DIAG_NV_READ_F, pack('<H', NV_GNSS_OEM_FEATURE_MASK))
|
||||
|
||||
setup_logs(diag, LOG_TYPES)
|
||||
try_setup_logs(diag, LOG_TYPES)
|
||||
|
||||
if gps_enabled():
|
||||
at_cmd("AT+QGPSEND")
|
||||
@@ -177,7 +190,11 @@ def setup_quectel(diag: ModemDiag):
|
||||
|
||||
# Do internet assistance
|
||||
at_cmd("AT+QGPSXTRA=1")
|
||||
download_and_inject_assistance()
|
||||
at_cmd("AT+QGPSSUPLURL=\"NULL\"")
|
||||
if os.path.exists(ASSIST_DATA_FILE):
|
||||
ret = True
|
||||
inject_assistance()
|
||||
os.remove(ASSIST_DATA_FILE)
|
||||
#at_cmd("AT+QGPSXTRADATA?")
|
||||
time_str = datetime.utcnow().strftime("%Y/%m/%d,%H:%M:%S")
|
||||
at_cmd(f"AT+QGPSXTRATIME=0,\"{time_str}\",1,1,1000")
|
||||
@@ -204,6 +221,8 @@ def setup_quectel(diag: ModemDiag):
|
||||
0,0
|
||||
))
|
||||
|
||||
return ret
|
||||
|
||||
def teardown_quectel(diag):
|
||||
at_cmd("AT+QGPSCFG=\"outport\",\"none\"")
|
||||
if gps_enabled():
|
||||
@@ -211,6 +230,15 @@ def teardown_quectel(diag):
|
||||
try_setup_logs(diag, [])
|
||||
|
||||
|
||||
def wait_for_modem():
|
||||
cloudlog.warning("waiting for modem to come up")
|
||||
while True:
|
||||
ret = subprocess.call("mmcli -m any --timeout 10 --command=\"AT+QGPS?\"", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=True)
|
||||
if ret == 0:
|
||||
return
|
||||
time.sleep(0.1)
|
||||
|
||||
|
||||
def main() -> NoReturn:
|
||||
unpack_gps_meas, size_gps_meas = dict_unpacker(gps_measurement_report, True)
|
||||
unpack_gps_meas_sv, size_gps_meas_sv = dict_unpacker(gps_measurement_report_sv, True)
|
||||
@@ -226,27 +254,25 @@ def main() -> NoReturn:
|
||||
|
||||
unpack_position, _ = dict_unpacker(position_report)
|
||||
|
||||
# wait for ModemManager to come up
|
||||
cloudlog.warning("waiting for modem to come up")
|
||||
while True:
|
||||
ret = subprocess.call("mmcli -m any --timeout 10 --command=\"AT+QGPS?\"", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=True)
|
||||
if ret == 0:
|
||||
break
|
||||
time.sleep(0.1)
|
||||
wait_for_modem()
|
||||
|
||||
# connect to modem
|
||||
diag = ModemDiag()
|
||||
|
||||
def cleanup(sig, frame):
|
||||
cloudlog.warning(f"caught sig {sig}, disabling quectel gps")
|
||||
stop_download_event = Event()
|
||||
assist_fetch_proc = Process(target=downloader_loop, args=(stop_download_event,))
|
||||
assist_fetch_proc.start()
|
||||
def cleanup(proc):
|
||||
cloudlog.warning("caught sig disabling quectel gps")
|
||||
gpio_set(GPIO.UBLOX_PWR_EN, False)
|
||||
teardown_quectel(diag)
|
||||
cloudlog.warning("quectel cleanup done")
|
||||
sys.exit(0)
|
||||
signal.signal(signal.SIGINT, cleanup)
|
||||
signal.signal(signal.SIGTERM, cleanup)
|
||||
signal.signal(signal.SIGINT, lambda sig, frame: cleanup(assist_fetch_proc))
|
||||
signal.signal(signal.SIGTERM, lambda sig, frame: cleanup(assist_fetch_proc))
|
||||
|
||||
setup_quectel(diag)
|
||||
# connect to modem
|
||||
diag = ModemDiag()
|
||||
r = setup_quectel(diag)
|
||||
want_assistance = not r
|
||||
current_gps_time = utc_to_gpst(GPSTime.from_datetime(datetime.utcnow()))
|
||||
cloudlog.warning("quectel setup done")
|
||||
gpio_init(GPIO.UBLOX_PWR_EN, True)
|
||||
gpio_set(GPIO.UBLOX_PWR_EN, True)
|
||||
@@ -254,6 +280,10 @@ def main() -> NoReturn:
|
||||
pm = messaging.PubMaster(['qcomGnss', 'gpsLocation'])
|
||||
|
||||
while 1:
|
||||
if os.path.exists(ASSIST_DATA_FILE) and want_assistance:
|
||||
setup_quectel(diag)
|
||||
want_assistance = False
|
||||
|
||||
opcode, payload = diag.recv()
|
||||
if opcode != DIAG_LOG_F:
|
||||
cloudlog.error(f"Unhandled opcode: {opcode}")
|
||||
@@ -315,6 +345,8 @@ def main() -> NoReturn:
|
||||
setattr(sv.measurementStatus, kk, bool(v & (1<<vv)))
|
||||
else:
|
||||
setattr(sv, k, v)
|
||||
if report.source == log.QcomGnss.MeasurementSource.gps:
|
||||
current_gps_time = GPSTime(report.gpsWeek, report.gpsMilliseconds / 1000.0)
|
||||
pm.send('qcomGnss', msg)
|
||||
elif log_type == LOG_GNSS_POSITION_REPORT:
|
||||
report = unpack_position(log_payload)
|
||||
@@ -335,10 +367,14 @@ def main() -> NoReturn:
|
||||
gps.source = log.GpsLocationData.SensorSource.qcomdiag
|
||||
gps.vNED = vNED
|
||||
gps.verticalAccuracy = report["q_FltVdop"]
|
||||
gps.bearingAccuracyDeg = report["q_FltHeadingUncRad"] * 180/math.pi
|
||||
gps.bearingAccuracyDeg = report["q_FltHeadingUncRad"] * 180/math.pi if (report["q_FltHeadingUncRad"] != 0) else 180
|
||||
gps.speedAccuracy = math.sqrt(sum([x**2 for x in vNEDsigma]))
|
||||
# quectel gps verticalAccuracy is clipped to 500, set invalid if so
|
||||
gps.flags = 1 if gps.verticalAccuracy != 500 else 0
|
||||
if gps.flags:
|
||||
want_assistance = False
|
||||
stop_download_event.set()
|
||||
|
||||
|
||||
pm.send('gpsLocation', msg)
|
||||
|
||||
@@ -357,6 +393,21 @@ def main() -> NoReturn:
|
||||
pass
|
||||
else:
|
||||
setattr(poly, k, v)
|
||||
|
||||
prn = get_prn_from_nmea_id(poly.svId)
|
||||
if prn[0] == 'R':
|
||||
epoch = GPSTime(current_gps_time.week, (poly.t0 - 3*SECS_IN_HR + SECS_IN_DAY) % (SECS_IN_WEEK) + get_leap_seconds(current_gps_time))
|
||||
else:
|
||||
epoch = GPSTime(current_gps_time.week, poly.t0)
|
||||
|
||||
# handle week rollover
|
||||
if epoch.tow < SECS_IN_DAY and current_gps_time.tow > 6*SECS_IN_DAY:
|
||||
epoch.week += 1
|
||||
elif epoch.tow > 6*SECS_IN_DAY and current_gps_time.tow < SECS_IN_DAY:
|
||||
epoch.week -= 1
|
||||
|
||||
poly.gpsWeek = epoch.week
|
||||
poly.gpsTow = epoch.tow
|
||||
pm.send('qcomGnss', msg)
|
||||
|
||||
elif log_type in [LOG_GNSS_GPS_MEASUREMENT_REPORT, LOG_GNSS_GLONASS_MEASUREMENT_REPORT]:
|
||||
|
||||
@@ -5,11 +5,15 @@ import time
|
||||
import datetime
|
||||
import unittest
|
||||
import subprocess
|
||||
import numpy as np
|
||||
|
||||
import cereal.messaging as messaging
|
||||
from system.hardware import TICI
|
||||
from system.sensord.rawgps.rawgpsd import at_cmd
|
||||
from system.sensord.rawgps.rawgpsd import at_cmd, wait_for_modem
|
||||
from selfdrive.manager.process_config import managed_processes
|
||||
from common.transformations.coordinates import ecef_from_geodetic
|
||||
|
||||
GOOD_SIGNAL = bool(int(os.getenv("GOOD_SIGNAL", '0')))
|
||||
|
||||
|
||||
class TestRawgpsd(unittest.TestCase):
|
||||
@@ -18,40 +22,56 @@ class TestRawgpsd(unittest.TestCase):
|
||||
if not TICI:
|
||||
raise unittest.SkipTest
|
||||
|
||||
cls.sm = messaging.SubMaster(['qcomGnss'])
|
||||
os.system("sudo systemctl start systemd-resolved")
|
||||
os.system("sudo systemctl restart ModemManager lte")
|
||||
wait_for_modem()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
managed_processes['rawgpsd'].stop()
|
||||
os.system("sudo systemctl restart systemd-resolved")
|
||||
os.system("sudo systemctl restart ModemManager lte")
|
||||
|
||||
def setUp(self):
|
||||
at_cmd("AT+QGPSDEL=0")
|
||||
self.sm = messaging.SubMaster(['qcomGnss', 'gpsLocation', 'gnssMeasurements'])
|
||||
|
||||
def tearDown(self):
|
||||
managed_processes['rawgpsd'].stop()
|
||||
os.system("sudo systemctl restart systemd-resolved")
|
||||
|
||||
def _wait_for_output(self, t=10):
|
||||
self.sm.update(0)
|
||||
for __ in range(t*10):
|
||||
self.sm.update(100)
|
||||
def _wait_for_output(self, t):
|
||||
dt = 0.1
|
||||
for _ in range(t*int(1/dt)):
|
||||
self.sm.update(0)
|
||||
if self.sm.updated['qcomGnss']:
|
||||
break
|
||||
time.sleep(dt)
|
||||
return self.sm.updated['qcomGnss']
|
||||
|
||||
def test_wait_for_modem(self):
|
||||
os.system("sudo systemctl stop ModemManager lte")
|
||||
managed_processes['rawgpsd'].start()
|
||||
assert not self._wait_for_output(10)
|
||||
def test_no_crash_double_command(self):
|
||||
at_cmd("AT+QGPSDEL=0")
|
||||
at_cmd("AT+QGPSDEL=0")
|
||||
|
||||
os.system("sudo systemctl restart ModemManager lte")
|
||||
def test_wait_for_modem(self):
|
||||
os.system("sudo systemctl stop ModemManager")
|
||||
managed_processes['rawgpsd'].start()
|
||||
assert not self._wait_for_output(5)
|
||||
|
||||
os.system("sudo systemctl restart ModemManager")
|
||||
assert self._wait_for_output(30)
|
||||
|
||||
def test_startup_time(self):
|
||||
for _ in range(5):
|
||||
managed_processes['rawgpsd'].start()
|
||||
|
||||
start_time = time.monotonic()
|
||||
assert self._wait_for_output(), "rawgpsd didn't start outputting messages in time"
|
||||
|
||||
et = time.monotonic() - start_time
|
||||
assert et < 7, f"rawgpsd took {et:.1f}s to start"
|
||||
managed_processes['rawgpsd'].stop()
|
||||
for internet in (True, False):
|
||||
if not internet:
|
||||
os.system("sudo systemctl stop systemd-resolved")
|
||||
with self.subTest(internet=internet):
|
||||
managed_processes['rawgpsd'].start()
|
||||
assert self._wait_for_output(7)
|
||||
managed_processes['rawgpsd'].stop()
|
||||
|
||||
def test_turns_off_gnss(self):
|
||||
for s in (0.1, 0.5, 1, 5):
|
||||
for s in (0.1, 1, 5):
|
||||
managed_processes['rawgpsd'].start()
|
||||
time.sleep(s)
|
||||
managed_processes['rawgpsd'].stop()
|
||||
@@ -60,24 +80,65 @@ class TestRawgpsd(unittest.TestCase):
|
||||
loc_status = json.loads(ls)
|
||||
assert set(loc_status['modem']['location']['enabled']) <= {'3gpp-lac-ci'}
|
||||
|
||||
def test_assistance_loading(self):
|
||||
# clear assistance data
|
||||
at_cmd("AT+QGPSDEL=0")
|
||||
|
||||
managed_processes['rawgpsd'].start()
|
||||
assert self._wait_for_output(10)
|
||||
managed_processes['rawgpsd'].stop()
|
||||
|
||||
def check_assistance(self, should_be_loaded):
|
||||
# after QGPSDEL: '+QGPSXTRADATA: 0,"1980/01/05,19:00:00"'
|
||||
# after loading: '+QGPSXTRADATA: 10080,"2023/06/24,19:00:00"'
|
||||
out = at_cmd("AT+QGPSXTRADATA?")
|
||||
out = out.split("+QGPSXTRADATA:")[1].split("'")[0].strip()
|
||||
valid_duration, injected_date = out.split(",", 1)
|
||||
assert valid_duration == "10080" # should be max time
|
||||
valid_duration, injected_time_str = out.split(",", 1)
|
||||
if should_be_loaded:
|
||||
assert valid_duration == "10080" # should be max time
|
||||
injected_time = datetime.datetime.strptime(injected_time_str.replace("\"", ""), "%Y/%m/%d,%H:%M:%S")
|
||||
self.assertLess(abs((datetime.datetime.utcnow() - injected_time).total_seconds()), 60*60*12)
|
||||
else:
|
||||
valid_duration, injected_time_str = out.split(",", 1)
|
||||
injected_time_str = injected_time_str.replace('\"', '').replace('\'', '')
|
||||
assert injected_time_str[:] == '1980/01/05,19:00:00'[:]
|
||||
assert valid_duration == '0'
|
||||
|
||||
# TODO: time doesn't match up
|
||||
assert injected_date[1:].startswith(datetime.datetime.now().strftime("%Y/%m/%d"))
|
||||
def test_assistance_loading(self):
|
||||
managed_processes['rawgpsd'].start()
|
||||
assert self._wait_for_output(10)
|
||||
managed_processes['rawgpsd'].stop()
|
||||
self.check_assistance(True)
|
||||
|
||||
def test_no_assistance_loading(self):
|
||||
os.system("sudo systemctl stop systemd-resolved")
|
||||
|
||||
managed_processes['rawgpsd'].start()
|
||||
assert self._wait_for_output(10)
|
||||
managed_processes['rawgpsd'].stop()
|
||||
self.check_assistance(False)
|
||||
|
||||
def test_late_assistance_loading(self):
|
||||
os.system("sudo systemctl stop systemd-resolved")
|
||||
|
||||
managed_processes['rawgpsd'].start()
|
||||
self._wait_for_output(17)
|
||||
assert self.sm.updated['qcomGnss']
|
||||
|
||||
os.system("sudo systemctl restart systemd-resolved")
|
||||
time.sleep(15)
|
||||
managed_processes['rawgpsd'].stop()
|
||||
self.check_assistance(True)
|
||||
|
||||
@unittest.skipIf(not GOOD_SIGNAL, "No good GPS signal")
|
||||
def test_fix(self):
|
||||
managed_processes['rawgpsd'].start()
|
||||
managed_processes['laikad'].start()
|
||||
assert self._wait_for_output(60)
|
||||
assert self.sm.updated['qcomGnss']
|
||||
assert self.sm.updated['gpsLocation']
|
||||
assert self.sm['gpsLocation'].flags == 1
|
||||
module_fix = ecef_from_geodetic([self.sm['gpsLocation'].latitude,
|
||||
self.sm['gpsLocation'].longitude,
|
||||
self.sm['gpsLocation'].altitude])
|
||||
assert self.sm['gnssMeasurements'].positionECEF.valid
|
||||
total_diff = np.array(self.sm['gnssMeasurements'].positionECEF.value) - module_fix
|
||||
self.assertLess(np.linalg.norm(total_diff), 100)
|
||||
managed_processes['laikad'].stop()
|
||||
managed_processes['rawgpsd'].stop()
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(failfast=True)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
import warnings
|
||||
from pathlib import Path
|
||||
from logging.handlers import BaseRotatingHandler
|
||||
|
||||
@@ -90,6 +91,8 @@ class UnixDomainSocketHandler(logging.Handler):
|
||||
|
||||
def emit(self, record):
|
||||
if os.getpid() != self.pid:
|
||||
# TODO suppresses warning about forking proc with zmq socket, fix root cause
|
||||
warnings.filterwarnings("ignore", category=ResourceWarning, message="unclosed.*<zmq.*>")
|
||||
self.connect()
|
||||
|
||||
msg = self.format(record).rstrip('\n')
|
||||
|
||||
@@ -0,0 +1,353 @@
|
||||
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
|
||||
|
||||
#include "glonass.h"
|
||||
|
||||
glonass_t::glonass_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, glonass_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = this;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void glonass_t::_read() {
|
||||
m_idle_chip = m__io->read_bits_int_be(1);
|
||||
m_string_number = m__io->read_bits_int_be(4);
|
||||
//m__io->align_to_byte();
|
||||
switch (string_number()) {
|
||||
case 4: {
|
||||
m_data = new string_4_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
m_data = new string_1_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
m_data = new string_3_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
m_data = new string_5_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
m_data = new string_2_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
m_data = new string_non_immediate_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_hamming_code = m__io->read_bits_int_be(8);
|
||||
m_pad_1 = m__io->read_bits_int_be(11);
|
||||
m_superframe_number = m__io->read_bits_int_be(16);
|
||||
m_pad_2 = m__io->read_bits_int_be(8);
|
||||
m_frame_number = m__io->read_bits_int_be(8);
|
||||
}
|
||||
|
||||
glonass_t::~glonass_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void glonass_t::_clean_up() {
|
||||
if (m_data) {
|
||||
delete m_data; m_data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
glonass_t::string_4_t::string_4_t(kaitai::kstream* p__io, glonass_t* p__parent, glonass_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
f_tau_n = false;
|
||||
f_delta_tau_n = false;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void glonass_t::string_4_t::_read() {
|
||||
m_tau_n_sign = m__io->read_bits_int_be(1);
|
||||
m_tau_n_value = m__io->read_bits_int_be(21);
|
||||
m_delta_tau_n_sign = m__io->read_bits_int_be(1);
|
||||
m_delta_tau_n_value = m__io->read_bits_int_be(4);
|
||||
m_e_n = m__io->read_bits_int_be(5);
|
||||
m_not_used_1 = m__io->read_bits_int_be(14);
|
||||
m_p4 = m__io->read_bits_int_be(1);
|
||||
m_f_t = m__io->read_bits_int_be(4);
|
||||
m_not_used_2 = m__io->read_bits_int_be(3);
|
||||
m_n_t = m__io->read_bits_int_be(11);
|
||||
m_n = m__io->read_bits_int_be(5);
|
||||
m_m = m__io->read_bits_int_be(2);
|
||||
}
|
||||
|
||||
glonass_t::string_4_t::~string_4_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void glonass_t::string_4_t::_clean_up() {
|
||||
}
|
||||
|
||||
int32_t glonass_t::string_4_t::tau_n() {
|
||||
if (f_tau_n)
|
||||
return m_tau_n;
|
||||
m_tau_n = ((tau_n_sign()) ? ((tau_n_value() * -1)) : (tau_n_value()));
|
||||
f_tau_n = true;
|
||||
return m_tau_n;
|
||||
}
|
||||
|
||||
int32_t glonass_t::string_4_t::delta_tau_n() {
|
||||
if (f_delta_tau_n)
|
||||
return m_delta_tau_n;
|
||||
m_delta_tau_n = ((delta_tau_n_sign()) ? ((delta_tau_n_value() * -1)) : (delta_tau_n_value()));
|
||||
f_delta_tau_n = true;
|
||||
return m_delta_tau_n;
|
||||
}
|
||||
|
||||
glonass_t::string_non_immediate_t::string_non_immediate_t(kaitai::kstream* p__io, glonass_t* p__parent, glonass_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void glonass_t::string_non_immediate_t::_read() {
|
||||
m_data_1 = m__io->read_bits_int_be(64);
|
||||
m_data_2 = m__io->read_bits_int_be(8);
|
||||
}
|
||||
|
||||
glonass_t::string_non_immediate_t::~string_non_immediate_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void glonass_t::string_non_immediate_t::_clean_up() {
|
||||
}
|
||||
|
||||
glonass_t::string_5_t::string_5_t(kaitai::kstream* p__io, glonass_t* p__parent, glonass_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void glonass_t::string_5_t::_read() {
|
||||
m_n_a = m__io->read_bits_int_be(11);
|
||||
m_tau_c = m__io->read_bits_int_be(32);
|
||||
m_not_used = m__io->read_bits_int_be(1);
|
||||
m_n_4 = m__io->read_bits_int_be(5);
|
||||
m_tau_gps = m__io->read_bits_int_be(22);
|
||||
m_l_n = m__io->read_bits_int_be(1);
|
||||
}
|
||||
|
||||
glonass_t::string_5_t::~string_5_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void glonass_t::string_5_t::_clean_up() {
|
||||
}
|
||||
|
||||
glonass_t::string_1_t::string_1_t(kaitai::kstream* p__io, glonass_t* p__parent, glonass_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
f_x_vel = false;
|
||||
f_x_accel = false;
|
||||
f_x = false;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void glonass_t::string_1_t::_read() {
|
||||
m_not_used = m__io->read_bits_int_be(2);
|
||||
m_p1 = m__io->read_bits_int_be(2);
|
||||
m_t_k = m__io->read_bits_int_be(12);
|
||||
m_x_vel_sign = m__io->read_bits_int_be(1);
|
||||
m_x_vel_value = m__io->read_bits_int_be(23);
|
||||
m_x_accel_sign = m__io->read_bits_int_be(1);
|
||||
m_x_accel_value = m__io->read_bits_int_be(4);
|
||||
m_x_sign = m__io->read_bits_int_be(1);
|
||||
m_x_value = m__io->read_bits_int_be(26);
|
||||
}
|
||||
|
||||
glonass_t::string_1_t::~string_1_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void glonass_t::string_1_t::_clean_up() {
|
||||
}
|
||||
|
||||
int32_t glonass_t::string_1_t::x_vel() {
|
||||
if (f_x_vel)
|
||||
return m_x_vel;
|
||||
m_x_vel = ((x_vel_sign()) ? ((x_vel_value() * -1)) : (x_vel_value()));
|
||||
f_x_vel = true;
|
||||
return m_x_vel;
|
||||
}
|
||||
|
||||
int32_t glonass_t::string_1_t::x_accel() {
|
||||
if (f_x_accel)
|
||||
return m_x_accel;
|
||||
m_x_accel = ((x_accel_sign()) ? ((x_accel_value() * -1)) : (x_accel_value()));
|
||||
f_x_accel = true;
|
||||
return m_x_accel;
|
||||
}
|
||||
|
||||
int32_t glonass_t::string_1_t::x() {
|
||||
if (f_x)
|
||||
return m_x;
|
||||
m_x = ((x_sign()) ? ((x_value() * -1)) : (x_value()));
|
||||
f_x = true;
|
||||
return m_x;
|
||||
}
|
||||
|
||||
glonass_t::string_2_t::string_2_t(kaitai::kstream* p__io, glonass_t* p__parent, glonass_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
f_y_vel = false;
|
||||
f_y_accel = false;
|
||||
f_y = false;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void glonass_t::string_2_t::_read() {
|
||||
m_b_n = m__io->read_bits_int_be(3);
|
||||
m_p2 = m__io->read_bits_int_be(1);
|
||||
m_t_b = m__io->read_bits_int_be(7);
|
||||
m_not_used = m__io->read_bits_int_be(5);
|
||||
m_y_vel_sign = m__io->read_bits_int_be(1);
|
||||
m_y_vel_value = m__io->read_bits_int_be(23);
|
||||
m_y_accel_sign = m__io->read_bits_int_be(1);
|
||||
m_y_accel_value = m__io->read_bits_int_be(4);
|
||||
m_y_sign = m__io->read_bits_int_be(1);
|
||||
m_y_value = m__io->read_bits_int_be(26);
|
||||
}
|
||||
|
||||
glonass_t::string_2_t::~string_2_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void glonass_t::string_2_t::_clean_up() {
|
||||
}
|
||||
|
||||
int32_t glonass_t::string_2_t::y_vel() {
|
||||
if (f_y_vel)
|
||||
return m_y_vel;
|
||||
m_y_vel = ((y_vel_sign()) ? ((y_vel_value() * -1)) : (y_vel_value()));
|
||||
f_y_vel = true;
|
||||
return m_y_vel;
|
||||
}
|
||||
|
||||
int32_t glonass_t::string_2_t::y_accel() {
|
||||
if (f_y_accel)
|
||||
return m_y_accel;
|
||||
m_y_accel = ((y_accel_sign()) ? ((y_accel_value() * -1)) : (y_accel_value()));
|
||||
f_y_accel = true;
|
||||
return m_y_accel;
|
||||
}
|
||||
|
||||
int32_t glonass_t::string_2_t::y() {
|
||||
if (f_y)
|
||||
return m_y;
|
||||
m_y = ((y_sign()) ? ((y_value() * -1)) : (y_value()));
|
||||
f_y = true;
|
||||
return m_y;
|
||||
}
|
||||
|
||||
glonass_t::string_3_t::string_3_t(kaitai::kstream* p__io, glonass_t* p__parent, glonass_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
f_gamma_n = false;
|
||||
f_z_vel = false;
|
||||
f_z_accel = false;
|
||||
f_z = false;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void glonass_t::string_3_t::_read() {
|
||||
m_p3 = m__io->read_bits_int_be(1);
|
||||
m_gamma_n_sign = m__io->read_bits_int_be(1);
|
||||
m_gamma_n_value = m__io->read_bits_int_be(10);
|
||||
m_not_used = m__io->read_bits_int_be(1);
|
||||
m_p = m__io->read_bits_int_be(2);
|
||||
m_l_n = m__io->read_bits_int_be(1);
|
||||
m_z_vel_sign = m__io->read_bits_int_be(1);
|
||||
m_z_vel_value = m__io->read_bits_int_be(23);
|
||||
m_z_accel_sign = m__io->read_bits_int_be(1);
|
||||
m_z_accel_value = m__io->read_bits_int_be(4);
|
||||
m_z_sign = m__io->read_bits_int_be(1);
|
||||
m_z_value = m__io->read_bits_int_be(26);
|
||||
}
|
||||
|
||||
glonass_t::string_3_t::~string_3_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void glonass_t::string_3_t::_clean_up() {
|
||||
}
|
||||
|
||||
int32_t glonass_t::string_3_t::gamma_n() {
|
||||
if (f_gamma_n)
|
||||
return m_gamma_n;
|
||||
m_gamma_n = ((gamma_n_sign()) ? ((gamma_n_value() * -1)) : (gamma_n_value()));
|
||||
f_gamma_n = true;
|
||||
return m_gamma_n;
|
||||
}
|
||||
|
||||
int32_t glonass_t::string_3_t::z_vel() {
|
||||
if (f_z_vel)
|
||||
return m_z_vel;
|
||||
m_z_vel = ((z_vel_sign()) ? ((z_vel_value() * -1)) : (z_vel_value()));
|
||||
f_z_vel = true;
|
||||
return m_z_vel;
|
||||
}
|
||||
|
||||
int32_t glonass_t::string_3_t::z_accel() {
|
||||
if (f_z_accel)
|
||||
return m_z_accel;
|
||||
m_z_accel = ((z_accel_sign()) ? ((z_accel_value() * -1)) : (z_accel_value()));
|
||||
f_z_accel = true;
|
||||
return m_z_accel;
|
||||
}
|
||||
|
||||
int32_t glonass_t::string_3_t::z() {
|
||||
if (f_z)
|
||||
return m_z;
|
||||
m_z = ((z_sign()) ? ((z_value() * -1)) : (z_value()));
|
||||
f_z = true;
|
||||
return m_z;
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
|
||||
|
||||
#include "gps.h"
|
||||
#include "kaitai/exceptions.h"
|
||||
|
||||
gps_t::gps_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, gps_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = this;
|
||||
m_tlm = 0;
|
||||
m_how = 0;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void gps_t::_read() {
|
||||
m_tlm = new tlm_t(m__io, this, m__root);
|
||||
m_how = new how_t(m__io, this, m__root);
|
||||
n_body = true;
|
||||
switch (how()->subframe_id()) {
|
||||
case 1: {
|
||||
n_body = false;
|
||||
m_body = new subframe_1_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
n_body = false;
|
||||
m_body = new subframe_2_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
n_body = false;
|
||||
m_body = new subframe_3_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
n_body = false;
|
||||
m_body = new subframe_4_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gps_t::~gps_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void gps_t::_clean_up() {
|
||||
if (m_tlm) {
|
||||
delete m_tlm; m_tlm = 0;
|
||||
}
|
||||
if (m_how) {
|
||||
delete m_how; m_how = 0;
|
||||
}
|
||||
if (!n_body) {
|
||||
if (m_body) {
|
||||
delete m_body; m_body = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gps_t::subframe_1_t::subframe_1_t(kaitai::kstream* p__io, gps_t* p__parent, gps_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
f_af_0 = false;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void gps_t::subframe_1_t::_read() {
|
||||
m_week_no = m__io->read_bits_int_be(10);
|
||||
m_code = m__io->read_bits_int_be(2);
|
||||
m_sv_accuracy = m__io->read_bits_int_be(4);
|
||||
m_sv_health = m__io->read_bits_int_be(6);
|
||||
m_iodc_msb = m__io->read_bits_int_be(2);
|
||||
m_l2_p_data_flag = m__io->read_bits_int_be(1);
|
||||
m_reserved1 = m__io->read_bits_int_be(23);
|
||||
m_reserved2 = m__io->read_bits_int_be(24);
|
||||
m_reserved3 = m__io->read_bits_int_be(24);
|
||||
m_reserved4 = m__io->read_bits_int_be(16);
|
||||
m__io->align_to_byte();
|
||||
m_t_gd = m__io->read_s1();
|
||||
m_iodc_lsb = m__io->read_u1();
|
||||
m_t_oc = m__io->read_u2be();
|
||||
m_af_2 = m__io->read_s1();
|
||||
m_af_1 = m__io->read_s2be();
|
||||
m_af_0_sign = m__io->read_bits_int_be(1);
|
||||
m_af_0_value = m__io->read_bits_int_be(21);
|
||||
m_reserved5 = m__io->read_bits_int_be(2);
|
||||
}
|
||||
|
||||
gps_t::subframe_1_t::~subframe_1_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void gps_t::subframe_1_t::_clean_up() {
|
||||
}
|
||||
|
||||
int32_t gps_t::subframe_1_t::af_0() {
|
||||
if (f_af_0)
|
||||
return m_af_0;
|
||||
m_af_0 = ((af_0_sign()) ? ((af_0_value() - (1 << 21))) : (af_0_value()));
|
||||
f_af_0 = true;
|
||||
return m_af_0;
|
||||
}
|
||||
|
||||
gps_t::subframe_3_t::subframe_3_t(kaitai::kstream* p__io, gps_t* p__parent, gps_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
f_omega_dot = false;
|
||||
f_idot = false;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void gps_t::subframe_3_t::_read() {
|
||||
m_c_ic = m__io->read_s2be();
|
||||
m_omega_0 = m__io->read_s4be();
|
||||
m_c_is = m__io->read_s2be();
|
||||
m_i_0 = m__io->read_s4be();
|
||||
m_c_rc = m__io->read_s2be();
|
||||
m_omega = m__io->read_s4be();
|
||||
m_omega_dot_sign = m__io->read_bits_int_be(1);
|
||||
m_omega_dot_value = m__io->read_bits_int_be(23);
|
||||
m__io->align_to_byte();
|
||||
m_iode = m__io->read_u1();
|
||||
m_idot_sign = m__io->read_bits_int_be(1);
|
||||
m_idot_value = m__io->read_bits_int_be(13);
|
||||
m_reserved = m__io->read_bits_int_be(2);
|
||||
}
|
||||
|
||||
gps_t::subframe_3_t::~subframe_3_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void gps_t::subframe_3_t::_clean_up() {
|
||||
}
|
||||
|
||||
int32_t gps_t::subframe_3_t::omega_dot() {
|
||||
if (f_omega_dot)
|
||||
return m_omega_dot;
|
||||
m_omega_dot = ((omega_dot_sign()) ? ((omega_dot_value() - (1 << 23))) : (omega_dot_value()));
|
||||
f_omega_dot = true;
|
||||
return m_omega_dot;
|
||||
}
|
||||
|
||||
int32_t gps_t::subframe_3_t::idot() {
|
||||
if (f_idot)
|
||||
return m_idot;
|
||||
m_idot = ((idot_sign()) ? ((idot_value() - (1 << 13))) : (idot_value()));
|
||||
f_idot = true;
|
||||
return m_idot;
|
||||
}
|
||||
|
||||
gps_t::subframe_4_t::subframe_4_t(kaitai::kstream* p__io, gps_t* p__parent, gps_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void gps_t::subframe_4_t::_read() {
|
||||
m_data_id = m__io->read_bits_int_be(2);
|
||||
m_page_id = m__io->read_bits_int_be(6);
|
||||
m__io->align_to_byte();
|
||||
n_body = true;
|
||||
switch (page_id()) {
|
||||
case 56: {
|
||||
n_body = false;
|
||||
m_body = new ionosphere_data_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gps_t::subframe_4_t::~subframe_4_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void gps_t::subframe_4_t::_clean_up() {
|
||||
if (!n_body) {
|
||||
if (m_body) {
|
||||
delete m_body; m_body = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gps_t::subframe_4_t::ionosphere_data_t::ionosphere_data_t(kaitai::kstream* p__io, gps_t::subframe_4_t* p__parent, gps_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void gps_t::subframe_4_t::ionosphere_data_t::_read() {
|
||||
m_a0 = m__io->read_s1();
|
||||
m_a1 = m__io->read_s1();
|
||||
m_a2 = m__io->read_s1();
|
||||
m_a3 = m__io->read_s1();
|
||||
m_b0 = m__io->read_s1();
|
||||
m_b1 = m__io->read_s1();
|
||||
m_b2 = m__io->read_s1();
|
||||
m_b3 = m__io->read_s1();
|
||||
}
|
||||
|
||||
gps_t::subframe_4_t::ionosphere_data_t::~ionosphere_data_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void gps_t::subframe_4_t::ionosphere_data_t::_clean_up() {
|
||||
}
|
||||
|
||||
gps_t::how_t::how_t(kaitai::kstream* p__io, gps_t* p__parent, gps_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void gps_t::how_t::_read() {
|
||||
m_tow_count = m__io->read_bits_int_be(17);
|
||||
m_alert = m__io->read_bits_int_be(1);
|
||||
m_anti_spoof = m__io->read_bits_int_be(1);
|
||||
m_subframe_id = m__io->read_bits_int_be(3);
|
||||
m_reserved = m__io->read_bits_int_be(2);
|
||||
}
|
||||
|
||||
gps_t::how_t::~how_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void gps_t::how_t::_clean_up() {
|
||||
}
|
||||
|
||||
gps_t::tlm_t::tlm_t(kaitai::kstream* p__io, gps_t* p__parent, gps_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void gps_t::tlm_t::_read() {
|
||||
m_preamble = m__io->read_bytes(1);
|
||||
if (!(preamble() == std::string("\x8B", 1))) {
|
||||
throw kaitai::validation_not_equal_error<std::string>(std::string("\x8B", 1), preamble(), _io(), std::string("/types/tlm/seq/0"));
|
||||
}
|
||||
m_tlm = m__io->read_bits_int_be(14);
|
||||
m_integrity_status = m__io->read_bits_int_be(1);
|
||||
m_reserved = m__io->read_bits_int_be(1);
|
||||
}
|
||||
|
||||
gps_t::tlm_t::~tlm_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void gps_t::tlm_t::_clean_up() {
|
||||
}
|
||||
|
||||
gps_t::subframe_2_t::subframe_2_t(kaitai::kstream* p__io, gps_t* p__parent, gps_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void gps_t::subframe_2_t::_read() {
|
||||
m_iode = m__io->read_u1();
|
||||
m_c_rs = m__io->read_s2be();
|
||||
m_delta_n = m__io->read_s2be();
|
||||
m_m_0 = m__io->read_s4be();
|
||||
m_c_uc = m__io->read_s2be();
|
||||
m_e = m__io->read_s4be();
|
||||
m_c_us = m__io->read_s2be();
|
||||
m_sqrt_a = m__io->read_u4be();
|
||||
m_t_oe = m__io->read_u2be();
|
||||
m_fit_interval_flag = m__io->read_bits_int_be(1);
|
||||
m_aoda = m__io->read_bits_int_be(5);
|
||||
m_reserved = m__io->read_bits_int_be(2);
|
||||
}
|
||||
|
||||
gps_t::subframe_2_t::~subframe_2_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void gps_t::subframe_2_t::_clean_up() {
|
||||
}
|
||||
@@ -0,0 +1,424 @@
|
||||
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
|
||||
|
||||
#include "ubx.h"
|
||||
#include "kaitai/exceptions.h"
|
||||
|
||||
ubx_t::ubx_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, ubx_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = this;
|
||||
f_checksum = false;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void ubx_t::_read() {
|
||||
m_magic = m__io->read_bytes(2);
|
||||
if (!(magic() == std::string("\xB5\x62", 2))) {
|
||||
throw kaitai::validation_not_equal_error<std::string>(std::string("\xB5\x62", 2), magic(), _io(), std::string("/seq/0"));
|
||||
}
|
||||
m_msg_type = m__io->read_u2be();
|
||||
m_length = m__io->read_u2le();
|
||||
n_body = true;
|
||||
switch (msg_type()) {
|
||||
case 2569: {
|
||||
n_body = false;
|
||||
m_body = new mon_hw_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
case 533: {
|
||||
n_body = false;
|
||||
m_body = new rxm_rawx_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
case 531: {
|
||||
n_body = false;
|
||||
m_body = new rxm_sfrbx_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
case 309: {
|
||||
n_body = false;
|
||||
m_body = new nav_sat_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
case 2571: {
|
||||
n_body = false;
|
||||
m_body = new mon_hw2_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
case 263: {
|
||||
n_body = false;
|
||||
m_body = new nav_pvt_t(m__io, this, m__root);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ubx_t::~ubx_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void ubx_t::_clean_up() {
|
||||
if (!n_body) {
|
||||
if (m_body) {
|
||||
delete m_body; m_body = 0;
|
||||
}
|
||||
}
|
||||
if (f_checksum) {
|
||||
}
|
||||
}
|
||||
|
||||
ubx_t::rxm_rawx_t::rxm_rawx_t(kaitai::kstream* p__io, ubx_t* p__parent, ubx_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
m_meas = 0;
|
||||
m__raw_meas = 0;
|
||||
m__io__raw_meas = 0;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void ubx_t::rxm_rawx_t::_read() {
|
||||
m_rcv_tow = m__io->read_f8le();
|
||||
m_week = m__io->read_u2le();
|
||||
m_leap_s = m__io->read_s1();
|
||||
m_num_meas = m__io->read_u1();
|
||||
m_rec_stat = m__io->read_u1();
|
||||
m_reserved1 = m__io->read_bytes(3);
|
||||
m__raw_meas = new std::vector<std::string>();
|
||||
m__io__raw_meas = new std::vector<kaitai::kstream*>();
|
||||
m_meas = new std::vector<measurement_t*>();
|
||||
const int l_meas = num_meas();
|
||||
for (int i = 0; i < l_meas; i++) {
|
||||
m__raw_meas->push_back(m__io->read_bytes(32));
|
||||
kaitai::kstream* io__raw_meas = new kaitai::kstream(m__raw_meas->at(m__raw_meas->size() - 1));
|
||||
m__io__raw_meas->push_back(io__raw_meas);
|
||||
m_meas->push_back(new measurement_t(io__raw_meas, this, m__root));
|
||||
}
|
||||
}
|
||||
|
||||
ubx_t::rxm_rawx_t::~rxm_rawx_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void ubx_t::rxm_rawx_t::_clean_up() {
|
||||
if (m__raw_meas) {
|
||||
delete m__raw_meas; m__raw_meas = 0;
|
||||
}
|
||||
if (m__io__raw_meas) {
|
||||
for (std::vector<kaitai::kstream*>::iterator it = m__io__raw_meas->begin(); it != m__io__raw_meas->end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
delete m__io__raw_meas; m__io__raw_meas = 0;
|
||||
}
|
||||
if (m_meas) {
|
||||
for (std::vector<measurement_t*>::iterator it = m_meas->begin(); it != m_meas->end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
delete m_meas; m_meas = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ubx_t::rxm_rawx_t::measurement_t::measurement_t(kaitai::kstream* p__io, ubx_t::rxm_rawx_t* p__parent, ubx_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void ubx_t::rxm_rawx_t::measurement_t::_read() {
|
||||
m_pr_mes = m__io->read_f8le();
|
||||
m_cp_mes = m__io->read_f8le();
|
||||
m_do_mes = m__io->read_f4le();
|
||||
m_gnss_id = static_cast<ubx_t::gnss_type_t>(m__io->read_u1());
|
||||
m_sv_id = m__io->read_u1();
|
||||
m_reserved2 = m__io->read_bytes(1);
|
||||
m_freq_id = m__io->read_u1();
|
||||
m_lock_time = m__io->read_u2le();
|
||||
m_cno = m__io->read_u1();
|
||||
m_pr_stdev = m__io->read_u1();
|
||||
m_cp_stdev = m__io->read_u1();
|
||||
m_do_stdev = m__io->read_u1();
|
||||
m_trk_stat = m__io->read_u1();
|
||||
m_reserved3 = m__io->read_bytes(1);
|
||||
}
|
||||
|
||||
ubx_t::rxm_rawx_t::measurement_t::~measurement_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void ubx_t::rxm_rawx_t::measurement_t::_clean_up() {
|
||||
}
|
||||
|
||||
ubx_t::rxm_sfrbx_t::rxm_sfrbx_t(kaitai::kstream* p__io, ubx_t* p__parent, ubx_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
m_body = 0;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void ubx_t::rxm_sfrbx_t::_read() {
|
||||
m_gnss_id = static_cast<ubx_t::gnss_type_t>(m__io->read_u1());
|
||||
m_sv_id = m__io->read_u1();
|
||||
m_reserved1 = m__io->read_bytes(1);
|
||||
m_freq_id = m__io->read_u1();
|
||||
m_num_words = m__io->read_u1();
|
||||
m_reserved2 = m__io->read_bytes(1);
|
||||
m_version = m__io->read_u1();
|
||||
m_reserved3 = m__io->read_bytes(1);
|
||||
m_body = new std::vector<uint32_t>();
|
||||
const int l_body = num_words();
|
||||
for (int i = 0; i < l_body; i++) {
|
||||
m_body->push_back(m__io->read_u4le());
|
||||
}
|
||||
}
|
||||
|
||||
ubx_t::rxm_sfrbx_t::~rxm_sfrbx_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void ubx_t::rxm_sfrbx_t::_clean_up() {
|
||||
if (m_body) {
|
||||
delete m_body; m_body = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ubx_t::nav_sat_t::nav_sat_t(kaitai::kstream* p__io, ubx_t* p__parent, ubx_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
m_svs = 0;
|
||||
m__raw_svs = 0;
|
||||
m__io__raw_svs = 0;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void ubx_t::nav_sat_t::_read() {
|
||||
m_itow = m__io->read_u4le();
|
||||
m_version = m__io->read_u1();
|
||||
m_num_svs = m__io->read_u1();
|
||||
m_reserved = m__io->read_bytes(2);
|
||||
m__raw_svs = new std::vector<std::string>();
|
||||
m__io__raw_svs = new std::vector<kaitai::kstream*>();
|
||||
m_svs = new std::vector<nav_t*>();
|
||||
const int l_svs = num_svs();
|
||||
for (int i = 0; i < l_svs; i++) {
|
||||
m__raw_svs->push_back(m__io->read_bytes(12));
|
||||
kaitai::kstream* io__raw_svs = new kaitai::kstream(m__raw_svs->at(m__raw_svs->size() - 1));
|
||||
m__io__raw_svs->push_back(io__raw_svs);
|
||||
m_svs->push_back(new nav_t(io__raw_svs, this, m__root));
|
||||
}
|
||||
}
|
||||
|
||||
ubx_t::nav_sat_t::~nav_sat_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void ubx_t::nav_sat_t::_clean_up() {
|
||||
if (m__raw_svs) {
|
||||
delete m__raw_svs; m__raw_svs = 0;
|
||||
}
|
||||
if (m__io__raw_svs) {
|
||||
for (std::vector<kaitai::kstream*>::iterator it = m__io__raw_svs->begin(); it != m__io__raw_svs->end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
delete m__io__raw_svs; m__io__raw_svs = 0;
|
||||
}
|
||||
if (m_svs) {
|
||||
for (std::vector<nav_t*>::iterator it = m_svs->begin(); it != m_svs->end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
delete m_svs; m_svs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ubx_t::nav_sat_t::nav_t::nav_t(kaitai::kstream* p__io, ubx_t::nav_sat_t* p__parent, ubx_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void ubx_t::nav_sat_t::nav_t::_read() {
|
||||
m_gnss_id = static_cast<ubx_t::gnss_type_t>(m__io->read_u1());
|
||||
m_sv_id = m__io->read_u1();
|
||||
m_cno = m__io->read_u1();
|
||||
m_elev = m__io->read_s1();
|
||||
m_azim = m__io->read_s2le();
|
||||
m_pr_res = m__io->read_s2le();
|
||||
m_flags = m__io->read_u4le();
|
||||
}
|
||||
|
||||
ubx_t::nav_sat_t::nav_t::~nav_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void ubx_t::nav_sat_t::nav_t::_clean_up() {
|
||||
}
|
||||
|
||||
ubx_t::nav_pvt_t::nav_pvt_t(kaitai::kstream* p__io, ubx_t* p__parent, ubx_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void ubx_t::nav_pvt_t::_read() {
|
||||
m_i_tow = m__io->read_u4le();
|
||||
m_year = m__io->read_u2le();
|
||||
m_month = m__io->read_u1();
|
||||
m_day = m__io->read_u1();
|
||||
m_hour = m__io->read_u1();
|
||||
m_min = m__io->read_u1();
|
||||
m_sec = m__io->read_u1();
|
||||
m_valid = m__io->read_u1();
|
||||
m_t_acc = m__io->read_u4le();
|
||||
m_nano = m__io->read_s4le();
|
||||
m_fix_type = m__io->read_u1();
|
||||
m_flags = m__io->read_u1();
|
||||
m_flags2 = m__io->read_u1();
|
||||
m_num_sv = m__io->read_u1();
|
||||
m_lon = m__io->read_s4le();
|
||||
m_lat = m__io->read_s4le();
|
||||
m_height = m__io->read_s4le();
|
||||
m_h_msl = m__io->read_s4le();
|
||||
m_h_acc = m__io->read_u4le();
|
||||
m_v_acc = m__io->read_u4le();
|
||||
m_vel_n = m__io->read_s4le();
|
||||
m_vel_e = m__io->read_s4le();
|
||||
m_vel_d = m__io->read_s4le();
|
||||
m_g_speed = m__io->read_s4le();
|
||||
m_head_mot = m__io->read_s4le();
|
||||
m_s_acc = m__io->read_s4le();
|
||||
m_head_acc = m__io->read_u4le();
|
||||
m_p_dop = m__io->read_u2le();
|
||||
m_flags3 = m__io->read_u1();
|
||||
m_reserved1 = m__io->read_bytes(5);
|
||||
m_head_veh = m__io->read_s4le();
|
||||
m_mag_dec = m__io->read_s2le();
|
||||
m_mag_acc = m__io->read_u2le();
|
||||
}
|
||||
|
||||
ubx_t::nav_pvt_t::~nav_pvt_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void ubx_t::nav_pvt_t::_clean_up() {
|
||||
}
|
||||
|
||||
ubx_t::mon_hw2_t::mon_hw2_t(kaitai::kstream* p__io, ubx_t* p__parent, ubx_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void ubx_t::mon_hw2_t::_read() {
|
||||
m_ofs_i = m__io->read_s1();
|
||||
m_mag_i = m__io->read_u1();
|
||||
m_ofs_q = m__io->read_s1();
|
||||
m_mag_q = m__io->read_u1();
|
||||
m_cfg_source = static_cast<ubx_t::mon_hw2_t::config_source_t>(m__io->read_u1());
|
||||
m_reserved1 = m__io->read_bytes(3);
|
||||
m_low_lev_cfg = m__io->read_u4le();
|
||||
m_reserved2 = m__io->read_bytes(8);
|
||||
m_post_status = m__io->read_u4le();
|
||||
m_reserved3 = m__io->read_bytes(4);
|
||||
}
|
||||
|
||||
ubx_t::mon_hw2_t::~mon_hw2_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void ubx_t::mon_hw2_t::_clean_up() {
|
||||
}
|
||||
|
||||
ubx_t::mon_hw_t::mon_hw_t(kaitai::kstream* p__io, ubx_t* p__parent, ubx_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
|
||||
try {
|
||||
_read();
|
||||
} catch(...) {
|
||||
_clean_up();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void ubx_t::mon_hw_t::_read() {
|
||||
m_pin_sel = m__io->read_u4le();
|
||||
m_pin_bank = m__io->read_u4le();
|
||||
m_pin_dir = m__io->read_u4le();
|
||||
m_pin_val = m__io->read_u4le();
|
||||
m_noise_per_ms = m__io->read_u2le();
|
||||
m_agc_cnt = m__io->read_u2le();
|
||||
m_a_status = static_cast<ubx_t::mon_hw_t::antenna_status_t>(m__io->read_u1());
|
||||
m_a_power = static_cast<ubx_t::mon_hw_t::antenna_power_t>(m__io->read_u1());
|
||||
m_flags = m__io->read_u1();
|
||||
m_reserved1 = m__io->read_bytes(1);
|
||||
m_used_mask = m__io->read_u4le();
|
||||
m_vp = m__io->read_bytes(17);
|
||||
m_jam_ind = m__io->read_u1();
|
||||
m_reserved2 = m__io->read_bytes(2);
|
||||
m_pin_irq = m__io->read_u4le();
|
||||
m_pull_h = m__io->read_u4le();
|
||||
m_pull_l = m__io->read_u4le();
|
||||
}
|
||||
|
||||
ubx_t::mon_hw_t::~mon_hw_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void ubx_t::mon_hw_t::_clean_up() {
|
||||
}
|
||||
|
||||
uint16_t ubx_t::checksum() {
|
||||
if (f_checksum)
|
||||
return m_checksum;
|
||||
std::streampos _pos = m__io->pos();
|
||||
m__io->seek((length() + 6));
|
||||
m_checksum = m__io->read_u2le();
|
||||
m__io->seek(_pos);
|
||||
f_checksum = true;
|
||||
return m_checksum;
|
||||
}
|
||||
Binary file not shown.
+2
-2
@@ -7,7 +7,7 @@ from functools import lru_cache
|
||||
from common.basedir import BASEDIR
|
||||
from system.swaglog import cloudlog
|
||||
|
||||
RELEASE_BRANCHES = ['release3-staging', 'dashcam3-staging', 'dashcam3', 'nightly']
|
||||
RELEASE_BRANCHES = ['release3-staging', 'dashcam3-staging', 'release3', 'dashcam3', 'nightly']
|
||||
TESTED_BRANCHES = RELEASE_BRANCHES + ['devel', 'devel-staging']
|
||||
|
||||
training_version: bytes = b"0.2.0"
|
||||
@@ -90,7 +90,7 @@ def is_comma_remote() -> bool:
|
||||
if origin is None:
|
||||
return False
|
||||
|
||||
return origin.startswith('git@github.com:dragonpilot-community') or origin.startswith('https://github.com/dragonpilot-community')
|
||||
return origin.startswith('git@github.com:commaai') or origin.startswith('https://github.com/commaai')
|
||||
|
||||
|
||||
@cache
|
||||
|
||||
Reference in New Issue
Block a user