Go Rosbag parser. Designed to provide ease of use, speed, and streamability.
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()
}
}
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()
}
}
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 |
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.
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!
Please see the examples directory within this repository.
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.
There are two known alternatives to go-rosbag (at least that I know of):
- https://github.com/starship-technologies/gobag: This project seems to be lacking a good way to process large rosbags, and unmarshall messages to structs.
- https://github.com/brychanrobot/goros/blob/master/rosbag.go: This project seems to be incomplete and abandoned.
Any contribution is welcomed! I will review pull requests as soon as possible.
go-rosbag is licensed under Apache license version 2.0. See LICENSE file.