OutOfLane.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package main
  2. //触发器名称:冲出车道
  3. import (
  4. "cicv-data-closedloop/pjisuv_msgs"
  5. "fmt"
  6. "math"
  7. "sync"
  8. )
  9. func Topic() string {
  10. return "/map_polygon"
  11. }
  12. func Label() string {
  13. return "OutOfLane"
  14. }
  15. func Rule(shareVars *sync.Map, data *pjisuv_msgs.PolygonStamped) string {
  16. defer func() {
  17. if r := recover(); r != nil {
  18. fmt.Println("Recovered from panic:", r)
  19. }
  20. }()
  21. positionXOfCicvLocation, ok1 := shareVars.Load("PositionXOfCicvLocation")
  22. positionYOfCicvLocation, ok2 := shareVars.Load("PositionYOfCicvLocation")
  23. yawOfCicvLocation, ok3 := shareVars.Load("YawOfCicvLocation")
  24. automodeOfPjVehicleFdbPub, ok4 := shareVars.Load("AutomodeOfPjVehicleFdbPub")
  25. if ok1 && ok2 && ok3 && ok4 {
  26. Points := data.Polygon.Points
  27. D1, D2, D3 := 1.0, 0.4, 0.4 //这是实车缩小后的尺寸
  28. corners := getVehicleCorners(positionXOfCicvLocation.(float64), positionYOfCicvLocation.(float64), D1, D2, D3, yawOfCicvLocation.(float64))
  29. for i := 0; i < len(Points)-1; i++ {
  30. A := Points[i]
  31. B := Points[i+1]
  32. if polygonLineIntersect(corners, A, B) && automodeOfPjVehicleFdbPub.(int16) == 1 {
  33. return Label()
  34. }
  35. }
  36. }
  37. return ""
  38. }
  39. type Point struct {
  40. X, Y float64
  41. }
  42. func getVehicleCorners(x0, y0, D1, D2, D3, h0 float64) []pjisuv_msgs.Point64 {
  43. h0Rad := h0 * math.Pi / 180 // 转换角度到弧度
  44. cosH0, sinH0 := math.Cos(h0Rad), math.Sin(h0Rad)
  45. // 车辆四个角点相对于后轴中心点的坐标(局部坐标系)
  46. cornersLocal := []Point{
  47. {D1, D3}, // 前左角
  48. {D1, -D3}, // 前右角
  49. {-D2, D3}, // 后左角
  50. {-D2, -D3}, // 后右角
  51. }
  52. // 旋转矩阵并计算全局坐标
  53. rotationMatrix := [2][2]float64{{cosH0, -sinH0}, {sinH0, cosH0}}
  54. cornersGlobal := make([]pjisuv_msgs.Point64, len(cornersLocal))
  55. for i, corner := range cornersLocal {
  56. cornersGlobal[i].X = corner.X*rotationMatrix[0][0] + corner.Y*rotationMatrix[1][0] + x0
  57. cornersGlobal[i].Y = corner.X*rotationMatrix[0][1] + corner.Y*rotationMatrix[1][1] + y0
  58. }
  59. return cornersGlobal
  60. }
  61. func ccw(A, B, C pjisuv_msgs.Point64) bool {
  62. return (C.Y-A.Y)*(B.X-A.X) > (C.X-A.X)*(B.Y-A.Y)
  63. }
  64. func lineIntersect(A, B, C, D pjisuv_msgs.Point64) bool {
  65. return ccw(A, C, D) != ccw(B, C, D) && ccw(A, B, C) != ccw(A, B, D)
  66. }
  67. func polygonLineIntersect(polygon []pjisuv_msgs.Point64, A, B pjisuv_msgs.Point64) bool {
  68. for i := 0; i < len(polygon)-1; i++ {
  69. C := polygon[i]
  70. D := polygon[(i+1)%len(polygon)]
  71. if lineIntersect(A, B, C, D) {
  72. return true
  73. }
  74. }
  75. return false
  76. }