libgdx / gdx-ai

Artificial Intelligence framework for games based on libGDX or not. Features: Steering Behaviors, Formation Motion, Pathfinding, Behavior Trees and Finite State Machines
Apache License 2.0
1.18k stars 241 forks source link

NaN return #45

Closed chase26091 closed 7 years ago

chase26091 commented 8 years ago
if (steeringBehavior != null) {
        steeringBehavior.calculateSteering(steeringOutput);
        if (this.body != null && !steeringOutput.linear.isZero()) {
            System.out.println(steeringOutput.linear);
            this.body.applyForceToCenter(steeringOutput.linear, true);
        }
        // applySteering(steeringOutput, deltaTime);
    }

I'm using gdx-ai 1.5.0

calculateSteering is returning a NaN,NaN vector. I am using the example Box2dRadiusProximity with the CollisionAvoidance steering behavior. No errors are thrown, my box2d body just disappears once i approach the radius distance, very weird behavior. I don't understand where the issue is spawning from

davebaol commented 8 years ago

Please provide a SSCCE. It's your best bet to get it fixed. Also, you can try gdxai-1.5.1-SNAPSHOT

davebaol commented 8 years ago

Please try gdxai-1.6.0

davebaol commented 8 years ago

@chase26091 Is this still an actual issue? I'll close it if I do not get a feedback within a few days.

davebaol commented 8 years ago

Ok, closing this since without SCCE there's no way I can reproduce your issue. Please reopen if you can supply the SSCE.

lukz commented 7 years ago

I've got the same issue. It's happening in Separation behavior.

public boolean reportNeighbor (Steerable<T> neighbor) {
    toAgent.set(owner.getPosition()).sub(neighbor.getPosition());
    float distanceSqr = toAgent.len2();
    float maxAcceleration = getActualLimiter().getMaxLinearAcceleration();

    // Calculate the strength of repulsion through inverse square law decay
    float strength = getDecayCoefficient() / distanceSqr;
    if (strength > maxAcceleration) strength = maxAcceleration;

    // Add the acceleration
    // Optimized code for linear.mulAdd(toAgent.nor(), strength);
    linear.mulAdd(toAgent, strength / (float)Math.sqrt(distanceSqr));

    return true;
}

Basically distanceSqr can be 0 and in this case we've division by zero.

davebaol commented 7 years ago

@lukz Correct. Reopening this. Any chance of a PR?

lukz commented 7 years ago

@davebaol I'm not sure what's the correct way to handle that. In my case I'm just checking steeringOutput after calculate steering and if it's NaN I'm setting it to zero. But it's just a temporary hack.

Maybe if distanceSqr == 0 than setting it to Float.MIN_VALUE is the way to go?

davebaol commented 7 years ago

@lukz

Maybe if distanceSqr == 0 than setting it to Float.MIN_VALUE is the way to go?

Even if you do this the produced linear acceleration would not change because you mulAdd toAgent, which is a zero vector. I'd say that we could just return true in this case.