VechicleControl, My car bounces or turns around when I turn

Hi everyone! First, i’m french so i hope you’ll understand what i says. I’m pretty new on jmonkey and i try to learn how it work progressively. I’m trying to make an arcade car, i mean the car will not leave the ground (except for jump) and will not drift.

I can’t do this, my car bouce and turn around if i turn at “too high speed”.



I’m asking your help, does anyone ever tried to do same?



Here’s a video of what i mean:

http://www.youtube.com/watch?v=-pUPBYske5E



And there's my java code:
[java]package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.math.Vector3f;
import com.jme3.math.FastMath;
import com.jme3.renderer.RenderManager;
import com.jme3.light.AmbientLight;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.control.VehicleControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.CameraNode;
import com.jme3.scene.control.CameraControl.ControlDirection;

/**
* test
* @author normenhansen
*/
public class Main extends SimpleApplication implements ActionListener{

private int speed = 0, accelerate = 500,maxSpeed = 100,minSpeed = 0;
private float angle = 0,rotation = 0.5f,maxAngle = 1.0f,minAngle = -1.0f,wheelRadius;
private boolean isRunning = true;
private RigidBodyControl trackControl;
private VehicleControl carControl;

private BulletAppState bulletAppState;
private Node trackNode;
private Node player;
private Spatial carNode;
private CameraNode camNode;

public static void main(String[] args) {
Main app = new Main();
app.start();
}

@Override
public void simpleInitApp() {
//BulletAppSpace collision
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.getPhysicsSpace().enableDebug(assetManager);

flyCam.setEnabled(false);
camNode = new CameraNode("Camera Node", cam);
camNode.setControlDir(ControlDirection.SpatialToCamera);

buildTrack();
buildCar();

Vector3f test = new Vector3f();
test.set(carNode.getLocalTranslation());
camNode.setLocalTranslation(new Vector3f(test.x,test.y +10,test.z - 50));

initKeys();
addLight();
}

@Override
public void simpleUpdate(float tpf) {
updateCam();
}

@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}

public void updateCam(){
Vector3f test = new Vector3f();
test.set(carNode.getLocalTranslation());
}

public void buildTrack() {
trackNode = (Node) assetManager.loadModel("Scenes/track/MountainValley_Track.j3o");
trackControl = new RigidBodyControl(CollisionShapeFactory.createMeshShape(trackNode),0);
trackNode.addControl(trackControl);
rootNode.attachChild(trackNode);

}

public void addLight() {
AmbientLight light = new AmbientLight();
light.setColor(ColorRGBA.White.mult(1.3f));
rootNode.addLight(light);
}

public void buildCar() {
float stiffness = 120.0f;
float compValue = 0.2f;
float dampValue = 0.3f;
final float mass = 400;

player = new Node("player");
carNode = assetManager.loadModel("Models/kart/kart_test_1.j3o");

carControl = carNode.getControl(VehicleControl.class);

carControl.setMass(mass);
carControl.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness));
carControl.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness));
carControl.setSuspensionStiffness(stiffness);
carControl.setFriction(20);
carControl.setMaxSuspensionForce(10000);

player.attachChild(carNode);
player.attachChild(camNode);
player.addControl(carControl);

carControl.setPhysicsLocation(new Vector3f(-95,10,120));

rootNode.attachChild(player);
bulletAppState.getPhysicsSpace().add(carControl);
bulletAppState.getPhysicsSpace().add(trackNode);
}

private void initKeys(){
//Mappage des touches
inputManager.addMapping("Pause", new KeyTrigger(KeyInput.KEY_P));
inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_UP));
inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_LEFT));
inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_RIGHT));

//On ajoute les nom au listenner
inputManager.addListener(this,"Pause");
inputManager.addListener(this,"Up");
inputManager.addListener(this,"Down");
inputManager.addListener(this,"Left");
inputManager.addListener(this,"Right");
}

public void onAction(String name, boolean keyPressed, float tpf){
if(isRunning){
if(name.equals("Pause") && !keyPressed) {

}else if(name.equals("Right")){
if(keyPressed){
angle += -rotation;
}else {
angle += rotation;
}
carControl.steer(angle);
}else if(name.equals("Left")){
if(keyPressed){
angle += rotation;
}else{
angle += -rotation;
}
carControl.steer(angle);
}else if(name.equals("Up")){
if(keyPressed){
speed += accelerate;
}else{
speed += -accelerate;
}
}
carControl.accelerate(speed);
}else if(name.equals("Down")){
if(keyPressed){

}else{

}
}

}
}[/java]

Looks like the center of mass of your car is pretty high. Make sure the center of the mesh that is the car chassis isn’t too high (e.g. move down the mesh inside the geometry).

Thank’s! i moved down the mesh with the scene editor, but now, i can’t see my car, only the wheel ^^’. Is there another solution?

You did it wrong, try in blender or something. Only Wile E. Coyote tries stuff just once :wink:

Again, the center of the chassis object should be below the actual mesh. Just open the model in blender, go into mesh mode, select all vertices and move the mesh up a bit.

Hum, i think i didn’t do the right things, cause it’s worst xD.



http://www.youtube.com/watch?v=OKpL1DSLetM



