Skip to content

lherman-cs/go-rosbag

Repository files navigation

go-rosbag

PkgGoDev CI

Go Rosbag parser. Designed to provide ease of use, speed, and streamability.

Usage

View Messages as map[string]interface{}

package main

import (
	"fmt"
	"io"
	"os"

	"github.com/lherman-cs/go-rosbag"
)

func main() {
	f, _ := os.Open("example.bag")
	defer f.Close()

	decoder := rosbag.NewDecoder(f)
	for {
		record, err := decoder.Read()
		if err == io.EOF {
			break
		}

		switch record := record.(type) {
		case *rosbag.RecordMessageData:
			data := make(map[string]interface{})
			// After ViewAs gets called, the variable "data" will be used to map
			// the underlying buffer to Go data structures, and they'll SHARE the
			// same underlying buffer.
			_ = record.ViewAs(data)
			fmt.Println(data)
		}
    
    		// Mark the current record is no longer used, the underlying buffer can be reused.
		record.Close()
	}
}

View Messages as structs

package main

import (
	"fmt"
	"io"
	"os"

	"github.com/lherman-cs/go-rosbag"
)

type Pixel struct {
	R uint8	`rosbag:"r"`
	G uint8	`rosbag:"g"`
	B uint8	`rosbag:"b"`
}

func main() {
	f, _ := os.Open("example.bag")
	defer f.Close()

	decoder := rosbag.NewDecoder(f)
	for {
		record, err := decoder.Read()
		if err == io.EOF {
			break
		}

		switch record := record.(type) {
		case *rosbag.RecordMessageData:
			if record.ConnectionHeader().Topic == "/pixel" {
				var pixel Pixel
				_ = record.ViewAs(&pixel)
				fmt.Println(pixel)
			}
		}
    
    		// Mark the current record is no longer used, the underlying buffer can be reused.
		record.Close()
	}
}

Data Type Mapping

Primitive Types

ROS Type Go Type
bool bool
int8 int8
byte int8
uint8 uint8
char uint8
int16 int16
uint16 uint16
int32 uint32
int64 uint64
float32 float32
float64 float64
string string
time time.Time
duration time.Duration

Array Handling

Both fixed-length and variable-length arrays are mapped to Go slices. For example, uint8[] with a length of 3 and uint8[3] will be mapped to []uint8 in Go.

Benchmark

Hardware specs:

  • Model: MacBook Pro (15-inch, 2017)
  • Processor: 2.8 GHz Quad-Core Intel Core i7
  • Memory: 16 GB 2133 MHz LPDDR3
  • Storage: 256GB PCIe-based onboard SSD

The following benchmark result (source) was taken by parsing a 696 MB rosbag file from webviz. The bag contains frames and metadata from a car.

Time taken: 147 ms
Throughput: 4.59 GB/s
Memory usage: 33.60 MB

For a reference, time cat <bag> > /dev/null takes 118 ms. This means, go-rosbag only adds 29 ms to the total runtime!

Examples

Please see the examples directory within this repository.

Code Coverage

Currently, the unit tests only cover the happy path, and it's not extensive as I want it to be. I'm still working on adding coverage during my free time.

Alternatives

There are two known alternatives to go-rosbag (at least that I know of):

Contributing

Any contribution is welcomed! I will review pull requests as soon as possible.

License

go-rosbag is licensed under Apache license version 2.0. See LICENSE file.