2019-12-27 14:38:12 +00:00
package main
import (
"flag"
"github.com/cyrilix/robocar-base/cli"
2022-09-05 13:30:26 +00:00
"github.com/cyrilix/robocar-throttle/pkg/brake"
2022-09-05 14:44:02 +00:00
"github.com/cyrilix/robocar-throttle/pkg/throttle"
2022-09-05 13:30:26 +00:00
"github.com/cyrilix/robocar-throttle/pkg/types"
2021-10-12 19:56:42 +00:00
"go.uber.org/zap"
2019-12-27 14:38:12 +00:00
"log"
"os"
)
const (
2020-01-01 18:36:22 +00:00
DefaultClientId = "robocar-throttle"
2023-06-14 18:07:12 +00:00
DefaultThrottleMin = 0.1
2019-12-27 14:38:12 +00:00
)
func main ( ) {
var mqttBroker , username , password , clientId string
2023-06-14 18:07:12 +00:00
var throttleTopic , driveModeTopic , rcThrottleTopic , steeringTopic , throttleFeedbackTopic , speedZoneTopic string
2019-12-27 14:38:12 +00:00
var minThrottle , maxThrottle float64
2022-09-05 14:44:02 +00:00
var publishPilotFrequency int
2022-09-05 13:30:26 +00:00
var brakeConfig string
var enableBrake bool
2023-06-14 18:07:12 +00:00
var enableSpeedZone bool
2023-06-14 18:07:43 +00:00
var enableCustomSteeringProcessor bool
var configFileSteeringProcessor string
2023-06-14 18:07:12 +00:00
var slowZoneThrottle , normalZoneThrottle , fastZoneThrottle float64
var moderateSteering , fullSteering float64
2019-12-27 14:38:12 +00:00
err := cli . SetFloat64DefaultValueFromEnv ( & minThrottle , "THROTTLE_MIN" , DefaultThrottleMin )
if err != nil {
2021-10-12 19:56:42 +00:00
zap . S ( ) . Errorf ( "unable to parse min throttle value arg: %v" , err )
2019-12-27 14:38:12 +00:00
}
err = cli . SetFloat64DefaultValueFromEnv ( & maxThrottle , "THROTTLE_MAX" , minThrottle )
if err != nil {
2021-10-12 19:56:42 +00:00
zap . S ( ) . Errorf ( "unable to parse max throttle value arg: %v" , err )
2019-12-27 14:38:12 +00:00
}
mqttQos := cli . InitIntFlag ( "MQTT_QOS" , 0 )
_ , mqttRetain := os . LookupEnv ( "MQTT_RETAIN" )
cli . InitMqttFlags ( DefaultClientId , & mqttBroker , & username , & password , & clientId , & mqttQos , & mqttRetain )
flag . StringVar ( & throttleTopic , "mqtt-topic-throttle" , os . Getenv ( "MQTT_TOPIC_THROTTLE" ) , "Mqtt topic to publish throttle result, use MQTT_TOPIC_THROTTLE if args not set" )
2019-12-27 16:42:10 +00:00
flag . StringVar ( & driveModeTopic , "mqtt-topic-drive-mode" , os . Getenv ( "MQTT_TOPIC_DRIVE_MODE" ) , "Mqtt topic that contains DriveMode value, use MQTT_TOPIC_DRIVE_MODE if args not set" )
flag . StringVar ( & rcThrottleTopic , "mqtt-topic-rc-throttle" , os . Getenv ( "MQTT_TOPIC_RC_THROTTLE" ) , "Mqtt topic that contains RC Throttle value, use MQTT_TOPIC_RC_THROTTLE if args not set" )
2022-09-05 14:44:02 +00:00
flag . StringVar ( & steeringTopic , "mqtt-topic-steering" , os . Getenv ( "MQTT_TOPIC_STEERING" ) , "Mqtt topic that contains steering value, use MQTT_TOPIC_STEERING if args not set" )
2022-09-05 09:22:31 +00:00
flag . StringVar ( & throttleFeedbackTopic , "mqtt-topic-throttle-feedback" , os . Getenv ( "MQTT_TOPIC_THROTTLE_FEEDBACK" ) , "Mqtt topic where to publish throttle feedback, use MQTT_TOPIC_THROTTLE_FEEDBACK if args not set" )
2023-06-14 18:07:12 +00:00
flag . StringVar ( & speedZoneTopic , "mqtt-topic-speed-zone" , os . Getenv ( "MQTT_TOPIC_SPEED_ZONE" ) , "Mqtt topic where to subscribe speed zone events, use MQTT_TOPIC_SPEED_ZONE if args not set" )
2022-09-05 14:44:02 +00:00
2019-12-27 14:38:12 +00:00
flag . Float64Var ( & minThrottle , "throttle-min" , minThrottle , "Minimum throttle value, use THROTTLE_MIN if args not set" )
flag . Float64Var ( & maxThrottle , "throttle-max" , maxThrottle , "Minimum throttle value, use THROTTLE_MAX if args not set" )
2022-09-05 14:44:02 +00:00
flag . IntVar ( & publishPilotFrequency , "update-pwm-frequency" , 2 , "Number of throttle event to publish when pilot mode is enabled" )
2022-09-05 13:30:26 +00:00
flag . BoolVar ( & enableBrake , "enable-brake-feature" , false , "Enable brake to slow car on throttle changes" )
flag . StringVar ( & brakeConfig , "brake-configuration" , "" , "Json file to use to configure brake adaptation when --enable-brake is `true`" )
2023-06-14 18:07:43 +00:00
flag . BoolVar ( & enableCustomSteeringProcessor , "enable-custom-steering-processor" , false , "Enable custom steering processor to estimate throttle" )
flag . StringVar ( & configFileSteeringProcessor , "custom-steering-processor-config" , "" , "Path to json config to parameter custom steering processor" )
2023-06-14 18:07:12 +00:00
flag . BoolVar ( & enableSpeedZone , "enable-speed-zone" , false , "Enable speed zone information to estimate throttle" )
flag . Float64Var ( & slowZoneThrottle , "slow-zone-throttle" , 0.11 , "Throttle target for slow speed zone" )
flag . Float64Var ( & normalZoneThrottle , "normal-zone-throttle" , 0.12 , "Throttle target for normal speed zone" )
flag . Float64Var ( & fastZoneThrottle , "fast-zone-throttle" , 0.13 , "Throttle target for fast speed zone" )
flag . Float64Var ( & moderateSteering , "moderate-steering" , 0.3 , "Steering above is considered as moderate" )
flag . Float64Var ( & fullSteering , "full-steering" , 0.8 , "Steering above is considered as full" )
2022-06-16 09:58:43 +00:00
logLevel := zap . LevelFlag ( "log" , zap . InfoLevel , "log level" )
2019-12-27 14:38:12 +00:00
flag . Parse ( )
if len ( os . Args ) <= 1 {
flag . PrintDefaults ( )
os . Exit ( 1 )
}
2021-10-12 19:56:42 +00:00
config := zap . NewDevelopmentConfig ( )
2022-06-16 09:58:43 +00:00
config . Level = zap . NewAtomicLevelAt ( * logLevel )
2021-10-12 19:56:42 +00:00
lgr , err := config . Build ( )
if err != nil {
log . Fatalf ( "unable to init logger: %v" , err )
}
defer func ( ) {
if err := lgr . Sync ( ) ; err != nil {
log . Printf ( "unable to Sync logger: %v\n" , err )
}
} ( )
zap . ReplaceGlobals ( lgr )
2023-06-14 18:07:12 +00:00
zap . S ( ) . Infof ( "Topic throttle : %s" , throttleTopic )
zap . S ( ) . Infof ( "Topic rc-throttle : %s" , rcThrottleTopic )
zap . S ( ) . Infof ( "Topic throttle feedback : %s" , throttleFeedbackTopic )
zap . S ( ) . Infof ( "Topic steering : %s" , steeringTopic )
zap . S ( ) . Infof ( "Topic drive mode : %s" , driveModeTopic )
zap . S ( ) . Infof ( "Topic speed zone : %s" , speedZoneTopic )
zap . S ( ) . Infof ( "Min throttle : %v" , minThrottle )
zap . S ( ) . Infof ( "Max throttle : %v" , maxThrottle )
zap . S ( ) . Infof ( "Publish frequency : %vHz" , publishPilotFrequency )
zap . S ( ) . Infof ( "Brake enabled : %v" , enableBrake )
2023-06-14 18:07:43 +00:00
zap . S ( ) . Infof ( "CustomSteeringProcessor enabled: %v" , enableCustomSteeringProcessor )
2023-06-14 18:07:12 +00:00
zap . S ( ) . Infof ( "SpeedZone enabled : %v" , enableSpeedZone )
zap . S ( ) . Infof ( "SpeedZone slow throttle : %v" , slowZoneThrottle )
zap . S ( ) . Infof ( "SpeedZone normal throttle : %v" , normalZoneThrottle )
zap . S ( ) . Infof ( "SpeedZone fast throttle : %v" , fastZoneThrottle )
zap . S ( ) . Infof ( "Steering moderate : %v" , moderateSteering )
zap . S ( ) . Infof ( "Steering full : %v" , fullSteering )
2022-09-05 17:06:58 +00:00
2019-12-27 14:38:12 +00:00
client , err := cli . Connect ( mqttBroker , username , password , clientId )
if err != nil {
2021-10-12 19:56:42 +00:00
zap . S ( ) . Fatalf ( "unable to connect to mqtt bus: %v" , err )
2019-12-27 14:38:12 +00:00
}
defer client . Disconnect ( 50 )
2022-09-05 13:30:26 +00:00
var brakeCtrl brake . Controller
if enableBrake {
brakeCtrl = brake . NewCustomControllerWithJsonConfig ( brakeConfig )
} else {
brakeCtrl = & brake . DisabledController { }
}
2023-06-14 18:07:43 +00:00
if enableSpeedZone && enableCustomSteeringProcessor {
zap . S ( ) . Panicf ( "invalid flag, speedZone and customSteering processor can't be enabled at the same time" )
}
var throttleProcessor throttle . Processor
if enableSpeedZone {
throttleProcessor = throttle . NewSpeedZoneProcessor (
types . Throttle ( slowZoneThrottle ) ,
types . Throttle ( normalZoneThrottle ) ,
types . Throttle ( fastZoneThrottle ) ,
moderateSteering ,
fullSteering ,
)
} else if enableCustomSteeringProcessor {
cfg , err := throttle . NewConfigFromJson ( configFileSteeringProcessor )
if err != nil {
zap . S ( ) . Fatalf ( "unable to load config '%v': %v" , configFileSteeringProcessor , err )
}
throttleProcessor = throttle . NewCustomSteeringProcessor ( cfg )
} else {
throttleProcessor = throttle . NewSteeringProcessor ( types . Throttle ( minThrottle ) , types . Throttle ( maxThrottle ) )
}
2022-09-05 13:30:26 +00:00
p := throttle . New ( client , throttleTopic , driveModeTopic , rcThrottleTopic , steeringTopic , throttleFeedbackTopic ,
2023-06-14 18:07:43 +00:00
speedZoneTopic , types . Throttle ( maxThrottle ) , 2 ,
throttle . WithThrottleProcessor ( throttleProcessor ) ,
throttle . WithBrakeController ( brakeCtrl ) )
2019-12-27 14:38:12 +00:00
defer p . Stop ( )
cli . HandleExit ( p )
err = p . Start ( )
if err != nil {
2021-10-12 19:56:42 +00:00
zap . S ( ) . Fatalf ( "unable to start service: %v" , err )
2019-12-27 14:38:12 +00:00
}
}