Vehicle simulation

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
vittix
Posts: 3
Joined: Sat Aug 25, 2012 2:08 pm

Vehicle simulation

Post by vittix »

Hi to all,
from about two days i'm trying to setup a vehicle simulation,my objective is obtain a fast and stable car.
I've managed to setup the vehicle and the environment, i've also obtain the car to move and steer but when i make steer the car, the car always tend to go on two wheels. i've tryed playing with the mass and the suspension values but with no success.
also i'm making accelerate the front wheel to simulate front traction and i've noticed two problems when it brakes the car rear go up, and in backward it seems to reach faster the top speed.
the car is a dodge charger so it has high setup from ground.

if someone could help i would be very grateful.

i post the code for the setupping of the car

Code: Select all

  var bodies = new List<CompoundShapeEntry>()
            {
                new CompoundShapeEntry(new BoxShape(7.45f, 2.83f, 16.5f), new Vector3(0, 0.0f, 0), 400),
                new CompoundShapeEntry(new BoxShape(7.5f, 1.14f, 6), new Vector3(0, 1.965f, 1.477f), 350)
            };

            CompoundBody vehiclebody=new CompoundBody(bodies,750);
        

            vehiclebody.Material.Bounciness = 0.2f;
            vehiclebody.Material.KineticFriction = 1;
            vehiclebody.Material.StaticFriction = 1;

            vehicle = new Vehicle(vehiclebody);


            #region RaycastWheelShapes
            //The wheel model used is not aligned initially with how a wheel would normally look, so rotate them.
            Matrix wheelGraphicRotation = Matrix.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);
            vehicle.AddWheel(new Wheel(
                new RaycastWheelShape(1.5f, wheelGraphicRotation),
                new WheelSuspension(1000, 200, Vector3.Down, 1f, new Vector3(-2.737f, -2f, 4.949f)),
                new WheelDrivingMotor(22, 60000, 10000),
                new WheelBrake(4, 6, .01f),
                new WheelSlidingFriction(8,10)));

            vehicle.AddWheel(new Wheel(
                new RaycastWheelShape(1.5f, wheelGraphicRotation),
                new WheelSuspension(1000, 200, Vector3.Down, 1f, new Vector3(2.737f, -2f, 4.949f)),
                new WheelDrivingMotor(22, 60000, 10000),
                new WheelBrake(4, 6, .01f),
                new WheelSlidingFriction(8, 10)));

            vehicle.AddWheel(new Wheel(
                new RaycastWheelShape(1.5f, wheelGraphicRotation),
                new WheelSuspension(1000, 200, Vector3.Down, 1f, new Vector3(-2.737f, -2f, -4.895f)),
                new WheelDrivingMotor(22, 60000, 10000),
                new WheelBrake(4, 6, .01f),
                new WheelSlidingFriction(8, 10)));

            vehicle.AddWheel(new Wheel(
                new RaycastWheelShape(1.5f, wheelGraphicRotation),
                new WheelSuspension(1000, 200, Vector3.Down, 1f, new Vector3(2.737f, -2f, -4.895f)),
                new WheelDrivingMotor(22, 60000, 10000),
                new WheelBrake(4, 6, .01f),
                new WheelSlidingFriction(8, 10)));
and the update of the car

Code: Select all

 if (GamePad.GetState(PlayerIndex.One).IsButtonDown(Buttons.Y))
            {
                vehicle.Body.WorldTransform = Matrix.CreateFromYawPitchRoll(0, 0, 0);
                vehicle.Body.Position = Vector3.Zero + (Vector3.Down * 90);
            }
            if (GamePad.GetState(PlayerIndex.One).IsButtonDown(Buttons.A))
            {
                vehicle.Wheels[0].Brake.IsBraking = true;
                vehicle.Wheels[1].Brake.IsBraking = true;
                vehicle.Wheels[2].Brake.IsBraking = true;
                vehicle.Wheels[3].Brake.IsBraking = true;
            }
            if (GamePad.GetState(PlayerIndex.One).IsButtonUp(Buttons.A))
            {
                vehicle.Wheels[0].Brake.IsBraking = false;
                vehicle.Wheels[1].Brake.IsBraking = false;
                vehicle.Wheels[2].Brake.IsBraking = false;
                vehicle.Wheels[3].Brake.IsBraking = false;
            }

 if (GamePad.GetState(PlayerIndex.One).Triggers.Left < 0.3f && GamePad.GetState(PlayerIndex.One).Triggers.Right < 0.3f)
            {
                targetspeed = 0;
            }
            if (GamePad.GetState(PlayerIndex.One).Triggers.Right > 0.3f)
            {
                targetspeed = 60000 * GamePad.GetState(PlayerIndex.One).Triggers.Right;
            }
            if (GamePad.GetState(PlayerIndex.One).Triggers.Left > 0.3f)
            {
                targetspeed = -10000 * GamePad.GetState(PlayerIndex.One).Triggers.Left;
            }

            targetrotation = GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.X * ((float)MathHelper.PiOver4 + ((float)MathHelper.PiOver4 / 4));

            if (vehicle.Wheels[2].DrivingMotor.TargetSpeed != targetspeed || vehicle.Wheels[3].DrivingMotor.TargetSpeed != targetspeed)
            {
                if (vehicle.Wheels[2].DrivingMotor.TargetSpeed < targetspeed)
                {

                    vehicle.Wheels[2].DrivingMotor.TargetSpeed += gameTime.ElapsedGameTime.Milliseconds * 0.1f;
                    vehicle.Wheels[3].DrivingMotor.TargetSpeed += gameTime.ElapsedGameTime.Milliseconds * 0.1f;
                }
               

                if (vehicle.Wheels[2].DrivingMotor.TargetSpeed > targetspeed)
                {
                    vehicle.Wheels[2].DrivingMotor.TargetSpeed -= gameTime.ElapsedGameTime.Milliseconds * 0.1f;
                    vehicle.Wheels[3].DrivingMotor.TargetSpeed += gameTime.ElapsedGameTime.Milliseconds * 0.1f;
                  
                }
              
                
            }
            if (vehicle.Wheels[2].Shape.SteeringAngle != targetrotation && vehicle.Wheels[3].Shape.SteeringAngle != targetrotation)
            {
                if (vehicle.Wheels[2].Shape.SteeringAngle < targetrotation)
                {

                    vehicle.Wheels[2].Shape.SteeringAngle += gameTime.ElapsedGameTime.Milliseconds * 0.0025f;
                    MathHelper.Clamp(vehicle.Wheels[2].Shape.SteeringAngle, 0, targetrotation);
                    vehicle.Wheels[3].Shape.SteeringAngle = vehicle.Wheels[2].Shape.SteeringAngle;
                }
                if (vehicle.Wheels[2].Shape.SteeringAngle > targetrotation)
                {
                    vehicle.Wheels[2].Shape.SteeringAngle -= gameTime.ElapsedGameTime.Milliseconds * 0.0025f;
                    MathHelper.Clamp(vehicle.Wheels[2].Shape.SteeringAngle, targetrotation, 0);
                    vehicle.Wheels[3].Shape.SteeringAngle = vehicle.Wheels[2].Shape.SteeringAngle;
                }
            }
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Vehicle simulation

Post by Norbo »

the car always tend to go on two wheels.
The center of mass is likely too high for the speed. You can offset the collision shape from the center of mass by setting body.CollisionInformation.LocalPosition. Here's an example usage from the VehicleInput class in the BEPUphysicsDemos:

Code: Select all

           body.CollisionInformation.LocalPosition = new Vector3(0, .5f, 0);
This means the collision shape is 0.5 units higher than the center of mass. Because the center of mass is lower relative to the body, it tends not to tip so frequently.

The faster you go around a corner, the lower the center of mass should be relative to the body. Try to avoid going so far as putting it underground, though; it will start tipping the other way :)

The weights provided to the compound shape entries are also used to distribute the mass. Giving more weight to the lowest object will help some.
when it brakes the car rear go up
This is also also caused partially by the center of mass being high. Normal cars do this too to a less exaggerated extent because their speeds are lower, braking usually is more gradual, and their center of masses are lower.

Note that the posted code has a maximum speed of 60000 units per second in the forward direction and 10000 units per second in the backward direction due to this code:

Code: Select all

            if (GamePad.GetState(PlayerIndex.One).Triggers.Right > 0.3f)
            {
                targetspeed = 60000 * GamePad.GetState(PlayerIndex.One).Triggers.Right;
            }
            if (GamePad.GetState(PlayerIndex.One).Triggers.Left > 0.3f)
            {
                targetspeed = -10000 * GamePad.GetState(PlayerIndex.One).Triggers.Left;
            }
Given that these values are the same as the motor force values chosen in the constructor, it sounds like you didn't actually want a max speed of 60000 but rather an applied force. The constructor values take care of that; the values in the above code should be target speeds as opposed to force.

There's also an oddity in the changing of the wheel motor target speed:

Code: Select all

                if (vehicle.Wheels[2].DrivingMotor.TargetSpeed < targetspeed)
                {

                    vehicle.Wheels[2].DrivingMotor.TargetSpeed += gameTime.ElapsedGameTime.Milliseconds * 0.1f;
                    vehicle.Wheels[3].DrivingMotor.TargetSpeed += gameTime.ElapsedGameTime.Milliseconds * 0.1f;
                }
               

                if (vehicle.Wheels[2].DrivingMotor.TargetSpeed > targetspeed)
                {
                    vehicle.Wheels[2].DrivingMotor.TargetSpeed -= gameTime.ElapsedGameTime.Milliseconds * 0.1f;
                    vehicle.Wheels[3].DrivingMotor.TargetSpeed += gameTime.ElapsedGameTime.Milliseconds * 0.1f;
                  
                }
Presumably, you want to reduce the target speed of both motors when the wheel target speed is less than the desired speed. As it is, the wheels will go out of sync.
vittix
Posts: 3
Joined: Sat Aug 25, 2012 2:08 pm

Re: Vehicle simulation

Post by vittix »

Thanks changing the local position solved the problem! you saved my life! :)
i'm really new with bepu and i don't understand very well how to set the speed for the wheel to obtain the speed i want.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Vehicle simulation

Post by Norbo »

i'm really new with bepu and i don't understand very well how to set the speed for the wheel to obtain the speed i want.
Check out the VehicleInput in the BEPUphysicsDemos for a simple example. All it does is set the wheel.DrivingMotor.TargetSpeed to the maximum value when the forward or back button is pressed. The car will not instantaneously jump to that speed; it will accelerate according to the strength of the DrivingMotor specified in the constructor. Friction will also play a role; if there isn't enough friction, the car will accelerate slower.

When a wheel.DrivingMotor.TargetSpeed is specified, the wheel will apply the appropriate driving force to reach the speed; if the speed is exceeded, the wheel will not brake to slow down.
-So, if the car's target speed is 30 but the car is rolling down a hill at 35, the wheel driving motor won't do any work.
-If the target speed is -10 and the car is rolling backwards at -15, the wheel driving motor won't do any work.
-If the target speed is zero, the wheel driving motor won't do any work in any case.
-If the target speed is 30 and the car is moving at 15, the driving motor will apply a force.
-If the target speed is -10 and the car is moving at -5, the driving motor will apply a force (to go backwards faster).
-If the target speed is -10 and the car is moving at 5, the driving motor will apply a force (to go backwards faster).

Other motors, like the wheel brake and rolling friction, can slow down the car.
vittix
Posts: 3
Joined: Sat Aug 25, 2012 2:08 pm

Re: Vehicle simulation

Post by vittix »

hi, sorry to bother again now the car is stable and fast as i wanted to, but to add a little fun to the game i would like to simulate the car to drift, but when i try to brake with my settings,the car does not move as i expected. any suggestion?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Vehicle simulation

Post by Norbo »

Braking simply increases the wheel's forward-back friction to the specified brake friction. If you want to force a slide, you may want to reduce the wheels' dynamic and static sliding friction for the duration of the brake. I do not quite know what you expect to see, though, so it's hard to give precise advice :)
Post Reply