-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e3b9eec
commit 9ec7ed6
Showing
2 changed files
with
240 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package types | ||
|
||
import ( | ||
"github.com/johnlettman/oyster/util" | ||
) | ||
|
||
// MultipurposeIOMode controls the functionality of the multipurpose I/O port on the | ||
// Ouster sensor, particularly with respect to the SYNC_PULSE_OUT signal. Its | ||
// configuration parameters include: | ||
// | ||
// - MultipurposeOff: | ||
// No SYNC_PULSE_OUT signal is output. | ||
// - MultipurposeInputNMEAUART: | ||
// The port is reconfigured as an input. | ||
// - MultipurposeOutputFromInternalOscillator: | ||
// SYNC_PULSE_OUT synchronized with the internal clock. | ||
// - MultipurposeOutputFromSyncPulseIn: | ||
// SYNC_PULSE_OUT synchronized with provided SYNC_PULSE_IN. | ||
// - MultipurposeOutputFromPTP1588: | ||
// SYNC_PULSE_OUT synchronized with an external PTP IEEE 1588 master. | ||
// - MultipurposeOutputFromEncoderAngle: | ||
// SYNC_PULSE_OUT at a user-defined rate in an integer number of degrees. | ||
// | ||
// Note: | ||
// | ||
// - When the mode is MultipurposeOutputFromInternalOscillator, MultipurposeOutputFromSyncPulseIn, | ||
// or MultipurposeOutputFromPTP1588, ConfigurationParameters.SyncPulseOutFrequency can define the output rate | ||
// (defaults to 1 Hz). | ||
// - When the sensor is in MultipurposeOutputFromEncoderAngle mode, ConfigurationParameters.SyncPulseOutAngle | ||
// defines the output pulse rate. | ||
// - In all modes, ConfigurationParameters.SyncPulseOutPulseWidth defines the output pulse width. | ||
// | ||
// For additional information, refer to [Ouster docs: multipurpose_io_mode] and | ||
// [Ouster docs: External Trigger Clock Source] | ||
// | ||
// [Ouster docs: External Trigger Clock Source]: https://static.ouster.dev/sensor-docs/image_route1/image_route3/time_sync/time-sync.html#external-trigger-clock-source | ||
// [Ouster docs: multipurpose_io_mode]: https://static.ouster.dev/sensor-docs/image_route1/image_route2/common_sections/API/sensor_configuration_description.html#multipurpose-io-mode | ||
type MultipurposeIOMode uint8 | ||
|
||
const ( | ||
MultipurposeOff MultipurposeIOMode = iota // Do not output a SYNC_PULSE_OUT signal. | ||
|
||
// MultipurposeInputNMEAUART reconfigures the MULTIPURPOSE_IO port as an input. | ||
// See [Ouster docs: Setting Ouster Sensors Time Source] for more information. | ||
// | ||
// [Ouster docs: Setting Ouster Sensors Time Source]: https://static.ouster.dev/sensor-docs/image_route1/image_route3/time_sync/time-sync.html#setting-sensor-time | ||
MultipurposeInputNMEAUART | ||
|
||
MultipurposeOutputFromInternalOscillator // Output a SYNC_PULSE_OUT signal synchronized with the internal clock. | ||
MultipurposeOutputFromSyncPulseIn // Output a SYNC_PULSE_OUT signal synchronized with a SYNC_PULSE_IN provided to the unit. | ||
MultipurposeOutputFromPTP1588 // Output a SYNC_PULSE_OUT signal synchronized with an external PTP IEEE 1588 master. | ||
MultipurposeOutputFromEncoderAngle // Output a SYNC_PULSE_OUT signal with a user defined rate in an integer number of degrees. | ||
) | ||
|
||
// multipurposeIOModeTextKV maps MultipurposeIOMode values to their text representations. | ||
var multipurposeIOModeTextKV = map[MultipurposeIOMode]string{ | ||
MultipurposeOff: "OFF", | ||
MultipurposeInputNMEAUART: "INPUT_NMEA_UART", | ||
MultipurposeOutputFromInternalOscillator: "OUTPUT_FROM_INTERNAL_OSC", | ||
MultipurposeOutputFromSyncPulseIn: "OUTPUT_FROM_SYNC_PULSE_IN", | ||
MultipurposeOutputFromPTP1588: "OUTPUT_FROM_PTP_1588", | ||
MultipurposeOutputFromEncoderAngle: "OUTPUT_FROM_ENCODER_ANGLE", | ||
} | ||
|
||
// multipurposeIOModeTextKV maps MultipurposeIOMode values to their string representations. | ||
var multipurposeIOModeStringKV = map[MultipurposeIOMode]string{ | ||
MultipurposeOff: "off", | ||
MultipurposeInputNMEAUART: "input from NMEA UART", | ||
MultipurposeOutputFromInternalOscillator: "output from Internal Oscillator", | ||
MultipurposeOutputFromSyncPulseIn: "output from Sync Pulse in", | ||
MultipurposeOutputFromPTP1588: "output from PTP 1588", | ||
MultipurposeOutputFromEncoderAngle: "output from encoder angle", | ||
} | ||
|
||
// multipurposeIOModeTextKV maps MultipurposeIOMode values to their Go syntax representations. | ||
var multipurposeIOModeGoStringKV = map[MultipurposeIOMode]string{ | ||
MultipurposeOff: "MultipurposeOff", | ||
MultipurposeInputNMEAUART: "MultipurposeInputNMEAUART", | ||
MultipurposeOutputFromInternalOscillator: "MultipurposeOutputFromInternalOscillator", | ||
MultipurposeOutputFromSyncPulseIn: "MultipurposeOutputFromSyncPulseIn", | ||
MultipurposeOutputFromPTP1588: "MultipurposeOutputFromPTP1588", | ||
MultipurposeOutputFromEncoderAngle: "MultipurposeOutputFromEncoderAngle", | ||
} | ||
|
||
// multipurposeIOModeTextVK maps string representations to MultipurposeIOMode values. | ||
var multipurposeIOModeTextVK = util.ReverseMap(multipurposeIOModeTextKV) | ||
|
||
// String returns the string representation of a MultipurposeIOMode value. | ||
func (m MultipurposeIOMode) String() string { | ||
if s, ok := multipurposeIOModeStringKV[m]; ok { | ||
return s | ||
} | ||
|
||
return multipurposeIOModeStringKV[MultipurposeOff] | ||
} | ||
|
||
// GoString returns the Go syntax representation of a MultipurposeIOMode value. | ||
func (m MultipurposeIOMode) GoString() string { | ||
if s, ok := multipurposeIOModeGoStringKV[m]; ok { | ||
return s | ||
} | ||
|
||
return multipurposeIOModeGoStringKV[MultipurposeOff] | ||
} | ||
|
||
// MarshalText returns the text representation of a MultipurposeIOMode value. | ||
func (m MultipurposeIOMode) MarshalText() ([]byte, error) { | ||
if text, ok := multipurposeIOModeTextKV[m]; ok { | ||
return []byte(text), nil | ||
} | ||
|
||
return []byte(multipurposeIOModeTextKV[MultipurposeOff]), nil | ||
} | ||
|
||
// UnmarshalText updates the value of the MultipurposeIOMode receiver based on the input text. | ||
// - If the input text matches a valid mapping in the multipurposeIOModeTextVK map, | ||
// the receiver is updated to the corresponding MultipurposeIOMode value. | ||
// - If the input text does not match any valid mapping, the receiver is set to MultipurposeOff. | ||
// | ||
// This method does not return an error. | ||
func (m *MultipurposeIOMode) UnmarshalText(text []byte) error { | ||
if mode, ok := multipurposeIOModeTextVK[string(text)]; ok { | ||
*m = mode | ||
} else { | ||
*m = MultipurposeOff | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package types | ||
|
||
import ( | ||
"github.com/brianvoe/gofakeit/v7" | ||
"github.com/stretchr/testify/assert" | ||
"math" | ||
"testing" | ||
) | ||
|
||
func TestMultipurposeIOMode_String(t *testing.T) { | ||
type TestCase struct { | ||
name string | ||
mode MultipurposeIOMode | ||
want string | ||
} | ||
|
||
cases := []TestCase{ | ||
{"MultipurposeOff", MultipurposeOff, "off"}, | ||
{"MultipurposeInputNMEAUART", MultipurposeInputNMEAUART, "input from NMEA UART"}, | ||
{"MultipurposeOutputFromInternalOscillator", MultipurposeOutputFromInternalOscillator, "output from Internal Oscillator"}, | ||
{"MultipurposeOutputFromSyncPulseIn", MultipurposeOutputFromSyncPulseIn, "output from Sync Pulse in"}, | ||
{"MultipurposeOutputFromPTP1588", MultipurposeOutputFromPTP1588, "output from PTP 1588"}, | ||
{"MultipurposeOutputFromEncoderAngle", MultipurposeOutputFromEncoderAngle, "output from encoder angle"}, | ||
{"unknown value", math.MaxUint8, "off"}, | ||
} | ||
|
||
for _, c := range cases { | ||
t.Run(c.name, func(t *testing.T) { | ||
got := c.mode.String() | ||
assert.Equal(t, c.want, got, "it should return the correct representation") | ||
}) | ||
} | ||
} | ||
|
||
func TestMultipurposeIOMode_GoString(t *testing.T) { | ||
type TestCase struct { | ||
name string | ||
mode MultipurposeIOMode | ||
want string | ||
} | ||
|
||
cases := []TestCase{ | ||
{"MultipurposeOff", MultipurposeOff, "MultipurposeOff"}, | ||
{"MultipurposeInputNMEAUART", MultipurposeInputNMEAUART, "MultipurposeInputNMEAUART"}, | ||
{"MultipurposeOutputFromInternalOscillator", MultipurposeOutputFromInternalOscillator, "MultipurposeOutputFromInternalOscillator"}, | ||
{"MultipurposeOutputFromSyncPulseIn", MultipurposeOutputFromSyncPulseIn, "MultipurposeOutputFromSyncPulseIn"}, | ||
{"MultipurposeOutputFromPTP1588", MultipurposeOutputFromPTP1588, "MultipurposeOutputFromPTP1588"}, | ||
{"MultipurposeOutputFromEncoderAngle", MultipurposeOutputFromEncoderAngle, "MultipurposeOutputFromEncoderAngle"}, | ||
{"unknown value", math.MaxUint8, "MultipurposeOff"}, | ||
} | ||
|
||
for _, c := range cases { | ||
t.Run(c.name, func(t *testing.T) { | ||
got := c.mode.GoString() | ||
assert.Equal(t, c.want, got, "it should return the correct representation") | ||
}) | ||
} | ||
} | ||
|
||
func TestMultipurposeIOMode_MarshalText(t *testing.T) { | ||
type TestCase struct { | ||
name string | ||
mode MultipurposeIOMode | ||
want string | ||
} | ||
|
||
cases := []TestCase{ | ||
{"MultipurposeOff", MultipurposeOff, "OFF"}, | ||
{"MultipurposeInputNMEAUART", MultipurposeInputNMEAUART, "INPUT_NMEA_UART"}, | ||
{"MultipurposeOutputFromInternalOscillator", MultipurposeOutputFromInternalOscillator, "OUTPUT_FROM_INTERNAL_OSC"}, | ||
{"MultipurposeOutputFromSyncPulseIn", MultipurposeOutputFromSyncPulseIn, "OUTPUT_FROM_SYNC_PULSE_IN"}, | ||
{"MultipurposeOutputFromPTP1588", MultipurposeOutputFromPTP1588, "OUTPUT_FROM_PTP_1588"}, | ||
{"MultipurposeOutputFromEncoderAngle", MultipurposeOutputFromEncoderAngle, "OUTPUT_FROM_ENCODER_ANGLE"}, | ||
{"unknown value", math.MaxUint8, "OFF"}, | ||
} | ||
|
||
for _, c := range cases { | ||
t.Run(c.name, func(t *testing.T) { | ||
got, err := c.mode.MarshalText() | ||
assert.NoError(t, err, "it should not error") | ||
assert.Equal(t, []byte(c.want), got, "it should return the correct representation") | ||
}) | ||
} | ||
} | ||
|
||
func TestMultipurposeIOMode_UnmarshalText(t *testing.T) { | ||
type TestCase struct { | ||
name string | ||
text string | ||
want MultipurposeIOMode | ||
} | ||
|
||
cases := []TestCase{ | ||
{"MultipurposeOff", "OFF", MultipurposeOff}, | ||
{"MultipurposeInputNMEAUART", "INPUT_NMEA_UART", MultipurposeInputNMEAUART}, | ||
{"MultipurposeOutputFromInternalOscillator", "OUTPUT_FROM_INTERNAL_OSC", MultipurposeOutputFromInternalOscillator}, | ||
{"MultipurposeOutputFromSyncPulseIn", "OUTPUT_FROM_SYNC_PULSE_IN", MultipurposeOutputFromSyncPulseIn}, | ||
{"MultipurposeOutputFromPTP1588", "OUTPUT_FROM_PTP_1588", MultipurposeOutputFromPTP1588}, | ||
{"MultipurposeOutputFromEncoderAngle", "OUTPUT_FROM_ENCODER_ANGLE", MultipurposeOutputFromEncoderAngle}, | ||
{"unknown text", gofakeit.LoremIpsumSentence(4), MultipurposeOff}, | ||
} | ||
|
||
for _, c := range cases { | ||
t.Run(c.name, func(t *testing.T) { | ||
var m MultipurposeIOMode | ||
err := m.UnmarshalText([]byte(c.text)) | ||
assert.NoError(t, err, "it should not error") | ||
assert.Equal(t, c.want, m, "it should return the correct representation") | ||
}) | ||
} | ||
} |