Rename service and implement record subcommand

This commit is contained in:
Cyrille Nofficial 2020-01-28 23:18:35 +01:00
parent 11c3c4139b
commit 2a80163c5d
10 changed files with 382 additions and 146 deletions

View File

@ -1,15 +1,23 @@
# robocar-display
Tool to display camera frame and metrics
Tools to manage robocar
## Usage
`rc-display <OPTIONS>`
## Display
Display events on live frames.
```
rc-tool display
Usage of display:
-frame-path string
Directory path where to read jpeg frame to inject in frame topic
-frame-per-second int
Video frame per second of frame to publish (default 25)
-mqtt-broker string
Broker Uri, use MQTT_BROKER env if arg not set (default "tcp://127.0.0.1:1883")
-mqtt-client-id string
Mqtt client id, use MQTT_CLIENT_ID env if args not set (default "robocar-display")
Mqtt client id, use MQTT_CLIENT_ID env if args not set (default "robocar-tools")
-mqtt-password string
Broker Password, MQTT_PASSWORD env if args not set
-mqtt-qos int
@ -30,3 +38,30 @@ Tool to display camera frame and metrics
Display detected road
```
## Record
Record event for tensorflow training
```
rc-tools record
Usage of record:
-mqtt-broker string
Broker Uri, use MQTT_BROKER env if arg not set (default "tcp://127.0.0.1:1883")
-mqtt-client-id string
Mqtt client id, use MQTT_CLIENT_ID env if args not set (default "robocar-tools")
-mqtt-password string
Broker Password, MQTT_PASSWORD env if args not set
-mqtt-qos int
Qos to pusblish message, use MQTT_QOS env if arg not set
-mqtt-retain
Retain mqtt message, if not set, true if MQTT_RETAIN env variable is set
-mqtt-topic-records string
Mqtt topic that contains record data for training, use MQTT_TOPIC_RECORDS if args not set
-mqtt-username string
Broker Username, use MQTT_USERNAME env if arg not set
-record-image-path string
Path where to write jpeg files, use RECORD_IMAGE_PATH if args not set
-record-json-path string
Path where to write json files, use RECORD_JSON_PATH if args not set
```

View File

@ -1,72 +0,0 @@
package main
import (
"flag"
"github.com/cyrilix/robocar-base/cli"
"github.com/cyrilix/robocar-display/part"
"github.com/cyrilix/robocar-display/video"
"log"
"os"
)
const (
DefaultClientId = "robocar-display"
)
func main() {
var mqttBroker, username, password, clientId string
var framePath string
var fps int
var frameTopic, objectsTopic, roadTopic string
var withObjects, withRoad bool
mqttQos := cli.InitIntFlag("MQTT_QOS", 0)
_, mqttRetain := os.LookupEnv("MQTT_RETAIN")
cli.InitMqttFlags(DefaultClientId, &mqttBroker, &username, &password, &clientId, &mqttQos, &mqttRetain)
flag.StringVar(&frameTopic, "mqtt-topic-frame", os.Getenv("MQTT_TOPIC_FRAME"), "Mqtt topic that contains frame to display, use MQTT_TOPIC_FRAME if args not set")
flag.StringVar(&framePath, "frame-path", "", "Directory path where to read jpeg frame to inject in frame topic")
flag.IntVar(&fps, "frame-per-second", 25, "Video frame per second of frame to publish")
flag.StringVar(&objectsTopic, "mqtt-topic-objects", os.Getenv("MQTT_TOPIC_OBJECTS"), "Mqtt topic that contains detected objects, use MQTT_TOPIC_OBJECTS if args not set")
flag.BoolVar(&withObjects, "with-objects", false, "Display detected objects")
flag.StringVar(&roadTopic, "mqtt-topic-road", os.Getenv("MQTT_TOPIC_ROAD"), "Mqtt topic that contains road description, use MQTT_TOPIC_ROAD if args not set")
flag.BoolVar(&withRoad, "with-road", false, "Display detected road")
flag.Parse()
if len(os.Args) <= 1 {
flag.PrintDefaults()
os.Exit(1)
}
client, err := cli.Connect(mqttBroker, username, password, clientId)
if err != nil {
log.Fatalf("unable to connect to mqtt bus: %v", err)
}
defer client.Disconnect(50)
if framePath != "" {
camera, err := video.NewCameraFake(client, frameTopic, framePath, fps)
if err != nil {
log.Fatalf("unable to load fake camera: %v", err)
}
if err = camera.Start(); err != nil {
log.Fatalf("unable to start fake camera: %v", err)
}
defer camera.Stop()
}
p := part.NewPart(client, frameTopic,
objectsTopic, roadTopic,
withObjects, withRoad )
defer p.Stop()
cli.HandleExit(p)
err = p.Start()
if err != nil {
log.Fatalf("unable to start service: %v", err)
}
}

135
cmd/rc-tools/rc-tools.go Normal file
View File

@ -0,0 +1,135 @@
package main
import (
"flag"
"fmt"
"github.com/cyrilix/robocar-base/cli"
"github.com/cyrilix/robocar-tools/part"
"github.com/cyrilix/robocar-tools/record"
"github.com/cyrilix/robocar-tools/video"
mqtt "github.com/eclipse/paho.mqtt.golang"
log "github.com/sirupsen/logrus"
"os"
)
const (
DefaultClientId = "robocar-tools"
)
func main() {
var mqttBroker, username, password, clientId string
var framePath string
var fps int
var frameTopic, objectsTopic, roadTopic, recordTopic string
var withObjects, withRoad bool
var jsonPath, imgPath string
mqttQos := cli.InitIntFlag("MQTT_QOS", 0)
_, mqttRetain := os.LookupEnv("MQTT_RETAIN")
flag.Usage = func() {
fmt.Printf("Usage of %s:\n", os.Args[0])
fmt.Printf(" display\n \tDisplay events on live frames\n")
fmt.Printf(" record \n \tRecord event for tensorflow training\n")
}
displayFlags := flag.NewFlagSet("display", flag.ExitOnError)
cli.InitMqttFlagSet(displayFlags, DefaultClientId, &mqttBroker, &username, &password, &clientId, &mqttQos, &mqttRetain)
displayFlags.StringVar(&frameTopic, "mqtt-topic-frame", os.Getenv("MQTT_TOPIC_FRAME"), "Mqtt topic that contains frame to display, use MQTT_TOPIC_FRAME if args not set")
displayFlags.StringVar(&framePath, "frame-path", "", "Directory path where to read jpeg frame to inject in frame topic")
displayFlags.IntVar(&fps, "frame-per-second", 25, "Video frame per second of frame to publish")
displayFlags.StringVar(&objectsTopic, "mqtt-topic-objects", os.Getenv("MQTT_TOPIC_OBJECTS"), "Mqtt topic that contains detected objects, use MQTT_TOPIC_OBJECTS if args not set")
displayFlags.BoolVar(&withObjects, "with-objects", false, "Display detected objects")
displayFlags.StringVar(&roadTopic, "mqtt-topic-road", os.Getenv("MQTT_TOPIC_ROAD"), "Mqtt topic that contains road description, use MQTT_TOPIC_ROAD if args not set")
displayFlags.BoolVar(&withRoad, "with-road", false, "Display detected road")
recordFlags := flag.NewFlagSet("record", flag.ExitOnError)
cli.InitMqttFlagSet(recordFlags, DefaultClientId, &mqttBroker, &username, &password, &clientId, &mqttQos, &mqttRetain)
recordFlags.StringVar(&recordTopic, "mqtt-topic-records", os.Getenv("MQTT_TOPIC_RECORDS"), "Mqtt topic that contains record data for training, use MQTT_TOPIC_RECORDS if args not set")
recordFlags.StringVar(&jsonPath, "record-json-path", os.Getenv("RECORD_JSON_PATH"), "Path where to write json files, use RECORD_JSON_PATH if args not set")
recordFlags.StringVar(&imgPath, "record-image-path", os.Getenv("RECORD_IMAGE_PATH"), "Path where to write jpeg files, use RECORD_IMAGE_PATH if args not set")
flag.Parse()
// Switch on the subcommand
// Parse the flags for appropriate FlagSet
// FlagSet.Parse() requires a set of arguments to parse as input
// os.Args[2:] will be all arguments starting after the subcommand at os.Args[1]
switch flag.Arg(0) {
case displayFlags.Name():
if err := displayFlags.Parse(os.Args[2:]); err == flag.ErrHelp {
displayFlags.PrintDefaults()
os.Exit(0)
}
client, err := cli.Connect(mqttBroker, username, password, clientId)
if err != nil {
log.Fatalf("unable to connect to mqtt bus: %v", err)
}
defer client.Disconnect(50)
runDisplay(client, framePath, frameTopic, fps, objectsTopic, roadTopic, withObjects, withRoad)
case recordFlags.Name():
if err := recordFlags.Parse(os.Args[2:]); err == flag.ErrHelp {
recordFlags.PrintDefaults()
os.Exit(0)
}
client, err := cli.Connect(mqttBroker, username, password, clientId)
if err != nil {
log.Fatalf("unable to connect to mqtt bus: %v", err)
}
defer client.Disconnect(50)
runRecord(client, jsonPath, imgPath, recordTopic)
default:
flag.PrintDefaults()
os.Exit(1)
}
cmd := flag.Arg(1)
switch cmd {
case "display":
case "record":
default:
log.Errorf("invalid command: %v", cmd)
}
}
func runRecord(client mqtt.Client, jsonDir, imgDir string, recordTopic string) {
r := record.New(client, jsonDir, imgDir, recordTopic)
defer r.Stop()
cli.HandleExit(r)
err := r.Start()
if err != nil {
log.Fatalf("unable to start service: %v", err)
}
}
func runDisplay(client mqtt.Client, framePath string, frameTopic string, fps int, objectsTopic string, roadTopic string, withObjects bool, withRoad bool) {
if framePath != "" {
camera, err := video.NewCameraFake(client, frameTopic, framePath, fps)
if err != nil {
log.Fatalf("unable to load fake camera: %v", err)
}
if err = camera.Start(); err != nil {
log.Fatalf("unable to start fake camera: %v", err)
}
defer camera.Stop()
}
p := part.NewPart(client, frameTopic,
objectsTopic, roadTopic,
withObjects, withRoad)
defer p.Stop()
cli.HandleExit(p)
err := p.Start()
if err != nil {
log.Fatalf("unable to start service: %v", err)
}
}

6
go.mod
View File

@ -1,10 +1,10 @@
module github.com/cyrilix/robocar-display
module github.com/cyrilix/robocar-tools
go 1.13
require (
github.com/cyrilix/robocar-base v0.0.0-20200103000136-b08c9be9a69a
github.com/cyrilix/robocar-protobuf/go v0.0.0-20200103235248-776649d250ff
github.com/cyrilix/robocar-base v0.0.0-20200128185221-fee4454c12c7
github.com/cyrilix/robocar-protobuf/go v0.0.0-20200125171436-7bf31bd564b8
github.com/eclipse/paho.mqtt.golang v1.2.0
github.com/golang/protobuf v1.3.2
github.com/sirupsen/logrus v1.4.2

8
go.sum
View File

@ -5,10 +5,10 @@ github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXn
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/cyrilix/robocar-base v0.0.0-20200103000136-b08c9be9a69a h1:Gznzd8APE9C+rkN3ePlKajYhgmNaCO7aJQ2WeNvoSt8=
github.com/cyrilix/robocar-base v0.0.0-20200103000136-b08c9be9a69a/go.mod h1:jRQ+lJAHKkdcjwS5vt2t5LX2zM+bxX+gKffixkc2lbA=
github.com/cyrilix/robocar-protobuf/go v0.0.0-20200103235248-776649d250ff h1:o92c28z6MCBh+WohNO4pkpKHumWcYjnrg4iW9U79N7s=
github.com/cyrilix/robocar-protobuf/go v0.0.0-20200103235248-776649d250ff/go.mod h1:I+i6Ujns+4DmRmmUej56MItlmT4K2zlMZ35vZrHEfQ4=
github.com/cyrilix/robocar-base v0.0.0-20200128185221-fee4454c12c7 h1:L7eLJDN59NALVN36Y/9Akt1BI0RfY7f1MqHQmR2yRKA=
github.com/cyrilix/robocar-base v0.0.0-20200128185221-fee4454c12c7/go.mod h1:jRQ+lJAHKkdcjwS5vt2t5LX2zM+bxX+gKffixkc2lbA=
github.com/cyrilix/robocar-protobuf/go v0.0.0-20200125171436-7bf31bd564b8 h1:8q1eiK2ii5IaztZUvW/rCaZoQMXqFR+EOP+8vUEAIgk=
github.com/cyrilix/robocar-protobuf/go v0.0.0-20200125171436-7bf31bd564b8/go.mod h1:I+i6Ujns+4DmRmmUej56MItlmT4K2zlMZ35vZrHEfQ4=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v0.7.3-0.20190506211059-b20a14b54661/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=

View File

@ -176,7 +176,7 @@ func (p *FramePart) drawRoad(img *gocv.Mat, road *events.RoadMessage) {
img,
[][]image.Point{cntr},
0,
color.RGBA{R: 255, G: 0, B: 0, A: 128,},
color.RGBA{R: 255, G: 0, B: 0, A: 128},
-1)
}

82
record/record.go Normal file
View File

@ -0,0 +1,82 @@
package record
import (
"encoding/json"
"fmt"
"github.com/cyrilix/robocar-base/service"
"github.com/cyrilix/robocar-protobuf/go/events"
mqtt "github.com/eclipse/paho.mqtt.golang"
"github.com/golang/protobuf/proto"
log "github.com/sirupsen/logrus"
"io/ioutil"
)
func New(client mqtt.Client, jsonDir, imgDir string, recordTopic string) *Recorder {
return &Recorder{
client: client,
jsonDir: jsonDir,
imgDir: imgDir,
recordTopic: recordTopic,
cancel: make(chan interface{}),
}
}
type Recorder struct {
client mqtt.Client
jsonDir, imgDir string
recordTopic string
cancel chan interface{}
}
func (r *Recorder) Start() error {
err := service.RegisterCallback(r.client, r.recordTopic, r.onRecordMsg)
if err != nil {
return fmt.Errorf("unable to start recorder part: %v", err)
}
<-r.cancel
return nil
}
func (r *Recorder) Stop() {
service.StopService("record", r.client, r.recordTopic)
close(r.cancel)
}
func (r *Recorder) onRecordMsg(_ mqtt.Client, message mqtt.Message) {
var msg events.RecordMessage
err := proto.Unmarshal(message.Payload(), &msg)
if err != nil {
log.Errorf("unable to unmarshal protobuf %T: %v", msg, err)
return
}
imgName := fmt.Sprintf("cam-image_array_%s.jpg", msg.GetFrame().GetId().GetId())
err = ioutil.WriteFile(imgName, msg.GetFrame().GetFrame(), 0755)
if err != nil {
log.Errorf("unable to write json file %v: %v", imgName, err)
return
}
recordName := fmt.Sprintf("record_%s.jpg", msg.GetFrame().GetId().GetId())
record := Record{
UserAngle: msg.GetSteering().GetSteering(),
CamImageArray: imgName,
}
jsonBytes, err := json.Marshal(&record)
if err != nil {
log.Errorf("unable to marshal json content: %v", err)
return
}
err = ioutil.WriteFile(recordName, jsonBytes, 0755)
if err != nil {
log.Errorf("unable to write json file %v: %v", recordName, err)
}
}
type Record struct {
UserAngle float32 `json:"user/angle,"`
CamImageArray string `json:"cam/image_array,"`
}

