View Issue Details

IDProjectCategoryView StatusLast Update
0002688The Dark ModAIpublic24.11.2017 16:33
Reportergrayman Assigned To 
PrioritynormalSeveritynormalReproducibilityrandom
Status acknowledgedResolutionopen 
PlatformWin32OSWindowsOS VersionXP
Product VersionTDM 1.04 
Summary0002688: AI walk in a circle
DescriptionNot those very large circles defined by path_corners, but the tight circles when they get stuck trying to move past something. Circling more than one or two times should not be allowed.
TagsNo tags attached.

Activities

grayman

grayman

11.01.2012 05:31

administrator   ~0004233

Update ...

After testing both distance-based and yaw-based solutions, I'm beginning to think that trying to solve the problem after the fact isn't going to be easy, and perhaps not possible. After recognizing a circling condition, each attempt to break the cycle by sending the AI elsewhere quickly fails as pathfinding undoes the request and puts the AI right back into the cycle.

Using debug drawing of obstacle recognition and pathfinding, I can see that even w/o corrective measures, pathfinding for a brief moment gives the AI a good path around an obstacle, but as the AI begins to walk toward the first goal point, subsequent pathfinding sends him back to where he was. This causes the AI to circle around to get back to that goal point. When he gets there, pathfinding finds the correct path again, then throws it away as soon as the AI begins to follow it.

Pathfinding's recalculation of a path each frame can discover a good path one frame, and a bad path the next.

So solving the circling problem will probably require some tweaking of pathfinding.
grayman

grayman

30.12.2014 23:30

administrator   ~0007282

You could experiment with this section of code in idAI::AnimMove():

// greebo: This should take care of rats running around in circles around their goal
// due to not turning fast enough to their goalPos, sending them into a stable orbit.
float oldTurnRate = turnRate;

float rad;
if (physicsObj.GetMass() <= SMALL_AI_MASS)
{
    rad = 50;
}
else
{
    rad = 100;
}

DM_LOG(LC_AAS, LT_DEBUG)LOGSTRING("idAI::AnimMove - %s - origin = [%s] oldTurnRate = %f dist to goal = %f\r", GetName(), physicsObj.GetOrigin().ToString(),oldTurnRate, (goalPos - physicsObj.GetOrigin()).LengthFast()); // grayman debug

DM_LOG(LC_AAS, LT_DEBUG)LOGSTRING("idAI::AnimMove - %s - bounds = [%s] rad = %f\r", GetName(), physicsObj.GetBounds().ToString(),rad); // grayman debug

gameRenderWorld->DebugArrow(colorRed, physicsObj.GetOrigin(), goalPos, 1, 60); // grayman debug

if ((goalPos - physicsObj.GetOrigin()).LengthSqr() < Square(rad))
//if ((goalPos - physicsObj.GetOrigin()).LengthSqr() < Square(50))
{
    turnRate *= gameLocal.random.RandomFloat() + 1;
    DM_LOG(LC_AAS, LT_DEBUG)LOGSTRING(" %s - temporary turnRate = %f\r", GetName(), turnRate); // grayman debug
}

// greebo: Now actually turn towards the "ideal" yaw.
Turn();

A good test case is the bridge in searching.map (in Cleighmoor/maps). Get someone to chase you onto the main bridge, then run onto one of the side supports. When the test distance is 50 (set for rats), an AI can circle for a long time before coming onto the support. When the test distance is 100, they usually circle once and then come after you.

It's an improvement, but you need to test what this does to other turns, like when the AI is walking normally or navigating a door.
grayman

grayman

24.01.2015 19:00

administrator   ~0007388

Something else to consider:

Turning is controlled by the turn rate, which is fixed. If, when starting a turn, instead of using a constant turn rate, try dividing the turn into smaller turns, each of which gets an increasingly larger turn rate. Work the math so that the last small turn and its rate put the AI on the path straight to the goal, ending the turn.

This seems like it might keep AI from getting stuck in these endless circles.

Issue History

Date Modified Username Field Change
11.03.2011 04:28 grayman New Issue
11.03.2011 04:28 grayman Status new => assigned
11.03.2011 04:28 grayman Assigned To => grayman
11.01.2012 05:31 grayman Note Added: 0004233
30.12.2014 23:30 grayman Note Added: 0007282
24.01.2015 19:00 grayman Note Added: 0007388
24.11.2017 16:33 grayman Assigned To grayman =>
24.11.2017 16:33 grayman Status assigned => acknowledged