コード例 #1
0
    def run(self):
        """ Runs simulations by quering the robot """
        self.reset()

        # Initialize robot object
        robot = Robot(self.speed, self.turning_speed, self.gps_delay, self.sonar_time, self.tick_move, self.tick_rotate)
        robot.set(self.init_position[0], self.init_position[1], self.init_position[2])
        robot.set_noise(self.steering_noise, self.distance_noise, self.measurement_noise, self.sonar_noise)

        # Initialize robot controller object given by contestant
        robot_controller = PythonTimedRobotController(self.robot_controller)
        robot_controller.init(
            self.init_position,
            robot.steering_noise,
            robot.distance_noise,
            robot.sonar_noise,
            robot.measurement_noise,
            self.speed,
            self.turning_speed,
            self.gps_delay,
            self.execution_cpu_time_limit,
        )

        maximum_timedelta = datetime.timedelta(seconds=self.execution_cpu_time_limit)

        self.robot_path.append((robot.x, robot.y))
        collision_counter = 0  # We have maximum collision allowed

        frame_time_left = self.simulation_dt
        frame_count = 0
        current_command = None
        iteration = 0
        communicated_finished = False
        try:
            while (
                not communicated_finished
                and not robot.time_elapsed >= self.simulation_time_limit
                and not self.terminate_flag
            ):
                # logger.info(robot_controller.time_consumed)

                if maximum_timedelta <= robot_controller.time_consumed:
                    raise KrakrobotException("Robot has exceeded CPU time limit")

                if iteration % self.iteration_write_frequency == 0:
                    logger.info("Iteration {0}, produced {1} frames".format(iteration, frame_count))
                    logger.info("Elapsed {0}".format(robot.time_elapsed))
                    logger.info(current_command)

                iteration += 1

                time.sleep(self.simulation_dt)
                if frame_time_left > self.frame_dt and self.visualisation:
                    ### Save frame <=> last command took long ###
                    if (
                        len(self.robot_path) == 0
                        or robot.x != self.robot_path[-1][0]
                        or robot.y != self.robot_path[-1][1]
                    ):
                        self.robot_path.append((robot.x, robot.y))
                    self.sim_frames.put(self._create_sim_data(robot))

                    frame_count += 1
                    frame_time_left -= self.frame_dt

                if current_command is not None:
                    ### Process current command ###

                    if current_command[0] == TURN:

                        robot = robot.turn(1) if current_command[1] > 0 else robot.turn(-1)
                        if current_command[1] > 1:
                            current_command = [current_command[0], current_command[1] - 1]
                        elif current_command[1] < 1:
                            current_command = [current_command[0], current_command[1] + 1]
                        else:
                            current_command = None

                        frame_time_left += self.tick_rotate / self.turning_speed

                    elif current_command[0] == MOVE:
                        robot_proposed = robot.move(1)

                        if not robot_proposed.check_collision(self.grid):
                            collision_counter += 1
                            self.collisions.append((robot_proposed.x, robot_proposed.y))
                            logger.error("##Collision##")
                            if collision_counter >= KrakrobotSimulator.COLLISION_THRESHOLD:
                                raise KrakrobotException(
                                    "The robot has been destroyed by wall. Sorry! We miss WALLE already.."
                                )
                        else:
                            robot = robot_proposed

                        ### Register movement, just do not move the robot

                        if current_command[1] > 1:
                            current_command = [current_command[0], current_command[1] - 1]
                        else:
                            current_command = None
                        frame_time_left += self.tick_move / self.speed

                else:
                    ### Get current command ###

                    command = None
                    try:
                        command = list(robot_controller.act())
                    except Exception, e:
                        logger.error("Robot controller failed with exception " + str(e))
                        break
                    # logger.info("Received command "+str(command))
                    # logger.info("Robot timer "+str(robot.time_elapsed))
                    if not command or len(command) == 0:
                        raise KrakrobotException("No command passed, or zero length command passed")

                    # Dispatch command
                    if command[0] == SENSE_GPS:
                        robot_controller.on_sense_gps(*robot.sense_gps())
                        frame_time_left += self.gps_delay
                    elif command[0] == WRITE_CONSOLE:
                        new_line = (
                            "{'frame': "
                            + str(frame_count)
                            + ", 'time': "
                            + str(robot.time_elapsed)
                            + "}:\n"
                            + command[1]
                        )
                        self.logs.append(new_line)
                        if self.print_robot:
                            print new_line
                    elif command[0] == SENSE_SONAR:
                        w = robot.sense_sonar(self.grid)
                        robot_controller.on_sense_sonar(w)
                        frame_time_left += self.sonar_time
                    elif command[0] == SENSE_FIELD:
                        w = robot.sense_field(self.grid)
                        if w == MAP_GOAL:
                            print robot.x, " ", robot.y, " ", w
                        if type(w) is not list:
                            robot_controller.on_sense_field(w, 0)
                        else:
                            robot_controller.on_sense_field(w[0], w[1])

                        frame_time_left += self.light_sensor_time
                    elif command[0] == TURN:
                        if len(command) <= 1 or len(command) > 2:
                            raise KrakrobotException("Wrong command length")
                        current_command = command
                        current_command[1] = int(current_command[1])
                        # Turn robot
                        # robot = robot.turn(command[1])

                    elif command[0] == MOVE:
                        if len(command) <= 1 or len(command) > 2:
                            raise KrakrobotException("Wrong command length")

                        if command[1] < 0:
                            raise KrakrobotException("Not allowed negative distance")
                        # Move robot

                        current_command = command
                        current_command[1] = int(current_command[1])
                    elif command[0] == FINISH:
                        logger.info("Communicated finishing")
                        communicated_finished = True

                    else:
                        raise KrakrobotException("Not received command from act(), or command was incorrect :(")

        except Exception, e:
            logger.error("Simulation failed with exception " + str(e) + " after " + str(robot.time_elapsed) + " time")
            return {
                "time_elapsed": robot.time_elapsed,
                "goal_achieved": False,
                "time_consumed_robot": robot_controller.time_consumed.total_seconds() * 1000,
                "error": str(e),
            }