ODE: Car simulations

Member
Posts: 156
Joined: 2002.10
Post: #1
(Not sure that this post should go here, but there's nowhere else to go...)

I'm using ODE to simulate driving a car, but I am getting weird effects like the drive wheels tend to spin when I accelerate, and the car will fish-tail skid a lot when turning.

There's a lot of parameters to tweak, both in the motors and in collision/friction. Does anyone have any example code of doing this kind of thing? Or a set of parameters that seem to work pretty well that I can work around?

Cheers

- Iain
Quote this message in a reply
Puzzler183
Unregistered
 
Post: #2
I could have sworn they had a car demo on their site which you could copy and play around with... I'll post a link later if I have time and can find what I'm thinking of.
Quote this message in a reply
Member
Posts: 156
Joined: 2002.10
Post: #3
Yeah they have a 'car' demo included in the ODE download, but it's not very useful directly, as I'm trying to get some kind of arcadey-style feel to driving, i.e. nice fast acceleration, possibility of wheelspin, and handrake turns. I've made more progress, but it's very fiddly.

- Iain
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #4
Hey, I happen to be doing something along these lines, using ODE. Perhaps we can bonk heads. I too have fishtailing issues Rasp

Here's a snap of me driving around:
[Image: Legion-2005-03-07-02.jpeg]

My vehicle has four-wheel steering and four-wheel drive, plus a suspension. It's fairly stable, though when the vehicle flips I've got a rocket to unflip you.

In my experience ODE actually behaves plausibly, you just have to do "unrealistic" things to make the experience more fun.
Quote this message in a reply
Member
Posts: 156
Joined: 2002.10
Post: #5
Looks cool - I will post some more when I get stuff working like the camera position etc, and we can see how it compares. Just out of interest, are you using the capped cylinders for your wheel primitives, or have you usedd the 'true' cylinders patch that's floating around. Just wondering as I heard that the cylinder/tri-mesh collision code is dodgy, and I'm guessing you use a tri-mesh to model the ground!

- Iain
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #6
Actually, I'm using spheres! I may move over to capped cylinders but the flat cylinder patch isn't robust enough.

Anyway, I am using trimesh ground, but I'm also using trimesh for trees, boulders, the buildings, etc. It works beautifully, though you have to be a little careful regarding places where trimeshes intersect, because bodies ( like my wheel spheres ) can go to infinity (and beyond) when they get caught up in the intersection.
Quote this message in a reply
Member
Posts: 156
Joined: 2002.10
Post: #7
Here is a build of my car demo. Have a play around with it:

A = accelerate
Z = handbrake
N,M = steering

There are a couple of issues with the simulation:

1. Although the physics is time-dependent, the acceleration and steering aren't yet (quick hack together), so slower computers will see slower accleration and steering

2. Currently, the dimensions are 'realistic' i.e. the car is 5x3x3 m, wheels are 0.3 m radius etc. However, the masses are all way off as the car is 1.0kg and the wheels are 0.2kg each! However, if I go to 'realistic' masses then the wheels tend to spin and the car accelerates very slowly. This is an issue as I plan to eventually support weights from 100kg (Dune buggy) to 20 tons (Battle tank!). If anyone has any idea how I can get the tires to grip better in this situation then let me know.

3. The car tends to roll when cornering - if anyone knows how to make the car grip the road better then that would be cool also.

4. Instabilities - sometimes the car will suddenly spin (if it has previously spun) and it can be hard to correct without stopping the car and starting again.

Anyway, the download is here : http://www.pyramid-productions.net/Trucks.tgz (1.7 MB)

Give it a shot and any feedback on the handling of the car, or any of the above would be cool. Also, if the thing won't run then it's probably my dodgy packaging - give me your crash log output.

For those of you who know ODE, the relevant code is below:


Code called every simulation frame
PHP Code:
        double omega speed dGeomSphereGetRadius(spheres[0]);
        for (
int i 04i++){
            if (
omega dJointGetHinge2Param(joint[i], dParamVel2)){
                if (
2)
                    
dJointSetHinge2Param (joint[i],dParamFMax2,100.0);
                    
dJointSetHinge2Param (joint[i],dParamVel2,-omega);
            }else{
                
dJointSetHinge2Param (joint[i],dParamFMax2,50.0);
                
dJointSetHinge2Param (joint[i],dParamVel2,-omega);
            }
        }
        
        if (
handbrake){
            
dJointSetHinge2Param (joint[2],dParamFMax2,1000.0);
            
dJointSetHinge2Param (joint[2],dParamVel2,0.0);
            
dJointSetHinge2Param (joint[3],dParamFMax2,1000.0);
            
dJointSetHinge2Param (joint[3],dParamVel2,0.0);
        }
        
        
// steering
        
        
dReal v steer dJointGetHinge2Angle1 (joint[0]);
        
dJointSetHinge2Param (joint[0],dParamVel,v);
        
steer dJointGetHinge2Angle1 (joint[1]);
        
dJointSetHinge2Param (joint[1],dParamVel,v); 


Collision callback:
PHP Code:
void GameWorld::nearCallback (void *datadGeomID o1dGeomID o2)
{
    
GameWorldPtr gw GameWorldPtr(data);
    
int i,n;
    
    
dBodyID b1 dGeomGetBody(o1);
    
dBodyID b2 dGeomGetBody(o2);
    if (
b1 && b2 && dAreConnected(b1b2))
        return; 
// Don't collide if connected by a joint
    
    
const int N 10;
    
dContact contact[N];
    
dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact));
    if (
0) {
        for (
i=0i<ni++) {
            
contact[i].surface.mode dContactApprox1 dContactSlip1 dContactSlip2;
            
contact[i].surface.mu dInfinity;
            
contact[i].surface.slip1 0.1;
            
contact[i].surface.slip2 0.1;
            if (
b1 == gw->wheels[2] || b2 == gw->wheels[2] || b1 == gw->wheels[3] || b2 == gw->wheels[3] && gw->handbrake)
                
contact[i].surface.mu 1.0;
                
            
dJointID c_joint dJointCreateContact (gw->world,gw->contactgroup,&contact[i]);
            
dJointAttach (c_joint,
                          
dGeomGetBody(contact[i].geom.g1),
                          
dGeomGetBody(contact[i].geom.g2));
        }
    }



