env.py 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. """
  2. Pure code-based environment building blocks for AGV simulation.
  3. """
  4. from CBD.CBD import BaseBlock
  5. class PathBlock(BaseBlock):
  6. def __init__(self, block_name, path_file, path_width=0.027, grace=0.001, black=55, white=5):
  7. BaseBlock.__init__(self, block_name, ["x", "y"], ["color", "offset"])
  8. self.path_width = path_width
  9. self.grace = grace
  10. self.black = black
  11. self.white = white
  12. self.path = []
  13. with open(path_file, 'r') as file:
  14. for line in file:
  15. try:
  16. pos = [float(l.strip()) for l in line.split(',')]
  17. except Exception as e:
  18. continue
  19. self.path.append(pos[:2])
  20. def compute(self, curIteration):
  21. position = self.getInputSignal(curIteration, "x").value, self.getInputSignal(curIteration, "y").value
  22. color = self.white
  23. offset = float('inf')
  24. for i, p1 in enumerate(self.path):
  25. p2 = self.path[i-1]
  26. dist = self.distance_to_line(p2, p1, position)
  27. if dist < offset:
  28. offset = dist
  29. if dist < (self.path_width / 2.0):
  30. color = self.black
  31. elif color == self.white and dist <= (self.path_width / 2.0 + self.grace):
  32. # Gradually go from black to white over a distance of grace
  33. d = dist - self.path_width / 2.0
  34. color = self.black + (d / self.grace * (self.white - self.black))
  35. self.appendToSignal(color, "color")
  36. self.appendToSignal(offset, "offset")
  37. def distance_to_line(self, p1, p2, p3):
  38. """
  39. Computes the distance from a point p3 to the line segment given by (p1, p2).
  40. Implementation based upon:
  41. https://stackoverflow.com/a/6853926
  42. """
  43. px = p2[0] - p1[0]
  44. py = p2[1] - p1[1]
  45. norm = px * px + py * py
  46. if norm == 0.0:
  47. ud = 0.0
  48. else:
  49. ud = float((p3[0] - p1[0]) * px + (p3[1] - p1[1]) * py) / norm
  50. ud = min(max(ud, 0.0), 1.0) # limits line segment to endpoints
  51. xd = p1[0] + ud * px
  52. yd = p1[1] + ud * py
  53. dx = xd - p3[0]
  54. dy = yd - p3[1]
  55. return (dx * dx + dy * dy) ** 0.5