Source code for ouster.sdk.open_source

from typing import List, Optional, Union, Callable, Dict
import os
from ouster.sdk.core import FrameSetSource, PacketSource, OusterIoType, io_type
from ouster.sdk.osf import OsfFrameSetSource
from ouster.sdk.bag import BagFrameSetSource, BagPacketSource
from ouster.sdk._bindings.client import open_source as _open_source
from ouster.sdk._bindings.client import collate as _collate
from ouster.sdk._bindings.client import open_packet_source as _open_packet_source
from functools import partial


def _url_to_osf_url(url: str):
    if "http://studio.ouster.com" in url or "https://studio.ouster.com" in url:
        from ouster.sdk.util import studio
        new_url = studio.get_osf_from_data_app_link(url)
        assert new_url is not None
        return new_url
    else:
        return url


def _python_source_wrapper(ty: type, ioty: OusterIoType, source_url: Union[str, List[str]], collate: bool,
                           sensor_idx: int, *args, **kwargs) -> FrameSetSource:
    # handle multiple files
    src: FrameSetSource
    is_collated = False
    if ioty == OusterIoType.URL:
        # try and get the real url
        if isinstance(source_url, list):
            first_url = source_url[0]
        else:
            first_url = source_url
        new_url = _url_to_osf_url(first_url)
        src = OsfFrameSetSource(new_url)
        is_collated = src.is_collated
    else:
        if type(source_url) is list and len(source_url) > 1:
            for name in source_url:
                if io_type(name) != ioty:
                    raise RuntimeError("All sources must have the same type.")
        src = ty(source_url, *args, **kwargs)
    if sensor_idx >= 0:
        src = src.single(sensor_idx)
    elif collate and not is_collated:
        src = _collate(src)
    return src


io_type_handlers = {
    OusterIoType.BAG: partial(_python_source_wrapper, BagFrameSetSource, OusterIoType.BAG),
    OusterIoType.MCAP: partial(_python_source_wrapper, BagFrameSetSource, OusterIoType.MCAP),
    OusterIoType.URL: partial(_python_source_wrapper, type(None), OusterIoType.URL)
}

packet_io_type_handlers: Dict[OusterIoType, Callable[..., PacketSource]] = {
    OusterIoType.BAG: BagPacketSource,
    OusterIoType.MCAP: BagPacketSource,
}


[docs] class SourceURLException(Exception): def __init__(self, sub_exception, url, packet = False): self._sub_exception = sub_exception self._url = url self._packet = packet def __str__(self): if self._packet: result = f"Failed to create packet_source for url {self._url}\n" else: result = f"Failed to create frame_set_source for URL {self._url}\n" result += f"more details: {self._sub_exception}" return result
[docs] def get_sub_exception(self): return self._sub_exception
[docs] def get_url(self): return self._url
[docs] def open_source(source_url: Union[str, List[str]], collate: bool = True, sensor_idx: int = -1, *args, **kwargs) -> FrameSetSource: """Open a frame set source from one or more URLs. Args: source_url: A single URL or a list of URLs. Each URL can be a path to a pcap or osf file, or a sensor hostname/IP address. collate: If True, collate the source. sensor_idx: If >= 0, only output data from that specific sensor. extrinsic_file: Path to an extrinsics file. extrinsics: A single 4x4 numpy array or a list of 4x4 numpy arrays. When a single array is given and the frame set source has more than one sensor, the same extrinsics are applied to all sensors. Extra entries beyond the number of sensors are discarded. index: Index the source before starting if the format does not natively support indexing. Does not apply to live sources. """ if len(source_url) == 0: raise ValueError("No valid source specified") if type(source_url) is list: source_url = [os.path.expanduser(url) for url in source_url] else: source_url = os.path.expanduser(source_url) # type: ignore first_url: str first_url = source_url[0] if type(source_url) is list else source_url # type: ignore source_type: OusterIoType frame_set_source: Optional[FrameSetSource] = None try: source_type = io_type(first_url) handler = _open_source if source_type in io_type_handlers: handler = io_type_handlers[source_type] frame_set_source = handler(source_url, collate=collate, sensor_idx=sensor_idx, *args, **kwargs) # type: ignore except Exception as ex: raise SourceURLException(ex, source_url if type(source_url) is list else [source_url], False) # type: ignore if frame_set_source is None: raise RuntimeError( f"Failed to create frame_set_source for URL {source_url}") return frame_set_source
[docs] def open_packet_source(source_url: Union[str, List[str]], *args, **kwargs) -> PacketSource: """Open a packet source from one or more URLs. Args: source_url: A single URL or a list of URLs. Each URL can be a path to a pcap or osf file, or a sensor hostname/IP address. extrinsics_file: Path to an extrinsics file. extrinsics: A single 4x4 numpy array or a list of 4x4 numpy arrays. When a single array is given and the frame set source has more than one sensor, the same extrinsics are applied to all sensors. Extra entries beyond the number of sensors are discarded. index: Index the source before starting if the format does not natively support indexing. Does not apply to live sources. """ if len(source_url) == 0: raise ValueError("No valid source specified") if type(source_url) is list: source_url = [os.path.expanduser(url) for url in source_url] else: source_url = os.path.expanduser(source_url) # type: ignore first_url: str first_url = source_url[0] if type(source_url) is list else source_url # type: ignore source_type: OusterIoType frame_set_source: Optional[PacketSource] = None try: source_type = io_type(first_url) handler = _open_packet_source if source_type in io_type_handlers: handler = packet_io_type_handlers[source_type] frame_set_source = handler(source_url, *args, **kwargs) except Exception as ex: raise SourceURLException(ex, source_url if type(source_url) is list else [source_url], True) # type: ignore if frame_set_source is None: raise RuntimeError( f"Failed to create packet_source for url {source_url}") return frame_set_source