15 Commits

Author SHA1 Message Date
25bea1aab3 WIP 2022-08-28 23:33:51 +02:00
86aef79e66 WIP 2022-08-28 12:06:43 +02:00
efbcac602a Corrector implementation 2022-08-27 19:03:09 +02:00
bd4c5d45a4 WIP 2022-08-24 13:54:36 +02:00
e6a5d6f781 wip 2022-08-23 22:08:07 +02:00
9100cedb38 build: upgrade to go 1.19 2022-08-23 18:28:15 +02:00
a7babb862b WIP 2022-08-23 13:53:59 +02:00
86f91d9f88 WIP 2022-08-23 13:24:31 +02:00
7d27ea866f WIP 2022-08-22 23:56:13 +02:00
a93159df90 WIP 2022-08-22 19:51:44 +02:00
23215bcb4a wip 2022-08-22 14:06:27 +02:00
9af8f3a770 Consume objects from mqtt topic 2022-08-22 13:12:12 +02:00
2b31a3b7eb Test GrouBBoxes OK 2022-08-22 12:06:41 +02:00
dffa7b4898 wip 2022-08-21 23:01:18 +02:00
3ae2986580 wip 2022-08-21 22:35:02 +02:00
5 changed files with 42 additions and 211 deletions

2
.gitignore vendored
View File

@ -284,5 +284,3 @@ local.properties
./build/
pkg/steering/test_result/

View File

@ -1,134 +1,50 @@
#! /bin/bash
IMAGE_NAME=robocar-steering
BINARY_NAME=rc-steering
TAG=$(git describe)
FULL_IMAGE_NAME=docker.io/cyrilix/${IMAGE_NAME}:${TAG}
OPENCV_VERSION=4.6.0
SRC_CMD=./cmd/$BINARY_NAME
GOLANG_VERSION=1.19
BINARY=rc-steering
GOTAGS="-tags netgo"
image_build(){
local containerName=builder
GOPATH=/go
buildah from --name ${containerName} docker.io/cyrilix/opencv-buildstage:${OPENCV_VERSION}
buildah config --label maintainer="Cyrille Nofficial" "${containerName}"
buildah copy --from=docker.io/library/golang:${GOLANG_VERSION} "${containerName}" /usr/local/go /usr/local/go
buildah config --env GOPATH=/go \
--env PATH=/usr/local/go/bin:$GOPATH/bin:/usr/local/go/bin:/usr/bin:/bin \
"${containerName}"
buildah run \
--env GOPATH=${GOPATH} \
"${containerName}" \
mkdir -p /src "$GOPATH/src" "$GOPATH/bin"
buildah run \
--env GOPATH=${GOPATH} \
"${containerName}" \
chmod -R 777 "$GOPATH"
local platform=$1
buildah config --env PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/local/lib64/pkgconfig "${containerName}"
buildah config --workingdir /src/ "${containerName}"
GOOS=$(echo $platform | cut -f1 -d/) && \
GOARCH=$(echo $platform | cut -f2 -d/) && \
GOARM=$(echo $platform | cut -f3 -d/ | sed "s/v//" )
VARIANT="--variant $(echo $platform | cut -f3 -d/ )"
if [[ -z "$GOARM" ]] ;
then
VARIANT=""
fi
buildah add "${containerName}" . .
local binary_suffix="$GOARCH$(echo $platform | cut -f3 -d/ )"
for platform in "linux/amd64" "linux/arm64" "linux/arm/v7"
do
local containerName="$IMAGE_NAME-$GOARCH$GOARM"
GOOS=$(echo "$platform" | cut -f1 -d/) && \
GOARCH=$(echo "$platform" | cut -f2 -d/) && \
GOARM=$(echo "$platform" | cut -f3 -d/ | sed "s/v//" )
case $GOARCH in
"amd64")
ARCH=amd64
ARCH_LIB_DIR=/usr/lib/x86_64-linux-gnu
EXTRA_LIBS=""
CC=gcc
CXX=g++
;;
"arm64")
ARCH=arm64
ARCH_LIB_DIR=/usr/lib/aarch64-linux-gnu
EXTRA_LIBS="-ltbb"
CC=aarch64-linux-gnu-gcc
CXX=aarch64-linux-gnu-g++
;;
"arm")
ARCH=armhf
ARCH_LIB_DIR=/usr/lib/arm-linux-gnueabihf
EXTRA_LIBS="-ltbb"
CC=arm-linux-gnueabihf-gcc
CXX=arm-linux-gnueabihf-g++
;;
esac
printf "\n\nBuild go binary %s\n\n" "${BINARY}.${binary_suffix}"
mkdir -p build
CGO_ENABLED=0 GOOS=${GOOS} GOARCH=${GOARCH} GOARM=${GOARM} go build -mod vendor -a ${GOTAGS} -o "build/${BINARY}.${binary_suffix}" ./cmd/${BINARY}/
printf "Build binary for %s\n\n" "${platform}"
buildah --os "$GOOS" --arch "$GOARCH" $VARIANT --name "$containerName" from gcr.io/distroless/static
buildah config --user 1234 "$containerName"
buildah copy "$containerName" "build/${BINARY}.${binary_suffix}" /go/bin/$BINARY
buildah config --entrypoint '["/go/bin/'$BINARY'"]' "${containerName}"
buildah run \
--env CGO_ENABLED=1 \
--env CC=${CC} \
--env CXX=${CXX} \
--env GOOS=${GOOS} \
--env GOARCH=${GOARCH} \
--env GOARM=${GOARM} \
--env CGO_CPPFLAGS="-I/opt/opencv/${ARCH}/include/opencv4/" \
--env CGO_LDFLAGS="-L/opt/opencv/${ARCH}/lib -L${ARCH_LIB_DIR} ${EXTRA_LIBS} -lopencv_core -lopencv_face -lopencv_videoio -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs -lopencv_objdetect -lopencv_features2d -lopencv_video -lopencv_dnn -lopencv_xfeatures2d -lopencv_calib3d -lopencv_photo -lopencv_flann" \
--env CGO_CXXFLAGS="--std=c++1z" \
"${containerName}" \
go build -tags customenv -a -o ${BINARY_NAME}.${ARCH} ${SRC_CMD}
done
buildah commit --rm ${containerName} ${IMAGE_NAME}-builder
}
image_final(){
local containerName=runtime
for platform in "linux/amd64" "linux/arm64" "linux/arm/v7"
do
GOOS=$(echo $platform | cut -f1 -d/) && \
GOARCH=$(echo $platform | cut -f2 -d/) && \
GOARM=$(echo $platform | cut -f3 -d/ | sed "s/v//" )
VARIANT="--variant $(echo $platform | cut -f3 -d/ )"
if [[ -z "$GOARM" ]] ;
then
VARIANT=""
fi
if [[ "${GOARCH}" == "arm" ]]
then
BINARY="${BINARY_NAME}.armhf"
else
BINARY="${BINARY_NAME}.${GOARCH}"
fi
buildah from --name "${containerName}" --os "${GOOS}" --arch "${GOARCH}" ${VARIANT} docker.io/cyrilix/opencv-runtime:${OPENCV_VERSION}
buildah copy --from ${IMAGE_NAME}-builder "$containerName" "/src/${BINARY}" /usr/local/bin/${BINARY_NAME}
buildah config --label maintainer="Cyrille Nofficial" "${containerName}"
buildah config --user 1234 "$containerName"
buildah config --cmd '' "$containerName"
buildah config --entrypoint '[ "/usr/local/bin/'${BINARY_NAME}'" ]' "$containerName"
buildah commit --rm --manifest ${IMAGE_NAME} ${containerName}
done
buildah commit --rm --manifest $IMAGE_NAME "${containerName}" "${containerName}"
}
buildah rmi localhost/$IMAGE_NAME
buildah manifest rm localhost/${IMAGE_NAME}
image_build
image_build linux/amd64
image_build linux/arm64
image_build linux/arm/v7
# push image
image_final
printf "\n\nPush manifest to %s\n\n" ${FULL_IMAGE_NAME}
buildah manifest push --rm -f v2s2 "localhost/$IMAGE_NAME" "docker://$FULL_IMAGE_NAME" --all

