google-research / falken

Falken provides developers with a service that allows them to train AI that can play their games
Apache License 2.0
253 stars 35 forks source link

Error with loading old brain in HelloFalkenDynamic #21

Closed mattlegro closed 3 years ago

mattlegro commented 3 years ago

Hi,

So I was experimenting with reloading brains to continue training from a specific snapshot. I was having troubles in my program, so I went back to HelloFalken to make sure I was doing it properly. With the static HelloFalken.exe, I have no problem passing -brain_id and -snapshot_id. However, when I try to use HelloFalkenDynamic.exe, I get the following output:

> .\Release\HelloFalkenDynamic.exe -brain_id f08db37f-c99b-4b73-b60b-5d87ca9904f8 -snapshot_id a9f42bf5-6619-408e-9abc-2354bcce43fa
INFO: Starting game with brain_id f08db37f-c99b-4b73-b60b-5d87ca9904f8 and snapshot_id a9f42bf5-6619-408e-9abc-2354bcce43fa
INFO: Connected to Falken!
INFO: Created brain: f08db37f-c99b-4b73-b60b-5d87ca9904f8
INFO: Started session: eff1ac11-c995-4887-b629-a69e227821d7
[Falken] ERROR: Entity goal not found in container. Found [entity_0, player, ]

The brain was originally created through running .\Release\HelloFalkenDynamic.exe without passing brain_id or snapshot_id flags. I find that I can use the same brain and snapshot IDs when running the static example and don't have any problems, only in the dynamic example.

It is as if the 'goal' entity is not rebound properly. Thoughts?

mattlegro commented 3 years ago

If I go into the models_dir for the above brain_id for HelloFalken and look at policy_specs.txt, under key "global_entities" there are keys "0" and "player" both with rotation and position. If I look under key "action" there are keys "steering" and "throttle" as expected. For some reason, the goal (red square) is not saved or referred to as goal internally, such that the lines in HelloFalkenDynamic

falken::EntityBase goal(observations, "goal");

doesn't seem to be doing anything. If I change lines further down, replacing "goal" in:

    brain_spec.observations_base().entity("goal")->position.set_value(
        AsXZPosition(goal.position));
    brain_spec.observations_base().entity("goal")->rotation.set_value(
        HFAngleToQuaternion(0));

so that it instead says

    brain_spec.observations_base().entity("entity_0")->position.set_value(
        AsXZPosition(goal.position));
    brain_spec.observations_base().entity("entity_0")->rotation.set_value(
        HFAngleToQuaternion(0));

I can use

> .\Release\HelloFalkenDynamic.exe -brain_id f08db37f-c99b-4b73-b60b-5d87ca9904f8 -snapshot_id a9f42bf5-6619-408e-9abc-2354bcce43fa

as above to start training or evaluating from that brain state as expected. This is a workaround for now however probably not a viable solution if there is more than one entity besides the player to be tracked.

I also tested a build as below:

falken::EntityBase goal(observations, "goal");
                      ... (other code) ...
    brain_spec.observations_base().entity("entity_0")->position.set_value(
        AsXZPosition(goal.position));
    brain_spec.observations_base().entity("entity_0")->rotation.set_value(
        HFAngleToQuaternion(0));

and this still allowed me to run HelloFalkenDynamic with a provided brain and snapshot ID, and the brain output still was effective in getting the ship to reach the goal. So again, I don't really know what the issue is, but there seems to be a problem with how EntityBase binds "goal" to observations.

mattlegro commented 3 years ago

Ah, okay.. Well I found this in entity.h:

  /// @details Given that the entities names are not stored in the service as
  ///     strings but as enum values instead, when a brain is loaded, generic
  ///     names will be retrieved. For instance, if the names were
  ///     {"enemy", "player", "sidekick"}, the mapping between stored and
  ///     retrieved values would be {"enemy": "entity_0", "player": "entity_1",
  ///     "sidekick": "entity_2"}, since all attributes are stored in
  ///     alphabetical order.

So I guess it's intended behavior, at the moment, except that for some reason in my brains, "player" is retained as an entity key but "goal" is not.

hmoraldo commented 3 years ago

Thanks a lot for the details. It sounds like it could be a bug either in the dynamic demo or in the bindings code. I don't personally handle either of those. I'll leave this open in case somebody can debug this more deeply in the future.

hinasakazaki commented 3 years ago

Yeah, as stated in in entity.h, this is is actually a known bug in our system (which we have no plans to fix, thus we made that comment) where the workaround is by specifying "entity_0", "entity_1". My understanding is that in your brain, the "goal" is retained as an entity key but as "entity_2". Could you try setting through that key (or other candidates of "entity_N") and see if that works?