示例#1
0
 def plotPoly(self, c, string, w=1):
     """
     Plot polygons inside the boundary
     c = polygon to be plotted with matlabplot
     string = string that specify color
     w      = width of the line plotting
     """
     if bool(c):
         for i in range(len(c)):
             # toPlot = Polygon.Polygon(c.contour(i))
             toPlot = Polygon.Polygon(c.contour(i)) & self.all
             if bool(toPlot):
                 for j in range(len(toPlot)):
                     # BoundPolyPoints = asarray(PolyUtils.pointList(toPlot.contour(j)))
                     BoundPolyPoints = asarray(PolyUtils.pointList(Polygon.Polygon(toPlot.contour(j))))
                     if self.operate_system == 2:
                         self.ax.plot(BoundPolyPoints[:, 0], BoundPolyPoints[:, 1], string, linewidth=w)
                         self.ax.plot(
                             [BoundPolyPoints[-1, 0], BoundPolyPoints[0, 0]],
                             [BoundPolyPoints[-1, 1], BoundPolyPoints[0, 1]],
                             string,
                             linewidth=w,
                         )
                     else:
                         plt.plot(BoundPolyPoints[:, 0], BoundPolyPoints[:, 1], string, linewidth=w)
                         plt.plot(
                             [BoundPolyPoints[-1, 0], BoundPolyPoints[0, 0]],
                             [BoundPolyPoints[-1, 1], BoundPolyPoints[0, 1]],
                             string,
                             linewidth=w,
                         )
示例#2
0
    def measureCurrentState(self):
        # the RawTimeToArriveOffline.py file has the derivation of this
        ND = len(self._defenders)
        u0 = np.zeros((ND,))
        th = np.linspace(0., np.pi, 181)
        NTH = th.shape[0]
        R = np.zeros((ND, NTH))  # radius that matches the time threshold


        for i in range(ND):
            defender = self._defenders[i]
            defender.TTAPolygon = list()
            defender.TTAData = list()
            x = defender.state[0]
            y = defender.state[1]
            u0 = defender.state[2]
            uid = defender.uniqueID
            heading = defender.state[4]
            transform = np.array([[np.cos(heading), -np.sin(heading), x], [np.sin(heading), np.cos(heading), y], [0., 0., 1.]])
            for T in self._T:

                R[i, :] = 1./self._defender_rCoeff*(T - self._defender_thCoeff*th - self._defender_u0Coeff*u0)
                R[R < 0.] = 0.
                bodyFrameData = np.row_stack((R[i, :]*np.cos(th), R[i, :]*np.sin(th), np.ones((1, NTH))))
                # mirror image the other side and invert y
                bodyFrameDataFlipped = np.fliplr(copy.deepcopy(bodyFrameData[:, 1:-1]))
                bodyFrameDataFlipped[1, :] *= -1.
                bodyFrameData = np.column_stack((bodyFrameData, bodyFrameDataFlipped))

                # transform from body frame into world frame
                worldFrameData = np.dot(transform, bodyFrameData)
                worldFrameData = worldFrameData[:2, :]  # remove extra 1's from homogenous transform
                # need to create a tuple of (x,y) 2-tuples to generate a polygon object. Start by appending to a list.
                worldFrameList = list()
                for j in range(worldFrameData.shape[1]):
                    worldFrameList.append((worldFrameData[0, j], worldFrameData[1, j]))
                worldFrameTuple = tuple(worldFrameList)
                self._polygons[uid] = polyUtils.prunePoints(polyUtils.Polygon(worldFrameTuple))  # remove any redundant points
                if u0 > 1.0 and self._T < 8.9:
                    # defender with forward velocity can't get back to where it started faster than 8.9 seconds
                    # for simplicity, just cut out the entire 3 meter circle where the plane fit for TTA breaks down
                    #R[i, np.where(R[i, :] < 3.0)] = 3.0
                    self._polygons[uid] -= polyShapes.Circle(radius=3.0, center=(x, y))
                defender.TTAPolygon.append(self._polygons[uid])
                TTAData = np.array(polyUtils.pointList(self._polygons[uid]))
                defender.TTAData.append(np.row_stack((TTAData, TTAData[0, :])))
示例#3
0
文件: convert.py 项目: ajelcode/tafor
def clipPolygon(subj, clip, maxPoint=7):
    """计算两个多边形之间的交集,并根据允许的最大点平滑多边形

        A General Polygon Clipping Library
        http://www.cs.man.ac.uk/~toby/alan/software/gpc.html

    :param subj: 列表,目标多边形的坐标集
    :param clip: 列表,相切多边形的坐标集
    :param maxPoint: 数字,交集允许的最大点
    :return: 列表,新的多边形坐标集
    """
    subj = Polygon(subj)
    clip = Polygon(clip)
    try:
        intersection = subj & clip
        points = Utils.pointList(intersection)
    except Exception as e:
        points = []
    finally:
        if len(points) > maxPoint:
            points = Utils.reducePoints(points, maxPoint)
        return points
def plotPoly(c,string,w = 1):
    """
    Plot polygons inside the boundary
    c = polygon to be plotted with matlabplot
    string = string that specify color
    w      = width of the line plotting 
    """
    for i in range(len(c)):
        toPlot = Polygon.Polygon(c.contour(i)) 
        if bool(toPlot):               
            BoundPolyPoints = asarray(PolyUtils.pointList(toPlot))
            plt.plot(BoundPolyPoints[:,0],BoundPolyPoints[:,1],string,linewidth=w)   
            plt.plot([BoundPolyPoints[-1,0],BoundPolyPoints[0,0]],[BoundPolyPoints[-1,1],BoundPolyPoints[0,1]],string,linewidth=w)   
示例#5
0
def plotPoly(c, string, w=1):
    """
    Plot polygons inside the boundary
    c = polygon to be plotted with matlabplot
    string = string that specify color
    w      = width of the line plotting 
    """
    for i in range(len(c)):
        toPlot = Polygon.Polygon(c.contour(i))
        if bool(toPlot):
            BoundPolyPoints = asarray(PolyUtils.pointList(toPlot))
            plt.plot(BoundPolyPoints[:, 0],
                     BoundPolyPoints[:, 1],
                     string,
                     linewidth=w)
            plt.plot([BoundPolyPoints[-1, 0], BoundPolyPoints[0, 0]],
                     [BoundPolyPoints[-1, 1], BoundPolyPoints[0, 1]],
                     string,
                     linewidth=w)
示例#6
0
 def plotPoly(self,c,string,w = 1):
     """
     Plot polygons inside the boundary
     c = polygon to be plotted with matlabplot
     string = string that specify color
     w      = width of the line plotting
     """
     if bool(c):
         for i in range(len(c)):
             toPlot = Polygon.Polygon(c.contour(i)) & self.all
             if bool(toPlot):
                 for j in range(len(toPlot)):
                     BoundPolyPoints = asarray(PolyUtils.pointList(Polygon.Polygon(toPlot.contour(j))))
                     if self.operate_system == 2:
                         self.ax.plot(BoundPolyPoints[:,0],BoundPolyPoints[:,1],string,linewidth=w)
                         self.ax.plot([BoundPolyPoints[-1,0],BoundPolyPoints[0,0]],[BoundPolyPoints[-1,1],BoundPolyPoints[0,1]],string,linewidth=w)
                     else:
                         self.ax.plot(BoundPolyPoints[:,0],BoundPolyPoints[:,1],string,linewidth=w)
                         self.ax.plot([BoundPolyPoints[-1,0],BoundPolyPoints[0,0]],[BoundPolyPoints[-1,1],BoundPolyPoints[0,1]],string,linewidth=w)
                         self.setPlotLimitXYZ()
示例#7
0
    def generateNewNode(self,V,V_theta,E,Other,regionPoly,stuck,append_after_latest_node =False):
        """
        Generate a new node on the current tree matrix
        V         : the node matrix
        V_theta   : the orientation matrix
        E         : the tree matrix (or edge matrix)
        Other     : the matrix containing the velocity and angular velocity(omega) information
        regionPoly: the polygon of current region
        stuck     : count on the number of times failed to generate new node
        append_after_latest_node : append new nodes to the latest node (True only if the previous node addition is successful)
        """


        if self.system_print == True:
            print "In control space generating path,stuck = " + str(stuck)

        connection_to_tree = False   # True when connection to the tree is successful

        if stuck > self.stuck_thres:
            # increase the range of omega since path cannot ge generated
            omega = random.choice(self.omega_range_escape)
        else:
            #!!!! CONTROL SPACE STEP 1 - generate random omega
            omega = random.choice(self.omega_range)


        #!!!! CONTROL SPACE STEP 2 - pick a random point on the tree
        if append_after_latest_node:
            tree_index = shape(V)[1]-1
        else:
            if random.choice([1,2]) == 1:
                tree_index = random.choice(array(V[0])[0])
            else:
                tree_index = shape(V)[1]-1


        xPrev     = V[1,tree_index]
        yPrev     = V[2,tree_index]
        thetaPrev = V_theta[tree_index]

        j = 1
        #!!!! CONTROL SPACE STEP 3 - Check path of the robot
        path_robot = PolyShapes.Circle(self.radius,(xPrev,yPrev))
        while j <= self.timeStep:
            xOrg      = xPrev
            yOrg      = yPrev
            xPrev     = xPrev + self.velocity/omega*(sin(omega* 1 + thetaPrev)-sin(thetaPrev))
            yPrev     = yPrev - self.velocity/omega*(cos(omega* 1 + thetaPrev)-cos(thetaPrev))
            thetaPrev = omega* 1 + thetaPrev
            path_robot = path_robot + PolyShapes.Circle(self.radius,(xPrev,yPrev))

            j = j + 1

        thetaPrev = self.orientation_bound(thetaPrev)
        path_all = PolyUtils.convexHull(path_robot)
        in_bound = regionPoly.covers(path_all)
        """
        # plotting
        if plotting == True:
            self.plotPoly(path_all,'r',1)
        """

        stuck = stuck + 1

        if in_bound:
            robot_new_node = PolyShapes.Circle(self.radius,(xPrev,yPrev))
            # check how many nodes on the tree does the new node overlaps with
            nodes_overlap_count = 0
            for k in range(shape(V)[1]-1):
                robot_old_node = PolyShapes.Circle(self.radius,(V[1,k],V[2,k]))
                if robot_new_node.overlaps(robot_old_node):
                    if  abs(thetaPrev - V_theta[k]) <   self.max_angle_overlap:
                        nodes_overlap_count += 1


            if nodes_overlap_count == 0 or (stuck > self.stuck_thres+1 and nodes_overlap_count < 2) or (stuck > self.stuck_thres+500):
                if  stuck > self.stuck_thres+1:
                    append_after_latest_node  = False

                if (stuck > self.stuck_thres+500):
                    stuck = 0
                stuck = stuck - 20
                # plotting
                if self.plotting == True:
                    self.plotPoly(path_all,'b',1)

                if self.system_print == True:
                    print "node connected"

                V = hstack((V,vstack((shape(V)[1],xPrev,yPrev))))
                V_theta = hstack((V_theta,thetaPrev))
                E = hstack((E,vstack((tree_index ,shape(V)[1]-1))))
                Other = hstack((Other,vstack((self.velocity,omega))))
                ##################### E should add omega and velocity
                connection_to_tree = True
                append_after_latest_node  = True
            else:
                append_after_latest_node = False

                if self.system_print == True:
                    print "node not connected. check goal point"

        else:
            append_after_latest_node = False

        return  V,V_theta,E,Other,stuck,append_after_latest_node, connection_to_tree
