# Foxglove Documentation (Full) > This file contains the complete Foxglove product documentation for LLM consumption. > For a concise overview, see llms.txt > For REST API reference, see /api/llms.txt and /api/llms-full.txt Base URL: https://docs.foxglove.dev --- # Overview > Introduction and getting started ## Foxglove Documentation **URL**: /docs **Description**: Foxglove is a purpose-built platform that empowers robotics teams to visually debug robots, build reliable autonomy, and scale their development. Foxglove is a platform to record, upload, organize, and visualize multimodal log data such as time series, text logs, video, 3D, maps, and more. It is most often used in hardware, robotics, and physical AI. ![Foxglove Visualization](/img/docs/introduction/hero@2x.webp) ## Foxglove components Foxglove provides a collection of tools that together support the entire data lifecycle for robotics teams. | Component | What it is | Where it runs | How to access it | | --- | --- | --- | --- | | **Foxglove app** | The main app through which Foxglove functionality can be accessed: visualization and debugging (panels, layouts, and playback), data organization, search, settings, and more. | In a desktop app or in the browser | | | **[Data Platform](/docs/data)** | Hosted storage, indexing, and search for your robotics data — recordings, devices, and events. This is the backbone of all collaboration, organization, and search functionality in Foxglove. |

Runs on [Primary Sites](/docs/data/primary-sites), available in multiple flavors:

