1
0

2 Коммиты e0ad61b067 ... e7f4e8c478

Автор SHA1 Сообщение Дата
  Yishi Wang e7f4e8c478 Merge remote-tracking branch 'origin/master' 9 месяцев назад
  Yishi Wang ad0f81f1da update trigger MultiTargetAhead: add ego vehicle min speed check; 9 месяцев назад

+ 92 - 44
test/ey_common_test.go

@@ -6,60 +6,137 @@ import (
 	"github.com/bluenviron/goroslib/v2"
 	"log"
 	"math"
+	"sync"
 	"testing"
 	"time"
 )
 
-type Record struct {
-	StableFrame      int
-	LastExistingTime float64
+var shareVars = new(sync.Map)
+
+func UpdateShareVariable(msg *pjisuv_msgs.PerceptionLocalization) {
+	shareVars.Store("OutsideWorkshopFlag", true)
+
+	shareVars.Store("VelocityXOfCicvLocation", msg.VelocityX)
+	shareVars.Store("VelocityYOfCicvLocation", msg.VelocityY)
 }
 
-var record *Record = nil
+func TestGoRosLib(t *testing.T) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println(fmt.Sprintf("Recovered from panic: [%s], [%#v]", Label(), r))
+		}
+	}()
+
+	rosNode, err := goroslib.NewNode(goroslib.NodeConf{
+		Name:          "eyTest",
+		MasterAddress: "localhost:11311",
+	})
+	if err != nil {
+		log.Panicln(err, fmt.Sprintf("failed to create rosNode: [%#v]", err), false)
+	}
+
+	_, err = goroslib.NewSubscriber(goroslib.SubscriberConf{
+		Node:  rosNode,
+		Topic: "/tpperception",
+		Callback: func(msg *pjisuv_msgs.PerceptionObjects) {
+			Rule(shareVars, msg)
+		},
+	})
+	if err != nil {
+		log.Panicln(err, fmt.Sprintf("failed to create subscriber: [%#v]", err), false)
+	}
+
+	_, err = goroslib.NewSubscriber(goroslib.SubscriberConf{
+		Node:  rosNode,
+		Topic: "/cicv_location",
+		Callback: func(msg *pjisuv_msgs.PerceptionLocalization) {
+			UpdateShareVariable(msg)
+		},
+	})
+	if err != nil {
+		log.Panicln(err, fmt.Sprintf("failed to create subscriber: [%#v]", err), false)
+	}
+
+	select {}
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+func Topic() string {
+	return "/tpperception"
+}
 
 // Label todo 禁止存在下划线_
+// MultiPedestrianAhead
+// MultiCarAhead
+// MultiTruckAhead
+// MultiBicycleAhead
+// MultiTricycleAhead
+// MultiTrafficConeAhead
 func Label() string {
-	return "test"
+	return "MultiTrafficConeAhead"
+}
+
+type Record struct {
+	StableFrame      int
+	LastExistingTime float64
 }
 
-// typeCheck 目标物类型检测
+var record *Record = nil
+
+// objTypeCheck 目标物类型检测
 // × 金龙车:CAR_TYPE=0, TRUCK_TYPE=1, PEDESTRIAN_TYPE=2, CYCLIST_TYPE=3, UNKNOWN_TYPE=4, UNKNOWN_MOVABLE_TYPE=5, UNKNOWN_UNMOVABLE_TYPE=6
 // √ 多功能车:UNKNOWN TYPE=O, PEDESTRIAN TYPE=1, CAR TYPE=2, TRUCK TYPE=3, Bicycle TYPE=4, Tricycle TYPE=5, Traffic Cone TYPE=6