示例#8
0
    def buildTree(self,p,theta,regionPoly,nextRegionPoly,q_gBundle,face_normal, last=False):
        """
        This function builds the RRT tree.
        p                : x,y position of the robot
        theta            : current orientation of the robot
        regionPoly       : current region polygon
        nextRegionPoly   : next region polygon
        q_gBundle        : coordinates of q_goals that the robot can reach
        face_normal      : the normal vector of each face corresponding to each goal point in q_gBundle
        """

        q_init          = mat(p).T
        V               = vstack((0,q_init))
        theta           = self.orientation_bound(theta)
        V_theta         = array([theta])

        #!!! CONTROL SPACE: generate a list of omega for random sampling
        omegaLowerBound = -math.pi/20      # upper bound for the value of omega
        omegaUpperBound = math.pi/20       # lower bound for the value of omega
        omegaNoOfSteps  = 20
        self.omega_range = linspace(omegaLowerBound,omegaUpperBound,omegaNoOfSteps)
        self.omega_range_escape = linspace(omegaLowerBound*4,omegaUpperBound*4,omegaNoOfSteps*4)    # range used when stuck > stuck_thres

        regionPolyOld = Polygon.Polygon(regionPoly)
        regionPoly += PolyShapes.Circle(self.radius*2.5,(q_init[0,0],q_init[1,0]))

        # check faces of the current region for goal points
        E     = [[],[]]       # the tree matrix
        Other = [[],[]]
        path                        = False          # if path formed then = 1
        stuck                       = 0              # count for changing the range of sampling omega
        append_after_latest_node    = False       # append new nodes to the latest node

        if self.system_print == True:
            print "plotting in buildTree is " + str(self.plotting)
        if self.plotting == True:
            if not plt.isinteractive():
                plt.ion()
            plt.hold(True)


        while not path:
            #step -1: try connection to q_goal (generate path to goal)
            i = 0

            if self.system_print == True:
                print "Try Connection to the goal points"

            # pushing possible q_goals into the current region (ensure path is covered by the current region polygon)
            q_pass = [[],[],[]]
            q_pass_dist = []
            q_gBundle = mat(q_gBundle)
            face_normal = mat(face_normal)

            while i < q_gBundle.shape[1]:
                q_g_original = q_gBundle[:,i]
                q_g = q_gBundle[:,i]+face_normal[:,i]*1.5*self.radius    ##original 2*self.radius
                #q_g = q_gBundle[:,i]+(q_gBundle[:,i]-V[1:,(shape(V)[1]-1)])/norm(q_gBundle[:,i]-V[1:,(shape(V)[1]-1)])*1.5*self.radius    ##original 2*self.radius
                if not regionPolyOld.isInside(q_g[0],q_g[1]):
                    #q_g = q_gBundle[:,i]-(q_gBundle[:,i]-V[1:,(shape(V)[1]-1)])/norm(q_gBundle[:,i]-V[1:,(shape(V)[1]-1)])*1.5*self.radius    ##original 2*self.radius
                    q_g = q_gBundle[:,i]-face_normal[:,i]*1.5*self.radius    ##original 2*self.radius

                #forming polygon for path checking
                EdgePolyGoal = PolyShapes.Circle(self.radius,(q_g[0,0],q_g[1,0])) + PolyShapes.Circle(self.radius,(V[1,shape(V)[1]-1],V[2:,shape(V)[1]-1]))
                EdgePolyGoal = PolyUtils.convexHull(EdgePolyGoal)
                dist = norm(q_g - V[1:,shape(V)[1]-1])

                #check connection to goal
                connect_goal = regionPoly.covers(EdgePolyGoal)   #check coverage of path from new point to goal

                # compare orientation difference
                thetaPrev = V_theta[shape(V)[1]-1]

                theta_orientation = abs(arctan((q_g[1,0]- V[2,shape(V)[1]-1])/(q_g[0,0]- V[1,shape(V)[1]-1])))
                if q_g[1,0] > V[2,shape(V)[1]-1]:
                    if q_g[0,0] < V[1,shape(V)[1]-1]: # second quadrant
                        theta_orientation = pi - theta_orientation
                    elif q_g[0,0] > V[1,shape(V)[1]-1]: # first quadrant
                        theta_orientation = theta_orientation
                elif q_g[1,0] < V[2,shape(V)[1]-1]:
                    if q_g[0,0] < V[1,shape(V)[1]-1]: #third quadrant
                        theta_orientation = pi + theta_orientation
                    elif q_g[0,0] > V[1,shape(V)[1]-1]: # foruth quadrant
                        theta_orientation =  2*pi - theta_orientation

                # check the angle between vector(new goal to goal_original ) and vector( latest node to new goal)
                Goal_to_GoalOriginal = q_g_original - q_g
                LatestNode_to_Goal   = q_g - V[1:,shape(V)[1]-1]
                Angle_Goal_LatestNode= arccos(vdot(array(Goal_to_GoalOriginal), array(LatestNode_to_Goal))/norm(Goal_to_GoalOriginal)/norm(LatestNode_to_Goal))

                # if connection to goal can be established and the max change in orientation of the robot is smaller than max_angle, tree is said to be completed.
                if self.orientation_print == True:
                    print "theta_orientation is " + str(theta_orientation)
                    print "thetaPrev is " + str(thetaPrev)
                    print "(theta_orientation - thetaPrev) is " + str(abs(theta_orientation - thetaPrev))
                    print "self.max_angle_allowed is " + str(self.max_angle_allowed)
                    print "abs(theta_orientation - thetaPrev) < self.max_angle_allowed" + str(abs(theta_orientation - thetaPrev) < self.max_angle_allowed)
                    print"Goal_to_GoalOriginal: " + str( array(Goal_to_GoalOriginal)) + "; LatestNode_to_Goal: " + str( array(LatestNode_to_Goal))
                    print vdot(array(Goal_to_GoalOriginal), array(LatestNode_to_Goal))
                    print "Angle_Goal_LatestNode" + str(Angle_Goal_LatestNode)

                if connect_goal and (abs(theta_orientation - thetaPrev) < self.max_angle_allowed) and (Angle_Goal_LatestNode < self.max_angle_allowed):

                    path = True
                    q_pass = hstack((q_pass,vstack((i,q_g))))
                    q_pass_dist = hstack((q_pass_dist,dist))

                i = i + 1

            if self.system_print == True:
                print "checked goal points"

            self.E = E
            self.V = V
            # connection to goal has established
            # Obtain the closest goal point that path can be formed.
            if path:
                if shape(q_pass_dist)[0] == 1:
                    cols = 0
                else:
                    (cols,) = nonzero(q_pass_dist == min(q_pass_dist))
                    cols = asarray(cols)[0]
                q_g = q_pass[1:,cols]
                """
                q_g = q_g-(q_gBundle[:,q_pass[0,cols]]-V[1:,(shape(V)[1]-1)])/norm(q_gBundle[:,q_pass[0,cols]]-V[1:,(shape(V)[1]-1)])*3*self.radius   #org 3
                if not nextRegionPoly.isInside(q_g[0],q_g[1]):
                    q_g = q_g+(q_gBundle[:,q_pass[0,cols]]-V[1:,(shape(V)[1]-1)])/norm(q_gBundle[:,q_pass[0,cols]]-V[1:,(shape(V)[1]-1)])*6*self.radius   #org 3
                """
                if self.plotting == True :
                    if self.operate_system == 1:
                        plt.suptitle('Rapidly-exploring Random Tree', fontsize=12)
                        plt.xlabel('x')
                        plt.ylabel('y')
                        if shape(V)[1] <= 2:
                            plt.plot(( V[1,shape(V)[1]-1],q_g[0,0]),( V[2,shape(V)[1]-1],q_g[1,0]),'b')
                        else:
                            plt.plot(( V[1,E[0,shape(E)[1]-1]], V[1,shape(V)[1]-1],q_g[0,0]),( V[2,E[0,shape(E)[1]-1]], V[2,shape(V)[1]-1],q_g[1,0]),'b')
                        plt.plot(q_g[0,0],q_g[1,0],'ko')
                        plt.figure(1).canvas.draw()
                    else:
                        BoundPolyPoints = asarray(PolyUtils.pointList(regionPoly))
                        self.ax.plot(BoundPolyPoints[:,0],BoundPolyPoints[:,1],'k')
                        if shape(V)[1] <= 2:
                            self.ax.plot(( V[1,shape(V)[1]-1],q_g[0,0]),( V[2,shape(V)[1]-1],q_g[1,0]),'b')
                        else:
                            self.ax.plot(( V[1,E[0,shape(E)[1]-1]], V[1,shape(V)[1]-1],q_g[0,0]),( V[2,E[0,shape(E)[1]-1]], V[2,shape(V)[1]-1],q_g[1,0]),'b')
                        self.ax.plot(q_g[0,0],q_g[1,0],'ko')

                # trim the path connecting current node to goal point into pieces if the path is too long now
                numOfPoint = floor(norm(V[1:,shape(V)[1]-1]- q_g)/self.step_size)
                if numOfPoint < 3:
                    numOfPoint = 3
                x = linspace( V[1,shape(V)[1]-1], q_g[0,0], numOfPoint )
                y = linspace( V[2,shape(V)[1]-1], q_g[1,0], numOfPoint )
                for i in range(x.shape[0]):
                    if i != 0:
                        V = hstack((V,vstack((shape(V)[1],x[i],y[i]))))
                        E = hstack((E,vstack((shape(V)[1]-2,shape(V)[1]-1))))

                #push the goal point to the next region
                q_g = q_g+face_normal[:,q_pass[0,cols]]*3*self.radius    ##original 2*self.radius
                if not nextRegionPoly.isInside(q_g[0],q_g[1]):
                    q_g = q_g-face_normal[:,q_pass[0,cols]]*6*self.radius    ##original 2*self.radius
                V = hstack((V,vstack((shape(V)[1],q_g[0,0],q_g[1,0]))))
                E = hstack((E,vstack((shape(V)[1]-2 ,shape(V)[1]-1))))

                if self.plotting == True :
                    if self.operate_system == 1:
                        plt.plot(q_g[0,0],q_g[1,0],'ko')
                        plt.plot(( V[1,shape(V)[1]-1],V[1,shape(V)[1]-2]),( V[2,shape(V)[1]-1],V[2,shape(V)[1]-2]),'b')
                        plt.figure(1).canvas.draw()
                    else:
                        self.ax.plot(q_g[0,0],q_g[1,0],'ko')
                        self.ax.plot(( V[1,shape(V)[1]-1],V[1,shape(V)[1]-2]),( V[2,shape(V)[1]-1],V[2,shape(V)[1]-2]),'b')

            # path is not formed, try to append points onto the tree
            if not path:

                # connection_to_tree : connection to the tree is successful
                if append_after_latest_node:
                    V,V_theta,E,Other,stuck,append_after_latest_node, connection_to_tree = self.generateNewNode(V,V_theta,E,Other,regionPoly,stuck, append_after_latest_node)
                else:
                    connection_to_tree = False
                    while not connection_to_tree:
                        V,V_theta,E,Other,stuck,append_after_latest_node, connection_to_tree = self.generateNewNode  (V,V_theta,E,Other,regionPoly,stuck)


        if self.finish_print:
            print 'Here is the V matrix:', V, 'Here is the E matrix:',E
            print >>sys.__stdout__, 'Here is the V matrix:\n', V, '\nHere is the E matrix:\n',E

        #B: trim to a single path
        single = 0
        while single == 0:
            trim  = 0
            for j in range(shape(V)[1]-3):
                (row,col) = nonzero(E == j+1)
                if len(col) == 1:
                    E = delete(E, col[0], 1)
                    trim = 1

            if trim == 0:
                single = 1;

        ####print with matlib
        if self.plotting ==True :
            if self.operate_system == 1:
                plt.plot(V[1,:],V[2,:],'b')
                for i in range(shape(E)[1]):
                    plt.text(V[1,E[0,i]],V[2,E[0,i]], V[0,E[0,i]], fontsize=12)
                    plt.text(V[1,E[1,i]],V[2,E[1,i]], V[0,E[1,i]], fontsize=12)
                plt.figure(1).canvas.draw()
            else:
                BoundPolyPoints = asarray(PolyUtils.pointList(regionPoly))
                self.ax.plot(BoundPolyPoints[:,0],BoundPolyPoints[:,1],'k')
                self.ax.plot(V[1,:],V[2,:],'b')
                for i in range(shape(E)[1]):
                    self.ax.text(V[1,E[0,i]],V[2,E[0,i]], V[0,E[0,i]], fontsize=12)
                    self.ax.text(V[1,E[1,i]],V[2,E[1,i]], V[0,E[1,i]], fontsize=12)

        #return V, E, and the current node number on the tree
        V = array(V)
        return V, E, 0
