Search Unity

Question How do I calculate the agents slowdown curve to stop at a point?

Discussion in 'Navigation' started by Tion-Gaming, Jun 5, 2022.

  1. Tion-Gaming

    Tion-Gaming

    Joined:
    Jan 30, 2015
    Posts:
    28
    I have been terribly frustrated with the black box that is the NavMeshAgent, so I have designed a wrapper around it that allows me near full control like waypoint setting, events for reaching corners/start and end of pathing, a almost exact replacement for rotation, debugging the multipath, and more. The only thing im still using the agent for is the actual movement, but with the lacking documentation, the fact that Ive already replaced so much of the original NavMeshAgent with my current, and my growing need for exact control for my project, replacing the acceleration,speed, autostop featues with my own implementation I can actually see,understand, and extend is the clear next step.

    I have so far worked out the equations used to start moving the agent. They are quite simple, constant acceleration over time produces a pretty clear square root curve for velocity given the equation of motion : V^2=V0^2 + 2A(ΔX). It goes until it reaches the velocity is equal to the speed, at which point it is capped as seen below:
    upload_2022-6-5_10-22-13.png

    My main question is what determines the distance the agent starts to slow down to reach the point using autostop and what formula can be used to model it? I tried a wide variety of speed and acceleration values and got a not so obvious result each time. The ending velocity and the distance the slowing starts at dont really ever map to whole values no matter what I put in (except 5 for speed and 5 for accel which had the agent stopping at a velocity of 2.5 which is neat). (in the current graph it uses a 2 for speed and 8 for accel). Despite how it looks, the velocity curve on the left is actually curving so its using what I assume to be a constant deceleration similar to how it starts. I also assume that because I plotted the velocity with respect to time at the same time and both curves turn into nice straight lines: upload_2022-6-5_10-34-6.png
    With the left side being pretty obvious, starting at 0,0 going to 0.25,2 gives a slope of 2/.25 which is 8, the acceleration. I however could never find an obvious or clear connection to the line on the right. They are not tangent and the line changes slope based on various parameters. There is no clear way to find the velocity it will end at. Can anyone help point me in the right direction as to what formula is used for the autostop feature of the agents?
     
  2. Tion-Gaming

    Tion-Gaming

    Joined:
    Jan 30, 2015
    Posts:
    28
    It seems they use the agent diameter for distance, the reason why I was getting those seemingly random cutoffs for velocity is I just had only been logging data > 0.2f, since the time graph depended on the distance graphs while loop, it too got cut off at the corresponding velocity. I believe the use the distance between the end and 2agent radii and the velocity at that distance to calculate a deceleration that would result in the agents position to be roughly where the end point is. Below you can see a much better graph. It uses an agent with radius of 0.5, speed of 50, acceleration of 150.
    upload_2022-6-8_15-16-54.png
    Id bet that the deviation from x=1 is just due to the speeds and lack of precision of floats. I had to run my tests at 0.1 speed just to get enough data points for the end curve. Again you can see a cutoff near 0, this was because I was only logging while the distance was greater than 0.01, so im quite sure that curve just goes directly to 0.
     
  3. Tion-Gaming

    Tion-Gaming

    Joined:
    Jan 30, 2015
    Posts:
    28
    Alliness likes this.
  4. Alliness

    Alliness

    Joined:
    Mar 13, 2016
    Posts:
    1
    Thanks man, you are saver! I'm was looking for proper formula for smooth rigidbody rotation about 2 days, and this what exactly need.
    That's what I've made
    Code (CSharp):
    1.         private float Calc(float from, float to, float speed)
    2.         {
    3.             var deltaDistance = to - from;
    4.             return Mathf.Min(Mathf.Sqrt(2 * dragForce * deltaDistance), speed);
    5.         }
    I just passing current, desired rotation and this works!
    Thanks Again!