#websocket #foxglove #data #messages #publish #applications

foxglove-ws

Library to publish messages to Foxglove via WebSocket

5 releases

0.2.2 Oct 2, 2023
0.2.1 Jul 5, 2023
0.2.0 Jun 29, 2023
0.1.1 Jun 18, 2023
0.1.0 Jun 18, 2023

#126 in Robotics

34 downloads per month

Apache-2.0

19KB
353 lines

Foxglove WebSocket publishing in Rust

This library provides means to publish messages to the amazing Foxglove UI in Rust. It implements part of the Foxglove WebSocket protocol described in https://github.com/foxglove/ws-protocol.

Example

Call

cargo run --release --example string

to start an example application that publishes ROS 1 string data -- both latching and non-latching.


lib.rs:

This library provides means to publish messages to the amazing Foxglove UI in Rust. It implements part of the Foxglove WebSocket protocol described in https://github.com/foxglove/ws-protocol.

On its own the protocol does not fix a specific data scheme for the messages. But for Foxglove to understand the messages it makes sense to follow the well-known serialization schemes https://mcap.dev/spec/registry.

Example

This is an example with single ROS1 channel/topic with the std_msgs/String message type.

use std::{io::Write, time::SystemTime};

fn build_string_message(data: &str) -> anyhow::Result<Vec<u8>> {
    let mut msg = vec![0; std::mem::size_of::<u32>() + data.len()];
    // ROS 1 message strings are encoded as 4-bytes length and then the byte data.
    let mut w = std::io::Cursor::new(&mut msg);
    w.write(&(data.len() as u32).to_le_bytes())?;
    w.write(data.as_bytes())?;
    Ok(msg)
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let server = foxglove_ws::FoxgloveWebSocket::new();
    tokio::spawn({
        let server = server.clone();
        async move { server.serve(([127, 0, 0, 1], 8765)).await }
    });
    let channel = server
        .publish(
            "/data".to_string(),
            "ros1".to_string(),
            "std_msgs/String".to_string(),
            "string data".to_string(),
            "ros1msg".to_string(),
            false,
        )
        .await?;
    channel
        .send(
            SystemTime::now().elapsed().unwrap().as_nanos() as u64,
            &build_string_message("Hello!")?,
        )
        .await?;
}

Dependencies

~9–19MB
~264K SLoC