UserPreferences

ModifiedAvoidTraining


1. Training a Robot Using a Modified Avoid Brain

1.1. Gathering Data and Training

In the avoid brain included with pyrobot, when the robot is coming straight to a wall, the behaviour is always turn to the right, no matter if there is an object to the right or not. I decided to modify the brain to check its right and left sensors as well to determine which direction the robot should turn. I also tweaked the speeds at which the robot is moving at certain times. Afterwards, I added code to record its front motor sensor values and the resulting translation and rotation in order to use this data to train a neural network.
# robot goes forward and then slows to a stop when it detects something   
   
from pyrobot.brain import Brain  
   
class Avoid(Brain):  

   def setup(self):
      #self.robot.range.units = "scaled"
      self.inputFile = open("avoid_inputs.dat", "w")
      self.targetFile = open("avoid_targets.dat", "w")
   
   def convert_motors(self, x, y):
      x, y = (x+1)/2.0, (y+1)/2.0
      return (x, y)
   
   # Give the front two sensors, decide the next move  
   def determineMove(self, front, left, right):
      self.robot.range.units = "scaled"
      for i in range(len(self.robot.range["front-all"])):
         self.inputFile.write("%f " % self.robot.range[i].distance())
      self.inputFile.write("\n")
      self.robot.range.units = "robots"
      if front < 0.5:
         if left < 0.7:
            print "obstacle ahead, hard turn from left"
            x = self.convert_motors(0.0, -.3)
            self.targetFile.write("%f %f\n" % x)
            return (0, -.3)
         elif right < 0.7:
            print "obstacle ahead, hard turn from right"
            x = self.convert_motors(0.0, .3)
            self.targetFile.write("%f %f\n" % x)
            return (0, .3)
         else:
            print "obstacle ahead, hard turn"
            x = self.convert_motors(0.0, .3)
            self.targetFile.write("%f %f\n" % x)
            return(0, .3)  
      elif left < 0.8:
         print "object detected on left, slow turn"
         x = self.convert_motors(0.1, -.2)
         self.targetFile.write("%f %f\n" % x)
         return(0.1, -.2)  
      elif right < 0.8: 
         print "object detected on right, slow turn"
         x = self.convert_motors(0.1, .2)
         self.targetFile.write("%f %f\n" % x)
         return(0.1, .2)  
      else:  
         print "clear"
         x = self.convert_motors(0.5, 0.0)
         self.targetFile.write("%f %f\n" % x)
         return(0.5, 0.0) 
      
   def step(self):  
      front = min([s.distance() for s in self.robot.range["front"]])
      left = min([s.distance() for s in self.robot.range["front-left"]])
      right = min([s.distance() for s in self.robot.range["front-right"]])
      translation, rotate = self.determineMove(front, left, right)  
      self.robot.move(translation, rotate)



def INIT(engine):  
   assert (engine.robot.requires("range-sensor") and
           engine.robot.requires("continuous-movement"))
   return Avoid('Avoid', engine)

After training a neural network to learn this with .2 tolerance and two hidden units, I ran another robot using these weights. I originally trained it in the tutorial world.

1.2. Results

This is the screenshot of the robot run through the training data:

http://bubo.brynmawr.edu/~jferraio/images/data_collection.png

This is the screenshot of the robot using the trained weights:

http://bubo.brynmawr.edu/~jferraio/images/trained.png

With this training data, it seemed like the robot was learning a path, rather than learning to avoid objects. Instead of gathering data in a world with obstacles, I decided to use an empty room, and then run it in a different world altogether. While trained robot would stall occasionally, it seemed like it had learned to avoid objects instead of following a specific path.