Applyimpulse movement wrong

Hello,

I’m trying to make a blimb fly, Forward and backwards is no problem in the direction it initialized.
But when i have turned with the engines in some direction (rudders and stuff are not yet implemented) and i will make it move forward,
it turns very rapidly until it has turned 180 degrees from the initialized direction and fly straight again.

I’ve tried to correct it, but nothing has worked,

[java]

public void updateLogicalState(float tpf) {
	super.updateLogicalState(tpf);
            //hover thrust
	control.applyImpulse(new Vector3f(0f, calculateHover(tpf), 0f),
			new Vector3f(0, 0, 0));

	Vector3f impulsedir = control.getPhysicsRotation()
			.mult(Vector3f.UNIT_Z);
            //right engine thrust
	control.applyImpulse(impulsedir.normalizeLocal().mult(rthrust * 1000),
			new Vector3f(-10, 0, -146));
	//left enige thrust
	control.applyImpulse(impulsedir.normalizeLocal().mult(lthrust * 1000),
			new Vector3f(10, 0, -146));

	if (level) {
		control.setAngularVelocity(Vector3f.ZERO);
	}
	// System.out.println("heading = " + this.getShipRealHeading()
	// * FastMath.RAD_TO_DEG);

}[/java] 

The hovering part of the code works like a charm, the part i’m looking for is for the right and left enige.

Wow, Sorry i have to make a habbit of reading my posts in english again before i post something.
English isn’t my first language, i hope you understand what i’m asking.

Why don’t you apply your trust force with applyForce() instead of with applyImpulse()? Also, why are you overriding the updateLogicalState() method of your spatial to implement this behavior? You should move this code to the update() method of your control class. This will help you : https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:physics
EDIT: this too : https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:update_loop

i didn’t use the main update loop because i didn’t want to put to much code there, and i wanted to keep the code with the object where it was used. (If anyone has idea’s to change that without losing the float tpf let me know)
The Object I use the updateLogicalState from is a Node which keeps the whole ship (blimb, i most of the times i call it a ship because it is over 250m long) together.
Why i use impulse instead of force, it’s mostly because of the engines. and because i looked over the fact that applyforce also could be applied to a location.
I have changed it to applyforce now, but i’m still having the same problem, it doesn’t fly straight until it reaches the direction it started in or 180 degrees of it.

If you go about using the engine your own way and not as its intended you are alone with your issues I suppose.

@normen
So you mean that i have to put all the code inside the main update() sequence? Even if it gets to long to maintain? If i build a class that is called from that loop with tpf in the simpleupdate class is that OK?

little update,

This code is inside my class:
[java] public void updateLoop(float tpf) {
control.applyImpulse(new Vector3f(0f, calculateHover(tpf), 0f),
new Vector3f(0, 0, 0));

	Vector3f impulsedir = control.getPhysicsRotation()
			.mult(Vector3f.UNIT_Z);

	control.applyImpulse(impulsedir.normalizeLocal().mult(rthrust * 1000),
			new Vector3f(-10, 0, -146));
	fire.setLocalRotation(control.getPhysicsRotation());
	// System.out.println("r = " + new Vector3f(-10, 0, 146));
	control.applyImpulse(impulsedir.normalizeLocal().mult(lthrust * 1000),
			new Vector3f(10, 0, -146));

	if (level) {
		control.setAngularVelocity(Vector3f.ZERO);
	}
	// System.out.println("heading = " + this.getShipRealHeading()
	// * FastMath.RAD_TO_DEG);

}[/java] 

This is the main update loop:
[java] @Override
public void simpleUpdate(float tpf) {
super.simpleUpdate(tpf);
jcontrol.update(tpf);
phoenix.updateLoop(tpf);
}[/java]

I don’t understand what you are saying. If you use a Control you achieve exactly that.

@normen, do you mean the controls described in this chapter?
https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:custom_controls
Ahhh: i see why i overlooked that part, i thought controls ment the keyboard control and stuff, but it also means control over objects. I’m sorry, i’m gonna look into that.

Also look at AppStates. They are global and controls are Spatial-specific.

@pspeed That was one part, i have looked at. But it was a bit to global for me. But thanks anyways, i will use that later when the application get bigger.