示例#9
0
    def gotoRegion(self, current_reg, next_reg, last=False):
        """
        If ``last`` is True, we will move to the center of the destination region.
        Returns ``True`` if we've reached the destination region.
        """
        q_gBundle = [[], []]  # goal bundle
        q_overlap = [[], []]  # overlapping points with robot range
        pose = self.pose_handler.getPose()  # Find our current configuration

        #Plot the robot on the map in figure 1
        if self.PLOT == True:
            plt.figure(self.original_figure)
            plt.clf()
            self.plotPoly(self.realRobot, 'r')
            self.plotPoly(self.robot, 'b')
            plt.plot(pose[0], pose[1], 'bo')
            self.plotPioneer(self.original_figure)

        if current_reg == next_reg and not last:
            # No need to move!
            self.drive_handler.setVelocity(0, 0)  # So let's stop
            return False

        # Check if Vicon has cut out
        if math.isnan(pose[2]):
            print "no vicon pose"
            print "WARNING: No Vicon data! Pausing."
            #self.drive_handler.setVelocity(0, 0)  # So let's stop
            time.sleep(1)
            return False

        ###This part is run when the robot goes to a new region, otherwise, the original map will be used.
        if not self.previous_current_reg == current_reg:
            #print 'getting into bug alogorithm'

            #clean up the previous self.map_work
            self.map_work = Polygon.Polygon()

            # NOTE: Information about region geometry can be found in self.proj.rfi.regions
            # create polygon list for regions other than the current_reg and the next_reg
            self.map_work += self.map[self.proj.rfi.regions[current_reg].name]
            self.map_work += self.map[self.proj.rfi.regions[next_reg].name]

            # building current polygon and destination polygon
            self.nextRegionPoly = self.map[
                self.proj.rfi.regions[next_reg].name]
            self.currentRegionPoly = self.map[
                self.proj.rfi.regions[current_reg].name]

            #set to zero velocity before finding the tranFace
            self.drive_handler.setVelocity(0, 0)
            if last:
                transFace = None
            else:
                print "Current reg is " + str(
                    self.proj.rfi.regions[current_reg].name.lower())
                print "Next reg is " + str(
                    self.proj.rfi.regions[next_reg].name.lower())

                for i in range(
                        len(self.proj.rfi.transitions[current_reg][next_reg])):
                    pointArray_transface = [
                        x for x in self.proj.rfi.transitions[current_reg]
                        [next_reg][i]
                    ]
                    transFace = asarray(
                        map(self.coordmap_map2lab, pointArray_transface))
                    bundle_x = (transFace[0, 0] +
                                transFace[1, 0]) / 2  #mid-point coordinate x
                    bundle_y = (transFace[0, 1] +
                                transFace[1, 1]) / 2  #mid-point coordinate y
                    q_gBundle = hstack((q_gBundle, vstack(
                        (bundle_x, bundle_y))))
                q_gBundle = q_gBundle.transpose()

                # Find the closest face to the current position
                max_magsq = 1000000
                for tf in q_gBundle:
                    magsq = (tf[0] - pose[0])**2 + (tf[1] - pose[1])**2
                    if magsq < max_magsq:
                        connection = 0
                        tf = tf + (tf - asarray(self.currentRegionPoly.center(
                        ))) / norm(tf - asarray(self.currentRegionPoly.center(
                        ))) * 2.1 * self.PioneerLengthHalf
                        if not self.nextRegionPoly.covers(
                                PolyShapes.Circle(self.PioneerLengthHalf * 2,
                                                  (tf[0], tf[1]))):
                            tf = tf - (tf - asarray(
                                self.currentRegionPoly.center())) / norm(
                                    tf - asarray(self.currentRegionPoly.center(
                                    ))) * 4.2 * self.PioneerLengthHalf
                            if self.nextRegionPoly.covers(
                                    PolyShapes.Circle(
                                        self.PioneerLengthHalf * 2,
                                        (tf[0], tf[1]))):
                                connection = 1
                        else:
                            connection = 1
                        if connection == 1:
                            pt1 = tf
                            max_magsq = magsq
                            transFace = 1
                            self.q_g[0] = pt1[0]
                            self.q_g[1] = pt1[1]
                        else:
                            sample = False
                            while not sample:
                                self.q_g[0], self.q_g[
                                    1] = self.nextRegionPoly.sample(
                                        random.random)
                                robo = PolyShapes.Circle(
                                    self.PioneerLengthHalf,
                                    (self.q_g[0], self.q_g[1]))
                                if not bool(robo - self.nextRegionPoly):
                                    sample = True
                """
                # Push the goal point to somewhere inside the next region to ensure the robot will get there.(CHECK!!)
                self.q_g = self.q_g+(self.q_g-asarray(self.currentRegionPoly.center()))/norm(self.q_g-asarray(self.currentRegionPoly.center()))*3*self.PioneerLengthHalf
                if not self.nextRegionPoly.isInside(self.q_g[0],self.q_g[1]):
                    self.q_g = self.q_g-(self.q_g-asarray(self.currentRegionPoly.center()))/norm(self.q_g-asarray(self.currentRegionPoly.center()))*6*self.PioneerLengthHalf
                """

                #plot exiting point
                if self.PLOT_EXIT == True:
                    plt.figure(self.overlap_figure)
                    plt.clf()
                    plt.plot(q_gBundle[:, 0], q_gBundle[:, 1], 'ko')
                    plt.plot(self.q_g[0], self.q_g[1], 'ro')
                    plt.plot(pose[0], pose[1], 'bo')
                    self.plotPioneer(self.overlap_figure, 0)

                if transFace is None:
                    print "ERROR: Unable to find transition face between regions %s and %s.  Please check the decomposition (try viewing projectname_decomposed.regions in RegionEditor or a text editor)." % (
                        self.proj.rfi.regions[current_reg].name,
                        self.proj.rfi.regions[next_reg].name)

        ##################################################
        #######check whether obstacle is detected#########
        ##################################################

        #Update pose,update self.robot, self.realRobot orientation
        self.robot.shift(pose[0] - self.prev_pose[0],
                         pose[1] - self.prev_pose[1])
        self.realRobot.shift(pose[0] - self.prev_pose[0],
                             pose[1] - self.prev_pose[1])
        self.robot.rotate(pose[2] - self.prev_pose[2], pose[0], pose[1])
        self.realRobot.rotate(pose[2] - self.prev_pose[2], pose[0], pose[1])
        self.prev_pose = pose

        ############################
        ########### STEP 1##########
        ############################
        ##Check whether obsRange overlaps with obstacle or the boundary (overlap returns the part of robot not covered by the region

        # for real Pioneer robot
        if self.system == 1:
            # motion controller is not in boundary following mode
            if self.boundary_following == False:

                if self.robocomm.getReceiveObs() == False:
                    overlap = self.robot - (self.map_work)
                else:
                    overlap = self.robot - (self.map_work -
                                            self.robocomm.getObsPoly())

            else:  #TRUE
                # use a robot with full range all around it
                Robot = PolyShapes.Circle(self.obsRange, (pose[0], pose[1]))
                Robot.shift(self.shift * cos(pose[2]),
                            self.shift * sin(pose[2]))

                if self.robocomm.getReceiveObs() == False:
                    overlap = Robot - (self.map_work)
                else:
                    overlap = Robot - (self.map_work -
                                       self.robocomm.getObsPoly())
        # for ODE
        else:
            if self.boundary_following == False:
                overlap = self.robot - (self.map_work)
            else:  #TRUE
                overlap = self.robot - (self.map_work)

        if self.boundary_following == False:
            if bool(overlap):  ## overlap of obstacles
                #print "There MAYBE overlap~~ check connection to goal"

                # check whether the real robot or and path to goal overlap with the obstacle
                QGoalPoly = PolyShapes.Circle(self.PioneerLengthHalf,
                                              (self.q_g[0], self.q_g[1]))
                path = PolyUtils.convexHull(self.realRobot + QGoalPoly)
                if self.system == 1:
                    if self.robocomm.getReceiveObs() == False:
                        pathOverlap = path - (self.map_work)
                    else:
                        pathOverlap = path - (self.map_work -
                                              self.robocomm.getObsPoly())
                else:
                    pathOverlap = path - (self.map_work)

                if bool(
                        pathOverlap
                ):  # there is overlapping, go into bounding following mode
                    #print "There IS overlap"
                    self.q_hit = mat([pose[0], pose[1]]).T
                    self.boundary_following = True

                    #Generate m-line polygon
                    QHitPoly = PolyShapes.Circle(self.PioneerLengthHalf / 4,
                                                 (pose[0], pose[1]))
                    QGoalPoly = PolyShapes.Circle(self.PioneerLengthHalf / 4,
                                                  (self.q_g[0], self.q_g[1]))
                    self.m_line = PolyUtils.convexHull(QHitPoly + QGoalPoly)

                    #plot the first overlap
                    if self.PLOT_M_LINE == True:
                        plt.figure(self.overlap_figure)
                        plt.clf()
                        self.plotPoly(QHitPoly, 'k')
                        self.plotPoly(QGoalPoly, 'k')
                        self.plotPoly(overlap, 'g')
                        self.plotPoly(self.m_line, 'b')
                        plt.plot(pose[0], pose[1], 'bo')
                        self.plotPioneer(self.overlap_figure, 0)

                else:  ##head towards the q_goal
                    if self.system == 1:
                        if self.robocomm.getReceiveObs(
                        ) == False:  # wait for obstacles from Pioneer
                            vx = 0
                            vy = 0
                        else:
                            dis_cur = vstack((self.q_g[0], self.q_g[1])) - mat(
                                [pose[0], pose[1]]).T
                            vx = (dis_cur / norm(dis_cur) / 3)[0, 0]
                            vy = (dis_cur / norm(dis_cur) / 3)[1, 0]

                    else:
                        dis_cur = vstack((self.q_g[0], self.q_g[1])) - mat(
                            [pose[0], pose[1]]).T
                        vx = (dis_cur / norm(dis_cur) / 3)[0, 0]
                        vy = (dis_cur / norm(dis_cur) / 3)[1, 0]
                        #print "no obstacles 2-ODE true"

            else:  ##head towards the q_goal
                if self.system == 1:
                    if self.robocomm.getReceiveObs(
                    ) == False:  # wait for obstacles from Pioneer
                        vx = 0
                        vy = 0
                    else:
                        dis_cur = vstack((self.q_g[0], self.q_g[1])) - mat(
                            [pose[0], pose[1]]).T
                        vx = (dis_cur / norm(dis_cur) / 3)[0, 0]
                        vy = (dis_cur / norm(dis_cur) / 3)[1, 0]

                else:
                    dis_cur = vstack(
                        (self.q_g[0], self.q_g[1])) - mat([pose[0], pose[1]]).T
                    vx = (dis_cur / norm(dis_cur) / 3)[0, 0]
                    vy = (dis_cur / norm(dis_cur) / 3)[1, 0]
                    #print "no obstacles 1-ODE true"

        if self.boundary_following == True:
            self.q_hit_count += 1
            # finding the point to go normal to (closest overlapping point)

            j = 0
            recheck = 0
            while not bool(overlap):
                # cannot see the obstacle. Based on the location of the previous point blow up the range of the robot on the left or on the right
                j += 1

                # finding whether the previous obstacle point is on the left side or the right side of the robot
                # angle = angle of the previous point from the x-axis of the field
                # omega = angle of the current Pioneer orientation from the x-axis of the field
                # cc    = differnece between angle and omega ( < pi = previous point on the left of robot, else on the right of robot)
                x = self.prev_follow[0] - pose[0]
                y = self.prev_follow[1] - pose[1]
                angle = atan(y / x)

                # convert angle to 2pi
                if x > 0 and y > 0:
                    angle = angle
                elif x < 0 and y > 0:
                    angle = pi + angle
                elif x < 0 and y < 0:
                    angle = pi + angle
                else:
                    angle = 2 * pi + angle

                # convert pose to 2pi
                if pose[2] < 0:
                    omega = (2 * pi + pose[2])
                else:
                    omega = pose[2]

                if omega > angle:
                    cc = 2 * pi - (omega - angle)
                else:
                    cc = angle - omega

                # on the left
                #if angle - omega > 0 and angle - omega < pi:
                if cc < pi:
                    #print "on the left, angle: "+ str(angle) + " omega: "+ str(omega)+ " angle-omega: "+ str(angle-omega)
                    Robot = PolyShapes.Rectangle(self.range * 2 * j,
                                                 self.range * 2 * j)
                    Robot.shift(pose[0] - self.range * j * 2,
                                pose[1] - self.range * j)
                    Robot.rotate(pose[2] - pi / 2, pose[0], pose[1])

                # on the right
                else:
                    #print "on the right, angle: "+ str(angle) + " omega: "+ str(omega)+ " angle-omega: "+ str(angle-omega)
                    Robot = PolyShapes.Rectangle(self.range * 2 * j,
                                                 self.range * 2 * j)
                    Robot.shift(pose[0], pose[1] - self.range * j)
                    Robot.rotate(pose[2] - pi / 2, pose[0], pose[1])

                if self.system == 1:
                    overlap = Robot - (self.map_work -
                                       self.robocomm.getObsPoly())
                else:
                    overlap = Robot - (self.map_work)

                #self.plotPoly(Robot, 'm',2)
                #determines as dynamic obstacles and can be go striaight to the goal point
                if j >= 2:
                    dis_cur = vstack(
                        (self.q_g[0], self.q_g[1])) - mat([pose[0], pose[1]]).T
                    vx = (dis_cur / norm(dis_cur) / 3)[0, 0]
                    vy = (dis_cur / norm(dis_cur) / 3)[1, 0]
                    overlap = None
                    self.overlap = overlap
                    self.q_hit_count = 0
                    self.boundary_following = False
                    self.m_line = None
                    self.drive_handler.setVelocity(vx, vy, pose[2])
                    RobotPoly = PolyShapes.Circle(self.PioneerLengthHalf +
                                                  0.06,
                                                  (pose[0], pose[1]))  ###0.05
                    departed = not self.currentRegionPoly.overlaps(
                        self.realRobot)
                    #departed = not self.currentRegionPoly.overlaps(self.realRobot) and (not (self.nextRegionPoly.overlaps(self.realRobot) and not self.nextRegionPoly.covers(self.realRobot)))
                    arrived = self.nextRegionPoly.covers(self.realRobot)
                    return arrived

            ##extra box plotting in figure 1#
            if self.PLOT_OVERLAP == True:
                plt.figure(self.original_figure)
                plt.clf()
                self.plotPoly(self.realRobot, 'r')
                self.plotPoly(self.robot, 'b')
                self.plotPoly(overlap, 'g', 3)
                plt.plot(pose[0], pose[1], 'bo')
                self.plotPioneer(self.original_figure)

            # find the closest point on the obstacle to the robot
            overlap_len = len(overlap)
            for j in range(overlap_len):
                BoundPolyPoints = asarray(overlap[j])
                for i in range(len(BoundPolyPoints) - 1):
                    bundle_x = (
                        BoundPolyPoints[i, 0] +
                        BoundPolyPoints[1 + i, 0]) / 2  #mid-point coordinate x
                    bundle_y = (
                        BoundPolyPoints[i, 1] +
                        BoundPolyPoints[1 + i, 1]) / 2  #mid-point coordinate y
                    q_overlap = hstack((q_overlap, vstack(
                        (bundle_x, bundle_y))))
                bundle_x = (BoundPolyPoints[len(BoundPolyPoints) - 1, 0] +
                            BoundPolyPoints[0, 0]) / 2  #mid-point coordinate x
                bundle_y = (BoundPolyPoints[len(BoundPolyPoints) - 1, 1] +
                            BoundPolyPoints[0, 1]) / 2  #mid-point coordinate y
                q_overlap = hstack((q_overlap, vstack((bundle_x, bundle_y))))
            q_overlap = q_overlap.transpose()
            pt = self.closest_pt([pose[0], pose[1]],
                                 vstack(
                                     (q_overlap,
                                      asarray(PolyUtils.pointList(overlap)))))
            self.prev_follow = pt

            #calculate the vector to follow the obstacle
            normal = mat([pose[0], pose[1]] - pt)

            #find the distance from the closest point
            distance = norm(normal)
            velocity = normal * self.trans_matrix
            vx = (velocity / norm(velocity) / 3)[0, 0]
            vy = (velocity / norm(velocity) / 3)[0, 1]

            # push or pull the robot towards the obstacle depending on whether the robot is close or far from the obstacle.
            turn = pi / 4 * (distance - 0.5 * self.obsRange) / (
                self.obsRange
            )  ### change to 0.6 from 0.5 for more allowance in following
            corr_matrix = mat([[cos(turn), -sin(turn)], [sin(turn),
                                                         cos(turn)]])
            v = corr_matrix * mat([[vx], [vy]])
            vx = v[0, 0]
            vy = v[1, 0]

            ##plotting overlap on figure 2
            if self.PLOT_OVERLAP == True:
                plt.figure(self.overlap_figure)
                plt.clf()
                self.plotPoly(self.m_line, 'b')
                self.plotPoly(overlap, 'r')
                plt.plot(pt[0], pt[1], 'ro')
                plt.plot(pose[0], pose[1], 'bo')
                self.plotPioneer(self.overlap_figure, 0)

            ## conditions that the loop will end
            #for 11111
            RobotPoly = PolyShapes.Circle(self.PioneerLengthHalf + 0.06,
                                          (pose[0], pose[1]))  ####0.05
            departed = not self.currentRegionPoly.overlaps(self.realRobot)
            #departed = not self.currentRegionPoly.overlaps(self.realRobot) and (not (self.nextRegionPoly.overlaps(self.realRobot) and not self.nextRegionPoly.covers(self.realRobot)))
            arrived = self.nextRegionPoly.covers(self.realRobot)

            #for 33333
            reachMLine = self.m_line.overlaps(RobotPoly)

            # 1.reached the next region
            if arrived:
                self.boundary_following = False
                self.m_line = None
                self.q_hit_count = 0
                print "arriving at the next region. Exit boundary following mode"
                vx = 0
                vy = 0
                """
                # 2.q_hit is reencountered
                elif norm(self.q_hit-mat([pose[0],pose[1]]).T) < 0.05 and self.q_hit_count > self.q_hit_Thres:
                    print "reencounter q_hit. cannot reach q_goal"
                    vx = 0
                    vy = 0
                """

            # 3.m-line reencountered
            elif reachMLine:
                #print >>sys.__stdout__, "m-line overlaps RoboPoly, m-line" + str(norm(self.q_g-self.q_hit)-2*self.obsRange) + " distance: " + str(norm(self.q_g-mat([pose[0],pose[1]]).T))
                if norm(self.q_g - mat([pose[0], pose[1]]).T
                        ) < norm(self.q_g - self.q_hit) - 2 * self.obsRange:
                    #print "m-line overlaps RoboPoly, m-line" + str(norm(self.q_g-self.q_hit)-2*self.obsRange) + " distance: " + str(norm(self.q_g-mat([pose[0],pose[1]]).T))
                    #print "leaving boundary following mode"
                    self.boundary_following = False
                    self.m_line = None
                    self.q_hit_count = 0
                    leaving = False

                    # turn the robot till it is facing the goal
                    while not leaving:
                        x = self.q_g[0] - self.pose_handler.getPose()[0]
                        y = self.q_g[1] - self.pose_handler.getPose()[1]
                        angle = atan(y / x)
                        if x > 0 and y > 0:
                            angle = angle
                        elif x < 0 and y > 0:
                            angle = pi + angle
                        elif x < 0 and y < 0:
                            angle = pi + angle
                        else:
                            angle = 2 * pi + angle

                        if self.pose_handler.getPose()[2] < 0:
                            omega = (2 * pi + self.pose_handler.getPose()[2])
                            #print >>sys.__stdout__,"omega<0: "+ str(omega)
                        else:
                            omega = self.pose_handler.getPose()[2]
                            #print >>sys.__stdout__,"omega: "+ str(omega)

                        if omega > angle:
                            cc = 2 * pi - (omega - angle)
                        else:
                            cc = angle - omega

                        # angle(goal point orientation) on the left of omega(robot orientation)
                        #if angle - omega > 0 and angle - omega < pi:
                        if cc < pi:
                            #print>>sys.__stdout__, "turn left"
                            vx, vy = self.turnLeft(cc)

                        # on the right
                        else:
                            #print>>sys.__stdout__, "turn right"
                            vx, vy = self.turnRight(2 * pi - cc)

                        #print>>sys.__stdout__, "omega: "+ str(omega) + " angle: "+ str(angle) + " (omega-angle): " + str(omega-angle)
                        self.drive_handler.setVelocity(
                            vx, vy,
                            self.pose_handler.getPose()[2])

                        if omega - angle < pi / 6 and omega - angle > -pi / 6:
                            leaving = True

            #Check whether the robot can leave now (the robot has to be closer to the goal than when it is at q_hit to leave)
            QGoalPoly = PolyShapes.Circle(self.PioneerLengthHalf,
                                          (self.q_g[0], self.q_g[1]))
            path = PolyUtils.convexHull(self.realRobot + QGoalPoly)
            if self.system == 1:
                if self.robocomm.getReceiveObs() == False:
                    pathOverlap = path - (self.map_work)
                else:
                    pathOverlap = path - (self.map_work -
                                          self.robocomm.getObsPoly())
            else:
                pathOverlap = path - (self.map_work)

            if not bool(pathOverlap):
                #print "There is NO MORE obstacles in front for now."

                # check if the robot is closer to the goal compared with q_hit
                if norm(self.q_hit - mat(self.q_g).T) > norm(
                        mat([pose[0], pose[1]]).T - mat(self.q_g).T):
                    #print "The robot is closer than the leaving point. The robot can leave"
                    self.boundary_following = False
                    self.m_line = None
                    self.q_hit_count = 0
                    dis_cur = vstack(
                        (self.q_g[0], self.q_g[1])) - mat([pose[0], pose[1]]).T
                    vx = (dis_cur / norm(dis_cur) / 3)[0, 0]
                    vy = (dis_cur / norm(dis_cur) / 3)[1, 0]
                else:
                    lala = 1
                    #print "not leaving bug algorithm. difference(-farther) =" + str(norm(self.q_hit-mat(self.q_g).T) - norm(mat([pose[0],pose[1]]).T-mat(self.q_g).T))
        """
        # Pass this desired velocity on to the drive handler
        # Check if there are obstacles within 0.35m of the robot, if so, stop the robot
        if self.system == 1:
            if self.robocomm.getSTOP() == True:
                vx = 0
                vy = 0
        """
        #vx = 0
        #vy = 0
        self.overlap = overlap
        self.drive_handler.setVelocity(vx, vy, pose[2])

        # Set the current region as the previous current region(for checking whether the robot has arrived at the next region)
        self.previous_current_reg = current_reg

        # check whether robot has arrived at the next region
        RobotPoly = PolyShapes.Circle(self.PioneerLengthHalf + 0.06,
                                      (pose[0], pose[1]))  ###0.05
        #departed = not self.currentRegionPoly.overlaps(self.realRobot) and (not (self.nextRegionPoly.overlaps(self.realRobot) and not self.nextRegionPoly.covers(self.realRobot)))
        departed = not self.currentRegionPoly.overlaps(self.realRobot)
        arrived = self.nextRegionPoly.covers(self.realRobot)
        if arrived:
            self.q_hit_count = 0
            self.boundary_following = False
            self.m_line = None

        if departed and (
                not arrived) and (time.time() - self.last_warning) > 0.5:
            print "WARNING: Left current region but not in expected destination region"
            # Figure out what region we think we stumbled into
            for r in self.proj.rfi.regions:
                pointArray = [self.coordmap_map2lab(x) for x in r.getPoints()]
                vertices = mat(pointArray).T

                if is_inside([pose[0], pose[1]], vertices):
                    #print "I think I'm in " + r.name
                    #print pose
                    break
            self.last_warning = time.time()

        return arrived
示例#10
0
    def gotoRegion(self, current_reg, next_reg, last=False):

        """
        If ``last`` is True, we will move to the center of the destination region.
        Returns ``True`` if we've reached the destination region.
        """
        q_gBundle              = [[],[]]          # goal bundle
        q_overlap              = [[],[]]          # overlapping points with robot range
        pose = self.pose_handler.getPose()        # Find our current configuration

        #Plot the robot on the map in figure 1
        if self.PLOT == True:
            plt.figure(self.original_figure)
            plt.clf()
            self.plotPoly(self.realRobot, 'r')
            self.plotPoly(self.robot, 'b')
            plt.plot(pose[0],pose[1],'bo')
            self.plotPioneer(self.original_figure)


        if current_reg == next_reg and not last:
            # No need to move!
            self.drive_handler.setVelocity(0, 0)  # So let's stop
            return False

        # Check if Vicon has cut out
        if math.isnan(pose[2]):
            print "no vicon pose"
            print "WARNING: No Vicon data! Pausing."
            #self.drive_handler.setVelocity(0, 0)  # So let's stop
            time.sleep(1)
            return False

        ###This part is run when the robot goes to a new region, otherwise, the original map will be used.
        if not self.previous_current_reg == current_reg:
            #print 'getting into bug alogorithm'

            #clean up the previous self.map_work
            self.map_work =  Polygon.Polygon()

            # NOTE: Information about region geometry can be found in self.proj.rfi.regions
            # create polygon list for regions other than the current_reg and the next_reg
            self.map_work += self.map[self.proj.rfi.regions[current_reg].name]
            self.map_work += self.map[self.proj.rfi.regions[next_reg].name]

            # building current polygon and destination polygon
            self.nextRegionPoly    = self.map[self.proj.rfi.regions[next_reg].name]
            self.currentRegionPoly = self.map[self.proj.rfi.regions[current_reg].name]

            #set to zero velocity before finding the tranFace
            self.drive_handler.setVelocity(0, 0)
            if last:
                transFace = None
            else:
                print "Current reg is " + str(self.proj.rfi.regions[current_reg].name.lower())
                print "Next reg is "+ str(self.proj.rfi.regions[next_reg].name.lower())


                for i in range(len(self.proj.rfi.transitions[current_reg][next_reg])):
                    pointArray_transface = [x for x in self.proj.rfi.transitions[current_reg][next_reg][i]]
                    transFace = asarray(map(self.coordmap_map2lab,pointArray_transface))
                    bundle_x = (transFace[0,0] +transFace[1,0])/2    #mid-point coordinate x
                    bundle_y = (transFace[0,1] +transFace[1,1])/2    #mid-point coordinate y
                    q_gBundle = hstack((q_gBundle,vstack((bundle_x,bundle_y))))
                q_gBundle = q_gBundle.transpose()

                # Find the closest face to the current position
                max_magsq = 1000000
                for tf in q_gBundle:
                    magsq = (tf[0] - pose[0])**2 + (tf[1] - pose[1])**2
                    if magsq < max_magsq:
                        connection = 0
                        tf = tf+(tf-asarray(self.currentRegionPoly.center()))/norm(tf-asarray(self.currentRegionPoly.center()))*2.1*self.PioneerLengthHalf
                        if not self.nextRegionPoly.covers(PolyShapes.Circle(self.PioneerLengthHalf*2,(tf[0],tf[1]))):
                            tf = tf-(tf-asarray(self.currentRegionPoly.center()))/norm(tf-asarray(self.currentRegionPoly.center()))*4.2*self.PioneerLengthHalf
                            if self.nextRegionPoly.covers(PolyShapes.Circle(self.PioneerLengthHalf*2,(tf[0],tf[1]))):
                                connection = 1
                        else:
                            connection = 1
                        if connection == 1:
                            pt1  = tf
                            max_magsq = magsq
                            transFace = 1
                            self.q_g[0] = pt1[0]
                            self.q_g[1] = pt1[1]
                        else:
                            sample = False
                            while not sample:
                                self.q_g[0],self.q_g[1] = self.nextRegionPoly.sample(random.random)
                                robo = PolyShapes.Circle(self.PioneerLengthHalf,(self.q_g[0],self.q_g[1]))
                                if not bool(robo - self.nextRegionPoly):
                                    sample = True


                """
                # Push the goal point to somewhere inside the next region to ensure the robot will get there.(CHECK!!)
                self.q_g = self.q_g+(self.q_g-asarray(self.currentRegionPoly.center()))/norm(self.q_g-asarray(self.currentRegionPoly.center()))*3*self.PioneerLengthHalf
                if not self.nextRegionPoly.isInside(self.q_g[0],self.q_g[1]):
                    self.q_g = self.q_g-(self.q_g-asarray(self.currentRegionPoly.center()))/norm(self.q_g-asarray(self.currentRegionPoly.center()))*6*self.PioneerLengthHalf
                """

                #plot exiting point
                if self.PLOT_EXIT == True:
                    plt.figure(self.overlap_figure)
                    plt.clf()
                    plt.plot(q_gBundle[:,0],q_gBundle[:,1],'ko' )
                    plt.plot(self.q_g[0],self.q_g[1],'ro')
                    plt.plot(pose[0],pose[1],'bo')
                    self.plotPioneer(self.overlap_figure,0)

                if transFace is None:
                    print "ERROR: Unable to find transition face between regions %s and %s.  Please check the decomposition (try viewing projectname_decomposed.regions in RegionEditor or a text editor)." % (self.proj.rfi.regions[current_reg].name, self.proj.rfi.regions[next_reg].name)


        ##################################################
        #######check whether obstacle is detected#########
        ##################################################

        #Update pose,update self.robot, self.realRobot orientation
        self.robot.shift(pose[0]-self.prev_pose[0],pose[1]-self.prev_pose[1])
        self.realRobot.shift(pose[0]-self.prev_pose[0],pose[1]-self.prev_pose[1])
        self.robot.rotate(pose[2]-self.prev_pose[2],pose[0],pose[1])
        self.realRobot.rotate(pose[2]-self.prev_pose[2],pose[0],pose[1])
        self.prev_pose = pose

        ############################
        ########### STEP 1##########
        ############################
        ##Check whether obsRange overlaps with obstacle or the boundary (overlap returns the part of robot not covered by the region

        # for real Pioneer robot
        if self.system == 1:
            # motion controller is not in boundary following mode
            if self.boundary_following == False:

                if self.robocomm.getReceiveObs() == False:
                    overlap = self.robot - ( self.map_work)
                else:
                    overlap = self.robot  - ( self.map_work - self.robocomm.getObsPoly())

            else: #TRUE
                # use a robot with full range all around it
                Robot = PolyShapes.Circle(self.obsRange,(pose[0],pose[1]))
                Robot.shift(self.shift*cos(pose[2]),self.shift*sin(pose[2]))

                if self.robocomm.getReceiveObs() == False:
                    overlap = Robot - ( self.map_work)
                else:
                    overlap = Robot  - ( self.map_work - self.robocomm.getObsPoly())
        # for ODE
        else:
            if self.boundary_following == False:
                overlap = self.robot  - (self.map_work)
            else:#TRUE
                overlap = self.robot  - (self.map_work)

        if self.boundary_following == False:
            if bool(overlap):    ## overlap of obstacles
                #print "There MAYBE overlap~~ check connection to goal"

                # check whether the real robot or and path to goal overlap with the obstacle
                QGoalPoly= PolyShapes.Circle(self.PioneerLengthHalf,(self.q_g[0],self.q_g[1]))
                path  = PolyUtils.convexHull(self.realRobot + QGoalPoly)
                if self.system == 1:
                    if self.robocomm.getReceiveObs() == False:
                        pathOverlap = path - ( self.map_work)
                    else:
                        pathOverlap = path  - ( self.map_work - self.robocomm.getObsPoly())
                else:
                    pathOverlap = path - ( self.map_work)


                if bool(pathOverlap):   # there is overlapping, go into bounding following mode
                    #print "There IS overlap"
                    self.q_hit  = mat([pose[0],pose[1]]).T
                    self.boundary_following = True

                    #Generate m-line polygon
                    QHitPoly = PolyShapes.Circle(self.PioneerLengthHalf/4,(pose[0],pose[1]))
                    QGoalPoly= PolyShapes.Circle(self.PioneerLengthHalf/4,(self.q_g[0],self.q_g[1]))
                    self.m_line  = PolyUtils.convexHull(QHitPoly + QGoalPoly)

                    #plot the first overlap
                    if self.PLOT_M_LINE == True:
                        plt.figure(self.overlap_figure)
                        plt.clf()
                        self.plotPoly(QHitPoly,'k')
                        self.plotPoly(QGoalPoly,'k')
                        self.plotPoly(overlap,'g')
                        self.plotPoly(self.m_line,'b')
                        plt.plot(pose[0],pose[1],'bo')
                        self.plotPioneer(self.overlap_figure,0)


                else:                ##head towards the q_goal
                    if self.system == 1:
                        if self.robocomm.getReceiveObs() == False:   # wait for obstacles from Pioneer
                            vx = 0
                            vy = 0
                        else:
                            dis_cur  = vstack((self.q_g[0],self.q_g[1]))- mat([pose[0],pose[1]]).T
                            vx = (dis_cur/norm(dis_cur)/3)[0,0]
                            vy = (dis_cur/norm(dis_cur)/3)[1,0]

                    else:
                        dis_cur  = vstack((self.q_g[0],self.q_g[1]))- mat([pose[0],pose[1]]).T
                        vx = (dis_cur/norm(dis_cur)/3)[0,0]
                        vy = (dis_cur/norm(dis_cur)/3)[1,0]
                        #print "no obstacles 2-ODE true"

            else:                ##head towards the q_goal
                    if self.system == 1:
                        if self.robocomm.getReceiveObs() == False:   # wait for obstacles from Pioneer
                            vx = 0
                            vy = 0
                        else:
                            dis_cur  = vstack((self.q_g[0],self.q_g[1]))- mat([pose[0],pose[1]]).T
                            vx = (dis_cur/norm(dis_cur)/3)[0,0]
                            vy = (dis_cur/norm(dis_cur)/3)[1,0]

                    else:
                        dis_cur  = vstack((self.q_g[0],self.q_g[1]))- mat([pose[0],pose[1]]).T
                        vx = (dis_cur/norm(dis_cur)/3)[0,0]
                        vy = (dis_cur/norm(dis_cur)/3)[1,0]
                        #print "no obstacles 1-ODE true"

        if self.boundary_following == True:
            self.q_hit_count       += 1
            # finding the point to go normal to (closest overlapping point)

            j = 0
            recheck = 0
            while not bool(overlap):
                # cannot see the obstacle. Based on the location of the previous point blow up the range of the robot on the left or on the right
                j += 1

                # finding whether the previous obstacle point is on the left side or the right side of the robot
                # angle = angle of the previous point from the x-axis of the field
                # omega = angle of the current Pioneer orientation from the x-axis of the field
                # cc    = differnece between angle and omega ( < pi = previous point on the left of robot, else on the right of robot)
                x = self.prev_follow[0] -pose[0]
                y = self.prev_follow[1] -pose[1]
                angle = atan(y/x)

                # convert angle to 2pi
                if x > 0 and y > 0:
                    angle = angle
                elif x < 0 and y > 0:
                    angle = pi + angle
                elif x <0 and y < 0:
                    angle = pi + angle
                else:
                    angle = 2*pi + angle

                # convert pose to 2pi
                if pose[2] < 0:
                    omega = (2*pi + pose[2])
                else:
                    omega = pose[2]


                if omega > angle:
                    cc = 2*pi - (omega - angle)
                else:
                    cc = angle - omega

                # on the left
                #if angle - omega > 0 and angle - omega < pi:
                if cc < pi:
                    #print "on the left, angle: "+ str(angle) + " omega: "+ str(omega)+ " angle-omega: "+ str(angle-omega)
                    Robot = PolyShapes.Rectangle(self.range*2*j,self.range*2*j)
                    Robot.shift(pose[0]-self.range*j*2,pose[1]-self.range*j)
                    Robot.rotate(pose[2]-pi/2,pose[0],pose[1])

                # on the right
                else:
                    #print "on the right, angle: "+ str(angle) + " omega: "+ str(omega)+ " angle-omega: "+ str(angle-omega)
                    Robot = PolyShapes.Rectangle(self.range*2*j,self.range*2*j)
                    Robot.shift(pose[0],pose[1]-self.range*j)
                    Robot.rotate(pose[2]-pi/2,pose[0],pose[1])

                if self.system == 1:
                    overlap = Robot - ( self.map_work - self.robocomm.getObsPoly())
                else:
                    overlap = Robot - ( self.map_work)

                #self.plotPoly(Robot, 'm',2)
                #determines as dynamic obstacles and can be go striaight to the goal point
                if j >= 2:
                    dis_cur  = vstack((self.q_g[0],self.q_g[1]))- mat([pose[0],pose[1]]).T
                    vx = (dis_cur/norm(dis_cur)/3)[0,0]
                    vy = (dis_cur/norm(dis_cur)/3)[1,0]
                    overlap = None
                    self.overlap = overlap
                    self.q_hit_count        = 0
                    self.boundary_following = False
                    self.m_line             = None
                    self.drive_handler.setVelocity(vx,vy, pose[2])
                    RobotPoly = PolyShapes.Circle(self.PioneerLengthHalf+0.06,(pose[0],pose[1]))     ###0.05
                    departed = not self.currentRegionPoly.overlaps(self.realRobot)
                    #departed = not self.currentRegionPoly.overlaps(self.realRobot) and (not (self.nextRegionPoly.overlaps(self.realRobot) and not self.nextRegionPoly.covers(self.realRobot)))
                    arrived  = self.nextRegionPoly.covers(self.realRobot)
                    return arrived




            ##extra box plotting in figure 1#
            if self.PLOT_OVERLAP == True:
                plt.figure(self.original_figure)
                plt.clf()
                self.plotPoly(self.realRobot, 'r')
                self.plotPoly(self.robot, 'b')
                self.plotPoly(overlap,'g',3)
                plt.plot(pose[0],pose[1],'bo')
                self.plotPioneer(self.original_figure)

            # find the closest point on the obstacle to the robot
            overlap_len = len(overlap)
            for j in range(overlap_len):
                BoundPolyPoints = asarray(overlap[j])
                for i in range(len(BoundPolyPoints)-1):
                    bundle_x = (BoundPolyPoints[i,0] +BoundPolyPoints[1+i,0])/2    #mid-point coordinate x
                    bundle_y = (BoundPolyPoints[i,1] +BoundPolyPoints[1+i,1])/2    #mid-point coordinate y
                    q_overlap = hstack((q_overlap,vstack((bundle_x,bundle_y))))
                bundle_x = (BoundPolyPoints[len(BoundPolyPoints)-1,0] +BoundPolyPoints[0,0])/2    #mid-point coordinate x
                bundle_y = (BoundPolyPoints[len(BoundPolyPoints)-1,1] +BoundPolyPoints[0,1])/2    #mid-point coordinate y
                q_overlap = hstack((q_overlap,vstack((bundle_x,bundle_y))))
            q_overlap = q_overlap.transpose()
            pt =  self.closest_pt([pose[0],pose[1]], vstack((q_overlap,asarray(PolyUtils.pointList(overlap)))))
            self.prev_follow = pt

            #calculate the vector to follow the obstacle
            normal = mat([pose[0],pose[1]] - pt)

            #find the distance from the closest point
            distance = norm(normal)
            velocity = normal * self.trans_matrix
            vx = (velocity/norm(velocity)/3)[0,0]
            vy = (velocity/norm(velocity)/3)[0,1]

            # push or pull the robot towards the obstacle depending on whether the robot is close or far from the obstacle.
            turn = pi/4*(distance-0.5*self.obsRange)/(self.obsRange)    ### change to 0.6 from 0.5 for more allowance in following
            corr_matrix       = mat([[cos(turn),-sin(turn)],[sin(turn),cos(turn)]])
            v =  corr_matrix*mat([[vx],[vy]])
            vx = v[0,0]
            vy = v[1,0]


            ##plotting overlap on figure 2
            if self.PLOT_OVERLAP == True:
                plt.figure(self.overlap_figure)
                plt.clf()
                self.plotPoly(self.m_line,'b');
                self.plotPoly(overlap,'r');
                plt.plot(pt[0],pt[1],'ro')
                plt.plot(pose[0],pose[1],'bo')
                self.plotPioneer(self.overlap_figure,0)


            ## conditions that the loop will end
            #for 11111
            RobotPoly = PolyShapes.Circle(self.PioneerLengthHalf+0.06,(pose[0],pose[1]))   ####0.05
            departed = not self.currentRegionPoly.overlaps(self.realRobot)
            #departed = not self.currentRegionPoly.overlaps(self.realRobot) and (not (self.nextRegionPoly.overlaps(self.realRobot) and not self.nextRegionPoly.covers(self.realRobot)))
            arrived  = self.nextRegionPoly.covers(self.realRobot)

            #for 33333
            reachMLine= self.m_line.overlaps(RobotPoly)

            # 1.reached the next region
            if arrived:
                self.boundary_following = False
                self.m_line             = None
                self.q_hit_count       = 0
                print "arriving at the next region. Exit boundary following mode"
                vx = 0
                vy = 0

                """
                # 2.q_hit is reencountered
                elif norm(self.q_hit-mat([pose[0],pose[1]]).T) < 0.05 and self.q_hit_count > self.q_hit_Thres:
                    print "reencounter q_hit. cannot reach q_goal"
                    vx = 0
                    vy = 0
                """

            # 3.m-line reencountered
            elif reachMLine:
                #print >>sys.__stdout__, "m-line overlaps RoboPoly, m-line" + str(norm(self.q_g-self.q_hit)-2*self.obsRange) + " distance: " + str(norm(self.q_g-mat([pose[0],pose[1]]).T))
                if norm(self.q_g-mat([pose[0],pose[1]]).T) < norm(self.q_g-self.q_hit)-2*self.obsRange:
                    #print "m-line overlaps RoboPoly, m-line" + str(norm(self.q_g-self.q_hit)-2*self.obsRange) + " distance: " + str(norm(self.q_g-mat([pose[0],pose[1]]).T))
                    #print "leaving boundary following mode"
                    self.boundary_following = False
                    self.m_line             = None
                    self.q_hit_count       = 0
                    leaving                = False

                    # turn the robot till it is facing the goal
                    while not leaving:
                        x = self.q_g[0] -self.pose_handler.getPose()[0]
                        y = self.q_g[1] -self.pose_handler.getPose()[1]
                        angle = atan(y/x)
                        if x > 0 and y > 0:
                            angle = angle
                        elif x < 0 and y > 0:
                            angle = pi + angle
                        elif x <0 and y < 0:
                            angle = pi + angle
                        else:
                            angle = 2*pi + angle


                        if self.pose_handler.getPose()[2] < 0:
                            omega = (2*pi + self.pose_handler.getPose()[2])
                            #print >>sys.__stdout__,"omega<0: "+ str(omega)
                        else:
                            omega = self.pose_handler.getPose()[2]
                            #print >>sys.__stdout__,"omega: "+ str(omega)


                        if omega > angle:
                            cc = 2*pi - (omega - angle)
                        else:
                            cc = angle - omega

                        # angle(goal point orientation) on the left of omega(robot orientation)
                        #if angle - omega > 0 and angle - omega < pi:
                        if cc < pi:
                            #print>>sys.__stdout__, "turn left"
                            vx,vy = self.turnLeft(cc)

                        # on the right
                        else:
                            #print>>sys.__stdout__, "turn right"
                            vx, vy = self.turnRight(2*pi-cc)

                        #print>>sys.__stdout__, "omega: "+ str(omega) + " angle: "+ str(angle) + " (omega-angle): " + str(omega-angle)
                        self.drive_handler.setVelocity(vx,vy, self.pose_handler.getPose()[2])

                        if omega - angle < pi/6 and omega - angle > -pi/6:
                            leaving = True

            #Check whether the robot can leave now (the robot has to be closer to the goal than when it is at q_hit to leave)
            QGoalPoly= PolyShapes.Circle(self.PioneerLengthHalf,(self.q_g[0],self.q_g[1]))
            path  = PolyUtils.convexHull(self.realRobot + QGoalPoly)
            if self.system == 1:
                if self.robocomm.getReceiveObs() == False:
                    pathOverlap = path - ( self.map_work)
                else:
                    pathOverlap = path  - ( self.map_work - self.robocomm.getObsPoly())
            else:
                pathOverlap = path - ( self.map_work)

            if not bool(pathOverlap):
                #print "There is NO MORE obstacles in front for now."

                # check if the robot is closer to the goal compared with q_hit
                if norm(self.q_hit-mat(self.q_g).T) > norm(mat([pose[0],pose[1]]).T-mat(self.q_g).T) :
                    #print "The robot is closer than the leaving point. The robot can leave"
                    self.boundary_following = False
                    self.m_line             = None
                    self.q_hit_count       = 0
                    dis_cur  = vstack((self.q_g[0],self.q_g[1]))- mat([pose[0],pose[1]]).T
                    vx = (dis_cur/norm(dis_cur)/3)[0,0]
                    vy = (dis_cur/norm(dis_cur)/3)[1,0]
                else:
                    lala = 1
                    #print "not leaving bug algorithm. difference(-farther) =" + str(norm(self.q_hit-mat(self.q_g).T) - norm(mat([pose[0],pose[1]]).T-mat(self.q_g).T))

        """
        # Pass this desired velocity on to the drive handler
        # Check if there are obstacles within 0.35m of the robot, if so, stop the robot
        if self.system == 1:
            if self.robocomm.getSTOP() == True:
                vx = 0
                vy = 0
        """
        #vx = 0
        #vy = 0
        self.overlap = overlap
        self.drive_handler.setVelocity(vx,vy, pose[2])


        # Set the current region as the previous current region(for checking whether the robot has arrived at the next region)
        self.previous_current_reg = current_reg


        # check whether robot has arrived at the next region
        RobotPoly = PolyShapes.Circle(self.PioneerLengthHalf+0.06,(pose[0],pose[1]))     ###0.05
        #departed = not self.currentRegionPoly.overlaps(self.realRobot) and (not (self.nextRegionPoly.overlaps(self.realRobot) and not self.nextRegionPoly.covers(self.realRobot)))
        departed = not self.currentRegionPoly.overlaps(self.realRobot)
        arrived  = self.nextRegionPoly.covers(self.realRobot)
        if arrived:
            self.q_hit_count        = 0
            self.boundary_following = False
            self.m_line             = None

        if departed and (not arrived) and (time.time()-self.last_warning) > 0.5:
            print "WARNING: Left current region but not in expected destination region"
            # Figure out what region we think we stumbled into
            for r in self.proj.rfi.regions:
                pointArray = [self.coordmap_map2lab(x) for x in r.getPoints()]
                vertices = mat(pointArray).T

                if is_inside([pose[0], pose[1]], vertices):
                    #print "I think I'm in " + r.name
                    #print pose
                    break
            self.last_warning = time.time()

        return arrived
示例#11
0
def buildTree(p,theta,vert, R, system, regionPoly,nextRegionPoly,q_gBundle,\
mappedRegions,allRegions,max_angle_allowed, plotting, operate_system,ax, last=False):
    """
    This function builds the RRT tree
    pose: x,y position of the robot
    theta: current orientation of the robot
    R: radius of the robot
    system: determine step_size and radius for the example
    regionPoly: current region polygon
    nextRegionPoly: next region polygon
    q_gBundle: coordinates of q_goals that the robot can reach
    mappedRegions: region polygons
    allRegions: polygon that includes all the region
    max_angle_allowed: the difference in angle between the two nodes allowed (between 0 to 2*pi)
    plotting: 1 if plotting is enabled, 0- disabled
    operate_system: Which operating system is used for execution. Ubuntu and Mac is 1, Windows is 2
    ax: plot for windows
    """

    max_angle = max_angle_allowed
    """
    if operate_system == 2:
        # start using anmination to plot Pioneer
        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(111)
        self.scope = _Scope(self.ax,self)
        thread.start_new_thread(self.jplot,())
    """

    ## 1: Nao ; 2: STAGE ;  3: ODE
    if system == 1:  ## Nao
        step_size = 0.2  #set the step_size for points be 1/5 of the norm from   ORIGINAL = 0.4
    elif system == 2:
        step_size = 0.5
    elif system == 3:
        step_size = 15

    if system == 1:  ## Nao
        timeStep = 5  #time step for calculation of x, y position
    elif system == 2:
        timeStep = 4  #time step for calculation of x, y position
    elif system == 3:
        timeStep = 10  #time step for calculation of x, y position    #10
    #############tune velocity OMEGA, TIME STEP

    #fix velocity
    ## 1: Nao ; 2: STAGE ;  3: ODE
    if system == 1:  ## Nao
        velocity = 0.05  #set the step_size for points be 1/5 of the norm from
    elif system == 2:
        velocity = 0.06
    elif system == 3:
        velocity = 2  # what is used in RRTControllerHelper.setVelocity    #1.5
    #############tune velocity OMEGA, TIME STEP

    BoundPoly = regionPoly  # Boundary polygon = current region polygon
    radius = R
    q_init = mat(p).T
    V = vstack((0, q_init))
    V_theta = array([theta])
    original_figure = 1

    #!!! CONTROL SPACE: generate a list of omega for random sampling
    omegaLowerBound = -math.pi / 20  # upper bound for the value of omega
    omegaUpperBound = math.pi / 20  # lower bound for the value of omega
    omegaStepSize = 20
    omega_range = linspace(omegaLowerBound, omegaUpperBound, omegaStepSize)
    omega_range_abso = linspace(omegaLowerBound * 4, omegaUpperBound * 4,
                                omegaStepSize *
                                4)  # range used when stuck > stuck_thres
    edgeX = []
    edgeY = []

    # check faces of the current region for goal points

    E = [[], []]
    Other = [[], []]
    path = 0  # if path formed then = 1
    stuck = 0  # count for changing the range of sampling omega
    stuck_thres = 300  # threshold for changing the range of sampling omega

    if not plt.isinteractive():
        plt.ion()
    plt.hold(True)
    while path == 0:
        #step -1: try connection to q_goal (generate path to goal)
        goalCheck = 0
        i = 0

        # pushing possible q_goals into the current region (ensure path is covered by the current region polygon)
        q_pass = [[], [], []]
        q_pass_dist = []
        q_gBundle = mat(q_gBundle)
        while i < q_gBundle.shape[1]:  ###not sure about shape
            q_g = q_gBundle[:, i] + (q_gBundle[:, i] - V[1:, (
                shape(V)[1] - 1)]) / norm(q_gBundle[:, i] - V[1:, (
                    shape(V)[1] - 1)]) * radius  ##original 2*radius
            trial = 1
            if not BoundPoly.isInside(q_g[0], q_g[1]):
                trial = 2
                q_g = q_gBundle[:, i] - (q_gBundle[:, i] - V[1:, (
                    shape(V)[1] - 1)]) / norm(q_gBundle[:, i] - V[1:, (
                        shape(V)[1] - 1)]) * radius  ##original 2*radius

            #forming polygon for path checking
            cross_goal = cross(
                vstack((q_g - vstack(
                    (V[1, shape(V)[1] - 1], V[2, shape(V)[1] - 1])), 0)).T,
                hstack((0, 0, 1)))
            cross_goal = cross_goal.T
            move_vector_goal = radius * cross_goal[0:2] / sqrt(
                (cross_goal[0, 0]**2 + cross_goal[1, 0]**2))
            upperEdgeG = hstack((vstack(
                (V[1,
                   shape(V)[1] - 1], V[2, shape(V)[1] - 1])), q_g)) + hstack(
                       (move_vector_goal, move_vector_goal))
            lowerEdgeG = hstack((vstack(
                (V[1,
                   shape(V)[1] - 1], V[2, shape(V)[1] - 1])), q_g)) - hstack(
                       (move_vector_goal, move_vector_goal))
            EdgePolyGoal = Polygon.Polygon(
                (tuple(array(lowerEdgeG[:, 0].T)[0]),
                 tuple(array(upperEdgeG[:, 0].T)[0]),
                 tuple(array(upperEdgeG[:, 1].T)[0]),
                 tuple(array(lowerEdgeG[:, 1].T)[0])))

            dist = norm(q_g - V[1:, shape(V)[1] - 1])
            connect_goal = BoundPoly.covers(
                EdgePolyGoal)  #check coverage of path from new point to goal
            #check connection to goal
            """
            if connect_goal:
                print "connection is true"
                path = 1
                q_pass = hstack((q_pass,vstack((i,q_g))))
                q_pass_dist = hstack((q_pass_dist,dist))
            """

            # compare orientation difference
            thetaPrev = V_theta[shape(V)[1] - 1]
            theta_orientation = abs(
                arctan((q_g[1, 0] - V[2, shape(V)[1] - 1]) /
                       (q_g[0, 0] - V[1, shape(V)[1] - 1])))
            if thetaPrev < 0:
                if q_g[1, 0] > V[2, shape(V)[1] - 1]:
                    if q_g[0, 0] < V[1, shape(V)[1] - 1]:  # second quadrant
                        theta_orientation = -2 * pi + theta_orientation
                    elif q_g[0, 0] > V[1, shape(V)[1] - 1]:  # first quadrant
                        theta_orientation = -pi - theta_orientation
                elif q_g[1, 0] < V[2, shape(V)[1] - 1]:
                    if q_g[0, 0] < V[1, shape(V)[1] - 1]:  #third quadrant
                        theta_orientation = -pi + theta_orientation
                    elif q_g[0, 0] > V[1, shape(V)[1] - 1]:  # foruth quadrant
                        theta_orientation = -theta_orientation
            else:
                if q_g[1, 0] > V[2, shape(V)[1] - 1]:
                    if q_g[0, 0] < V[1, shape(V)[1] - 1]:  # second quadrant
                        theta_orientation = pi - theta_orientation
                    elif q_g[0, 0] > V[1, shape(V)[1] - 1]:  # first quadrant
                        theta_orientation = theta_orientation
                elif q_g[1, 0] < V[2, shape(V)[1] - 1]:
                    if q_g[0, 0] < V[1, shape(V)[1] - 1]:  #third quadrant
                        theta_orientation = pi + theta_orientation
                    elif q_g[0, 0] > V[1, shape(V)[1] - 1]:  # foruth quadrant
                        theta_orientation = 2 * pi - theta_orientation

            ################################## PRINT PLT #################

            if connect_goal:
                if plotting == True:
                    if operate_system == 1:
                        plt.suptitle('Randomly-exploring rapid tree',
                                     fontsize=12)
                        BoundPolyPoints = asarray(
                            PolyUtils.pointList(BoundPoly))
                        plt.plot(BoundPolyPoints[:, 0], BoundPolyPoints[:, 1],
                                 'k')
                        plt.xlabel('x')
                        plt.ylabel('y')
                        if shape(V)[1] <= 2:
                            plt.plot((V[1, shape(V)[1] - 1], q_g[0, 0]),
                                     (V[2, shape(V)[1] - 1], q_g[1, 0]), 'b')
                        else:
                            plt.plot((V[1, E[0, shape(E)[1] - 1]],
                                      V[1, shape(V)[1] - 1], q_g[0, 0]),
                                     (V[2, E[0, shape(E)[1] - 1]],
                                      V[2, shape(V)[1] - 1], q_g[1, 0]), 'b')
                        plt.figure(original_figure).canvas.draw()
                    else:
                        ax.suptitle('Randomly-exploring rapid tree',
                                    fontsize=12)
                        BoundPolyPoints = asarray(
                            PolyUtils.pointList(BoundPoly))
                        ax.plot(BoundPolyPoints[:, 0], BoundPolyPoints[:, 1],
                                'k')
                        ax.xlabel('x')
                        ax.ylabel('y')
                        if shape(V)[1] <= 2:
                            ax.plot((V[1, shape(V)[1] - 1], q_g[0, 0]),
                                    (V[2, shape(V)[1] - 1], q_g[1, 0]), 'b')
                        else:
                            ax.plot((V[1, E[0, shape(E)[1] - 1]],
                                     V[1, shape(V)[1] - 1], q_g[0, 0]),
                                    (V[2, E[0, shape(E)[1] - 1]],
                                     V[2, shape(V)[1] - 1], q_g[1, 0]), 'b')

            if connect_goal and abs(theta_orientation - thetaPrev) < max_angle:
                #if connect_goal and abs(theta_orientation - thetaPrev) < pi/3:
                print "connection is true.Path = 1"
                path = 1
                q_pass = hstack((q_pass, vstack((i, q_g))))
                q_pass_dist = hstack((q_pass_dist, dist))

            i = i + 1

        # connection to goal has established
        if path == 1:
            if shape(q_pass_dist)[0] == 1:
                cols = 0
            else:
                (cols, ) = nonzero(q_pass_dist == min(q_pass_dist))
                cols = asarray(cols)[0]
            q_g = q_pass[1:, cols]  ###Catherine
            q_g = q_g - (q_gBundle[:, q_pass[0, cols]] - V[1:,
                                                           (shape(V)[1] - 1)]
                         ) / norm(q_gBundle[:, q_pass[0, cols]] -
                                  V[1:,
                                    (shape(V)[1] - 1)]) * 3 * radius  #org 3
            if not nextRegionPoly.isInside(q_g[0], q_g[1]):
                q_g = q_g + (q_gBundle[:, q_pass[0, cols]] -
                             V[1:, (shape(V)[1] - 1)]) / norm(
                                 q_gBundle[:, q_pass[0, cols]] -
                                 V[1:, (shape(V)[1] - 1)]) * 6 * radius  #org 3

            if plotting == True:
                if operate_system == 1:
                    plt.plot(q_g[0, 0], q_g[1, 0], 'ko')
                    plt.figure(original_figure).canvas.draw()
                else:
                    ax.plot(q_g[0, 0], q_g[1, 0], 'ko')

            numOfPoint = floor(norm(V[1:, shape(V)[1] - 1] - q_g) / step_size)
            if numOfPoint < 3:
                numOfPoint = 3
            x = linspace(V[1, shape(V)[1] - 1], q_g[0, 0], numOfPoint)
            y = linspace(V[2, shape(V)[1] - 1], q_g[1, 0], numOfPoint)
            for i in range(x.shape[0]):
                if i != 0:
                    V = hstack((V, vstack((shape(V)[1], x[i], y[i]))))
                    E = hstack((E, vstack((shape(V)[1] - 2, shape(V)[1] - 1))))

        # path is not formed, try to append points onto the tree
        if path == 0:
            success = 0  # whether adding a new point is successful
            hit_count = 0  # count for regenerating new edge with the same q_rand
            Icurrent = [
            ]  # to keep track of the index of the closest point to q_n

            while success == 0 and hit_count <= 2:
                if stuck > stuck_thres:
                    omega = random.choice(omega_range_abso)
                else:
                    #!!!! CONTROL SPACE STEP 1 - generate random omega
                    omega = random.choice(omega_range)

                #!!!! CONTROL SPACE STEP 2 - pick a random point on the tree
                tree_index = random.choice(array(V[0])[0])
                xPrev = V[1, tree_index]
                yPrev = V[2, tree_index]
                thetaPrev = V_theta[tree_index]

                j = 1
                #!!!! CONTROL SPACE STEP 3 - Check path of the robot
                path_robot = PolyShapes.Circle(radius, (xPrev, yPrev))
                while j <= timeStep:
                    xOrg = xPrev
                    yOrg = yPrev
                    xPrev = xPrev + velocity / omega * (
                        sin(omega * 1 + thetaPrev) - sin(thetaPrev))
                    yPrev = yPrev - velocity / omega * (
                        cos(omega * 1 + thetaPrev) - cos(thetaPrev))
                    thetaPrev = omega * 1 + thetaPrev
                    path_robot = path_robot + PolyShapes.Circle(
                        radius, (xPrev, yPrev))

                    j = j + 1

                path_all = PolyUtils.convexHull(path_robot)
                in_bound = BoundPoly.covers(path_all)

                # plotting
                plotPoly(path_all, 'r', 1)
                plotMap(original_figure, BoundPoly, allRegions)

                stuck = stuck + 1
                if in_bound:
                    stuck = stuck - 5
                    x = []
                    y = []
                    for k in PolyUtils.pointList(path_all):
                        x = hstack((x, k[0]))
                        y = hstack((y, k[1]))

                    V = hstack((V, vstack((shape(V)[1], xPrev, yPrev))))
                    V_theta = hstack((V_theta, thetaPrev))
                    E = hstack((E, vstack((tree_index, shape(V)[1] - 1))))
                    Other = hstack((Other, vstack((velocity, omega))))
                    ##################### E should add omega and velocity
                    success = 1

    if finish_print == 1:
        print 'Here is the V matrix:', V, 'Here is the E matrix:', E
        print >> sys.__stdout__, 'Here is the V matrix:\n', V, '\nHere is the E matrix:\n', E

    #B: trim to a single path
    single = 0
    while single == 0:
        trim = 0
        for j in range(shape(V)[1] - 3):
            (row, col) = nonzero(E == j + 1)
            if len(col) == 1:
                E = delete(E, col[0], 1)
                trim = 1

        if trim == 0:
            single = 1

    # generate V to be sent to SimGUI to plot
    V_toPass = V[0:, 0]
    E_toPass = [[], []]
    for i in range(shape(E)[1]):
        V_toPass = hstack(
            (V_toPass, vstack((i, V[1, E[1, i - 1]], V[2, E[1, i - 1]]))))
        E_toPass = hstack((E_toPass, vstack((i - 1, i))))

    ####print with matlib
    if plotting == True:
        if operate_system == 1:
            BoundPolyPoints = asarray(PolyUtils.pointList(BoundPoly))
            plt.plot(BoundPolyPoints[:, 0], BoundPolyPoints[:, 1], 'k')
            plt.plot(V[1, :], V[2, :], 'b')
            for i in range(shape(E)[1] - 1):
                plt.text(V[1, E[0, i]],
                         V[2, E[0, i]],
                         V[0, E[0, i]],
                         fontsize=12)
                plt.text(V[1, E[1, i]],
                         V[2, E[1, i]],
                         V[0, E[1, i]],
                         fontsize=12)
            plt.figure(original_figure).canvas.draw()
        else:
            BoundPolyPoints = asarray(PolyUtils.pointList(BoundPoly))
            ax.plot(BoundPolyPoints[:, 0], BoundPolyPoints[:, 1], 'k')
            ax.plot(V[1, :], V[2, :], 'b')
            for i in range(shape(E)[1] - 1):
                ax.text(V[1, E[0, i]],
                        V[2, E[0, i]],
                        V[0, E[0, i]],
                        fontsize=12)
                ax.text(V[1, E[1, i]],
                        V[2, E[1, i]],
                        V[0, E[1, i]],
                        fontsize=12)

    heading = E[0, 0]
    # parse string for RRT printing in GUI (in format: RRT:E[[1,2,3]]:V[[1,2,3]])
    V = array(V)
    V_toPass = array(V_toPass)
    E_toPass = array(E_toPass)
    return V, E, heading, 0, V_toPass, E_toPass
示例#12
0
    def generateNewNode(self,V,V_theta,E,Other,regionPoly,stuck,append_after_latest_node =False):
        """
        Generate a new node on the current tree matrix
        V         : the node matrix
        V_theta   : the orientation matrix
        E         : the tree matrix (or edge matrix)
        Other     : the matrix containing the velocity and angular velocity(omega) information
        regionPoly: the polygon of current region
        stuck     : count on the number of times failed to generate new node
        append_after_latest_node : append new nodes to the latest node (True only if the previous node addition is successful)
        """


        if self.system_print == True:
            print "In control space generating path,stuck = " + str(stuck)

        connection_to_tree = False   # True when connection to the tree is successful

        if stuck > self.stuck_thres:
            # increase the range of omega since path cannot ge generated
            omega = random.choice(self.omega_range_escape)
        else:
            #!!!! CONTROL SPACE STEP 1 - generate random omega
            omega = random.choice(self.omega_range)


        #!!!! CONTROL SPACE STEP 2 - pick a random point on the tree
        if append_after_latest_node:
            tree_index = shape(V)[1]-1
        else:
            if random.choice([1,2]) == 1:
                tree_index = random.choice(array(V[0])[0])
            else:
                tree_index = shape(V)[1]-1


        xPrev     = V[1,tree_index]
        yPrev     = V[2,tree_index]
        thetaPrev = V_theta[tree_index]

        j = 1
        #!!!! CONTROL SPACE STEP 3 - Check path of the robot
        path_robot = PolyShapes.Circle(self.radius,(xPrev,yPrev))
        while j <= self.timeStep:
            xOrg      = xPrev
            yOrg      = yPrev
            xPrev     = xPrev + self.velocity/omega*(sin(omega* 1 + thetaPrev)-sin(thetaPrev))
            yPrev     = yPrev - self.velocity/omega*(cos(omega* 1 + thetaPrev)-cos(thetaPrev))
            thetaPrev = omega* 1 + thetaPrev
            path_robot = path_robot + PolyShapes.Circle(self.radius,(xPrev,yPrev))

            j = j + 1

        thetaPrev = self.orientation_bound(thetaPrev)
        path_all = PolyUtils.convexHull(path_robot)
        in_bound = regionPoly.covers(path_all)

        # plotting
        if self.plotting == True:
            self.plotPoly(path_all,'r',1)

        stuck = stuck + 1

        if in_bound:
            robot_new_node = PolyShapes.Circle(self.radius,(xPrev,yPrev))
            # check how many nodes on the tree does the new node overlaps with
            nodes_overlap_count = 0
            for k in range(shape(V)[1]-1):
                robot_old_node = PolyShapes.Circle(self.radius,(V[1,k],V[2,k]))
                if robot_new_node.overlaps(robot_old_node):
                    if  abs(thetaPrev - V_theta[k]) <   self.max_angle_overlap:
                        nodes_overlap_count += 1


            if nodes_overlap_count == 0 or (stuck > self.stuck_thres+1 and nodes_overlap_count < 2) or (stuck > self.stuck_thres+500):
                if  stuck > self.stuck_thres+1:
                    append_after_latest_node  = False

                if (stuck > self.stuck_thres+500):
                    stuck = 0
                stuck = stuck - 20
                # plotting
                if self.plotting == True:
                    self.plotPoly(path_all,'b',1)

                if self.system_print == True:
                    print "node connected"

                V = hstack((V,vstack((shape(V)[1],xPrev,yPrev))))
                V_theta = hstack((V_theta,thetaPrev))
                E = hstack((E,vstack((tree_index ,shape(V)[1]-1))))
                Other = hstack((Other,vstack((self.velocity,omega))))
                ##################### E should add omega and velocity
                connection_to_tree = True
                append_after_latest_node  = True
            else:
                append_after_latest_node = False

                if self.system_print == True:
                    print "node not connected. check goal point"

        else:
            append_after_latest_node = False

        return  V,V_theta,E,Other,stuck,append_after_latest_node, connection_to_tree
