Why do my velocity estimates have such a large margin of error
I am writing a script in unity that applies a force to the object to advance it a set distance in an environment without friction or drag, producing a cosine force curve. However, as the target approaches the destination, the force to apply is less than the value specified by the curve as the time unit is too large and will cause the object to reverse direction. To resolve this, I estimate what the speed will be after applying this frames force and, if that reverses the direction, we take a proportion of the force. It is working well around 4 times out of 5, but every so often it will not detect the reverse in direction and will apply the force for an extra frame or 2, causing the object to back up. Closer investigation revealed that basically the problem stems from my estimate being significantly (some times up to 0.05) different from the velocity the next frame. I compute it as follows: Vector3 currentVelocity = ship.rigidbody.velocity; Vector3 direction = ship.transform.right; // this is the value I use for the "actual" speed float velocityAlongDir = Vector3.Dot(currentVelocity, direction); // this is my estimate float estimatedVelocity = velocityAlongDir + (applyingForce * lDeltaTime); Where the applyingForce is applied thus: ship.rigidbody.AddForce((applyingForce * ship.rigidbody.mass) * transform.right); Some sample data: Predicted velocity: 0.3048308 Actual velocity: 0.2880591 Predicted velocity: 0.2068605 Actual velocity: 0.1900333 Predicted velocity: 0.09798826 Actual velocity: 0.1900333 Predicted velocity: 0.1082982 Actual velocity: -0.007007703 As you can see by the last entry, the predicted value doesn't change sing, but the real value does. Trying to work around this using does it go below a small value get different problems where the current velocity is too small etc. Any idea why my calculation for next frame velocity seems so wrong and is there anything I can do about it? Update As pointed out in the comments, I needed to apply the force in the FixedUpdate and calculate my next frames velocity using Time.fixedDeltaTime. However, the following can happen, presumably in adverse frame conditions: Predicted Velocity: 15.67547 Actual Velocity: 15.67547 Predicted Velocity: 17.54726 Actual Velocity: 15.67547 // note the same as the previous update, there has been no physics step! Predicted Velocity: 17.51759 // estimate is subtly different, because my own timer has advanced I fixed this by using fixedTime as opposed to fixedDeltaTime. However, then when I do a double update I am wrong for that frame, its like the physics step is trying to make up for the lost time: // all going well... Predicted Velocity: 52.25977 Actual Velocity: 52.25977 Predicted Velocity: 52.40138 // the estimate is wrong, we are moving at the same speed => no physics update Actual Velocity: 52.25977 // we predict the same velocity for next frame Predicted Velocity: 52.40138 // but we are wrong, like it is trying to catch up for lost time Actual Velocity: 52.543 // then after that point we are precisely right Predicted Velocity: 52.66479 Actual Velocity: 52.66479 This wouldn't be an issue except in the edge case where we do this double step precisely at the point we need to detect when the speed will change and apply the ratio. Since the physics step seems to play catch up, I miss the fact we changed speed.
I resolve this (and a related question I asked on SO) as follows.
The first issue, as AdamS pointed out was that I was applying the force in the Update not the FixedUpdate. This resolved the large discrepancies originally posted.
The second issue, where it wouldn’t do an FixedUpdate came from the fact that I was still advancing the time as if it had done a fixed update each update, so I used fixedTime so I could tell if there had been an update.
The last case (in this question) came from the fact the forces were accumulating so when there had been 2 updates between fixed updates, it was applying double the force.
This caused its own issues as, because the forces were only being applied per fixed update, low frame rate would cause the ship to not go fast enough (see SO question).
- Database Administration Tutorials
- Programming Tutorials & IT News
- Linux & DevOps World
- Entertainment & General News
- Games & eSport