I have now changed my code to use controls, but i’m still stuck with the issue of the wrong movement.

i don’t know what you put in rthrust and lthrust.

Also, i am not sure of the result of quaternion.mult(Vector3F.UNIT_Z) (i usually use quaternion.getRotationColumn(2))

Also, i think that the second parameter of applyImpulse is NOT relative to the current rotation of your spatial. I am maybe wrong, but you definitively need to know it.

And, i think that if you apply an impulse every frame, you should use the tpf for that impulse, or the comportement of your game will be framerate dependent.

@bubuche
The rthrust and lthrust variables are the amount of thrust that are applied as thrust. i haven’t ranged them yet so the range is very big. The part about the tpf you are right about, i have changed that now in my code.

The quaternion.mult(Vector3F.UNIT_Z) i think is doing the same as quaternion.getRotationColumn(2), i have used it now and the results are exactly the same.

Your point about the second parameter is something i’m not sure about, maybe someone else knows the answer, but if i try to apply the rotation of the ship to these locations and i try to turn the ship with one positive thrust and one negative thrust it won’t turn at all.
But i can be mistaken at that point. Though it meight explain why the ship is turning around the central axle instead of around the point where the engines are right now.

i’ll go to my lunch (or breakfast or an other name in english i don’t know), but i think that you should try to use “localToWorld” or “worldToLocal” or something like that to transform your “absolute in regard of the rotation” points in real local points. Maybe you can cheat with a fake spatial that you attach and detach only to have its absolute position (i.e. create a node, set its localtranslation to (+/-10, 0, -146), attach it to your ship, get its worldlocation, subtract the world’s location of your ship etc.)

@bubuche That sounds like an idea! i’ll try that!
Uhhmm, i think breakfast is in the morning, lunch around 12 and diner in the evening. I just had the last :slight_smile:
Have a nice meal! Bon apetit, Eet smakelijk. (it all says the same ;))

@diepen45 said: @pspeed That was one part, i have looked at. But it was a bit to global for me. But thanks anyways, i will use that later when the application get bigger.

I have now changed my code to use controls, but i’m still stuck with the issue of the wrong movement.

Calling update() manually from simpleUpdate() or using an app state = no different… except the code is simpler and more modular with an app state.

@bubuche said: Also, i am not sure of the result of quaternion.mult(Vector3F.UNIT_Z) (i usually use quaternion.getRotationColumn(2))

quaternion.mult(Vector3F.UNIT_Z) is the proper way.

quaternion.getRotationColumn(2) is the bad way. It requires that you know a whole lot about how quaternions and matrices work(*) just to find the z axis in the local rotation… which is exactly what the first way is doing explicitly. “I want to know what my z-axis is in this local space… I should probably rotate the z axis into local space then.” seems logical to me.)

(* the irony is that when I see this in code I automatically assume that someone cut and pasted it from somewhere and has no idea what it’s actually doing.)

@bubuche said: i'll go to my lunch (or breakfast or an other name in english i don't know), but i think that you should try to use "localToWorld" or "worldToLocal" or something like that to transform your "absolute in regard of the rotation" points in real local points. Maybe you can cheat with a fake spatial that you attach and detach only to have its absolute position (i.e. create a node, set its localtranslation to (+/-10, 0, -146), attach it to your ship, get its worldlocation, subtract the world's location of your ship etc.)

Actually, the physics rotation should be in world space. So getPhysicsRotation().mult(Z) should be getting the world space vector in the direction of the ship.

If he wants to try a local vector then Vector3f.UNIT_Z untransformed would be enough.

@pspeed,
That is something you are right about. But that was a temporary solution, because first the updateloop was the overriden updatelogicalstate of a Node. (and another developer (normen) was not happy about that) He has pointed me toward the control classes and they are much better suited for the task. especially if i want to add a duplicate ship but move it independant.

I found something else that was funny when i used the quaternion.getRotationColumn(2) method, if i applied negative thrust to both engines the complete ship whould flip over and move. with positive thrust it flipped back again. quaternion.mult(Vector3F.UNIT_Z) didn’t behave in the same way but behaved like it should.