UserPreferences

ExampleChase


In this example, two robots are placed into the same circular world as used in the previous example. One robot is green and seeks out red, while the other robot is red and seeks out green. Both robots also avoid obstacles. Typically the robots will end up in the center of the environment in a tight circle after a few seconds. Try dragging one robot to a new location to see how they adjust.

Here is a Pyro brain to control the robot that seeks out red.

  1 
  2 
  3 
  4 
  5 
  6 
  7 
  8 
  9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 48 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71 
 72 
 73 
 74 
 75 
 76 
 77 
 78 
 79 
 80 
 81 
 82 
 83 
 84 
 85 
 86 
 87 
 88 
 89 
 90 
 91 
 92 
 93 
 94 
 95 
 96 
 97 
 98 
 99 
100 
101 

# OUT_OF_DATE! THIS USES THE OLD PLAYER INTERNAL BLOB DATA STRUCTURES

from pyrobot.brain import Brain

# Seeks out red blobs
class FindBlobs(Brain):
    def setup(self):
        self.startDevice('blobfinder')

    def destroy(self):
        self.removeDevice('blobfinder')

    def step(self):
        self.seekColor('red')

    def seekColor(self, color):
        minRange = 0.9
        if self.collisionImminent('front-all', minRange):
            translate, rotate = self.avoid(minRange)
            self.move(translate, rotate)
        else:
            result = self.getLargestBlob(color)
            if result == None:
                leftSide = min([s.distance() for s in self.robot.range["front-left"]])
                rightSide = min([s.distance() for s in self.robot.range["front-right"]])
                if leftSide < rightSide:
                    self.move(0.1, -0.5)
                else:
                    self.move(0.1, 0.5)
            else:
                (turnDirection, distance) = result
                if turnDirection > 0:
                    self.move(0.1, 0.15)
                elif turnDirection < 0:
                    self.move(0.1, -0.15)
                else:
                    self.move(0.2, 0)

    # Returns True when the minimum sonar value from the given location
    # group is less than the minRange.
    def collisionImminent(self, location, minRange):
        return min([s.distance() for s in self.robot.range[location]]) < minRange

    # Returns translate and rotate values for avoiding obstacles.
    def avoid(self, minRange):
        if self.collisionImminent('front', minRange):
            return 0, -0.3
        elif self.collisionImminent('front-left', minRange):
            return 0, -0.3
        elif self.collisionImminent('front-right', minRange):
            return 0, 0.3
        else:
            return 0.2, 0

    # Returns a list of all blobs of the given color.
    def getBlobs(self, color):
        data = self.robot.blobfinder.data
        (width, height) = data[0]
        colorChannels = data[1]
        if color == 'red':
           index = 0
        elif color == 'green':
           index = 1
        elif color == 'blue':
           index = 2
        else:
           raise ValueError, 'unrecognized color channel: %s' % color
        blobs = colorChannels[index]
        return blobs

    # Returns the direction (+1, -1, or 0) to the largest blob of the
    # specified color along with the distance to the blob.  The blob
    # information consists of a list of nine features:
    #     (colorCode, area, xc, yc, x0, x1, y0, y1, distance)
    # xc is an integer between 0 and 160 which represents the x position of
    # the blob's center.  A value of 0 indicates that the blob is at the
    # farthest left location, a value of 80 indicates that the blob is
    # centered, and a value of 160 indicates that the blob is at the farthest
    # right location.  Distance is an integer representing the distance to the
    # blob.  When using a Pioneer robot with a gripper, if the blob is
    # centered, then a range of 380 indicates that it is within the grasp of
    # the gripper.
    def getLargestBlob(self, color):
        allBlobs = self.getBlobs(color)
        if len(allBlobs) == 0:
            return None
        else:
            largestBlob = allBlobs[0]
            (colorCode, area, xc, yc, x0, x1, y0, y1, distance) = largestBlob
            if xc < 75:
                turnDirection = +1
            elif xc > 85:
                turnDirection = -1
            else:
                turnDirection = 0
            return (turnDirection, distance)


def INIT(engine):
   return FindBlobs('FindBlobs', engine)

Save the above code into a file called ChaseRedProgram.py. Then copy this code to a file called ChaseGreenProgram.py and change the argument in the call to seekColor from red to green.

Now try out this example by executing the following commands:

pyro -s StageSimulator -w chase.world -r Player6665 -b ChaseRedProgram.py & 
pyro -r Player6666 -b ChaseGreenProgram.py 

Press the Run button in each Pyro window to get the robots started.

Return to PyroModuleMultirobot.