Blender picture (was it good?):

Hm thats actually not necessarily worse, maybe you have to adjust your settings and suspension dimensions a bit now. The vehicle can be complicated to get right.

Ok, i tried to adjust some settings ( thank’s again :wink: ) and i’ve got a pretty good result!



http://www.youtube.com/watch?v=T7_wlNViB94



But as you can see, the car still bounce in a bend and at the beginning she's come into the ground and get out slowly.
How can i adjust these problem and improve my car?

Maybe its too heavy? Try increasing the maxForce of the suspension.

When i made changes in this window properties, they don’t change. Can i change the maxForce of the suspension or all Vehicle properties inside the code instead of the vehicle editor?



How you mean “they don’t change”? When you can edit them they should get applied. I can’t reproduce this. For vehicles you set the things like suspension travel etc before adding the wheel, after you have to set it to the wheel directly.

I recorded this video:



http://www.youtube.com/watch?v=AkKnsZ31QN4



The change i made is not saved, maybe it's a bug or i've got a problem on my computer. oO

Well you don’t save the file. Whats happening is that the save button isn’t triggered for some reason, change something else and then save the file.

I applied new properties to the wheels and then the save button was active, before save i changed the maxSuspensionForce and save but when i reopen the files the properties were the same ( 6000 ).

Hm, idk. You can set it via code as well: spatial.getControl(VehicleControl.class).setMaxSuspensionForce(value);

I surrender, i made a lots a test with many different value for supension force, mass, friction, etc… And i can’t control the VehicleControl.

Is there any other way to create a car. Like use a characterControl? or rigidbody? i really don’t know. If someone have an idea telle me ^^.



:cry:

I do have some suggestions I’ve done before for a truck in code, I used the following for the feel I wanted:

Code:
private void buildTruck() { final float mass = 500;
    matWire = new Material(assetManager, "Common/MatDefs/Misc/WireColor.j3md");
    matWire.setColor("Color", ColorRGBA.Red);

    //load vehicle and access VehicleControl
    Spatial vehicle = assetManager.loadModel("Scenes/Truck101.j3o");
    //vehicle.setMaterial(matWire);
    //then use the control to control the vehicle:
    truck = vehicle.getControl(VehicleControl.class);

    bulletAppState.getPhysicsSpace().add(truck);

    //Set the start Rotation
    Matrix3f truckRot = new Matrix3f();
        truckRot.setColumn(0, new Vector3f(0,0,-1));
        truckRot.setColumn(1, new Vector3f(0,1,0));
        truckRot.setColumn(2, new Vector3f(1,0,0));

    truck.setPhysicsRotation(truckRot);
    //Mass
    truck.setMass(mass);
    //Gravity
    Vector3f gravity = (new Vector3f(0f, -35.0f, 0f));
    truck.setGravity(gravity);
    
    //Suspension force
    truck.setMaxSuspensionForce(0, 90000.0f);
    truck.setMaxSuspensionForce(1, 90000.0f);
    truck.setMaxSuspensionForce(2, 90000.0f);
    truck.setMaxSuspensionForce(3, 90000.0f);
    //Suspension Stiffness // lower = slower
    truck.setSuspensionStiffness(0, 68.5f);//25.5
    truck.setSuspensionStiffness(1, 68.5f);
    truck.setSuspensionStiffness(2, 68.5f);
    truck.setSuspensionStiffness(3, 68.5f);
    // Compression  // Lower = more suspension travel
    //Max ammount spring cam be compressed?
    truck.setSuspensionCompression(0, 7.5f);//9.5
    truck.setSuspensionCompression(1, 7.5f);
    truck.setSuspensionCompression(2, 7.5f);
    truck.setSuspensionCompression(3, 7.5f);
    // Dampening  //release higher then stiff  Lower = slower suspension recovery
    truck.setSuspensionDamping(0, 70.1f);//25
    truck.setSuspensionDamping(1, 70.1f);
    truck.setSuspensionDamping(2, 70.1f);
    truck.setSuspensionDamping(3, 70.1f);
    //
    truck.setAngularFactor(1.11f);

    //Roll Influence
    truck.setRollInfluence(0, 1.0f);
    truck.setRollInfluence(1, 1.0f);
    truck.setRollInfluence(2, 1.0f);
    truck.setRollInfluence(3, 1.0f);
    
    // Friction
    truck.setFriction(1.27f);

    truck.setFrictionSlip(0, 1.26f);
    truck.setFrictionSlip(1, 1.26f);
    truck.setFrictionSlip(2, 1.24f);
    truck.setFrictionSlip(3, 1.24f);

    vehicle.setShadowMode(ShadowMode.CastAndReceive);
    truck.setPhysicsLocation(startLocation);
    rootNode.attachChild(vehicle);

    camSpatial = vehicle.center();
}

Hope this can help in some way :)

Imo vehicle creator is great for creating the relationships for the chassis and wheels, but the handling feel seems to work much better with the code.

Oh and for a demo of how this vehicle feels there is a demo here: windows Linux Mac.



camera controls still need modifying though…

The vehicle control seems to make no provision for aerodynamic down force as speeds increase, nor for engine and gearbox control.

Are there any additions to the JME vehicle control that provide these functions ?