OutoffRoad.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package main
  2. import (
  3. "cicv-data-closedloop/common/entity"
  4. "cicv-data-closedloop/pjisuv_msgs"
  5. "math"
  6. )
  7. func Topic() string {
  8. return "/cicv_location"
  9. }
  10. func Label() string {
  11. return "outofroad"
  12. }
  13. type Point struct {
  14. X, Y float64
  15. }
  16. func getVehicleCorners(x0, y0, D1, D2, D3, h0 float64) []pjisuv_msgs.Point64 {
  17. h0Rad := h0 * math.Pi / 180 // 转换角度到弧度
  18. cosH0, sinH0 := math.Cos(h0Rad), math.Sin(h0Rad)
  19. // 车辆四个角点相对于后轴中心点的坐标(局部坐标系)
  20. cornersLocal := []Point{
  21. {D1, D3}, // 前左角
  22. {D1, -D3}, // 前右角
  23. {-D2, D3}, // 后左角
  24. {-D2, -D3}, // 后右角
  25. }
  26. // 旋转矩阵并计算全局坐标
  27. rotationMatrix := [2][2]float64{{cosH0, -sinH0}, {sinH0, cosH0}}
  28. cornersGlobal := make([]pjisuv_msgs.Point64, len(cornersLocal))
  29. for i, corner := range cornersLocal {
  30. cornersGlobal[i].X = corner.X*rotationMatrix[0][0] + corner.Y*rotationMatrix[1][0] + x0
  31. cornersGlobal[i].Y = corner.X*rotationMatrix[0][1] + corner.Y*rotationMatrix[1][1] + y0
  32. }
  33. return cornersGlobal
  34. }
  35. func ccw(A, B, C pjisuv_msgs.Point64) bool {
  36. return (C.Y-A.Y)*(B.X-A.X) > (C.X-A.X)*(B.Y-A.Y)
  37. }
  38. func lineIntersect(A, B, C, D pjisuv_msgs.Point64) bool {
  39. return ccw(A, C, D) != ccw(B, C, D) && ccw(A, B, C) != ccw(A, B, D)
  40. }
  41. func polygonLineIntersect(polygon []pjisuv_msgs.Point64, A, B pjisuv_msgs.Point64) bool {
  42. for i := 0; i < len(polygon)-1; i++ {
  43. C := polygon[i]
  44. D := polygon[(i+1)%len(polygon)]
  45. if lineIntersect(A, B, C, D) {
  46. return true
  47. }
  48. }
  49. return false
  50. }
  51. func Rule(data *pjisuv_msgs.PolygonStamped, param entity.PjisuvParam) string {
  52. Points := data.Polygon.Points
  53. D1, D2, D3 := 3.813, 0.952, 1.086
  54. corners := getVehicleCorners(param.PositionXOfCicvLocation, param.PositionYOfCicvLocation, D1, D2, D3, param.YawOfCicvLocation)
  55. for i := 0; i < len(Points)-1; i++ {
  56. A := Points[i]
  57. B := Points[i+1]
  58. if polygonLineIntersect(corners, A, B) {
  59. return "outofroad"
  60. }
  61. }
  62. return ""
  63. }