示例#13
0
    def buildTree(self,p,theta,regionPoly,nextRegionPoly,q_gBundle,face_normal, last=False):
        """
        This function builds the RRT tree.
        p                : x,y position of the robot
        theta            : current orientation of the robot
        regionPoly       : current region polygon
        nextRegionPoly   : next region polygon
        q_gBundle        : coordinates of q_goals that the robot can reach
        face_normal      : the normal vector of each face corresponding to each goal point in q_gBundle
        """

        q_init          = mat(p).T
        V               = vstack((0,q_init))
        theta           = self.orientation_bound(theta)
        V_theta         = array([theta])

        #!!! CONTROL SPACE: generate a list of omega for random sampling
        omegaLowerBound = -math.pi/20      # upper bound for the value of omega
        omegaUpperBound = math.pi/20       # lower bound for the value of omega
        omegaNoOfSteps  = 20
        self.omega_range = linspace(omegaLowerBound,omegaUpperBound,omegaNoOfSteps)
        self.omega_range_escape = linspace(omegaLowerBound*4,omegaUpperBound*4,omegaNoOfSteps*4)    # range used when stuck > stuck_thres

        regionPolyOld = Polygon.Polygon(regionPoly)
        #regionPoly += PolyShapes.Circle(self.radius*2.5,(q_init[0,0],q_init[1,0]))
        regionPoly += PolyShapes.Circle(self.radius*4,(q_init[0,0],q_init[1,0]))

        # check faces of the current region for goal points
        E     = [[],[]]       # the tree matrix
        Other = [[],[]]
        path                        = False          # if path formed then = 1
        stuck                       = 0              # count for changing the range of sampling omega
        append_after_latest_node    = False       # append new nodes to the latest node

        if self.system_print == True:
            print "plotting in buildTree is " + str(self.plotting)
        if self.plotting == True:
            if not plt.isinteractive():
                plt.ion()
            plt.hold(True)


        while not path:
            #step -1: try connection to q_goal (generate path to goal)
            i = 0
            ltlmop_logger.debug("finding RRT Path...")
            if self.system_print == True:
                print "Try Connection to the goal points"

            # pushing possible q_goals into the current region (ensure path is covered by the current region polygon)
            q_pass = [[],[],[]]
            q_pass_dist = []
            q_gBundle = mat(q_gBundle)
            face_normal = mat(face_normal)

            while i < q_gBundle.shape[1]:
                q_g_original = q_gBundle[:,i]
                q_g = q_gBundle[:,i]+face_normal[:,i]*1.5*self.radius    ##original 2*self.radius
                #q_g = q_gBundle[:,i]+(q_gBundle[:,i]-V[1:,(shape(V)[1]-1)])/norm(q_gBundle[:,i]-V[1:,(shape(V)[1]-1)])*1.5*self.radius    ##original 2*self.radius
                if not regionPolyOld.isInside(q_g[0],q_g[1]):
                    #q_g = q_gBundle[:,i]-(q_gBundle[:,i]-V[1:,(shape(V)[1]-1)])/norm(q_gBundle[:,i]-V[1:,(shape(V)[1]-1)])*1.5*self.radius    ##original 2*self.radius
                    q_g = q_gBundle[:,i]-face_normal[:,i]*1.5*self.radius    ##original 2*self.radius

                #forming polygon for path checking
                EdgePolyGoal = PolyShapes.Circle(self.radius,(q_g[0,0],q_g[1,0])) + PolyShapes.Circle(self.radius,(V[1,shape(V)[1]-1],V[2:,shape(V)[1]-1]))
                EdgePolyGoal = PolyUtils.convexHull(EdgePolyGoal)
                dist = norm(q_g - V[1:,shape(V)[1]-1])

                #check connection to goal
                connect_goal = regionPoly.covers(EdgePolyGoal)   #check coverage of path from new point to goal

                # compare orientation difference
                thetaPrev = V_theta[shape(V)[1]-1]

                if not (q_g[0,0]- V[1,shape(V)[1]-1]) == 0:
                    theta_orientation = abs(arctan((q_g[1,0]- V[2,shape(V)[1]-1])/(q_g[0,0]- V[1,shape(V)[1]-1])))
                else:
                    theta_orientation = 0
                if q_g[1,0] > V[2,shape(V)[1]-1]:
                    if q_g[0,0] < V[1,shape(V)[1]-1]: # second quadrant
                        theta_orientation = pi - theta_orientation
                    elif q_g[0,0] > V[1,shape(V)[1]-1]: # first quadrant
                        theta_orientation = theta_orientation
                elif q_g[1,0] < V[2,shape(V)[1]-1]:
                    if q_g[0,0] < V[1,shape(V)[1]-1]: #third quadrant
                        theta_orientation = pi + theta_orientation
                    elif q_g[0,0] > V[1,shape(V)[1]-1]: # foruth quadrant
                        theta_orientation =  2*pi - theta_orientation

                # check the angle between vector(new goal to goal_original ) and vector( latest node to new goal)
                Goal_to_GoalOriginal = q_g_original - q_g
                LatestNode_to_Goal   = q_g - V[1:,shape(V)[1]-1]
                Angle_Goal_LatestNode= arccos(vdot(array(Goal_to_GoalOriginal), array(LatestNode_to_Goal))/norm(Goal_to_GoalOriginal)/norm(LatestNode_to_Goal))

                # if connection to goal can be established and the max change in orientation of the robot is smaller than max_angle, tree is said to be completed.
                if self.orientation_print == True:
                    print "theta_orientation is " + str(theta_orientation)
                    print "thetaPrev is " + str(thetaPrev)
                    print "(theta_orientation - thetaPrev) is " + str(abs(theta_orientation - thetaPrev))
                    print "self.max_angle_allowed is " + str(self.max_angle_allowed)
                    print "abs(theta_orientation - thetaPrev) < self.max_angle_allowed" + str(abs(theta_orientation - thetaPrev) < self.max_angle_allowed)
                    print"Goal_to_GoalOriginal: " + str( array(Goal_to_GoalOriginal)) + "; LatestNode_to_Goal: " + str( array(LatestNode_to_Goal))
                    print vdot(array(Goal_to_GoalOriginal), array(LatestNode_to_Goal))
                    print "Angle_Goal_LatestNode" + str(Angle_Goal_LatestNode)

                if connect_goal and (abs(theta_orientation - thetaPrev) < self.max_angle_allowed) and (Angle_Goal_LatestNode < self.max_angle_allowed):

                    path = True
                    q_pass = hstack((q_pass,vstack((i,q_g))))
                    q_pass_dist = hstack((q_pass_dist,dist))

                i = i + 1

            if self.system_print == True:
                print "checked goal points"

            self.E = E
            self.V = V
            # connection to goal has established
            # Obtain the closest goal point that path can be formed.
            if path:
                if shape(q_pass_dist)[0] == 1:
                    cols = 0
                else:
                    (cols,) = nonzero(q_pass_dist == min(q_pass_dist))
                    cols = asarray(cols)[0]
                q_g = q_pass[1:,cols]
                """
                q_g = q_g-(q_gBundle[:,q_pass[0,cols]]-V[1:,(shape(V)[1]-1)])/norm(q_gBundle[:,q_pass[0,cols]]-V[1:,(shape(V)[1]-1)])*3*self.radius   #org 3
                if not nextRegionPoly.isInside(q_g[0],q_g[1]):
                    q_g = q_g+(q_gBundle[:,q_pass[0,cols]]-V[1:,(shape(V)[1]-1)])/norm(q_gBundle[:,q_pass[0,cols]]-V[1:,(shape(V)[1]-1)])*6*self.radius   #org 3
                """
                if self.plotting == True :
                    if self.operate_system == 1:
                        plt.suptitle('Rapidly-exploring Random Tree', fontsize=12)
                        plt.xlabel('x')
                        plt.ylabel('y')
                        if shape(V)[1] <= 2:
                            plt.plot(( V[1,shape(V)[1]-1],q_g[0,0]),( V[2,shape(V)[1]-1],q_g[1,0]),'b')
                        else:
                            plt.plot(( V[1,E[0,shape(E)[1]-1]], V[1,shape(V)[1]-1],q_g[0,0]),( V[2,E[0,shape(E)[1]-1]], V[2,shape(V)[1]-1],q_g[1,0]),'b')
                        plt.plot(q_g[0,0],q_g[1,0],'ko')
                        plt.figure(1).canvas.draw()
                        plt.pause(0.0001)
                    else:
                        BoundPolyPoints = asarray(PolyUtils.pointList(regionPoly))
                        self.ax.plot(BoundPolyPoints[:,0],BoundPolyPoints[:,1],'k')
                        if shape(V)[1] <= 2:
                            self.ax.plot(( V[1,shape(V)[1]-1],q_g[0,0]),( V[2,shape(V)[1]-1],q_g[1,0]),'b')
                        else:
                            self.ax.plot(( V[1,E[0,shape(E)[1]-1]], V[1,shape(V)[1]-1],q_g[0,0]),( V[2,E[0,shape(E)[1]-1]], V[2,shape(V)[1]-1],q_g[1,0]),'b')
                        self.ax.plot(q_g[0,0],q_g[1,0],'ko')

                # trim the path connecting current node to goal point into pieces if the path is too long now
                numOfPoint = floor(norm(V[1:,shape(V)[1]-1]- q_g)/self.step_size)
                if numOfPoint < 3:
                    numOfPoint = 3
                x = linspace( V[1,shape(V)[1]-1], q_g[0,0], numOfPoint )
                y = linspace( V[2,shape(V)[1]-1], q_g[1,0], numOfPoint )
                for i in range(x.shape[0]):
                    if i != 0:
                        V = hstack((V,vstack((shape(V)[1],x[i],y[i]))))
                        E = hstack((E,vstack((shape(V)[1]-2,shape(V)[1]-1))))

                #push the goal point to the next region
                if self.system == 1:
                    q_g = q_g+face_normal[:,q_pass[0,cols]]*4*self.radius    ##original 3*self.radius
                else:
                    q_g = q_g+face_normal[:,q_pass[0,cols]]*3*self.radius    ##original 3*self.radius

                if not nextRegionPoly.isInside(q_g[0],q_g[1]):
                    if self.system == 1:
                        q_g = q_g-face_normal[:,q_pass[0,cols]]*8*self.radius    ##original 6*self.radius
                    else:
                        q_g = q_g-face_normal[:,q_pass[0,cols]]*6*self.radius    ##original 6*self.radius

                V = hstack((V,vstack((shape(V)[1],q_g[0,0],q_g[1,0]))))
                E = hstack((E,vstack((shape(V)[1]-2 ,shape(V)[1]-1))))

                if self.plotting == True :
                    if self.operate_system == 1:
                        plt.plot(q_g[0,0],q_g[1,0],'ko')
                        plt.plot(( V[1,shape(V)[1]-1],V[1,shape(V)[1]-2]),( V[2,shape(V)[1]-1],V[2,shape(V)[1]-2]),'b')
                        plt.figure(1).canvas.draw()
                        plt.pause(0.0001)
                    else:
                        self.ax.plot(q_g[0,0],q_g[1,0],'ko')
                        self.ax.plot(( V[1,shape(V)[1]-1],V[1,shape(V)[1]-2]),( V[2,shape(V)[1]-1],V[2,shape(V)[1]-2]),'b')

            # path is not formed, try to append points onto the tree
            if not path:

                # connection_to_tree : connection to the tree is successful
                if append_after_latest_node:
                    V,V_theta,E,Other,stuck,append_after_latest_node, connection_to_tree = self.generateNewNode(V,V_theta,E,Other,regionPoly,stuck, append_after_latest_node)
                else:
                    connection_to_tree = False
                    while not connection_to_tree:
                        V,V_theta,E,Other,stuck,append_after_latest_node, connection_to_tree = self.generateNewNode  (V,V_theta,E,Other,regionPoly,stuck)


        if self.finish_print:
            print 'Here is the V matrix:', V, 'Here is the E matrix:',E
            print >>sys.__stdout__, 'Here is the V matrix:\n', V, '\nHere is the E matrix:\n',E

        #B: trim to a single path
        single = 0
        while single == 0:
            trim  = 0
            for j in range(shape(V)[1]-3):
                (row,col) = nonzero(E == j+1)
                if len(col) == 1:
                    E = delete(E, col[0], 1)
                    trim = 1

            if trim == 0:
                single = 1;

        ####print with matlib
        if self.plotting ==True :
            if self.operate_system == 1:
                plt.plot(V[1,:],V[2,:],'b')
                for i in range(shape(E)[1]):
                    plt.text(V[1,E[0,i]],V[2,E[0,i]], V[0,E[0,i]], fontsize=12)
                    plt.text(V[1,E[1,i]],V[2,E[1,i]], V[0,E[1,i]], fontsize=12)
                plt.figure(1).canvas.draw()
                plt.pause(0.0001)

            else:
                BoundPolyPoints = asarray(PolyUtils.pointList(regionPoly))
                self.ax.plot(BoundPolyPoints[:,0],BoundPolyPoints[:,1],'k')
                self.ax.plot(V[1,:],V[2,:],'b')
                for i in range(shape(E)[1]):
                    self.ax.text(V[1,E[0,i]],V[2,E[0,i]], V[0,E[0,i]], fontsize=12)
                    self.ax.text(V[1,E[1,i]],V[2,E[1,i]], V[0,E[1,i]], fontsize=12)

        # plot in simGUI
        self.path = []
        for i in range(shape(E)[1]):
            self.path.append(tuple(map(int, self.executor.hsub.coordmap_lab2map([V[1,E[0,i]],V[2,E[0,i]]]))))
        self.path.append(tuple(map(int, self.executor.hsub.coordmap_lab2map([V[1,E[1,i]],V[2,E[1,i]]]))))
        self.executor.postEvent("RRT", self.path)

        #return V, E, and the current node number on the tree
        V = array(V)
        return V, E, 0
