Advertisement
Guest User

Untitled

a guest
Dec 5th, 2019
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.49 KB | None | 0 0
  1. import sys
  2.  
  3. import matplotlib.pyplot as plt
  4. from matplotlib.path import Path
  5. import matplotlib.patches as patches
  6. from matplotlib import collections as mc
  7. import numpy as np
  8. import math
  9. import queue
  10.  
  11. '''
  12. Set up matplotlib to create a plot with an empty square
  13. '''
  14. def setupPlot():
  15. fig = plt.figure(num=None, figsize=(5, 5), dpi=120, facecolor='w', edgecolor='k')
  16. ax = fig.subplots()
  17. ax.set_axisbelow(True)
  18. ax.set_ylim(-1, 11)
  19. ax.set_xlim(-1, 11)
  20. ax.grid(which='minor', linestyle=':', alpha=0.2)
  21. ax.grid(which='major', linestyle=':', alpha=0.5)
  22. return fig, ax
  23.  
  24. '''
  25. Make a patch for a single pology
  26. '''
  27. def createPolygonPatch(polygon, color):
  28. verts = []
  29. codes= []
  30. for v in range(0, len(polygon)):
  31. xy = polygon[v]
  32. verts.append((xy[0], xy[1]))
  33. if v == 0:
  34. codes.append(Path.MOVETO)
  35. else:
  36. codes.append(Path.LINETO)
  37. verts.append(verts[0])
  38. codes.append(Path.CLOSEPOLY)
  39. path = Path(verts, codes)
  40. patch = patches.PathPatch(path, facecolor=color, lw=1)
  41.  
  42. return patch
  43.  
  44.  
  45. '''
  46. Render the problem
  47. '''
  48. def drawProblem(robotStart, robotGoal, polygons):
  49. _, ax = setupPlot()
  50. patch = createPolygonPatch(robotStart, 'green')
  51. ax.add_patch(patch)
  52. patch = createPolygonPatch(robotGoal, 'red')
  53. ax.add_patch(patch)
  54. for p in range(0, len(polygons)):
  55. patch = createPolygonPatch(polygons[p], 'gray')
  56. ax.add_patch(patch)
  57. plt.show()
  58.  
  59. '''
  60. Grow a simple RRT
  61. '''
  62. def growSimpleRRT(points):
  63. newPoints = {}
  64. adjListMap = {}
  65.  
  66. bool = True
  67. count = 0
  68. # Your code goes here
  69. for i in points:
  70. if len(newPoints) == 0:
  71. newPoints[i] = points[i]
  72. newPoints[i+1] = points[i+1]
  73. adjListMap[i] = [i+1]
  74. adjListMap[i+1] = [i]
  75. elif len(newPoints) == 2 and bool:
  76. bool = False
  77. continue
  78. else:
  79. num = 0
  80. index = 0
  81. point1 = 0
  82. point2 = 0
  83. d = sys.maxsize #distance from random point to nearest point on line
  84. x = 0
  85. y = 0
  86. for j in list(adjListMap): # j is the key in adjListMap. j just goes through each point
  87. for k in adjListMap[j]: # k goes through every point that j is connected to
  88. m1 = (newPoints[k][1]-newPoints[j][1])/(newPoints[k][0]-newPoints[j][0])
  89. b1 = newPoints[j][1] - m1*newPoints[j][0]
  90. m2 = -1/m1
  91. b2 = points[i][1] - m2*points[i][0]
  92. newPointX = (b2-b1)/(m1-m2)
  93. newPointY = m1*newPointX + b1
  94. if not collisionDetection(adjListMap,newPoints,[points[i],(newPointX,newPointY)],j,k):
  95. if (newPoints[k][0] <= newPointX <= newPoints[j][0] or newPoints[k][0] >= newPointX >= newPoints[j][0]) and (newPoints[k][1] <= newPointY <= newPoints[j][1] or newPoints[k][1] >= newPointY >= newPoints[j][1]):
  96. if d > math.sqrt((newPointX-points[i][0])**2+(newPointY-points[i][1])**2):
  97. d = math.sqrt((newPointX-points[i][0])**2+(newPointY-points[i][1])**2)
  98. x = newPointX
  99. y = newPointY
  100. point1 = j
  101. point2 = k
  102. num = 0
  103. else:
  104. if newPoints[k][0] > newPoints[j][0]:
  105. if newPointX > newPoints[k][0]:
  106. if d > math.sqrt((newPoints[k][0]-points[i][0])**2+(newPoints[k][1]-points[i][1])**2):
  107. d = math.sqrt((newPoints[k][0]-points[i][0])**2+(newPoints[k][1]-points[i][1])**2)
  108. index = k
  109. num = 1
  110. else:
  111. if d > math.sqrt((newPoints[j][0]-points[i][0])**2+(newPoints[j][1]-points[i][1])**2):
  112. d = math.sqrt((newPoints[j][0]-points[i][0])**2+(newPoints[j][1]-points[i][1])**2)
  113. index = j
  114. num = 1
  115. else:
  116. if newPointX > newPoints[j][0]:
  117. if d > math.sqrt((newPoints[j][0]-points[i][0])**2+(newPoints[j][1]-points[i][1])**2):
  118. d = math.sqrt((newPoints[j][0]-points[i][0])**2+(newPoints[j][1]-points[i][1])**2)
  119. index = j
  120. num = 1
  121. else:
  122. if d > math.sqrt((newPoints[k][0]-points[i][0])**2+(newPoints[k][1]-points[i][1])**2):
  123. d = math.sqrt((newPoints[k][0]-points[i][0])**2+(newPoints[k][1]-points[i][1])**2)
  124. index = k
  125. num = 1
  126.  
  127. if newPointX != points[i][0] and newPointY != points[i][1]:
  128. temp = i+count
  129. newPoints[temp] = points[i]
  130. if num == 0:
  131. count+=1
  132. newPoints[i+count] = (x,y)
  133. if adjListMap.get(temp) == None:
  134. adjListMap[temp] = [i+count]
  135. else:
  136. adjListMap[temp].append(i+count)
  137. adjListMap[i+count] = [temp]
  138. adjListMap[i+count].append(point1)
  139. adjListMap[i+count].append(point2)
  140. newList = adjListMap[point1]
  141. newList.remove(point2)
  142. newList.append(i+count)
  143. adjListMap[point1] = newList
  144. newList = adjListMap[point2]
  145. newList.remove(point1)
  146. newList.append(i+count)
  147. adjListMap[point2] = newList
  148. else:
  149. adjListMap[temp] = [index]
  150. adjListMap[index].append(temp)
  151.  
  152.  
  153. return newPoints, adjListMap
  154.  
  155. def collisionDetection(adjListMap, newPoints, points,a,b):
  156. bool = 0
  157. for i in adjListMap:
  158. for j in adjListMap[i]:
  159. if i == a and j == b or i == b and j == a:
  160. continue
  161. m1 = (newPoints[j][1]-newPoints[i][1])/(newPoints[j][0]-newPoints[i][0])
  162. b1 = newPoints[i][1] - m1*newPoints[i][0]
  163. m2 = (points[1][1]-points[0][1])/(points[1][0]-points[0][0])
  164. b2 = points[1][1]-m2*points[1][0]
  165. if (m1 == m2):
  166. continue
  167. intersectX = (b2-b1)/(m1-m2)
  168. intersectY = m1*intersectX + b1
  169. for k in adjListMap:
  170. for l in adjListMap[k]:
  171. if ((newPoints[l][0] > intersectX > newPoints[k][0] or newPoints[l][0] < intersectX < newPoints[k][0]) and (newPoints[l][1] > intersectY > newPoints[k][1] or newPoints[l][1] < intersectY < newPoints[k][1])) and ((points[0][0] < intersectX < points[1][0] or points[0][0] > intersectX > points[1][0]) and (points[1][0] < intersectY < points[1][1] or points[1][0] > intersectY > points[1][1])) and not intersectX == points[1][0] and not intersectY == points[1][1]:
  172. bool = 1
  173. break
  174. if bool==1:
  175. break
  176. if bool==1:
  177. break
  178. if bool==1:
  179. break
  180. if bool==1:
  181. return True #the lines collide. This is not a valid point
  182. return False #the lines do not collide.
  183.  
  184. '''
  185. Perform basic search
  186. '''
  187. def backtrace(parent, start, end):
  188. path = [end]
  189. while path[-1] != start:
  190. path.append(parent[path[-1]])
  191. path.reverse()
  192. return path
  193.  
  194. def basicSearch(tree, start, goal):
  195. parent = {}
  196. path = []
  197. visited = [False] * (len(tree))
  198. squeue = queue.Queue()
  199.  
  200. squeue.put(start)
  201. visited[start] = True
  202. found=False
  203. while squeue:
  204. s = squeue.get(0)
  205. path.append(s)
  206. if(s == goal):
  207. found=True
  208. return backtrace(parent, start, goal)
  209.  
  210. # Get all adjacent vertices of the
  211. # dequeued vertex s. If a adjacent
  212. # has not been visited, then mark it
  213. # visited and enqueue it
  214.  
  215. for l in tree[s]:
  216. if visited[l] == False:
  217. parent[l] = s
  218. squeue.put(l)
  219. visited[l] = True
  220.  
  221.  
  222. return path
  223.  
  224. '''
  225. Display the RRT and Path
  226. '''
  227. def displayRRTandPath(points, adjListMap, path, robotStart=None, robotGoal=None, polygons=None):
  228. # Your code goes here
  229. # You could start by copying code from the function
  230. # drawProblem and modify it to do what you need.
  231. # You should draw the problem when applicable.
  232. _, ax = setupPlot()
  233. patch = createPolygonPatch(robotStart, 'green')
  234. ax.add_patch(patch)
  235. patch = createPolygonPatch(robotGoal, 'red')
  236. ax.add_patch(patch)
  237.  
  238. for p in range(0, len(polygons)):
  239. patch = createPolygonPatch(polygons[p], 'gray')
  240. ax.add_patch(patch)
  241.  
  242.  
  243. line = []
  244. for j in adjListMap:
  245. for k in adjListMap[j]:
  246. line.append([points[j],points[k]])
  247.  
  248. lc = mc.LineCollection(line, linewidths=2, color='black')
  249. ax.add_collection(lc)
  250.  
  251.  
  252. plt.show()
  253.  
  254. #lines = [[(0, 1), (1, 1)], [(2, 3), (3, 3)], [(1, 2), (1, 3)]]
  255. #lc = mc.LineCollection(lines, linewidths=2)
  256. #ax.add_collection(lc)
  257. #plt.scatter(x,y, color='black', marker='o')
  258. return
  259.  
  260. '''
  261. Collision checking
  262. '''
  263. def isCollisionFree(robot, point, obstacles):
  264.  
  265. # Your code goes here.
  266. for i in range(0,len(robot)):
  267. robot[i] = (robot[i][0]+point[0],robot[i][1]+point[1])
  268. if robot[i][0] < 0 or robot[i][1] < 0 or robot[i][0] > 10 or robot[i][1] > 10:
  269. return False
  270. bool = False
  271. for i in robot:
  272. if i != len(robot)-1:
  273. m1 = (robot[i+1][1]-robot[i][1])/(robot[i+1][0]-robot[i][0])
  274. b1 = robot[i][1]-m1*robot[i][0]
  275. for j in obstacles:
  276. for k in obstacles[j]:
  277. if k != len(obstacles[j])-1:
  278. m2 = (obstacles[k][1]-obstacles[j][1])/(obstacles[k][0]-obstacles[j][0])
  279. if m1 == m2:
  280. continue
  281. b2 = obstacles[j][1]-m2*obstacles[j][0]
  282. intersectX = (b2-b1)/(m1-m2)
  283. intersectY = m1*intersectX + b1
  284. if (obstacles[j][0] <= intersectX <= obstacles[k][0] or obstacles[j][0] >= intersectX >= obstacles[k][0]) and (robot[i][0] <= intersectX <= robot[i+1][0] or robot[i][0] >= intersectX >= robot[i+1][0]) and (obstacles[j][1] <= intersectY <= obstacles[k][1] or obstacles[j][1] >= intersectY >= obstacles[k][1]) and (robot[i][1] <= intersectY <= robot[i+1][1] or robot[i][1] >= intersectY >= robot[i+1][1]):
  285. bool = True
  286. break
  287. if bool:
  288. break
  289. if bool:
  290. break
  291. if bool:
  292. return False
  293. return True
  294.  
  295. '''
  296. The full RRT algorithm
  297. '''
  298. def RRT(robot, obstacles, startPoint, goalPoint):
  299.  
  300. points = dict()
  301. tree = dict()
  302. path = []
  303. # Your code goes here.
  304.  
  305. return points, tree, path
  306.  
  307. def main(filename, x1, y1, x2, y2, display=''):
  308. # Read data and parse polygons
  309. lines = [line.rstrip('\n') for line in open(filename)]
  310. robot = []
  311. obstacles = []
  312. for line in range(0, len(lines)):
  313. xys = lines[line].split(';')
  314. polygon = []
  315. for p in range(0, len(xys)):
  316. xy = xys[p].split(',')
  317. polygon.append((float(xy[0]), float(xy[1])))
  318. if line == 0 :
  319. robot = polygon
  320. else:
  321. obstacles.append(polygon)
  322.  
  323. # Print out the data
  324. print("Robot:")
  325. print(str(robot))
  326. print("Pologonal obstacles:")
  327. for p in range(0, len(obstacles)):
  328. print(str(obstacles[p]))
  329. print("")
  330.  
  331. # Visualize
  332. if display == 'display':
  333. robotStart = [(x + x1, y + y1) for x, y in robot]
  334. robotGoal = [(x + x2, y + y2) for x, y in robot]
  335. #drawProblem(robotStart, robotGoal, obstacles)
  336.  
  337. # Example points for calling growSimpleRRT
  338. # You should expect many mroe points, e.g., 200-500
  339. points = dict()
  340. points[1] = (5, 5)
  341. points[2] = (7, 8.2)
  342. points[3] = (6.5, 5.2)
  343. points[4] = (0.3, 4)
  344. points[5] = (6, 3.7)
  345. points[6] = (9.7, 6.4)
  346. points[7] = (4.4, 2.8)
  347. points[8] = (9.1, 3.1)
  348. points[9] = (8.1, 6.5)
  349. points[10] = (0.7, 5.4)
  350. points[11] = (5.1, 3.9)
  351. points[12] = (2, 6)
  352. points[13] = (0.5, 6.7)
  353. points[14] = (8.3, 2.1)
  354. points[15] = (7.7, 6.3)
  355. points[16] = (7.9, 5)
  356. points[17] = (4.8, 6.1)
  357. points[18] = (3.2, 9.3)
  358. points[19] = (7.3, 5.8)
  359. points[20] = (9, 0.6)
  360.  
  361. # Printing the points
  362. print("")
  363. print("The input points are:")
  364. print(str(points))
  365. print("")
  366.  
  367. points, adjListMap = growSimpleRRT(points)
  368. print("")
  369. print("The new points are:")
  370. print(str(points))
  371. print("")
  372. print("")
  373. print("The tree is:")
  374. print(str(adjListMap))
  375. print("")
  376.  
  377. # Search for a solution
  378. # change 1 and 20 as you want
  379. path = basicSearch(adjListMap, 1, 2)
  380. print("")
  381. print("The path is:")
  382. print(str(path))
  383. print("")
  384.  
  385. # Your visualization code
  386. #if display == 'display':
  387. #displayRRTandPath(points, adjListMap, path)
  388.  
  389. # Solve a real RRT problem
  390. points, adjListMap, path = RRT(robot, obstacles, (x1, y1), (x2, y2))
  391.  
  392. # Your visualization code
  393. if display == 'display':
  394. displayRRTandPath(points, adjListMap, path, robotStart, robotGoal, obstacles)
  395.  
  396.  
  397. if __name__ == "__main__":
  398. # Retrive file name for input data
  399. if(len(sys.argv) < 6):
  400. print("Five arguments required: python spr.py [env-file] [x1] [y1] [x2] [y2]")
  401. exit()
  402.  
  403. filename = sys.argv[1]
  404. x1 = float(sys.argv[2])
  405. y1 = float(sys.argv[3])
  406. x2 = float(sys.argv[4])
  407. y2 = float(sys.argv[5])
  408. display = ''
  409. if(len(sys.argv) == 7):
  410. display = sys.argv[6]
  411.  
  412. main(filename, x1, y1, x2, y2, display)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement