コード例 #1
0
 def __init__(self):
     self.robotPos = Position(0, 0)
     self.goalPos = None
     self.occupancy_grid = OccupancyGrid()
     self.occupancy_grid.initializeData()
     self.subscribeEvents()
     self.setMarkerPublishers()
     self.markerUniqueId = 10
     self.pathMarkerIds = []
     self.openListMarkerIds = {}
コード例 #2
0
 def generateOccupancyGrid(self, cellSize = 0.1):
     grid = OccupancyGrid(self._xll, self._yll, self._width, self._height, cellSize)
     for l in self._lines:
         # Note: element check is done by reference.
         # This is valid, since each line is constructed only once.
         if l in self._dynObstacles:
             continue
         x0 = l.getP1().getX()
         y0 = l.getP1().getY()
         x1 = l.getP2().getX()
         y1 = l.getP2().getY()
         grid.addLine(x0, y0, x1, y1)
     return grid
コード例 #3
0
ファイル: World.py プロジェクト: CptainWho/Aufgabe1
 def getOccupancyGrid(self, cellSize = 0.1):
     if self._grid is None:
         self._grid = OccupancyGrid(self._xll, self._yll, self._width, self._height, cellSize)
         for l in self._lines:
             x0 = l.getP1().getX()
             y0 = l.getP1().getY()
             x1 = l.getP2().getX()
             y1 = l.getP2().getY()
             self._grid.addLine(x0, y0, x1, y1)
     return self._grid
コード例 #4
0
ファイル: AStarPlanner.py プロジェクト: kolokolca/Searistica
	def __init__(self):
		self.robotPos = Position(0,0)
		self.goalPos = None
		self.occupancy_grid = OccupancyGrid()
		self.occupancy_grid.initializeData()
		self.subscribeEvents()
		self.setMarkerPublishers()
		self.markerUniqueId = 10
		self.pathMarkerIds = []
		self.openListMarkerIds = {}
コード例 #5
0
class AStarPlanning:
    def __init__(self):
        self.robotPos = Position(0, 0)
        self.goalPos = None
        self.occupancy_grid = OccupancyGrid()
        self.occupancy_grid.initializeData()
        self.subscribeEvents()
        self.setMarkerPublishers()
        self.markerUniqueId = 10
        self.pathMarkerIds = []
        self.openListMarkerIds = {}

    def getMarkerUniqueId(self):
        self.markerUniqueId += 1
        return self.markerUniqueId

    def setMarkerPublishers(self):
        self.markerPublisher = rospy.Publisher('/planning_markers', Marker)
        self.markerArray_publisher = rospy.Publisher(
            '/planning_multiple_markers', MarkerArray, latch=True)

    def subscribeEvents(self):
        rospy.Subscriber('/goal_pos', PoseStamped, self.rvizGoalPosCallBack)

    def rvizGoalPosCallBack(self, clickedPose):
        comandType = rospy.get_param('comandType')
        pos_x = int(clickedPose.pose.position.x)
        pos_y = int(clickedPose.pose.position.y)

        if (comandType == "o"):
            clickedPosition = Position(pos_x, pos_y)
            self.occupancy_grid.setData(clickedPosition.x, clickedPosition.y,
                                        100)
        elif (comandType == "g"):
            r = rospy.Rate(4)
            self.publisRobotPoseMarker()
            self.deletePathMarkers()
            r.sleep()
            self.updatePlanning = True
            self.goalPos = Position(pos_x, pos_y)

    def deletePathMarkers(self):
        for i in range(len(self.pathMarkerIds)):
            pathMarkerId = self.pathMarkerIds[i]
            marker = Marker()
            marker.header.frame_id = '/map'
            marker.ns = 'AStartPlanning'
            marker.id = pathMarkerId
            marker.action = Marker.DELETE
            self.markerPublisher.publish(marker)

    def publisText(self, s):

        marker = Marker()
        shape = Marker.TEXT_VIEW_FACING
        marker.header.frame_id = '/map'
        marker.header.stamp = rospy.Time()  #rospy.Time.now()
        marker.ns = 'AStartPlanning'
        marker.id = 5
        marker.type = shape
        marker.action = Marker.ADD
        marker.text = s

        marker.pose.position.x = 17.0
        marker.pose.position.y = -3.0
        marker.pose.position.z = 2.0

        marker.scale.z = 1.1

        marker.color.r = 0.8
        marker.color.g = 0.0
        marker.color.b = 0.0
        marker.color.a = 0.9

        self.markerPublisher.publish(marker)

    def publisDrawPathLine(self):
        self.path.reverse()
        r = rospy.Rate(5)
        for i in range(len(self.path) - 1):

            pathPoint1 = self.path[i]
            pathPoint2 = self.path[i + 1]
            self.robotPos = Position(int(pathPoint2.x), int(pathPoint2.y))
            marker = Marker()
            shape = Marker.LINE_STRIP
            marker.header.frame_id = '/map'
            marker.header.stamp = rospy.Time()  #rospy.Time.now()
            marker.ns = 'AStartPlanning'
            marker.id = self.getMarkerUniqueId()
            self.pathMarkerIds.append(marker.id)
            marker.type = shape
            marker.action = Marker.ADD
            marker.points = [pathPoint1, pathPoint2]

            marker.scale.x = 0.4
            marker.scale.y = 1.0
            marker.scale.z = 1.0

            marker.color.r = 0.0
            marker.color.g = 1.0
            marker.color.b = 1.0
            marker.color.a = 1.0

            self.publisRobotPoseMarker()
            self.markerPublisher.publish(marker)
            r.sleep()

    def robotPosChangedCallback(self, robotPos):
        self.robotPos = robotPos
        self.cmd_robotPos_sub.unregister()

    def goalPosChangedCallback(self, goalPos):
        self.goalPos = goalPos

    def computeEquledianDistance(self, currentCell):
        xDistance = self.goalPos.x - currentCell.x
        yDistance = self.goalPos.y - currentCell.y
        return math.sqrt(math.pow(xDistance, 2) + math.pow(yDistance, 2))

    def computeH(self, childGridCell):
        childGridCell.hVal = self.computeEquledianDistance(childGridCell)

    def oneCellMoveCost(self):
        return 1

    def isAnObstacle(self, gridCell):
        gridCellData = self.occupancy_grid.data[gridCell.x][gridCell.y]
        if (gridCellData == 100):
            return True
        return False

    def getCellCost(self, gridCell):
        if (self.isAnObstacle(gridCell)):
            return 100
        return 1

    def computeG(self, gridCell):
        if (gridCell.parentGridCell is None):
            gridCell.gVal = 0
        else:
            gridCell.gVal = gridCell.parentGridCell.gVal + self.getCellCost(
                gridCell)

    def computeTotalCost(self, childGridCell):
        self.computeG(childGridCell)
        self.computeH(childGridCell)
        return childGridCell.getCost()

    def isGoalGridCell(self, currentCell):
        return currentCell.x == self.goalPos.x and currentCell.y == self.goalPos.y

    def isInRange(self, x, y):
        return (x >= 0
                and y >= 0) and (x < self.occupancy_grid.dimension.width
                                 and y < self.occupancy_grid.dimension.height)

    def getAdjacentCells(self, currentCell):

        adjacentCells = []
        x = currentCell.x
        y = currentCell.y

        if (self.isInRange(x + 1, y)):
            gridCell = GridCell(x + 1, y, currentCell)
            if (self.isAnObstacle(gridCell) == False):
                adjacentCells.append(gridCell)

        if (self.isInRange(x + 1, y + 1)):
            gridCell = GridCell(x + 1, y + 1, currentCell)
            if (self.isAnObstacle(gridCell) == False):
                adjacentCells.append(gridCell)

        if (self.isInRange(x, y + 1)):
            gridCell = GridCell(x, y + 1, currentCell)
            if (self.isAnObstacle(gridCell) == False):
                adjacentCells.append(gridCell)

        if (self.isInRange(x - 1, y + 1)):
            gridCell = GridCell(x - 1, y + 1, currentCell)
            if (self.isAnObstacle(gridCell) == False):
                adjacentCells.append(gridCell)

        if (self.isInRange(x - 1, y)):
            gridCell = GridCell(x - 1, y, currentCell)
            if (self.isAnObstacle(gridCell) == False):
                adjacentCells.append(gridCell)

        if (self.isInRange(x - 1, y - 1)):
            gridCell = GridCell(x - 1, y - 1, currentCell)
            if (self.isAnObstacle(gridCell) == False):
                adjacentCells.append(gridCell)

        if (self.isInRange(x, y - 1)):
            gridCell = GridCell(x, y - 1, currentCell)
            if (self.isAnObstacle(gridCell) == False):
                adjacentCells.append(gridCell)

        if (self.isInRange(x + 1, y - 1)):
            gridCell = GridCell(x + 1, y - 1, currentCell)
            if (self.isAnObstacle(gridCell) == False):
                adjacentCells.append(gridCell)

        return adjacentCells

    def printAdjacentCells(self, adjs):
        s = "Adjs : "
        for i in range(len(adjs)):
            adj = adjs[i]
            s += "(" + str(adj.x) + "," + str(adj.y) + ") "
        print s

    def getPath(self, gridCell):
        self.path.append(Point(gridCell.x + 0.5, gridCell.y + 0.5, 1))
        if (gridCell.x == self.robotPos.x and gridCell.y == self.robotPos.y):
            return

        self.getPath(gridCell.parentGridCell)

    def publisMultipleMarkers(self, dictionary):
        l = dictionary.items()

        marker_array = MarkerArray()
        r = rospy.Rate(25)
        life = 6
        for i in range(len(l)):

            (key, gridCell) = l[i]
            marker = Marker()
            marker.header.frame_id = '/map'
            marker.header.stamp = rospy.Time()
            marker.ns = 'AStartPlanning'
            markerId = str(gridCell.x) + "_" + str(gridCell.y)
            if (markerId in self.openListMarkerIds):
                marker.id = self.openListMarkerIds[markerId]
            else:
                marker.id = self.getMarkerUniqueId()
                self.openListMarkerIds[markerId] = marker.id

            marker.type = Marker.CUBE
            marker.action = Marker.ADD
            marker.lifetime = rospy.Duration(life, 0)

            marker.pose.position.x = gridCell.x + 0.5
            marker.pose.position.y = gridCell.y + 0.5

            marker.scale.x = 1.0
            marker.scale.y = 1.0
            marker.scale.z = 1.0

            marker.color.r = 0.0
            marker.color.g = 100.0
            marker.color.b = 0.0
            marker.color.a = 0.7

            marker_array.markers.append(marker)

        self.markerArray_publisher.publish(marker_array)
        r.sleep()

    def computePlan(self):

        if (self.robotPos != None and self.goalPos != None):
            start = time.time()
            startGridCell = GridCell(self.robotPos.x, self.robotPos.y, None)
            priorityQueue = PriorityQueue()
            closeList = {}
            openList = {}
            openList[startGridCell.getKey()] = startGridCell
            self.computeTotalCost(startGridCell)
            priorityQueue.push(startGridCell.getCost(), startGridCell)
            goal = None

            while (len(openList) > 0):
                (cost, currentCell) = priorityQueue.pop()
                #print "low cell:(", currentCell.x , currentCell.y, ") cost:", cost
                if (currentCell.getKey() in openList):
                    del openList[currentCell.getKey()]

                if (self.isGoalGridCell(currentCell)):
                    goal = currentCell
                    break
                else:
                    adjacentCells = self.getAdjacentCells(currentCell)
                    #self.printAdjacentCells(adjacentCells)
                    #print "\n"

                    for index in range(len(adjacentCells)):
                        adjacentCell = adjacentCells[index]
                        allReadyVisited = adjacentCell.getKey() in closeList
                        if (allReadyVisited): continue
                        self.computeTotalCost(adjacentCell)
                        #print "Adj:(" , adjacentCell.x , adjacentCell.y , ") " , "cost:", adjacentCell.getCost()
                        exploredBefore = adjacentCell.getKey() in openList
                        if (exploredBefore == False):
                            openList[adjacentCell.getKey()] = adjacentCell
                            priorityQueue.push(adjacentCell.getCost(),
                                               adjacentCell)
                            #print "Adj:(" , adjacentCell.x , adjacentCell.y , ") ", "not in open list, added to open list"
                        else:
                            oldAdjacentCell = openList[adjacentCell.getKey()]
                            #print "found old Adj:(" , oldAdjacentCell.x , oldAdjacentCell.y , ") " , "cost:", oldAdjacentCell.getCost(), " parent:" , oldAdjacentCell.parentGridCell.x , oldAdjacentCell.parentGridCell.y
                            if (adjacentCell.getCost() <
                                    oldAdjacentCell.getCost()):
                                oldAdjacentCell.setParent(currentCell)
                                self.computeTotalCost(oldAdjacentCell)
                                #print "old Adj upadte:(" , oldAdjacentCell.x , oldAdjacentCell.y , ") " , "new cost:", oldAdjacentCell.getCost(), " new parent:" , oldAdjacentCell.parentGridCell.x , oldAdjacentCell.parentGridCell.y
                            #else:
                            #print "Old Adj not updated"
                        #print "\n"

                    closeList[currentCell.getKey()] = currentCell
                    self.publisMultipleMarkers(closeList)
                    #print "low cell:(", currentCell.x , currentCell.y, ") cost:", cost, " REMOVED"
                    #print "-----------"

            #print "Goal:", goal.x, goal.y

            end = time.time()
            elapsed = end - start
            s = "Time taken: " + str(elapsed) + " seconds.\n"
            s += "Total node expanded: " + str(
                len(closeList)) + " out of " + "(30 * 30) = 900. \n"
            self.path = []
            if (goal is not None):
                self.getPath(goal)
                self.publisDrawPathLine()
            else:
                s = "Goal not found !!!"

            self.publisText(s)

    def publisRobotPoseMarker(self):

        marker = Marker()
        shape = Marker.SPHERE
        marker.header.frame_id = '/map'
        marker.header.stamp = rospy.Time()
        marker.ns = 'AStartPlanning'
        marker.id = 1
        marker.type = shape
        marker.action = Marker.ADD

        marker.pose.position.x = self.robotPos.x + 0.5
        marker.pose.position.y = self.robotPos.y + 0.5
        marker.pose.position.z = 1.0

        marker.scale.x = 0.75
        marker.scale.y = 0.75
        marker.scale.z = 1.0

        marker.color.r = 0.0
        marker.color.g = 1.0
        marker.color.b = 0.0
        marker.color.a = 0.75

        self.markerPublisher.publish(marker)

    def makePalnning(self):
        r = rospy.Rate(5)
        print 'Running A start planner'
        self.publisRobotPoseMarker()
        while not rospy.is_shutdown():
            if self.updatePlanning:
                self.computePlan()
                self.updatePlanning = False
            r.sleep()
コード例 #6
0
ファイル: World.py プロジェクト: CptainWho/Aufgabe1
class World:

    # --------
    # init: creates a an empty world
    # with the given size in [m]
    #
    def __init__(self, width, height):
        # World size:
        self._width = width
        self._height = height

        # Border lines:
        self._xll = 0.0 # x coord of left lower point
        self._yll = 0.0 # y coord of left lower point
        self._lines = [] # List of lines
        ll = Point(self._xll, self._yll) # lower left
        lr = Point(self._xll+width, self._yll) # lower right
        ur = Point(self._xll+width, self._yll+height) # upper right
        ul = Point(self._xll, self._yll+height) # upper left
        self._lines.append(Line(ll,lr))
        self._lines.append(Line(lr,ur))
        self._lines.append(Line(ur,ul))
        self._lines.append(Line(ul,ll))

        # Boxes:
        self._boxes = []
        self._boxSensor = True
        self._boxSensorAngle = 140 * (pi/180) # 140 degree
        self._boxRadius = 0.1 # box radius
        self._boxesSensedDist = [] # Distance to the sensed boxes
        self._boxesSensedAngles = [] # Angles of the sensed boxes

        # Rooms
        self._rooms = []

        # Define graphic window with coordinates and draw borderline
        self._win = GraphWin("HTWG Robot Simulator", int(800.0*width/height), 800, autoflush=False)
        self._win.setCoords(self._xll-0.1, self._yll-0.3, self._xll+width+0.1, self._yll+height+0.1)
        for l in self._lines:
            l.draw(self._win)

        # Robot (initialization is done in setRobot()
        self._robot = None
        self._robotCircle = None # robot is shown as circle with robot position as center
        self._robotTheta = None # robot's global orientation
        self._robotLine = None # local x-axis of the robot

        # Sensor values:
        self._sensorShow = True # Sensor values are shown
        self._sensorDist = [] # Distances to obstacles
        self._sensorPoints = [] # Obstacle points
        self._sensorLines = [] # Sensor beams as lines for drawing

        # Clock:
        self._clockTime = 0.0
        p = Point(self._xll+width/2, self._yll-0.1)
        self._clockTimeText = Text(p,"Clock Time %4.2f" % self._clockTime )
        self._clockTimeText.draw(self._win)

        # Occupancy Grid:
        self._grid = None

        # Path history
        self._showPathHistory = False
        self._drivenDistance = 0.0

        # Drawn Polyline:
        self._drawnPolyline = []

    # --------
    # Draw a polyline.
    #
    def drawPolyline(self, poly, color = 'green'):
        self.undrawPolyline()
        for n in range(len(poly)-1):
            l = Line(Point(poly[n][0],poly[n][1]),Point(poly[n+1][0],poly[n+1][1]))
            l.draw(self._win)
            l.setFill(color)
            l.setWidth(3)
            self._drawnPolyline.append(l)

    # --------
    # Undraw the polyline.
    #
    def undrawPolyline(self):
        if self._drawnPolyline == []:
            return
        for l in self._drawnPolyline:
            l.undraw()
        self._drawnPolyline = []


    # --------
    # add new a new line from point (x0,y0) to (x1,y1)
    #
    def addLine(self, x0, y0, x1, y1):
        l = Line(Point(x0,y0),Point(x1,y1))
        self._lines.append(l)
        l.setWidth(5)
        l.setFill('blue')
        l.draw(self._win)

    # --------
    # add new a new round Box at point (x,y).
    #
    def addBox(self, x, y):
        box = Circle(Point(x,y),self._boxRadius)
        box.draw(self._win)
        self._boxes.append(box)

    # --------
    # Define a new room with name n and center position (x,y).
    #
    def defineRoom(self, n, x, y):
        self._rooms.append([n,x,y])
        t = Text(Point(x,y),n)
        t.draw(self._win)

    # --------
    # Return all rooms.
    #
    def getRooms(self):
        return self._rooms

    # --------
    # set the robot at pose (x,y,theta) and draw it.
    #
    def setRobot(self, robot, x, y, theta):
        self._robot = robot
        robot.setWorld(self) # the robot must know his world

        # Set robot and draw robot:
        c = Point(x,y)
        r = robot.getSize()/2
        self._robotCircle = Circle(c,r)
        self._robotTheta = theta
        p = Point(x+r*cos(theta),y+r*sin(theta))
        self._robotLine = Line(c,p) # line shows the robot's orientation
        self._robotCircle.draw(self._win)
        self._robotLine.draw(self._win)
        self._robotLine.setWidth(3)

        # Update status bar
        self._clockTimeText.setText("Clock Time: %4.2f Driven Distance: %4.2f Position: %4.2f, %4.2f, %4.2f "
                                    % (self._clockTime, self._drivenDistance, x, y, theta*180/pi))

        # Show all:
        self._udateWindow()
        print "click in window to start"
        self._win.getMouse() # pause for click in window
        #k = self.win.getKey()
        #print "key "

    # --------
    # get the true robot pose (x,y,theta).
    #
    def getTrueRobotPose(self):
        x = self._robotCircle.getCenter().getX()
        y = self._robotCircle.getCenter().getY()
        theta = self._robotTheta
        return [x,y,theta]

    # --------
    # move the robot in the direction of his self._robotTheta + dTheta/2 by the length of d
    # and then change the robot's orientation by dTheta.
    # The movement takes dt in clock time (dt is only used to change clock time output).
    # If the robot's movement is not possible because of obstacles, the movement will be not
    # performed and False is returned.
    #
    def moveRobot(self, d, dTheta, dT):
        c = self._robotCircle.getCenter()
        r = self._robotCircle.getRadius()
        x = c.getX()
        y = c.getY()
        theta = self._robotTheta
        dx = d*cos(theta+0.5*dTheta)
        dy = d*sin(theta+0.5*dTheta)
        nc = Point(x+dx,y+dy)

        if self.getNearestDistance(nc) < r: # movement is not possible because of obstacles
            print "Robot stalled: ", x, y, theta
            # raw_input("Enter: ")
            return False

        # move robot and draw robot:
        self._robotLine.undraw()
        self._robotCircle.move(dx,dy)
        self._robotTheta = (self._robotTheta + dTheta)%(2*pi)
        p = Point(x+dx+r*cos(self._robotTheta),y+dy+r*sin(self._robotTheta))
        self._robotLine = Line(nc,p)
        self._robotLine.draw(self._win)
        self._robotLine.setWidth(3)

        # Path history:
        self._drivenDistance += d
        if self._showPathHistory == True:
            pathLine = Line(c,nc)
            pathLine.setFill('red')
            pathLine.setWidth(3)
            pathLine.draw(self._win)
        #print x+dx, y+dy, self.robotTheta

         # Clear sensor values, compute new sensor values and draw it:
        self._sensorPoints = []
        self._sensorDist = []
        self.sense()
        self._drawSense()
        self._boxesSensedDist = []
        self._boxesSensedAngles = []
        self.senseBox()

        # Update clock and status bar
        self._clockTime += dT
        self._clockTimeText.setText("Clock Time: %4.2f Driven Distance: %4.2f Position: %4.2f, %4.2f, %4.2f "
                                    % (self._clockTime, self._drivenDistance, x+dx, y+dy, self._robotTheta*180/pi))

        # show all
        self._udateWindow()
        return True

    # --------
    # Compute distance values in the given direction of the robot sensors
    # If sensorShow = True, sensor beams are displayed.
    #
    def sense(self):
        if self._sensorDist == []:
            alphas = self._robot.getSensorDirections()
            distMax = self._robot.getMaxSenseValue()
            p = self._robotCircle.getCenter()
            for alpha in alphas:
                theta = (self._robotTheta+alpha) % (2*pi)
                q = self.getNearestIntersectionWithBeam(p,theta)
                #print "p: ", p.getX(), p.getY(), theta
                d = World._dist(p,q)
                #print "q: ", q.getX(), q.getY(), d
                if d > distMax:
                    self._sensorDist.append(None)
                    x = p.getX()+distMax*cos(theta)
                    y = p.getY()+distMax*sin(theta)
                    self._sensorPoints.append(Point(x,y))
                    #print "sensorPoint: ", x, y, "\n"
                else:
                    self._sensorDist.append(d)
                    self._sensorPoints.append(q)
                    #print "sensorPoint: ", q.getX(), q.getY(), "\n"
            self._drawSense()
            # print "time: ", self._clockTime, time.clock()

        return self._sensorDist


    # --------
    # Draw sensor beams.
    #
    def _drawSense(self):
        if not self._sensorShow:
            return

        # Undraw sensor beam lines:
        for l in self._sensorLines:
            l.undraw()

        # Draw new sensor beam lines:
        self._sensorLines = []
        p = self._robotCircle.getCenter()
        for q in self._sensorPoints:
            l = Line(p,q)
            l.setFill('red')
            self._sensorLines.append(l)
            l.draw(self._win)
        self._robotCircle.undraw()
        self._robotLine.undraw()
        self._robotCircle.draw(self._win)
        self._robotLine.draw(self._win)
        self._robotLine.setWidth(3)

    # --------
    # If boxSensor = True, try to detect box and
    # compute distance and orientation to the detected boxes.
    #
    def senseBox(self):
        if self._boxSensor == False:
            return None
        if self._boxesSensedDist == []:
            p = self._robotCircle.getCenter()
            for box in self._boxes:
                box.undraw()
                box.setFill('white')
                pb = box.getCenter()
                theta = atan2(pb.getY()-p.getY(), pb.getX()-p.getX())
                # print 'Box check', self._robotTheta, theta
                # angle to box relative to robot's x axis from [-pi,+pi)
                alphaBox = (self._robotTheta - theta + pi) % (2*pi) - pi
                if abs(alphaBox) <= self._boxSensorAngle/2:
                    ip = self.getNearestIntersectionWithBeam(p, theta)
                    d = World._dist(p, pb)
                    if World._dist(p, ip) > d:
                        # Box can be seen:
                        #print 'Box can be seen', d, alphaBox
                        box.setFill('red')
                        self.boxDist = World._dist(p, pb)
                        self._boxesSensedDist.append(d)
                        self._boxesSensedAngles.append(alphaBox)
                box.draw(self._win)
        #print "senseBox: ", self._boxesSensedDist,self._boxesSensedAngles
        return [self._boxesSensedDist,self._boxesSensedAngles]

    def getCursorController(self):
        return CursorController(self._win)

    # --------
    # update and draw the actual window.
    # If simulation runs to fast then delay wth a time.sleep()
    def _udateWindow(self):
        #time.sleep(0.05)
        self._win.update()
        #self.win.getMouse() # pause for click in window


    def close(self, waitForClick = True):
        if waitForClick:
            print "click in window to close"
            self._win.getMouse() # pause for click in window
        self._win.close()


    # --------
    # compute the nearest intersection point between the beam starting at point p in direction of theta
    # and a line of the world
    #
    def getNearestIntersectionWithBeam(self, p, theta):
        #print "\ntheta= ", theta*180/pi
        if len(self._lines) == 0:
            return None
        dmin = float("inf")
        ip = None
        for line in self._lines:
            #print "line: ", line.getP1().getX(),line.getP1().getY(),line.getP2().getX(),line.getP2().getY()
            q = World._intersectSegmentBeam(p,theta,line)
            if q is not None:
                #print "q =", q.getX(), q.getY(), self._dist(p,q)
                d = World._dist(p,q)
                if d < dmin:
                    dmin = d
                    ip = q
        if ip is None:
            return None
        #l = Line(p,ip)
        #l.setFill('red')
        #l.draw(self.win)
        return ip


    # --------
    # compute the distance to the line of the world which is nearest to p.
    #
    def getNearestDistance(self, p):
        if len(self._lines) == 0:
            return None
        dmin = float("inf")
        for l in self._lines:
            d = World._distPointSegment(p,l)
            #print "Distance to Line: ", l.getP1().getX(), l.getP1().getY(), l.getP2().getX(), l.getP2().getY(), d
            if d < dmin:
                dmin = d
        return dmin


    # --------
    # compute the distance between the points p and q.
    #
    @staticmethod
    def _dist(p, q):
        dx = p.getX()-q.getX()
        dy = p.getY()-q.getY()
        return sqrt(dx*dx+dy*dy)


    # --------
    # compute the distance between point p and segment line.
    #
    @staticmethod
    def _distPointSegment(p, line):
        p1 = line.getP1()
        p2 = line.getP2()
        x1 = p1.getX()
        y1 = p1.getY()
        x2 = p2.getX()
        y2 = p2.getY()
        theta = atan2(y2-y1,x2-x1)+pi/2
        ip = World._intersectSegmentBeam(p, theta, line, oppositeDirectionInclusive = True)
        if ip is None:
            # print "ip = None: "
            d1 = World._dist(p,p1)
            d2 = World._dist(p,p2)
            if d1 <= d2:
                return d1
            else:
                return d2
        else:
            # print "ip: ", ip.getX(), ip.getY()
            return World._dist(ip,p)


    # --------
    # Compute the intersection point between segment line and the beam given by p and theta.
    # If oppositeDirectionInclusive = True, then the intersection point between segment line
    # and the line through point p with grade theta is computed.
    #
    @staticmethod
    def _intersectSegmentBeam(p, theta, line, oppositeDirectionInclusive = False):
        x0 = p.getX()
        y0 = p.getY()
        x1 = line.getP1().getX()
        y1 = line.getP1().getY()
        x2 = line.getP2().getX()
        y2 = line.getP2().getY()

        delta = fabs(atan2(y2-y1,x2-x1)-theta)
        if delta < 1.0e-03 or fabs(delta-pi) < 1.0e-03:
            # line and beam are nearly parallel
            # print 'parallel'
            return None

        a = np.array([[x2-x1, -cos(theta)],
                      [y2-y1, -sin(theta)]])
        b = np.array([x0-x1,
                      y0-y1])
        k = np.linalg.solve(a, b)
        k0 = k[0]
        k1 = k[1]
        if k0 < 0 or k0 > 1:
            return None
        if not oppositeDirectionInclusive and k1 < 0:
            return None
        ip = Point(x1 + k0*(x2-x1), y1 + k0*(y2-y1))
        return ip

    def getOccupancyGrid(self, cellSize = 0.1):
        if self._grid is None:
            self._grid = OccupancyGrid(self._xll, self._yll, self._width, self._height, cellSize)
            for l in self._lines:
                x0 = l.getP1().getX()
                y0 = l.getP1().getY()
                x1 = l.getP2().getX()
                y1 = l.getP2().getY()
                self._grid.addLine(x0, y0, x1, y1)
        return self._grid
コード例 #7
0
ファイル: path.py プロジェクト: Kocolipy/SmoothControl
        # # Timing
        # from timeit import timeit
        #
        # def timing():
        #   astar(start_pose, goal_pose, occupancy_grid)
        #
        # times = []
        # for i in range(100):
        #   occupancy_grid, start_pose, goal_pose = OccupancyGrid.loadMap(grid)
        #   times.append(timeit(timing, number=1))
        # times = np.array(times)
        # print(np.mean(times))
        # print(np.std(times))

        occupancy_grid, start_pose, goal_pose = OccupancyGrid.loadMap(grid)

        path = astar(start_pose, goal_pose, occupancy_grid)
        path.append(goal_pose)

        filtered_path = los_trimming(occupancy_grid, path)
        linx, liny = zip(*filtered_path)

        edited_path = smoothing(occupancy_grid, filtered_path, start_pose)
        px, py = zip(*edited_path)

        chain = CatmullRomChain(occupancy_grid, edited_path)
        ax, ay = zip(*edited_path)

        # Combine discretised splines to form a path
        if chain:
コード例 #8
0
ファイル: AStarPlanner.py プロジェクト: kolokolca/Searistica
class AStarPlanning:
	
	def __init__(self):
		self.robotPos = Position(0,0)
		self.goalPos = None
		self.occupancy_grid = OccupancyGrid()
		self.occupancy_grid.initializeData()
		self.subscribeEvents()
		self.setMarkerPublishers()
		self.markerUniqueId = 10
		self.pathMarkerIds = []
		self.openListMarkerIds = {}
	
	def getMarkerUniqueId(self):
		self.markerUniqueId +=1
		return self.markerUniqueId

	def setMarkerPublishers(self):
		self.markerPublisher = rospy.Publisher('/planning_markers', Marker)
		self.markerArray_publisher = rospy.Publisher('/planning_multiple_markers', MarkerArray, latch=True)
		
	def subscribeEvents(self):
		rospy.Subscriber('/goal_pos', PoseStamped, self.rvizGoalPosCallBack)
	
	def rvizGoalPosCallBack(self, clickedPose):
		comandType = rospy.get_param('comandType')
		pos_x = int(clickedPose.pose.position.x)
		pos_y = int(clickedPose.pose.position.y)		
		
		if(comandType == "o"):	
			clickedPosition = Position(pos_x, pos_y)
			self.occupancy_grid.setData(clickedPosition.x, clickedPosition.y, 100)
		elif(comandType == "g"):
			r = rospy.Rate(4)
			self.publisRobotPoseMarker()
			self.deletePathMarkers()
			r.sleep()
			self.updatePlanning = True
			self.goalPos = Position(pos_x, pos_y)
			
	def deletePathMarkers(self):		
		for i in range(len(self.pathMarkerIds)):
			pathMarkerId = self.pathMarkerIds[i]
			marker = Marker()
			marker.header.frame_id = '/map'		
			marker.ns = 'AStartPlanning'
			marker.id = pathMarkerId
			marker.action = Marker.DELETE
			self.markerPublisher.publish(marker)
	
        def publisText(self, s):
		
		marker = Marker()		
		shape = Marker.TEXT_VIEW_FACING
		marker.header.frame_id = '/map'
		marker.header.stamp = rospy.Time() #rospy.Time.now()
		marker.ns = 'AStartPlanning'
		marker.id = 5
		marker.type = shape
	   	marker.action = Marker.ADD
		marker.text = s
		
		marker.pose.position.x = 17.0
		marker.pose.position.y = -3.0
		marker.pose.position.z = 2.0
		
		marker.scale.z =  1.1

		marker.color.r = 0.8
		marker.color.g = 0.0
		marker.color.b = 0.0
		marker.color.a = 0.9

		self.markerPublisher.publish(marker)
	
	def publisDrawPathLine(self):
		self.path.reverse()
		r = rospy.Rate(5)
		for i in range(len(self.path) - 1):
						
			pathPoint1 = self.path[i]
			pathPoint2 = self.path[i+1]			
			self.robotPos = Position(int(pathPoint2.x), int(pathPoint2.y))
			marker = Marker()		
			shape = Marker.LINE_STRIP
			marker.header.frame_id = '/map'
			marker.header.stamp = rospy.Time() #rospy.Time.now()
			marker.ns = 'AStartPlanning'
			marker.id = self.getMarkerUniqueId()
			self.pathMarkerIds.append(marker.id)
			marker.type = shape
			marker.action = Marker.ADD
			marker.points = [pathPoint1, pathPoint2]
			
			marker.scale.x = 0.4
			marker.scale.y = 1.0
			marker.scale.z = 1.0

			marker.color.r = 0.0
			marker.color.g = 1.0
			marker.color.b = 1.0
			marker.color.a = 1.0

			self.publisRobotPoseMarker()
			self.markerPublisher.publish(marker)
			r.sleep()
		
	def robotPosChangedCallback(self, robotPos):
		self.robotPos = robotPos
		self.cmd_robotPos_sub.unregister()
		
	def goalPosChangedCallback(self, goalPos):
		self.goalPos = goalPos
	
	def computeEquledianDistance(self, currentCell):
		xDistance =  self.goalPos.x - currentCell.x
		yDistance =  self.goalPos.y - currentCell.y 		
		return math.sqrt( math.pow(xDistance, 2) + math.pow(yDistance, 2) )
		
	def computeH(self, childGridCell):
		childGridCell.hVal = self.computeEquledianDistance(childGridCell)
	
	def oneCellMoveCost(self):
		return 1;
	
	def isAnObstacle(self, gridCell):
		gridCellData = self.occupancy_grid.data[gridCell.x][gridCell.y]
		if(gridCellData == 100):
			return True
		return False
		
	def getCellCost(self, gridCell):
		if(self.isAnObstacle(gridCell)):
			return 100
		return 1
		
	def computeG(self, gridCell):
		if(gridCell.parentGridCell is None):
			gridCell.gVal = 0
		else:			
			gridCell.gVal = gridCell.parentGridCell.gVal + self.getCellCost(gridCell)
		
	def computeTotalCost(self, childGridCell):
		self.computeG(childGridCell)
		self.computeH(childGridCell)
		return childGridCell.getCost()
	
	def isGoalGridCell(self, currentCell):
		return currentCell.x == self.goalPos.x and currentCell.y == self.goalPos.y
		
	def isInRange(self, x, y):
		return (x >= 0 and y >= 0) and ( x < self.occupancy_grid.dimension.width and y < self.occupancy_grid.dimension.height)
	
	def getAdjacentCells(self, currentCell):
		
		adjacentCells = []
		x = currentCell.x
		y = currentCell.y		
		
		if(self.isInRange(x + 1, y)):
			gridCell = GridCell(x + 1, y,currentCell)
			if(self.isAnObstacle(gridCell) == False):
				adjacentCells.append(gridCell)
					
		if(self.isInRange(x + 1, y + 1)):
			gridCell = GridCell(x + 1, y + 1,currentCell)
			if(self.isAnObstacle(gridCell) == False):
				adjacentCells.append(gridCell)
		
		if(self.isInRange(x, y + 1)):
			gridCell = GridCell(x, y + 1,currentCell)
			if(self.isAnObstacle(gridCell) == False):
				adjacentCells.append(gridCell)
		
		if(self.isInRange(x - 1, y + 1)):
			gridCell = GridCell(x - 1, y + 1,currentCell)
			if(self.isAnObstacle(gridCell) == False):
				adjacentCells.append(gridCell)
		
		if(self.isInRange(x - 1, y)):
			gridCell = GridCell(x - 1, y,currentCell)
			if(self.isAnObstacle(gridCell) == False):
				adjacentCells.append(gridCell)
		
		if(self.isInRange(x - 1, y - 1)):
			gridCell = GridCell(x - 1, y - 1,currentCell)
			if(self.isAnObstacle(gridCell) == False):
				adjacentCells.append(gridCell)
		
		if(self.isInRange(x, y - 1)):
			gridCell = GridCell(x, y - 1, currentCell)
			if(self.isAnObstacle(gridCell) == False):
				adjacentCells.append(gridCell)
		
		if(self.isInRange(x + 1, y - 1)):
			gridCell = GridCell(x + 1, y - 1,currentCell)
			if(self.isAnObstacle(gridCell) == False):
				adjacentCells.append(gridCell)
		
		return adjacentCells
	
	def printAdjacentCells(self, adjs):
		s = "Adjs : "
		for i in range(len(adjs)):
			adj = adjs[i]
			s += "(" + str(adj.x) + "," + str(adj.y) + ") "  
		print s
		
	def getPath(self, gridCell):
		self.path.append(Point(gridCell.x + 0.5 ,gridCell.y + 0.5, 1))
		if(gridCell.x == self.robotPos.x and gridCell.y == self.robotPos.y):
			return
		
		self.getPath(gridCell.parentGridCell)		 
	
	def publisMultipleMarkers(self, dictionary):
		l = dictionary.items()
		
		marker_array = MarkerArray()		
		r = rospy.Rate(25)
		life = 6
		for i in range(len(l)):
			
			(key, gridCell) = l[i]
			marker = Marker()
			marker.header.frame_id = '/map'
			marker.header.stamp = rospy.Time()
			marker.ns = 'AStartPlanning'
			markerId = str(gridCell.x) +"_" + str(gridCell.y)
			if(markerId in self.openListMarkerIds):
				marker.id = self.openListMarkerIds[markerId]
			else:
				marker.id = self.getMarkerUniqueId()
				self.openListMarkerIds[markerId] = marker.id
			
			marker.type = Marker.CUBE
			marker.action = Marker.ADD
			marker.lifetime = rospy.Duration(life, 0)
			
			marker.pose.position.x = gridCell.x + 0.5
			marker.pose.position.y = gridCell.y + 0.5
			
			marker.scale.x = 1.0
			marker.scale.y = 1.0
			marker.scale.z = 1.0

			
			marker.color.r = 0.0
			marker.color.g = 100.0
			marker.color.b = 0.0
			marker.color.a = 0.7

			marker_array.markers.append(marker)				

		self.markerArray_publisher.publish(marker_array)
		r.sleep()
	
	def computePlan(self):
		
		if(self.robotPos != None and self.goalPos != None):			
			start = time.time()						
			startGridCell = GridCell(self.robotPos.x, self.robotPos.y, None)
			priorityQueue = PriorityQueue()
			closeList = {}
			openList = {}
			openList[startGridCell.getKey()] = startGridCell
			self.computeTotalCost(startGridCell)
			priorityQueue.push(startGridCell.getCost(),startGridCell)
			goal = None
			
			while(len(openList) > 0):		
				(cost, currentCell) = priorityQueue.pop()							
				#print "low cell:(", currentCell.x , currentCell.y, ") cost:", cost
				if(currentCell.getKey() in openList):
					del openList[currentCell.getKey()]
				
				if(self.isGoalGridCell(currentCell)):
					goal = currentCell
					break
				else:					
					adjacentCells = self.getAdjacentCells(currentCell)
					#self.printAdjacentCells(adjacentCells)
					#print "\n"
										
					for index in range(len(adjacentCells)):
						adjacentCell = adjacentCells[index]						
						allReadyVisited = adjacentCell.getKey() in closeList						
						if(allReadyVisited): continue
						self.computeTotalCost(adjacentCell)
						#print "Adj:(" , adjacentCell.x , adjacentCell.y , ") " , "cost:", adjacentCell.getCost() 
						exploredBefore = adjacentCell.getKey() in openList
						if(exploredBefore == False):							
							openList[adjacentCell.getKey()] = adjacentCell							
							priorityQueue.push(adjacentCell.getCost(),adjacentCell)
							#print "Adj:(" , adjacentCell.x , adjacentCell.y , ") ", "not in open list, added to open list"
						else:
							oldAdjacentCell = openList[adjacentCell.getKey()]
							#print "found old Adj:(" , oldAdjacentCell.x , oldAdjacentCell.y , ") " , "cost:", oldAdjacentCell.getCost(), " parent:" , oldAdjacentCell.parentGridCell.x , oldAdjacentCell.parentGridCell.y
							if(adjacentCell.getCost() < oldAdjacentCell.getCost()):
								oldAdjacentCell.setParent(currentCell)
								self.computeTotalCost(oldAdjacentCell)
								#print "old Adj upadte:(" , oldAdjacentCell.x , oldAdjacentCell.y , ") " , "new cost:", oldAdjacentCell.getCost(), " new parent:" , oldAdjacentCell.parentGridCell.x , oldAdjacentCell.parentGridCell.y
							#else:
								#print "Old Adj not updated"
						#print "\n"	
						
					closeList[currentCell.getKey()] = currentCell
					self.publisMultipleMarkers(closeList)
					#print "low cell:(", currentCell.x , currentCell.y, ") cost:", cost, " REMOVED"
					#print "-----------"		
			
			#print "Goal:", goal.x, goal.y
			
			end = time.time()
			elapsed = end - start
			s = "Time taken: " + str(elapsed) + " seconds.\n"
			s += "Total node expanded: " + str(len(closeList)) + " out of " + "(30 * 30) = 900. \n"
			self.path = []
			if(goal is not None):
				self.getPath(goal)				
				self.publisDrawPathLine()
			else:
				s = "Goal not found !!!"
			
			self.publisText(s)
	
	def publisRobotPoseMarker(self):
		
		marker = Marker()		
		shape = Marker.SPHERE
		marker.header.frame_id = '/map'
		marker.header.stamp = rospy.Time()
		marker.ns = 'AStartPlanning'
		marker.id = 1
		marker.type = shape
	   	marker.action = Marker.ADD

		marker.pose.position.x = self.robotPos.x + 0.5
		marker.pose.position.y = self.robotPos.y + 0.5
		marker.pose.position.z = 1.0

		marker.scale.x = 0.75
		marker.scale.y = 0.75
		marker.scale.z = 1.0

		marker.color.r = 0.0
		marker.color.g = 1.0
		marker.color.b = 0.0
		marker.color.a = 0.75

		self.markerPublisher.publish(marker)

	def makePalnning(self):
		r = rospy.Rate(5)
		print 'Running A start planner'
		self.publisRobotPoseMarker()
		while not rospy.is_shutdown():
			if self.updatePlanning:
				self.computePlan()				
				self.updatePlanning = False			
			r.sleep()
コード例 #9
0
 def __init__(self):
     self.agent_data = {}
     self.occupancy_grid = occ.OccupancyGrid()