2020-01-04 13:10:36 +00:00
package main
import (
"flag"
"github.com/cyrilix/robocar-base/cli"
2024-04-14 10:09:06 +00:00
"github.com/cyrilix/robocar-road/road"
2021-10-12 21:15:05 +00:00
"go.uber.org/zap"
2024-04-14 10:09:06 +00:00
"gocv.io/x/gocv"
"image"
2020-01-04 13:10:36 +00:00
"log"
2024-04-14 10:09:06 +00:00
"math"
2020-01-04 13:10:36 +00:00
"os"
)
const (
2021-10-12 21:05:10 +00:00
DefaultClientId = "robocar-road"
2024-04-14 10:09:06 +00:00
DefaultHorizon = 110
2020-01-04 13:10:36 +00:00
)
func main ( ) {
var mqttBroker , username , password , clientId string
var cameraTopic , roadTopic string
var horizon int
2024-04-14 10:09:06 +00:00
var whiteThresholdLow , whiteThresholdHigh int
var cannyThresholdLow , cannyThresholdHigh int
var imgWidth , imgHeight int
2020-01-04 13:10:36 +00:00
err := cli . SetIntDefaultValueFromEnv ( & horizon , "HORIZON" , DefaultHorizon )
if err != nil {
log . Printf ( "unable to parse horizon value arg: %v" , err )
}
mqttQos := cli . InitIntFlag ( "MQTT_QOS" , 0 )
_ , mqttRetain := os . LookupEnv ( "MQTT_RETAIN" )
cli . InitMqttFlags ( DefaultClientId , & mqttBroker , & username , & password , & clientId , & mqttQos , & mqttRetain )
flag . StringVar ( & roadTopic , "mqtt-topic-road" , os . Getenv ( "MQTT_TOPIC_ROAD" ) , "Mqtt topic to publish road detection result, use MQTT_TOPIC_ROAD if args not set" )
flag . StringVar ( & cameraTopic , "mqtt-topic-camera" , os . Getenv ( "MQTT_TOPIC_CAMERA" ) , "Mqtt topic that contains camera frame values, use MQTT_TOPIC_CAMERA if args not set" )
flag . IntVar ( & horizon , "horizon" , horizon , "Limit horizon in pixels from top, use HORIZON if args not set" )
2024-04-14 10:09:06 +00:00
flag . IntVar ( & imgWidth , "image-width" , 160 , "Video pixels width" )
2024-05-02 18:03:37 +00:00
flag . IntVar ( & imgHeight , "image-height" , 120 , "Video pixels height" )
2024-04-14 10:09:06 +00:00
flag . IntVar ( & whiteThresholdLow , "white-threshold-low" , 20 , "White pixels threshold, low limit" )
flag . IntVar ( & whiteThresholdHigh , "white-threshold-high" , 255 , "White pixels threshold, high limit" )
flag . IntVar ( & cannyThresholdLow , "canny-threshold-low" , 100 , "White pixels threshold, low limit" )
flag . IntVar ( & cannyThresholdHigh , "canny-threshold-high" , 250 , "White pixels threshold, high limit" )
var houghLinesRho , houghLinesThreshold , houghLinesMinLineLength , houghLinesMaxLineGap int
var houghLinesTheta float64
flag . IntVar ( & houghLinesRho , "hough-lines-rho" , 2 , "distance resolution in pixels of the Hough grid" )
flag . Float64Var ( & houghLinesTheta , "hough-lines-theta" , 1 * math . Pi / 180 , "angular resolution in radians of the Hough grid, default Pi/180" )
flag . IntVar ( & houghLinesThreshold , "hough-lines-threshold" , 15 , "minimum number of votes (intersections in Hough grid cell)" )
flag . IntVar ( & houghLinesMinLineLength , "hough-lines-min-line-length" , 10 , "minimum number of pixels making up a line" )
flag . IntVar ( & houghLinesMaxLineGap , "hough-lines-max-lines-gap" , 20 , "maximum gap in pixels between connectable line segments" )
2021-12-25 15:13:43 +00:00
logLevel := zap . LevelFlag ( "log" , zap . InfoLevel , "log level" )
2020-01-04 13:10:36 +00:00
flag . Parse ( )
2021-12-25 15:13:43 +00:00
2020-01-04 13:10:36 +00:00
if len ( os . Args ) <= 1 {
flag . PrintDefaults ( )
os . Exit ( 1 )
}
2021-10-12 21:15:05 +00:00
config := zap . NewDevelopmentConfig ( )
2021-12-25 15:13:43 +00:00
config . Level = zap . NewAtomicLevelAt ( * logLevel )
2021-10-12 21:15:05 +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 )
2020-01-04 13:10:36 +00:00
client , err := cli . Connect ( mqttBroker , username , password , clientId )
if err != nil {
2021-10-12 21:15:05 +00:00
zap . S ( ) . Fatalf ( "unable to connect to mqtt bus: %v" , err )
2020-01-04 13:10:36 +00:00
}
defer client . Disconnect ( 50 )
2024-04-14 10:09:06 +00:00
p := road . NewPart ( client ,
cameraTopic , roadTopic ,
road . NewDetector (
road . WithWhiteFilter ( whiteThresholdLow , whiteThresholdHigh ) ,
road . WithYellowFilter (
gocv . NewMatFromScalar ( gocv . Scalar { Val1 : 90. , Val2 : 100. , Val3 : 100. } , gocv . MatTypeCV8U ) ,
gocv . NewMatFromScalar ( gocv . Scalar { Val1 : 110. , Val2 : 255. , Val3 : 255. } , gocv . MatTypeCV8U ) ,
) ,
road . WithCanny ( cannyThresholdLow , cannyThresholdHigh ) ,
road . WithGaussianBlur ( 3 ) ,
road . WithRegionOfInterest ( imgWidth , imgHeight , horizon ) ,
road . WithPointOnRoad ( image . Point { X : imgWidth / 2 , Y : imgHeight - 30 } ) ,
road . WithHoughLines ( houghLinesRho , float32 ( houghLinesTheta ) , houghLinesThreshold , houghLinesMinLineLength , houghLinesMaxLineGap ) ,
) ,
)
2020-01-04 13:10:36 +00:00
defer p . Stop ( )
cli . HandleExit ( p )
err = p . Start ( )
if err != nil {
2021-10-12 21:15:05 +00:00
zap . S ( ) . Fatalf ( "unable to start service: %v" , err )
2020-01-04 13:10:36 +00:00
}
}