eaplatanios / jelly-bean-world

A framework for experimenting with never-ending learning
Apache License 2.0
73 stars 17 forks source link

Environment isn't modified after loading from filepath #14

Closed finbarrtimbers closed 2 years ago

finbarrtimbers commented 2 years ago

Hey folks!

Sorry to raise so many issues. Hopefully this is the last one.

After I save the environment + an agent to a file and then load it back up, the environment doesn't change when an action is taken.

I assume I'm calling this wrong- can you advise me how to fix this?

Here's my minimal reproducible example:

def test_repro():
    simulator_dict = dict(
        max_steps_per_movement=1,
        vision_range=8,
        no_op_allowed=False,
        patch_size=64,
        mcmc_num_iter=10000,
        agent_color=[0.0, 0.0, 0.0],
        agent_field_of_view=2 * np.pi,
        collision_policy=jbw.MovementConflictPolicy.FIRST_COME_FIRST_SERVED,
        decay_param=0.4,
        diffusion_param=0.14,
        deleted_item_lifetime=2000,
        allowed_movement_directions=[
            jbw.ActionPolicy.ALLOWED, jbw.ActionPolicy.ALLOWED,
            jbw.ActionPolicy.ALLOWED, jbw.ActionPolicy.ALLOWED
        ],
        allowed_turn_directions=[
            jbw.ActionPolicy.DISALLOWED, jbw.ActionPolicy.DISALLOWED,
            jbw.ActionPolicy.DISALLOWED, jbw.ActionPolicy.DISALLOWED
        ],
        seed=2)
    items = [
        jbw.item.Item(
            name='JellyBean',
            scent=[1.64, 0.54, 0.4],
            color=[0.82, 0.27, 0.2],
            required_item_counts=[0],
            required_item_costs=[0],
            blocks_movement=False,
            visual_occlusion=0.0,
            intensity_fn=jbw.item.IntensityFunction.CONSTANT,
            intensity_fn_args=[1.5],
            interaction_fns=[
                # JellyBean
                [
                    jbw.item.InteractionFunction.PIECEWISE_BOX, 10., 100., 0.,
                    -6.
                ]])
    ]

    simulator_config = jbw.SimulatorConfig(items=items, **simulator_dict)
    simulator = jbw.Simulator(sim_config=simulator_config)
    agent = base._DummyAgent(simulator)

    # Save and then recreate.
    agent_filepath = '/tmp/agent_file'
    agent.save(agent_filepath)
    simulator.save('/tmp')

    class CallbackClass:

      def __init__(self):
        self.t = 0

      def callback(self):
        self.t += 1

    callback = CallbackClass()
    new_simulator = jbw.Simulator(
        load_filepath='/tmp',
        load_time=simulator.time(),
        on_step_callback=callback.callback)
    new_agent = base._DummyAgent(simulator, '/tmp/agent_file')
    action = jbw.RelativeDirection.FORWARD
    initial_t = callback.t
    vision = new_agent.vision()
    new_simulator.move(new_agent, action)
    while initial_t == callback.t:
      time.sleep(0.5)
    initial_t = callback.t
    new_simulator.move(new_agent, action)
    while initial_t == callback.t:
      time.sleep(0.5)
    stepped_vision = new_agent.vision()
    assert False np.allclose(vision, stepped_vision)

vision is below, so it should change when the agent takes a step forward: image

asaparov commented 2 years ago

No worries! In your case, I think the bug is the line new_agent = base._DummyAgent(simulator, '/tmp/agent_file'). The new agent is being added to the old simulator rather than the new one. Also, I don't think Simulator has a save method (as in the line simulator.save('/tmp')). Did you add one?

We designed the Simulator class to handle saving and loading the agents in addition the environment. Simulator has a get_agents function that will return the loaded agents. So you shouldn't reload the agents separately. This test has a working example of how to save/load simulators and agents.

finbarrtimbers commented 2 years ago

Ah, that DummyAgent bug is embarrassing. Thanks for the catch. However, if I change it to be the new simulator, it still fails.

When I switch it to use get_agents that fixes it- thanks for the help.

asaparov commented 2 years ago

Ah right, so if you don't use get_agents, there will actually be two agents in the simulator, so time will not advance until both have moved.