ey_common_test.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package test
  2. import (
  3. "cicv-data-closedloop/pjisuv_msgs"
  4. "fmt"
  5. "github.com/bluenviron/goroslib/v2"
  6. "log"
  7. "math"
  8. "sync"
  9. "testing"
  10. "time"
  11. )
  12. var shareVars = new(sync.Map)
  13. func UpdateShareVariable(msg *pjisuv_msgs.PerceptionLocalization) {
  14. shareVars.Store("OutsideWorkshopFlag", true)
  15. shareVars.Store("VelocityXOfCicvLocation", msg.VelocityX)
  16. shareVars.Store("VelocityYOfCicvLocation", msg.VelocityY)
  17. }
  18. func TestGoRosLib(t *testing.T) {
  19. defer func() {
  20. if r := recover(); r != nil {
  21. fmt.Println(fmt.Sprintf("Recovered from panic: [%s], [%#v]", Label(), r))
  22. }
  23. }()
  24. rosNode, err := goroslib.NewNode(goroslib.NodeConf{
  25. Name: "eyTest",
  26. MasterAddress: "localhost:11311",
  27. })
  28. if err != nil {
  29. log.Panicln(err, fmt.Sprintf("failed to create rosNode: [%#v]", err), false)
  30. }
  31. _, err = goroslib.NewSubscriber(goroslib.SubscriberConf{
  32. Node: rosNode,
  33. Topic: "/tpperception",
  34. Callback: func(msg *pjisuv_msgs.PerceptionObjects) {
  35. Rule(shareVars, msg)
  36. },
  37. })
  38. if err != nil {
  39. log.Panicln(err, fmt.Sprintf("failed to create subscriber: [%#v]", err), false)
  40. }
  41. _, err = goroslib.NewSubscriber(goroslib.SubscriberConf{
  42. Node: rosNode,
  43. Topic: "/cicv_location",
  44. Callback: func(msg *pjisuv_msgs.PerceptionLocalization) {
  45. UpdateShareVariable(msg)
  46. },
  47. })
  48. if err != nil {
  49. log.Panicln(err, fmt.Sprintf("failed to create subscriber: [%#v]", err), false)
  50. }
  51. select {}
  52. }
  53. // ---------------------------------------------------------------------------------------------------------------------
  54. func Topic() string {
  55. return "/tpperception"
  56. }
  57. // Label todo 禁止存在下划线_
  58. // MultiPedestrianAhead
  59. // MultiCarAhead
  60. // MultiTruckAhead
  61. // MultiBicycleAhead
  62. // MultiTricycleAhead
  63. // MultiTrafficConeAhead
  64. func Label() string {
  65. return "MultiTrafficConeAhead"
  66. }
  67. type Record struct {
  68. StableFrame int
  69. LastExistingTime float64
  70. }
  71. var record *Record = nil
  72. // objTypeCheck 目标物类型检测
  73. // × 金龙车:CAR_TYPE=0, TRUCK_TYPE=1, PEDESTRIAN_TYPE=2, CYCLIST_TYPE=3, UNKNOWN_TYPE=4, UNKNOWN_MOVABLE_TYPE=5, UNKNOWN_UNMOVABLE_TYPE=6
  74. // √ 多功能车:UNKNOWN TYPE=O, PEDESTRIAN TYPE=1, CAR TYPE=2, TRUCK TYPE=3, Bicycle TYPE=4, Tricycle TYPE=5, Traffic Cone TYPE=6
  75. func objTypeCheck(obj *pjisuv_msgs.PerceptionObject) bool {
  76. const targetType uint8 = 4
  77. return targetType == obj.Type
  78. }
  79. // objPosCheck 判断目标物位置关系
  80. func objPosCheck(obj *pjisuv_msgs.PerceptionObject) bool {
  81. const laneWidth = 3.5 // m
  82. return obj.X > 0 && math.Abs(float64(obj.Y)) < laneWidth*1.5
  83. }
  84. // isEgoStationary 判断主车是否“静止”(速度低于阈值)
  85. func isEgoStationary(shareVars *sync.Map) bool {
  86. const minSpeed = 1 // m/s
  87. VelocityXOfCicvLocation, _ := shareVars.Load("VelocityXOfCicvLocation") // float64
  88. VelocityYOfCicvLocation, _ := shareVars.Load("VelocityYOfCicvLocation")
  89. speed := math.Sqrt(math.Pow(VelocityXOfCicvLocation.(float64), 2) + math.Pow(VelocityYOfCicvLocation.(float64), 2))
  90. return speed > minSpeed
  91. }
  92. // Rule 检测前方指定目标物数量
  93. func Rule(shareVars *sync.Map, msg *pjisuv_msgs.PerceptionObjects) string {
  94. defer func() {
  95. if r := recover(); r != nil {
  96. fmt.Println("Recovered from panic:", r)
  97. }
  98. }()
  99. outsideWorkshopFlag, _ := shareVars.Load("OutsideWorkshopFlag")
  100. if !outsideWorkshopFlag.(bool) || !isEgoStationary(shareVars) {
  101. return ""
  102. }
  103. const Cgcs2000X = 456256.260152
  104. const Cgcs2000Y = 4397809.886833
  105. const MinStableFrameCount = 5 // frame
  106. const MaxTimeBetweenFrame = 0.5 // second
  107. const minTargetNum = 3
  108. if len(msg.Objs) >= minTargetNum {
  109. currTargetNum := 0
  110. fmt.Println("\n", time.Unix(int64(msg.Header.TimeStamp), int64(msg.Header.TimeStamp*1e9)%1e9).Format(time.StampNano))
  111. for _, obj := range msg.Objs {
  112. // 判断目标物是否满足筛选条件
  113. if objTypeCheck(&obj) && objPosCheck(&obj) {
  114. fmt.Println(fmt.Sprintf("id: [%d], type: [%d], x/yrel: [%f, %f], x/yabs: [%f, %f], speed: [%f], size: [%f/%f/%f]",
  115. obj.Id, obj.Type, obj.X, obj.Y, obj.Xabs-Cgcs2000X, obj.Yabs-Cgcs2000Y, obj.Speed, obj.Length, obj.Width, obj.Height))
  116. currTargetNum++
  117. }
  118. }
  119. if currTargetNum >= minTargetNum {
  120. if nil == record {
  121. record = &Record{
  122. StableFrame: 1,
  123. LastExistingTime: msg.Header.TimeStamp,
  124. }
  125. fmt.Println("---------- create ----------")
  126. } else {
  127. newRecord := Record{
  128. StableFrame: 1,
  129. LastExistingTime: msg.Header.TimeStamp,
  130. }
  131. if newRecord.LastExistingTime-record.LastExistingTime <= MaxTimeBetweenFrame {
  132. newRecord.StableFrame = record.StableFrame + 1
  133. if newRecord.StableFrame == MinStableFrameCount {
  134. record = nil
  135. fmt.Println("!!!!!!!!!! found !!!!!!!!!!")
  136. return Label()
  137. } else {
  138. fmt.Println("---------- update ----------")
  139. }
  140. } else {
  141. fmt.Println("---------- reset ----------")
  142. }
  143. record = &newRecord
  144. }
  145. }
  146. }
  147. return ""
  148. }