ODE: Car simulations

Sage
Posts: 1,199
Joined: 2004.10
Post: #16
You *need* a differential. I'm serious -- and it isn't that hard.

Here's my approach ( again, I'm not using Hinge2 ). Also, I'm using a C++ wrapper to ODE which I developed independantly for robotics simulation, but the code ought to be legible nonetheless.

Code:
void Player::setSpeed( float speed )
{
    if ( _brakes )
    {
        _motors[ Q_FrontLeft ]->setSpeed( 0 );
        _motors[ Q_FrontRight ]->setSpeed( 0 );
        _motors[ Q_BackLeft ]->setSpeed( 0 );
        _motors[ Q_BackRight ]->setSpeed( 0 );
    
        return;
    }

    _speed = speed;
    if ( _speed < -1.0f )
    {
        _speed = -1.0f;
        _speedAccumulator = -1.0f;
    }
    else if ( _speed > 1.0f )
    {
        _speed = 1.0f;
        _speedAccumulator = 1.0f;
    }
    
    /*
        Calculate differential wheel speeds. This is not
        by any means a correct calculation, just a hack!
    */
                
    float rightSpeed, leftSpeed, steer = fabs( _steering ), iFactor = 10.0f, iForceFactor = 1.5f,
        rightForce = _defaultMotorTorque, leftForce = _defaultMotorTorque;
    
    if ( _steering > 0.01f )
    {
        /*
            We're turning to the right.
            Right wheels spin less, left wheels spin more
        */
        
        rightSpeed = ( 1.0f - ( steer / iFactor )) * _speed;
        leftSpeed = ( 1.0f + ( steer / iFactor )) * _speed;        
        rightForce *= ( 1.0f - (steer / iForceFactor ));
        if ( rightForce < 0 ) rightForce = 0;
    }
    else if ( _steering < -0.01f )
    {
        /*
            We're turning to the left.
            Right wheels spin more, left wheels spin less
        */

        rightSpeed = ( 1.0f + ( steer / iFactor )) * _speed;
        leftSpeed = ( 1.0f - ( steer / iFactor )) * _speed;        
        leftForce *= ( 1.0f - (steer / iForceFactor ));
        if ( leftForce < 0 ) leftForce = 0;
    }
    else
    {
        rightSpeed = _speed;
        leftSpeed = _speed;
    }
    
    _motors[ Q_FrontLeft ]->setSpeed( leftSpeed );
    _motors[ Q_FrontRight ]->setSpeed( rightSpeed );
    _motors[ Q_BackLeft ]->setSpeed( leftSpeed );
    _motors[ Q_BackRight ]->setSpeed( rightSpeed );
    
    _motors[ Q_FrontLeft ]->setForce( leftForce );
    _motors[ Q_FrontRight ]->setForce( rightForce );
    _motors[ Q_BackLeft ]->setForce( leftForce );
    _motors[ Q_BackRight ]->setForce( rightForce );
}

With a differential, you'll see a lot of improvement. That said, when it comes to flipping, you've got to decide what kind of gameplay you're interested in.

On the one hand you could have a game like that Simpsons GTA game where you simply *can't* flip the car. This is good if your interest is speed and unrealistic playability with the focus on getting around. I've not approached this, so I can't comment on technique.

In my game, which is meant to be sort of gritty and "realistic" ( realistic is subjective when you're talking about fighting swarms of energy-based aliens on a terraformed planet ) you can flip if you hit a boulder or tree going top speed, or drive off a cliff, or run into your base or whatever.

If you're going to let it flip, you've got to come up with a way to handle that -- either provide an unflip mechanism or say "Game Over". If you do provide an unflipper, ODE doesn't like for you to just reset position and orientation -- that will result in a *massive* change in linear/angular velocity in just one timestep. So don't do it. You'll have to come up with a physically plausible way to unflip. In my robotics simulation, some of my robots have a "rollbar" which extends and unflips the little guy if he turns over. In my game, the rover has a rocket engine which applies a linear thrust and unflips you.
Quote this message in a reply
Member
Posts: 320
Joined: 2003.06
Post: #17
Quote: If you do provide an unflipper, ODE doesn't like for you to just reset position and orientation -- that will result in a *massive* change in linear/angular velocity in just one timestep. So don't do it.


Damn. I hoped this wasn't the case. Currently in my game I reset the car by deleting it and making it again. Thing is, a networked multiplayer game would need that ability to keep everyone in sync. Any ideas how that would work?

David

Chopper, iSight Screensavers, DuckDuckDuck: http://majicjungle.com
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #18
If you can delete and recreate your car quickly, I don't see any problem with that approach. Obviously, you'll have to send some sort of notification to all clients -- and the fact that the same player is now represented by completely different geoms may be an issue.

Frankly, multiplayer networked ODE sounds like more trouble than it's worth to me. The first class game-physics engines have robustly solved this stuff already, whereas ODE doesn't even approach it, much less provide a model which lends itself to it. You can't really ( you can, but not elegently ) serialize ODE state and fire it across the nework...
Quote this message in a reply
Post Reply