ey_common_test.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package test
  2. import (
  3. "cicv-data-closedloop/pjisuv_msgs"
  4. "fmt"
  5. "github.com/bluenviron/goroslib/v2"
  6. "log"
  7. "math"
  8. "testing"
  9. "time"
  10. )
  11. type Object struct {
  12. ID uint32
  13. StableFrame int
  14. LastExistingTime float64
  15. }
  16. var objectsStability = make(map[uint32]Object)
  17. const (
  18. Cgcs2000X = 456256.260152
  19. Cgcs2000Y = 4397809.886833
  20. MinStableFrameCount = 5
  21. MaxTimeBetweenFrame = 0.5
  22. )
  23. // typeCheck 目标物类型检测
  24. // × 金龙车:CAR_TYPE=0, TRUCK_TYPE=1, PEDESTRIAN_TYPE=2, CYCLIST_TYPE=3, UNKNOWN_TYPE=4, UNKNOWN_MOVABLE_TYPE=5, UNKNOWN_UNMOVABLE_TYPE=6
  25. // √ 多功能车:UNKNOWN TYPE=O, PEDESTRIAN TYPE=1, CAR TYPE=2, TRUCK TYPE=3, Bicycle TYPE=4, Tricycle TYPE=5, Traffic Cone TYPE=6
  26. func typeCheck(obj *pjisuv_msgs.PerceptionObject) bool {
  27. const targetType uint8 = 0
  28. return targetType == obj.Type
  29. }
  30. // sizeCheck 目标物大小检测
  31. func sizeCheck(obj *pjisuv_msgs.PerceptionObject) bool {
  32. // 多功能车
  33. const targetMinLength = 3.6 // m
  34. const targetMinWidth = 1.605 // m
  35. const targetMinHeight = 1.995 // m
  36. // 金龙车
  37. //targetMinLength := 5.99
  38. //targetMinWidth := 2.065
  39. //targetMinHeight := 2.82
  40. // 至少满足两个条件
  41. counter := 0
  42. if obj.Length >= targetMinLength {
  43. counter++
  44. }
  45. if obj.Width >= targetMinWidth {
  46. counter++
  47. }
  48. if obj.Height >= targetMinHeight {
  49. counter++
  50. }
  51. return counter > 1
  52. }
  53. // posCheck 判断目标物位置关系
  54. func posCheck(obj *pjisuv_msgs.PerceptionObject) bool {
  55. const laneWidth = 3.5 // m
  56. return obj.X > 0 && math.Abs(float64(obj.Y)) < laneWidth*1.5
  57. }
  58. // Rule 检测前方未知大目标物
  59. func Rule(msg *pjisuv_msgs.PerceptionObjects) string {
  60. defer func() {
  61. if r := recover(); r != nil {
  62. fmt.Println("Recovered from panic:", r)
  63. }
  64. }()
  65. fmt.Println()
  66. for _, obj := range msg.Objs {
  67. //fmt.Println(fmt.Sprintf("id: [%d], type: [%d], x/yrel: [%f, %f], x/yabs: [%f, %f], speed: [%f], size: [%f/%f/%f]",
  68. // obj.Id, obj.Type, obj.X, obj.Y, obj.Xabs-CGCS2000_X, obj.Yabs-CGCS2000_Y, obj.Speed, obj.Length, obj.Width, obj.Height))
  69. // 判断目标物是否满足筛选条件
  70. if typeCheck(&obj) && posCheck(&obj) && sizeCheck(&obj) {
  71. fmt.Println(time.Unix(int64(msg.Header.TimeStamp), int64(msg.Header.TimeStamp*1e9)%1e9).Format(time.StampNano))
  72. // 目标物初见存档
  73. if prevObjRecord, exists := objectsStability[obj.Id]; exists == false {
  74. objectsStability[obj.Id] = Object{
  75. ID: obj.Id,
  76. StableFrame: 1,
  77. LastExistingTime: msg.Header.TimeStamp,
  78. }
  79. fmt.Println("create: ", objectsStability[obj.Id])
  80. } else {
  81. currObjRecord := Object{
  82. ID: obj.Id,
  83. StableFrame: 1,
  84. LastExistingTime: msg.Header.TimeStamp,
  85. }
  86. // 目标物确认/更新/重置
  87. if currObjRecord.LastExistingTime-prevObjRecord.LastExistingTime <= MaxTimeBetweenFrame { // 目标物消失不超过0.5s
  88. currObjRecord.StableFrame = prevObjRecord.StableFrame + 1
  89. if currObjRecord.StableFrame == MinStableFrameCount {
  90. fmt.Println("found: ", currObjRecord)
  91. fmt.Println(fmt.Sprintf("id: [%d], type: [%d], x/yrel: [%f, %f], x/yabs: [%f, %f], speed: [%f], size: [%f/%f/%f]",
  92. obj.Id, obj.Type, obj.X, obj.Y, obj.Xabs-Cgcs2000X, obj.Yabs-Cgcs2000Y, obj.Speed, obj.Length, obj.Width, obj.Height))
  93. delete(objectsStability, obj.Id)
  94. //continue // todo
  95. //return "UnknownBigTargetAhead"
  96. } else {
  97. fmt.Println("update: ", currObjRecord)
  98. objectsStability[obj.Id] = currObjRecord
  99. }
  100. } else {
  101. fmt.Println("reset: ", currObjRecord)
  102. objectsStability[obj.Id] = currObjRecord
  103. }
  104. }
  105. }
  106. }
  107. return ""
  108. }
  109. func TestGoRosLib(t *testing.T) {
  110. defer func() {
  111. if err := recover(); err != nil {
  112. log.Println(err, fmt.Sprintf("recover: [%#v]", err), false)
  113. }
  114. }()
  115. rosNode, err := goroslib.NewNode(goroslib.NodeConf{
  116. Name: "eyTest",
  117. MasterAddress: "localhost:11311",
  118. })
  119. if err != nil {
  120. log.Panicln(err, fmt.Sprintf("failed to create rosNode: [%#v]", err), false)
  121. }
  122. _, err = goroslib.NewSubscriber(goroslib.SubscriberConf{
  123. Node: rosNode,
  124. Topic: "/tpperception",
  125. Callback: func(msg *pjisuv_msgs.PerceptionObjects) {
  126. Rule(msg)
  127. },
  128. })
  129. if err != nil {
  130. log.Panicln(err, fmt.Sprintf("failed to create subscriber: [%#v]", err), false)
  131. }
  132. select {}
  133. }