View File

@ -112,7 +112,6 @@ func (c *Controller) onObjects(_ mqtt.Client, message mqtt.Message) {
c.muObjects.Lock()
defer c.muObjects.Unlock()
c.objects = msg.GetObjects()
zap.S().Debugf("%v object(s) received", len(c.objects))
}
func (c *Controller) onDriveMode(_ mqtt.Client, message mqtt.Message) {
@ -187,7 +186,6 @@ func (c *Controller) onTFSteering(_ mqtt.Client, message mqtt.Message) {
func (c *Controller) adjustSteering(evt *events.SteeringMessage) ([]byte, error) {
steering := float64(evt.GetSteering())
steering = c.corrector.AdjustFromObjectPosition(steering, c.Objects())
zap.S().Debugf("adjust steering to avoid objects: %v -> %v", evt.GetSteering(), steering)
evt.Steering = float32(steering)
// override payload content
payload, err := proto.Marshal(evt)
@ -201,10 +199,7 @@ func (c *Controller) Objects() []*events.Object {
c.muObjects.RLock()
defer c.muObjects.RUnlock()
res := make([]*events.Object, 0, len(c.objects))
for _, o := range c.objects {
res = append(res, o)
}
zap.S().Debugf("copy object from %v to %v", c.objects, res)
copy(res, c.objects)
return res
}

View File

@ -160,7 +160,18 @@ func TestController_Start(t *testing.T) {
objectsTopic := "topic/objects"
type fields struct {
client mqtt.Client
steeringTopic string
muDriveMode sync.RWMutex
driveMode events.DriveMode
cancel chan interface{}
driveModeTopic string
rcSteeringTopic string
tfSteeringTopic string
objectsTopic string
muObjects sync.RWMutex
objects []*events.Object
corrector *GridCorrector
enableCorrection bool
enableCorrectionOnUser bool
}
@ -182,10 +193,9 @@ func TestController_Start(t *testing.T) {
}{
{
name: "On user drive mode, none correction",
fields: fields{
driveMode: events.DriveMode_USER,
enableCorrection: false,
enableCorrectionOnUser: false,
driveMode: events.DriveMode_USER,
},
msgEvents: msgEvents{
driveMode: events.DriveModeMessage{DriveMode: events.DriveMode_USER},
@ -197,91 +207,6 @@ func TestController_Start(t *testing.T) {
// Get rc value without correction
want: events.SteeringMessage{Steering: 0.3, Confidence: 1.0},
},
{
name: "On pilot drive mode, none correction",
fields: fields{
driveMode: events.DriveMode_PILOT,
enableCorrection: false,
enableCorrectionOnUser: false,
},
msgEvents: msgEvents{
driveMode: events.DriveModeMessage{DriveMode: events.DriveMode_PILOT},
rcSteering: events.SteeringMessage{Steering: 0.3, Confidence: 1.0},
tfSteering: events.SteeringMessage{Steering: 0.4, Confidence: 1.0},
objects: events.ObjectsMessage{Objects: []*events.Object{&objectOnMiddleNear}},
},
correctionOnObject: 0.5,
// Get rc value without correction
want: events.SteeringMessage{Steering: 0.4, Confidence: 1.0},
},
{
name: "On pilot drive mode, correction enabled",
fields: fields{
driveMode: events.DriveMode_PILOT,
enableCorrection: true,
enableCorrectionOnUser: false,
},
msgEvents: msgEvents{
driveMode: events.DriveModeMessage{DriveMode: events.DriveMode_PILOT},
rcSteering: events.SteeringMessage{Steering: 0.3, Confidence: 1.0},
tfSteering: events.SteeringMessage{Steering: 0.4, Confidence: 1.0},
objects: events.ObjectsMessage{Objects: []*events.Object{&objectOnMiddleNear}},
},
correctionOnObject: 0.5,
// Get rc value without correction
want: events.SteeringMessage{Steering: 0.5, Confidence: 1.0},
},
{
name: "On pilot drive mode, all corrections enabled",
fields: fields{
driveMode: events.DriveMode_PILOT,
enableCorrection: true,
enableCorrectionOnUser: true,
},
msgEvents: msgEvents{
driveMode: events.DriveModeMessage{DriveMode: events.DriveMode_PILOT},
rcSteering: events.SteeringMessage{Steering: 0.3, Confidence: 1.0},
tfSteering: events.SteeringMessage{Steering: 0.4, Confidence: 1.0},
objects: events.ObjectsMessage{Objects: []*events.Object{&objectOnMiddleNear}},
},
correctionOnObject: 0.5,
// Get rc value without correction
want: events.SteeringMessage{Steering: 0.5, Confidence: 1.0},
},
{
name: "On user drive mode, only correction PILOT enabled",
fields: fields{
driveMode: events.DriveMode_PILOT,
enableCorrection: true,
enableCorrectionOnUser: false,
},
msgEvents: msgEvents{
driveMode: events.DriveModeMessage{DriveMode: events.DriveMode_USER},
rcSteering: events.SteeringMessage{Steering: 0.3, Confidence: 1.0},
tfSteering: events.SteeringMessage{Steering: 0.4, Confidence: 1.0},
objects: events.ObjectsMessage{Objects: []*events.Object{&objectOnMiddleNear}},
},
correctionOnObject: 0.5,
// Get rc value without correction
want: events.SteeringMessage{Steering: 0.3, Confidence: 1.0},
},
{
name: "On user drive mode, all corrections enabled",
fields: fields{
driveMode: events.DriveMode_USER,
enableCorrection: true,
enableCorrectionOnUser: true,
},
msgEvents: msgEvents{
driveMode: events.DriveModeMessage{DriveMode: events.DriveMode_USER},
rcSteering: events.SteeringMessage{Steering: 0.3, Confidence: 1.0},
tfSteering: events.SteeringMessage{Steering: 0.4, Confidence: 1.0},
objects: events.ObjectsMessage{Objects: []*events.Object{&objectOnMiddleNear}},
},
correctionOnObject: 0.5,
// Get rc value without correction
want: events.SteeringMessage{Steering: 0.5, Confidence: 1.0},
},
}
for _, tt := range tests {
@ -292,7 +217,7 @@ func TestController_Start(t *testing.T) {
WithCorrector(&StaticCorrector{delta: tt.correctionOnObject}),
)
go c.Start()
time.Sleep(1 * time.Millisecond)
defer c.Stop()
// Publish events and wait generation of new steering message
waitPublish.Add(1)

View File

@ -131,7 +131,6 @@ AdjustFromObjectPosition modify steering value according object positions
: | ... | ... | ... | ... | ... | ... |
*/
func (c *GridCorrector) AdjustFromObjectPosition(currentSteering float64, objects []*events.Object) float64 {
zap.S().Debugf("%v objects to avoid", len(objects))
if len(objects) == 0 {
return currentSteering
}
@ -140,7 +139,7 @@ func (c *GridCorrector) AdjustFromObjectPosition(currentSteering float64, object
// get nearest object
nearest, err := c.nearObject(grpObjs)
if err != nil {
zap.S().Warnf("unexpected error on nearest search object, ignore objects: %v", err)
zap.S().Warnf("unexpected error on nearest seach object, ignore objects: %v", err)
return currentSteering
}
@ -178,7 +177,6 @@ func (c *GridCorrector) computeDeviation(nearest *events.Object) float64 {
var delta float64
var err error
zap.S().Debugf("search delta value for bottom limit: %v", nearest.Bottom)
if nearest.Left < 0 && nearest.Right < 0 {
delta, err = c.gridMap.ValueOf(float64(nearest.Right)*2-1., float64(nearest.Bottom))
}
@ -191,7 +189,6 @@ func (c *GridCorrector) computeDeviation(nearest *events.Object) float64 {
zap.S().Warnf("unable to compute delta to apply to steering, skip correction: %v", err)
delta = 0
}
zap.S().Debugf("new deviation computed: %v", delta)
return delta
}