Custom

Foxglove Studio can load your custom data (i.e. Protobuf, JSON, FlatBuffers) as local or remote MCAP files. It can also connect directly to your live custom data with the Foxglove WebSocket, an encoding-agnostic WebSocket connection.

Files

Load custom data into Foxglove Studio by first encoding it in MCAP (.mcap) files.

MCAP supports the following serialization formats:

Please get in touch if there are other data formats that your team would like to see supported.

Use the guides at mcap.dev to learn how to read and write your custom data to and from MCAP files.

Local file

Once you have your local MCAP file, follow the MCAP directions for loading it in Studio.

Cloud data

Foxglove Data Platform

Once you've recorded your custom data to MCAP (.mcap) files, you can upload them to Foxglove Data Platform's web console and stream them directly into Foxglove Studio.

Check out the Data Platform docs for more information on how to export and visualize your robotics data.

By URL

Once you have an MCAP file in remote storage, follow the MCAP directions for opening it via URL in Studio.

Check out the Setting up CORS page for more details on loading your remote data files into Foxglove Studio.

Live connection

Connect directly to your live custom data (i.e. Protobuf, JSON, FlatBuffers) with an encoding-agnostic WebSocket connection.

Foxglove WebSocket

First, you'll need to create your own server to start publishing your custom data.

The foxglove/ws-protocol repo provides:

The @foxglove/ws-protocol-examples npm package also provides example servers and clients that you can run to see how Studio can receive system stats and image data from a custom WebSocket server:

$ npx @foxglove/ws-protocol-examples sysmon
$ npx @foxglove/ws-protocol-examples image-server

To learn more, reference the protocol specification.

Connecting to data

Open connection in the Data source dialog, select Foxglove WebSocket, and enter the URL to your WebSocket server:

Foxglove WebSocket dialog

Schema encodings

Both MCAP-based and Foxglove WebSocket sources support several message and schema encodings.

JSON

For JSON data, use schema encoding "jsonschema" and message encoding "json" for MCAP files, or "encoding": "json" for Foxglove WebSocket connections.

Schemas are required, and must be a JSON Schema definition with "type": "object".

Each message should be UTF8-encoded JSON representing an object. Binary data should be represented as a base64-encoded string in the JSON object, and should use "contentEncoding": "base64" (e.g. { "type": "string", "contentEncoding": "base64" }) in the schema.

Protobuf

For Protobuf data, use schema encoding "protobuf" and message encoding "protobuf" for MCAP files, or "encoding": "protobuf" for Foxglove WebSocket connections.

Studio expects the schema data to be a binary FileDescriptorSet. For Foxglove WebSocket connections, the schema must additionally be base64-encoded because it is represented as a string.

You can generate the FileDescriptorSet at runtime using Python:

from typing import Any, Set
from google.protobuf.descriptor import FileDescriptor
from google.protobuf.descriptor_pb2 import FileDescriptorSet

def build_file_descriptor_set(message_class: Any) -> FileDescriptorSet:
  file_descriptor_set = FileDescriptorSet()
  seen_dependencies: Set[str] = set()

  def append_file_descriptor(file_descriptor: FileDescriptor):
    for dep in file_descriptor.dependencies:
      if dep.name not in seen_dependencies:
        seen_dependencies.add(dep.name)
        append_file_descriptor(dep)
    file_descriptor.CopyToProto(file_descriptor_set.file.add())

  append_file_descriptor(message_class.DESCRIPTOR.file)
  return file_descriptor_set

Or C++:

#include <google/protobuf/descriptor.pb.h>

// Writes the FileDescriptor of this descriptor and all transitive dependencies
// to a string, for use as a channel schema.
std::string SerializeFdSet(const google::protobuf::Descriptor* toplevelDescriptor) {
  google::protobuf::FileDescriptorSet fdSet;
  std::queue<const google::protobuf::FileDescriptor*> toAdd;
  toAdd.push(toplevelDescriptor->file());
  std::unordered_set<std::string> added;
  while (!toAdd.empty()) {
    const google::protobuf::FileDescriptor* next = toAdd.front();
    toAdd.pop();
    next->CopyTo(fdSet.add_file());
    added.insert(next->name());
    for (int i = 0; i < next->dependency_count(); ++i) {
      const auto& dep = next->dependency(i);
      if (added.find(dep->name()) == added.end()) {
        toAdd.push(dep);
      }
    }
  }
  return fdSet.SerializeAsString();
}

Studio also expects schemaName to be one of the message types defined in the FileDescriptorSet.

Each message should be encoded in the Protobuf binary wire format – we provide .proto files compatible with Foxglove Studio in our foxglove/schemas repo.

FlatBuffers

For FlatBuffer data, use schema encoding "flatbuffer" and message encoding "flatbuffer" for MCAP files, or "encoding": "flatbuffer" for Foxglove WebSocket connections.

Studio expects the schema data to be a binary-encoded FlatBuffers schema (.bfbs) file, compiled from the source FlatBuffers schema (.fbs) file. For Foxglove WebSocket connections, the schema must additionally be base64-encoded because it is represented as a string. Use the FlatBuffers schema compiler to generate the .bfbs files:

$ flatc --schema -b -o <PATH_TO_BFBS_OUTPUT_DIR> <PATH_TO_FBS_INPUT_DIR>

We provide .fbs files compatible with Foxglove Studio in our foxglove/schemas repo.

Check out this example that uses Foxglove schemas to write FlatBuffers-encoded data to an MCAP file for more details.

ROS 1 and ROS 2

For ROS 1 data, use schema encoding "ros1msg" and message encoding "ros1" for MCAP files, or "encoding": "ros1" for Foxglove WebSocket connections.

For ROS 2 data, use schema encoding "ros2msg" and message encoding "cdr" for MCAP files, or "encoding": "cdr" for Foxglove WebSocket connections.

Studio expects the schema data to be a concatenation of the referenced .msg file and its dependencies. For more information about the concatenated format, see the MCAP specification appendix.