示例#14
0
def buildTree(p,theta,vert, R, system, regionPoly,nextRegionPoly,q_gBundle,\
mappedRegions,allRegions,max_angle_allowed, plotting, operate_system,ax, last=False):

    """
    This function builds the RRT tree
    pose: x,y position of the robot
    theta: current orientation of the robot
    R: radius of the robot
    system: determine step_size and radius for the example
    regionPoly: current region polygon
    nextRegionPoly: next region polygon
    q_gBundle: coordinates of q_goals that the robot can reach
    mappedRegions: region polygons
    allRegions: polygon that includes all the region
    max_angle_allowed: the difference in angle between the two nodes allowed (between 0 to 2*pi)
    plotting: 1 if plotting is enabled, 0- disabled
    operate_system: Which operating system is used for execution. Ubuntu and Mac is 1, Windows is 2
    ax: plot for windows
    """

    max_angle = max_angle_allowed
    """
    if operate_system == 2:
        # start using anmination to plot Pioneer
        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(111)
        self.scope = _Scope(self.ax,self)
        thread.start_new_thread(self.jplot,())
    """

    ## 1: Nao ; 2: STAGE ;  3: ODE
    if system == 1:    ## Nao
        step_size  = 0.2          	#set the step_size for points be 1/5 of the norm from   ORIGINAL = 0.4
    elif system == 2:
        step_size  = 0.5
    elif system == 3:
        step_size  = 15

    if system == 1:    ## Nao
        timeStep = 5   #time step for calculation of x, y position
    elif system == 2:
        timeStep = 4   #time step for calculation of x, y position
    elif system == 3:
        timeStep = 10  #time step for calculation of x, y position    #10
    #############tune velocity OMEGA, TIME STEP

    #fix velocity
    ## 1: Nao ; 2: STAGE ;  3: ODE
    if system == 1:    ## Nao
        velocity  = 0.05          	#set the step_size for points be 1/5 of the norm from
    elif system == 2:
        velocity  = 0.06
    elif system == 3:
        velocity = 2    # what is used in RRTControllerHelper.setVelocity    #1.5
    #############tune velocity OMEGA, TIME STEP

    BoundPoly  = regionPoly       # Boundary polygon = current region polygon
    radius     = R
    q_init     = mat(p).T
    V          = vstack((0,q_init))
    V_theta    = array([theta])
    original_figure = 1

    #!!! CONTROL SPACE: generate a list of omega for random sampling
    omegaLowerBound = -math.pi/20      # upper bound for the value of omega
    omegaUpperBound = math.pi/20       # lower bound for the value of omega
    omegaStepSize   = 20
    omega_range = linspace(omegaLowerBound,omegaUpperBound,omegaStepSize)
    omega_range_abso = linspace(omegaLowerBound*4,omegaUpperBound*4,omegaStepSize*4)    # range used when stuck > stuck_thres
    edgeX    = []
    edgeY    = []

    # check faces of the current region for goal points

    E = [[],[]]
    Other = [[],[]]
    path     = 0          # if path formed then = 1
    stuck    = 0          # count for changing the range of sampling omega
    stuck_thres = 300     # threshold for changing the range of sampling omega

    if not plt.isinteractive():
        plt.ion()
    plt.hold(True)
    while path == 0:
        #step -1: try connection to q_goal (generate path to goal)
        goalCheck = 0;
        i = 0

        # pushing possible q_goals into the current region (ensure path is covered by the current region polygon)
        q_pass = [[],[],[]]
        q_pass_dist = []
        q_gBundle = mat(q_gBundle)
        while i < q_gBundle.shape[1]:   ###not sure about shape
            q_g = q_gBundle[:,i]+(q_gBundle[:,i]-V[1:,(shape(V)[1]-1)])/norm(q_gBundle[:,i]-V[1:,(shape(V)[1]-1)])*radius    ##original 2*radius
            trial = 1
            if not BoundPoly.isInside(q_g[0],q_g[1]):
                trial = 2
                q_g = q_gBundle[:,i]-(q_gBundle[:,i]-V[1:,(shape(V)[1]-1)])/norm(q_gBundle[:,i]-V[1:,(shape(V)[1]-1)])*radius    ##original 2*radius

            #forming polygon for path checking
            cross_goal     = cross(vstack((q_g-vstack((V[1,shape(V)[1]-1],V[2,shape(V)[1]-1])),0)).T,hstack((0,0,1)))
            cross_goal       = cross_goal.T
            move_vector_goal = radius*cross_goal[0:2]/sqrt((cross_goal[0,0]**2 + cross_goal[1,0]**2))
            upperEdgeG   = hstack((vstack((V[1,shape(V)[1]-1],V[2,shape(V)[1]-1])),q_g)) + hstack((move_vector_goal,move_vector_goal))
            lowerEdgeG   = hstack((vstack((V[1,shape(V)[1]-1],V[2,shape(V)[1]-1])),q_g)) - hstack((move_vector_goal,move_vector_goal))
            EdgePolyGoal    = Polygon.Polygon((tuple(array(lowerEdgeG[:,0].T)[0]),tuple(array(upperEdgeG[:,0].T)[0]),tuple(array(upperEdgeG[:,1].T)[0]),tuple(array(lowerEdgeG[:,1].T)[0])))

            dist = norm(q_g - V[1:,shape(V)[1]-1])
            connect_goal = BoundPoly.covers(EdgePolyGoal)   #check coverage of path from new point to goal
            #check connection to goal

            """
            if connect_goal:
                print "connection is true"
                path = 1
                q_pass = hstack((q_pass,vstack((i,q_g))))
                q_pass_dist = hstack((q_pass_dist,dist))
            """

            # compare orientation difference
            thetaPrev = V_theta[shape(V)[1]-1]
            theta_orientation = abs(arctan((q_g[1,0]- V[2,shape(V)[1]-1])/(q_g[0,0]- V[1,shape(V)[1]-1])))
            if thetaPrev < 0:
                if q_g[1,0] > V[2,shape(V)[1]-1]:
                    if q_g[0,0] < V[1,shape(V)[1]-1]: # second quadrant
                        theta_orientation = -2*pi + theta_orientation
                    elif q_g[0,0] > V[1,shape(V)[1]-1]: # first quadrant
                        theta_orientation = -pi -theta_orientation
                elif q_g[1,0] < V[2,shape(V)[1]-1]:
                    if q_g[0,0] < V[1,shape(V)[1]-1]: #third quadrant
                        theta_orientation = -pi + theta_orientation
                    elif q_g[0,0] > V[1,shape(V)[1]-1]: # foruth quadrant
                        theta_orientation =  - theta_orientation
            else:
                if q_g[1,0] > V[2,shape(V)[1]-1]:
                    if q_g[0,0] < V[1,shape(V)[1]-1]: # second quadrant
                        theta_orientation = pi - theta_orientation
                    elif q_g[0,0] > V[1,shape(V)[1]-1]: # first quadrant
                        theta_orientation = theta_orientation
                elif q_g[1,0] < V[2,shape(V)[1]-1]:
                    if q_g[0,0] < V[1,shape(V)[1]-1]: #third quadrant
                        theta_orientation = pi + theta_orientation
                    elif q_g[0,0] > V[1,shape(V)[1]-1]: # foruth quadrant
                        theta_orientation =  2*pi - theta_orientation

            ################################## PRINT PLT #################

            if connect_goal :
                if plotting == True:
                    if operate_system == 1:
                        plt.suptitle('Randomly-exploring rapid tree', fontsize=12)
                        BoundPolyPoints = asarray(PolyUtils.pointList(BoundPoly))
                        plt.plot(BoundPolyPoints[:,0],BoundPolyPoints[:,1],'k')
                        plt.xlabel('x')
                        plt.ylabel('y')
                        if shape(V)[1] <= 2:
                            plt.plot(( V[1,shape(V)[1]-1],q_g[0,0]),( V[2,shape(V)[1]-1],q_g[1,0]),'b')
                        else:
                            plt.plot(( V[1,E[0,shape(E)[1]-1]], V[1,shape(V)[1]-1],q_g[0,0]),( V[2,E[0,shape(E)[1]-1]], V[2,shape(V)[1]-1],q_g[1,0]),'b')
                        plt.figure(original_figure).canvas.draw()
                    else:
                        ax.suptitle('Randomly-exploring rapid tree', fontsize=12)
                        BoundPolyPoints = asarray(PolyUtils.pointList(BoundPoly))
                        ax.plot(BoundPolyPoints[:,0],BoundPolyPoints[:,1],'k')
                        ax.xlabel('x')
                        ax.ylabel('y')
                        if shape(V)[1] <= 2:
                            ax.plot(( V[1,shape(V)[1]-1],q_g[0,0]),( V[2,shape(V)[1]-1],q_g[1,0]),'b')
                        else:
                            ax.plot(( V[1,E[0,shape(E)[1]-1]], V[1,shape(V)[1]-1],q_g[0,0]),( V[2,E[0,shape(E)[1]-1]], V[2,shape(V)[1]-1],q_g[1,0]),'b')


            if connect_goal and abs(theta_orientation - thetaPrev) < max_angle:
                #if connect_goal and abs(theta_orientation - thetaPrev) < pi/3:
                print "connection is true.Path = 1"
                path = 1
                q_pass = hstack((q_pass,vstack((i,q_g))))
                q_pass_dist = hstack((q_pass_dist,dist))


            i = i + 1

        # connection to goal has established
        if path == 1:
            if shape(q_pass_dist)[0] == 1:
                cols = 0
            else:
                (cols,) = nonzero(q_pass_dist == min(q_pass_dist))
                cols = asarray(cols)[0]
            q_g = q_pass[1:,cols]   ###Catherine
            q_g = q_g-(q_gBundle[:,q_pass[0,cols]]-V[1:,(shape(V)[1]-1)])/norm(q_gBundle[:,q_pass[0,cols]]-V[1:,(shape(V)[1]-1)])*3*radius   #org 3
            if not nextRegionPoly.isInside(q_g[0],q_g[1]):
                q_g = q_g+(q_gBundle[:,q_pass[0,cols]]-V[1:,(shape(V)[1]-1)])/norm(q_gBundle[:,q_pass[0,cols]]-V[1:,(shape(V)[1]-1)])*6*radius   #org 3

            if plotting == True:
                if operate_system == 1:
                    plt.plot(q_g[0,0],q_g[1,0],'ko')
                    plt.figure(original_figure).canvas.draw()
                else:
                    ax.plot(q_g[0,0],q_g[1,0],'ko')


            numOfPoint = floor(norm(V[1:,shape(V)[1]-1]- q_g)/step_size)
            if numOfPoint < 3:
                numOfPoint = 3
            x = linspace( V[1,shape(V)[1]-1], q_g[0,0], numOfPoint )
            y = linspace( V[2,shape(V)[1]-1], q_g[1,0], numOfPoint )
            for i in range(x.shape[0]):
                if i != 0:
                    V = hstack((V,vstack((shape(V)[1],x[i],y[i]))))
                    E = hstack((E,vstack((shape(V)[1]-2,shape(V)[1]-1))))

        # path is not formed, try to append points onto the tree
        if path == 0:
            success     = 0           # whether adding a new point is successful
            hit_count   = 0           # count for regenerating new edge with the same q_rand
            Icurrent    = []          # to keep track of the index of the closest point to q_n

            while success == 0 and hit_count <= 2:
                if stuck > stuck_thres:
                    omega = random.choice(omega_range_abso)
                else:
                    #!!!! CONTROL SPACE STEP 1 - generate random omega
                    omega = random.choice(omega_range)


                #!!!! CONTROL SPACE STEP 2 - pick a random point on the tree
                tree_index = random.choice(array(V[0])[0])
                xPrev     = V[1,tree_index]
                yPrev     = V[2,tree_index]
                thetaPrev = V_theta[tree_index]

                j = 1
                #!!!! CONTROL SPACE STEP 3 - Check path of the robot
                path_robot = PolyShapes.Circle(radius,(xPrev,yPrev))
                while j <= timeStep:
                    xOrg      = xPrev
                    yOrg      = yPrev
                    xPrev     = xPrev + velocity/omega*(sin(omega* 1 + thetaPrev)-sin(thetaPrev))
                    yPrev     = yPrev - velocity/omega*(cos(omega* 1 + thetaPrev)-cos(thetaPrev))
                    thetaPrev = omega* 1 + thetaPrev
                    path_robot = path_robot + PolyShapes.Circle(radius,(xPrev,yPrev))

                    j = j + 1

                path_all = PolyUtils.convexHull(path_robot)
                in_bound = BoundPoly.covers(path_all)

                # plotting
                plotPoly(path_all,'r',1)
                plotMap(original_figure,BoundPoly,allRegions)

                stuck = stuck + 1
                if in_bound:
                    stuck = stuck -5
                    x = []
                    y = []
                    for k in  PolyUtils.pointList(path_all):
                        x = hstack((x,k[0]))
                        y = hstack((y,k[1]))

                    V = hstack((V,vstack((shape(V)[1],xPrev,yPrev))))
                    V_theta = hstack((V_theta,thetaPrev))
                    E = hstack((E,vstack((tree_index ,shape(V)[1]-1))))
                    Other = hstack((Other,vstack((velocity,omega))))
                    ##################### E should add omega and velocity
                    success = 1

    if finish_print == 1:
        print 'Here is the V matrix:', V, 'Here is the E matrix:',E
        print >>sys.__stdout__, 'Here is the V matrix:\n', V, '\nHere is the E matrix:\n',E

    #B: trim to a single path
    single = 0
    while single == 0:
        trim  = 0
        for j in range(shape(V)[1]-3):
            (row,col) = nonzero(E == j+1)
            if len(col) == 1:
                E = delete(E, col[0], 1)
                trim = 1

        if trim == 0:
            single = 1;

    # generate V to be sent to SimGUI to plot
    V_toPass = V[0:,0]
    E_toPass = [[],[]]
    for i in range(shape(E)[1]):
        V_toPass = hstack((V_toPass,vstack((i,V[1,E[1,i-1]],V[2,E[1,i-1]]))))
        E_toPass = hstack((E_toPass,vstack((i-1,i))))

    ####print with matlib
    if plotting ==True:
        if operate_system == 1:
            BoundPolyPoints = asarray(PolyUtils.pointList(BoundPoly))
            plt.plot(BoundPolyPoints[:,0],BoundPolyPoints[:,1],'k')
            plt.plot(V[1,:],V[2,:],'b')
            for i in range(shape(E)[1]-1):
                plt.text(V[1,E[0,i]],V[2,E[0,i]], V[0,E[0,i]], fontsize=12)
                plt.text(V[1,E[1,i]],V[2,E[1,i]], V[0,E[1,i]], fontsize=12)
            plt.figure(original_figure).canvas.draw()
        else:
            BoundPolyPoints = asarray(PolyUtils.pointList(BoundPoly))
            ax.plot(BoundPolyPoints[:,0],BoundPolyPoints[:,1],'k')
            ax.plot(V[1,:],V[2,:],'b')
            for i in range(shape(E)[1]-1):
                ax.text(V[1,E[0,i]],V[2,E[0,i]], V[0,E[0,i]], fontsize=12)
                ax.text(V[1,E[1,i]],V[2,E[1,i]], V[0,E[1,i]], fontsize=12)

    heading  = E[0,0]
    # parse string for RRT printing in GUI (in format: RRT:E[[1,2,3]]:V[[1,2,3]])
    V = array(V)
    V_toPass = array(V_toPass)
    E_toPass = array(E_toPass)
    return V, E, heading,0,V_toPass,E_toPass