Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411423 Posts in 69363 Topics- by 58416 Members - Latest Member: JamesAGreen

April 18, 2024, 05:11:39 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Steering Behaviors: getting the "Arrive" behavior to behave
Pages: [1]
Print
Author Topic: Steering Behaviors: getting the "Arrive" behavior to behave  (Read 2111 times)
Latah
Level 0
*



View Profile
« on: January 15, 2015, 06:58:40 PM »

Hello all,

I'm trying to implement some steering behaviors in a game I'm working on, and I'm having a little trouble getting the "Arrive" behavior working properly. The function I have here is supposed to return a steering force that will cause the agent to slow down and stop at the TargetPos grcefully, however the way it's working now causes him to overshoot the target over and over before finally coming to a stop. I've tried tweaking everything I can think of, but I just can't seem to get the agent to behave the way I want.

One solution I've seen involves a "braking radius" that kicks in when the agent is close to the target, but the functionality I'm after shouldn't need to involve a radius; I want the agent to slow himself based on his distance to the targetPos.

Here's the function in question. The Deceleration parameter is simply an enumerated int 1-3.

Code:
private Vector2 Arrive(Vector2 Targetpos, Deceleration deceleration) {
        Vector2 ToTarget = sub(Targetpos, agentPos);

        //calculate the distance to the target
        float dist = ToTarget.len();

        if (dist > 0.2f) {

            final float DecelerationTweaker = 0.3f;

            //calculate the speed required to reach the target given the desired
            //deceleration
            float speed = dist / ((float) deceleration.value() * DecelerationTweaker);

            //make sure the velocity does not exceed the max
            speed = Math.min(speed, agentMaxSpeed);

            Vector2 DesiredVelocity = mul(ToTarget, speed / dist);

            return sub(DesiredVelocity, agentVelocity);
        }

        return new Vector2(0, 0);
    }

And here's the code that updates my agent's position:

Code:
        float agentMass = 1f;
        Vector2 agentForce = new Vector2(0f,0f);
        float agentMaxSpeed = 1.6f;
        float agentMaxForce = 5f;

agentForce = calculate(); //calls Arrive function

            agentAccel = div(agentForce, agentMass);

            agentVelocity.add(agentAccel.x * deltaTime, agentAccel.y * deltaTime );

            agentVelocity.truncate(agentMaxForce);

            //update the heading if the vehicle has a non zero velocity
            if (agentVelocity.lenSq() > 0.00000001f) {
                agentHeading = vec2Normalize(agentVelocity);

                agentHeadingAngle = agentHeading.angle();

            }

            agentPos.add(agentVelocity.x * deltaTime, agentVelocity.y * deltaTime);

Thanks in advance for the help. This problem has been giving me a headache for days and I'm sure it's just something very small I'm missing.
Logged
Cheezmeister
Level 3
***



View Profile
« Reply #1 on: January 15, 2015, 11:32:27 PM »

It's actually a pretty gnarly problem to come precisely to a complete stop, check out https://en.wikipedia.org/wiki/PID_controller

Depending on how "physical" you want to be, you can cheat a little bit, e.g. once inside the radius switch to a linear deceleration or even a position lookup type thing. But I don't know of any concise way to get a perfect slowdown.

Personally I think toilet-bowling has character, but that's just me.
Logged

෴Me෴ @chzmstr | www.luchenlabs.com ቒMadeቓ RA | Nextris | Chromathud   ᙍMakingᙌCheezus II (Devlog)
haimat
Level 0
**



View Profile WWW
« Reply #2 on: January 16, 2015, 06:21:20 AM »

I asked a similar question on Stack Overflow recently.
Maybe it could be of some help for you too:

http://stackoverflow.com/questions/27790962/calculating-the-speed-of-a-moving-object-based-on-its-distance-to-a-target

Good luck!
Logged
Latah
Level 0
*



View Profile
« Reply #3 on: January 16, 2015, 10:04:50 AM »

Wouldn't you know it...

Earlier today I finally figured it out.

It turns out that the steering force returned by the function was working properly, but it was never enough to fully counteract the current velocity of the moving agent. I fixed this by simply multiplying the force returned by the function by 50.

Silly me.

Thanks for the help anyway though, guys.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic