示例#1
0
    def _initialize(self, **kwargs):
        """
        :param kwargs:
        :return:
        """

        super(CoreComponentWithMics, self)._initialize(**kwargs)

        half_width = WIDTH / 2.0
        right_angle = 3.14159265 / 2.0

        # rotates clockwise around axis by angle:
        mic_pose_1 = Pose(position=Vector3(0, half_width, 0),
                          rotation=Quaternion.from_angle_axis(
                              angle=right_angle, axis=Vector3(-1, 0, 0)))

        mic_pose_2 = Pose(position=Vector3(half_width, 0, 0),
                          rotation=Quaternion.from_angle_axis(
                              angle=right_angle, axis=Vector3(0, 1, 0)))

        mic_pose_3 = Pose(position=Vector3(0, -half_width, 0),
                          rotation=Quaternion.from_angle_axis(
                              angle=right_angle, axis=Vector3(1, 0, 0)))

        mic_pose_4 = Pose(position=Vector3(-half_width, 0, 0),
                          rotation=Quaternion.from_angle_axis(
                              angle=right_angle, axis=Vector3(0, -1, 0)))

        # The second argument ("direction") is the type of the sensor that is checked in SensorFactory.cpp.
        # Any existing type of gazebo sensors can be used. Beside that, a new type can be registered in WorldController.cpp
        mic_1 = SdfSensor("dir_sensor_1",
                          "direction",
                          pose=mic_pose_1,
                          update_rate=self.conf.sensor_update_rate)
        mic_2 = SdfSensor("dir_sensor_2",
                          "direction",
                          pose=mic_pose_2,
                          update_rate=self.conf.sensor_update_rate)
        mic_3 = SdfSensor("dir_sensor_3",
                          "direction",
                          pose=mic_pose_3,
                          update_rate=self.conf.sensor_update_rate)
        mic_4 = SdfSensor("dir_sensor_4",
                          "direction",
                          pose=mic_pose_4,
                          update_rate=self.conf.sensor_update_rate)

        self.link.add_sensor(mic_1)
        self.link.add_sensor(mic_2)
        self.link.add_sensor(mic_3)
        self.link.add_sensor(mic_4)
示例#2
0
def do_mate(world, ra, rb):
    """
    :param world:
    :param ra:
    :param rb:
    :return:
    """
    mate = None
    num_attempts = 0
    while num_attempts < 10:
        # Attempt reproduction
        mate = yield From(world.attempt_mate(ra, rb))

        if mate:
            break
        num_attempts += 1


#    logger.debug("Mates selected, highlighting points...")

    new_pos = pick_position()
    new_pos.z = insert_z
    #    hls = yield From(create_highlights(
    #        world, ra.last_position, rb.last_position, new_pos))
    #    yield From(trollius.sleep(2))
    if mate:
        logger.debug("Inserting child...")
        child, bbox = mate
        pose = Pose(position=new_pos)
        spawn_robot(world, tree=child, pose=pose, parents=[ra, rb])
    else:
        logger.debug("Could not mate")
示例#3
0
def do_mate(world, ra, rb):
    """

    :param world:
    :param ra:
    :param rb:
    :return:
    """
    mate = None
    while True:
        # Attempt reproduction
        mate = yield From(world.attempt_mate(ra, rb))

        if mate:
            break

    logger.debug("Mates selected, highlighting points...")

    new_pos = get_insert_position(world.conf, ra, rb, world)
    new_pos.z = insert_z
    hls = yield From(create_highlights(
        world, ra.last_position, rb.last_position, new_pos))
    yield From(trollius.sleep(2))

    logger.debug("Inserting child...")
    child, bbox = mate
    pose = Pose(position=new_pos)
    future = yield From(world.insert_robot(child, pose, parents=[ra, rb]))
    yield From(future)

    yield From(sleep_sim_time(world, 1.8))

    logger.debug("Removing highlights...")
    yield From(remove_highlights(world, hls))
示例#4
0
    def run(self, conf):
        conf.min_parts = 1
        conf.max_parts = 3
        conf.arena_size = (3, 3)
        conf.max_lifetime = 99999
        conf.initial_age_mu = 99999
        conf.initial_age_sigma = 1
        conf.age_cutoff = 99999

        self.body_spec = get_body_spec(conf)
        self.brain_spec = get_brain_spec(conf)
        self.nn_parser = NeuralNetworkParser(self.brain_spec)

        print "OPENING FILES!!!!!!!!!!!!!!!!!!!"
        with open("body/{0}".format(self.body_file), 'r') as robot_file:
            robot_yaml = robot_file.read()

        for filename in self.brain_files:
            with open("brains/{0}".format(filename, 'r')) as brain_file:
                br_yaml = brain_file.read()
                self.brain_genotypes.append(
                    yaml_to_genotype(br_yaml, self.brain_spec))

        yield From(wait_for(self.pause(True)))

        pose = Pose(position=Vector3(0, 0, 0.5), rotation=rotate_vertical(0))

        robot_pb = yaml_to_robot(self.body_spec, self.brain_spec, robot_yaml)
        tree = Tree.from_body_brain(robot_pb.body, robot_pb.brain,
                                    self.body_spec)

        print "INSERTING ROBOT!!!!!!!!!!!!!!!!!!!!!!"
        robot = yield From(wait_for(self.insert_robot(tree, pose)))
        self.robot_name = robot.name

        self.modify_nn_publisher = yield From(
            self.manager.advertise(
                '/gazebo/default/{0}/modify_neural_network'.format(
                    self.robot_name),
                'gazebo.msgs.ModifyNeuralNetwork',
            ))
        # Wait for connections
        yield From(self.modify_nn_publisher.wait_for_listener())

        brain_num = 0
        num_of_brains = len(self.brain_genotypes)
        print "Number of brains = {0}".format(num_of_brains)

        yield From(wait_for(self.pause(False)))
        while (True):
            if self.timers.is_it_time('evaluate', self.time_period,
                                      self.get_world_time()):
                n = brain_num % num_of_brains
                print "Switching brain to #{0}!!!!!!!!!".format(n)
                yield From(self.insert_brain(self.brain_genotypes[n]))
                self.timers.reset('evaluate', self.get_world_time())
                brain_num += 1

            yield From(trollius.sleep(0.1))
示例#5
0
def run_server(conf):
    """

    :param args:
    :return:
    """
    conf.proposal_threshold = 0
    conf.output_directory = None
    conf.min_parts = 6
    conf.max_parts = 15
    conf.arena_size = (3, 3)

    interactive = [True]
    world = yield From(World.create(conf))
    yield From(world.pause(True))

    start_bots = conf.num_initial_bots
    poses = [Pose(position=pick_position(conf)) for _ in range(start_bots)]
    trees, bboxes = yield From(world.generate_population(len(poses)))
    fut = yield From(world.insert_population(trees, poses))
    yield From(fut)

    # List of reproduction requests
    reproduce = []

    # Request callback for the subscriber
    def callback(data):
        req = Request()
        req.ParseFromString(data)
        imode_value = None

        if req.request == "produce_offspring":
            reproduce.append(req.data.split("+++"))
            imode_value = True
        elif req.request == "enable_interaction":
            imode_value = True
        elif req.request == "disable_interaction":
            imode_value = False

        if imode_value is not None:
            interactive[0] = imode_value
            print("Interactive mode is now %s" % ("ON" if interactive[0] else "OFF"))

            if not interactive[0]:
                reproduce[:] = []

    subscriber = world.manager.subscribe(
        '/gazebo/default/request', 'gazebo.msgs.Request', callback)
    yield From(subscriber.wait_for_connection())

    while True:
        if interactive[0]:
            yield From(interactive_mode(world, reproduce))
        else:
            yield From(automatic_mode(conf, world, interactive))

        yield From(trollius.sleep(0.1))
        yield From(cleanup(world))
示例#6
0
def spawn_initial_robots(world, number):
    """
    :param world:
    :type world: World
    :return:
    """
    poses = [Pose(position=pick_position()) for _ in range(number)]
    trees, bboxes = yield From(world.generate_population(len(poses)))
    for index in range(number):
        spawn_robot(world, trees[index], poses[index])
示例#7
0
    def birth(self, tree, bbox, parents):
        """
        Birth process, picks a robot position and inserts
        the robot into the world.

        Robots are currently placed at a random position within the circular
        birth clinic. In this process, 5 attempts are made to place the robot
        at the minimum drop distance from other robots. If this fails however
        the last generated position is used anyway.
        :param tree:
        :param bbox:
        :param parents:
        :return:
        """
        s = len(tree)
        if (s + self.total_size()) > self.conf.part_limit:
            print("Not enough parts in pool to create robot of size %d." % s)
            raise Return(False)

        # Pick a random radius and angle within the birth clinic
        pos = Vector3()
        pos.z = -bbox.min.z + self.conf.drop_height
        done = False
        min_drop = self.conf.min_drop_distance

        for i in range(5):
            angle = random.random() * 2 * math.pi
            radius = self.conf.birth_clinic_diameter * 0.5 * random.random()
            pos.x = radius * math.cos(angle)
            pos.y = radius * math.sin(angle)

            done = True
            for robot in self.robots.values():
                if robot.distance_to(pos, planar=True) < min_drop:
                    done = False
                    break

            if done:
                break

        if not done:
            logger.warning("Warning: could not satisfy minimum drop distance.")

        # Note that we register the reproduction only if
        # the child is actually born, i.e. there were enough parts
        # left in the world to satisfy the request.
        if parents:
            ra, rb = parents
            ra.did_mate_with(rb)
            rb.did_mate_with(ra)

        self.births += 1
        fut = yield From(self.insert_robot(tree, Pose(position=pos), parents=parents))
        raise Return(fut)
示例#8
0
def spawn_population(world, conf):
    """
    :param world:
    :type world: World
    :return:
    """
    poses = [Pose(position=pick_position(conf)) for _ in range(1)]
    trees, bboxes = yield From(world.generate_population(len(poses)))


    fut = yield From(world.insert_population(trees, poses))
    yield From(fut)
示例#9
0
def get_poses(n, z=in_mm(24.5), spacing=0.4, row_limit=5):
    x = 0
    y = 0
    poses = []

    for i in range(n):
        poses.append(Pose(position=Vector3(x, y, z)))

        x += spacing
        if (i % row_limit) == 0:
            y += spacing
            x = 0

    return poses
示例#10
0
def run_server(conf):
    """

    :param args:
    :return:
    """
 #   conf.proposal_threshold = 0
 #   conf.output_directory = None
    conf.min_parts = 1
    conf.max_parts = 3
    conf.arena_size = (3, 3)

 #   interactive = [True]

    world = yield From(World.create(conf))
    yield From(world.pause(True))

    start_bots = conf.num_initial_bots
    poses = [Pose(position=pick_position(conf)) for _ in range(start_bots)]

    trees, bboxes = yield From(world.generate_population(len(poses)))

    fut = yield From(world.insert_population(trees, poses))
    yield From(fut)

    # List of reproduction requests
    reproduce = []

    # Request callback for the subscriber
    def callback(data):
        req = Request()
        req.ParseFromString(data)
       

        if req.request == "produce_offspring":
            reproduce.append(req.data.split("+++"))


    subscriber = world.manager.subscribe(
        '/gazebo/default/request', 'gazebo.msgs.Request', callback)
    yield From(subscriber.wait_for_connection())

    yield From(world.pause(False))

    while True:
        yield From(spawn_population(world, conf))

        yield From(trollius.sleep(12))
        yield From(cleanup(world))
