Advertisement
Guest User

MIT Robot Simulation

a guest
Oct 31st, 2014
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.72 KB | None | 0 0
  1. # 6.00.2x Problem Set 2: Simulating robots
  2.  
  3. import math
  4. import random
  5.  
  6. import ps2_visualize
  7. import pylab
  8.  
  9. # For Python 2.7:
  10. from ps2_verify_movement27 import testRobotMovement
  11.  
  12. # If you get a "Bad magic number" ImportError, you are not using
  13. # Python 2.7 and using most likely Python 2.6:
  14.  
  15.  
  16. # === Provided class Position
  17. class Position(object):
  18.     """
  19.    A Position represents a location in a two-dimensional room.
  20.    """
  21.     def __init__(self, x, y):
  22.         """
  23.        Initializes a position with coordinates (x, y).
  24.        """
  25.         self.x = x
  26.         self.y = y
  27.        
  28.     def getX(self):
  29.         return self.x
  30.    
  31.     def getY(self):
  32.         return self.y
  33.    
  34.     def getNewPosition(self, angle, speed):
  35.         """
  36.        Computes and returns the new Position after a single clock-tick has
  37.        passed, with this object as the current position, and with the
  38.        specified angle and speed.
  39.  
  40.        Does NOT test whether the returned position fits inside the room.
  41.  
  42.        angle: number representing angle in degrees, 0 <= angle < 360
  43.        speed: positive float representing speed
  44.  
  45.        Returns: a Position object representing the new position.
  46.        """
  47.         old_x, old_y = self.getX(), self.getY()
  48.         angle = float(angle)
  49.         # Compute the change in position
  50.         delta_y = speed * math.cos(math.radians(angle))
  51.         delta_x = speed * math.sin(math.radians(angle))
  52.         # Add that to the existing position
  53.         new_x = old_x + delta_x
  54.         new_y = old_y + delta_y
  55.         return Position(new_x, new_y)
  56.  
  57.     def __str__(self):  
  58.         return "(%0.2f, %0.2f)" % (self.x, self.y)
  59.  
  60.  
  61. # === Problem 1
  62. class RectangularRoom(object):
  63.     """
  64.    A RectangularRoom represents a rectangular region containing clean or dirty
  65.    tiles.
  66.  
  67.    A room has a width and a height and contains (width * height) tiles. At any
  68.    particular time, each of these tiles is either clean or dirty.
  69.    """
  70.     def __init__(self, width, height):
  71.         """
  72.        Initializes a rectangular room with the specified width and height.
  73.  
  74.        Initially, no tiles in the room have been cleaned.
  75.  
  76.        width: an integer > 0
  77.        height: an integer > 0
  78.        """
  79.         self.width = width
  80.         self.height = height
  81.         self.room = []
  82.         for i in range(height):
  83.             self.room.append([])
  84.             for j in range(width):
  85.                 self.room[i].append(False)
  86.    
  87.     def cleanTileAtPosition(self, pos):
  88.         """
  89.        Mark the tile under the position POS as cleaned.
  90.  
  91.        Assumes that POS represents a valid position inside this room.
  92.  
  93.        pos: a Position
  94.        """
  95.         self.room[int(pos.getY())][int(pos.getX())] = True
  96.  
  97.     def isTileCleaned(self, m, n):
  98.         """
  99.        Return True if the tile (m, n) has been cleaned.
  100.  
  101.        Assumes that (m, n) represents a valid tile inside the room.
  102.  
  103.        m: an integer
  104.        n: an integer
  105.        returns: True if (m, n) is cleaned, False otherwise
  106.        """
  107.         return self.room[n][m]
  108.    
  109.     def getNumTiles(self):
  110.         """
  111.        Return the total number of tiles in the room.
  112.  
  113.        returns: an integer
  114.        """
  115.         return self.width * self.height
  116.  
  117.     def getNumCleanedTiles(self):
  118.         """
  119.        Return the total number of clean tiles in the room.
  120.  
  121.        returns: an integer
  122.        """
  123.         tot = 0
  124.         for i in range(self.height):
  125.             for j in range(self.width):
  126.                 if self.room[i][j] == True:
  127.                     tot += 1
  128.         return tot
  129.  
  130.     def getRandomPosition(self):
  131.         """
  132.        Return a random position inside the room.
  133.  
  134.        returns: a Position object.
  135.        """
  136.         rand_y = random.randrange(0, self.height)
  137.         rand_x = random.randrange(0, self.width)
  138.         p = Position(rand_x, rand_y)
  139.         return p
  140.  
  141.     def isPositionInRoom(self, pos):
  142.         """
  143.        Return True if pos is inside the room.
  144.  
  145.        pos: a Position object.
  146.        returns: True if pos is in the room, False otherwise.
  147.        """
  148.         return (pos.getY() < self.height and pos.getY() >= 0) and (pos.getX() < self.width and pos.getX() >= 0)
  149.  
  150.  
  151.  
  152. class Robot(object):
  153.     """
  154.    Represents a robot cleaning a particular room.
  155.  
  156.    At all times the robot has a particular position and direction in the room.
  157.    The robot also has a fixed speed.
  158.  
  159.    Subclasses of Robot should provide movement strategies by implementing
  160.    updatePositionAndClean(), which simulates a single time-step.
  161.    """
  162.     def __init__(self, room, speed):
  163.         """
  164.        Initializes a Robot with the given speed in the specified room. The
  165.        robot initially has a random direction and a random position in the
  166.        room. The robot cleans the tile it is on.
  167.  
  168.        room:  a RectangularRoom object.
  169.        speed: a float (speed > 0)
  170.        """
  171.         self.room = room
  172.         self.speed = speed
  173.         self.direction = random.randrange(0, 360)
  174.         self.position = self.room.getRandomPosition()
  175.         self.room.cleanTileAtPosition(self.position)
  176.  
  177.     def getRobotPosition(self):
  178.         """
  179.        Return the position of the robot.
  180.  
  181.        returns: a Position object giving the robot's position.
  182.        """
  183.         return self.position
  184.    
  185.     def getRobotDirection(self):
  186.         """
  187.        Return the direction of the robot.
  188.  
  189.        returns: an integer d giving the direction of the robot as an angle in
  190.        degrees, 0 <= d < 360.
  191.        """
  192.         return self.direction
  193.  
  194.     def setRobotPosition(self, position):
  195.         """
  196.        Set the position of the robot to POSITION.
  197.  
  198.        position: a Position object.
  199.        """
  200.         self.position = position
  201.  
  202.     def setRobotDirection(self, direction):
  203.         """
  204.        Set the direction of the robot to DIRECTION.
  205.  
  206.        direction: integer representing an angle in degrees
  207.        """
  208.         self.direction = direction
  209.  
  210.     def updatePositionAndClean(self):
  211.         """
  212.        Simulate the raise passage of a single time-step.
  213.  
  214.        Move the robot to a new position and mark the tile it is on as having
  215.        been cleaned.
  216.        """
  217.         raise NotImplementedError # don't change this!
  218.  
  219. # === Problem 2
  220. class StandardRobot(Robot):
  221.     """
  222.    A StandardRobot is a Robot with the standard movement strategy.
  223.  
  224.    At each time-step, a StandardRobot attempts to move in its current
  225.    direction; when it would hit a wall, it *instead* chooses a new direction
  226.    randomly.
  227.    """
  228.     def updatePositionAndClean(self):
  229.         """
  230.        Simulate the raise passage of a single time-step.
  231.  
  232.        Move the robot to a new position and mark the tile it is on as having
  233.        been cleaned.
  234.        """
  235.         current_position = self.getRobotPosition()
  236.         new_position = current_position.getNewPosition(self.direction, self.speed)
  237.        
  238.         while self.room.isPositionInRoom(new_position) == False:
  239.             self.direction = random.randrange(0, 360)
  240.             new_position = current_position.getNewPosition(self.direction, self.speed)
  241.    
  242.         self.position = new_position
  243.         self.room.cleanTileAtPosition(new_position)
  244.    
  245.  
  246. # Uncomment this line to see your implementation of StandardRobot in action!
  247. #testRobotMovement(StandardRobot, RectangularRoom)
  248.  
  249.  
  250. # === Problem 3
  251. def generateMove(robot):
  252.     # this function gets a robot and moves him based on this direction and speed. If it moved him to a valid position in the room, it cleans it. If not, it spends that time step
  253.     # setting him a new random direction
  254.     current_position = robot.getRobotPosition()
  255.     new_position = current_position.getNewPosition(robot.direction, robot.speed)
  256.     if robot.room.isPositionInRoom(new_position) == True:
  257.         robot.setRobotPosition(new_position)
  258.         robot.room.cleanTileAtPosition(robot.position)
  259.     else:
  260.         robot.setRobotDirection(random.randrange(0, 360))
  261.        
  262.  
  263. def runSimulation(num_robots, speed, width, height, min_coverage, num_trials,
  264.                   robot_type):
  265.     """
  266.    Runs NUM_TRIALS trials of the simulation and returns the mean number of
  267.    time-steps needed to clean the fraction MIN_COVERAGE of the room.
  268.  
  269.    The simulation is run with NUM_ROBOTS robots of type ROBOT_TYPE, each with
  270.    speed SPEED, in a room of dimensions WIDTH x HEIGHT.
  271.  
  272.    num_robots: an int (num_robots > 0)
  273.    speed: a float (speed > 0)
  274.    width: an int (width > 0)
  275.    height: an int (height > 0)
  276.    min_coverage: a float (0 <= min_coverage <= 1.0)
  277.    num_trials: an int (num_trials > 0)
  278.    robot_type: class of robot to be instantiated (e.g. StandardRobot or
  279.                RandomWalkRobot)
  280.    """
  281.    
  282.    
  283.     results = []
  284.     # for numTrials
  285.     for i in range(num_trials):
  286.         # create room and robots
  287.         room = RectangularRoom(width, height)
  288.         robots = []
  289.         for i in range(num_robots):
  290.             robot = robot_type(room, speed)
  291.             robots.append(robot)
  292.  
  293.         # calculate current coverage
  294.         current_coverage = room.getNumCleanedTiles() / float(room.getNumTiles())
  295.         steps = 0
  296.        
  297.         # until min_coverage is satisfied
  298.         while current_coverage < min_coverage:
  299.             # move every robot. add one time-step to counter. recalculate current coverage of room.
  300.             for robot in robots:
  301.                 generateMove(robot)
  302.             steps += 1
  303.             current_coverage = room.getNumCleanedTiles() / float(room.getNumTiles())
  304.         # append result of this trial    
  305.         results.append(steps)
  306.     # return average of time steps taken by the robots in all the simulations    
  307.     return sum(results) / float(len(results))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement