goroslib_test.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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. StableAge int
  14. LastExistTime float64
  15. }
  16. var objectsStability = make(map[uint32]Object)
  17. // speedCheck 目标物速度检测
  18. func speedCheck(obj *pjisuv_msgs.PerceptionObject) bool {
  19. var targetMinSpeed float32 = 2 / 3.6 // m/s
  20. var targetMaxSpeed float32 = 20 / 3.6 // m/s
  21. if targetMinSpeed < obj.Speed && obj.Speed < targetMaxSpeed {
  22. return true
  23. }
  24. return false
  25. }
  26. // typeCheck 目标物类型检测
  27. // × 金龙车:CAR_TYPE=0, TRUCK_TYPE=1, PEDESTRIAN_TYPE=2, CYCLIST_TYPE=3, UNKNOWN_TYPE=4, UNKNOWN_MOVABLE_TYPE=5, UNKNOWN_UNMOVABLE_TYPE=6
  28. // √ 多功能车:UNKNOWN TYPE=O, PEDESTRIAN TYPE=1, CAR TYPE=2, TRUCK TYPE=3, Bicycle TYPE=4, Tricycle TYPE=5, Traffic Cone TYPE=6
  29. func typeCheck(obj *pjisuv_msgs.PerceptionObject) bool {
  30. var targetType uint8 = 3
  31. if targetType == obj.Type {
  32. return true
  33. }
  34. return false
  35. }
  36. // sizeCheck 目标物大小检测
  37. func sizeCheck(obj *pjisuv_msgs.PerceptionObject) bool {
  38. // 多功能车
  39. var targetMinLength float32 = 3.6 // m
  40. var targetMinWidth float32 = 1.605 // m
  41. var targetMinHeight float32 = 1.995 // m
  42. // 金龙车
  43. //targetMinLength := 5.99
  44. //targetMinWidth := 2.065
  45. //targetMinHeight := 2.82
  46. if obj.Length > targetMinLength || obj.Width > targetMinWidth || obj.Height > targetMinHeight {
  47. return true
  48. }
  49. return false
  50. }
  51. // posCheck 判断目标物位置关系
  52. func posCheck(obj *pjisuv_msgs.PerceptionObject) bool {
  53. laneWidth := 3.5 // m
  54. if obj.X > 0 && math.Abs(float64(obj.Y)) < laneWidth*1.5 {
  55. return true
  56. }
  57. return false
  58. }
  59. // Rule 感知算法识别大车、有车辆在前方车道且低速行驶
  60. func Rule(msg *pjisuv_msgs.PerceptionObjects) string {
  61. defer func() {
  62. if r := recover(); r != nil {
  63. fmt.Println("Recovered from panic:", r)
  64. }
  65. }()
  66. CGCS2000_X := 456256.260152
  67. CGCS2000_Y := 4397809.886833
  68. existingFrameThreshold := 5 // frame
  69. existingTimeThreshold := 0.5 // s
  70. //for _, obj := range msg.Objs {
  71. // //fmt.Println(fmt.Sprintf("id: [%d], type: [%d], x/yrel: [%f, %f], x/yabs: [%f, %f], speed: [%f], size: [%f/%f/%f]",
  72. // // obj.Id, obj.Type, obj.X, obj.Y, obj.Xabs-CGCS2000_X, obj.Yabs-CGCS2000_Y, obj.Speed, obj.Length, obj.Width, obj.Height))
  73. //
  74. // // todo: 对各判断条件单独进行稳定性校验?
  75. // if speedCheck(&obj) && posCheck(&obj) && (typeCheck(&obj) || sizeCheck(&obj)) {
  76. // fmt.Println(fmt.Sprintf("id: [%d], type: [%d], x/yrel: [%f, %f], x/yabs: [%f, %f], speed: [%f], size: [%f/%f/%f]",
  77. // obj.Id, obj.Type, obj.X, obj.Y, obj.Xabs-CGCS2000_X, obj.Yabs-CGCS2000_Y, obj.Speed, obj.Length, obj.Width, obj.Height))
  78. // //fmt.Println("!!!")
  79. // return "LowSpdTruckAhead"
  80. // }
  81. //}
  82. //return ""
  83. fmt.Println()
  84. fmt.Println(time.Unix(int64(msg.Header.TimeStamp), int64(msg.Header.TimeStamp*1e9)%1e9).Format(time.StampNano))
  85. for _, obj := range msg.Objs {
  86. //fmt.Println(fmt.Sprintf("id: [%d], type: [%d], x/yrel: [%f, %f], x/yabs: [%f, %f], speed: [%f], size: [%f/%f/%f]",
  87. // obj.Id, obj.Type, obj.X, obj.Y, obj.Xabs-CGCS2000_X, obj.Yabs-CGCS2000_Y, obj.Speed, obj.Length, obj.Width, obj.Height))
  88. // 判断目标物是否满足筛选条件
  89. if speedCheck(&obj) && posCheck(&obj) && (typeCheck(&obj) || sizeCheck(&obj)) {
  90. // 目标物初见存档
  91. if prevObjRecord, exists := objectsStability[obj.Id]; exists == false {
  92. objectsStability[obj.Id] = Object{
  93. ID: obj.Id,
  94. StableAge: 1,
  95. LastExistTime: msg.Header.TimeStamp,
  96. }
  97. fmt.Println("create: ", objectsStability[obj.Id])
  98. } else {
  99. currObjRecord := Object{
  100. ID: obj.Id,
  101. StableAge: 1,
  102. LastExistTime: msg.Header.TimeStamp,
  103. }
  104. // 目标物确认/更新/重置
  105. if currObjRecord.LastExistTime-prevObjRecord.LastExistTime <= existingTimeThreshold { // 目标物消失不超过0.5s
  106. currObjRecord.StableAge = prevObjRecord.StableAge + 1
  107. if existingFrameThreshold == currObjRecord.StableAge {
  108. fmt.Println("found: ", currObjRecord)
  109. fmt.Println(fmt.Sprintf("id: [%d], type: [%d], x/yrel: [%f, %f], x/yabs: [%f, %f], speed: [%f], size: [%f/%f/%f]",
  110. obj.Id, obj.Type, obj.X, obj.Y, obj.Xabs-CGCS2000_X, obj.Yabs-CGCS2000_Y, obj.Speed, obj.Length, obj.Width, obj.Height))
  111. delete(objectsStability, obj.Id)
  112. continue // todo
  113. //return "LowSpdTruckAhead"
  114. } else {
  115. }
  116. } else {
  117. fmt.Println("reset: ", currObjRecord)
  118. }
  119. objectsStability[obj.Id] = currObjRecord
  120. fmt.Println("update: ", currObjRecord)
  121. }
  122. }
  123. }
  124. return ""
  125. }
  126. func TestGoRosLib(t *testing.T) {
  127. defer func() {
  128. if err := recover(); err != nil {
  129. log.Println(err, fmt.Sprintf("recover: [%#v]", err), false)
  130. }
  131. }()
  132. rosNode, err := goroslib.NewNode(goroslib.NodeConf{
  133. Name: "eyTest",
  134. MasterAddress: "localhost:11311",
  135. })
  136. if err != nil {
  137. log.Panicln(err, fmt.Sprintf("failed to create rosNode: [%#v]", err), false)
  138. }
  139. _, err = goroslib.NewSubscriber(goroslib.SubscriberConf{
  140. Node: rosNode,
  141. Topic: "/tpperception",
  142. Callback: func(msg *pjisuv_msgs.PerceptionObjects) {
  143. Rule(msg)
  144. },
  145. })
  146. if err != nil {
  147. log.Panicln(err, fmt.Sprintf("failed to create subscriber: [%#v]", err), false)
  148. }
  149. select {}
  150. }