2020-09-20 21:16:06 +00:00
package main
import (
"flag"
2021-02-16 16:46:10 +00:00
"fmt"
2020-09-20 21:16:06 +00:00
"github.com/cyrilix/robocar-base/cli"
2021-01-23 11:30:59 +00:00
events2 "github.com/cyrilix/robocar-protobuf/go/events"
"github.com/cyrilix/robocar-simulator/pkg/events"
2021-01-15 10:12:21 +00:00
"github.com/cyrilix/robocar-simulator/pkg/gateway"
2021-02-09 18:14:29 +00:00
"github.com/cyrilix/robocar-simulator/pkg/simulator"
2021-01-23 11:30:59 +00:00
mqtt "github.com/eclipse/paho.mqtt.golang"
"github.com/golang/protobuf/proto"
2021-10-12 20:33:13 +00:00
"go.uber.org/zap"
"log"
2020-09-20 21:16:06 +00:00
"os"
2021-02-16 16:46:10 +00:00
"strconv"
"strings"
2020-09-20 21:16:06 +00:00
)
2021-01-15 10:12:21 +00:00
const DefaultClientId = "robocar-simulator"
2020-09-20 21:16:06 +00:00
func main ( ) {
2021-01-23 11:30:59 +00:00
var mqttBroker , username , password , clientId , topicFrame , topicSteering , topicThrottle string
var topicCtrlSteering , topicCtrlThrottle string
2020-09-20 21:16:06 +00:00
var address string
2021-01-15 10:12:21 +00:00
var debug bool
2020-09-20 21:16:06 +00:00
mqttQos := cli . InitIntFlag ( "MQTT_QOS" , 0 )
_ , mqttRetain := os . LookupEnv ( "MQTT_RETAIN" )
cli . InitMqttFlags ( DefaultClientId , & mqttBroker , & username , & password , & clientId , & mqttQos , & mqttRetain )
2021-02-01 16:04:42 +00:00
flag . StringVar ( & topicFrame , "events-topic-camera" , os . Getenv ( "MQTT_TOPIC_CAMERA" ) , "Mqtt topic to events gateway frames, use MQTT_TOPIC_CAMERA if args not set" )
flag . StringVar ( & topicSteering , "events-topic-steering" , os . Getenv ( "MQTT_TOPIC_STEERING" ) , "Mqtt topic to events gateway steering, use MQTT_TOPIC_STEERING if args not set" )
flag . StringVar ( & topicThrottle , "events-topic-throttle" , os . Getenv ( "MQTT_TOPIC_THROTTLE" ) , "Mqtt topic to events gateway throttle, use MQTT_TOPIC_THROTTLE if args not set" )
flag . StringVar ( & topicCtrlSteering , "topic-steering-ctrl" , os . Getenv ( "MQTT_TOPIC_STEERING_CTRL" ) , "Mqtt topic to send steering instructions, use MQTT_TOPIC_STEERING_CTRL if args not set" )
flag . StringVar ( & topicCtrlThrottle , "topic-throttle-ctrl" , os . Getenv ( "MQTT_TOPIC_THROTTLE_CTRL" ) , "Mqtt topic to send throttle instructions, use MQTT_TOPIC_THROTTLE_CTRL if args not set" )
2020-09-20 21:16:06 +00:00
flag . StringVar ( & address , "simulator-address" , "127.0.0.1:9091" , "Simulator address" )
2021-01-15 10:12:21 +00:00
flag . BoolVar ( & debug , "debug" , false , "Debug logs" )
2020-09-20 21:16:06 +00:00
2021-02-16 16:46:10 +00:00
var carName , carStyle , carColor string
var carFontSize int
carStyles := [ ] string {
string ( simulator . CarConfigBodyStyleDonkey ) ,
string ( simulator . CarConfigBodyStyleBare ) ,
string ( simulator . CarConfigBodyStyleCar01 ) ,
}
flag . StringVar ( & carName , "car-name" , "simulator-gateway" , "Car name to display" )
flag . StringVar ( & carStyle , "car-style" , string ( simulator . CarConfigBodyStyleDonkey ) , fmt . Sprintf ( "Car style, only %s" , strings . Join ( carStyles , "," ) ) )
flag . StringVar ( & carColor , "car-color" , "0,0,0" , "Color car as rgb value" )
flag . IntVar ( & carFontSize , "car-font-size" , 0 , "Car font size" )
var racerName , racerBio , racerCountry , racerGuid string
flag . StringVar ( & racerName , "racer-name" , "" , "" )
flag . StringVar ( & racerBio , "racer-bio" , "" , "" )
flag . StringVar ( & racerCountry , "racer-country" , "" , "" )
flag . StringVar ( & racerGuid , "racer-guid" , "" , "" )
var cameraFov , cameraImgW , cameraImgH , cameraImgD int
var cameraFishEyeX , cameraFishEyeY float64
var cameraOffsetX , cameraOffsetY , cameraOffsetZ , cameraRotX float64
var cameraImgEnc string
flag . IntVar ( & cameraFov , "camera-fov" , 90 , "" )
flag . Float64Var ( & cameraFishEyeX , "camera-fish-eye-x" , 0.4 , "" )
flag . Float64Var ( & cameraFishEyeY , "camera-fish-eye-y" , 0.7 , "" )
flag . IntVar ( & cameraImgW , "camera-img-w" , 160 , "image width" )
2021-10-12 20:13:44 +00:00
flag . IntVar ( & cameraImgH , "camera-img-h" , 128 , "image height" )
2021-02-16 16:46:10 +00:00
flag . IntVar ( & cameraImgD , "camera-img-d" , 3 , "Image depth" )
flag . StringVar ( & cameraImgEnc , "camera-img-enc" , string ( simulator . CameraImageEncJpeg ) , "" )
flag . Float64Var ( & cameraOffsetX , "camera-offset-x" , 0 , "moves camera left/right" )
flag . Float64Var ( & cameraOffsetY , "camera-offset-y" , 1.120395 , "moves camera up/down" )
flag . Float64Var ( & cameraOffsetZ , "camera-offset-z" , 0.5528488 , "moves camera forward/back" )
flag . Float64Var ( & cameraRotX , "camera-rot-x" , 15.0 , "rotate the camera" )
2020-09-20 21:16:06 +00:00
flag . Parse ( )
if len ( os . Args ) <= 1 {
flag . PrintDefaults ( )
os . Exit ( 1 )
}
2021-10-12 20:33:13 +00:00
config := zap . NewDevelopmentConfig ( )
2021-01-15 10:12:21 +00:00
if debug {
2021-10-12 20:33:13 +00:00
config . Level = zap . NewAtomicLevelAt ( zap . DebugLevel )
} else {
config . Level = zap . NewAtomicLevelAt ( zap . InfoLevel )
}
lgr , err := config . Build ( )
if err != nil {
log . Fatalf ( "unable to init logger: %v" , err )
2021-01-15 10:12:21 +00:00
}
2021-10-12 20:33:13 +00:00
defer func ( ) {
if err := lgr . Sync ( ) ; err != nil {
log . Printf ( "unable to Sync logger: %v\n" , err )
}
} ( )
zap . ReplaceGlobals ( lgr )
2020-09-20 21:16:06 +00:00
client , err := cli . Connect ( mqttBroker , username , password , clientId )
if err != nil {
2021-10-12 20:33:13 +00:00
zap . S ( ) . Fatalf ( "unable to connect to events broker: %v" , err )
2020-09-20 21:16:06 +00:00
}
defer client . Disconnect ( 10 )
2021-02-16 16:46:10 +00:00
bodyColors := strings . Split ( carColor , "," )
2021-02-09 18:14:29 +00:00
carConfig := simulator . CarConfigMsg {
MsgType : simulator . MsgTypeCarConfig ,
2021-02-16 16:46:10 +00:00
BodyStyle : simulator . CarStyle ( carStyle ) ,
BodyR : bodyColors [ 0 ] ,
BodyG : bodyColors [ 1 ] ,
BodyB : bodyColors [ 2 ] ,
CarName : carName ,
FontSize : strconv . Itoa ( carFontSize ) ,
2021-02-09 18:14:29 +00:00
}
2021-02-16 16:46:10 +00:00
racer := simulator . RacerBioMsg {
MsgType : simulator . MsgTypeRacerInfo ,
RacerName : racerName ,
CarName : carName ,
Bio : racerBio ,
Country : racerCountry ,
Guid : racerGuid ,
}
camera := simulator . CamConfigMsg {
MsgType : simulator . MsgTypeCameraConfig ,
Fov : strconv . Itoa ( cameraFov ) ,
2021-10-12 20:13:44 +00:00
FishEyeX : fmt . Sprintf ( "%.2f" , cameraFishEyeX ) ,
FishEyeY : fmt . Sprintf ( "%.2f" , cameraFishEyeY ) ,
2021-02-16 16:46:10 +00:00
ImgW : strconv . Itoa ( cameraImgW ) ,
ImgH : strconv . Itoa ( cameraImgH ) ,
ImgD : strconv . Itoa ( cameraImgD ) ,
ImgEnc : simulator . CameraImageEnc ( cameraImgEnc ) ,
2021-10-12 20:13:44 +00:00
OffsetX : fmt . Sprintf ( "%.2f" , cameraOffsetX ) ,
OffsetY : fmt . Sprintf ( "%.2f" , cameraOffsetY ) ,
OffsetZ : fmt . Sprintf ( "%.2f" , cameraOffsetZ ) ,
RotX : fmt . Sprintf ( "%.2f" , cameraRotX ) ,
2021-02-16 16:46:10 +00:00
}
gtw := gateway . New ( address , & carConfig , & racer , & camera )
2021-01-23 11:30:59 +00:00
defer gtw . Stop ( )
2020-09-20 21:16:06 +00:00
2021-01-23 11:30:59 +00:00
msgPub := events . NewMsgPublisher (
gtw ,
events . NewMqttPublisher ( client ) ,
topicFrame ,
topicSteering ,
topicThrottle ,
)
defer msgPub . Stop ( )
2021-02-01 16:04:42 +00:00
msgPub . Start ( )
2020-09-20 21:16:06 +00:00
2021-01-23 11:30:59 +00:00
cli . HandleExit ( gtw )
if topicCtrlSteering != "" {
2021-10-12 20:33:13 +00:00
zap . S ( ) . Info ( "configure mqtt route on steering command" )
2021-02-08 22:07:09 +00:00
client . Subscribe ( topicCtrlSteering , byte ( mqttQos ) , func ( client mqtt . Client , message mqtt . Message ) {
2021-01-23 11:30:59 +00:00
onSteeringCommand ( gtw , message )
} )
}
if topicCtrlThrottle != "" {
2021-10-12 20:33:13 +00:00
zap . S ( ) . Info ( "configure mqtt route on throttle command" )
2021-02-08 22:07:09 +00:00
client . Subscribe ( topicCtrlThrottle , byte ( mqttQos ) , func ( client mqtt . Client , message mqtt . Message ) {
2021-01-23 11:30:59 +00:00
onThrottleCommand ( gtw , message )
} )
}
2021-02-08 22:07:09 +00:00
err = gtw . Start ( )
if err != nil {
2021-10-12 20:33:13 +00:00
zap . S ( ) . Fatalf ( "unable to start service: %v" , err )
2021-02-08 22:07:09 +00:00
}
2021-01-23 11:30:59 +00:00
}
func onSteeringCommand ( c * gateway . Gateway , message mqtt . Message ) {
2021-02-08 22:07:09 +00:00
var steeringMsg events2 . SteeringMessage
err := proto . Unmarshal ( message . Payload ( ) , & steeringMsg )
2021-01-23 11:30:59 +00:00
if err != nil {
2021-10-12 20:33:13 +00:00
zap . S ( ) . Errorf ( "unable to unmarshal steering msg: %v" , err )
2021-01-23 11:30:59 +00:00
return
}
2021-02-08 22:07:09 +00:00
c . WriteSteering ( & steeringMsg )
2021-01-23 11:30:59 +00:00
}
func onThrottleCommand ( c * gateway . Gateway , message mqtt . Message ) {
2021-02-08 22:07:09 +00:00
var throttleMsg events2 . ThrottleMessage
err := proto . Unmarshal ( message . Payload ( ) , & throttleMsg )
2021-01-23 11:30:59 +00:00
if err != nil {
2021-10-12 20:33:13 +00:00
zap . S ( ) . Errorf ( "unable to unmarshal throttle msg: %v" , err )
2021-01-23 11:30:59 +00:00
return
}
2021-02-08 22:07:09 +00:00
c . WriteThrottle ( & throttleMsg )
2020-09-20 21:16:06 +00:00
}