소스 검색

add JiLi data acquisition project

zwh 7 달 전
부모
커밋
d0026ad072
33개의 변경된 파일2115개의 추가작업 그리고 191개의 파일을 삭제
  1. 112 4
      aarch64/pjisuv/master/service/produce_window.go
  2. 25 29
      trigger/pjisuv/cicv_location/AbnormalStopOnJunction/main/AbnormalStopOnJunction.go
  3. 6 57
      trigger/pjisuv/cicv_location/EnterTjunction/main/EnterTjunction.go
  4. 12 55
      trigger/pjisuv/cicv_location/JunctionOverspeed/main/JunctionOverspeed.go
  5. 65 0
      trigger/pjisuv/cicv_location/ReverseAndOverspeed/main/ReverseAndOverspeed.go
  6. 108 0
      trigger/pjisuv/cicv_ticker/CBFA/main/CBFA.go
  7. 108 0
      trigger/pjisuv/cicv_ticker/CBNA/main/CBNA.go
  8. 108 0
      trigger/pjisuv/cicv_ticker/CBNAO/main/CBNAO.go
  9. 84 0
      trigger/pjisuv/cicv_ticker/CCCscp_f/main/CCCscp_f.go
  10. 84 0
      trigger/pjisuv/cicv_ticker/CCCscp_n/main/CCCscp_n.go
  11. 110 0
      trigger/pjisuv/cicv_ticker/CCCscpo/main/CCCscpo.go
  12. 86 0
      trigger/pjisuv/cicv_ticker/CCFhos/main/CCFhos.go
  13. 85 0
      trigger/pjisuv/cicv_ticker/CCRH/main/CCRH.go
  14. 108 0
      trigger/pjisuv/cicv_ticker/CPNCO/main/CPNCO.go
  15. 86 0
      trigger/pjisuv/cicv_ticker/CPRm_f/main/CPRm_f.go
  16. 86 0
      trigger/pjisuv/cicv_ticker/CPRm_n/main/CPRm_n.go
  17. 99 0
      trigger/pjisuv/cicv_ticker/FrontCarRetrogradeOnJunction/main/FrontCarRetrogradeOnJunction.go
  18. 56 0
      trigger/pjisuv/cicv_ticker/FrontCarSideBySide/main/FrontCarSideBySide.go
  19. 85 0
      trigger/pjisuv/cicv_ticker/FrontCarStayAway/main/FrontCarStayAway.go
  20. 1 1
      trigger/pjisuv/cicv_ticker/FrontVehicleBrake/main/FrontVehicleBrake.go
  21. 1 1
      trigger/pjisuv/cicv_ticker/FrontVehicleBrakeInCurve/main/FrontVehicleBrakeInCurve.go
  22. 4 42
      trigger/pjisuv/cicv_ticker/FrontVehicleBrakeInJunction/main/FrontVehicleBrakeInJunction.go
  23. 2 2
      trigger/pjisuv/cicv_ticker/FrontVehiclesFrequentChangeLane/main/FrontVehiclesFrequentChangeLane.go
  24. 85 0
      trigger/pjisuv/cicv_ticker/RearTruckApproach/main/RearTruckApproach.go
  25. 98 0
      trigger/pjisuv/cicv_ticker/RearVehiclesFrequentChangeLane/main/RearVehiclesFrequentChangeLane.go
  26. 60 0
      trigger/pjisuv/tpperception/CBLA/main/CBLA.go
  27. 48 0
      trigger/pjisuv/tpperception/CBTA_f/main/CBTA_f.go
  28. 48 0
      trigger/pjisuv/tpperception/CBTA_n/main/CBTA_n.go
  29. 46 0
      trigger/pjisuv/tpperception/CCFtap/main/CCFtap.go
  30. 60 0
      trigger/pjisuv/tpperception/CPLA/main/CPLA.go
  31. 47 0
      trigger/pjisuv/tpperception/CPTA_f/main/CPTA_f.go
  32. 47 0
      trigger/pjisuv/tpperception/CPTA_n/main/CPTA_n.go
  33. 55 0
      trigger/pjisuv/tpperception/FrontCarSideBySide/main/FrontCarSideBySide.go

+ 112 - 4
aarch64/pjisuv/master/service/produce_window.go