Cheers

- Iain
Quote this message in a reply
Sage
Posts: 1,234
Joined: 2002.10
Post: #8
can't open library: /usr/local/lib/libfreetype.6.dylib (No such file or directory, errno = 2)
Quote this message in a reply
Member
Posts: 156
Joined: 2002.10
Post: #9
Should be good to go now (maybe...) http://www.pyramid-productions.net/Trucks.tgz

- Iain
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #10
No freetype here, either. But, looking at your nearCallback, I can say that one of the things that made my game more playable was to actually *not* use dInfinity for friction. My car tended to flip and pop wheelies when friction's too high.

What I did was to have custom mu for every object in the game ( everything managed by ODE derives from a "Collidable" base class, which has dBodySetData and dGeomSetData pointing to the Collidable instance, so I can safely cast out a collidable in my nearCallback and then just ask for mu and other factors ) -- to calculate the friction for a given collision I have a hacked up calculation which ( if I recall, I'm at work ) is the product divided by the sum of the two geom's mu. This allows for high-friction objects to stick, but if one has *no* friction, the other will slide.

Anyway, I don't use hinge2, so I can't comment on that. I've got a more or less "real" suspension. I'll post a build later which you can drive, but I'll warn you now stencil shadows don't work on ATI cards right now. I'm working on that Wink
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #11
OK, I just used ln to link freetype so I got it working. Looking at the geometry of the vehicle, I'd say that your first problem is the center of mass is too high. You can use dMassTranslate to *fake* moving the mass down a little -- watch out though, if you move it too far you'll get new oddities.

Second, you might want to move the wheels out from the chassis a little, even if you draw it conventionally.

Third, I don't know if you've done this, but if you're dealing with more than one powered wheel ( in my game I've got 4 wheel drive ) you'll absolutely, positively, 100% *need* to implement a differential. I don't know what kind of experience you've got in the real world or in engineering, but differentials allow for the wheels on the outside of a turn to spin more quickly and the wheels on the inside to spin more slowly. What I did was to increase speed and torque on the outer wheels, and decrease speed and torque on the inner. I also modulate total speed just a little when turning sharply to minimize fishtailing.

The good news about ODE is that it works. The bas news about ODE is that it works correctly, but with a finite subset of reality, missing things like kinetic friction, atmospheric drag and so on.

You'll have to do a metric shit-ton of magic to make an ODE based driving game fun Rasp
Quote this message in a reply
Member
Posts: 86
Joined: 2005.01
Post: #12
It's pretty neat. Smile Maybe the car needs a little bit more mass; mine keeps rolling from side to side when I make a tight turn.

Fun, though: I could see a fairly decent top-down racer (or GTA clone) out of this.
Quote this message in a reply
Member
Posts: 320
Joined: 2003.06
Post: #13
I found that mu of about 20 and slip of about 0.4 was pretty good in general. I also found that setting the velcocities like that meant that the car would never roll forward and backward properly so I ended up using:
dJointAddHinge2Torques(_joints[i], 0, -_power * timeInterval);
instead of
dJointSetHinge2Param (joint[i],dParamFMax2,50.0);
dJointSetHinge2Param (joint[i],dParamVel2,-omega);
Actually, I'm not entirely sure whether that * timeInterval should be there, but my time interval is always constant so it shouldn't really matter.

Also.. using this for my steering:
float leftAdjust = (_steer > 0 ? _steer : _steer * TURN_INNER_SCALE);
float rightAdjust = (_steer < 0 ? _steer : _steer * TURN_INNER_SCALE);
dJointSetHinge2Param(_joints[TIRE_FRONT_LEFT], dParamLoStop, leftAdjust );
dJointSetHinge2Param(_joints[TIRE_FRONT_LEFT], dParamHiStop, leftAdjust );
dJointSetHinge2Param(_joints[TIRE_FRONT_RIGHT], dParamLoStop, rightAdjust );
dJointSetHinge2Param(_joints[TIRE_FRONT_RIGHT], dParamHiStop, rightAdjust );
dJointSetHinge2Param(_joints[TIRE_FRONT_LEFT], dParamLoStop, leftAdjust );
dJointSetHinge2Param(_joints[TIRE_FRONT_LEFT], dParamHiStop, leftAdjust );
dJointSetHinge2Param(_joints[TIRE_FRONT_RIGHT], dParamLoStop, rightAdjust );
dJointSetHinge2Param(_joints[TIRE_FRONT_RIGHT], dParamHiStop, rightAdjust );

stopped the wheels from bouncing at strange angles occasionally as they did when I used the method you are using. You have to do it twice because of a bug in ode. (possibly fixed in latest version?)

And if you roll the car too much, lower the center of mass, decrease the mass of the chasis or increase the tire mass, make the wheels further apart, increase slip.

Seems that making ODE car games is the thing to do at the moment. Wink
David

Chopper, iSight Screensavers, DuckDuckDuck: http://majicjungle.com
Quote this message in a reply
Puzzler183
Unregistered
 
Post: #14
ravuya Wrote:It's pretty neat. Smile Maybe the car needs a little bit more mass; mine keeps rolling from side to side when I make a tight turn.

You might actually want to play with (read: lower) the center of mass to fix that... Not physically accurate but from my experience (which is largely with editting GTA Grin) it will work.
Quote this message in a reply
Member
Posts: 156
Joined: 2002.10
Post: #15
Another build up now: http://www.pyramid-productions.net/Trucks.tgz

This time with lower centre of mass and wider wheelbase, the vehicle is less likely to roll. However, I still have the problem of the back end 'spinning out' when turning sharp corners. Also, the freetype dylib problems should now be gone for good.

I haven't implemented a differential yet - do you think this would help here?

What I am aiming for is a driving experience that is 'fun' in the sense that it feels pretty realistic, but the driver isn't going to flip their car unless then collide with some obstacles, bumps etc.

- Iain
Quote this message in a reply
Post Reply