def test_mixed_timestamp_write(n_lidar_timestamp, n_lidar_no_timestamp, n_imu_timestamp, n_imu_no_timestamp, metadata, tmpdir): lidar_timestamp_packets = islice( random_lidar_packets(metadata, random_time=RANDOM_FLOAT), n_lidar_timestamp) lidar_no_timestamp_packets = islice( random_lidar_packets(metadata, random_time=NO_RANDOM_TIME), n_lidar_no_timestamp) imu_timestamp_packets = islice( random_imu_packets(metadata, random_time=RANDOM_FLOAT), n_imu_timestamp) imu_no_timestamp_packets = islice( random_imu_packets(metadata, random_time=NO_RANDOM_TIME), n_imu_no_timestamp) in_packets = list( chain(lidar_timestamp_packets, lidar_no_timestamp_packets, imu_timestamp_packets, imu_no_timestamp_packets)) file_path = os.path.join(tmpdir, "pcap_test.pcap") yes_timestamps = n_lidar_timestamp + n_imu_timestamp no_timestamps = n_lidar_no_timestamp + n_imu_no_timestamp if yes_timestamps > 0 and no_timestamps > 0: with pytest.raises(ValueError): pcap.record(in_packets, file_path) else: pcap.record(in_packets, file_path)
def test_mixed_timestamp_write(n_lidar_timestamp, n_lidar_no_timestamp, n_imu_timestamp, n_imu_no_timestamp, fake_meta, tmpdir) -> None: """Test recording mixed (un)timestamped packets fails.""" lidar_ts_packets = fake_packets(fake_meta, n_lidar=n_lidar_timestamp, timestamped=True) lidar_no_ts_packets = fake_packets(fake_meta, n_lidar=n_lidar_no_timestamp, timestamped=False) imu_ts_packets = fake_packets(fake_meta, n_imu=n_imu_timestamp, timestamped=True) imu_no_ts_packets = fake_packets(fake_meta, n_imu=n_imu_no_timestamp, timestamped=False) in_packets: List[client.Packet] = list( chain(lidar_ts_packets, lidar_no_ts_packets, imu_ts_packets, imu_no_ts_packets)) shuffle(in_packets) file_path = path.join(tmpdir, "pcap_test.pcap") yes_timestamps = n_lidar_timestamp + n_imu_timestamp no_timestamps = n_lidar_no_timestamp + n_imu_no_timestamp if yes_timestamps > 0 and no_timestamps > 0: with pytest.raises(ValueError): pcap.record(in_packets, file_path) else: pcap.record(in_packets, file_path)
def test_write_nonsensical_packet_type(metadata, tmpdir): file_path = os.path.join(tmpdir, "pcap_test.pcap") in_packets = [42] with pytest.raises(ValueError): pcap.record(in_packets, file_path) assert not os.path.exists(file_path), "Didn't clean up empty file"
def fake_pcap_path(lidar_imu_frac: float, fake_meta: client.SensorInfo, n_packets: int, use_sll: bool, tmpdir: str) -> str: file_path = path.join(tmpdir, "pcap_test.pcap") n_lidar = int(lidar_imu_frac * n_packets) n_imu = n_packets - n_lidar packets = fake_packets(fake_meta, n_lidar, n_imu) pcap.record(packets, file_path, use_sll_encapsulation=use_sll) return file_path
def test_write_nonsensical_packet_type(tmpdir) -> None: """Check that writing nonsense raises an error and cleans up.""" file_path = path.join(tmpdir, "pcap_test.pcap") in_packets = [42] with pytest.raises(ValueError): pcap.record(in_packets, file_path) # type: ignore assert not path.exists(file_path), "Didn't clean up empty file"
def pcap_path(metadata, n_packets, use_sll, tmpdir): file_path = os.path.join(tmpdir, "pcap_test.pcap") packets = islice( roundrobin(random_lidar_packets(metadata), random_imu_packets(metadata)), n_packets) pcap.record(packets, file_path, use_sll_encapsulation=use_sll) yield file_path
def test_read_write_lidar_imu(n_lidar, n_imu, fake_meta, tmpdir) -> None: """Test that random packets read back from pcap are identical.""" in_packets = list(fake_packets(fake_meta, n_lidar, n_imu)) file_path = path.join(tmpdir, "pcap_test.pcap") pcap.record(in_packets, file_path) out_packets = list(pcap.Pcap(file_path, fake_meta)) out_bufs = [bytes(p._data) for p in out_packets] in_bufs = [bytes(p._data) for p in in_packets] assert in_bufs == out_bufs
def test_timestamp_read_write(fake_meta, tmpdir) -> None: """Check that timestamps are preserved by a round trip.""" in_packets = list( fake_packets(fake_meta, n_lidar=10, n_imu=10, timestamped=True)) file_path = path.join(tmpdir, "pcap_test.pcap") pcap.record(in_packets, file_path) out_packets = list(pcap.Pcap(file_path, fake_meta)) out_timestamps = [p.capture_timestamp for p in out_packets] in_timestamps = [p.capture_timestamp for p in in_packets] assert len(in_timestamps) == len(out_timestamps) assert in_timestamps == pytest.approx(out_timestamps)
def test_read_write_lidar_imu(n_lidar, n_imu, metadata, tmpdir): """Test that random packets read back from pcap are identical.""" lidar_packets = islice(random_lidar_packets(metadata), n_lidar) imu_packets = islice(random_imu_packets(metadata), n_imu) in_packets = list(chain(lidar_packets, imu_packets)) shuffle(in_packets) file_path = os.path.join(tmpdir, "pcap_test.pcap") pcap.record(in_packets, file_path) out_packets = list(pcap.Pcap(file_path, metadata)) out_bufs = [bytes(p._data) for p in out_packets] in_bufs = [bytes(p._data) for p in in_packets] assert in_bufs == out_bufs
def test_no_timestamp_read_write(fake_meta, tmpdir) -> None: """Check that capture timestamps are set when recording.""" in_packets = list( fake_packets(fake_meta, n_lidar=10, n_imu=10, timestamped=False)) file_path = path.join(tmpdir, "pcap_test.pcap") current_timestamp = time.time() pcap.record(in_packets, file_path) out_packets = list(pcap.Pcap(file_path, fake_meta)) out_timestamps = [p.capture_timestamp for p in out_packets] in_timestamps = [p.capture_timestamp for p in in_packets] assert len(in_timestamps) == len(out_timestamps) assert all(ts is None for ts in in_timestamps) assert all(ts == pytest.approx(current_timestamp, abs=1.0) for ts in out_timestamps)
def test_timestamp_float_read_write(mode, metadata, tmpdir): lidar_packets = islice(random_lidar_packets(metadata, random_time=mode), 10) imu_packets = islice(random_imu_packets(metadata, random_time=mode), 10) in_packets = list(chain(lidar_packets, imu_packets)) file_path = os.path.join(tmpdir, "pcap_test.pcap") pcap.record(in_packets, file_path) out_packets = list(pcap.Pcap(file_path, metadata)) out_timestamps = [] in_timestamps = [] out_timestamps = [p.capture_timestamp for p in out_packets] in_timestamps = [p.capture_timestamp for p in in_packets] assert len(in_timestamps) == len(out_timestamps) for i, o in zip(in_timestamps, out_timestamps): # Make sure to deal with float rounding issues in the compare assert i == pytest.approx(o, abs=1e-6)
def test_no_timestamp_read_write(metadata, tmpdir): mode = NO_RANDOM_TIME current_timestamp = time.time() lidar_packets = islice(random_lidar_packets(metadata, random_time=mode), 10) imu_packets = islice(random_imu_packets(metadata, random_time=mode), 10) in_packets = list(chain(lidar_packets, imu_packets)) file_path = os.path.join(tmpdir, "pcap_test.pcap") pcap.record(in_packets, file_path) out_packets = list(pcap.Pcap(file_path, metadata)) out_timestamps = [] in_timestamps = [] out_timestamps = [p.capture_timestamp for p in out_packets] in_timestamps = [p.capture_timestamp for p in in_packets] assert len(in_timestamps) == len(out_timestamps) for i, o in zip(in_timestamps, out_timestamps): assert i is None assert current_timestamp == pytest.approx(o, abs=5e-1)
def record_pcap(hostname: str, lidar_port: int = 7502, imu_port: int = 7503, n_seconds: int = 10) -> None: """Record data from live sensor to pcap file. Note that pcap files recorded this way only preserve the UDP data stream and not networking information, unlike capturing packets directly from a network interface with tools like tcpdump or wireshark. See the API docs of :py:func:`.pcap.record` for additional options for writing pcap files. Args: hostname: hostname of the sensor lidar_port: UDP port to listen on for lidar data imu_port: UDP port to listen on for imu data n_seconds: max seconds of time to record. (Ctrl-Z correctly closes streams) """ import ouster.pcap as pcap from datetime import datetime # [doc-stag-pcap-record] from more_itertools import time_limited # connect to sensor and record lidar/imu packets with closing(client.Sensor(hostname, lidar_port, imu_port, buf_size=640)) as source: # make a descriptive filename for metadata/pcap files time_part = datetime.now().strftime("%Y%m%d_%H%M%S") meta = source.metadata fname_base = f"{meta.prod_line}_{meta.sn}_{meta.mode}_{time_part}" print(f"Saving sensor metadata to: {fname_base}.json") source.write_metadata(f"{fname_base}.json") print(f"Writing to: {fname_base}.pcap (Ctrl-C to stop early)") source_it = time_limited(n_seconds, source) n_packets = pcap.record(source_it, f"{fname_base}.pcap") print(f"Captured {n_packets} packets")