# Robot with 3 wheels

Hi Everyone,

I’m creating a robot that have three wheels, the two wheels in front of the robot are moved by two motors; the last one wheel is only a support wheel, is free to rotate around its vertical axis and move by inertia. There is a way to create this last wheel with VeichleControl? Anyone can help me?

http://img819.imageshack.us/img819/1608/nxtrobot.jpg

p.s. my Photoshop level it’s over 9000!

… its the same as the 4 wheels examples, just attach one less.

ok thanks, but can the back wheel rotate without applying any motor force (only with the boost given by front wheels)?

And, more important, how can i make the wheel rotate around its vertical axis?

To make the idea watch this video:

At 00:07 seconds, looks the movements of the back wheel.

Just make it steerable (“front” wheels) and set a steering value, you can do that per wheel, as well as setting acceleration etc. Best work with the standard z-forward.

1 Like

Thank you, one last question, did i need to change the value of RollInfluence to make it move by inertia or it rotates already by default?

if you don’t brake it will roll yeah. braking is more like the friction of the axes.

1 Like

Thank you so much, i will try tomorrow to create the model and check if it works.

I’ve tried to create the robot’s model with three wheels, the two front wheels governed singularly by two motors and the back wheel, more little, with no motor.

I’ve found some problems:

-I can’t find the mode to makes the back wheel rotate freely around is y axis, I’ve found only the method “steer” that steers the wheel not the steerability, I shouldn’t give it any value of steer, it should steers by itself in agreement with the movements of the robot;

-If I give an accelleration value to a single front wheel (A), theorically the robot must rotate around an y axis that is placed in the front wheel (B) that has no accelleration, but B moves with a little inertia and the y axis is not placed in this wheel. I’ve tried to use for the B wheel “setRollInfluence”, giving it the 0.0f value, but the B wheel continues to move with a little intertia. I need that the B wheel doesn’t move if I didn’t give it an accelleration value.

a) you will have to determine and set that steering value yourself

b) like I said, use the brake value, setting rollInfluence to 0 has the exact opposite effect

ok thanks, it’s too complicated give it a steer value to every rotational motion, if I block completely the wheel and give it a lower fricitonSlip it will be like a support wheel (like a sphere)? Or it will not give stability to the robot rotation?

I guess that works, the hover example I did does the same.

I did some correction, but now when I set motor forward the robot goes on about a meter and then does a spin around itself. When I try the rotation using one front wheel it works correctly. I attach the code:

I think the problem it’s because the setFrictionSlip to “0.0f” on the back wheel but if I set a higher value the robot doesn’t rotate because the back wheel opposes resistance.

[java]package jme3test.helloworld;

import com.jme3.app.SimpleApplication;

import com.jme3.bullet.BulletAppState;

import com.jme3.bullet.PhysicsSpace;

import com.jme3.bullet.collision.shapes.BoxCollisionShape;

import com.jme3.bullet.collision.shapes.CompoundCollisionShape;

import com.jme3.bullet.control.VehicleControl;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.FastMath;

import com.jme3.math.Matrix3f;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.Node;

import com.jme3.scene.shape.Cylinder;

public class TestPhysicsCar extends SimpleApplication implements ActionListener {

private BulletAppState bulletAppState;

private VehicleControl vehicle;

private final float accelerationForce = 1000.0f;

private final float brakeForce = 500.0f;

private float accelerationValueLeft = 0;

private float accelerationValueRight = 0;

private Vector3f jumpForce = new Vector3f(0, 3000, 0);

public static void main(String[] args) {

TestPhysicsCar app = new TestPhysicsCar();

app.start();

}

@Override

public void simpleInitApp() {

bulletAppState = new BulletAppState();

stateManager.attach(bulletAppState);

bulletAppState.getPhysicsSpace().enableDebug(assetManager);

PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace());

setupKeys();

buildPlayer();

}

private PhysicsSpace getPhysicsSpace(){

return bulletAppState.getPhysicsSpace();

}

private void setupKeys() {

}

private void buildPlayer() {

Material mat = new Material(getAssetManager(), “Common/MatDefs/Misc/Unshaded.j3md”);

mat.setColor(“Color”, ColorRGBA.Red);

//create a compound shape and attach the BoxCollisionShape for the car body at 0,1,0

//this shifts the effective center of mass of the BoxCollisionShape to 0,-1,0

CompoundCollisionShape compoundShape = new CompoundCollisionShape();

BoxCollisionShape box = new BoxCollisionShape(new Vector3f(1.2f, 0.5f, 2.4f));

//create vehicle node

Node vehicleNode=new Node(“vehicleNode”);

vehicle = new VehicleControl(compoundShape, 800);

//setting suspension values for wheels, this can be a bit tricky

float stiffness = 400.0f;//200=f1 car

float compValue = .3f; //(should be lower than damp)

float dampValue = .4f;

vehicle.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness));

