Writing a good acceleration function in Jmonkey

I have this acceleration function:



[java]



@Override

public void onUpdate(float tpf) {



// to be synchronized with setTime()

if (spatial != null)

{

// time = myApp.time;

// value = Math.min(time / initialDuration, 1.0f);



// acceleration using tpf, acceleration, and Cinematics speed

if(acceleration > epsilon)

{

//System.out.println("Accelerated Speed: "+speed);

//System.out.println("Current Position: "+spatial.getLocalTranslation());

speed += tpf * accelerationFactor;// * myApp.getAnimationSpeed();



// if final speed exceeds max speed

if( speed - maxSpeed > epsilon )

{

speed = maxSpeed;

}

}



// deceleration using tpf, acceleration, and Cinematics speed

else if(acceleration < epsilon)

{

speed -= tpf * accelerationFactor;// * myApp.getAnimationSpeed();



// if speed becomes negative

if( speed < epsilon)

{

speed = 0;

}



}

}

[/java]



The issue is when the spatial wants to go in reverse, things get inaccurate. Can anyone guide me into improving it? I originally designed thinking that the spatial (which is now a car) would never have to go in reverse.



thanks

Uh, with lines 30-33 in I guess thats normal?

yeah that was initially to avoid speed going negative. However, if I take it off , this will not solve the issue, in fact in would cause the spatial to move indefinitely in space.

I don’t understand. Do you want speed to be able to go negative or not? To me “reverse” means speed is negative.



If you simply want to have a dead spot then you need to check if the abs(speed) < epsilon before setting it to 0.

The thing is is I replace it with if (speed < minSpeed) { speed = minSpeed } to maintain the reverse speed, I am losing the accuracy of allowing the spatial to stop with speed 0 at the location of the destination

I want both options



(1) FORWARD DRIVING: car accelerates, coasts at constant speed and decelerates with final speed = 0 // already done



(2) REVERSE DRIVING: car decelerates, coasts at constant speed and accelerates to reach a final speed = 0



The question is how to combine these two

Should the car roll to a stop if there is no acceleration or is friction/damping not in consideration?

no friction, it reads from a trace file the duration of acceleration, coast, and deceleration, basically the acceleration and deceleration are the same except the acceleration factor being opposite.

So, I think if you add a third else branch with:



if( FastMath.abs(speed) < 0 ) speed = 0;



I think your car will stop when speed is small and there is no acceleration.

??? isn’t FastMath.abs(speed) supposed to be always >= 0 ?

d’oh. I mistyped.

if( FastMath.abs(speed) < epsilon ) speed = 0;

did u mean acceleration instead of speed?



looks like the same thing to me, if abs(speed) is too low make it 0 but thats not the issue. The issue is that it keeps decelerating with that method:



[java]speed -= tpf * accelerationFactor;[/java]

pspeed, To be clear, by doing something like this:



[java] @Override

public void onUpdate(float tpf) {



// to be synchronized with setTime()

if (spatial != null)

{

// time = myApp.time;

// value = Math.min(time / initialDuration, 1.0f);



// acceleration using tpf, acceleration, and Cinematics speed

if(acceleration > epsilon)

{

System.out.println("Accelerated Speed: "+speed);

//System.out.println("Current Position: "+spatial.getLocalTranslation());

speed += tpf * accelerationFactor;// * myApp.getAnimationSpeed();



// if final speed exceeds max speed

if( speed - maxSpeed > epsilon )

{

speed = maxSpeed;

}

}



// deceleration using tpf, acceleration, and Cinematics speed

else if(acceleration < epsilon)

{

System.out.println("Reduced Speed: "+speed);

speed -= tpf * accelerationFactor;// * myApp.getAnimationSpeed();



// if speed becomes negative

if( speed < epsilon)

{

speed = 0;

}



}



else if( FastMath.abs(speed) < epsilon )

{

speed = 0;

}

}[/java]



I still have the same issue, if the car goes in reverse, it’s stopping in a different location, in other words it’s accelerating a little at the end before stopping causing the inaccuracy

pspeed, To be clear, by doing something like this:



[java] @Override

public void onUpdate(float tpf) {



// to be synchronized with setTime()

if (spatial != null)

{

// time = myApp.time;

// value = Math.min(time / initialDuration, 1.0f);



// acceleration using tpf, acceleration, and Cinematics speed

if(acceleration > epsilon)

{

System.out.println("Accelerated Speed: "+speed);

//System.out.println("Current Position: "+spatial.getLocalTranslation());

speed += tpf * accelerationFactor;// * myApp.getAnimationSpeed();



// if final speed exceeds max speed

if( speed - maxSpeed > epsilon )

{

speed = maxSpeed;

}

}



// deceleration using tpf, acceleration, and Cinematics speed

else if(acceleration < epsilon)

{

System.out.println("Reduced Speed: "+speed);

speed -= tpf * accelerationFactor;// * myApp.getAnimationSpeed();



// if speed becomes negative

if( speed < epsilon)

{

speed = 0;

}



}



else if( FastMath.abs(speed) < epsilon )

{

speed = 0;

}

}[/java]



I still have the same issue, if the car goes in reverse, it’s stopping in a different location, in other words it’s accelerating a little at the end before stopping causing the inaccuracy

There’s an issue in the deceleration as I get an ouput:



[java]uced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0

Reduced Speed: 0.0[/java]



even when it’s coasting at constant speed

You are still setting speed to 0 if it’s less than epsilon. That should be setting speed to minSpeed if less than minSpeed.

Also, technically when you say if acceleration < epsilon it should be < -epsilon or 0 acceleration will still decelerate.



I think this all might be overcomplicated but I don’t know where your input is coming from.

if acceleration < epsilon it should be < -epsilon or 0 acceleration will still decelerate.


I think that's a very good point.

however the speed still decreases, I don't know why, it even enter the if statement you mentioned and sets speed to 0 then keeps decreasing again.

i think you have a problem because of “canncellation”.

you should avoid this line:

[java]speed -= tpf * accelerationFactor;[/java]

because you substract two numbers which are similar to each other (~0)

floating point numbers have a problem with this.

???



this is the most important line in the update. I don’t agree with you Lulumann6