View File

@ -61,16 +61,20 @@ func HandleExit(p service.Part) {
}()
}
func InitMqttFlags(defaultClientId string, mqttBroker, username, password, clientId *string, mqttQos *int, mqttRetain *bool) {
func InitMqttFlagSet(flagSet *flag.FlagSet, defaultClientId string, mqttBroker, username, password, clientId *string, mqttQos *int, mqttRetain *bool) {
SetDefaultValueFromEnv(clientId, "MQTT_CLIENT_ID", defaultClientId)
SetDefaultValueFromEnv(mqttBroker, "MQTT_BROKER", "tcp://127.0.0.1:1883")
flag.StringVar(mqttBroker, "mqtt-broker", *mqttBroker, "Broker Uri, use MQTT_BROKER env if arg not set")
flag.StringVar(username, "mqtt-username", os.Getenv("MQTT_USERNAME"), "Broker Username, use MQTT_USERNAME env if arg not set")
flag.StringVar(password, "mqtt-password", os.Getenv("MQTT_PASSWORD"), "Broker Password, MQTT_PASSWORD env if args not set")
flag.StringVar(clientId, "mqtt-client-id", *clientId, "Mqtt client id, use MQTT_CLIENT_ID env if args not set")
flag.IntVar(mqttQos, "mqtt-qos", *mqttQos, "Qos to pusblish message, use MQTT_QOS env if arg not set")
flag.BoolVar(mqttRetain, "mqtt-retain", *mqttRetain, "Retain mqtt message, if not set, true if MQTT_RETAIN env variable is set")
flagSet.StringVar(mqttBroker, "mqtt-broker", *mqttBroker, "Broker Uri, use MQTT_BROKER env if arg not set")
flagSet.StringVar(username, "mqtt-username", os.Getenv("MQTT_USERNAME"), "Broker Username, use MQTT_USERNAME env if arg not set")
flagSet.StringVar(password, "mqtt-password", os.Getenv("MQTT_PASSWORD"), "Broker Password, MQTT_PASSWORD env if args not set")
flagSet.StringVar(clientId, "mqtt-client-id", *clientId, "Mqtt client id, use MQTT_CLIENT_ID env if args not set")
flagSet.IntVar(mqttQos, "mqtt-qos", *mqttQos, "Qos to pusblish message, use MQTT_QOS env if arg not set")
flagSet.BoolVar(mqttRetain, "mqtt-retain", *mqttRetain, "Retain mqtt message, if not set, true if MQTT_RETAIN env variable is set")
}
func InitMqttFlags(defaultClientId string, mqttBroker, username, password, clientId *string, mqttQos *int, mqttRetain *bool) {
InitMqttFlagSet(flag.CommandLine, defaultClientId, mqttBroker, username, password, clientId, mqttQos, mqttRetain)
}
func InitIntFlag(key string, defValue int) int {

View File

@ -671,6 +671,54 @@ func (m *Ellipse) GetConfidence() float32 {
return 0
}
// Record message used to tensorflow learning
type RecordMessage struct {
Frame *FrameMessage `protobuf:"bytes,1,opt,name=frame,proto3" json:"frame,omitempty"`
Steering *SteeringMessage `protobuf:"bytes,2,opt,name=steering,proto3" json:"steering,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *RecordMessage) Reset() { *m = RecordMessage{} }
func (m *RecordMessage) String() string { return proto.CompactTextString(m) }
func (*RecordMessage) ProtoMessage() {}
func (*RecordMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_8ec31f2d2a3db598, []int{11}
}
func (m *RecordMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RecordMessage.Unmarshal(m, b)
}
func (m *RecordMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_RecordMessage.Marshal(b, m, deterministic)
}
func (m *RecordMessage) XXX_Merge(src proto.Message) {
xxx_messageInfo_RecordMessage.Merge(m, src)
}
func (m *RecordMessage) XXX_Size() int {
return xxx_messageInfo_RecordMessage.Size(m)
}
func (m *RecordMessage) XXX_DiscardUnknown() {
xxx_messageInfo_RecordMessage.DiscardUnknown(m)
}
var xxx_messageInfo_RecordMessage proto.InternalMessageInfo
func (m *RecordMessage) GetFrame() *FrameMessage {
if m != nil {
return m.Frame
}
return nil
}
func (m *RecordMessage) GetSteering() *SteeringMessage {
if m != nil {
return m.Steering
}
return nil
}
func init() {
proto.RegisterEnum("robocar.events.DriveMode", DriveMode_name, DriveMode_value)
proto.RegisterEnum("robocar.events.TypeObject", TypeObject_name, TypeObject_value)
@ -685,51 +733,55 @@ func init() {
proto.RegisterType((*RoadMessage)(nil), "robocar.events.RoadMessage")
proto.RegisterType((*Point)(nil), "robocar.events.Point")
proto.RegisterType((*Ellipse)(nil), "robocar.events.Ellipse")
proto.RegisterType((*RecordMessage)(nil), "robocar.events.RecordMessage")
}
func init() { proto.RegisterFile("events/events.proto", fileDescriptor_8ec31f2d2a3db598) }
var fileDescriptor_8ec31f2d2a3db598 = []byte{
// 649 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xcb, 0x6e, 0xd3, 0x5c,
0x10, 0xae, 0x9d, 0x38, 0x76, 0x26, 0x55, 0x7e, 0xeb, 0xf4, 0xa7, 0x98, 0x2c, 0xa0, 0x32, 0x9b,
0xa8, 0x52, 0x1d, 0x08, 0x42, 0x82, 0x65, 0x4a, 0x8b, 0x54, 0xa9, 0x97, 0xe8, 0x34, 0x45, 0x82,
0x4d, 0xe4, 0xd8, 0xe3, 0xc4, 0xc8, 0xf1, 0x89, 0xec, 0xd3, 0x4b, 0xf6, 0x3c, 0x06, 0x0f, 0xc0,
0x82, 0x87, 0x44, 0x3e, 0x97, 0xd0, 0x5a, 0xaa, 0x84, 0x90, 0x58, 0x65, 0xbe, 0x39, 0x33, 0xdf,
0x7c, 0x73, 0x89, 0x61, 0x07, 0x6f, 0x30, 0xe7, 0xe5, 0x40, 0xfe, 0x04, 0xab, 0x82, 0x71, 0x46,
0xba, 0x05, 0x9b, 0xb1, 0x28, 0x2c, 0x02, 0xe9, 0xed, 0xbd, 0x98, 0x33, 0x36, 0xcf, 0x70, 0x20,
0x5e, 0x67, 0xd7, 0xc9, 0x80, 0xa7, 0x4b, 0x2c, 0x79, 0xb8, 0x5c, 0xc9, 0x04, 0x3f, 0x05, 0xe7,
0x63, 0x11, 0x2e, 0x91, 0x62, 0x42, 0x08, 0x34, 0xf3, 0x70, 0x89, 0x9e, 0xb1, 0x67, 0xf4, 0xdb,
0x54, 0xd8, 0xa4, 0x0b, 0x66, 0x1a, 0x7b, 0xa6, 0xf0, 0x98, 0x69, 0x4c, 0xde, 0x03, 0x44, 0x05,
0x86, 0x1c, 0xe3, 0x69, 0xc8, 0xbd, 0xc6, 0x9e, 0xd1, 0xef, 0x0c, 0x7b, 0x81, 0xac, 0x12, 0xe8,
0x2a, 0xc1, 0x44, 0x57, 0xa1, 0x6d, 0x15, 0x3d, 0xe2, 0xfe, 0x39, 0x6c, 0x8b, 0x52, 0x67, 0x58,
0x96, 0xe1, 0x1c, 0x49, 0x5f, 0x50, 0x1b, 0x82, 0xc2, 0x0b, 0x1e, 0x0a, 0x0f, 0xb4, 0x28, 0x51,
0xf4, 0x7f, 0xb0, 0x92, 0x0a, 0x0b, 0x1d, 0xdb, 0x54, 0x02, 0xff, 0x9b, 0x01, 0xff, 0x5d, 0x72,
0xc4, 0x22, 0xcd, 0xe7, 0x9a, 0xb3, 0x07, 0x4e, 0xa9, 0x5c, 0x82, 0xd9, 0xa4, 0x1b, 0x4c, 0x9e,
0x03, 0x44, 0x2c, 0x4f, 0xd2, 0x18, 0xf3, 0x48, 0x52, 0x99, 0xf4, 0x9e, 0x87, 0xbc, 0x85, 0xb6,
0x20, 0x9e, 0x16, 0x98, 0xa8, 0xce, 0x1e, 0x97, 0xe5, 0x24, 0xca, 0x12, 0x32, 0x26, 0x8b, 0x82,
0x71, 0x9e, 0xe1, 0x3d, 0x19, 0x5c, 0xb9, 0xb4, 0x0c, 0x8d, 0xff, 0x95, 0x8c, 0x53, 0x70, 0x8f,
0x8a, 0xf4, 0x06, 0xcf, 0x58, 0xbc, 0x91, 0xf1, 0x0e, 0x20, 0xae, 0x7c, 0xd3, 0x25, 0x8b, 0xa5,
0x90, 0xee, 0xf0, 0x59, 0x9d, 0x6b, 0x93, 0x45, 0xdb, 0xb1, 0x36, 0xfd, 0x35, 0x74, 0x2f, 0x66,
0x5f, 0x31, 0xe2, 0xa5, 0xe6, 0x7a, 0x05, 0x36, 0x93, 0x1e, 0xcf, 0xd8, 0x6b, 0xf4, 0x3b, 0xc3,
0xdd, 0x3a, 0x91, 0x4c, 0xa0, 0x3a, 0xec, 0x61, 0x23, 0xe6, 0x1f, 0x37, 0xf2, 0xd3, 0x80, 0x96,
0xa4, 0x22, 0x01, 0x34, 0xf9, 0x7a, 0xa5, 0x95, 0xf7, 0xea, 0xc9, 0x93, 0xf5, 0x0a, 0x55, 0x51,
0x11, 0x57, 0x1d, 0x70, 0x86, 0x09, 0x17, 0xc5, 0x2c, 0x2a, 0x6c, 0xe2, 0x42, 0x83, 0xb3, 0x95,
0x18, 0xa4, 0x45, 0x2b, 0xb3, 0xba, 0xa6, 0x22, 0x9d, 0x2f, 0xb8, 0xd7, 0x14, 0x3e, 0x09, 0xc8,
0x2e, 0xb4, 0x66, 0x8c, 0x73, 0xb6, 0xf4, 0x2c, 0xe1, 0x56, 0xa8, 0xb6, 0xae, 0x56, 0x7d, 0x5d,
0xfe, 0x00, 0x76, 0x2e, 0x6f, 0x53, 0x1e, 0x2d, 0x28, 0x46, 0xac, 0x88, 0xf5, 0xb8, 0x3c, 0xb0,
0x31, 0x0f, 0x67, 0x19, 0xca, 0x0b, 0x77, 0xa8, 0x86, 0xfe, 0x0f, 0x03, 0x3a, 0x94, 0x85, 0x9b,
0xc8, 0x01, 0xd8, 0x11, 0xcb, 0x39, 0xbb, 0x2e, 0xd4, 0x60, 0x9f, 0xd4, 0xfb, 0x1c, 0xb3, 0x34,
0xe7, 0x54, 0x47, 0x91, 0xd7, 0x60, 0x63, 0x96, 0xa5, 0xab, 0x12, 0xd5, 0x54, 0x9f, 0xd6, 0x13,
0x8e, 0xe5, 0x33, 0xd5, 0x71, 0x7f, 0x7b, 0x53, 0x2f, 0xc1, 0x12, 0xb5, 0xc9, 0x36, 0x18, 0x77,
0xa2, 0x0f, 0x8b, 0x1a, 0x77, 0x15, 0x5a, 0xab, 0x19, 0x1b, 0x6b, 0xff, 0xbb, 0x01, 0xb6, 0x2a,
0x48, 0x0e, 0xa0, 0x15, 0x61, 0xce, 0xb1, 0x50, 0x7f, 0xeb, 0x47, 0x5a, 0x51, 0x41, 0xd5, 0x26,
0x6e, 0xd3, 0x98, 0x2f, 0x14, 0x99, 0x04, 0xd5, 0x26, 0x16, 0x28, 0x16, 0x24, 0x97, 0xa6, 0x50,
0x15, 0x1d, 0xe6, 0xf3, 0x0c, 0xc5, 0xde, 0x4c, 0x2a, 0x41, 0x6d, 0x3f, 0x56, 0x7d, 0x3f, 0xfb,
0x07, 0xd0, 0xde, 0x5c, 0x38, 0xe9, 0x80, 0x7d, 0x72, 0xfe, 0x69, 0x74, 0x7a, 0x72, 0xe4, 0x6e,
0x11, 0x07, 0x9a, 0x57, 0x97, 0xc7, 0xd4, 0x35, 0x48, 0x1b, 0xac, 0xf1, 0xc9, 0xe9, 0xc5, 0xc4,
0x35, 0xf7, 0x87, 0x00, 0xbf, 0xcf, 0x8a, 0xd8, 0xd0, 0x18, 0x9d, 0x7f, 0x76, 0xb7, 0x2a, 0xe3,
0xc3, 0xa8, 0x0a, 0x75, 0xa0, 0x79, 0x78, 0x75, 0x36, 0x76, 0xcd, 0xca, 0x1a, 0x57, 0x39, 0x8d,
0x43, 0xe7, 0x4b, 0x4b, 0xb6, 0x37, 0x6b, 0x89, 0x2f, 0xe0, 0x9b, 0x5f, 0x01, 0x00, 0x00, 0xff,
0xff, 0xed, 0xb2, 0x58, 0x43, 0x9c, 0x05, 0x00, 0x00,
// 689 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0x4b, 0x6f, 0xd3, 0x5a,
0x10, 0xee, 0x71, 0xe2, 0x3c, 0x26, 0xbd, 0xb9, 0xd1, 0xe9, 0xbd, 0xbd, 0xbe, 0x11, 0xa2, 0x95,
0xd9, 0x44, 0x95, 0xea, 0x40, 0x10, 0x12, 0x88, 0x55, 0x4a, 0x8b, 0x54, 0xa9, 0x8f, 0xe8, 0x34,
0x45, 0x82, 0x4d, 0xe5, 0xd8, 0xe3, 0xc4, 0xc8, 0xf1, 0x89, 0xec, 0xd3, 0x47, 0x76, 0x2c, 0xf8,
0x19, 0xfc, 0x00, 0x16, 0xfc, 0x48, 0xe4, 0xf3, 0x48, 0x5b, 0x43, 0x25, 0x84, 0xc4, 0x2a, 0xf3,
0x4d, 0x66, 0xbe, 0xf9, 0x66, 0xe6, 0x78, 0x60, 0x03, 0xaf, 0x30, 0x15, 0x79, 0x5f, 0xfd, 0x78,
0x8b, 0x8c, 0x0b, 0x4e, 0xdb, 0x19, 0x9f, 0xf0, 0xc0, 0xcf, 0x3c, 0xe5, 0xed, 0x6e, 0x4d, 0x39,
0x9f, 0x26, 0xd8, 0x97, 0xff, 0x4e, 0x2e, 0xa3, 0xbe, 0x88, 0xe7, 0x98, 0x0b, 0x7f, 0xbe, 0x50,
0x09, 0x6e, 0x0c, 0x8d, 0xb7, 0x99, 0x3f, 0x47, 0x86, 0x11, 0xa5, 0x50, 0x4d, 0xfd, 0x39, 0x3a,
0x64, 0x9b, 0xf4, 0x9a, 0x4c, 0xda, 0xb4, 0x0d, 0x56, 0x1c, 0x3a, 0x96, 0xf4, 0x58, 0x71, 0x48,
0x5f, 0x01, 0x04, 0x19, 0xfa, 0x02, 0xc3, 0x0b, 0x5f, 0x38, 0x95, 0x6d, 0xd2, 0x6b, 0x0d, 0xba,
0x9e, 0xaa, 0xe2, 0x99, 0x2a, 0xde, 0xd8, 0x54, 0x61, 0x4d, 0x1d, 0x3d, 0x14, 0xee, 0x09, 0xac,
0xcb, 0x52, 0xc7, 0x98, 0xe7, 0xfe, 0x14, 0x69, 0x4f, 0x52, 0x13, 0x49, 0xe1, 0x78, 0xf7, 0x85,
0x7b, 0x46, 0x94, 0x2c, 0xfa, 0x0f, 0xd8, 0x51, 0x81, 0xa5, 0x8e, 0x75, 0xa6, 0x80, 0xfb, 0x99,
0xc0, 0xdf, 0x67, 0x02, 0x31, 0x8b, 0xd3, 0xa9, 0xe1, 0xec, 0x42, 0x23, 0xd7, 0x2e, 0xc9, 0x6c,
0xb1, 0x15, 0xa6, 0x8f, 0x01, 0x02, 0x9e, 0x46, 0x71, 0x88, 0x69, 0xa0, 0xa8, 0x2c, 0x76, 0xc7,
0x43, 0x5f, 0x40, 0x53, 0x12, 0x5f, 0x64, 0x18, 0xe9, 0xce, 0x1e, 0x96, 0xd5, 0x88, 0xb4, 0x25,
0x65, 0x8c, 0x67, 0x19, 0x17, 0x22, 0xc1, 0x3b, 0x32, 0x84, 0x76, 0x19, 0x19, 0x06, 0xff, 0x29,
0x19, 0x47, 0xd0, 0xd9, 0xcf, 0xe2, 0x2b, 0x3c, 0xe6, 0xe1, 0x4a, 0xc6, 0x4b, 0x80, 0xb0, 0xf0,
0x5d, 0xcc, 0x79, 0xa8, 0x84, 0xb4, 0x07, 0xff, 0x97, 0xb9, 0x56, 0x59, 0xac, 0x19, 0x1a, 0xd3,
0x5d, 0x42, 0xfb, 0x74, 0xf2, 0x11, 0x03, 0x91, 0x1b, 0xae, 0xa7, 0x50, 0xe7, 0xca, 0xe3, 0x90,
0xed, 0x4a, 0xaf, 0x35, 0xd8, 0x2c, 0x13, 0xa9, 0x04, 0x66, 0xc2, 0xee, 0x37, 0x62, 0xfd, 0x72,
0x23, 0xdf, 0x08, 0xd4, 0x14, 0x15, 0xf5, 0xa0, 0x2a, 0x96, 0x0b, 0xa3, 0xbc, 0x5b, 0x4e, 0x1e,
0x2f, 0x17, 0xa8, 0x8b, 0xca, 0xb8, 0xe2, 0x01, 0x27, 0x18, 0x09, 0x59, 0xcc, 0x66, 0xd2, 0xa6,
0x1d, 0xa8, 0x08, 0xbe, 0x90, 0x83, 0xb4, 0x59, 0x61, 0x16, 0xaf, 0x29, 0x8b, 0xa7, 0x33, 0xe1,
0x54, 0xa5, 0x4f, 0x01, 0xba, 0x09, 0xb5, 0x09, 0x17, 0x82, 0xcf, 0x1d, 0x5b, 0xba, 0x35, 0x2a,
0xad, 0xab, 0x56, 0x5e, 0x97, 0xdb, 0x87, 0x8d, 0xb3, 0xeb, 0x58, 0x04, 0x33, 0x86, 0x01, 0xcf,
0x42, 0x33, 0x2e, 0x07, 0xea, 0x98, 0xfa, 0x93, 0x04, 0xd5, 0x0b, 0x6f, 0x30, 0x03, 0xdd, 0xaf,
0x04, 0x5a, 0x8c, 0xfb, 0xab, 0xc8, 0x3e, 0xd4, 0x03, 0x9e, 0x0a, 0x7e, 0x99, 0xe9, 0xc1, 0xfe,
0x5b, 0xee, 0x73, 0xc4, 0xe3, 0x54, 0x30, 0x13, 0x45, 0x9f, 0x41, 0x1d, 0x93, 0x24, 0x5e, 0xe4,
0xa8, 0xa7, 0xfa, 0x5f, 0x39, 0xe1, 0x40, 0xfd, 0xcd, 0x4c, 0xdc, 0xef, 0xbe, 0xa9, 0x27, 0x60,
0xcb, 0xda, 0x74, 0x1d, 0xc8, 0x8d, 0xec, 0xc3, 0x66, 0xe4, 0xa6, 0x40, 0x4b, 0x3d, 0x63, 0xb2,
0x74, 0xbf, 0x10, 0xa8, 0xeb, 0x82, 0x74, 0x17, 0x6a, 0x01, 0xa6, 0x02, 0x33, 0xfd, 0x59, 0x3f,
0xd0, 0x8a, 0x0e, 0x2a, 0x36, 0x71, 0x1d, 0x87, 0x62, 0xa6, 0xc9, 0x14, 0x28, 0x36, 0x31, 0x43,
0xb9, 0x20, 0xb5, 0x34, 0x8d, 0x8a, 0x68, 0x3f, 0x9d, 0x26, 0x28, 0xf7, 0x66, 0x31, 0x05, 0x4a,
0xfb, 0xb1, 0x7f, 0xd8, 0xcf, 0x27, 0x02, 0x7f, 0xdd, 0x5f, 0xcd, 0xc0, 0x5c, 0x13, 0xa5, 0xf1,
0xd1, 0x4f, 0x07, 0xa1, 0x83, 0xf5, 0xad, 0xa1, 0xaf, 0xef, 0xdc, 0x15, 0x35, 0xf4, 0xad, 0x72,
0x5a, 0xe9, 0x14, 0xdd, 0x1e, 0x9e, 0x9d, 0x5d, 0x68, 0xae, 0x3e, 0x32, 0xda, 0x82, 0xfa, 0xe1,
0xc9, 0xbb, 0xe1, 0xd1, 0xe1, 0x7e, 0x67, 0x8d, 0x36, 0xa0, 0x7a, 0x7e, 0x76, 0xc0, 0x3a, 0x84,
0x36, 0xc1, 0x1e, 0x1d, 0x1e, 0x9d, 0x8e, 0x3b, 0xd6, 0xce, 0x00, 0xe0, 0xf6, 0x65, 0xd3, 0x3a,
0x54, 0x86, 0x27, 0xef, 0x3b, 0x6b, 0x85, 0xf1, 0x66, 0x58, 0x84, 0x36, 0xa0, 0xba, 0x77, 0x7e,
0x3c, 0xea, 0x58, 0x85, 0x35, 0x2a, 0x72, 0x2a, 0x7b, 0x8d, 0x0f, 0x35, 0x25, 0x63, 0x52, 0x93,
0x47, 0xf8, 0xf9, 0xf7, 0x00, 0x00, 0x00, 0xff, 0xff, 0x97, 0x5e, 0xa7, 0x9f, 0x1f, 0x06, 0x00,
0x00,
}

4
vendor/modules.txt vendored
View File

@ -1,7 +1,7 @@
# github.com/cyrilix/robocar-base v0.0.0-20200103000136-b08c9be9a69a
# github.com/cyrilix/robocar-base v0.0.0-20200128185221-fee4454c12c7
github.com/cyrilix/robocar-base/cli
github.com/cyrilix/robocar-base/service
# github.com/cyrilix/robocar-protobuf/go v0.0.0-20200103235248-776649d250ff
# github.com/cyrilix/robocar-protobuf/go v0.0.0-20200125171436-7bf31bd564b8
github.com/cyrilix/robocar-protobuf/go/events
# github.com/eclipse/paho.mqtt.golang v1.2.0
github.com/eclipse/paho.mqtt.golang