@@ -28,24 +28,43 @@ type Weather struct {
 type Point struct {
 	x, y float64
 }
+type Location struct {
+	Latitude  float64
+	Longitude float64
+}
 
 var (
+	LeftCurveFlag  bool = false
+	RightCurveFlag bool = false //用来判断车辆是左转还是右转
 	//定义了车间四个边界点,将车间抽象成一个四边形
-	vertices = []Point{
+	LocationCount = 0
+	vertices      = []Point{
 		{x: 456128.413, y: 4397847.78},
 		{x: 456288.257, y: 4397953.51},
 		{x: 456359.022, y: 4397822.84},
 		{x: 456191.065, y: 4397733.3},
 	}
+	//定义园区部门T字路口的经纬度坐标值
+	point3 = Location{39.73040966605621, 116.48995329696209}
+	point4 = Location{39.73083727413453, 116.49079780188244}
+	point5 = Location{39.72976753711939, 116.49043130389033}
+	point6 = Location{39.73012466515933, 116.49128381717591}
+	point7 = Location{39.729251498328246, 116.49077484625299}
+	point8 = Location{39.72964529630643, 116.49164592200161}
+
+	pointlist = []Location{point3, point4, point5, point6, point7, point8}
+
 	cicvLocationTime = time.Now()
 	// -----------------------------共享变量
 	//cicv_location
 	//NumOfCicvLocation = 0
-	SpeedSlice  = []float64{}
-	AccelXSlice = []float64{}
+	SpeedSlice   = []float64{}
+	AccelXSlice  = []float64{}
+	JunctionFlag = false
 	//Yowslice          = make([]float64, 0)
 	//AngleSlice        = make([][]float64, 0)
 	// /tpperception
+	countSideBySide           int     = 0
 	Frame                     float32 = 0.0
 	ObjDicOfTpperception              = make(map[uint32][][]float32)
 	objTypeDicOfTpperception          = make(map[uint32]uint8)
@@ -592,6 +611,34 @@ func ProduceWindow() {
 						}
 						subscribersTimeMutexes[i].Unlock()
 						// 更新共享变量
+
+						Trajectorypoints := data.Trajectoryinfo.Trajectorypoints
+						if len(Trajectorypoints) > 2 {
+							StartHeading := Trajectorypoints[0].Heading
+							EndHeading := Trajectorypoints[len(Trajectorypoints)-1].Heading
+							diffHeading := StartHeading - EndHeading
+							//fmt.Println(diffHeading)
+
+							if diffHeading < -1.0 && diffHeading > -3.0 {
+								LeftCurveFlag = true
+								//fmt.Println(diffHeading)
+							} else {
+								LeftCurveFlag = false
+							}
+							if diffHeading > 1.0 && diffHeading < 3.0 {
+								RightCurveFlag = true
+								//fmt.Println(diffHeading)
+							} else {
+								RightCurveFlag = false
+							}
+
+						} else {
+							LeftCurveFlag = false
+							RightCurveFlag = false
+						}
+						shareVars.Store("LeftCurveFlag", LeftCurveFlag)
+						shareVars.Store("RightCurveFlag", RightCurveFlag)
+
 						currentCurvateres := make([]float64, 0)
 						for _, point := range data.Trajectoryinfo.Trajectorypoints {
 							currentCurvateres = append(currentCurvateres, math.Abs(float64(point.Curvature)))
@@ -607,6 +654,7 @@ func ProduceWindow() {
 
 			// 12 有共享变量的订阅者必须被创建
 			if topic == masterConfig.TopicOfCicvLocation {
+				LocationCount++
 				subscribers[i], err = goroslib.NewSubscriber(goroslib.SubscriberConf{
 					Node:  commonConfig.RosNode,
 					Topic: topic,
@@ -643,6 +691,12 @@ func ProduceWindow() {
 						}
 						subscribersTimeMutexes[i].Unlock()
 						// 更新共享变量
+						if LocationCount%10 == 0 {
+							enterflag := IfEnter(pointlist, 12.0, data.Latitude, data.Longitude)
+							shareVars.Store("EnterJunctionFlag", enterflag)
+							LocationCount = 0
+						}
+
 						AbsSpeed := math.Sqrt(math.Pow(data.VelocityX, 2) + math.Pow(data.VelocityY, 2))
 						AccelXSlice = append(AccelXSlice, data.AccelX)
 						shareVars.Store("AbsSpeed", AbsSpeed)
@@ -1532,11 +1586,21 @@ func ProduceWindow() {
 
 						// 更新共享变量
 						for _, obj := range data.Objs {
+							YawOfCicvLocation, _ := shareVars.Load("YawOfCicvLocation")
+							diffh := (float64(obj.Heading - YawOfCicvLocation.(float32)))
+							if diffh < -180.0 {
+								diffh = 360.0 + diffh
+							} else if diffh > 180.0 {
+								diffh = 360.0 - diffh
+							} else {
+								diffh = math.Abs(diffh)
+							}
+
 							if math.Abs(float64(obj.X)) >= 30 || math.Abs(float64(obj.Y)) >= 30 {
 								continue
 							}
 							if _, ok := ObjDicOfTpperception[obj.Id]; !ok {
-								ObjDicOfTpperception[obj.Id] = [][]float32{{}, {}, {}, {}, {}, {}}
+								ObjDicOfTpperception[obj.Id] = [][]float32{{}, {}, {}, {}, {}, {}, {}, {}}
 							}
 							ObjDicOfTpperception[obj.Id][0] = append(ObjDicOfTpperception[obj.Id][0], obj.X)
 							ObjDicOfTpperception[obj.Id][1] = append(ObjDicOfTpperception[obj.Id][1], obj.Y)
@@ -1545,6 +1609,18 @@ func ProduceWindow() {
 							ObjDicOfTpperception[obj.Id][3] = append(ObjDicOfTpperception[obj.Id][3], float32(absspeed))
 							ObjDicOfTpperception[obj.Id][4] = append(ObjDicOfTpperception[obj.Id][4], obj.Heading)
 							ObjDicOfTpperception[obj.Id][5] = append(ObjDicOfTpperception[obj.Id][5], Frame)
+							ObjDicOfTpperception[obj.Id][6] = append(ObjDicOfTpperception[obj.Id][6], float32(obj.Type))
+							ObjDicOfTpperception[obj.Id][7] = append(ObjDicOfTpperception[obj.Id][7], float32(diffh))
+							if len(ObjDicOfTpperception[obj.Id][0]) >= 100 {
+								ObjDicOfTpperception[obj.Id][0] = ObjDicOfTpperception[obj.Id][0][1:]
+								ObjDicOfTpperception[obj.Id][1] = ObjDicOfTpperception[obj.Id][1][1:]
+								ObjDicOfTpperception[obj.Id][2] = ObjDicOfTpperception[obj.Id][2][1:]
+								ObjDicOfTpperception[obj.Id][3] = ObjDicOfTpperception[obj.Id][3][1:]
+								ObjDicOfTpperception[obj.Id][4] = ObjDicOfTpperception[obj.Id][4][1:]
+								ObjDicOfTpperception[obj.Id][5] = ObjDicOfTpperception[obj.Id][5][1:]
+								ObjDicOfTpperception[obj.Id][6] = ObjDicOfTpperception[obj.Id][6][1:]
+								ObjDicOfTpperception[obj.Id][7] = ObjDicOfTpperception[obj.Id][7][1:]
+							}
 
 							objTypeDicOfTpperception[obj.Id] = obj.Type
 							objSpeedDicOfTpperception[obj.Id] = math.Pow(math.Pow(float64(obj.Vxabs), 2)+math.Pow(float64(obj.Vyabs), 2), 0.5)
@@ -1552,6 +1628,8 @@ func ProduceWindow() {
 						shareVars.Store("ObjDicOfTpperception", ObjDicOfTpperception)
 						shareVars.Store("ObjTypeDicOfTpperception", objTypeDicOfTpperception)
 						shareVars.Store("ObjSpeedDicOfTpperception", objSpeedDicOfTpperception)
+						shareVars.Store("countSideBySide", countSideBySide)
+
 						Frame++
 					},
 				})
@@ -2128,3 +2206,33 @@ func max(a, b float64) float64 {
 	}
 	return b
 }
+
+// 判断Ego是否在交叉口,在的话返回true
+func IfEnter(pointlist []Location, radius float64, lat, lon float64) bool {
+	// 判断是否进入点列表中的区域
+	point1 := Location{Latitude: lat, Longitude: lon}
+	for _, point := range pointlist {
+		d := distance(point1, point)
+		if d <= radius {
+			return true
+		}
+	}
+	return false
+}
+
+// 计算两点之间的距离(米)
+func distance(point1, point2 Location) float64 {
+	// 经纬度转弧度
+	lat1 := point1.Latitude * math.Pi / 180
+	lon1 := point1.Longitude * math.Pi / 180
+	lat2 := point2.Latitude * math.Pi / 180
+	lon2 := point2.Longitude * math.Pi / 180
+
+	// 计算距离
+	dlon := lon2 - lon1
+	dlat := lat2 - lat1
+	a := math.Sin(dlat/2)*math.Sin(dlat/2) + math.Sin(dlon/2)*math.Sin(dlon/2)*math.Cos(lat1)*math.Cos(lat2)
+	c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
+	d := 6371000 * c
+	return d
+}

+ 25 - 29
trigger/pjisuv/cicv_location/AbnormalStopOnJunction/main/AbnormalStopOnJunction.go

@@ -17,18 +17,10 @@ var (
 	StartTime  int64
 	threshold  int64 = 3
 	IsStopped  bool
-	IsEndPoint bool
 	IsJunction bool
+	IsEndPoint bool
 	count1     int64
-	point3     = Point{39.73040966605621, 116.48995329696209}
-	point4     = Point{39.73083727413453, 116.49079780188244}
-	point5     = Point{39.72976753711939, 116.49043130389033}
-	point6     = Point{39.73012466515933, 116.49128381717591}
-	point7     = Point{39.729251498328246, 116.49077484625299}
-	point8     = Point{39.72964529630643, 116.49164592200161}
-
-	PointJunctionList = []Point{point3, point4, point5, point6, point7, point8}
-	EndPoint          = Point{0, 0}
+	EndPoint   = Point{0, 0}
 )
 
 func Topic() string {
@@ -77,7 +69,7 @@ func Rule(shareVars *sync.Map, data *pjisuv_msgs.PerceptionLocalization) string
 		}
 	}()
 	if count1%10 == 0 {
-		Automode, _ := shareVars.Load("AutomodeOfPjVehicleFdbPub")
+		Automode, ok3 := shareVars.Load("AutomodeOfPjVehicleFdbPub")
 		Longitude, ok1 := shareVars.Load("EndPointX")
 		if !ok1 {
 			Longitude = 0.0
@@ -90,30 +82,34 @@ func Rule(shareVars *sync.Map, data *pjisuv_msgs.PerceptionLocalization) string
 		EndPoint.Longitude = Longitude.(float64)
 		EndPoint.Latitude = Latitude.(float64)
 		pointlist2 := []Point{EndPoint}
-		IsJunction = IfEnter(PointJunctionList, 25.0, data.Latitude, data.Longitude)
-		IsEndPoint = IfEnter(pointlist2, 5.0, data.Latitude, data.Longitude)
-		if Automode == 1 && IsJunction && !IsEndPoint {
-			AbsSpeed, _ := shareVars.Load("AbsSpeed")
-			if AbsSpeed.(float64) < 0.5 {
-				// 如果之前没有记录开始时间,记录当前时间
-				if StartTime == 0 {
-					StartTime = time.Now().Unix()
-				}
-				// 判断是否持续超过 50s
-				if time.Now().Unix()-StartTime > threshold {
-					if !IsStopped {
-						IsStopped = true
-						return Label()
+		EnterJunctionFlag, ok := shareVars.Load("EnterJunctionFlag")
+		if ok && ok3 {
+
+			IsJunction = EnterJunctionFlag.(bool)
+			IsEndPoint = IfEnter(pointlist2, 5.0, data.Latitude, data.Longitude)
+			if Automode == 1 && IsJunction && !IsEndPoint {
+				AbsSpeed, _ := shareVars.Load("AbsSpeed")
+				if AbsSpeed.(float64) < 0.5 {
+					// 如果之前没有记录开始时间,记录当前时间
+					if StartTime == 0 {
+						StartTime = time.Now().Unix()
+					}
+					// 判断是否持续超过 50s
+					if time.Now().Unix()-StartTime > threshold {
+						if !IsStopped {
+							IsStopped = true
+							return Label()
+						}
 					}
+				} else {
+					// 如果速度大于 0.1,重置开始时间和停止标志
+					StartTime = 0
+					IsStopped = false
 				}
 			} else {
-				// 如果速度大于 0.1,重置开始时间和停止标志
 				StartTime = 0
 				IsStopped = false
 			}
-		} else {
-			StartTime = 0
-			IsStopped = false
 		}
 	}
 	count1++

+ 6 - 57
trigger/pjisuv/cicv_location/EnterTjunction/main/EnterTjunction.go

@@ -3,7 +3,6 @@ package main
 import (
 	"cicv-data-closedloop/pjisuv_msgs"
 	"fmt"
-	"math"
 	"sync"
 )
 
@@ -16,69 +15,19 @@ func Label() string {
 	return "EnterTjunction"
 }
 
-type Point struct {
-	Latitude  float64
-	Longitude float64
-}
-
-var (
-	count2 int = 0
-
-	//定义园区部门T字路口的经纬度坐标值
-	point3 = Point{39.73040966605621, 116.48995329696209}
-	point4 = Point{39.73083727413453, 116.49079780188244}
-	point5 = Point{39.72976753711939, 116.49043130389033}
-	point6 = Point{39.73012466515933, 116.49128381717591}
-	point7 = Point{39.729251498328246, 116.49077484625299}
-	point8 = Point{39.72964529630643, 116.49164592200161}
-
-	pointlist = []Point{point3, point4, point5, point6, point7, point8}
-)
-
 func Rule(shareVars *sync.Map, data *pjisuv_msgs.PerceptionLocalization) string {
 	defer func() {
 		if r := recover(); r != nil {
 			fmt.Println("Recovered from panic:", r)
 		}
 	}()
-	if count2%10 == 0 {
-		enterflag := IfEnter(pointlist, 12.0, data.Latitude, data.Longitude)
-		velocityXOfCicvLocation, ok := shareVars.Load("VelocityXOfCicvLocation")
-		if ok {
-			if enterflag && velocityXOfCicvLocation.(float64) >= 1 {
-				return Label()
-			}
-		}
-	}
-	count2++
-	return ""
-}
+	EnterJunctionFlag, ok := shareVars.Load("EnterJunctionFlag")
+	AbsSpeed, ok1 := shareVars.Load("AbsSpeed")
 
-func IfEnter(pointlist []Point, radius float64, lat, lon float64) bool {
-	// 判断是否进入点列表中的区域
-	point1 := Point{Latitude: lat, Longitude: lon}
-	for _, point := range pointlist {
-		d := distance(point1, point)
-		if d <= radius {
-			return true
-		}
-	}
-	return false
-}
+	if ok && ok1 && EnterJunctionFlag.(bool) == true && AbsSpeed.(float64) >= 1 {
+		return Label()
 
-// 计算两点之间的距离(米)
-func distance(point1, point2 Point) float64 {
-	// 经纬度转弧度
-	lat1 := point1.Latitude * math.Pi / 180
-	lon1 := point1.Longitude * math.Pi / 180
-	lat2 := point2.Latitude * math.Pi / 180
-	lon2 := point2.Longitude * math.Pi / 180
+	}
 
-	// 计算距离
-	dlon := lon2 - lon1
-	dlat := lat2 - lat1
-	a := math.Sin(dlat/2)*math.Sin(dlat/2) + math.Sin(dlon/2)*math.Sin(dlon/2)*math.Cos(lat1)*math.Cos(lat2)
-	c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
-	d := 6371000 * c
-	return d
+	return ""
 }

+ 12 - 55
trigger/pjisuv/cicv_location/JunctionOverspeed/main/JunctionOverspeed.go

@@ -3,7 +3,6 @@ package main
 import (
 	"cicv-data-closedloop/pjisuv_msgs"
 	"fmt"
-	"math"
 	"sync"
 )
 
@@ -14,17 +13,6 @@ type Point struct {
 
 var (
 	threshold float64 = 5
-	IsCurve   bool
-	count1    int64
-	//定义园区T字路口的经纬度坐标值
-	point3 = Point{39.73040966605621, 116.48995329696209}
-	point4 = Point{39.73083727413453, 116.49079780188244}
-	point5 = Point{39.72976753711939, 116.49043130389033}
-	point6 = Point{39.73012466515933, 116.49128381717591}
-	point7 = Point{39.729251498328246, 116.49077484625299}
-	point8 = Point{39.72964529630643, 116.49164592200161}
-
-	pointlist = []Point{point3, point4, point5, point6, point7, point8}
 )
 
 func Topic() string {
@@ -36,57 +24,26 @@ func Label() string {
 	return "JunctionOverspeed"
 }
 
-func IfEnter(pointlist []Point, radius float64, lat, lon float64) bool {
-	// 判断是否进入点列表中的区域
-	point1 := Point{Latitude: lat, Longitude: lon}
-	for _, point := range pointlist {
-		d := distance(point1, point)
-		if d <= radius {
-			return true
-		}
-	}
-	return false
-}
-
-// 计算两点之间的距离(米)
-func distance(point1, point2 Point) float64 {
-	// 经纬度转弧度
-	lat1 := point1.Latitude * math.Pi / 180
-	lon1 := point1.Longitude * math.Pi / 180
-	lat2 := point2.Latitude * math.Pi / 180
-	lon2 := point2.Longitude * math.Pi / 180
-
-	// 计算距离
-	dlon := lon2 - lon1
-	dlat := lat2 - lat1
-	a := math.Sin(dlat/2)*math.Sin(dlat/2) + math.Sin(dlon/2)*math.Sin(dlon/2)*math.Cos(lat1)*math.Cos(lat2)
-	c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
-	d := 6371000 * c
-
-	return d
-}
-
 func Rule(shareVars *sync.Map, data *pjisuv_msgs.PerceptionLocalization) string {
 	defer func() {
 		if r := recover(); r != nil {
 			fmt.Println("Recovered from panic:", r)
 		}
 	}()
-	if count1%10 == 0 {
-		Automode, _ := shareVars.Load("AutomodeOfPjVehicleFdbPub")
-		Automode = Automode.(int16)
-		IsCurve = IfEnter(pointlist, 16.0, data.Latitude, data.Longitude)
 
-		if Automode == 1 && IsCurve {
-			absspeed, ok := shareVars.Load("AbsSpeed")
-			if ok && absspeed.(float64) >= threshold {
-				eventLabel := "JunctionOverspeed"
-				fmt.Println(eventLabel)
-				count1 = 1
-				return Label()
-			}
+	Automode, _ := shareVars.Load("AutomodeOfPjVehicleFdbPub")
+	Automode = Automode.(int16)
+	EnterJunctionFlag, ok1 := shareVars.Load("EnterJunctionFlag")
+
+	if ok1 && Automode == 1 && EnterJunctionFlag.(bool) == true {
+		absspeed, ok := shareVars.Load("AbsSpeed")
+		if ok && absspeed.(float64) >= threshold {
+			eventLabel := "JunctionOverspeed"
+			fmt.Println(eventLabel)
+
+			return Label()
 		}
 	}
-	count1++
+
 	return ""
 }

+ 65 - 0
trigger/pjisuv/cicv_location/ReverseAndOverspeed/main/ReverseAndOverspeed.go

@@ -0,0 +1,65 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_msgs"
+	"fmt"
+	"math"
+	"sync"
+)
+
+var (
+	threshold float64 = 15 / 3.6
+	count1    int     = 0
+)
+
+func Topic() string {
+	return "/cicv_location"
+}
+
+// 禁止存在下划线_
+func Label() string {
+	return "ReverseAndOverspeed"
+}
+func calculateDirectionAngle(speedX, speedY float64) float64 {
+	// 使用反正切函数计算方向角
+	angle := math.Atan2(speedY, speedX)
+
+	// 将角度转换为度数
+	angleDegree := angle * (180 / math.Pi)
+
+	// 将角度限定在 0~360 范围内
+	if angleDegree < 0 {
+		angleDegree += 360
+	} else if angleDegree > 360 {
+		angleDegree -= 360
+	}
+
+	return angleDegree
+}
+
+// 主进程的逻辑是先判断触发再缓存全局变量
+func Rule(shareVars *sync.Map, data *pjisuv_msgs.PerceptionLocalization) string {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	if count1%200 == 0 {
+		OutsideWorkshopFlag, ok3 := shareVars.Load("OutsideWorkshopFlag")
+		if ok3 {
+			directionAngle := calculateDirectionAngle(data.VelocityX, data.VelocityY)
+			AbsSpeed, _ := shareVars.Load("AbsSpeed")
+			diffAngle := math.Abs(float64(directionAngle - data.Yaw))
+			//fmt.Println(diffAngle)
+			if AbsSpeed.(float64) >= threshold && diffAngle >= 160 && diffAngle <= 200 && OutsideWorkshopFlag.(bool) {
+
+				eventLabel := "ReverseAndOverspeed"
+				fmt.Println(eventLabel)
+				count1 = 1
+				return Label()
+			}
+		}
+	}
+	count1++
+	return ""
+}

+ 108 - 0
trigger/pjisuv/cicv_ticker/CBFA/main/CBFA.go

@@ -0,0 +1,108 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"sync"
+	"time"
+)
+
+var ()
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "CBFA"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(3) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+func findIndex(lst []float32, target float32) int {
+	for i, v := range lst {
+		if v == target {
+			return i
+		}
+	}
+	return -1
+}
+
+func isCrossAndOcclusion(id uint32, ObjectList [][]float32, ObjectSlice map[uint32][][]float32) bool {
+	for i := 0; i < len(ObjectList[0]); i++ {
+		xi := ObjectList[0][i]
+		yi := ObjectList[1][i]
+		diff_hi := ObjectList[7][i]
+		Type := ObjectList[6][0]
+
+		if xi >= 0 && yi >= 3 && diff_hi <= 120 && diff_hi >= 60 && Type == 4.0 {
+			startFrame1 := ObjectList[5][i]
+
+			for j := 0; j < len(ObjectList[0])-i-1; j++ {
+				xj := ObjectList[0][j]
+				yj := ObjectList[1][j]
+				diff_hj := ObjectList[7][j]
+				if xj >= 0 && xj >= 30 && xj <= 50 && yj <= -1 && diff_hj <= 120 && diff_hj >= 60 {
+					startFrame2 := ObjectList[5][j]
+					for this_id, objValue := range ObjectSlice {
+						if this_id != id {
+							this_startFrame_index1 := findIndex(objValue[3], startFrame1)
+							this_startFrame_index2 := findIndex(objValue[3], startFrame2)
+							this_type := objValue[6][0]
+							//fmt.Println(objValue[0][this_startFrame_index2], xj)
+							if objValue[0][this_startFrame_index1] >= 2 && objValue[0][this_startFrame_index1] < xi-1 && objValue[1][this_startFrame_index1] > 0 && objValue[1][this_startFrame_index1] < yi && objValue[0][this_startFrame_index2] >= 1 && objValue[0][this_startFrame_index2] < xj-1 && objValue[1][this_startFrame_index2] > 0 && (this_type == 2.0 || this_type == 3.0) {
+								return true
+							}
+						} else {
+							continue
+						}
+					}
+				}
+			}
+		}
+	}
+	return false
+}
+func FinalCallback(shareVars *sync.Map) {
+
+	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
+	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
+	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+	AbsSpeed, ok2 := shareVars.Load("AbsSpeed")
+
+	if ok && ok1 && ok2 && OutsideWorkshopFlag.(bool) == true && AbsSpeed.(float64) > 1 {
+		for id, objValue := range ObjDic {
+			if len(ObjDic[0]) <= 10 || !isCrossAndOcclusion(id, objValue, ObjDic) {
+				continue
+			}
+			event_lable := "CBFA"
+			fmt.Println(event_lable)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+		}
+
+	}
+
+}

+ 108 - 0
trigger/pjisuv/cicv_ticker/CBNA/main/CBNA.go

@@ -0,0 +1,108 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"sync"
+	"time"
+)
+
+var ()
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "CBNA"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(3) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+func findIndex(lst []float32, target float32) int {
+	for i, v := range lst {
+		if v == target {
+			return i
+		}
+	}
+	return -1
+}
+
+func isCrossAndOcclusion(id uint32, ObjectList [][]float32, ObjectSlice map[uint32][][]float32) bool {
+	for i := 0; i < len(ObjectList[0]); i++ {
+		xi := ObjectList[0][i]
+		yi := ObjectList[1][i]
+		diff_hi := ObjectList[7][i]
+		Type := ObjectList[6][0]
+
+		if xi >= 0 && yi <= -3 && diff_hi <= 120 && diff_hi >= 60 && Type == 4.0 {
+			startFrame1 := ObjectList[5][i]
+
+			for j := 0; j < len(ObjectList[0])-i-1; j++ {
+				xj := ObjectList[0][j]
+				yj := ObjectList[1][j]
+				diff_hj := ObjectList[7][j]
+				if xj >= 0 && xj <= 25 && yj >= 1 && diff_hj <= 120 && diff_hj >= 60 {
+					startFrame2 := ObjectList[5][j]
+					for this_id, objValue := range ObjectSlice {
+						if this_id != id {
+							this_startFrame_index1 := findIndex(objValue[3], startFrame1)
+							this_startFrame_index2 := findIndex(objValue[3], startFrame2)
+							this_type := objValue[6][0]
+							//fmt.Println(objValue[0][this_startFrame_index2], xj)
+							if objValue[0][this_startFrame_index1] >= 2 && objValue[0][this_startFrame_index1] < xi-1 && objValue[1][this_startFrame_index1] < 0 && objValue[1][this_startFrame_index1] > yi && objValue[0][this_startFrame_index2] >= 1 && objValue[0][this_startFrame_index2] < xj-1 && objValue[1][this_startFrame_index2] < 0 && (this_type == 2.0 || this_type == 3.0) {
+								return true
+							}
+						} else {
+							continue
+						}
+					}
+				}
+			}
+		}
+	}
+	return false
+}
+func FinalCallback(shareVars *sync.Map) {
+
+	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
+	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
+	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+	AbsSpeed, ok2 := shareVars.Load("AbsSpeed")
+
+	if ok && ok1 && ok2 && OutsideWorkshopFlag.(bool) == true && AbsSpeed.(float64) > 1 {
+		for id, objValue := range ObjDic {
+			if len(ObjDic[0]) <= 10 || !isCrossAndOcclusion(id, objValue, ObjDic) {
+				continue
+			}
+			event_lable := "CBNA"
+			fmt.Println(event_lable)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+		}
+
+	}
+
+}

+ 108 - 0
trigger/pjisuv/cicv_ticker/CBNAO/main/CBNAO.go

@@ -0,0 +1,108 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"sync"
+	"time"
+)
+
+var ()
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "CBNAO"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(3) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+func findIndex(lst []float32, target float32) int {
+	for i, v := range lst {
+		if v == target {
+			return i
+		}
+	}
+	return -1
+}
+
+func isCrossAndOcclusion(id uint32, ObjectList [][]float32, ObjectSlice map[uint32][][]float32) bool {
+	for i := 0; i < len(ObjectList[0]); i++ {
+		xi := ObjectList[0][i]
+		yi := ObjectList[1][i]
+		diff_hi := ObjectList[7][i]
+		Type := ObjectList[6][0]
+
+		if xi >= 0 && yi <= -3 && diff_hi <= 120 && diff_hi >= 60 && Type == 4.0 {
+			startFrame1 := ObjectList[5][i]
+
+			for j := 0; j < len(ObjectList[0])-i-1; j++ {
+				xj := ObjectList[0][j]
+				yj := ObjectList[1][j]
+				diff_hj := ObjectList[7][j]
+				if xj >= 0 && xj <= 25 && yj >= 1 && diff_hj <= 120 && diff_hj >= 60 {
+					startFrame2 := ObjectList[5][j]
+					for this_id, objValue := range ObjectSlice {
+						if this_id != id {
+							this_startFrame_index1 := findIndex(objValue[3], startFrame1)
+							this_startFrame_index2 := findIndex(objValue[3], startFrame2)
+							this_type := objValue[6][0]
+							//fmt.Println(objValue[0][this_startFrame_index2], xj)
+							if objValue[0][this_startFrame_index1] >= 2 && objValue[0][this_startFrame_index1] < xi-5 && objValue[1][this_startFrame_index1] < 0 && objValue[1][this_startFrame_index1] > yi && objValue[0][this_startFrame_index2] >= 1 && objValue[0][this_startFrame_index2] < xj-3 && objValue[1][this_startFrame_index2] < 0 && (this_type == 2.0 || this_type == 3.0) {
+								return true
+							}
+						} else {
+							continue
+						}
+					}
+				}
+			}
+		}
+	}
+	return false
+}
+func FinalCallback(shareVars *sync.Map) {
+
+	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
+	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
+	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+	AbsSpeed, ok2 := shareVars.Load("AbsSpeed")
+
+	if ok && ok1 && ok2 && OutsideWorkshopFlag.(bool) == true && AbsSpeed.(float64) > 1 {
+		for id, objValue := range ObjDic {
+			if len(ObjDic[0]) <= 10 || !isCrossAndOcclusion(id, objValue, ObjDic) {
+				continue
+			}
+			event_lable := "CBNAO"
+			fmt.Println(event_lable)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+		}
+
+	}
+
+}

+ 84 - 0
trigger/pjisuv/cicv_ticker/CCCscp_f/main/CCCscp_f.go

@@ -0,0 +1,84 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"sync"
+	"time"
+)
+
+var ()
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "CCCscpf"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(3) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+func isCross(ObjectList [][]float32, AbsSpeed float64) bool {
+	for i := 0; i < len(ObjectList[0]); i++ {
+		Type := ObjectList[6][0]
+		xi := ObjectList[0][i]
+		yi := ObjectList[1][i]
+		diff_hi := ObjectList[7][i]
+
+		if xi >= 0 && yi >= 2 && diff_hi <= 120 && diff_hi >= 60 && Type != 1.0 && AbsSpeed > 1 {
+			for j := 0; j < len(ObjectList[0])-i-1; j++ {
+				xj := ObjectList[0][j]
+				yj := ObjectList[1][j]
+				diff_hj := ObjectList[7][j]
+				if xj >= 0 && yj <= -2 && diff_hj <= 120 && diff_hj >= 60 {
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
+func FinalCallback(shareVars *sync.Map) {
+
+	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
+	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
+	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+	AbsSpeed, ok2 := shareVars.Load("AbsSpeed")
+
+	if ok && ok1 && ok2 && OutsideWorkshopFlag.(bool) == true {
+		for _, objValue := range ObjDic {
+			if len(ObjDic[0]) <= 10 || !isCross(objValue, AbsSpeed.(float64)) {
+				continue
+			}
+			event_lable := "CCCscp_f"
+			fmt.Println(event_lable)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+		}
+
+	}
+
+}

+ 84 - 0
trigger/pjisuv/cicv_ticker/CCCscp_n/main/CCCscp_n.go

@@ -0,0 +1,84 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"sync"
+	"time"
+)
+
+var ()
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "CCCscpn"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(3) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+func isCross(ObjectList [][]float32, AbsSpeed float64) bool {
+	for i := 0; i < len(ObjectList[0]); i++ {
+		Type := ObjectList[6][0]
+		xi := ObjectList[0][i]
+		yi := ObjectList[1][i]
+		diff_hi := ObjectList[7][i]
+
+		if xi >= 0 && yi <= -2 && diff_hi <= 120 && diff_hi >= 60 && Type != 1.0 && AbsSpeed > 1 {
+			for j := 0; j < len(ObjectList[0])-i-1; j++ {
+				xj := ObjectList[0][j]
+				yj := ObjectList[1][j]
+				diff_hj := ObjectList[7][j]
+				if xj >= 0 && yj >= 2 && diff_hj <= 120 && diff_hj >= 60 {
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
+func FinalCallback(shareVars *sync.Map) {
+
+	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
+	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
+	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+	AbsSpeed, ok2 := shareVars.Load("AbsSpeed")
+
+	if ok && ok1 && ok2 && OutsideWorkshopFlag.(bool) == true {
+		for _, objValue := range ObjDic {
+			if len(ObjDic[0]) <= 10 || !isCross(objValue, AbsSpeed.(float64)) {
+				continue
+			}
+			event_lable := "CCCscp_n"
+			fmt.Println(event_lable)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+		}
+
+	}
+
+}

+ 110 - 0
trigger/pjisuv/cicv_ticker/CCCscpo/main/CCCscpo.go

@@ -0,0 +1,110 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"sync"
+	"time"
+)
+
+var ()
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "CCCscpo"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(3) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+func findIndex(lst []float32, target float32) int {
+	for i, v := range lst {
+		if v == target {
+			return i
+		}
+	}
+	return -1
+}
+
+func isCrossAndOcclusion(id uint32, ObjectList [][]float32, ObjectSlice map[uint32][][]float32, AbsSpeed float64) bool {
+	for i := 0; i < len(ObjectList[0]); i++ {
+		xi := ObjectList[0][i]
+		yi := ObjectList[1][i]
+		diff_hi := ObjectList[7][i]
+		Type := ObjectList[6][0]
+
+		if xi >= 0 && yi <= -3 && diff_hi <= 120 && diff_hi >= 60 && Type != 1.0 && AbsSpeed > 1 {
+			startFrame1 := ObjectList[5][i]
+
+			for j := 0; j < len(ObjectList[0])-i-1; j++ {
+				xj := ObjectList[0][j]
+				yj := ObjectList[1][j]
+				diff_hj := ObjectList[7][j]
+				if xj >= 0 && yj >= 1 && diff_hj <= 120 && diff_hj >= 60 {
+					startFrame2 := ObjectList[5][j]
+					for this_id, objValue := range ObjectSlice {
+						if this_id != id {
+
+							this_startFrame_index1 := findIndex(objValue[5], startFrame1)
+							this_startFrame_index2 := findIndex(objValue[5], startFrame2)
+							this_type := objValue[6][0]
+							//fmt.Println(objValue[0][this_startFrame_index2], xj)
+
+							if objValue[0][this_startFrame_index1] >= 2 && objValue[0][this_startFrame_index1] < xi-1 && objValue[1][this_startFrame_index1] < 0 && objValue[1][this_startFrame_index1] > yi && objValue[0][this_startFrame_index2] >= 1 && objValue[0][this_startFrame_index2] < xj-1 && objValue[1][this_startFrame_index2] < 0 && (this_type == 2.0 || this_type == 3.0) {
+								return true
+							}
+						} else {
+							continue
+						}
+					}
+				}
+			}
+		}
+	}
+	return false
+}
+func FinalCallback(shareVars *sync.Map) {
+
+	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
+	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
+	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+	AbsSpeed, ok2 := shareVars.Load("AbsSpeed")
+
+	if ok && ok1 && ok2 && OutsideWorkshopFlag.(bool) == true {
+		for id, objValue := range ObjDic {
+			if len(ObjDic[0]) <= 10 || !isCrossAndOcclusion(id, objValue, ObjDic, AbsSpeed.(float64)) {
+				continue
+			}
+			event_lable := "CCCscpo"
+			fmt.Println(event_lable)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+		}
+
+	}
+
+}

+ 86 - 0
trigger/pjisuv/cicv_ticker/CCFhos/main/CCFhos.go

@@ -0,0 +1,86 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"math"
+	"sync"
+	"time"
+)
+
+var ()
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "CCFhos"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(3) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+func isRetrograde(ObjectList [][]float32) bool {
+	for i := 0; i < len(ObjectList[0]); i++ {
+		xi := ObjectList[0][i]
+		yi := math.Abs(float64(ObjectList[1][i]))
+		diff_hi := ObjectList[7][i]
+		Type := ObjectList[6][0]
+
+		if xi >= 20 && yi <= 1.2 && diff_hi > 150 && Type != 1.0 {
+			for j := 0; j < len(ObjectList[0])-i-1; j++ {
+				xj := ObjectList[0][j]
+				yj := math.Abs(float64(ObjectList[1][j]))
+				diff_hj := ObjectList[7][j]
+
+				if xj <= 8 && yj <= 1.2 && diff_hj > 150 {
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
+func FinalCallback(shareVars *sync.Map) {
+
+	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
+	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
+	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+	AbsSpeed, ok2 := shareVars.Load("AbsSpeed")
+
+	if ok && ok1 && ok2 && OutsideWorkshopFlag.(bool) == true && AbsSpeed.(float64) > 1 {
+		for _, objValue := range ObjDic {
+			if len(ObjDic[0]) <= 10 || !isRetrograde(objValue) {
+				continue
+			}
+			event_lable := "CCFhos"
+			fmt.Println(event_lable)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+		}
+
+	}
+
+}

+ 85 - 0
trigger/pjisuv/cicv_ticker/CCRH/main/CCRH.go

@@ -0,0 +1,85 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"math"
+	"sync"
+	"time"
+)
+
+var ()
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "CCRH"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(3) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+func isCuttingOut(ObjectList [][]float32) bool {
+	for i := 0; i < len(ObjectList[0]); i++ {
+		xi := ObjectList[0][i]
+		yi := math.Abs(float64(ObjectList[1][i]))
+		Type := ObjectList[4][0]
+
+		if xi >= 0 && yi <= 0.7 && Type != 1.0 {
+			for j := 0; j < len(ObjectList[0])-i-1; j++ {
+				xj := ObjectList[0][j]
+				yj := math.Abs(float64(ObjectList[1][j]))
+
+				if xj >= 0 && yj >= 2.5 {
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
+func FinalCallback(shareVars *sync.Map) {
+
+	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
+	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
+	AngularVelocityZOfCicvLocation, ok3 := shareVars.Load("AngularVelocityZOfCicvLocation")
+	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+	AbsSpeed, ok2 := shareVars.Load("AbsSpeed")
+
+	if ok && ok1 && ok2 && ok3 && AngularVelocityZOfCicvLocation.(float64) < 0.6 && AbsSpeed.(float64) > 1 && OutsideWorkshopFlag.(bool) == true {
+		for _, objValue := range ObjDic {
+			if len(ObjDic[0]) <= 10 || !isCuttingOut(objValue) {
+				continue
+			}
+			event_lable := "CCRH"
+			fmt.Println(event_lable)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+		}
+
+	}
+
+}

+ 108 - 0
trigger/pjisuv/cicv_ticker/CPNCO/main/CPNCO.go

@@ -0,0 +1,108 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"sync"
+	"time"
+)
+
+var ()
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "CPNCO"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(3) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+func findIndex(lst []float32, target float32) int {
+	for i, v := range lst {
+		if v == target {
+			return i
+		}
+	}
+	return -1
+}
+
+func isCrossAndOcclusion(id uint32, ObjectList [][]float32, ObjectSlice map[uint32][][]float32) bool {
+	for i := 0; i < len(ObjectList[0]); i++ {
+		xi := ObjectList[0][i]
+		yi := ObjectList[1][i]
+		diff_hi := ObjectList[7][i]
+		Type := ObjectList[6][0]
+
+		if xi >= 0 && yi <= -3 && diff_hi <= 120 && diff_hi >= 60 && Type == 1.0 {
+			startFrame1 := ObjectList[5][i]
+
+			for j := 0; j < len(ObjectList[0])-i-1; j++ {
+				xj := ObjectList[0][j]
+				yj := ObjectList[1][j]
+				diff_hj := ObjectList[7][j]
+				if xj >= 0 && yj >= 1 && diff_hj <= 120 && diff_hj >= 60 {
+					startFrame2 := ObjectList[5][j]
+					for this_id, objValue := range ObjectSlice {
+						if this_id != id {
+							this_startFrame_index1 := findIndex(objValue[3], startFrame1)
+							this_startFrame_index2 := findIndex(objValue[3], startFrame2)
+							this_type := objValue[6][0]
+							//fmt.Println(objValue[0][this_startFrame_index2], xj)
+							if objValue[0][this_startFrame_index1] >= 2 && objValue[0][this_startFrame_index1] < xi-1 && objValue[1][this_startFrame_index1] < 0 && objValue[1][this_startFrame_index1] > yi && objValue[0][this_startFrame_index2] >= 1 && objValue[0][this_startFrame_index2] < xj-1 && objValue[1][this_startFrame_index2] < 0 && (this_type == 2.0 || this_type == 3.0) {
+								return true
+							}
+						} else {
+							continue
+						}
+					}
+				}
+			}
+		}
+	}
+	return false
+}
+func FinalCallback(shareVars *sync.Map) {
+
+	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
+	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
+	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+	AbsSpeed, ok2 := shareVars.Load("AbsSpeed")
+
+	if ok && ok1 && ok2 && OutsideWorkshopFlag.(bool) == true && AbsSpeed.(float64) > 1 {
+		for id, objValue := range ObjDic {
+			if len(ObjDic[0]) <= 10 || !isCrossAndOcclusion(id, objValue, ObjDic) {
+				continue
+			}
+			event_lable := "CPNCO"
+			fmt.Println(event_lable)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+		}
+
+	}
+
+}

+ 86 - 0
trigger/pjisuv/cicv_ticker/CPRm_f/main/CPRm_f.go

@@ -0,0 +1,86 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"sync"
+	"time"
+)
+
+var (
+	threshold float32 = 30
+)
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "CPRm_f"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(3) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+func isCross(ObjectList [][]float32) bool {
+	for i := 0; i < len(ObjectList[0]); i++ {
+		Type := ObjectList[6][0]
+		xi := ObjectList[0][i]
+		yi := ObjectList[1][i]
+		diff_hi := ObjectList[7][i]
+
+		if xi >= threshold && yi >= 2 && diff_hi <= 120 && diff_hi >= 60 && Type == 1.0 {
+			for j := 0; j < len(ObjectList[0])-i-1; j++ {
+				xj := ObjectList[0][j]
+				yj := ObjectList[1][j]
+				diff_hj := ObjectList[7][j]
+				if xj >= threshold && yj <= -2 && diff_hj <= 120 && diff_hj >= 60 {
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
+func FinalCallback(shareVars *sync.Map) {
+
+	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
+	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
+	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+	AbsSpeed, ok2 := shareVars.Load("AbsSpeed")
+
+	if ok && ok1 && ok2 && OutsideWorkshopFlag.(bool) == true && AbsSpeed.(float64) > 1 {
+		for _, objValue := range ObjDic {
+			if len(ObjDic[0]) <= 10 || !isCross(objValue) {
+				continue
+			}
+			event_lable := "CPRm_f"
+			fmt.Println(event_lable)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+		}
+
+	}
+
+}

+ 86 - 0
trigger/pjisuv/cicv_ticker/CPRm_n/main/CPRm_n.go

@@ -0,0 +1,86 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"sync"
+	"time"
+)
+
+var (
+	threshold float32 = 30
+)
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "CPRm_n"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(3) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+func isCross(ObjectList [][]float32) bool {
+	for i := 0; i < len(ObjectList[0]); i++ {
+		Type := ObjectList[4][0]
+		xi := ObjectList[0][i]
+		yi := ObjectList[1][i]
+		diff_hi := ObjectList[2][i]
+
+		if xi >= 0 && xi <= threshold && yi <= -2 && diff_hi <= 120 && diff_hi >= 60 && Type == 1.0 {
+			for j := 0; j < len(ObjectList[0])-i-1; j++ {
+				xj := ObjectList[0][j]
+				yj := ObjectList[1][j]
+				diff_hj := ObjectList[2][j]
+				if xj >= 0 && xj <= threshold && yj >= 2 && diff_hj <= 120 && diff_hj >= 60 {
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
+func FinalCallback(shareVars *sync.Map) {
+
+	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
+	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
+	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+	AbsSpeed, ok2 := shareVars.Load("AbsSpeed")
+
+	if ok && ok1 && ok2 && OutsideWorkshopFlag.(bool) == true && AbsSpeed.(float64) > 1 {
+		for _, objValue := range ObjDic {
+			if len(ObjDic[0]) <= 10 || !isCross(objValue) {
+				continue
+			}
+			event_lable := "CPRm_n"
+			fmt.Println(event_lable)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+		}
+
+	}
+
+}

+ 99 - 0
trigger/pjisuv/cicv_ticker/FrontCarRetrogradeOnJunction/main/FrontCarRetrogradeOnJunction.go

@@ -0,0 +1,99 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"math"
+	"sync"
+	"time"
+)
+
+// 要想正确触发必须保证EnterTjunction这个触发器正常工作
+var (
+	Maxlenobj int32 = 0
+)
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "FrontCarRetrogradeOnJunction"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(2) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+
+func isWrongDirection(ObjectList [][]float32, AngularVelocityZ float64, YawOfCicvLocation float32) bool {
+
+	for i, heading := range ObjectList[4] {
+		objXi := ObjectList[0][i]
+		objYi := ObjectList[1][i]
+		Anglei := math.Abs(float64(heading - YawOfCicvLocation))
+
+		if math.Abs(float64(objYi)) <= 1.8 && math.Abs(AngularVelocityZ) <= 0.6 && objXi > 15 && Anglei <= 200 && Anglei >= 160 {
+			//fmt.Println(objY)
+			for j := 0; j < len(ObjectList[1])-i-1; j++ {
+				objXij := ObjectList[0][1+i+j]
+				objYij := ObjectList[1][1+i+j]
+				if math.Abs(float64(objYij)) <= 1.8 && math.Abs(AngularVelocityZ) <= 0.6 && objXij <= 10 {
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
+func FinalCallback(shareVars *sync.Map) {
+	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
+	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
+	YawOfCicvLocation, ok2 := shareVars.Load("YawOfCicvLocation")
+	EnterJunctionFlag, ok3 := shareVars.Load("EnterJunctionFlag")
+
+	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+	AngularVelocityZOfCicvLocation, _ := shareVars.Load("AngularVelocityZOfCicvLocation")
+	AngularVelocityZ := AngularVelocityZOfCicvLocation.(float64)
+
+	if ok && ok1 && ok2 && ok3 && EnterJunctionFlag.(bool) && OutsideWorkshopFlag.(bool) == true {
+		for _, objValue := range ObjDic {
+			Maxlenobj = max(Maxlenobj, int32(len(objValue[0])))
+			if len(ObjDic[0]) <= 10 || !isWrongDirection(objValue, AngularVelocityZ, YawOfCicvLocation.(float32)) {
+				continue
+			}
+			event_lable := "FrontCarRetrogradeOnJunction"
+			fmt.Println(event_lable)
+			ObjDicOfTpperception = make(map[uint32][][]float32)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+		}
+
+		if Maxlenobj >= 100 {
+			ObjDicOfTpperception = make(map[uint32][][]float32)
+			shareVars.Store("ObjDicOfTpperception", ObjDicOfTpperception)
+			Maxlenobj = 0
+		}
+	}
+
+}

+ 56 - 0
trigger/pjisuv/cicv_ticker/FrontCarSideBySide/main/FrontCarSideBySide.go

@@ -0,0 +1,56 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"sync"
+	"time"
+)
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "FrontCarSideBySide"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(3) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+
+func FinalCallback(shareVars *sync.Map) {
+	countSideBySide, ok := shareVars.Load("CountSideBySide")
+	if ok {
+		if countSideBySide.(int) >= 20 {
+			event_lable := "FrontCarSideBySide"
+			fmt.Println(event_lable)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+
+		}
+
+	}
+	shareVars.Store("countSideBySide", 0)
+}

+ 85 - 0
trigger/pjisuv/cicv_ticker/FrontCarStayAway/main/FrontCarStayAway.go

@@ -0,0 +1,85 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"math"
+	"sync"
+	"time"
+)
+
+var (
+	Maxlenobj int32 = 0
+)
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "FrontCarStayAway"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(2) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+func isApproach(ObjectList [][]float32) bool {
+	for i, objX := range ObjectList[0] {
+
+		if math.Abs(float64(ObjectList[1][i])) <= 1.3 && objX <= 6 {
+			for j := 0; j < len(ObjectList[0])-i-1; j++ {
+				if math.Abs(float64(ObjectList[1][1+i+j])) <= 1.3 && ObjectList[0][1+i+j] >= 13 {
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
+func FinalCallback(shareVars *sync.Map) {
+	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
+	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
+	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+
+	if ok && ok1 && OutsideWorkshopFlag.(bool) == true {
+		for _, objValue := range ObjDic {
+			Maxlenobj = max(Maxlenobj, int32(len(objValue[0])))
+			if len(ObjDic[0]) <= 10 || !isApproach(objValue) {
+				continue
+			}
+			event_lable := "FrontCarStayAway"
+			fmt.Println(event_lable)
+			ObjDicOfTpperception = make(map[uint32][][]float32)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+		}
+
+		if Maxlenobj >= 100 {
+			ObjDicOfTpperception = make(map[uint32][][]float32)
+			shareVars.Store("ObjDicOfTpperception", ObjDicOfTpperception)
+			Maxlenobj = 0
+		}
+	}
+
+}

+ 1 - 1
trigger/pjisuv/cicv_ticker/FrontVehicleBrake/main/FrontVehicleBrake.go

@@ -72,7 +72,7 @@ func FinalCallback(shareVars *sync.Map) {
 			}
 			event_lable := "FrontVehicleBrake"
 			fmt.Println(event_lable)
-			ObjDicOfTpperception = make(map[uint32][][]float32)
+			//ObjDicOfTpperception = make(map[uint32][][]float32)
 			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
 		}
 		if Maxlenobj >= 100 {

+ 1 - 1
trigger/pjisuv/cicv_ticker/FrontVehicleBrakeInCurve/main/FrontVehicleBrakeInCurve.go

@@ -113,7 +113,7 @@ func FinalCallback(shareVars *sync.Map) {
 				}
 				event_lable := "FrontVehicleBrakeInCurve"
 				fmt.Println(event_lable)
-				ObjDicOfTpperception = make(map[uint32][][]float32)
+				//ObjDicOfTpperception = make(map[uint32][][]float32)
 				pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
 			}
 		}

+ 4 - 42
trigger/pjisuv/cicv_ticker/FrontVehicleBrakeInJunction/main/FrontVehicleBrakeInJunction.go

@@ -16,14 +16,6 @@ type Point struct {
 var (
 	Maxlenobj int32 = 0
 	//定义园区T字路口的经纬度坐标值
-	point3 = Point{39.73040966605621, 116.48995329696209}
-	point4 = Point{39.73083727413453, 116.49079780188244}
-	point5 = Point{39.72976753711939, 116.49043130389033}
-	point6 = Point{39.73012466515933, 116.49128381717591}
-	point7 = Point{39.729251498328246, 116.49077484625299}
-	point8 = Point{39.72964529630643, 116.49164592200161}
-
-	PointJunctionList = []Point{point3, point4, point5, point6, point7, point8}
 )
 
 // 定时任务触发器固定的
@@ -36,35 +28,6 @@ func Topic() string {
 func Label() string {
 	return "FrontVehicleBrakeInJunction"
 }
-func IfEnter(pointlist []Point, radius float64, lat, lon float64) bool {
-	// 判断是否进入点列表中的区域
-	point1 := Point{Latitude: lat, Longitude: lon}
-	for _, point := range pointlist {
-		d := distance(point1, point)
-		if d <= radius {
-			return true
-		}
-	}
-	return false
-}
-
-// 计算两点之间的距离(米)
-func distance(point1, point2 Point) float64 {
-	// 经纬度转弧度
-	lat1 := point1.Latitude * math.Pi / 180
-	lon1 := point1.Longitude * math.Pi / 180
-	lat2 := point2.Latitude * math.Pi / 180
-	lon2 := point2.Longitude * math.Pi / 180
-
-	// 计算距离
-	dlon := lon2 - lon1
-	dlat := lat2 - lat1
-	a := math.Sin(dlat/2)*math.Sin(dlat/2) + math.Sin(dlon/2)*math.Sin(dlon/2)*math.Cos(lat1)*math.Cos(lat2)
-	c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
-	d := 6371000 * c
-
-	return d
-}
 
 func Rule(shareVars *sync.Map) {
 	defer func() {
@@ -106,12 +69,11 @@ func isBrake(ObjectList [][]float32) bool {
 func FinalCallback(shareVars *sync.Map) {
 	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
 	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
-	Latitude, ok2 := shareVars.Load("Latitude")
-	Longitude, ok3 := shareVars.Load("Longitude")
 	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+	EnterJunctionFlag, ok4 := shareVars.Load("EnterJunctionFlag")
 
-	if ok && ok1 && ok2 && ok3 && OutsideWorkshopFlag.(bool) == true {
-		enterflag := IfEnter(PointJunctionList, 20.0, Latitude.(float64), Longitude.(float64))
+	if ok && ok1 && ok4 && OutsideWorkshopFlag.(bool) == true {
+		enterflag := EnterJunctionFlag.(bool)
 		if enterflag {
 			for _, objValue := range ObjDic {
 				Maxlenobj = max(Maxlenobj, int32(len(objValue[0])))
@@ -120,7 +82,7 @@ func FinalCallback(shareVars *sync.Map) {
 				}
 				event_lable := "FrontVehicleBrakeInJunction"
 				fmt.Println(event_lable)
-				ObjDicOfTpperception = make(map[uint32][][]float32)
+				//ObjDicOfTpperception = make(map[uint32][][]float32)
 				pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
 			}
 		}

+ 2 - 2
trigger/pjisuv/cicv_ticker/FrontVehiclesFrequentChangeLane/main/FrontVehiclesFrequentChangeLane.go

@@ -50,11 +50,11 @@ func countChanges(slice [][]float32, AngularVelocityZOfCicvLocation float64) int
 lable1:
 	for i := 0; i < len(slice[1]); {
 		xi := slice[0][i]
-		yi := slice[1][i]
+		yi := math.Abs(float64(slice[1][i]))
 		if (yi >= 1.8 || yi < 0.7) && xi >= 2 && math.Abs(AngularVelocityZOfCicvLocation) <= 1.6 {
 			for j := 0; j < len(slice[1])-i-1; j++ {
 				xij := slice[0][1+i+j]
-				yij := slice[1][1+i+j]
+				yij := math.Abs(float64(slice[1][1+i+j]))
 				if ((yi >= 1.8 && yij <= 0.7) || (yi < 0.7 && yij >= 1.8)) && xij >= 2 && math.Abs(AngularVelocityZOfCicvLocation) <= 1.6 {
 					count++
 					//fmt.Println("here!!")

+ 85 - 0
trigger/pjisuv/cicv_ticker/RearTruckApproach/main/RearTruckApproach.go

@@ -0,0 +1,85 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"math"
+	"sync"
+	"time"
+)
+
+var (
+	Maxlenobj int32 = 0
+)
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "RearTruckApproach"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(2) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+func isApproach(ObjectList [][]float32) bool {
+	for i, objX := range ObjectList[0] {
+
+		if ObjectList[6][i] == float32(3) && math.Abs(float64(ObjectList[1][i])) <= 1.3 && objX <= -10 {
+			for j := 0; j < len(ObjectList[0])-i-1; j++ {
+				if math.Abs(float64(ObjectList[1][1+i+j])) <= 1.3 && ObjectList[0][1+i+j] >= -6 && ObjectList[2][1+i+j] >= 1 {
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
+func FinalCallback(shareVars *sync.Map) {
+	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
+	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
+	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+
+	if ok && ok1 && OutsideWorkshopFlag.(bool) == true {
+		for _, objValue := range ObjDic {
+			Maxlenobj = max(Maxlenobj, int32(len(objValue[0])))
+			if len(ObjDic[0]) <= 10 || !isApproach(objValue) {
+				continue
+			}
+			event_lable := "RearTruckApproach"
+			fmt.Println(event_lable)
+			ObjDicOfTpperception = make(map[uint32][][]float32)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+		}
+
+		if Maxlenobj >= 100 {
+			ObjDicOfTpperception = make(map[uint32][][]float32)
+			shareVars.Store("ObjDicOfTpperception", ObjDicOfTpperception)
+			Maxlenobj = 0
+		}
+	}
+
+}

+ 98 - 0
trigger/pjisuv/cicv_ticker/RearVehiclesFrequentChangeLane/main/RearVehiclesFrequentChangeLane.go

@@ -0,0 +1,98 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_ticker"
+	"fmt"
+	"math"
+	"sync"
+	"time"
+)
+
+var (
+	Maxlenobj int32 = 0
+)
+
+// 定时任务触发器固定的
+func Topic() string {
+	return pjisuv_ticker.TickerTopic
+}
+
+// ******* 禁止存在下划线_
+// 触发器标记
+func Label() string {
+	return "RearVehiclesFrequentChangeLane"
+}
+
+func Rule(shareVars *sync.Map) {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	// 1 使用goroutine
+	go func(shareVars *sync.Map) {
+		// 2 定义触发器的间隔时间
+		ticker := time.NewTicker(time.Duration(4) * time.Second)
+		defer ticker.Stop()
+		// 3 运行一个无限循环
+		for {
+			select {
+			// 定时器触发时执行的代码
+			case <-ticker.C:
+				FinalCallback(shareVars)
+
+			}
+		}
+	}(shareVars)
+}
+func countChanges(slice [][]float32, AngularVelocityZOfCicvLocation float64) int {
+	count := 0
+lable1:
+	for i := 0; i < len(slice[1]); {
+		xi := slice[0][i]
+		yi := math.Abs(float64(slice[1][i]))
+		if (yi >= 1.8 || yi < 0.7) && xi <= -2 && math.Abs(AngularVelocityZOfCicvLocation) <= 1.6 {
+			for j := 0; j < len(slice[1])-i-1; j++ {
+				xij := slice[0][1+i+j]
+				yij := math.Abs(float64(slice[1][1+i+j]))
+				if ((yi >= 1.8 && yij <= 0.7) || (yi < 0.7 && yij >= 1.8)) && xij <= -2 && math.Abs(AngularVelocityZOfCicvLocation) <= 1.6 {
+					count++
+					//fmt.Println("here!!")
+					i = i + j + 1
+					continue lable1
+				}
+			}
+			break lable1
+		} else {
+			i++
+		}
+
+	}
+	return count
+}
+func FinalCallback(shareVars *sync.Map) {
+	OutsideWorkshopFlag, ok := shareVars.Load("OutsideWorkshopFlag")
+	ObjDicOfTpperception, ok1 := shareVars.Load("objDicOfTpperception")
+	ObjDic := ObjDicOfTpperception.(map[uint32][][]float32)
+	AngularVelocityZOfCicvLocation, _ := shareVars.Load("AngularVelocityZOfCicvLocation")
+	AngularVelocityZ := AngularVelocityZOfCicvLocation.(float64)
+
+	if ok && ok1 && OutsideWorkshopFlag.(bool) == true {
+		for _, objValue := range ObjDic {
+			Maxlenobj = max(Maxlenobj, int32(len(objValue[0])))
+			if len(ObjDic[0]) <= 10 || countChanges(objValue, AngularVelocityZ) < 2 {
+				continue
+			}
+			event_lable := "RearVehiclesFrequentChangeLane"
+			fmt.Println(event_lable)
+			pjisuv_ticker.TickerChan <- pjisuv_ticker.TickInfo{FaultLabel: Label(), FaultHappenTime: pjisuv_ticker.GetNowTimeCustom()}
+		}
+
+		if Maxlenobj >= 100 {
+			ObjDicOfTpperception = make(map[uint32][][]float32)
+			shareVars.Store("ObjDicOfTpperception", ObjDicOfTpperception)
+			Maxlenobj = 0
+		}
+	}
+
+}

+ 60 - 0
trigger/pjisuv/tpperception/CBLA/main/CBLA.go

@@ -0,0 +1,60 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_msgs"
+	"fmt"
+	"math"
+	"sync"
+	"time"
+)
+
+var (
+	StartTime int64
+	IsFollow  bool
+)
+
+func Topic() string {
+	return "/tpperception"
+}
+
+// 禁止存在下划线_
+func Label() string {
+	return "CBLA"
+}
+
+func Rule(shareVars *sync.Map, data *pjisuv_msgs.PerceptionObjects) string {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	OutsideWorkshopFlag, ok3 := shareVars.Load("OutsideWorkshopFlag")
+	AbsSpeed, ok2 := shareVars.Load("AbsSpeed")
+
+	if ok3 && ok2 && OutsideWorkshopFlag.(bool) && AbsSpeed.(float64) > 1 {
+
+		for _, obj := range data.Objs {
+			if obj.Type == 4 && obj.X >= 2 && obj.X <= 20 && math.Abs(float64(obj.Y)) <= 1.2 {
+				if StartTime == 0 {
+					StartTime = time.Now().Unix()
+				}
+
+				// 判断是否持续超过一分钟
+				if time.Now().Unix()-StartTime > 5 {
+					if !IsFollow {
+						event_label := "CBLA"
+						fmt.Println(event_label)
+						IsFollow = true
+						return Label()
+
+					}
+				}
+			} else {
+				StartTime = 0
+				IsFollow = false
+			}
+		}
+	}
+
+	return ""
+}

+ 48 - 0
trigger/pjisuv/tpperception/CBTA_f/main/CBTA_f.go

@@ -0,0 +1,48 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_msgs"
+	"fmt"
+	"math"
+	"sync"
+)
+
+func Topic() string {
+	return "/tpperception"
+}
+
+// 禁止存在下划线_
+func Label() string {
+	return "CBTAf"
+}
+
+func Rule(shareVars *sync.Map, data *pjisuv_msgs.PerceptionObjects) string {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	OutsideWorkshopFlag, ok3 := shareVars.Load("OutsideWorkshopFlag")
+	PositionXOfCicvLocation, ok2 := shareVars.Load("PositionXOfCicvLocation")
+	PositionYOfCicvLocation, ok1 := shareVars.Load("PositionYOfCicvLocation")
+	LeftCurveFlag, ok := shareVars.Load("LeftCurveFlag")
+
+	if ok && ok1 && ok2 && ok3 && OutsideWorkshopFlag.(bool) && LeftCurveFlag.(bool) == true {
+		for _, obj := range data.Objs {
+			if obj.Type == 4 {
+				Distance := math.Sqrt(math.Pow(PositionXOfCicvLocation.(float64)-obj.Xabs, 2) + math.Pow(PositionYOfCicvLocation.(float64)-obj.Yabs, 2))
+				Objspeed := math.Sqrt(math.Pow(float64(obj.Vxabs), 2) + math.Pow(float64(obj.Vyabs), 2))
+
+				//fmt.Println("Distance:", Distance)
+				if obj.X >= 2.0 && obj.X <= 40.0 && Distance <= 40.0 && Objspeed > 0.7 {
+					event_lable := "CBTA_f"
+					fmt.Println(event_lable)
+					return Label()
+
+				}
+			}
+		}
+	}
+
+	return ""
+}

+ 48 - 0
trigger/pjisuv/tpperception/CBTA_n/main/CBTA_n.go

@@ -0,0 +1,48 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_msgs"
+	"fmt"
+	"math"
+	"sync"
+)
+
+func Topic() string {
+	return "/tpperception"
+}
+
+// 禁止存在下划线_
+func Label() string {
+	return "CBTAn"
+}
+
+func Rule(shareVars *sync.Map, data *pjisuv_msgs.PerceptionObjects) string {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	OutsideWorkshopFlag, ok3 := shareVars.Load("OutsideWorkshopFlag")
+	PositionXOfCicvLocation, ok2 := shareVars.Load("PositionXOfCicvLocation")
+	PositionYOfCicvLocation, ok1 := shareVars.Load("PositionYOfCicvLocation")
+	RightCurveFlag, ok := shareVars.Load("RightCurveFlag")
+
+	if ok && ok1 && ok2 && ok3 && OutsideWorkshopFlag.(bool) && RightCurveFlag.(bool) == true {
+		for _, obj := range data.Objs {
+			if obj.Type == 4 {
+				Distance := math.Sqrt(math.Pow(PositionXOfCicvLocation.(float64)-obj.Xabs, 2) + math.Pow(PositionYOfCicvLocation.(float64)-obj.Yabs, 2))
+				Objspeed := math.Sqrt(math.Pow(float64(obj.Vxabs), 2) + math.Pow(float64(obj.Vyabs), 2))
+
+				//fmt.Println("Distance:", Distance)
+				if obj.X >= 2.0 && Distance <= 35.0 && Objspeed > 0.7 {
+					event_lable := "CBTA_n"
+					fmt.Println(event_lable)
+					return Label()
+
+				}
+			}
+		}
+	}
+
+	return ""
+}

+ 46 - 0
trigger/pjisuv/tpperception/CCFtap/main/CCFtap.go

@@ -0,0 +1,46 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_msgs"
+	"fmt"
+	"math"
+	"sync"
+)
+
+func Topic() string {
+	return "/tpperception"
+}
+
+// 禁止存在下划线_
+func Label() string {
+	return "CCFtap"
+}
+
+func Rule(shareVars *sync.Map, data *pjisuv_msgs.PerceptionObjects) string {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	OutsideWorkshopFlag, ok3 := shareVars.Load("OutsideWorkshopFlag")
+	PositionXOfCicvLocation, ok2 := shareVars.Load("PositionXOfCicvLocation")
+	PositionYOfCicvLocation, ok1 := shareVars.Load("PositionYOfCicvLocation")
+	LeftCurveFlag, ok := shareVars.Load("LeftCurveFlag")
+
+	if ok && ok1 && ok2 && ok3 && OutsideWorkshopFlag.(bool) && LeftCurveFlag.(bool) == true {
+
+		for _, obj := range data.Objs {
+			if obj.Type == 2 || obj.Type == 3 {
+				Distance := math.Sqrt(math.Pow(PositionXOfCicvLocation.(float64)-obj.Xabs, 2) + math.Pow(PositionYOfCicvLocation.(float64)-obj.Yabs, 2))
+				//fmt.Println("Distance:", Distance)
+				if obj.X >= 2.0 && obj.X <= 30.0 && (math.Abs(float64(obj.Y)) <= 4.0 || Distance <= 35.0) {
+					event_lable := "CCFtap"
+					fmt.Println(event_lable)
+					return Label()
+				}
+			}
+		}
+	}
+
+	return ""
+}

+ 60 - 0
trigger/pjisuv/tpperception/CPLA/main/CPLA.go

@@ -0,0 +1,60 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_msgs"
+	"fmt"
+	"math"
+	"sync"
+	"time"
+)
+
+var (
+	StartTime int64
+	IsFollow  bool
+)
+
+func Topic() string {
+	return "/tpperception"
+}
+
+// 禁止存在下划线_
+func Label() string {
+	return "CPLA"
+}
+
+func Rule(shareVars *sync.Map, data *pjisuv_msgs.PerceptionObjects) string {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	OutsideWorkshopFlag, ok3 := shareVars.Load("OutsideWorkshopFlag")
+	AbsSpeed, ok2 := shareVars.Load("AbsSpeed")
+
+	if ok3 && ok2 && OutsideWorkshopFlag.(bool) && AbsSpeed.(float64) > 1 {
+
+		for _, obj := range data.Objs {
+			if obj.Type == 1 && obj.X >= 2 && obj.X <= 20 && math.Abs(float64(obj.Y)) <= 1.2 {
+				if StartTime == 0 {
+					StartTime = time.Now().Unix()
+				}
+
+				// 判断是否持续超过一分钟
+				if time.Now().Unix()-StartTime > 5 {
+					if !IsFollow {
+						event_label := "CPLA"
+						fmt.Println(event_label)
+						IsFollow = true
+						return Label()
+
+					}
+				}
+			} else {
+				StartTime = 0
+				IsFollow = false
+			}
+		}
+	}
+
+	return ""
+}

+ 47 - 0
trigger/pjisuv/tpperception/CPTA_f/main/CPTA_f.go

@@ -0,0 +1,47 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_msgs"
+	"fmt"
+	"math"
+	"sync"
+)
+
+func Topic() string {
+	return "/tpperception"
+}
+
+// 禁止存在下划线_
+func Label() string {
+	return "CPTAf"
+}
+
+func Rule(shareVars *sync.Map, data *pjisuv_msgs.PerceptionObjects) string {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	OutsideWorkshopFlag, ok3 := shareVars.Load("OutsideWorkshopFlag")
+	PositionXOfCicvLocation, ok2 := shareVars.Load("PositionXOfCicvLocation")
+	PositionYOfCicvLocation, ok1 := shareVars.Load("PositionYOfCicvLocation")
+	LeftCurveFlag, ok := shareVars.Load("LeftCurveFlag")
+
+	if ok && ok1 && ok2 && ok3 && OutsideWorkshopFlag.(bool) && LeftCurveFlag.(bool) == true {
+
+		for _, obj := range data.Objs {
+			if obj.Type == 1 {
+				Distance := math.Sqrt(math.Pow(PositionXOfCicvLocation.(float64)-obj.Xabs, 2) + math.Pow(PositionYOfCicvLocation.(float64)-obj.Yabs, 2))
+				Objspeed := math.Sqrt(math.Pow(float64(obj.Vxabs), 2) + math.Pow(float64(obj.Vyabs), 2))
+				//fmt.Println("Distance:", Distance)
+				if obj.X >= 2.0 && obj.X <= 30.0 && Distance <= 30.0 && Objspeed > 0.7 {
+					event_lable := "CPTA_f"
+					fmt.Println(event_lable)
+					return Label()
+				}
+			}
+		}
+	}
+
+	return ""
+}

+ 47 - 0
trigger/pjisuv/tpperception/CPTA_n/main/CPTA_n.go

@@ -0,0 +1,47 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_msgs"
+	"fmt"
+	"math"
+	"sync"
+)
+
+func Topic() string {
+	return "/tpperception"
+}
+
+// 禁止存在下划线_
+func Label() string {
+	return "CPTAn"
+}
+
+func Rule(shareVars *sync.Map, data *pjisuv_msgs.PerceptionObjects) string {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	OutsideWorkshopFlag, ok3 := shareVars.Load("OutsideWorkshopFlag")
+	PositionXOfCicvLocation, ok2 := shareVars.Load("PositionXOfCicvLocation")
+	PositionYOfCicvLocation, ok1 := shareVars.Load("PositionYOfCicvLocation")
+	RightCurveFlag, ok := shareVars.Load("RightCurveFlag")
+
+	if ok && ok1 && ok2 && ok3 && OutsideWorkshopFlag.(bool) && RightCurveFlag.(bool) == true {
+
+		for _, obj := range data.Objs {
+			if obj.Type == 1 {
+				Distance := math.Sqrt(math.Pow(PositionXOfCicvLocation.(float64)-obj.Xabs, 2) + math.Pow(PositionYOfCicvLocation.(float64)-obj.Yabs, 2))
+				Objspeed := math.Sqrt(math.Pow(float64(obj.Vxabs), 2) + math.Pow(float64(obj.Vyabs), 2))
+				//fmt.Println("Distance:", Distance)
+				if obj.X >= 2.0 && obj.X <= 30.0 && Distance <= 20.0 && Objspeed > 0.7 {
+					event_lable := "CPTA_n"
+					fmt.Println(event_lable)
+					return Label()
+				}
+			}
+		}
+	}
+
+	return ""
+}

+ 55 - 0
trigger/pjisuv/tpperception/FrontCarSideBySide/main/FrontCarSideBySide.go

@@ -0,0 +1,55 @@
+package main
+
+import (
+	"cicv-data-closedloop/pjisuv_msgs"
+	"fmt"
+	"math"
+	"sync"
+)
+
+// 该程序存在的意义是为cicv_ticker中的FrontCarSideBySide触发器提供countSideBySide的全局变量
+func Topic() string {
+	return "/tpperception"
+}
+
+func Rule(shareVars *sync.Map, data *pjisuv_msgs.PerceptionObjects) string {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered from panic:", r)
+		}
+	}()
+	count1 := 0
+	AbsSpeed, ok := shareVars.Load("AbsSpeed")
+	OutsideWorkshopFlag, ok1 := shareVars.Load("OutsideWorkshopFlag")
+	OutsideWorkshopFlag = OutsideWorkshopFlag.(bool)
+	countSideBySide, ok2 := shareVars.Load("CountSideBySide")
+	if ok && ok1 && ok2 {
+	lable1:
+		for _, obj := range data.Objs {
+			if !(obj.Type != 2 || obj.Type != 3 || obj.Type != 4 || !(obj.X >= 3 && obj.X <= 17) || math.Abs(float64(obj.Y)) > 10) {
+				//fmt.Println("here")
+				obj1ID := obj.Id
+				obj1x := obj.X
+				obj1y := obj.Y
+				//fmt.Println(obj1ID, obj1x, obj1y)
+				for _, obj1 := range data.Objs {
+					if !(obj1.Type != 2 || obj1.Type != 3 || obj1.Type != 4 || !(obj1.X >= 3 && obj1.X <= 17) || math.Abs(float64(obj1.Y)) > 10) {
+						obj2ID := obj1.Id
+						obj2x := obj1.X
+						obj2y := obj1.Y
+						if obj2ID != obj1ID && math.Abs(float64(obj2x-obj1x)) <= 2.2 && math.Abs(float64(obj2y-obj1y)) >= 2 && math.Abs(float64(obj2y-obj1y)) <= 4.0 && AbsSpeed.(float64) > 2 {
+							count1 = countSideBySide.(int) + 1
+							shareVars.Store("countSideBySide", count1)
+							break lable1
+						}
+					}
+
+				}
+
+			}
+
+		}
+	}
+
+	return ""
+}