| | | **The software that runs on robots** | | Your robots, though SDK code can also run on your local machine | | ## Workflows Foxglove supports all aspects of the multimodal data lifecycle: **Record** - Record logs in the open source [MCAP](https://mcap.dev/) file format using the [SDK](/docs/sdk) (C++, Python, and Rust) **Ingest** - Automatically upload recorded files (ROS 1 bag and MCAP) through [Foxlet](/docs/fleet/foxlet) running on your robot - [Import](/docs/data/importing-data) recordings into the Data Platform using the Foxglove app **Organize** - Index imported [data recordings](/docs/data/recordings) by device, time, and topic - Annotate logs with [metadata and events](/docs/data/events) for easier search and discovery - [Search](/docs/data/search) for interesting moments across all your recordings - Share recordings with team members to triage incidents and analyze the root cause of an issue **Visualize** - Connect to [live](/docs/visualization/connecting/live) robot data to visualize or [teleoperate](/docs/visualization/panels/teleop) using the Foxglove app - Open a variety of [supported formats](/docs/visualization/connecting/local-data#supported-formats) (MCAP, ROS Bag, ULog, etc) locally using the Foxglove app - Visualize [recordings in the cloud](/docs/visualization/connecting/cloud-data), from your organization's Data Platform or remote HTTP servers - Configure [panels](/docs/visualization/panels) to understand how your robots sense, think, and act - Create shared [layouts](/docs/visualization/layouts) to tackle repeated visualization and debugging tasks **Integrate** - Configure [webhooks](/docs/webhooks) to react to data updates such as a new recording, event creation, or device update - Chart telemetry from your recordings on [Grafana](/docs/grafana) dashboards - Automate aspects of your data pipeline using the [API](/api) and [CLI](/docs/cli) ## Command palette The command palette provides quick access to actions and navigation across the app. Open it with `Ctrl` + `K` (Windows and Linux) or `Cmd` + `K` (macOS) to search for commands by name or keyword. Use the command palette to: - **Open data sources** — Open local files, compare local files, start a live connection, or open a recording - **Compare sources** — Add a comparison source, switch merge/compare, adjust offsets, or remove a source - **Navigate** — Jump to pages like the dashboard, settings, devices, recordings, events, or timeline - **Switch layouts** — Browse and switch between recent, personal, and organization layouts - **Access help** — Open the documentation, view version info, or launch the getting started guide Start typing to filter the list. Some commands have sub-menus that expand when selected. For example, selecting "Change layout" drills down into a searchable list of available layouts. Use the mouse or arrow keys to navigate, click a list entry or press `Enter` to select, and `Esc` or click outside the list to close the palette. Available commands are context-aware, meaning some only appear on certain pages. ## Links and resources - [Create a free account](https://app.foxglove.dev/signup) - [Download the desktop app](https://foxglove.dev/download) (for Linux, Windows, and macOS) - [Browse tutorials](https://foxglove.dev/blog?topic=tutorial) --- ## Settings **URL**: /docs/settings **Description**: Use the Settings page to configure preferred time zone, timestamp format, and more. Additionally, admins can modify the subscription plan, invite and manage organization members, and configure organization-wide settings like sites and custom device properties. ## User settings Use the [Settings page](https://app.foxglove.dev/~/settings/user/general) page to configure your preferred time zone, timestamp format, and more. ### General | field | description | | --- | --- | | **Color scheme** | Choose between light or dark mode, or follow your OS settings | | **Timestamp format** | Formatting used to display timestamps (12-hour, 24-hour, RFC 3339, or seconds) | | **Language** | App language | | **Open links in** (Web app only) | Choose whether [shareable links](/docs/visualization/shareable-links) are opened in the web app or desktop app | ### Time zone Visit the [Dashboard](https://app.foxglove.dev/~/dashboard) and use the dropdown menu in the top bar to change the time zone used for displaying timestamps. ![time zone menu](/img/docs/visualization/timezone-menu@2x.webp) If your organization admin has set an organization [default time zone](#org-general), it appears at the top of the menu as **Organization default: ``** and applies to anyone who hasn't picked their own. Selecting **Detected** or any other zone overrides the org default for your account; selecting **Organization default** at any time switches you back to following it. ### Extensions Visit the [Extensions](https://app.foxglove.dev/~/settings/user/extensions) settings page to select the [Foxglove extensions](/docs/extensions) you want to install locally. :::note Administrators can also [publish extensions](#extensions-1) to all users of their organization. ::: Each row has an **Enabled** toggle that turns the extension off for you on this device, hiding its contributions from your session. The setting is saved in your browser and does not sync across devices. The toggle is only available on developer seats. If you are switched to a basic seat, your disabled selections are preserved but ignored — org extensions activate normally — and they re-engage if you are upgraded back to developer. ### Connected accounts Visit the [Connected accounts](https://app.foxglove.dev/~/settings/user/connected-accounts) settings page to link or disconnect external accounts. Link your Slack account to use the [Slack integration](/docs/agents/slack). ### Desktop app In the desktop app, visit _Settings > Desktop_ to configure the following settings: | field | description | | --- | --- | | **Automatically install updates** | Whether the app should automatically check for and install updates (macOS and Windows only) | | [**ROS_PACKAGE_PATH**](https://wiki.ros.org/ROS/EnvironmentVariables#ROS_PACKAGE_PATH) | Paths to search for ROS packages (local file paths or `package://` URLs); separate paths with standard OS path separator (e.g. ':' on Unix).
_Example_: `/path/to/workspace/src:/opt/ros/noetic/share`
_Note_: The `ROS_PACKAGE_PATH` environment variable will also be used. | ### Standalone license If your desktop installation uses standalone mode, see [Standalone license activation](/docs/standalone-license) for setup and activation instructions. ## Organization settings Admins can use the [Organization settings](https://app.foxglove.dev/~/settings/general) to modify the subscription plan, invite and manage organization members, and configure organization-wide settings like sites and custom device properties. ### General {#org-general} On the [General settings page](https://app.foxglove.dev/~/settings/general), admins can: - **Organization name** – Edit the organization name - **Default time zone** – Set the time zone used to render timestamps for organization members who haven't picked their own. Members can still override it from their personal [Time zone](#time-zone) menu; the override persists across sessions. - **Subscription** – View and modify plan details - **Approved domains** – New users signing in with email addresses from these domains are automatically added to the organization - **Usage** – Shows data storage usage - **Danger zone** – Delete the organization ### Members On the [Members settings page](https://app.foxglove.dev/~/settings/members), admins can: - View a list of all organization members (name, email address, last seen, [role](/docs/security/roles), [seat type](/docs/security/seat-types)) - Invite or remove organization members - Modify organization members' roles ("admin", "user") - Change a member's [seat type](/docs/security/seat-types) ("developer", "basic") :::note All organization members of Free plan organizations have the admin role. ::: ### Projects On the [Projects settings page](https://app.foxglove.dev/~/settings/projects), admins can: - Create new [Projects](/docs/projects) - Manage Project access - Rename and delete Projects ### Sites On the [Sites settings page](https://app.foxglove.dev/~/settings/sites), admins can: - Look up the status, name, and ID of their Foxglove- and self-hosted [Primary Sites](/docs/data/primary-sites) - Look up the status, name, and ID of their on-premises [Edge Sites](/docs/data/edge-sites) - Add Foxglove-hosted Primary Sites - Add Edge Sites ### Devices On the [Devices settings page](https://app.foxglove.dev/~/settings/devices), admins can set predefined metadata fields (i.e. [properties](/docs/data/devices#properties)) for the whole organization to associate with their devices. ### API keys On the [API keys settings page](https://app.foxglove.dev/~/settings/apikeys), admins can: - Generate API keys for accessing the [Foxglove API](/api) - Enable, disable, or permanently delete generated API keys - Configure the API key's capabilities per data resource (e.g. read-only for devices, read and write for recordings, etc.) ### Audit logs On the [Audit logs settings page](https://app.foxglove.dev/~/settings/audit-logs), Enterprise organization admins can review organization activity. The feed shows who performed an action, what they did, and when. See [Audit logs](/docs/audit-logs) for details. ### SSO On the [SSO settings page](https://app.foxglove.dev/~/settings/sso), admins can configure Okta SSO OIDC settings like the Okta domain, client ID, and more. Foxglove currently supports both [Microsoft](https://foxglove.dev/blog/announcing-microsoft-sign-in) and [Okta SSO](/docs/security/sso). ### Search On the [Search settings page](https://app.foxglove.dev/~/settings/search), admins can manage how [visual search](/docs/data/search#visual-search) indexing is configured. They can: - Manage which projects have visual search indexing enabled - Configure which topics are indexed for newly uploaded recordings - See the time range of recording data that has been indexed ### Webhooks On the [Webhooks settings page](https://app.foxglove.dev/~/settings/webhooks), admins can manage [Webhooks](/docs/webhooks) to subscribe to notifications about events that occur within Foxglove. ### Slack On the [Slack settings page](https://app.foxglove.dev/~/settings/slack), admins can add [Foxglove to their Slack workspace](/docs/agents/slack). Once it's installed, anyone in the workspace can ask Foxglove about their organization's data. ### Extensions On the [Extensions settings page](https://app.foxglove.dev/~/settings/extensions), admins can install Foxglove [extensions](/docs/extensions) across the organization to better support the team's unique workflows. Enabled extensions are automatically installed for all signed-in organization members. Use the `foxglove` CLI to [write](/docs/extensions#writing-an-extension) and [publish](/docs/extensions/publish) Foxglove extensions. ### Insights On the [Insights settings page](https://app.foxglove.dev/~/settings/insights), admins can understand how their team members are leveraging the platform. #### Import volume Track the net and cumulative volume of data your Foxglove organization has imported week-over-week: ![imports](/img/docs/organization-setup/insights/imports@2x.webp) Understand your team's data storage bill, whether you are nearing your plan's data limit, and the time periods during which the team imported the most data. --- ## Standalone License Activation **URL**: /docs/standalone-license **Description**: Activate Foxglove desktop in standalone mode for offline and air-gapped environments. Use standalone mode to run Foxglove desktop with a standalone license instead of signing in with an account. ## Before you begin Standalone mode is intended for offline and air-gapped workflows. In standalone mode: - Cloud-based pages and features are unavailable - Users do not sign in with an account - Users cannot sign out to switch accounts - [Preloaded layouts and extensions](#preload-layouts-and-extensions-optional) can be used but cannot be modified or removed To show the **Activate License** link on the welcome page, create a `standalone` folder in your Foxglove app data directory. After you create the folder, start Foxglove desktop and select **Activate License** on the welcome page. ## Activate online Use this flow when the machine can reach the internet. 1. Open **Activate License** from the welcome page. 2. Enter your license key. 3. Select **Activate**. ## Activate offline Use this flow for offline or air-gapped machines. 1. On the offline machine, open **Activate License**. 2. Select **use offline activation**. 3. Enter your license key and select **Generate .req file**. 4. Transfer the generated `.req` file to an online machine. 5. On the online machine, open [licensing.foxglove.dev](https://licensing.foxglove.dev/). 6. Upload the `.req` file and download the generated `.lic` file. 7. Transfer the `.lic` file back to the offline machine. 8. Using Foxglove on the offline machine, select **Import .lic file** and choose the `.lic` file. ## Preload layouts and extensions (optional) You can pre-configure standalone installations by placing files in subdirectories under `standalone`: ```text .../Foxglove/ └── standalone/ ├── layouts/ │ └── My Layout.json └── extensions/ └── mycompany.example-extension-1.0.0.foxe ``` - Put exported layout `.json` files in `standalone/layouts/` - Put extension `.foxe` files in `standalone/extensions/` Foxglove loads these files when a valid standalone license is active. ## Need help? Contact [support@foxglove.dev](mailto:support@foxglove.dev). --- ## Pricing **URL**: /docs/pricing **Description**: Foxglove offers Free, Pro, and Enterprise plans to fit teams of every size. Compare features, usage limits, and find the right plan for your workflow. Foxglove offers pricing plans for teams of any size, from individual developers to large organizations. Visit our [Pricing](https://foxglove.dev/pricing) page for an overview of the available plans. ## Managing your plan Organization admins can view and modify your plan from the [Billing settings](https://app.foxglove.dev/~/settings/billing) page. ## Tiered pricing Each plan includes a set amount of managed infrastructure, users, and devices. On Pro and Enterprise plans, additional usage is billed according to the marginal pricing tiers below. On Free and Academic plans, included usage is a hard limit. Prepaid committed-use credits are available on the Enterprise plan. To learn more, please [contact sales](https://foxglove.dev/contact?reason=sales). ## Data platform ### Included usage | Dimension | **Free** | **Pro / Enterprise** | **Academic** | | ------------- | --------- | -------------------- | ------------ | | **Storage** | 10 GB | 1 TB | 1 TB | | **Query** | 1 hour/mo | 1 hour/mo | 10 hours/mo | | **Indexing** | 100 GB/mo | 1 TB/mo | 1 TB/mo | | **Bandwidth** | 100 GB/mo | 100 GB/mo | 1 TB/mo | ### Storage Storage is priced per TB-month, calculated based on your average hourly data during the billing period. | Range | Rate | | ------------- | --------- | | First 1 TB | Included | | 1 - 10 TB | $50/TB/mo | | 10 - 100 TB | $40/TB/mo | | 100 TB - 1 PB | $30/TB/mo | | 1+ PB | $26/TB/mo | ### Query Query is calculated as the sum of execution time for all search, stream, and visualization data requests. | Range | Rate | | ---------------- | ---------- | | First 1 hour | Included | | 1 - 10 hours | $3.65/hour | | 10 - 100 hours | $2.75/hour | | 100 - 500 hours | $2.35/hour | | 500 - 1000 hours | $2.15/hour | | 1000+ hours | $2.05/hour | ### Indexing Indexing includes any data uploaded to Foxglove, or data indexed with [BYO Storage](/docs/data/primary-sites#foxglove-cloud-bring-your-own-storage). | Range | Rate | | ------------- | -------- | | First 1 TB | Included | | 1 - 10 TB | $35/TB | | 10 - 100 TB | $28/TB | | 100 TB - 1 PB | $24/TB | | 1+ PB | $22/TB | ### Bandwidth Bandwidth (egress) is charged for all data requests. | Range | Rate | | -------------- | -------- | | First 100 GB | Included | | 100 GB - 10 TB | $150/TB | | 10 - 100 TB | $135/TB | | 100 TB - 1 PB | $125/TB | | 1+ PB | $115/TB | ## Fleet ### Included usage | Dimension | Free | Pro / Enterprise | Academic | | ----------------- | ---- | ----------------- | -------- | | **Devices** | 5 | 5 | 10 | | **Remote access** | — | 300 min/device/mo | — | ### Devices Devices are only charged if they were active during the billing period. Additional devices are charged at $20/device/mo. ### Remote access Each device includes 300 remote access minutes per month (minutes are not pooled across devices). Additional minutes are charged at $0.05/min. ## AI agents ### Included usage Included usage is granted per user and is not pooled across users. | Dimension | **Free** | **Pro / Enterprise** | **Academic** | | ------------ | ---------- | -------------------- | ------------ | | **AI usage** | $5/user/mo | $5/user/mo | $5/user/mo | ### AI usage AI agent usage is measured by the tokens consumed by Large Language Model (LLM) requests, across both the agent sidebar and the Slack integration. When a user reaches their limit, behavior depends on the plan: - **Free and Academic**: included usage is a hard limit. The user is blocked from further AI agent usage until the monthly cycle renews, with no overage billing. - **Pro**: the user keeps working, and the organization is billed in arrears for that user's overage at the rate below. Overage is charged per user, so users still within their allowance are never billed. - **Enterprise**: AI overage is credit-gated rather than billed in arrears. It draws from the organization's prepaid credits, and once those run out, users are blocked until more are added. Usage includes input tokens (prompts and context), output tokens (AI responses), and prompt caching operations. | Range | Rate | | ---------------- | -------------------------- | | First $5/user/mo | Included | | Additional usage | Provider cost + $1.00/MTok | Provider costs vary by model and are passed through at cost. The Foxglove fee is a flat $1.00 per million tokens across all token types. --- ## Projects **URL**: /docs/projects **Description**: Projects are collections of resources within an organization. Projects provide data isolation and access control to collections of resources within an organization. Every [recording](/docs/data/recordings), [device](/docs/data/devices), and [event](/docs/data/events) belongs to one Project. ## What can you do with Projects? Projects enable you to organize data and control access within your organization. - Separate production and development workflows - Organize data by team or customer - Share subsets of data with specific members - Restrict third parties or external contractors to specific data within your Foxglove organization ## Creating a Project Every organization starts with a single shared Project that all members can access. Admins of enterprise organizations can create additional Projects from the [Projects page](https://app.foxglove.dev/~/settings/projects). :::warning Before creating a second Project, ensure all programmatic uploads specify a Project or existing device. See below. ::: ## Access control A Project can either be invite-only or shared. Invite-only Projects require explicit assignments for non-admin members, while shared Projects are available to all members of the organization. Admins can assign members to Projects via the [Members page](https://app.foxglove.dev/~/settings/members) and change the invite-only status of a Project via the [Projects page](https://app.foxglove.dev/~/settings/projects). - Members with the **user** role can only see and access shared Projects and Projects they are assigned to. - Members with the **admin** role can access all Projects. - API Keys can access all Projects. Projects are isolated. Data in one Project cannot be accessed from or moved to another Project. :::note [Pending imports](/docs/data/importing-data#track-pending-imports) not yet associated with a Project are only visible to admins via the [Pending Imports page](https://app.foxglove.party/~/settings/pending-imports). This can happen when uploads don't specify a device or Project ID — for example, at self-hosted sites where metadata isn't included during the upload. To ensure non-admin members can track their imports, always include a device or Project ID. ::: ## Associating data We recommend always providing a Project ID when interacting with Foxglove programmatically. For organizations with multiple Projects, a Project ID is required when creating devices or uploading recordings without an existing device. Project IDs can be found on the [Projects page](https://app.foxglove.dev/~/settings/projects). ### API requests Endpoints that create or list Project scoped resources accept a `projectId` field to specify the Project. See [API docs](/api) for more information. ### Self-hosted Primary Sites Providing a `foxglove_project_id` record in object metadata or a `projectId` in MCAP metadata associates the upload with a Project. See [Site docs](/docs/data/primary-sites/manage-data#adding-metadata-to-imports) for more information. Self-hosted Primary Sites support Projects as of [version 0.0.69](/docs/data/primary-sites/upgrading). ### Web and desktop apps Uploading files and creating devices from the Foxglove dashboard automatically associates them with the current Project. ## Project vs Organization scoped resources Every device, event, and recording belongs to a single Project. Data in one Project cannot be accessed from another Project. Resources at the organization level work across all Projects. | Resource | Project | Organization | | ----------------- | ------- | ------------ | | Devices | ✓ | | | Events | ✓ | | | Recordings | ✓ | | | API Keys | | ✓ | | Custom Properties | | ✓ | | Extensions | | ✓ | | Layouts | | ✓ | | Sites | | ✓ | | Webhooks | | ✓ | --- ## CLI **URL**: /docs/cli **Description**: The foxglove CLI tool helps you import, export, and interact with your data from the command line. The [Foxglove CLI tool](https://github.com/foxglove/foxglove-cli) helps you import, export, and interact with your data from the command line. ### Installation Download the latest release from your command line. | OS | architecture | command | | --- | --- | --- | | linux | | | amd64 | `curl -L https://github.com/foxglove/foxglove-cli/releases/latest/download/foxglove-linux-amd64 -o foxglove && chmod +x foxglove` | | | arm64 | `curl -L https://github.com/foxglove/foxglove-cli/releases/latest/download/foxglove-linux-arm64 -o foxglove && chmod +x foxglove` | | macos | | | any | Using [homebrew](https://brew.sh/): `brew install foxglove-cli` | | | amd64 | `curl -L https://github.com/foxglove/foxglove-cli/releases/latest/download/foxglove-macos-amd64 -o foxglove && chmod +x foxglove` | | | arm64 | `curl -L https://github.com/foxglove/foxglove-cli/releases/latest/download/foxglove-macos-arm64 -o foxglove && chmod +x foxglove` | | windows | | | amd64 | `curl -L https://github.com/foxglove/foxglove-cli/releases/latest/download/foxglove-windows-amd64.exe -o foxglove.exe` | | | arm64 | `curl -L https://github.com/foxglove/foxglove-cli/releases/latest/download/foxglove-windows-arm64.exe -o foxglove.exe` | After downloading the file, you may want to move it to a location in your system's `PATH` to make it more easily executable. To install a specific release, see the [releases page](https://github.com/foxglove/foxglove-cli/releases). ### Getting started Before interacting with your data, you must first authenticate with your [Foxglove account](https://app.foxglove.dev/signup): ```bash foxglove auth login ``` For a list of all available CLI commands: ```bash foxglove -h ``` Enable shell autocompletion for subcommands and parameters (`bash`, `zsh`, `fish`, and `PowerShell` are supported): ```bash foxglove completion -h ``` ### Actions | | Create | List | Delete | | --- | --- | --- | --- | | **Projects** | | `foxglove projects list` | | | **Devices** | `foxglove devices add --name "my device" --project-id prj_abcd1234` | `foxglove devices list` | `foxglove devices delete --name "my device"` | | **Recordings** | `foxglove data import ~/data/bags/gps.bag --device-id dev_drpLqjBZYUzus3gv` | `foxglove recordings list` | | | **Events** | `foxglove events add --device-id dev_flm75pLkfzUBX2DH --timestamp 2022-01-01T12:00:00Z --duration-nanos 0 --metadata 'someKey:someValue'` | `foxglove events list` | | | **Extensions** | `foxglove extensions publish ./my-extension.1.0.0.foxe` | `foxglove extensions list` | `foxglove extensions unpublish ext_BsGXKGsZ9c4WQF1` | ### Visualizing data The Foxglove CLI tool cannot directly open data in the Foxglove app, but the app binary can [accept data source parameters when opened via the command line](/docs/visualization/shareable-links). --- ## Audit logs **URL**: /docs/audit-logs **Description**: Review organization activity from the Audit logs page. Available to org admins on Enterprise plans. Audit logs let organization [admins](/docs/security/roles) review who did what in your Foxglove organization, and when. Use them to investigate unexpected layout changes, track membership and access updates, or confirm whether an action was intentional. :::note Audit logs are available only to organization admins on Enterprise plans. If you don't see **Audit logs** under organization settings, check your [plan](/docs/pricing) or ask an admin. ::: ## Open audit logs 1. Sign in as an organization admin on an Enterprise plan. 2. Open [Settings → Audit logs](https://app.foxglove.dev/~/settings/audit-logs). The page lists recent organization events in reverse chronological order. ## What each event shows Each row includes: | Field | Description | | --------- | ------------------------------------------------------------------------------ | | **Time** | When the event occurred | | **Event** | The action name (for example `layout.delete` or `device.update_remote_access`) | | **Actor** | Who performed the action — an organization member, an API key, or the system | Select a row to open details, including event metadata such as the name of a deleted layout or other action-specific fields. ## Filter events Use the filters at the top of the page to narrow the feed: - **Event** — limit results to a specific action name - **From** / **To** — limit results to a date range ## Examples of recorded activity Audit logs cover a range of organization actions, including: - Layout deletions and restores - Remote Access enable and disable on devices - Member invitations, removals, and seat-type changes - API key create, edit, and delete - Project create, delete, and membership changes - Device edits and device token changes - Recording and import deletions ## Links and resources - [Settings](/docs/settings) - [Roles](/docs/security/roles) - [Pricing](/docs/pricing) --- # Getting Started > Quick start guides by framework ## Python **URL**: /docs/getting-started/python **Description**: Log data from Python into Foxglove Connect directly to Foxglove or play back local data recorded with the Python SDK. ## Install the SDK The SDK is distributed through [PyPI](https://pypi.org/project/foxglove-sdk/). You can get started with a new project or use Foxglove from a [notebook](/docs/notebook). The exact installation will depend on your package manager; here's an example using [uv](https://docs.astral.sh/uv/getting-started/installation/). ```bash uv init example cd example uv add foxglove-sdk ``` ## Live data ### Log messages from Python Edit the generated `main.py`: ```python import foxglove import time foxglove.start_server() while True: foxglove.log("/hello", {"time": time.time()}) time.sleep(0.03) ``` #### Run the script Run the script to start logging. Following the uv example above, you can run the following command from the "example" directory: ```bash uv run python main.py ``` ### Connect In Foxglove, select "Open connection" from the dashboard or left-hand menu. ![Select open connection](/img/docs/getting-started/open-connection@2x.webp) Select "Foxglove WebSocket" in the "Open a new connection" dialog, then click "Open" to accept the default connection string: ![Foxglove WebSocket dialog](/img/docs/getting-started/foxglove-websocket@2x.webp) ## Local data ### Recording data to a file The SDK can also log data to disk. Let's augment the example above to also produce an [MCAP](https://mcap.dev/) file which can later be opened in Foxglove: ```python import foxglove import time foxglove.start_server() # highlight-start # Keep a reference to the mcap. It will automatically close the file when the program exits, but # we could also close it manually with `mcap.close()`. with foxglove.open_mcap("example.mcap"): # highlight-end while True: foxglove.log("/hello", {"time": time.time()}) time.sleep(0.03) ``` ### Viewing data from a file ## Links and resources - [SDK documentation](/docs/sdk?lang=python) with a more detailed [example](/docs/sdk/example?lang=python) - [Jupyter notebook integration](/docs/notebook) - [Python reference](https://foxglove-sdk-api-docs.pages.dev/python) - [Source code](https://github.com/foxglove/foxglove-sdk) with additional examples --- ## Rust **URL**: /docs/getting-started/rust **Description**: Log data from Rust into Foxglove Connect directly to Foxglove or play back local data recorded with the Rust SDK. ## Install the SDK If you want to try Foxglove with a new project, you can use these steps: ```bash cargo new example --bin cd example cargo add foxglove ``` ## Live data ### Log messages from Rust Add the following to `main.rs`: ```rust use std::{thread, time}; #[derive(foxglove::Encode)] struct Message { elapsed: f64, } fn main() { foxglove::WebSocketServer::new() .start_blocking() .expect("Server failed to start"); let start = time::SystemTime::now(); loop { foxglove::log!( "/hello", Message { elapsed: start .elapsed() .expect("clock failed to elapse") .as_secs_f64() } ); thread::sleep(time::Duration::from_millis(30)); } } ``` #### Run the example From the project directory: ```bash cargo run ``` ### Connect In Foxglove, select "Open connection" from the dashboard or left-hand menu. ![Select open connection](/img/docs/getting-started/open-connection@2x.webp) Select "Foxglove WebSocket" in the "Open a new connection" dialog, then click "Open" to accept the default connection string: ![Foxglove WebSocket dialog](/img/docs/getting-started/foxglove-websocket@2x.webp) ## Local data ### Recording data to a file The SDK can also log data to disk. Let's augment the example above to also produce an [MCAP](https://mcap.dev/) file which can later be opened in Foxglove: ```rust //highlight-start use std::{ sync::{ atomic::{AtomicBool, Ordering}, Arc, }, thread, time, }; //highlight-end #[derive(foxglove::Encode)] struct Message { elapsed: f64, } fn main() { foxglove::WebSocketServer::new() .start_blocking() .expect("Server failed to start"); //highlight-start // Keep a reference to the writer. It'll automatically flush and close when it's dropped, // or we could call `.close()` to close it manually. // We use a named variable here to ensure it's dropped only at the end of the scope. let _writer = foxglove::McapWriter::new() .create_new_buffered_file("example.mcap") .expect("Failed to create writer"); // Log until interrupted. We need a ctrlc handler here to ensure // that main() exits cleanly, dropping _writer before ending the process. let done = Arc::new(AtomicBool::default()); ctrlc::set_handler({ let done = done.clone(); move || { done.store(true, Ordering::Relaxed); } }) .expect("Failed to set SIGINT handler"); let start = time::SystemTime::now(); while !done.load(Ordering::Relaxed) { //highlight-end foxglove::log!( "/hello", Message { elapsed: start .elapsed() .expect("clock failed to elapse") .as_secs_f64() } ); thread::sleep(time::Duration::from_millis(30)); } } ``` ### Viewing data from a file ## Links and resources - [SDK documentation](/docs/sdk?lang=rust) with a more detailed [example](/docs/sdk/example?lang=rust) - [Rust reference](https://docs.rs/foxglove/latest/foxglove) - [Source code](https://github.com/foxglove/foxglove-sdk) --- ## C++ **URL**: /docs/getting-started/cpp **Description**: Log data from C++ into Foxglove Connect directly to Foxglove or play back local data recorded with the C++ SDK. ## Install the SDK ## Live data ### Log messages from C++ ```cpp #include #include #include #include #include #include using namespace std::chrono_literals; int main(int argc, const char *argv[]) { foxglove::WebSocketServerOptions options; auto serverResult = foxglove::WebSocketServer::create(std::move(options)); if (!serverResult.has_value()) { std::cerr << foxglove::strerror(serverResult.error()) << '\n'; return 1; } auto server = std::move(serverResult.value()); auto channel = foxglove::RawChannel::create("/hello", "json").value(); auto start = std::chrono::steady_clock::now(); // Log until interrupted static std::function sigint_handler; std::atomic_bool done = false; sigint_handler = [&] { done = true; }; std::signal(SIGINT, [](int) { if (sigint_handler) { sigint_handler(); } }); while (!done) { auto dur = std::chrono::steady_clock::now() - start; float elapsed_seconds = std::chrono::duration(dur).count(); std::string msg = "{\"elapsed\": " + std::to_string(elapsed_seconds) + "}"; channel.log(reinterpret_cast(msg.data()), msg.size()); std::this_thread::sleep_for(33ms); } return 0; } ``` #### Run the example If you're using something like the CMake configuration above, you can create a `build` directory and run the following. ```bash cd build cmake .. cmake --build . ./my_program ``` ### Connect In Foxglove, select "Open connection" from the dashboard or left-hand menu. ![Select open connection](/img/docs/getting-started/open-connection@2x.webp) Select "Foxglove WebSocket" in the "Open a new connection" dialog, then click "Open" to accept the default connection string: ![Foxglove WebSocket dialog](/img/docs/getting-started/foxglove-websocket@2x.webp) ## Local data ### Recording data to a file The SDK can also log data to disk. Let's augment the example above to also produce an [MCAP](https://mcap.dev/) file which can later be opened in Foxglove: ```cpp #include // highlight-start #include // highlight-end #include #include #include #include #include using namespace std::chrono_literals; int main(int argc, const char *argv[]) { foxglove::WebSocketServerOptions options; auto serverResult = foxglove::WebSocketServer::create(std::move(options)); if (!serverResult.has_value()) { std::cerr << foxglove::strerror(serverResult.error()) << '\n'; return 1; } auto server = std::move(serverResult.value()); auto channel = foxglove::RawChannel::create("/hello", "json").value(); auto start = std::chrono::steady_clock::now(); // highlight-start foxglove::McapWriterOptions mcap_options; mcap_options.path = "example.mcap"; auto writerResult = foxglove::McapWriter::create(mcap_options); if (!writerResult.has_value()) { std::cerr << foxglove::strerror(writerResult.error()) << '\n'; return 1; } // Keep a reference to the writer. It will be closed when the writer is // destroyed, or we could call `.close()` to close it manually. auto writer = std::move(writerResult.value()); // highlight-end // Log until interrupted static std::function sigint_handler; std::atomic_bool done = false; sigint_handler = [&] { done = true; }; std::signal(SIGINT, [](int) { if (sigint_handler) { sigint_handler(); } }); while (!done) { auto dur = std::chrono::steady_clock::now() - start; float elapsed_seconds = std::chrono::duration(dur).count(); std::string msg = "{\"elapsed\": " + std::to_string(elapsed_seconds) + "}"; channel.log(reinterpret_cast(msg.data()), msg.size()); std::this_thread::sleep_for(33ms); } return 0; } ``` ### Viewing data from a file ## Links and resources - [SDK documentation](/docs/sdk?lang=cpp) with a more detailed [example](/docs/sdk/example?lang=cpp) - [C++ reference](https://foxglove-sdk-api-docs.pages.dev/cpp) - [Source code](https://github.com/foxglove/foxglove-sdk) --- ## Explore examples **URL**: /docs/getting-started/explore-examples **Description**: Curated example datasets with prebuilt layouts — no setup or code required. Explore Foxglove with curated example datasets — real multimodal robotics data with prebuilt layouts and 3D scenes, ready to browse without writing any code. ## In the app Open the command palette (`Cmd/Ctrl` + `K`), search for "Getting started", then select _Explore examples_. Each example opens with a layout already configured for its data. ## On the web Browse the [Foxglove example gallery](https://foxglove.dev/examples) for datasets spanning autonomous vehicles, drones, robot arms, and more. ## Next steps - Rearrange the [panels](/docs/visualization/panels) in an example and save your own [layout](/docs/visualization/layouts) - Ready to see your own data instead? Follow the [getting started guide](/docs/getting-started-guide) or [open a file](/docs/getting-started/open-a-file) --- ## Getting started guide **URL**: /docs/getting-started/getting-started-guide **Description**: Stream a sample drone recording live into Foxglove with one command using the Foxglove wizard — no hardware, robot, or code needed. The Foxglove wizard is a command line tool that streams a sample drone recording live into Foxglove, uploads that same recording to your [project](/docs/projects), and tags the moment the drone takes off so you can search for it. One command covers all three, so you can see how Foxglove works before you connect a robot or write any code. The app walks you through these same steps on its _Getting started_ page, which opens automatically the first time you open Foxglove. To open it again later, use the command palette (`Cmd/Ctrl` + `K`) and search for "Getting started". :::tip Want to use your own robot or code instead? Log from your code with the [SDK](/docs/sdk), or connect [ROS 1](/docs/getting-started/frameworks/ros1), [ROS 2](/docs/getting-started/frameworks/ros2), [PX4](/docs/getting-started/frameworks/px4), or [LeRobot](/docs/getting-started/frameworks/lerobot). To browse real robot data without running anything, [explore examples](/docs/getting-started/explore-examples). ::: ## Before you start - [Create a free Foxglove account](https://app.foxglove.dev/signup) - [Download the desktop app](https://foxglove.dev/download) or use [app.foxglove.dev](https://app.foxglove.dev) in Chrome - Install [uv](https://docs.astral.sh/uv/), or use Python 3.9 or newer with `pip` ## Run the wizard The wizard uploads its recording to a Foxglove project, so it needs a project ID. The _Getting started_ page fills yours in for you and offers the same package manager choice, which makes copying the command from there the shortest path. To write the command yourself, replace `` with the [project](/docs/projects) you want the recording to land in. The wizard opens your browser so you can sign in and confirm the request. If the browser doesn't open, use the verification link and code it prints in your terminal. It signs you in for that session only — it creates no [API key](/docs/settings#api-keys) and writes no credentials to disk. Once you confirm, the wizard serves the recording at `ws://localhost:8765` and waits for Foxglove to connect. Leave it running. Running the wizard is the only step in your terminal — from here you work in Foxglove. You'll connect to the stream you just started, watch the drone fly live in the viewer, then search the recording the wizard saved. ## See it live Once connected, Foxglove opens the [viewer](/docs/visualization), its visualization workspace, on a prebuilt [layout](/docs/visualization/layouts) built for the drone's flight. The wizard replays the recording at the cadence it was captured, so the data updates in real time rather than arriving all at once. A _You're live in Foxglove_ hint confirms the stream — leave the wizard running to keep the data flowing. ![The wizard's drone layout playing live in the viewer, with the "You're live in Foxglove" hint](/img/docs/getting-started/getting-started-guide-viewer@2x.webp) The layout arranges several [panels](/docs/visualization/panels), each showing the same flight a different way: - A [**3D**](/docs/visualization/panels/3d) panel plots the drone in space over the `world` grid, tracing its pose and flight path as the recording plays. - Four [**Gauge**](/docs/visualization/panels/gauge) panels read the drone's live telemetry: **Speed** (0 to 10) and its orientation as **Pitch**, **Roll**, and **Yaw** (each −π to π radians). Every needle tracks the current value as the recording plays. - A [**Plot**](/docs/visualization/panels/plot) panel traces those values over time — speed, pitch, roll, and position — so you can see how the flight develops, not just where the drone is right now. Together they show one recording from several angles at once, which is the point of a layout. The viewer is where you'll spend most of your time in Foxglove — drag the panels around, add your own, or save the arrangement as a [layout](/docs/visualization/layouts) you can reuse. ## Search the uploaded recording While it streams, the wizard also uploads the same recording to your project and tags an [event](/docs/data/events) three seconds in, where the drone takes off — so the flight is saved and searchable, not just shown once. When the _Your recording has been uploaded_ hint appears in the viewer: 1. Select _Search your data_. 2. Foxglove opens the [Search](/docs/data/search) page with the takeoff query already filled in and run: ```text event.properties.event like takeoff ``` 3. You land on the matching event, and an _Explore your data_ hint points out the takeoff events the wizard recorded. Edit the query to explore the rest of the flight, or open a result to [play the recording back](/docs/data/recordings) without the live connection. ## Recap The wizard exercised every core Foxglove concept. It streamed messages on **topics** through [**channels**](/docs/sdk/concepts), which Foxglove rendered in [**panels**](/docs/visualization/panels) arranged into a [**layout**](/docs/visualization/layouts) you can rearrange, save, and share. The same messages were recorded to an [MCAP file](/docs/visualization/connecting/local-data#supported-formats) and uploaded as a searchable [**recording**](/docs/data/recordings) carrying an [**event**](/docs/data/events). Everything else you do in Foxglove builds on those pieces. ## Troubleshooting If Foxglove doesn't connect: - Confirm the wizard is still running in your terminal - Check the connection URL is `ws://localhost:8765` - If the wizard runs on another machine, use that machine's IP address instead of `localhost` If sign-in doesn't finish, open the verification link the wizard printed in your terminal and enter the code shown beside it. If a _Still waiting for your recording_ hint appears, the upload hasn't registered yet. Leave the wizard running until it reports the upload finished, then reload the page. ## Next steps - [Add more panels](/docs/visualization/panels) — try a [Plot](/docs/visualization/panels/plot) or [Raw Messages](/docs/visualization/panels/raw-messages) panel, then save your arrangement as a [layout](/docs/visualization/layouts) - Log from your own code or robot — add the [SDK](/docs/sdk) to your Python, C++, or Rust program, or connect [ROS](/docs/getting-started/frameworks/ros1), [PX4](/docs/getting-started/frameworks/px4), or [LeRobot](/docs/getting-started/frameworks/lerobot) - [Upload your own recordings](/docs/data/importing-data) so your team can search and share them - Learn the [SDK concepts](/docs/sdk/concepts) behind channels, schemas, and servers --- ## Open a file **URL**: /docs/getting-started/open-a-file **Description**: Drop an MCAP file or ROS bag into Foxglove and explore it instantly. Have a recording already? Foxglove opens local files directly — no upload or conversion required. Foxglove supports MCAP files, ROS 1 bags, and [other common formats](/docs/visualization/connecting/local-data#supported-formats). ## Open your recording :::note Don't have a recording handy? [Explore examples](/docs/getting-started/explore-examples) instead, or follow the [getting started guide](/docs/getting-started-guide) — it runs the Foxglove wizard to stream a sample recording live and upload it to your project. ::: ## Next steps - [Import recordings](/docs/data/importing-data) to organize, search, and share them with your team - [Create a layout](/docs/visualization/layouts) so your panel setup is ready every time you open a file - Ready to log your own data? The [Foxglove SDK](/docs/sdk) walks you through it --- # Framework Guides > Integration guides for ROS, PX4, and more ## ROS 1 **URL**: /docs/getting-started/frameworks/ros1 **Description**: Use Foxglove to stream multimodal robotics data using ROS 1 or replay it from `.bag` files. ## Learn more - Set up [remote access](/docs/fleet/remote-access) to visualize and teleoperate your robot through the Foxglove platform without direct network access - Explore [all of the panels](/docs/visualization/panels) Foxglove has to offer for viewing and exploring data - Create and save sets of panels and their setting as [layouts](/docs/visualization/layouts) to reuse them or share with teammates - Use [Foxglove Data Platform](/docs/data) to store, stream, and share your robotics data - Learn about all the [configuration options available for Foxglove Bridge](https://github.com/foxglove/foxglove-bridge-ros1/blob/main/README.md#parameters) --- ## ROS 2 **URL**: /docs/getting-started/frameworks/ros2 **Description**: Use Foxglove to stream multimodal robotics data using ROS 2 or replay it from MCAP files. Foxglove offers two ways to visualize ROS 2 data: live from a running stack via the Foxglove Bridge, or from recorded `.mcap` files. ## Before you start - [Create a free Foxglove account](https://app.foxglove.dev/signup) - [Download the desktop app](https://foxglove.dev/download) or use [the web app](https://app.foxglove.dev) in Chrome ## Learn more - Set up [remote access](/docs/fleet/remote-access) to visualize and teleoperate your robot through the Foxglove platform without direct network access - Explore [all of the panels](/docs/visualization/panels) Foxglove has to offer for viewing and exploring data - Create and save sets of panels and their setting as [layouts](/docs/visualization/layouts) to reuse them or share with teammates - Use [Foxglove Data Platform](/docs/data) to store, stream, and share your robotics data - Learn about all the [configuration options available for Foxglove Bridge](https://github.com/foxglove/foxglove-sdk/blob/main/ros/src/foxglove_bridge/README.md#configuration) --- ## PX4 **URL**: /docs/getting-started/frameworks/px4 **Description**: Load local PX4 ULog (`.ulg`) files for visualization. ## Visualize PX4 flight logs Foxglove can open [PX4 ULog](https://docs.px4.io/main/en/dev_log/ulog_file_format.html) (`.ulg`) files natively for visualization. ULog files contain flight data recorded by PX4 autopilots, including sensor readings, actuator outputs, and system state information. ## Record flight data PX4 automatically logs flight data to ULog files when the autopilot is armed. The logs are typically stored on the SD card or in the `log` directory on your flight controller. To manually start logging or configure logging parameters, use the PX4 command line interface or QGroundControl. For more details on recording and managing ULog files, see the [PX4 logging documentation](https://docs.px4.io/main/en/dev_log/logging). ## Open your recording ## PX4 Converter extension The [PX4 Converter extension](https://github.com/foxglove/px4_converter) translates selected UORB messages and creates Foxglove messages from them so that the PX4 data can be visualized in additional panels such as [map](../../visualization/panels/map.mdx) and [3D](../../visualization/panels/3d.mdx). To install the extension, navigate to Settings->Extensions, select PX4 Converter Extension, and click install. Once installed, the messages will be automatically converted when you load the panels utilizing them. ![PX4 Converter Extension](/img/docs/getting-started/px4-extension@2x.webp) The converter will publish the following frame transforms: - `local_origin` - an ENU frame matching the EKF2 initialization frame - `base_intermediate` - an ENU intermediate frame containing the local position of the aircraft and yaw - `base_link` - same as base_intermediate but with applied Roll and Pitch angles ## Learn more - [PX4 Converter extension](https://github.com/foxglove/px4_converter) - Explore [all of the panels](/docs/visualization/panels) Foxglove has to offer for viewing and exploring data - Create and save sets of panels and their settings as [layouts](/docs/visualization/layouts) to reuse them or share with teammates --- ## LeRobot **URL**: /docs/getting-started/frameworks/lerobot **Description**: Stream LeRobot teleop, recording, and dataset replay to Foxglove with native WebSocket support. ## Visualize LeRobot with Foxglove As of [LeRobot 0.6.0](https://github.com/huggingface/lerobot), Foxglove is a built-in visualization backend. Pass `--display_mode=foxglove` to `lerobot-teleoperate`, `lerobot-record`, or `lerobot-rollout` to stream live camera feeds and joint plots over WebSocket. Replay any recorded dataset as a seekable timeline with `lerobot-dataset-viz --display-mode foxglove`. No custom integration code is required. :::tip The [Native Foxglove Visualization in LeRobot](https://foxglove.dev/blog/native-foxglove-visualization-in-lerobot) blog post walks through teleoperation, recording, and dataset playback with videos. ::: :::note This example uses an SO-101 arm. If you are using a different robot, adjust `--robot.type`, `--teleop.type`, and the related configuration for your hardware. Data will stream to Foxglove as expected for any LeRobot-supported robot as long as you pass `--display_data=true` and `--display_mode=foxglove`. ::: ### 1. Install LeRobot LeRobot requires Python 3.12+. Use [uv](https://docs.astral.sh/uv/) to create a virtual environment and install from PyPI: ```bash uv venv --python 3.12 source .venv/bin/activate uv pip install 'lerobot[feetech,dataset_viz]' ``` The `dataset_viz` extra includes everything needed for Foxglove visualization. See the [LeRobot installation guide](https://huggingface.co/docs/lerobot/v0.6.0/en/installation) for system dependencies and hardware setup. ### 2. Connect Foxglove Start any LeRobot command with `--display_mode=foxglove` (live) or `--display-mode foxglove` (dataset replay). Data appears on `ws://localhost:8765` as soon as the server starts. Import a starter layout from the [Foxglove SDK examples](https://github.com/foxglove/foxglove-sdk/tree/main/python/foxglove-sdk-examples/so101-visualization/foxglove) or [create your own](/docs/visualization/layouts). ### 3. Live visualization :::tip Make sure your SO-101 hardware is set up and calibrated. When in doubt, follow the [LeRobot SO-101 guide](https://huggingface.co/docs/lerobot/en/so101#calibrate). ::: Pass `--display_data=true --display_mode=foxglove` to stream observations, actions, and camera feeds in real time: ```bash uv run lerobot-teleoperate \ --robot.type=so101_follower \ --robot.port=/dev/tty.usbmodemFOLLOWER \ --robot.id=my_follower \ --robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}}" \ --teleop.type=so101_leader \ --teleop.port=/dev/tty.usbmodemLEADER \ --teleop.id=my_leader \ --display_data=true \ --display_mode=foxglove ``` Replace the USB port paths with your device paths (find them with `lerobot-find-port`). Camera IDs come from `lerobot-find-cameras opencv`. Live data is published on these topics: | Topic | Contents | | ------------------------------ | ----------------------------------------------------------- | | `/observation/state` | Per-joint observation values (named series for Plot panels) | | `/action/state` | Teleoperator or policy action targets | | `/observation/images/` | Camera frames (`RawImage` or compressed JPEG) | The same flags work for `lerobot-record` and `lerobot-rollout`. During recording, live visualization helps catch bad camera framing or joint limits before you finish an episode. ### 4. Dataset replay `lerobot-dataset-viz` serves any LeRobot dataset — from the Hugging Face Hub or recorded locally — as a seekable timeline in Foxglove: ```bash # A public dataset from the Hub uv run lerobot-dataset-viz \ --repo-id lerobot/svla_so101_pickplace \ --episode-index 0 \ --display-mode foxglove # A dataset you recorded locally uv run lerobot-dataset-viz \ --repo-id ${HF_USER}/my-dataset \ --root ~/.cache/huggingface/lerobot/${HF_USER}/my-dataset \ --episode-index 0 \ --display-mode foxglove ``` The Foxglove playback bar drives play, pause, seek, and speed. Dataset replay uses the same topics as live streaming, plus `/episode/state` for episode metadata. :::note Live commands use underscores (`--display_mode`, `--display_data`) while `lerobot-dataset-viz` uses hyphens (`--display-mode`). This matches each tool's CLI convention. ::: ### 5. Common options | Goal | Live commands | Dataset replay | | -------------------------- | ----------------------------- | ----------------------------- | | JPEG-compress images | `--display_compressed_images` | `--display-compressed-images` | | Custom port | `--display_port=8766` | `--web-port 8766` | | Stream to another machine | `--display_ip=0.0.0.0` | `--host 0.0.0.0` | | Don't auto-play on connect | — | `--no-autoplay` | When streaming to another machine, connect Foxglove to `ws://:8765` instead of `localhost`. ## Learn more - [Blog Post - Native Foxglove Visualization in LeRobot](https://foxglove.dev/blog/native-foxglove-visualization-in-lerobot) - [LeRobot dataset visualization docs](https://huggingface.co/docs/lerobot/en/using_dataset_tools) - [Foxglove SO-101 Documentation](/docs/getting-started/robots/so-100) - [Foxglove Python SDK examples](https://github.com/foxglove/foxglove-sdk/tree/main/python/foxglove-sdk-examples) --- # Hardware Guides > Connecting cameras, lidar, and sensors ## Luxonis OAK Cameras **URL**: /docs/getting-started/hardware/oak-depth-cameras **Description**: Stream data from Luxonis OAK depth cameras to Foxglove for real-time visualization and recording. # Integrate Luxonis OAK Cameras with Foxglove You can stream data from Luxonis OAK cameras to Foxglove using [DepthAI](https://docs.luxonis.com/software-v3/) and the [Foxglove SDK](https://github.com/foxglove/foxglove-sdk). Stream RGB images, colored point clouds, camera calibration, IMU, and transforms, with no ROS required. The camera calculates depth on-device (stereo or neural, chosen with `--depth-source`), and the SDK streams results over a WebSocket that Foxglove connects to directly. :::note If you are using ROS, launch your OAK ROS 2 node and follow the [ROS 2 documentation](../frameworks/ros2.mdx) to run Foxglove Bridge. ::: This approach works with all DepthAI-enabled devices. The examples require a stereo camera pair and an IMU — tested with the [OAK 4 D](https://docs.luxonis.com/hardware/products/OAK%204%20D). `--depth-source neural` needs an OAK 4 (RVC4) device; use `--depth-source stereo` (the default) on older OAK cameras. Use the [Python](https://github.com/foxglove/foxglove-sdk/tree/main/python/foxglove-sdk-examples/oak-camera-streaming) and [C++](https://github.com/foxglove/foxglove-sdk/tree/main/cpp/examples/oak-camera-streaming) SDK examples as the reference implementation. ## Prerequisites - A DepthAI-enabled device with a stereo camera pair and an IMU (for example a Luxonis [OAK 4 D](https://docs.luxonis.com/hardware/products/OAK%204%20D)), connected over USB 3 or Ethernet - For Python: [uv](https://docs.astral.sh/uv/) (installs `foxglove-sdk` and DepthAI v3 from `pyproject.toml`) - For C++: the [DepthAI C++ library](https://github.com/luxonis/depthai-core) (`depthai-core`). If it's in a non-standard prefix, pass `CMAKE_PREFIX_PATH` or `depthai_DIR` when building - On Linux, install the Luxonis [udev rules](https://docs.luxonis.com/hardware/platform/deploy/usb-deployment-guide/) for USB devices ## Published Topics The examples publish these topics: | Topic | Schema | Contents | | --- | --- | --- | | `/oak/points` | `foxglove.PointCloud` | Colored point cloud in meters | | `/oak/rgb/image` | `foxglove.RawImage` | Color video (`bgr8`) | | `/oak/rgb/calibration` | `foxglove.CameraCalibration` | Color-camera intrinsics and distortion | | `/oak/imu` | JSON (ROS `sensor_msgs/Imu`-like) | Accelerometer (m/s²) and gyroscope (rad/s) | | `/tf` | `foxglove.FrameTransforms` | Transform that orients the camera frame upright | ## Installation ## Usage ### Command Line Options | Option | Description | Default | | --- | --- | --- | | `--depth-source` | Depth source: `stereo` or `neural` (`neural` requires OAK 4 / RVC4) | `stereo` | | `--port` | WebSocket server port | `8765` | | `--record ` | Also record to an MCAP file at this path | Disabled | | `--point-unit` | Unit of the DepthAI point coordinates: `auto`, `meters`, or `millimeters` | `auto` | | `--help`, `-h` | Show help message | - | `--point-unit auto` detects whether DepthAI point coordinates are meter-scale or millimeter-scale before publishing Foxglove point clouds in meters. If the point cloud renders ~1000× too large or too small in the 3D panel, override the detection with `--point-unit meters` or `--point-unit millimeters`. ## How It Works DepthAI v3 describes on-device processing as a graph of nodes. Color and depth feed an `RGBD` node that produces a colored point cloud; the IMU publishes on a separate path. The snippet below is abridged from `main.py`. The examples create typed Foxglove channels, start a WebSocket server, then poll RGBD and IMU queues and log Foxglove messages. The C++ example mirrors this structure; see the [Python example](https://github.com/foxglove/foxglove-sdk/tree/main/python/foxglove-sdk-examples/oak-camera-streaming) and [C++ example](https://github.com/foxglove/foxglove-sdk/tree/main/cpp/examples/oak-camera-streaming) for the full convert-and-log loop. ### Build the DepthAI Pipeline ```python color = pipeline.create(dai.node.Camera).build(sensorFps=fps) # stereo or neural depth from CAM_B / CAM_C ... rgbd = pipeline.create(dai.node.RGBD).build(color, depth, size, fps) rgbd.setDepthUnits(dai.LengthUnit.METER) imu = pipeline.create(dai.node.IMU) imu.enableIMUSensor(dai.IMUSensor.ACCELEROMETER_UNCALIBRATED, IMU_HZ) imu.enableIMUSensor(dai.IMUSensor.GYROSCOPE_UNCALIBRATED, IMU_HZ) ``` ## Visualize OAK Camera Data in Foxglove Run the example, then connect Foxglove to the WebSocket server. Optionally import the example layout at `foxglove/oak_layout.json` (in the Python example directory) via _Import from file…_ in the layout menu. ### Visualize Camera Feed ### Visualize Point Cloud ### Visualize IMU Data The `/oak/imu` payload is shaped like ROS `sensor_msgs/Imu`. Add a Plot panel and set the expression to `/oak/imu.linear_acceleration.x` or `/oak/imu.angular_velocity.x` (and `.y` / `.z`) to chart accelerometer or gyroscope readings over time. ## Learn More - Explore the [Python OAK camera streaming example](https://github.com/foxglove/foxglove-sdk/tree/main/python/foxglove-sdk-examples/oak-camera-streaming) - Explore the [C++ OAK camera streaming example](https://github.com/foxglove/foxglove-sdk/tree/main/cpp/examples/oak-camera-streaming) - Read the [Luxonis documentation](https://docs.luxonis.com/) - Learn more about using the [Foxglove SDK](/docs/sdk/) --- ## RGB Camera **URL**: /docs/getting-started/hardware/rgb-camera **Description**: Stream data from RGB cameras to Foxglove for real-time visualization # Integrate RGB Cameras with Foxglove With Foxglove, you can stream data from any RGB camera (USB webcams, built-in laptop cameras, or IP cameras) for real-time visualization. The [Foxglove SDK](https://github.com/foxglove/foxglove-sdk) contains example code that shows how to stream data that you can modify to fit your application. :::note If you are using ROS, you can launch your camera node, and follow [ROS 2 Documentation](../frameworks/ros2.mdx) to start Foxglove Bridge. ::: ## Prerequisites ### OpenCV Installation ## Installation and Setup ## Usage ### Command Line Options | Option | Description | Default | | ------------------- | -------------------------------------- | ------- | | `--camera-id`, `-c` | Camera ID (integer) or video file path | `0` | | `--help`, `-h` | Show help message | - | ## Visualize RGB Camera Data in Foxglove To visualize the RGB camera data, open Foxglove and connect to the websocket server. ### Visualize Camera Feed ## Learn More - Explore the [Foxglove SDK documentation](/docs/sdk/) - Check out the [Python RGB camera stream example](https://github.com/foxglove/foxglove-sdk/tree/main/python/foxglove-sdk-examples/rgb-camera-visualization) - Check out the [Rust RGB camera stream example](https://github.com/foxglove/foxglove-sdk/tree/main/rust/examples/rgb_camera_visualization) - Check out the [C++ RGB camera stream example](https://github.com/foxglove/foxglove-sdk/tree/main/cpp/examples/rgb-camera-visualization) - Learn more about [OpenCV camera capture](https://docs.opencv.org/4.x/d8/dfe/classcv_1_1VideoCapture.html) --- ## Stereolabs ZED Cameras **URL**: /docs/getting-started/hardware/stereolabs-depth-cameras **Description**: Stream data from Stereolabs ZED depth cameras to Foxglove for real-time visualization and recording. # Integrate Stereolabs ZED Cameras with Foxglove With Foxglove, you can stream data from any of the Stereolabs ZED cameras: - ZED Mini - ZED 2 - ZED 2i - ZED X series The [ZED Foxglove Integration](https://github.com/stereolabs/zed-foxglove) utilizes Stereolabs' ZED SDK and Foxglove SDK to stream real-time image and point cloud data from ZED cameras to Foxglove. Both Python and C++ implementations are available. ## Installation :::note If you are using ROS, launch [ZED ROS 2 wrapper](https://github.com/stereolabs/zed-ros2-wrapper), and run Foxglove Bridge, as described in [ROS 2 Documentation](../frameworks/ros2.mdx). ::: ### ZED SDK Installation :::tip For up-to-date instructions on ZED SDK and CUDA installation, refer to the [Stereolabs documentation](https://www.stereolabs.com/docs/development/zed-sdk/). ::: ### ZED Foxglove Integration Setup ## Usage ### Command Line Options | Option | Description | Default | | --- | --- | --- | | `--ws` | Enable WebSocket server for live streaming | Disabled | | `--mcap ` | Output MCAP file name | `output.mcap` (C++), disabled (Python) | | `--help`, `-h` | Show help message | - | ## Visualize Depth Camera Data in Foxglove To visualize the ZED camera data in Foxglove, run the application with the `--ws` option, as described in the previous section, and follow these steps. ### Visualize Camera Feed ### Visualize Point Cloud ## Learn More - Explore [Stereolabs Documentation](https://www.stereolabs.com/docs/) - Check out the [ZED-Foxglove Repository](https://github.com/stereolabs/zed-foxglove/) - Learn more about using [Foxglove SDK](/docs/sdk/) --- # Visualization > Panel-based data visualization and debugging ## Foxglove Visualization **URL**: /docs/visualization **Description**: After connecting to a data source, leverage Foxglove's visualization and debugging tools to start exploring your data. Download Foxglove as a [desktop app](https://foxglove.dev/download) (available on Linux, Windows, or macOS), or navigate to the [web app](https://app.foxglove.dev) in a Chrome browser window. ### Extensions - Installing [extensions](/docs/extensions) via the [registry](https://github.com/foxglove/extension-registry) ### Other - [Creating shareable links](/docs/visualization/shareable-links) prefixed with `foxglove://` ## Interface [Connect to a data source](/docs/visualization/connecting) to explore it with Foxglove's visualization and debugging tools. ![top nav](/img/docs/visualization/navigation.png) | component | description | | --- | --- | | **App menu** | Connect to a [data source](/docs/visualization/connecting#data-sources), toggle the sidebars, or view resources | | **Add tab** | Add a tab to the current window | | **Add panel** | Add a [panel](/docs/visualization/panels) to the current layout | | **Layout menu** | Save your workspace view as a [layout](/docs/visualization/layouts) and share it with teammates | | **Left sidebar** | Edit panel settings (Panel), view data source's topics (Topics), and troubleshoot issues with your connection (Problems) | | **Right sidebar** | Set layout-wide [variables](/docs/visualization/variables) (Variables), write layout-scoped [user scripts](/docs/visualization/user-scripts) (User Scripts), and view playback metrics (Performance). Must enable debugging features in the [General settings](https://app.foxglove.dev/~/settings/user/general) to see the Performance tab | | **User menu** | Sign in to your Foxglove account, configure preferences, manage [extensions](/docs/extensions), and more | ## Sidebars ### Panel [Edit panel settings](/docs/visualization/panels#edit-settings) for any selected [panel](/docs/visualization/panels). ### Topics View all topics available in the data source, along with their data types, message encodings, and message rates. :::note Message frequency and count are not available for data streamed from Foxglove Data Platform. ::: ### Problems See a list of playback errors to troubleshoot. ### Variables Set layout-wide [variables](/docs/visualization/variables) that can be used in different panels with [FoxQL](/docs/visualization/foxql). ### User Scripts Write layout-scoped data transformations in [User Scripts](/docs/visualization/user-scripts). Open the **User Scripts** tab in the right sidebar or use the command palette to create and switch scripts. ### Performance Display playback and data-streaming performance statistics. The following statistics are displayed for a given playback session. "Instantaneous" statistics are reported based on the most recent frame, and also are averaged over the last 5 seconds. #### Memory usage Details the `jsHeapSizeLimit`, `usedJSHeapSize`, and `totalJSHeapSize`. #### Main thread ##### Frame rate The number of frames played per second. Though the player can play back at up to 60fps, this statistic will be lower if frames take longer than 16ms to render. ##### Latency Measures time for information to travel from the data source to the visualization panels. #### User scripts Measures time spent executing user scripts, both individually and in total. #### Data pipeline ##### Playback speed The player tries to play at the speed specified by the user, but may not be able to keep up, given heavy layouts and large amounts of data. This chart displays the actual playback speed as a ratio of bag time to playback time. ##### Frame rate The number of frames played per second. Though the player can play back at up to 60fps, this statistic will be lower if frames take longer than 16ms to render. ##### Bag frame time The duration in bag-time for the rendered frames in milliseconds. To "keep up" with playback, Foxglove will often emit "larger" frames. ##### Data throughput The amount of data received by the player in megabits per second. For remote bags, this includes topics that the player is not subscribed to. This statistic does not account for Content-Encoding compression, so it may be larger than the actual network bandwidth. ## Desktop-only features Some features are only available via the [desktop app](https://foxglove.dev/download). Specifically: - Tabs — Open multiple data sources in a single window using browser-style tabs. Create new tabs, drag to reorder, and use [keyboard shortcuts](/docs/visualization/shortcuts#desktop-tabs) to switch between them. Each tab maintains its own navigation history. - Opening a [native ROS 1 connection](/docs/getting-started/frameworks/ros1?modality=live) - Loading local URDF and mesh resources in the [3D panel](/docs/visualization/panels/3d) using URLs prefixed with `package://` - Exporting the current panel layout to a [video file](/docs/visualization/video-export) ## System requirements Foxglove visualization requires Chrome v130+ on Linux, Windows, or macOS. Make sure you are using the [latest version of Chrome](https://www.google.com/chrome/), or download [Foxglove Desktop](https://foxglove.dev/download) instead. Graphics acceleration is strongly preferred when using the Image panel for video replay or the 3D panel. See [checking video acceleration](/docs/visualization/panels/image#checking-video-acceleration) for more. Actual performance will depend significantly on a number of factors including the data you are visualizing, network connectivity, and whether you're looking at live, local, or cloud data - among other factors. Use the [performance sidebar](/docs/visualization#performance) to profile your workloads. ## Links and resources - [Getting Started with Foxglove](https://www.youtube.com/watch?v=ySVzQ3iFw90) --- ## Playback **URL**: /docs/visualization/playback **Description**: When visualizing a local or remote data file, you can navigate its contents using the playback bar controls. When visualizing a local or remote data file, you can navigate its contents using the playback bar controls. ![playback bar](/img/docs/visualization/playback/bar@2x.webp) If you're playing back a data file using [the Foxglove SDK's WebSocket server](/docs/sdk/websocket-server), you can also expose the playback bar controls like play/pause, seek, and playback speed, by enabling the [`PlaybackControl` capability](/docs/sdk/websocket-server#playback-control). This lets you control playback on your remote server directly from the Foxglove app. ### Message ordering The Foxglove app processes and delivers messages in **log time** order. Log time is meant to be a monotonic increasing value from some epoch, but its specific meaning varies by context: - **For recorded data files** (MCAP, ROS bags, ULog): Log time typically refers to when the message was originally recorded by the robot - **For live connections** (WebSocket, Foxglove Bridge): Log time refers to when the message was received by the WebSocket client Foxglove has some interpretation for log time in every supported data format, including [MCAP](https://mcap.dev/spec#message-op0x05), [WebSocket](/docs/sdk/websocket-server), [ROS 1](https://docs.ros.org/en/noetic/api/roscpp_traits/html/classros_1_1MessageEvent.html#a21d12c15255967761a0078ef29902414), [ROS 2](https://docs.ros.org/en/rolling/p/message_filters/generated/classmessage__filters_1_1MessageEvent.html#_CPPv4NK15message_filters12MessageEvent14getReceiptTimeEv), and [ULog](https://docs.px4.io/main/en/dev_log/ulog_file_format.html). Messages are always delivered in log time order to panels, scripts, and range subscriptions. #### Other timestamp fields Messages may contain other timestamp fields beyond log time. Depending on your robot logic, these timestamps might come before or after the log time: - **Header stamp**: Common in ROS messages, typically represents when sensor data was published - **Publish time**: The time a message was created, usually closer to the actual event - **Custom timestamp fields**: Any field in your message containing time data Some panels can use these alternative timestamps: - The [Plot](/docs/visualization/panels/plot) and [State Transitions](/docs/visualization/panels/state-transitions) panels support plotting data by custom timestamp fields - 3D and Image panels interpret and visualize [transform frames](/docs/visualization/panels/3d) based on timestamps within those messages Note that when mixing time sources, they still must all use a common reference time (epoch). You should normalize the times using offsets in order to ensure that time 0 refers to the same time for all sources. :::tip For most accurate playback synchronization, use log time as your primary timestamp. ::: #### Choosing the right timestamp When working with multiple timestamp options, consider these guidelines: - **Log time** (recommended default): - Best for overall playback synchronization - Ensures consistent message ordering across all panels - Use this unless you have a specific reason to use another timestamp - **Publish time**: - Time at which the message was published - Use to view information base on when it happened rather than wen it was logged - Possible to have message appear out of order - When writing an MCAP, if not available, must be set to the log time - **Header stamp**: - Use if you have ROS specific needs that rely on header time stamp - Possible to have messages appear out of order - **Custom timestamp fields**: - Use for specialized analysis of specific timing aspects in your system - Useful when your messages contain multiple relevant timestamps ### Message loading Foxglove optimizes how it loads your complex robotics data, for more streamlined seeking and playback. #### Message buffering To enable smoother playback, Foxglove buffers messages ahead of time into memory. The darker gray sections in the playback bar show which portions of the timeline have already been buffered. Playing from these buffered areas is typically faster, as the messages are already loaded into memory. Depending on the data being played back, the buffer may fill up quickly — especially when dealing with high-bandwidth topics. #### Message "lookback" When seeking to an arbitrary point in your loaded data, it's unlikely that every topic you are visualizing has a message at exactly the time you jumped to. The vast majority of your topics will have messages sometime before or after that exact seek point. To ensure that your layout still displays something reasonable, Foxglove performs a “lookback” on your data. Essentially, it looks for the most recent message on each subscribed topic. This ensures that even when seeking to an arbitrary point in your data, Foxglove will still display reasonable data for all the panels in your layout – even if their messages occurred at different times. #### Latched topics By default, ROS 1 `.bag` files, MCAP files, and Foxglove data streams will play back using message latching. When seeking within your data, Foxglove fetches the last message on all subscribed topics – even if they occurred multiple minutes before your seek location. Every panel in the layout will then automatically display the last data it saw for that topic – even if that data is infrequently published or was not published at that exact moment in time. For Foxglove data streams, Foxglove will load the last seen messages for each subscribed topic – even if those messages are from before your current data segment's start time. Message latching allows panels to accurately display data from infrequently published topics (like a map, for example), even while seeking around to multiple points in your data at random. #### Range loading While most Foxglove panels – like the [Raw Messages](/docs/visualization/panels/raw-messages) and [Image](/docs/visualization/panels/image) panels – display just the most recent message for a given topic, others like the [Plot](/docs/visualization/panels/plot) and [Map](/docs/visualization/panels/map) panels benefit from visualizing messages across the data's entire time range. Seeing a complete view of one's data makes spotting anomalies, summarizing robot behavior, and recognizing trends and patterns much easier. Range loading data allows these panels to access all their historical data throughout playback. Some panels that visualize only their most recently seen data also leverage range loading. For example, the [3D panel](/docs/visualization/panels/3d) can preload transform messages from the full data range to accurately position its markers. Robots often have many coordinate frames (e.g. joints of a robot arm, cameras on a self-driving car), each with their own markers. To render markers from different frames in a single 3D scene, the panel needs to use transforms to calculate the position of these visual elements in a common coordinate space. Since transforms accumulate and update over time, looking at just the latest message would result in an incompletely or incorrectly rendered scene. By loading all transforms, the 3D panel can accurately position its markers, regardless of where and how often you decide to seek in your data. ## Controls and shortcuts - Create, edit, view, and search [events](/docs/data/events) - Trim or expand the range of the active data - Format the current timestamp display - Seek back and forth at increments of 100ms - Loop playback - Configure playback speed ### Adjusting the playback range You can adjust the playback start and end time when viewing a local file, streaming a recording, or streaming data for a device + time range. Drag the handles on the playback bar to make quick adjustments or edit the input fields for precise adjustments. The time format will match your current timestamp display. Each input also has a button that fills it with the current playback time, and `Cmd`/`Ctrl` + `Shift` + `←`/`→` do the same from the keyboard while the dialog is open, so you can seek to the moment you care about and snap the range to it instead of copying the timestamp by hand. Once you have adjusted the range, a **Reset to full recording** link appears beneath the inputs to restore the recording's full extent. Changes take effect when you select **Update**. The command palette offers the same adjustments without opening the dialog: **Trim start to here** and **Trim end to here** move the corresponding end of the range to the playback time, and **Reset playback range** restores the full recording. These apply immediately. ![playback bar](/img/docs/visualization/playback/bar-range@2x.webp) :::tip If you make an adjustment and the resulting start/end time do not match what you expected, it's likely one of two scenarios occurred: - You're viewing a fixed-length recording and tried to extend beyond the start/end. In this case, we will automatically adjust the range to match the full recording. - You're viewing device data and the new playback range did not include any additional data. In this case, we will automatically trim the playback range around available data. ::: ### Keyboard shortcuts | Shortcut | Description | | --- | --- | | `Space` | Toggle playback | | `←` | Seek backward 100ms | | `→` | Seek forward 100ms | | `Shift` + `←` | Seek backward 10ms | | `Shift` + `→` | Seek forward 10ms | | `Alt` + `←` (Windows and Linux)
`Option` + `←` (macOS) | Seek backward 500ms | | `Alt` + `→` (Windows and Linux)
`Option` + `→` (macOS) | Seek forward 500ms | | `Home` (Windows and Linux)
`Fn` + `←` (macOS) | Seek to start | | `End` (Windows and Linux)
`Fn` + `→` (macOS) | Seek to end | | `Shift` + `↑` | Increase playback speed | | `Shift` + `↓` | Decrease playback speed | | `Ctrl` + `Shift` + `←` (Windows and Linux)
`Cmd` + `Shift` + `←` (macOS) | Set the range start to the current playback time (while adjusting the playback range) | | `Ctrl` + `Shift` + `→` (Windows and Linux)
`Cmd` + `Shift` + `→` (macOS) | Set the range end to the current playback time (while adjusting the playback range) | --- ## Comparison mode **URL**: /docs/visualization/comparison-mode **Description**: Open multiple data sources on a shared playback timeline and view their data together, either overlaid or side-by-side. You can open two or more data sources on a shared playback timeline while keeping each source distinct using **comparison mode**. This is useful when the sources share topics and you want to view the data together, either overlaid or side-by-side. For example, comparing a run before and after a code change, or aligning a simulation against a real-world log. Because comparison mode can pull data from different devices, it is an excellent fit for multi-device workflows. Select sessions and events from separate robots to unlock comparing like topics, overlaid or side-by-side. ## Starting a comparison On the Recordings, Sessions, or Events pages, select two or more items and click **Compare**. ![Compare button on the Recordings page](/img/docs/visualization/comparison-mode/recordings-compare@2x.webp) To open local files straight into comparison mode, click **Compare local files** on the dashboard, **Compare local files…** in the nav menu under **Open data sources**, or run **Compare local files…** from the command palette, then select two or more files of the same type. Opening local files any other way — **Open local file(s)**, `Ctrl` + `O` / `Cmd` + `O`, or dragging files into Foxglove — merges them by default. To split a merged set into slots, open the Sources sidebar and set **Source mode** to **Compare** at the top, or run **Switch to compare** from the command palette. While a recording, session, or event is open, the command palette’s **Add comparison source…** command searches for another item of the same kind and adds it as a comparison slot. **Add source** adds local files to the current selection. ## Reading the comparison Each item you compare (such as a recording, session, or event) is a **source**. Each source occupies a **slot** labeled A, B, C, and so on, assigned in the order you select them. Slot badges appear next to the source name in the top bar, in Plot and State Transitions legends and series settings, in the Sources sidebar, and in the scrubber tooltip. Map represents each slot with a distinct color instead of a badge. ![Slot badges across the top bar and Plot legend](/img/docs/visualization/comparison-mode/plot-legend-slots@2x.webp) Some panels, such as [Plot](/docs/visualization/panels/plot#comparison-mode), [State Transitions](/docs/visualization/panels/state-transitions#comparison-mode), and [Map](/docs/visualization/panels/map#comparison-mode), are **multi-source**: they render every source at once. Others are **single-source**: they display one source at a time. Both types have a data source picker in the panel toolbar. Use it to focus a multi-source panel on one slot, or to switch a single-source panel between slots. Hovering a slot accents the matching slot and dims the other sources' data in multi-source panels, so you can pick out one source's data. The slot badges themselves stay visible. ## Adjusting a comparison Every source begins at time zero on the shared timeline, regardless of when it was originally recorded. Shift a source's start time to align two sources recorded at different real-world times. Open the Sources sidebar to: - **Add local files.** Click **Add** in the footer, or run **Add source** from the command palette. Local-file comparisons only. - **Add a cloud source.** Run **Add comparison source…** from the command palette and choose a recording, session, or event of the same kind. - **Remove a source.** Click **×** next to its heading and confirm, or run **Remove source…** from the command palette. - **Reorder slots and change start times.** Click **Manage** in the footer (or the compare icon on the playback bar), or run **Adjust comparison** from the command palette, to open the editor. Drag rows in the editor to reorder slots, type new offsets in each row's field, or drag each source's bar on the playback timeline to shift its start time. - **Switch merge and compare.** Use **Source mode** at the top of the Sources sidebar, or run **Switch to compare** / **Switch to merge** from the command palette.