Visualize dive log data in Foxglove - Blueye SDK

Skip to content

# Visualize dive log sensor data with Foxglove

With some simple steps you can visualize dive log data with ease in Foxglove. This is a great tool to play back and visualize control signals and estimated states and other sensor data from the dive.

1. Download foxglove here and create an account.
2. Download a divelog from the drone as shown here.
3. Run `pip install "blueye.sdk[examples]"` to get the necessary dependencies, if you have not done so already.
4. Clone the blueye.sdk repository to get the examples, or copy the script below into a file. In the examples folder you simply run `python foxglove_bez_to_mcap.py <logfile.bez> [output_filename.mcap]` to convert your .bez-file.
5. Open foxglove, in the top left menu, click on `Open local file`, and pick your newly created .mcap-file.
6. Click on `Add panel`, and `Raw message`, or `Plot` and select the signal you want to display.
7. Start typing `DepthTel.depth.value` to get auto-complete on all available messages in the protocol.
8. You can also get a nice overview of the logged messages with this command: `mcap info logfile.mcap` in your terminal.

### The .bez to .mcap log file converter:

    import os
    import time
    from mcap_protobuf.writer import Writer
    import sys
    from blueye.sdk.logs import LogStream
    from pathlib import Path

    def parse_logfile(log: Path) -> LogStream:
        log_bytes = b""
        with open(log, "rb") as f:
            log_bytes = f.read()
        return LogStream(log_bytes)

    def main(logfile_path, output_mcap_path):
        start_time_tic = time.time()
        print(f"Converting {logfile_path} to {output_mcap_path}...")

        # Prepare MCAP writer
        with open(output_mcap_path, "wb") as mcap_file:
            writer = Writer(mcap_file)

            # Read messages from the log file, deserialize, and forward the protobuf object to the MCAP file.
            path = Path(logfile_path)

            # We need to get the last message's timestamp and delta in order to get the correct start time
            # after the clock is set. The delta time is then added to the start time to get a continuous timeline in foxglove.
            last_time = 0
            last_delta = 0
            for last_time, last_delta, _, _ in parse_logfile(path):
                continue

            start_time = last_time - last_delta

            count = 0
            for unix_ts, delta, msg_type, msg in parse_logfile(path):
                writer.write_message(
                    topic=msg_type.__name__,
                    message=msg._pb,
                    log_time=int((start_time + delta).timestamp() * 1e9),
                    publish_time=int((start_time + delta).timestamp() * 1e9),
                )
                count += 1

            # Add indexes to the MCAP file
            writer.finish()

            print(f"MCAP file successfully created!")
            print(
                f"Total of messages written: {count} in {round(time.time() - start_time_tic, 3)} seconds"
            )
            print(f"MCAP file name: {output_mcap_path}")
            print(f"MCAP file size: {round(os.path.getsize(output_mcap_path)/1000000, 2)} MB")
            print(f"Start of dive time: {unix_ts - delta}")
            print(f"Duration of dive log: {delta}")

    if __name__ == "__main__":
        if len(sys.argv) < 2:
            print("Usage: python bez_to_mcap.py <logfile.bez> [output_filename.mcap]")
            sys.exit(1)
        logfile = sys.argv[1]
        output = sys.argv[2] if len(sys.argv) > 2 else sys.argv[1].replace(".bez", ".mcap")
        main(logfile, output)