-func typeCheck(obj *pjisuv_msgs.PerceptionObject) bool {
+func objTypeCheck(obj *pjisuv_msgs.PerceptionObject) bool {
 	const targetType uint8 = 4
 
 	return targetType == obj.Type
 }
 
-// posCheck 判断目标物位置关系
-func posCheck(obj *pjisuv_msgs.PerceptionObject) bool {
+// objPosCheck 判断目标物位置关系
+func objPosCheck(obj *pjisuv_msgs.PerceptionObject) bool {
 	const laneWidth = 3.5 // m
 
 	return obj.X > 0 && math.Abs(float64(obj.Y)) < laneWidth*1.5
 }
 
+// isEgoStationary 判断主车是否“静止”(速度低于阈值)
+func isEgoStationary(shareVars *sync.Map) bool {
+	const minSpeed = 1 // m/s
+
+	VelocityXOfCicvLocation, _ := shareVars.Load("VelocityXOfCicvLocation") // float64
+	VelocityYOfCicvLocation, _ := shareVars.Load("VelocityYOfCicvLocation")
+	speed := math.Sqrt(math.Pow(VelocityXOfCicvLocation.(float64), 2) + math.Pow(VelocityYOfCicvLocation.(float64), 2))
+
+	return speed > minSpeed
+}
+
 // Rule 检测前方指定目标物数量
-func Rule(msg *pjisuv_msgs.PerceptionObjects) string {
+func Rule(shareVars *sync.Map, msg *pjisuv_msgs.PerceptionObjects) string {
 	defer func() {
 		if r := recover(); r != nil {
 			fmt.Println("Recovered from panic:", r)
 		}
 	}()
 
+	outsideWorkshopFlag, _ := shareVars.Load("OutsideWorkshopFlag")
+	if !outsideWorkshopFlag.(bool) || !isEgoStationary(shareVars) {
+		return ""
+	}
+
 	const Cgcs2000X = 456256.260152
 	const Cgcs2000Y = 4397809.886833
 	const MinStableFrameCount = 5   // frame
 	const MaxTimeBetweenFrame = 0.5 // second
-	const minTargetNum = 4
+	const minTargetNum = 3
 
-	fmt.Println("\n", time.Unix(int64(msg.Header.TimeStamp), int64(msg.Header.TimeStamp*1e9)%1e9).Format(time.StampNano))
 	if len(msg.Objs) >= minTargetNum {
 
 		currTargetNum := 0
+		fmt.Println("\n", time.Unix(int64(msg.Header.TimeStamp), int64(msg.Header.TimeStamp*1e9)%1e9).Format(time.StampNano))
 		for _, obj := range msg.Objs {
-
 			// 判断目标物是否满足筛选条件
-			if typeCheck(&obj) && posCheck(&obj) {
+			if objTypeCheck(&obj) && objPosCheck(&obj) {
 				fmt.Println(fmt.Sprintf("id: [%d], type: [%d], x/yrel: [%f, %f], x/yabs: [%f, %f], speed: [%f], size: [%f/%f/%f]",
 					obj.Id, obj.Type, obj.X, obj.Y, obj.Xabs-Cgcs2000X, obj.Yabs-Cgcs2000Y, obj.Speed, obj.Length, obj.Width, obj.Height))
 				currTargetNum++
@@ -83,7 +160,7 @@ func Rule(msg *pjisuv_msgs.PerceptionObjects) string {
 					newRecord.StableFrame = record.StableFrame + 1
 					if newRecord.StableFrame == MinStableFrameCount {
 						record = nil
-						fmt.Println("!!!!!!!!!! found !!!!!!!!!!") // todo
+						fmt.Println("!!!!!!!!!! found !!!!!!!!!!")
 						return Label()
 					} else {
 						fmt.Println("---------- update ----------")
@@ -99,32 +176,3 @@ func Rule(msg *pjisuv_msgs.PerceptionObjects) string {
 
 	return ""
 }
-
-func TestGoRosLib(t *testing.T) {
-	defer func() {
-		if err := recover(); err != nil {
-			log.Println(err, fmt.Sprintf("recover: [%#v]", err), false)
-		}
-	}()
-
-	rosNode, err := goroslib.NewNode(goroslib.NodeConf{
-		Name:          "eyTest",
-		MasterAddress: "localhost:11311",
-	})
-	if err != nil {
-		log.Panicln(err, fmt.Sprintf("failed to create rosNode: [%#v]", err), false)
-	}
-
-	_, err = goroslib.NewSubscriber(goroslib.SubscriberConf{
-		Node:  rosNode,
-		Topic: "/tpperception",
-		Callback: func(msg *pjisuv_msgs.PerceptionObjects) {
-			Rule(msg)
-		},
-	})
-	if err != nil {
-		log.Panicln(err, fmt.Sprintf("failed to create subscriber: [%#v]", err), false)
-	}
-
-	select {}
-}

+ 5 - 5
trigger/pjisuv/tpperception/UnknownBigTargetAhead/main/UnknownBigTargetAhead.go

@@ -24,17 +24,17 @@ type Object struct {
 
 var objectsStability = make(map[uint32]Object)
 
-// typeCheck 目标物类型检测
+// objTypeCheck 目标物类型检测
 // × 金龙车:CAR_TYPE=0, TRUCK_TYPE=1, PEDESTRIAN_TYPE=2, CYCLIST_TYPE=3, UNKNOWN_TYPE=4, UNKNOWN_MOVABLE_TYPE=5, UNKNOWN_UNMOVABLE_TYPE=6
 // √ 多功能车:UNKNOWN TYPE=O, PEDESTRIAN TYPE=1, CAR TYPE=2, TRUCK TYPE=3, Bicycle TYPE=4, Tricycle TYPE=5, Traffic Cone TYPE=6
-func typeCheck(obj *pjisuv_msgs.PerceptionObject) bool {
+func objTypeCheck(obj *pjisuv_msgs.PerceptionObject) bool {
 	const targetType uint8 = 0
 
 	return targetType == obj.Type
 }
 
-// sizeCheck 目标物大小检测
-func sizeCheck(obj *pjisuv_msgs.PerceptionObject) bool {
+// objSizeCheck 目标物大小检测
+func objSizeCheck(obj *pjisuv_msgs.PerceptionObject) bool {
 	// 多功能车
 	const targetMinLength = 3.6   // m
 	const targetMinWidth = 1.605  // m
@@ -101,7 +101,7 @@ func Rule(shareVars *sync.Map, msg *pjisuv_msgs.PerceptionObjects) string {
 	for _, obj := range msg.Objs {
 
 		// 判断目标物是否满足筛选条件
-		if typeCheck(&obj) && objPosCheck(&obj) && sizeCheck(&obj) {
+		if objTypeCheck(&obj) && objPosCheck(&obj) && objSizeCheck(&obj) {
 			//fmt.Println(fmt.Sprintf("id: [%d], type: [%d], x/yrel: [%f, %f], x/yabs: [%f, %f], speed: [%f], size: [%f/%f/%f]",
 			//	obj.Id, obj.Type, obj.X, obj.Y, obj.Xabs-Cgcs2000X, obj.Yabs-Cgcs2000Y, obj.Speed, obj.Length, obj.Width, obj.Height))
 

+ 34 - 14
trigger/pjisuv/tpperception/multiTargetAhead/main/multiTargetAhead.go → trigger/pjisuv/tpperception/multiTargetAhead/main/multiTrafficConeAhead.go

@@ -19,7 +19,7 @@ func Topic() string {
 // MultiTricycleAhead
 // MultiTrafficConeAhead
 func Label() string {
-	return "MultiPedestrianAhead"
+	return "MultiTrafficConeAhead"
 }
 
 type Record struct {
@@ -29,22 +29,33 @@ type Record struct {
 
 var record *Record = nil
 
-// typeCheck 目标物类型检测
+// objTypeCheck 目标物类型检测
 // × 金龙车:CAR_TYPE=0, TRUCK_TYPE=1, PEDESTRIAN_TYPE=2, CYCLIST_TYPE=3, UNKNOWN_TYPE=4, UNKNOWN_MOVABLE_TYPE=5, UNKNOWN_UNMOVABLE_TYPE=6
 // √ 多功能车:UNKNOWN TYPE=O, PEDESTRIAN TYPE=1, CAR TYPE=2, TRUCK TYPE=3, Bicycle TYPE=4, Tricycle TYPE=5, Traffic Cone TYPE=6
-func typeCheck(obj *pjisuv_msgs.PerceptionObject) bool {
-	const targetType uint8 = 1
+func objTypeCheck(obj *pjisuv_msgs.PerceptionObject) bool {
+	const targetType uint8 = 6
 
 	return targetType == obj.Type
 }
 
-// posCheck 判断目标物位置关系
-func posCheck(obj *pjisuv_msgs.PerceptionObject) bool {
+// objPosCheck 判断目标物位置关系
+func objPosCheck(obj *pjisuv_msgs.PerceptionObject) bool {
 	const laneWidth = 3.5 // m
 
 	return obj.X > 0 && math.Abs(float64(obj.Y)) < laneWidth*1.5
 }
 
+// isEgoStationary 判断主车是否“静止”(速度低于阈值)
+func isEgoStationary(shareVars *sync.Map) bool {
+	const minSpeed = 1 // m/s
+
+	VelocityXOfCicvLocation, _ := shareVars.Load("VelocityXOfCicvLocation") // float64
+	VelocityYOfCicvLocation, _ := shareVars.Load("VelocityYOfCicvLocation")
+	speed := math.Sqrt(math.Pow(VelocityXOfCicvLocation.(float64), 2) + math.Pow(VelocityYOfCicvLocation.(float64), 2))
+
+	return speed > minSpeed
+}
+
 // Rule 检测前方指定目标物数量
 func Rule(shareVars *sync.Map, msg *pjisuv_msgs.PerceptionObjects) string {
 	defer func() {
@@ -53,21 +64,26 @@ func Rule(shareVars *sync.Map, msg *pjisuv_msgs.PerceptionObjects) string {
 		}
 	}()
 
-	const Cgcs2000X = 456256.260152
-	const Cgcs2000Y = 4397809.886833
+	outsideWorkshopFlag, _ := shareVars.Load("OutsideWorkshopFlag")
+	if !outsideWorkshopFlag.(bool) || !isEgoStationary(shareVars) {
+		return ""
+	}
+
+	//const Cgcs2000X = 456256.260152
+	//const Cgcs2000Y = 4397809.886833
 	const MinStableFrameCount = 5   // frame
 	const MaxTimeBetweenFrame = 0.5 // second
-	const minTargetNum = 4
-	OutsideWorkshopFlag, _ := shareVars.Load("OutsideWorkshopFlag")
-	OutsideWorkshopFlag = OutsideWorkshopFlag.(bool)
+	const minTargetNum = 3
 
 	if len(msg.Objs) >= minTargetNum {
 
 		currTargetNum := 0
+		//fmt.Println("\n", time.Unix(int64(msg.Header.TimeStamp), int64(msg.Header.TimeStamp*1e9)%1e9).Format(time.StampNano))
 		for _, obj := range msg.Objs {
-
 			// 判断目标物是否满足筛选条件
-			if typeCheck(&obj) && posCheck(&obj) {
+			if objTypeCheck(&obj) && objPosCheck(&obj) {
+				//fmt.Println(fmt.Sprintf("id: [%d], type: [%d], x/yrel: [%f, %f], x/yabs: [%f, %f], speed: [%f], size: [%f/%f/%f]",
+				//	obj.Id, obj.Type, obj.X, obj.Y, obj.Xabs-Cgcs2000X, obj.Yabs-Cgcs2000Y, obj.Speed, obj.Length, obj.Width, obj.Height))
 				currTargetNum++
 			}
 		}
@@ -78,6 +94,7 @@ func Rule(shareVars *sync.Map, msg *pjisuv_msgs.PerceptionObjects) string {
 					StableFrame:      1,
 					LastExistingTime: msg.Header.TimeStamp,
 				}
+				//fmt.Println("---------- create ----------")
 			} else {
 				newRecord := Record{
 					StableFrame:      1,
@@ -86,12 +103,15 @@ func Rule(shareVars *sync.Map, msg *pjisuv_msgs.PerceptionObjects) string {
 
 				if newRecord.LastExistingTime-record.LastExistingTime <= MaxTimeBetweenFrame {
 					newRecord.StableFrame = record.StableFrame + 1
-					if newRecord.StableFrame == MinStableFrameCount && OutsideWorkshopFlag == true {
+					if newRecord.StableFrame == MinStableFrameCount {
 						record = nil
+						//fmt.Println("!!!!!!!!!! found !!!!!!!!!!")
 						return Label()
 					} else {
+						//fmt.Println("---------- update ----------")
 					}
 				} else {
+					//fmt.Println("---------- reset ----------")
 				}
 				record = &newRecord
 			}