• Advertisement
Sign in to follow this  

Inaccuracies in deceleration

This topic is 1088 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am rotating an object with constant deceleration. I want the object to stop at a predetermined location at given time t. The object stops at the correct location when I do not take time in consideration using the equation acceleration =  -(velocity * velocity)/(2 * spinTo) or a = (v22 – v12) / (2 ?s)

 

However this equation does not allow me to incorporate the amount of time I want the deceleration to take. To incorporate time I am using the equation

acceleration = (2 * spinTo - (2 * velocity() * time))/(time * time) or a = (2 ?s – 2 v1 ?t) / (?t)2

 

This produces inconsistent results and my object does not rotate to the correct location. I'm fairly confident my math is correct. What could be causing the inaccuracies when time is taken into consideration? My rotation code looks like this

 

void WheelSpinEffect::HandleRotation(float degree, float velocity, float accel)
{
    float oldVel = velocity;
    float dt = 1.0f/GraphicsDevice::GetRefreshRate();
        
    velocity += (accel * dt);    
    degree += (oldVel + velocity) * 0.5f * dt; 
   
    Rotate(degree);
    SetVelocity( velocity );
}

 

Any help is greatly appreciated.

Edited by ivincent

Share this post


Link to post
Share on other sites
Advertisement
I don't understand your math, what spinTo represents or even whether this is 2D or 3D. Why is velocity a float, and not a vector? Can you provide some definitions so we know what we are talking about?

Share this post


Link to post
Share on other sites

I don't understand your math, what spinTo represents or even whether this is 2D or 3D. Why is velocity a float, and not a vector? Can you provide some definitions so we know what we are talking about?

 

spinTo = (360 * 3) -  (stopPosition * 30.0f) - currentDegree;       //wedges are 30 degrees apart  (360/12)

 

It's a basic 2D rotation.

Share this post


Link to post
Share on other sites

I personally wouldn't have the timing of my rotation based on the refresh rate as you have here:

float dt = 1.0f/GraphicsDevice::GetRefreshRate();

Because it varies wildly and can affect accuracy and consistency of results. It should be over a more stable timer like those offered by chrono in C++ 11 shown here http://en.cppreference.com/w/cpp/chrono/steady_clock. As the wheel slows you sample the time interval less and less to decelerate it.

 

So using chrono your dt will look something like:

std::chrono::steady_clock::time_point start, stop;
std::chrono::duration<double> elapsed_secs;

...

// Start the timer.
start = std::chrono::steady_clock::now();

// Do something in here like the time taken for the wheel to rotate 1 degree as it decelerates.

// Stop the timer.
stop = std::chrono::steady_clock::now();

elapsed_secs = std::chrono::duration_cast<std::chrono::duration<double>>(stop - start);

double dt = 1.0 / elapsed_secs;

Something like this will give you better results because it isn't based on framerate.

Edited by ButchDean

Share this post


Link to post
Share on other sites


float dt = 1.0f/GraphicsDevice::GetRefreshRate();

This is  bad at any frame rate: the duration of your animation should be fixed and predictable, while your refresh rate is constant and need not be queried repeatedly.

 


velocity += (accel * dt);
degree += (oldVel + velocity) * 0.5f * dt;

This accumulates errors. Multiply instead, with t varying between 0 and the animation length and matching the real time clock, not theoretical frame rates::

  • velocity = initial velocity+ accel*t
  • position= initial position + 0.5*accel*t*t

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement