First of all I would like to say - thanks for an awesome physics library for jME!
Right, so here's my problem: I'm trying to create a bicycle in jMEphysics2. I've created a simple bicycle consisting of two relatively wide weels and a body. I've added steering functionality but as the physics of a bicycle is relatively complex with leaning and everything, the bicycle very easily tips over
So my question is this: How would you create a bicycle in jMEphysics2 that:
Behaves relatively realisticly
Doesn't tip over that easily - i.e. is able to balance somehow.
well, for detecting "tip over" I'd just check if worldUpVector dot bikeUpVector gets too low (or e.g. the 'angle' of the bike). That should be easy.
But as even simulating cars is quite hard, I imagine getting a bike behaving like desired gets really difficult. Additionally: I won't be of much help - no idea what's needed, actually - sorry
well, for detecting "tip over" I'd just check if worldUpVector dot bikeUpVector gets too low (or e.g. the 'angle' of the bike). That should be easy.
But as even simulating cars is quite hard, I imagine getting a bike behaving like desired gets really difficult. Additionally: I won't be of much help - no idea what's needed, actually - sorry :|
Thanks for your reply. How would you rotate a DynamicPhysicsNode as setLocalRotation doesn't seem to have any effect? Add a torque? If so, how would you ensure that an object never flips over?
setLocalRotation should have an effect (after updating the scene). Adding tourque is the preferred way if you want to turn something while the simulation is already running (setLocalRotation allows to circumvent collision detection and other physical effects).
An easy way to avoid flipping of a car is to lower the center of gravity below the street - you can do this for your bicycle, too. It won't be realistic any more, of course.
Right, I've got a working bicycle now although it's still very difficult to steer
Here are some screenshots (click for larger image):
Basically every part of the bike is attached to Bicycle which extends Node. Every part is a DynamicPhysicsNode which are connected together by Joints. One problem I've stumbled into is that the bike vibrates violently. I suspect this has to do with the fact that the wheels aren't perfectly circular, so is it possible to "treat" them as perfect cylinders even though the visual model representation is not? Also, what does the green cross directly below the pedals indicate when rendering the physics?
irrisor said:
An easy way to avoid flipping of a car is to lower the center of gravity below the street - you can do this for your bicycle, too. It won't be realistic any more, of course.
Well, I tried changing the center of mass (I assume this is what you meant by center of gravity?) with setCenterOfMass() as in Lesson8 in the tutorial, but this physically moved the model. Is this intentional? Do I then have to move it up again with setLocalTranslation()? What effect does this have?
One last question, to set the steer back to it's straight position I'm doing the following:
This works, but is there a way I can control how fast this happens? steerAxis.setAvailableAcceleration() doesn't seem to have any effect when I set the position minimum and maximum...
is it possible to "treat" them as perfect cylinders even though the visual model representation is not?
Sure, use createCylinder() and adjust the size instead of generating physics geometry.
I assume this is what you meant by center of gravity?
err, yesss :), sorry
Also, what does the green cross directly below the pedals indicate when rendering the physics?
The green cross is the origin of a physics node.
Well, I tried changing the center of mass (I assume this is what you meant by center of gravity?) with setCenterOfMass() as in Lesson8 in the tutorial, but this physically moved the model. Is this intentional?
Yes it's a workaround for ODE's lack of a moved center of mass (it's always at the origin of the body)
Do I then have to move it up again with setLocalTranslation()? What effect does this have?
That's ok, if you move the physics node but not the geoms back. The center of mass is then shifted.
steerAxis.setAvailableAcceleration() doesn't seem to have any effect when I set the position minimum and maximum...
Position maximum/minimum are affected by ERP and CFM only. setAvailableAcceleration is for setDesiredVelocity
is it possible to "treat" them as perfect cylinders even though the visual model representation is not?
Sure, use createCylinder() and adjust the size instead of generating physics geometry.
I tried that but the bicycle still shakes as violently as before. I could post the code somewhere if you would be able to look at it?
irrisor said:
steerAxis.setAvailableAcceleration() doesn't seem to have any effect when I set the position minimum and maximum...
Position maximum/minimum are affected by ERP and CFM only. setAvailableAcceleration is for setDesiredVelocity
What's ERP and CFM? :) How can I achieve the functionality of the wheel turning back to 0? Just change the velocity and check every update if getPosition() becomes 0?
Another question - I discovered that when there is no DynamicPhysicsNode within the camera's view, all the StaticPhysicsNodes no longer get rendered... Why is this?
Another question - I discovered that when there is no DynamicPhysicsNode within the camera's view, all the StaticPhysicsNodes no longer get rendered... Why is this?
Culling - most likely they are lacking bounding volumes.
ERP, CFM - see ODE docs, but I'm not sure you really should use stops (max/min) this way. Do you really need it to be at position 0? Or just stop it somewhere?
About the shaking - is it only while moving? If yes, are you shure there are no trimesh collision geometries any more? Probably have a look with the debugger what geoms are there...
Another question - I discovered that when there is no DynamicPhysicsNode within the camera's view, all the StaticPhysicsNodes no longer get rendered... Why is this?
Culling - most likely they are lacking bounding volumes.
Ah, ofcourse! It works now.
irrisor said:
ERP, CFM - see ODE docs, but I'm not sure you really should use stops (max/min) this way. Do you really need it to be at position 0? Or just stop it somewhere?
I need it to stop at position 0. One way to do this I guess would be to setDesiredVelocity(direction * someVelocity) and then check for its position every update() and call setDesiredVelocity(0) when it hits the mark... But I'm not sure this is the way to do this?
irrisor said:
About the shaking - is it only while moving? If yes, are you shure there are no trimesh collision geometries any more? Probably have a look with the debugger what geoms are there...
Regarding the TriMesh collision geometries there are loads (actually, there's the steering, body and 2 wheels), I just tried to replace the wheels with perfect cylinders. Should I try to replace the other geometries aswell?
Another question I discovered - I tried adding a body (a cyclist) as a simple sphere connected directly above the bicycle. I set its mass to 50f or so and discovered that when its mass is far greater than the body, the joints connecting the body to the wheel and body to the steering would give and allow the body to move right into the floor below! Is this intentional or is there any way to set the "strength" of the joints?
Screenshot of the joints "breaking"
I also discovered that there were no odejava-natives for Mac OS X in the latest CVS version of jMEphysics2. I would be happy to provide these - I'm compiling on my ppc mac atm...
Sorry for spamming you with a wall of text here but another question:
How do you get the force affecting a DynamicPhysicsNode which is connected with others through a Joint? Calling getForce(null) on the DynamicPhysicsNode in question results in a zeroed vector, always. I'm interested in retrieving the force from the gravity currently affecting the node. What I'm trying to do is add another force to it to cancel out the force from the gravity in one direction and thus preventing the bike from falling…
wouldnt it be easier to make it look real by omitting physics than adding 'unnatural' forces ?
Well, I need physics like gravity and collision ;) So what I need is something in between, if that makes any sense :P
holodri said:
on the other hand...if u already use a physics engine .. so why dont u prevent the bike from tip over by adding torque to steering ?
make it learn driving with genetic algo stuff (JGAP) :D
Problem with adding a torque to the steering is that we want to allow the player to be able to steer himself and this need a way to lean the bike. If you have any tips on how to achieve this by adding a torque or something similar to one of the bike parts (like the body) given the angle of the steering it would be greatly appreciated :)
One could divide this process in two: as you say, allow the bike to learn driving by itself "with genetic algo stuff (JGAP)" (not sure what that means :)) and on the other hand lean the whole bike over given the user input...
How do you get the force affecting a DynamicPhysicsNode which is connected with others through a Joint? Calling getForce(null) on the DynamicPhysicsNode in question results in a zeroed vector, always. I'm interested in retrieving the force from the gravity currently affecting the node. What I'm trying to do is add another force to it to cancel out the force from the gravity in one direction and thus preventing the bike from falling...
This could be done with ODE's joint callbacks but is not implemented in jME Physics.
I've created a "balanceKeeper" function in ODE (with ALOT of help from my cousin who is PHD in math and computer science, so i guess I didnt really create it lol but i was there:) ).
When it discovers that the object is tipping it adds appropiate force, smalls "pushes" to the object…
I use it for my ragdolls to make them stand. It works just perfectly.
I will post the subrutine as soon as I get home from work.
It's not JME psysics but old odejava but it shoudnt be hard to convert.
But shoudlnt a bike be able to balance by itself when it reaches a certain speed ?
A speeding bike should never tip over but I wonder it ODE takes that into calculation,
I've created a "balanceKeeper" function in ODE (with ALOT of help from my cousin who is PHD in math and computer science, so i guess I didnt really create it lol but i was there:)
package net.ode.util;
import javax.vecmath.Matrix3f;
import javax.vecmath.Vector3f;
import org.odejava.Body;
/**
* Class to make an object balance using forces.
* @author Mlp
*
*/
public class BalanceKeeper {
/**
* Balances a {@link Body}
* @param body the body to balance
* @param maxDegrees when body is tipping more than maxDegrees the balancekeeper will give up
* @param velFactor when measuring speed do it with the factor of this.
* @param forceFactor how much force can be applied
* @param aggressiveness how aggressive is the balancekeeper. That means, should it stabilize the object quickly or over a longer period
*/
public static void keepBalance(Body body,float maxDegrees,float velFactor,float forceFactor,float aggressiveness) {
//get tilt
float tilt = getTilt(body);
//if tilt is too great maybe the balancekeeper should give up
if(tilt>maxDegrees) return;;
Matrix3f r = body.getRotation();
Vector3f y = new Vector3f();
y.x = r.m01;
y.y = r.m11;
y.z = r.m21;
float dist = (float)Math.sqrt(y.x*y.x+y.z*y.z);
if(dist == 0.0) return;
//vector to hold force
Vector3f force = new Vector3f();
force.x = (float)tilt*y.x/dist;
force.y = (float)tilt*y.y/dist;
force.z = (float)tilt*y.z/dist;
Vector3f vel = body.getLinearVel();
vel.x = vel.x*velFactor;
vel.z = vel.z*velFactor;
force.x = (force.x+(vel.x*aggressiveness));
force.z = (force.z+(vel.z*aggressiveness));
body.addForce(-force.x*forceFactor,0,-force.z*forceFactor);
}
/**
* Get the tilt of the body using Y axis.
* @param body
* @return
*/
public static float getTilt(Body body) {
Matrix3f r = body.getRotation();
Vector3f v = new Vector3f();
v.x = r.m01;
v.y = r.m11;
v.z = r.m21;
float dist = (float)Math.sqrt(v.x*v.x+v.z*v.z);
return (float)(90-Math.toDegrees(Math.atan(v.y/dist)));
}
}