vehicle.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness));

vehicle.setSuspensionStiffness(stiffness);

vehicle.setMaxSuspensionForce(10000.0f);

//Create four wheels and add them at their locations

Vector3f wheelDirection = new Vector3f(0, -1, 0); // was 0, -1, 0

Vector3f wheelAxle = new Vector3f(-1, 0, 0); // was -1, 0, 0

float restLength = 0.3f;

float yOff = 1f;

float xOff = 1f;

float zOff = 2f;

Node node1 = new Node(“wheel 1 node”);

Geometry wheels1 = new Geometry(“wheel 1”, wheelMesh);

node1.attachChild(wheels1);

wheels1.rotate(0, FastMath.HALF_PI, 0);

wheels1.setMaterial(mat);

Node node2 = new Node(“wheel 2 node”);

Geometry wheels2 = new Geometry(“wheel 2”, wheelMesh);

node2.attachChild(wheels2);

wheels2.rotate(0, FastMath.HALF_PI, 0);

wheels2.setMaterial(mat);

Node node3 = new Node(“wheel 3 node”);

Geometry wheels3 = new Geometry(“wheel 3”, wheelMesh);

node3.attachChild(wheels3);

wheels3.rotate(0, FastMath.HALF_PI, 0);

wheels3.setMaterial(mat);

vehicleNode.attachChild(node1);

vehicleNode.attachChild(node2);

vehicleNode.attachChild(node3);

rootNode.attachChild(vehicleNode);

vehicle.setFrictionSlip(0, 1000.0f);

vehicle.setFrictionSlip(1, 1000.0f);

vehicle.setFrictionSlip(2, 0.0f);

vehicle.setRollInfluence(2, 0.0f);

}

@Override

public void simpleUpdate(float tpf) {

cam.lookAt(vehicle.getPhysicsLocation(), Vector3f.UNIT_Y);

vehicle.brake(0, brakeForce);

vehicle.brake(1, brakeForce);

}

public void onAction(String binding, boolean value, float tpf) {

if (binding.equals(“Lefts”)) {

if (value) {

accelerationValueLeft += accelerationForce;

} else {

accelerationValueLeft -= accelerationForce;

}

vehicle.accelerate(0, accelerationValueLeft);

} else if (binding.equals(“Rights”)) {

if (value) {

accelerationValueRight += accelerationForce;

} else {

accelerationValueRight -= accelerationForce;

}

vehicle.accelerate(1, accelerationValueRight);

} else if (binding.equals(“Ups”)) {

if (value) {

accelerationValueLeft += accelerationForce;

accelerationValueRight += accelerationForce;

} else {

accelerationValueLeft -= accelerationForce;

accelerationValueRight -= accelerationForce;

}

vehicle.accelerate(0, accelerationValueLeft);

vehicle.accelerate(1, accelerationValueRight);

} else if (binding.equals(“Downs”)) {

if (value) {

vehicle.brake(brakeForce);

} else {

vehicle.brake(0f);

}

} else if (binding.equals(“Space”)) {

if (value) {

vehicle.applyImpulse(jumpForce, Vector3f.ZERO);

}

} else if (binding.equals(“Reset”)) {

if (value) {

System.out.println(“Reset”);

vehicle.setPhysicsLocation(Vector3f.ZERO);

vehicle.setPhysicsRotation(new Matrix3f());

vehicle.setLinearVelocity(Vector3f.ZERO);

vehicle.setAngularVelocity(Vector3f.ZERO);

vehicle.resetSuspension();

} else {

}

}

}

}

[/java]

Yeah, listen, I am not here to debug your code, I can help you with engine features and issues. So I guess its your job to find out how to make your ideas work with bullet and jme.

I suggest to use real physic cylinders for the wheels, as the raytrace vehicle is only a approximation that (sometimes) feels real.

Since you probably only have 1-4 robots at the same time, that should work performant enough

Thank you for your reply, I don’t understand what do you mean for “real physic cylinders”, what does it change?

At the moment my principal problem is that my robot spins around itself when I set the two front wheels motors forward and steer a little, for example, if I set for the front wheel A an accelleration value of 1000f and for the front wheel B an accelleration value of 800f I should see a regular circle with the centre of its rotation like this:

http://img51.imageshack.us/img51/4733/traiettoria.jpg

but currently it does not comply the circular trajectory and change the center of curvature.

I do not want you to do debug my code, I simply ask help for solving this problem.

He says you could use hinge joints and cylinders etc. to make “real” rotating wheels and everything. Idk if thats necessary, I guess by playing around with the raycast vehicle you should be able to get similar results.

Thanks for the explanation, i will try and let you know if it works.