示例#11
0
def run(conf):
    """

    :param conf:
    :return:
    """
    conf.evaluation_time = 5.0
    conf.output_directory = 'output'
    world = yield From(World.create(conf))
    yield From(world.pause(True))

    for i in range(3):
        ta, _, _ = yield From(world.generate_valid_robot())
        tb, _, _ = yield From(world.generate_valid_robot())
        ra = yield From(
            wait_for(
                world.insert_robot(ta,
                                   pose=Pose(position=Vector3(0, 3 *
                                                              i, 0.5)))))
        rb = yield From(
            wait_for(
                world.insert_robot(
                    tb, pose=Pose(position=Vector3(0, 3 * i + 1, 0.5)))))

        while True:
            # Attempt reproduction
            mate = yield From(world.attempt_mate(ra, rb))

            if mate:
                break

        tree, bbox = mate
        yield From(
            wait_for(
                world.insert_robot(
                    tree, pose=Pose(position=Vector3(0, 3 * i + 2, 0.5)))))
示例#12
0
def get_circle_poses(n, radius):
    """

    :param n:
    :param radius:
    :return:
    """
    shift = 2.0 * math.pi / n
    poses = []
    for i in xrange(n):
        angle = i * shift
        x, y = radius * math.cos(angle), radius * math.sin(angle)
        starting_rotation = Quaternion.from_angle_axis(math.pi + angle, Vector3(0, 0, 1))
        poses.append(Pose(position=Vector3(x, y, 0), rotation=starting_rotation))

    return poses
示例#13
0
def birth(world, tree, bbox, parents):
    """
    Birth process, picks a robot position and inserts
    the robot into the world.
    :param world:
    :param tree:
    :param bbox:
    :param parents:
    :return:
    """
    angle = random.random() * 2 * math.pi
    r = 2.0

    # Drop height is 20cm here
    # TODO Should we check whether other robots are not too close?
    pos = Vector3(r * math.cos(angle), r * math.sin(angle), -bbox.min.z + 0.2)
    fut = yield From(world.insert_robot(tree, Pose(position=pos), parents))
    raise Return(fut)
示例#14
0
    def evaluate_pair(self, tree, bbox, parents=None):
        """
        Evaluates a single robot tree.
        :param tree:
        :param bbox:
        :param parents:
        :return: Evaluated Robot object
        """
        # Pause the world just in case it wasn't already
        yield From(wait_for(self.pause(True)))

        pose = Pose(position=Vector3(0, 0, -bbox.min.z))
        fut = yield From(self.insert_robot(tree, pose, parents=parents))
        robot = yield From(fut)

        max_age = self.conf.evaluation_time + self.conf.warmup_time

        # Unpause the world to start evaluation
        yield From(wait_for(self.pause(False)))

        before = time.time()

        while True:
            if robot.age() >= max_age:
                break

            # Sleep for the pose update frequency, which is about when
            # we expect a new age update.
            yield From(trollius.sleep(1.0 / self.state_update_frequency))

        yield From(wait_for(self.delete_robot(robot)))
        yield From(wait_for(self.pause(True)))

        diff = time.time() - before
        if diff > self.conf.evaluation_threshold:
            sys.stderr.write(
                "Evaluation threshold exceeded, shutting down with nonzero status code.\n"
            )
            sys.stderr.flush()
            sys.exit(15)

        raise Return(robot)
示例#15
0
def run_server():
    conf = Config(proposal_threshold=0, output_directory='output')

    world = yield From(World.create(conf))
    yield From(world.pause(True))

    wall_x = conf.arena_size[0] / 2.0
    wall_y = conf.arena_size[1] / 2.0
    wall_points = [
        Vector3(-wall_x, -wall_y, 0),
        Vector3(wall_x, -wall_y, 0),
        Vector3(wall_x, wall_y, 0),
        Vector3(-wall_x, wall_y, 0)
    ]

    future = yield From(world.build_walls(wall_points))
    yield From(future)

    grid_size = (1, 2)
    spacing = 3 * conf.mating_distance
    grid_x, grid_y = grid_size
    x_offset = -(grid_x - 1) * spacing * 0.5
    y_offset = -(grid_y - 1) * spacing * 0.5
    poses = [
        Pose(position=Vector3(x_offset + spacing * i, y_offset +
                              spacing * j, 0))
        for i, j in itertools.product(range(grid_x), range(grid_y))
    ]

    trees, bboxes = yield From(world.generate_population(len(poses)))
    for pose, bbox in itertools.izip(poses, bboxes):
        pose.position += Vector3(0, 0, bbox[2])

    fut = yield From(world.insert_population(trees, poses))
    yield From(fut)

    while True:
        yield From(trollius.sleep(0.1))
        yield From(world.perform_reproduction())
示例#16
0
async def run():
    conf = parser.parse_args()
    conf.evaluation_time_sigma = 2.0
    conf.weight_mutation_probability = 0.8
    conf.weight_mutation_sigma = 5.0
    conf.param_mutation_probability = 0.8
    conf.param_mutation_sigma = 0.25

    # this is the world state update frequency in simulation Hz
    conf.pose_update_frequency = 5  # in simulation Hz

    # update frequency of sensors in simulation Hz (default 10Hz)
    # conf.sensor_update_rate = 10.

    # # these are irrelevant parameters but we need to set them anyway,
    # # otherwise it won't work
    # conf.min_parts = 1
    # conf.max_parts = 3
    # conf.arena_size = (3, 3)
    # conf.max_lifetime = 99999
    # conf.initial_age_mu = 99999
    # conf.initial_age_sigma = 1
    # conf.age_cutoff = 99999

    # create the learning manager
    world = await LearningManager.create(conf)
    await world.pause(True)

    path_to_log_dir = os.path.join(world.path_to_log_dir, "learner1")

    body_spec = get_body_spec(conf)
    brain_spec = get_extended_brain_spec(conf)

    # mutation spec contains info about what parameters of neurons can be mutated
    mut_spec = get_extended_mutation_spec(conf.param_mutation_sigma,
                                          conf.weight_mutation_sigma)

    # what types of neurons can be added to the network
    # allowed_types = ["Simple", "Sigmoid", "DifferentialCPG"]
    # allowed_types = ["Simple", "Sigmoid"]
    allowed_types = ["Simple"]

    mutator = Mutator(mut_spec, allowed_neuron_types=allowed_types)

    # if we are not restoring a saved state:
    if not world.do_restore:

        with open(conf.test_bot, 'r') as yamlfile:
            bot_yaml = yamlfile.read()

        pose = Pose(position=Vector3(0, 0, 0.2))
        bot = yaml_to_robot(body_spec, brain_spec, bot_yaml)
        tree = Tree.from_body_brain(bot.body, bot.brain, body_spec)

        robot = await world.insert_robot(tree, pose)

        learner = RobotLearner(world=world,
                               robot=robot,
                               brain_spec=brain_spec,
                               mutator=mutator,
                               conf=conf)

        gen_files = []
        init_brain_list = None

        if (os.path.isdir(path_to_log_dir)):
            gen_files = list(fname for fname in os.listdir(path_to_log_dir) if \
                fnmatch.fnmatch(fname, "gen_*_genotypes.log"))

        # if we are reading an initial population from a file:
        if len(gen_files) > 0:

            gen_files = sorted(gen_files,
                               key=lambda item: int(item.split('_')[1]))
            last_gen_file = gen_files[-1]

            num_generations = int(last_gen_file.split('_')[1])  # + 1
            num_brains_evaluated = conf.population_size * num_generations

            print("last generation file = {0}".format(last_gen_file))

            # get list of brains from the last generation log file:
            init_brain_list, min_mark, max_mark = \
                get_brains_from_file(os.path.join(path_to_log_dir, last_gen_file), brain_spec)

            print("Max historical mark = {0}".format(max_mark))

            # set mutator's innovation number according to the max historical mark:
            mutator.innovation_number = max_mark + 1

            learner.total_brains_evaluated = num_brains_evaluated
            learner.generation_number = num_generations

        # initialize learner with initial list of brains:
        await world.add_learner(learner, "learner1", init_brain_list)
        print(learner.parameter_string())

        # log experiment parameter values:
        create_param_log_file(conf, learner.generation_number,
                              os.path.join(path_to_log_dir, "parameters.log"))
        # copy the robot body file:
        shutil.copy(conf.test_bot, path_to_log_dir)

    # if we are restoring a saved state:
    else:
        print("WORLD RESTORED FROM {0}".format(world.world_snapshot_filename))
        print("STATE RESTORED FROM {0}".format(world.snapshot_filename))

    print("WORLD CREATED")
    await world.run()
示例#17
0
def run():
    """
    The main coroutine, which is started below.
    """
    # Parse command line / file input arguments
    conf = parser.parse_args()

    conf.output_directory = "output"
    conf.restore_directory = "restore"
    with open("models/robot_26.yaml", 'r') as yamlfile:
        bot_yaml1 = yamlfile.read()

    with open("models/robot_150.yaml", 'r') as yamlfile:
        bot_yaml2 = yamlfile.read()

    # Create the world, this connects to the Gazebo world

    world = yield From(World.create(conf))

    # These are useful when working with YAML
    body_spec = world.builder.body_builder.spec
    brain_spec = world.builder.brain_builder.spec

    # Create a robot from YAML
    protobot1 = yaml_to_robot(body_spec=body_spec,
                              nn_spec=brain_spec,
                              yaml=bot_yaml1)

    # Create a robot from YAML
    protobot2 = yaml_to_robot(body_spec=body_spec,
                              nn_spec=brain_spec,
                              yaml=bot_yaml2)

    # Create a revolve.angle `Tree` representation from the robot, which
    # is what is used in the world manager.
    robot_tree1 = Tree.from_body_brain(body=protobot1.body,
                                       brain=protobot1.brain,
                                       body_spec=body_spec)
    # Create a revolve.angle `Tree` representation from the robot, which
    # is what is used in the world manager.
    robot_tree2 = Tree.from_body_brain(body=protobot2.body,
                                       brain=protobot2.brain,
                                       body_spec=body_spec)
    # Insert the robot into the world. `insert_robot` resolves when the insert
    # request is sent, the future it returns resolves when the robot insert
    # is actually confirmed and a robot manager object has been created
    pose1 = Pose(position=Vector3(0, 0, 0.05))
    pose2 = Pose(position=Vector3(0, 2, 0.05))
    future1 = yield From(
        world.insert_robot(
            tree=robot_tree1,
            pose=pose1,
            # name="robot_26"
        ))
    future2 = yield From(
        world.insert_robot(
            tree=robot_tree2,
            pose=pose2,
            # name="robot_26"
        ))
    robot_manager1 = yield From(future1)
    robot_manager2 = yield From(future2)

    # I usually start the world paused, un-pause it here. Note that
    # pause again returns a future for when the request is sent,
    # that future in turn resolves when a response has been received.
    # This is the general convention for all message actions in the
    # world manager. `wait_for` saves the hassle of grabbing the
    # intermediary future in this case.
    yield From(wait_for(world.pause(True)))

    # Start a run loop to do some stuff
    while True:
        # Print robot fitness every second
        print("Robot fitness is {fitness}".format(
            fitness=robot_manager1.fitness()))
        yield From(trollius.sleep(1.0))