feat: record autopilot steering and driveMode
This commit is contained in:
@ -11,12 +11,15 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func NewRecorder(client mqtt.Client, recordTopic, cameraTopic, steeringTopic, switchRecordTopic string) *Recorder {
|
||||
func NewRecorder(client mqtt.Client, recordTopic, cameraTopic, rcSteeringTopic, tfSteeringTopic, driveModeTopic,
|
||||
switchRecordTopic string) *Recorder {
|
||||
return &Recorder{
|
||||
client: client,
|
||||
recordTopic: recordTopic,
|
||||
cameraTopic: cameraTopic,
|
||||
steeringTopic: steeringTopic,
|
||||
rcSteeringTopic: rcSteeringTopic,
|
||||
tfSteeringTopic: tfSteeringTopic,
|
||||
driveModeTopic: driveModeTopic,
|
||||
switchRecordTopic: switchRecordTopic,
|
||||
enabled: false,
|
||||
idGenerator: NewDateBasedGenerator(),
|
||||
@ -26,12 +29,20 @@ func NewRecorder(client mqtt.Client, recordTopic, cameraTopic, steeringTopic, sw
|
||||
}
|
||||
|
||||
type Recorder struct {
|
||||
client mqtt.Client
|
||||
recordTopic string
|
||||
cameraTopic, steeringTopic, switchRecordTopic string
|
||||
client mqtt.Client
|
||||
recordTopic string
|
||||
cameraTopic, switchRecordTopic string
|
||||
|
||||
muSteeringMsg sync.Mutex
|
||||
currentSteering *events.SteeringMessage
|
||||
driveModeTopic, rcSteeringTopic, tfSteeringTopic string
|
||||
|
||||
muRcSteeringMsg sync.Mutex
|
||||
currentRcSteering *events.SteeringMessage
|
||||
|
||||
muTfSteeringMsg sync.Mutex
|
||||
currentTfSteering *events.SteeringMessage
|
||||
|
||||
muDriveModeMsg sync.Mutex
|
||||
currentDriveMode *events.DriveModeMessage
|
||||
|
||||
muEnabled sync.RWMutex
|
||||
enabled bool
|
||||
@ -57,7 +68,7 @@ func (r *Recorder) Start() error {
|
||||
|
||||
func (r *Recorder) Stop() {
|
||||
close(r.cancel)
|
||||
service.StopService("record", r.client, r.cameraTopic, r.steeringTopic)
|
||||
service.StopService("record", r.client, r.cameraTopic, r.rcSteeringTopic, r.tfSteeringTopic, r.driveModeTopic)
|
||||
}
|
||||
|
||||
func (r *Recorder) onSwitchRecord(_ mqtt.Client, message mqtt.Message) {
|
||||
@ -78,7 +89,7 @@ func (r *Recorder) onSwitchRecord(_ mqtt.Client, message mqtt.Message) {
|
||||
r.enabled = msg.GetEnabled()
|
||||
}
|
||||
|
||||
func (r *Recorder) onSteering(_ mqtt.Client, message mqtt.Message) {
|
||||
func (r *Recorder) onRcSteering(_ mqtt.Client, message mqtt.Message) {
|
||||
var msg events.SteeringMessage
|
||||
err := proto.Unmarshal(message.Payload(), &msg)
|
||||
if err != nil {
|
||||
@ -86,9 +97,35 @@ func (r *Recorder) onSteering(_ mqtt.Client, message mqtt.Message) {
|
||||
return
|
||||
}
|
||||
|
||||
r.muSteeringMsg.Lock()
|
||||
defer r.muSteeringMsg.Unlock()
|
||||
r.currentSteering = &msg
|
||||
r.muRcSteeringMsg.Lock()
|
||||
defer r.muRcSteeringMsg.Unlock()
|
||||
r.currentRcSteering = &msg
|
||||
}
|
||||
|
||||
func (r *Recorder) onTfSteering(_ mqtt.Client, message mqtt.Message) {
|
||||
var msg events.SteeringMessage
|
||||
err := proto.Unmarshal(message.Payload(), &msg)
|
||||
if err != nil {
|
||||
zap.S().Errorf("unable to unmarshal protobuf %T: %v", msg, err)
|
||||
return
|
||||
}
|
||||
|
||||
r.muTfSteeringMsg.Lock()
|
||||
defer r.muTfSteeringMsg.Unlock()
|
||||
r.currentTfSteering = &msg
|
||||
}
|
||||
|
||||
func (r *Recorder) onDriveMode(_ mqtt.Client, message mqtt.Message) {
|
||||
var msg events.DriveModeMessage
|
||||
err := proto.Unmarshal(message.Payload(), &msg)
|
||||
if err != nil {
|
||||
zap.S().Errorf("unable to unmarshal protobuf %T: %v", msg, err)
|
||||
return
|
||||
}
|
||||
|
||||
r.muDriveModeMsg.Lock()
|
||||
defer r.muDriveModeMsg.Unlock()
|
||||
r.currentDriveMode = &msg
|
||||
}
|
||||
|
||||
func (r *Recorder) onFrame(_ mqtt.Client, message mqtt.Message) {
|
||||
@ -109,10 +146,22 @@ func (r *Recorder) onFrame(_ mqtt.Client, message mqtt.Message) {
|
||||
return
|
||||
}
|
||||
|
||||
autopilot := r.CurrentAutopilotSteering()
|
||||
if autopilot == nil {
|
||||
zap.S().Warnf("no current autopilot steeringMsg")
|
||||
}
|
||||
|
||||
driveMode := r.CurrentDriveMode()
|
||||
if driveMode == nil {
|
||||
zap.S().Warnf("no current driveModeMsg")
|
||||
}
|
||||
|
||||
record := events.RecordMessage{
|
||||
Frame: &msg,
|
||||
Steering: steering,
|
||||
RecordSet: r.recordSet,
|
||||
Frame: &msg,
|
||||
Steering: steering,
|
||||
AutopilotSteering: autopilot,
|
||||
DriveMode: driveMode,
|
||||
RecordSet: r.recordSet,
|
||||
}
|
||||
|
||||
payload, err := proto.Marshal(&record)
|
||||
@ -128,12 +177,26 @@ var publish = func(client mqtt.Client, topic string, payload *[]byte) {
|
||||
}
|
||||
|
||||
func (r *Recorder) CurrentSteering() *events.SteeringMessage {
|
||||
r.muSteeringMsg.Lock()
|
||||
defer r.muSteeringMsg.Unlock()
|
||||
steering := r.currentSteering
|
||||
r.muRcSteeringMsg.Lock()
|
||||
defer r.muRcSteeringMsg.Unlock()
|
||||
steering := r.currentRcSteering
|
||||
return steering
|
||||
}
|
||||
|
||||
func (r *Recorder) CurrentAutopilotSteering() *events.SteeringMessage {
|
||||
r.muTfSteeringMsg.Lock()
|
||||
defer r.muTfSteeringMsg.Unlock()
|
||||
steering := r.currentTfSteering
|
||||
return steering
|
||||
}
|
||||
|
||||
func (r *Recorder) CurrentDriveMode() *events.DriveModeMessage {
|
||||
r.muDriveModeMsg.Lock()
|
||||
defer r.muDriveModeMsg.Unlock()
|
||||
driveMode := r.currentDriveMode
|
||||
return driveMode
|
||||
}
|
||||
|
||||
func (r *Recorder) Enabled() bool {
|
||||
r.muEnabled.RLock()
|
||||
defer r.muEnabled.RUnlock()
|
||||
@ -146,9 +209,19 @@ var registerCallBacks = func(r *Recorder) {
|
||||
zap.S().Panicf("unable to register callback to %v:%v", r.cameraTopic, err)
|
||||
}
|
||||
|
||||
err = service.RegisterCallback(r.client, r.steeringTopic, r.onSteering)
|
||||
err = service.RegisterCallback(r.client, r.rcSteeringTopic, r.onRcSteering)
|
||||
if err != nil {
|
||||
zap.S().Panicf("unable to register callback to %v:%v", r.steeringTopic, err)
|
||||
zap.S().Panicf("unable to register callback to %v:%v", r.rcSteeringTopic, err)
|
||||
}
|
||||
|
||||
err = service.RegisterCallback(r.client, r.tfSteeringTopic, r.onTfSteering)
|
||||
if err != nil {
|
||||
zap.S().Panicf("unable to register callback to %v:%v", r.tfSteeringTopic, err)
|
||||
}
|
||||
|
||||
err = service.RegisterCallback(r.client, r.driveModeTopic, r.onDriveMode)
|
||||
if err != nil {
|
||||
zap.S().Panicf("unable to register callback to %v:%v", r.driveModeTopic, err)
|
||||
}
|
||||
|
||||
err = service.RegisterCallback(r.client, r.switchRecordTopic, r.onSwitchRecord)
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
mqtt "github.com/eclipse/paho.mqtt.golang"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -27,6 +27,8 @@ func TestRecorder_Record(t *testing.T) {
|
||||
recordTopic := "topic/record"
|
||||
cameraTopic := "topic/camera"
|
||||
steeringTopic := "topic/steeringMsg"
|
||||
autopilotSteeringTopic := "topic/autopilot/steering"
|
||||
driveModeTopic := "topic/driveMode"
|
||||
switchRecord := "topic/switch/record"
|
||||
|
||||
var muEventsPublished sync.Mutex
|
||||
@ -46,7 +48,13 @@ func TestRecorder_Record(t *testing.T) {
|
||||
eventsPublished = &msg
|
||||
}
|
||||
|
||||
recorder := NewRecorder(nil, recordTopic, cameraTopic, steeringTopic, switchRecord)
|
||||
recorder := NewRecorder(nil,
|
||||
recordTopic,
|
||||
cameraTopic,
|
||||
steeringTopic,
|
||||
autopilotSteeringTopic,
|
||||
driveModeTopic,
|
||||
switchRecord)
|
||||
recorder.idGenerator = &DateBasedGenerator{
|
||||
muCpt: sync.Mutex{},
|
||||
cpt: 0,
|
||||
@ -64,24 +72,52 @@ func TestRecorder_Record(t *testing.T) {
|
||||
frame2 := loadImage(t, "testdata/img.jpg", "02")
|
||||
steeringRight := events.SteeringMessage{Steering: 0.5, Confidence: 1.0}
|
||||
steeringLeft := events.SteeringMessage{Steering: -0.5, Confidence: 1.0}
|
||||
autopilotLeft := events.SteeringMessage{Steering: -0.8, Confidence: 1.0}
|
||||
driveModeManuel := events.DriveModeMessage{DriveMode: events.DriveMode_USER}
|
||||
|
||||
cases := []struct {
|
||||
recordMsg *events.SwitchRecordMessage
|
||||
frameMsg *events.FrameMessage
|
||||
steeringMsg *events.SteeringMessage
|
||||
autopilotMsg *events.SteeringMessage
|
||||
driveModeMsg *events.DriveModeMessage
|
||||
expectedRecordMsg *events.RecordMessage
|
||||
wait time.Duration
|
||||
}{
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: false}, frameMsg: nil, steeringMsg: nil, expectedRecordMsg: nil, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: true}, frameMsg: nil, steeringMsg: nil, expectedRecordMsg: nil, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: true}, frameMsg: frame1, steeringMsg: nil, expectedRecordMsg: nil, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: true}, frameMsg: nil, steeringMsg: &steeringRight, expectedRecordMsg: nil, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: true}, frameMsg: frame1, steeringMsg: &steeringRight, expectedRecordMsg: &events.RecordMessage{RecordSet: "record-1", Frame: frame1, Steering: &steeringRight}, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: true}, frameMsg: nil, steeringMsg: &steeringLeft, expectedRecordMsg: nil, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: true}, frameMsg: frame2, steeringMsg: &steeringLeft, expectedRecordMsg: &events.RecordMessage{RecordSet: "record-1", Frame: frame2, Steering: &steeringLeft}, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: false}, frameMsg: nil, steeringMsg: nil, expectedRecordMsg: nil, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: false}, frameMsg: nil, steeringMsg: nil, expectedRecordMsg: nil, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: true}, frameMsg: frame1, steeringMsg: &steeringRight, expectedRecordMsg: &events.RecordMessage{RecordSet: "record-2", Frame: frame1, Steering: &steeringLeft}, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: false}, frameMsg: nil,
|
||||
steeringMsg: nil, autopilotMsg: nil, driveModeMsg: nil,
|
||||
expectedRecordMsg: nil, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: true}, frameMsg: nil,
|
||||
steeringMsg: nil, autopilotMsg: nil, driveModeMsg: nil,
|
||||
expectedRecordMsg: nil, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: true}, frameMsg: frame1,
|
||||
steeringMsg: nil, autopilotMsg: nil, driveModeMsg: nil,
|
||||
expectedRecordMsg: nil, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: true}, frameMsg: nil,
|
||||
steeringMsg: &steeringRight, autopilotMsg: nil, driveModeMsg: nil,
|
||||
expectedRecordMsg: nil, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: true}, frameMsg: frame1,
|
||||
steeringMsg: &steeringRight, autopilotMsg: nil, driveModeMsg: nil,
|
||||
expectedRecordMsg: &events.RecordMessage{RecordSet: "record-1", Frame: frame1, Steering: &steeringRight}, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: true}, frameMsg: nil,
|
||||
steeringMsg: &steeringLeft, autopilotMsg: nil, driveModeMsg: nil,
|
||||
expectedRecordMsg: nil, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: true}, frameMsg: frame2,
|
||||
steeringMsg: &steeringLeft, autopilotMsg: nil, driveModeMsg: nil,
|
||||
expectedRecordMsg: &events.RecordMessage{RecordSet: "record-1", Frame: frame2, Steering: &steeringLeft}, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: false}, frameMsg: nil,
|
||||
steeringMsg: nil, autopilotMsg: nil, driveModeMsg: nil,
|
||||
expectedRecordMsg: nil, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: false}, frameMsg: nil,
|
||||
steeringMsg: nil, autopilotMsg: nil, driveModeMsg: nil,
|
||||
expectedRecordMsg: nil, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: true}, frameMsg: frame1,
|
||||
steeringMsg: &steeringRight, autopilotMsg: nil, driveModeMsg: nil,
|
||||
expectedRecordMsg: &events.RecordMessage{RecordSet: "record-2", Frame: frame1, Steering: &steeringLeft}, wait: 5 * time.Millisecond},
|
||||
{recordMsg: &events.SwitchRecordMessage{Enabled: true}, frameMsg: frame1,
|
||||
steeringMsg: &steeringRight, autopilotMsg: &autopilotLeft, driveModeMsg: &driveModeManuel,
|
||||
expectedRecordMsg: &events.RecordMessage{RecordSet: "record-2", Frame: frame1, Steering: &steeringRight, AutopilotSteering: &autopilotLeft, DriveMode: &driveModeManuel},
|
||||
wait: 5 * time.Millisecond},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
@ -89,6 +125,12 @@ func TestRecorder_Record(t *testing.T) {
|
||||
eventsPublished = nil
|
||||
muEventsPublished.Unlock()
|
||||
|
||||
if c.autopilotMsg != nil {
|
||||
recorder.onTfSteering(nil, testtools.NewFakeMessageFromProtobuf(autopilotSteeringTopic, c.autopilotMsg))
|
||||
}
|
||||
if c.driveModeMsg != nil {
|
||||
recorder.onDriveMode(nil, testtools.NewFakeMessageFromProtobuf(driveModeTopic, c.driveModeMsg))
|
||||
}
|
||||
if c.recordMsg != nil {
|
||||
recorder.onSwitchRecord(nil, testtools.NewFakeMessageFromProtobuf(recordTopic, c.recordMsg))
|
||||
}
|
||||
@ -96,7 +138,7 @@ func TestRecorder_Record(t *testing.T) {
|
||||
recorder.onFrame(nil, testtools.NewFakeMessageFromProtobuf(cameraTopic, c.frameMsg))
|
||||
}
|
||||
if c.steeringMsg != nil {
|
||||
recorder.onSteering(nil, testtools.NewFakeMessageFromProtobuf(steeringTopic, c.steeringMsg))
|
||||
recorder.onRcSteering(nil, testtools.NewFakeMessageFromProtobuf(steeringTopic, c.steeringMsg))
|
||||
}
|
||||
|
||||
time.Sleep(c.wait)
|
||||
@ -112,7 +154,7 @@ func TestRecorder_Record(t *testing.T) {
|
||||
}
|
||||
|
||||
func loadImage(t *testing.T, imgPath string, id string) *events.FrameMessage {
|
||||
jpegContent, err := ioutil.ReadFile(imgPath)
|
||||
jpegContent, err := os.ReadFile(imgPath)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to load image: %v", err)
|
||||
}
|
||||
|
Reference in New Issue
Block a user