1313import  math 
1414import  matplotlib .pyplot  as  plt 
1515
16- show_animation  =  True 
16+ show_animation  =  False 
1717
1818
1919class  RTree (object ):
2020
21-     def  __init__ (self , start = [0 ,0 ], lowerLimit = [0 ,0 ], upperLimit = [10 ,10 ], resolution = 1 ):
21+     def  __init__ (self , start = [0 , 0 ], lowerLimit = [0 , 0 ], upperLimit = [10 , 10 ], resolution = 1 ):
22+ 
2223        self .vertices  =  dict ()
23-         
2424        self .edges  =  []
2525        self .start  =  start 
2626        self .lowerLimit  =  lowerLimit 
@@ -61,7 +61,7 @@ def realCoordsToGridCoord(self, real_coord):
6161        # the output is the same as real world coords if the resolution 
6262        # is set to 1 
6363        coord  =  [0 ] *  self .dimension 
64-         for  i  in  range (0 ,  len (coord )):
64+         for  i  in  range (len (coord )):
6565            start  =  self .lowerLimit [i ]  # start of the grid space 
6666            coord [i ] =  np .around ((real_coord [i ] -  start ) /  self .resolution )
6767        return  coord 
@@ -131,8 +131,8 @@ def __init__(self, start, goal,
131131        self .start  =  start 
132132        self .goal  =  goal 
133133
134-         self .minrand  =  randArea [0 ]
135-         self .maxrand  =  randArea [1 ]
134+         self .minrand  =  randArea [0 ]  
135+         self .maxrand  =  randArea [1 ]  
136136        self .expandDis  =  expandDis 
137137        self .goalSampleRate  =  goalSampleRate 
138138        self .maxIter  =  maxIter 
@@ -152,7 +152,8 @@ def __init__(self, start, goal,
152152        # initialize tree 
153153        lowerLimit  =  [randArea [0 ], randArea [0 ]]
154154        upperLimit  =  [randArea [1 ], randArea [1 ]]
155-         self .tree  =  RTree (start = start ,lowerLimit = lowerLimit ,upperLimit = upperLimit ,resolution = 0.1 )
155+         self .tree  =  RTree (start = start , lowerLimit = lowerLimit ,
156+                           upperLimit = upperLimit , resolution = 0.1 )
156157
157158    def  plan (self , animation = True ):
158159
@@ -175,14 +176,14 @@ def plan(self, animation=True):
175176        cBest  =  self .g_scores [self .goalId ]
176177        pathLen  =  float ('inf' )
177178        solutionSet  =  set ()
178-         path  =  None 
179+         plan  =  [] 
179180
180181        # Computing the sampling space 
181182        cMin  =  math .sqrt (pow (self .start [0 ] -  self .goal [1 ], 2 ) + 
182183                         pow (self .start [0 ] -  self .goal [1 ], 2 ))
183184        xCenter  =  np .matrix ([[(self .start [0 ] +  self .goal [0 ]) /  2.0 ],
184185                             [(self .goal [1 ] -  self .start [1 ]) /  2.0 ], [0 ]])
185-         a1  =  np .matrix ([[(self .goal [0 ]-  self .start [0 ]) /  cMin ],
186+         a1  =  np .matrix ([[(self .goal [0 ]  -  self .start [0 ]) /  cMin ],
186187                        [(self .goal [1 ] -  self .start [1 ]) /  cMin ], [0 ]])
187188        etheta  =  math .atan2 (a1 [1 ], a1 [0 ])
188189        # first column of idenity matrix transposed 
@@ -238,7 +239,7 @@ def plan(self, animation=True):
238239                        secondCoord  =  self .tree .nodeIdToRealWorldCoord (
239240                            bestEdge [1 ])
240241                        path  =  self .connect (firstCoord , secondCoord )
241-                         if  path  ==  None  or  len (path ) ==  0 :
242+                         if  path  is  None  or  len (path ) ==  0 :
242243                            continue 
243244                        nextCoord  =  path [len (path ) -  1 , :]
244245                        nextCoordPathId  =  self .tree .realWorldToNodeId (
@@ -248,7 +249,7 @@ def plan(self, animation=True):
248249                            del  self .samples [bestEdge [1 ]]
249250                        except (KeyError ):
250251                            pass 
251-                         eid  =  self .tree .addVertex (nextCoordPathId )
252+                         eid  =  self .tree .addVertex (nextCoord )
252253                        self .vertex_queue .append (eid )
253254                        if  eid  ==  self .goalId  or  bestEdge [0 ] ==  self .goalId  or  bestEdge [1 ] ==  self .goalId :
254255                            print ("Goal found" )
@@ -259,15 +260,17 @@ def plan(self, animation=True):
259260                        g_score  =  self .computeDistanceCost (
260261                            bestEdge [0 ], bestEdge [1 ])
261262                        self .g_scores [bestEdge [1 ]] =  g_score  +  \
262-                             self .g_scores [best_edge [0 ]]
263+                             self .g_scores [bestEdge [0 ]]
263264                        self .f_scores [bestEdge [1 ]] =  g_score  +  \
264265                            self .computeHeuristicCost (bestEdge [1 ], self .goalId )
265266                        self .updateGraph ()
266267
267268                        # visualize new edge 
268-                         # if animation: 
269-                         # 	self.drawGraph(xCenter=xCenter, cBest=cBest, 
270-                         # 	   cMin=cMin, etheta=etheta, samples=samples) 
269+ 
270+                         if  animation :
271+                         	self .drawGraph (xCenter = xCenter , cBest = cBest ,
272+                         	   cMin = cMin , etheta = etheta , samples = self .samples .values (),
273+                         	   start = firstCoord , end = secondCoord , plan = plan )
271274
272275                        for  edge  in  self .edge_queue :
273276                            if (edge [0 ] ==  bestEdge [1 ]):
@@ -288,14 +291,36 @@ def plan(self, animation=True):
288291        plan .append (self .goal )
289292        currId  =  self .goalId 
290293        while  (currId  !=  self .startId ):
291-             plan .append (seld .tree .nodeIdToRealWorldCoord (currId ))
294+             plan .append (self .tree .nodeIdToRealWorldCoord (currId ))
292295            currId  =  self .nodes [currId ]
293296
294297        plan .append (self .startId )
295298        plan  =  plan [::- 1 ]  # reverse the plan 
296299        return  np .array (plan )
297300
298-     # def expandVertex(self, vertex): 
301+     def  connect (self , start , end ):
302+             # A function which attempts to extend from a start coordinates 
303+             # to goal coordinates 
304+         steps  =  self .computeDistanceCost (self .tree .realWorldToNodeId (
305+             start ), self .tree .realWorldToNodeId (end )) *  25 
306+         x  =  np .linspace (start [0 ], end [0 ], num = steps )
307+         y  =  np .linspace (start [1 ], end [1 ], num = steps )
308+         for  i  in  range (len (x )):
309+             if (self ._collisionCheck (x [i ], y [i ])):
310+                 if (i  ==  0 ):
311+                     return  None 
312+                 # if collision, send path until collision 
313+                 return  np .vstack ((x [0 :i ], y [0 :i ])).transpose ()
314+             return  np .vstack ((x , y )).transpose ()
315+ 
316+     def  _collisionCheck (self , x , y ):
317+         for  (ox , oy , size ) in  self .obstacleList :
318+             dx  =  ox  -  x 
319+             dy  =  oy  -  y 
320+             d  =  dx  *  dx  +  dy  *  dy 
321+             if  d  <=  1.1  *  size  **  2 :
322+                 return  True   # collision 
323+         return  False 
299324
300325    # def prune(self, c): 
301326
@@ -485,7 +510,8 @@ def updateGraph(self):
485510                    # store the parent and child 
486511                    self .nodes [succesor ] =  currId 
487512
488-     def  drawGraph (self , xCenter = None , cBest = None , cMin = None , etheta = None , samples = None ):
513+     def  drawGraph (self , xCenter = None , cBest = None , cMin = None , etheta = None , 
514+     			  samples = None , start = None , end = None , plan = None ):
489515        print ("Plotting Graph" )
490516        plt .clf ()
491517        for  rnd  in  samples :
@@ -494,6 +520,9 @@ def drawGraph(self, xCenter=None, cBest=None, cMin=None, etheta=None, samples=No
494520                if  cBest  !=  float ('inf' ):
495521                    self .plot_ellipse (xCenter , cBest , cMin , etheta )
496522
523+         if  start  is  not   None  and  end  is  not   None :
524+         	plt .plot ([start [0 ], start [1 ]], [end [0 ], end [1 ]], "-g" )
525+ 
497526        # for node in self.nodeList: 
498527        # 	if node.parent is not None: 
499528        # 		if node.x or node.y is not None: 
@@ -503,11 +532,11 @@ def drawGraph(self, xCenter=None, cBest=None, cMin=None, etheta=None, samples=No
503532        for  (ox , oy , size ) in  self .obstacleList :
504533            plt .plot (ox , oy , "ok" , ms = 30  *  size )
505534
506-         plt .plot (self .start . x , self .start . y , "xr" )
507-         plt .plot (self .goal . x , self .goal . y , "xr" )
535+         plt .plot (self .start [ 0 ] , self .start [ 1 ] , "xr" )
536+         plt .plot (self .goal [ 0 ] , self .goal [ 1 ] , "xr" )
508537        plt .axis ([- 2 , 15 , - 2 , 15 ])
509538        plt .grid (True )
510-         plt .pause (5 )
539+         plt .pause (0.01 )
511540
512541    def  plot_ellipse (self , xCenter , cBest , cMin , etheta ):
513542
@@ -532,16 +561,16 @@ def plot_ellipse(self, xCenter, cBest, cMin, etheta):
532561def  main ():
533562    print ("Starting Batch Informed Trees Star planning" )
534563    obstacleList  =  [
535-         (5 , 5 , 0.5 ),
536-         (9 , 6 , 1 ),
537-         (7 , 5 , 1 ),
538-         (1 , 5 , 1 ),
539-         (3 , 6 , 1 ),
540-         (7 , 9 , 1 )
564+         #  (5, 5, 0.5),
565+         #  (9, 6, 1),
566+         #  (7, 5, 1),
567+         #  (1, 5, 1),
568+         #  (3, 6, 1),
569+         #  (7, 9, 1)
541570    ]
542571
543-     bitStar  =  BITStar (start = [0 , 0 ], goal = [5 ,  10 ], obstacleList = obstacleList ,
544-                       randArea = [0 , 15 ])
572+     bitStar  =  BITStar (start = [0 , 0 ], goal = [2 ,  4 ], obstacleList = obstacleList ,
573+                       randArea = [- 2 , 15 ])
545574    path  =  bitStar .plan (animation = show_animation )
546575    print ("Done" )
547576
0 commit comments