Skip to content

Commit

Permalink
types: lidar-mode
Browse files Browse the repository at this point in the history
  • Loading branch information
johnlettman committed Jul 16, 2024
1 parent 1243040 commit 4508497
Show file tree
Hide file tree
Showing 2 changed files with 304 additions and 0 deletions.
138 changes: 138 additions & 0 deletions types/lidar-mode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package types

import (
"github.com/johnlettman/oyster/util"

Check failure on line 4 in types/lidar-mode.go

View workflow job for this annotation

GitHub Actions / test

no required module provides package github.com/johnlettman/oyster/util; to add it:
)

// LIDARMode represents the horizontal resolution and rotation rate of the sensor.
// The effective range of the sensor is increased by 15-20% for every halving of the number of points gathered.
// For example, LidarMode512x10 has a 15-20% longer range than LidarMode512x20.
//
// LIDARMode implements encoding/json.Marshaller and encoding/json.Unmarshaller
// to simplify loading from ouster_meta.json
//
// For additional information, refer to [Ouster docs: lidar_mode].
//
// [Ouster docs: lidar_mode]: https://static.ouster.dev/sensor-docs/image_route1/image_route2/common_sections/API/sensor_configuration_description.html?highlight=512x10#lidar-mode
type LIDARMode int

const (
LidarModeUnknown LIDARMode = iota // unspecified
LidarMode512x10 // 10 scans of 512 columns per second
LidarMode512x20 // 20 scans of 512 columns per second
LidarMode1024x10 // 10 scans of 1024 columns per second
LidarMode1024x20 // 20 scans of 1024 columns per second
LidarMode2048x10 // 10 scans of 2048 columns per second
LidarMode4096x5 // 5 scans of 4096 columns per second
)

var lidarModeGoKV = map[LIDARMode]string{
LidarModeUnknown: "LidarModeUnknown",
LidarMode512x10: "LidarMode512x10",
LidarMode512x20: "LidarMode512x20",
LidarMode1024x10: "LidarMode1024x10",
LidarMode1024x20: "LidarMode1024x20",
LidarMode2048x10: "LidarMode2048x10",
LidarMode4096x5: "LidarMode4096x5",
}

// lidarModeKV maps LIDARMode values to their respective string representations.
var lidarModeKV = map[LIDARMode]string{
LidarModeUnknown: "unknown",
LidarMode512x10: "512x10",
LidarMode512x20: "512x20",
LidarMode1024x10: "1024x10",
LidarMode1024x20: "1024x20",
LidarMode2048x10: "2048x10",
LidarMode4096x5: "4096x5",
}

// lidarModeVK is a variable that stores the reverse mapping of the lidarModeKV map.
// It maps string representations of LIDARMode values to their respective LIDARMode values.
var lidarModeVK = util.ReverseMap(lidarModeKV)

// String returns the string representation of a LIDARMode value.
// If no match is found, it returns "unknown" as the default string representation.
func (m LIDARMode) String() string {
if s, ok := lidarModeKV[m]; ok {
return s
}

return lidarModeKV[LidarModeUnknown]
}

// GoString returns the Go syntax representation of a LIDARMode value.
// If no match is found, it returns "LidarModeUnknown" as the default string representation.
func (m LIDARMode) GoString() string {
if s, ok := lidarModeGoKV[m]; ok {
return s
}

return lidarModeGoKV[LidarModeUnknown]
}

// MarshalText returns the text representation of a LIDARMode value.
// - If the LIDARMode has a matching string representation in the lidarModeKV map,
// it returns the byte slice of that string representation.
// - If no match is found, it returns nil.
//
// The error returned is always nil.
func (m LIDARMode) MarshalText() ([]byte, error) {
if s, ok := lidarModeKV[m]; ok {
return []byte(s), nil
}

return []byte{}, nil
}

// UnmarshalText unmarshals the given text into a LIDARMode value.
// - If the string representation of the text exists in the lidarModeVK map,
// it assigns the corresponding LIDARMode value to the receiver pointer.
// - Otherwise, it assigns LidarModeUnknown to the receiver pointer.
//
// The error returned is always nil.
func (m *LIDARMode) UnmarshalText(text []byte) error {
if mode, ok := lidarModeVK[string(text)]; ok {
*m = mode
} else {
*m = LidarModeUnknown
}

return nil
}

// Columns returns the number of columns for a given LIDARMode value.
// It returns 0 if the LIDARMode is unknown or not specified.
func (m LIDARMode) Columns() int {
switch m {
default:
fallthrough
case LidarModeUnknown:
return 0
case LidarMode512x10, LidarMode512x20:
return 512
case LidarMode1024x10, LidarMode1024x20:
return 1024
case LidarMode2048x10:
return 2048
case LidarMode4096x5:
return 4096
}
}

// Frequency returns the frequency (number of scans per second) for a given LIDARMode value.
// It returns 0 if the LIDARMode is unknown or not specified.
func (m LIDARMode) Frequency() int {
switch m {
default:
fallthrough
case LidarModeUnknown:
return 0
case LidarMode512x20, LidarMode1024x20:
return 20
case LidarMode512x10, LidarMode1024x10, LidarMode2048x10:
return 10
case LidarMode4096x5:
return 5
}
}
166 changes: 166 additions & 0 deletions types/lidar-mode_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package types

import (
"github.com/brianvoe/gofakeit/v7"
"github.com/stretchr/testify/assert"
"testing"
)

func TestLIDARMode_String(t *testing.T) {
type TestCase struct {
name string
m LIDARMode
want string
}

cases := []TestCase{
{"LIDARModeUnknown", LidarModeUnknown, "unknown"},
{"LidarMode512x10", LidarMode512x10, "512x10"},
{"LidarMode512x20", LidarMode512x20, "512x20"},
{"LidarMode1024x10", LidarMode1024x10, "1024x10"},
{"LidarMode1024x20", LidarMode1024x20, "1024x20"},
{"LidarMode2048x10", LidarMode2048x10, "2048x10"},
{"LidarMode4096x5", LidarMode4096x5, "4096x5"},
{"unknown value", LidarMode4096x5 + 1, "unknown"},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got := c.m.String()
assert.Equal(t, c.want, got, "it should return the correct representation")
})
}
}

func TestLIDARMode_GoString(t *testing.T) {
type TestCase struct {
name string
m LIDARMode
want string
}

cases := []TestCase{
{"LIDARModeUnknown", LidarModeUnknown, "LidarModeUnknown"},
{"LidarMode512x10", LidarMode512x10, "LidarMode512x10"},
{"LidarMode512x20", LidarMode512x20, "LidarMode512x20"},
{"LidarMode1024x10", LidarMode1024x10, "LidarMode1024x10"},
{"LidarMode1024x20", LidarMode1024x20, "LidarMode1024x20"},
{"LidarMode2048x10", LidarMode2048x10, "LidarMode2048x10"},
{"LidarMode4096x5", LidarMode4096x5, "LidarMode4096x5"},
{"unknown value", LidarMode4096x5 + 1, "LidarModeUnknown"},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got := c.m.GoString()
assert.Equal(t, c.want, got, "it should return the correct representation")
})
}
}

func TestLIDARMode_MarshalText(t *testing.T) {
type TestCase struct {
name string
m LIDARMode
want string
}

cases := []TestCase{
{"LIDARModeUnknown", LidarModeUnknown, "unknown"},
{"LidarMode512x10", LidarMode512x10, "512x10"},
{"LidarMode512x20", LidarMode512x20, "512x20"},
{"LidarMode1024x10", LidarMode1024x10, "1024x10"},
{"LidarMode1024x20", LidarMode1024x20, "1024x20"},
{"LidarMode2048x10", LidarMode2048x10, "2048x10"},
{"LidarMode4096x5", LidarMode4096x5, "4096x5"},
{"unknown value", LidarMode4096x5 + 1, ""},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got, err := c.m.MarshalText()
assert.NoError(t, err, "it should not error")
assert.Equal(t, []byte(c.want), got, "it should return the correct representation")
})
}
}

func TestLIDARMode_UnmarshalText(t *testing.T) {
type TestCase struct {
name string
text string
want LIDARMode
}

cases := []TestCase{
{"LIDARModeUnknown", "unknown", LidarModeUnknown},
{"LidarMode512x10", "512x10", LidarMode512x10},
{"LidarMode512x20", "512x20", LidarMode512x20},
{"LidarMode1024x10", "1024x10", LidarMode1024x10},
{"LidarMode1024x20", "1024x20", LidarMode1024x20},
{"LidarMode2048x10", "2048x10", LidarMode2048x10},
{"LidarMode4096x5", "4096x5", LidarMode4096x5},
{"random text", gofakeit.LoremIpsumSentence(4), LidarModeUnknown},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var m LIDARMode
err := m.UnmarshalText([]byte(c.text))
assert.NoError(t, err, "it should not error")
assert.Equal(t, c.want, m, "it should assign the correct value")
})
}
}

func TestLIDARMode_Columns(t *testing.T) {
type TestCase struct {
name string
m LIDARMode
want int
}

cases := []TestCase{
{"LIDARModeUnknown", LidarModeUnknown, 0},
{"LIDARMode512x10", LidarMode512x10, 512},
{"LIDARMode512x20", LidarMode512x20, 512},
{"LIDARMode1024x10", LidarMode1024x10, 1024},
{"LIDARMode1024x20", LidarMode1024x20, 1024},
{"LIDARMode2048x10", LidarMode2048x10, 2048},
{"LIDARMode4096x5", LidarMode4096x5, 4096},
{"unknown value", LidarMode4096x5 + 1, 0},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got := c.m.Columns()
assert.Equal(t, c.want, got, "it should return the correct number of columns")
})
}
}

func TestLIDARMode_Frequency(t *testing.T) {
type TestCase struct {
name string
m LIDARMode
want int
}

cases := []TestCase{
{"LIDARModeUnknown", LidarModeUnknown, 0},
{"LIDARMode512x10", LidarMode512x10, 10},
{"LIDARMode512x20", LidarMode512x20, 20},
{"LIDARMode1024x10", LidarMode1024x10, 10},
{"LIDARMode1024x20", LidarMode1024x20, 20},
{"LIDARMode2048x10", LidarMode2048x10, 10},
{"LIDARMode4096x5", LidarMode4096x5, 5},
{"unknown value", LidarMode4096x5 + 1, 0},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got := c.m.Frequency()
assert.Equal(t, c.want, got, "it should return the correct number of columns")
})
}
}

0 comments on commit 4508497

Please sign in to comment.