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.
