lowSpdTruckAhead.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package main
  2. import (
  3. "cicv-data-closedloop/pjisuv_msgs"
  4. "fmt"
  5. "math"
  6. "time"
  7. )
  8. type Object struct {
  9. ID uint32
  10. StableAge int
  11. LastExistTime float64
  12. }
  13. var objectsStability = make(map[uint32]Object)
  14. const (
  15. Cgcs2000X = 456256.260152
  16. Cgcs2000Y = 4397809.886833
  17. MinStableFrameCount = 5
  18. MaxTimeBetweenFrame = 0.5
  19. )
  20. func Topic() string {
  21. return "/tpperception"
  22. }
  23. // Label todo 禁止存在下划线_
  24. func Label() string {
  25. return "LowSpdTruckAhead"
  26. }
  27. // speedCheck 目标物速度检测
  28. func speedCheck(obj *pjisuv_msgs.PerceptionObject) bool {
  29. const targetMinSpeed = 2 / 3.6 // m/s
  30. const targetMaxSpeed = 20 / 3.6 // m/s
  31. return targetMinSpeed < obj.Speed && obj.Speed < targetMaxSpeed
  32. }
  33. // typeCheck 目标物类型检测
  34. // × 金龙车:CAR_TYPE=0, TRUCK_TYPE=1, PEDESTRIAN_TYPE=2, CYCLIST_TYPE=3, UNKNOWN_TYPE=4, UNKNOWN_MOVABLE_TYPE=5, UNKNOWN_UNMOVABLE_TYPE=6
  35. // √ 多功能车:UNKNOWN TYPE=O, PEDESTRIAN TYPE=1, CAR TYPE=2, TRUCK TYPE=3, Bicycle TYPE=4, Tricycle TYPE=5, Traffic Cone TYPE=6
  36. func typeCheck(obj *pjisuv_msgs.PerceptionObject) bool {
  37. const targetType uint8 = 3
  38. return targetType == obj.Type
  39. }
  40. // posCheck 判断目标物位置关系
  41. func posCheck(obj *pjisuv_msgs.PerceptionObject) bool {
  42. const laneWidth = 3.5 // m
  43. return obj.X > 0 && math.Abs(float64(obj.Y)) < laneWidth*1.5
  44. }
  45. // Rule 检测前方大车低速行驶
  46. func Rule(msg *pjisuv_msgs.PerceptionObjects) string {
  47. defer func() {
  48. if r := recover(); r != nil {
  49. fmt.Println("Recovered from panic:", r)
  50. }
  51. }()
  52. fmt.Println()
  53. fmt.Println(time.Unix(int64(msg.Header.TimeStamp), int64(msg.Header.TimeStamp*1e9)%1e9).Format(time.StampNano))
  54. for _, obj := range msg.Objs {
  55. //fmt.Println(fmt.Sprintf("id: [%d], type: [%d], x/yrel: [%f, %f], x/yabs: [%f, %f], speed: [%f], size: [%f/%f/%f]",
  56. // obj.Id, obj.Type, obj.X, obj.Y, obj.Xabs-CGCS2000_X, obj.Yabs-CGCS2000_Y, obj.Speed, obj.Length, obj.Width, obj.Height))
  57. // 判断目标物是否满足筛选条件
  58. if speedCheck(&obj) && posCheck(&obj) && typeCheck(&obj) {
  59. // 目标物初见存档
  60. if prevObjRecord, exists := objectsStability[obj.Id]; exists == false {
  61. objectsStability[obj.Id] = Object{
  62. ID: obj.Id,
  63. StableAge: 1,
  64. LastExistTime: msg.Header.TimeStamp,
  65. }
  66. fmt.Println("create: ", objectsStability[obj.Id])
  67. } else {
  68. currObjRecord := Object{
  69. ID: obj.Id,
  70. StableAge: 1,
  71. LastExistTime: msg.Header.TimeStamp,
  72. }
  73. // 目标物确认/更新/重置
  74. if currObjRecord.LastExistTime-prevObjRecord.LastExistTime <= MaxTimeBetweenFrame { // 目标物消失不超过0.5s
  75. currObjRecord.StableAge = prevObjRecord.StableAge + 1
  76. if currObjRecord.StableAge == MinStableFrameCount {
  77. fmt.Println("found: ", currObjRecord)
  78. fmt.Println(fmt.Sprintf("id: [%d], type: [%d], x/yrel: [%f, %f], x/yabs: [%f, %f], speed: [%f], size: [%f/%f/%f]",
  79. obj.Id, obj.Type, obj.X, obj.Y, obj.Xabs-Cgcs2000X, obj.Yabs-Cgcs2000Y, obj.Speed, obj.Length, obj.Width, obj.Height))
  80. delete(objectsStability, obj.Id)
  81. //continue // todo
  82. return "LowSpdTruckAhead"
  83. } else {
  84. //fmt.Println("update: ", currObjRecord)
  85. objectsStability[obj.Id] = currObjRecord
  86. }
  87. } else {
  88. //fmt.Println("reset: ", currObjRecord)
  89. objectsStability[obj.Id] = currObjRecord
  90. }
  91. }
  92. }
  93. }
  94. return ""
  95. }