Skip to main content

Create topic converter

This guide shows how to build a topic message converter that computes and plots the absolute value of acceleration data from a topic.

Setting up

In a Terminal window, cd into the directory where your source code will live and run the following command:

npm init foxglove-extension@latest myExtensionName

This uses create-foxglove-extension to create a myExtensionName directory containing source code for an example message converter.

Registering a converter

The index.ts file in your project's src folder is the entry point for your extension source code. It must export an activate function that accepts a single extensionContext argument of type ExtensionContext.

To register a message converter, we call registerMessageConverter on the extensionContext argument with the type topic and several arguments to define the input and output.

import { MessageEvent } from "@foxglove/extension";

type MySignal = { acceleration: number };

export function activate(extensionContext: ExtensionContext) {
extensionContext.registerMessageConverter({
type: "topic",
inputTopics: ["/acceleration"],
outputTopic: "/acceleration/absolute",
schemaName: "AccelerationAbsolute",
schemaDescription: { value: "number" },
create: () => {
// create() returns a function that the app will call with a MessageEvent
// for every input message. The input MessageEvents are in log time order.
return (msgEvent) => {
const msg = msgEvent.message as MySignal;
return { value: Math.abs(msg.acceleration) };
};
},
});
}

Line-by-line explanation

Let's go through the lines above to explain what happens.

type: "topic"

This tells Foxglove that we're registering a topic message converter. Topic message converters use messages from one or more input topics to compute a new message on an output topic.

inputTopics: ["/acceleration"]

This tells Foxglove that we want to process incoming messages on the /acceleration topic.

outputTopic: "/acceleration/absolute"

This tells Foxglove that we want to output messages to the /acceleration/absolute topic.

note

The output topic is local to the app, it is not published back to a live connection or external system.

schemaName: "AccelerationAbsolute"

We've set the schema name for our output topic to AccelerationAbsolute.

All topics have an associated schema name for the type of messages they contain. Since our topic is producing a new custom message type, we can pick any schema name we want.

tip

For topics that produce custom messages, avoid schema names that conflict with existing schema names in your data source or well-known schema names.

schemaDescription: { value: "number" }

Here we define the actual schema for the output message. Our converter will output one field, named value in the new message and that field will be a number.

To power message path selection and autocomplete (i.e. in the plot panel series config or raw message panel), the app needs to know the shape of the messages you are creating.

create: () => { ... }

The create function initializes the converter. It is called by the app to create the converter when some panel subscribes to the output topic.

It should return a function that will be called with a MessageEvent for every input message (from the input topics).

return (msgEvent) => { ... }

This function, returned by the create function, is called with a MessageEvent for every input message. It performs any computation and returns a new message matching the schema description. You can optionally return undefined to skip producing a message for the given input.

Testing

Once we've packaged and installed our extension, load any data source containing our custom /acceleration topic and visualize them with the Plot panel by selecting the message path /acceleration/absolute.value as the series to plot.

note

Message converters run on-demand only when the topic is subscribed to by a panel.