KIT-MRT / arbitration_graphs

Hierarchical behavior models for complex decision-making and behavior generation in robotics
https://kit-mrt.github.io/arbitration_graphs/
MIT License
15 stars 0 forks source link

Demo: Fix pacman drift #12

Closed ll-nick closed 5 months ago

ll-nick commented 5 months ago

There seems to be a timing issue that results in a sort of drift. Here's a screen recording of the current state of the demo. Note the direction change at the ~12 seconds in.

https://github.com/KIT-MRT/arbitration_graphs/assets/68419636/1e41a907-d766-4343-97db-3fd210922f0a

Issue description/Diagnosis

When entering the intersection, Pacman might want to change directions upwards. The direction change will result from the command in the instant, the tile center is reached because that will change the state stored in the EnTT simulation (i.e. the Position vector of Pacman changes). However, in the next frame, when the command is executed, Pacman may already be past the intersection and will have "missed his exit".

This occurs multiple times and will result in Pacman only every making actual direction changes, when the current corridor ends in a wall.

Side note: When Pacman changes direction towards a wall, he will keep moving in the same direction as before but facing that wall.

Potential Solution

I think compute the command not for the current but for the next position should fix the issue. Pacman will change directions sooner but the actual direction change will only occurs once the next position is reached.

ll-nick commented 5 months ago

@orzechow @ChristophBurger89 FYI

ll-nick commented 5 months ago

I implemented a first version of a fix on this branch. Looks way better. But I have to give the question of when to use the current position and when to use the predicted position a little more thought and integrate the prediction a little more nicely.

Here's an updated version.

https://github.com/KIT-MRT/arbitration_graphs/assets/68419636/8082a399-20a6-44c8-bc17-f18b2b0254fb

ll-nick commented 5 months ago

I looked into this in a little more detail today. I did not yet find a solution but I know the cause of the issue. Let me write it down here before I forget again.

Context

The Game::logic() function isn't executed in every frame. Instead, it is only executed often enough such that each entity has moved exactly one tile. The continuous visualization is done by calling the renderer in each frame which will get the current entity position (integer) and compute the pixel position using the number of frames.

In the Game::logic function, (almost) the first thing that is being executed is the movement() function which moves all entities into their actualDirection. Next, the wallCollide() functions checks if the desiredDirection is valid and if it is will set the actualDirection to be the desiredDirection.

The actualDirection is then used to compute the pixel position for the renderer while the desiredDirection is visualized by the rotation of the entity.

Ok, that's how it works. Now to explain the problem we see.

The problem

We set the desiredDirection before we call the Game::logic() which is fine but the Game::logic() will execute the actualDirection from the last time step before setting the desiredDirection we defined for the current time step. By that time, pacman may have "missed his exit".

Solution?

So the solution would be to swap the two functions. Execute the functions setting the correct actualDirection before executing the movement() function. However, this appears to have some side effects.

First of all, the renderer uses the actualDirection to compute the pixel positions. So if first set the actualDirection and then move, the entity will seem to move into walls etc.

So next I tried to call wallCollide(), then movement(), then wallCollide again. This fixes the glitchy rendering somewhat but now I have two ghosts stuck in the house. Also the tunnel sometimes causes run time errors, I think that also happened in this configuration.

Overall, I think solving this within the pacman sim would be way cleaner than having the "prediction" solution I tried in the video above. I guess I just need to figure out what function has to be called in which order but this turned out to be way harder than I thought it would

ll-nick commented 5 months ago

Should be solved with https://github.com/KIT-MRT/EnTT-Pacman/pull/1