Arithmetic crash with veichle

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
giulioz
Posts: 5
Joined: Sun Sep 04, 2011 5:34 pm

Arithmetic crash with veichle

Post by giulioz »

Hi!

When I add an veichle to the space i get the follow error (ehm... I have VS in italian...):

Code: Select all

System.ArithmeticException non è stata gestita
  Message=La funzione non accetta valori in virgola mobile non numerici.
  Source=mscorlib
  StackTrace:
       in System.Math.Sign(Single value)
       in BEPUphysics.CollisionShapes.ConvexShapes.BoxShape.GetBoundingBox(RigidTransform& shapeTransform, BoundingBox& boundingBox)
       in BEPUphysics.Collidables.MobileCollidables.ConvexCollidable`1.UpdateBoundingBoxInternal(Single dt)
       in BEPUphysics.Collidables.MobileCollidables.EntityCollidable.UpdateBoundingBox(Single dt)
       in BEPUphysics.Collidables.MobileCollidables.EntityCollidable.UpdateBoundingBox()
       in BEPUphysics.BroadPhaseSystems.Hierarchies.DynamicHierarchy.Add(BroadPhaseEntry entry)
       in BEPUphysics.Space.Add(ISpaceObject spaceObject)
       in BEPUphysics.Vehicle.Vehicle.OnAdditionToSpace(ISpace newSpace)
       in BEPUphysics.Space.Add(ISpaceObject spaceObject)
       in DrivingSim.Tank.Load(ContentManager content, Space space) in d:\documents and settings\guz! software\documenti\visual studio 2010\Projects\DrivingSim\DrivingSim\DrivingSim\Tank.cs:riga 172
       in DrivingSim.Game1.LoadContent() in d:\documents and settings\guz! software\documenti\visual studio 2010\Projects\DrivingSim\DrivingSim\DrivingSim\Game1.cs:riga 43
       in Microsoft.Xna.Framework.Game.Initialize()
       in DrivingSim.Game1.Initialize() in d:\documents and settings\guz! software\documenti\visual studio 2010\Projects\DrivingSim\DrivingSim\DrivingSim\Game1.cs:riga 37
       in Microsoft.Xna.Framework.Game.RunGame(Boolean useBlockingRun)
       in Microsoft.Xna.Framework.Game.Run()
       in DrivingSim.Program.Main(String[] args) in d:\documents and settings\guz! software\documenti\visual studio 2010\Projects\DrivingSim\DrivingSim\DrivingSim\Program.cs:riga 15
  InnerException: 
That's the code:

Code: Select all

// Fisica.
Vehicle physics;
Wheel[] wheels;

(...)

// Inizializza la fisica.
 wheels = new Wheel[4];

wheels[0] = new Wheel(new RaycastWheelShape(20, Matrix.Identity));
wheels[1] = new Wheel(new RaycastWheelShape(20, Matrix.Identity));
wheels[2] = new Wheel(new RaycastWheelShape(20, Matrix.Identity));
wheels[3] = new Wheel(new RaycastWheelShape(20, Matrix.Identity));

physics = new Vehicle(new Box(new BEPUphysics.EntityStateManagement.MotionState(), 50, 50, 100), wheels);
space.Add(physics); // ERROR
Thanks you very much!
Very AWESOME engine! :D
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Arithmetic crash with veichle

Post by Norbo »

The WheelShape-only constructor expects the constituent wheels to be fully initialized after construction and before usage. If they are not set up before the simulation runs, bad things happen :)

The VehicleInput class in the BEPUphysicsDemos project shows how to set up a wheel fully using the other constructor:

Code: Select all

            var bodies = new List<CompoundShapeEntry>()
            {
                new CompoundShapeEntry(new BoxShape(2.5f, .75f, 4.5f), new Vector3(0, 0, 0), 60),
                new CompoundShapeEntry(new BoxShape(2.5f, .3f, 2f), new Vector3(0, .75f / 2 + .3f / 2, .5f), 1)
            };
            var body = new CompoundBody(bodies, 61);
            body.CollisionInformation.LocalPosition = new Vector3(0, .5f, 0);
            body.Position = (position); //At first, just keep it out of the way.
            Vehicle = new Vehicle(body);


            //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(.375f, wheelGraphicRotation),
                                 new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(-1.1f, 0, 1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));
            Vehicle.AddWheel(new Wheel(
                                 new RaycastWheelShape(.375f, wheelGraphicRotation),
                                 new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(-1.1f, 0, -1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));
            Vehicle.AddWheel(new Wheel(
                                 new RaycastWheelShape(.375f, wheelGraphicRotation),
                                 new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(1.1f, 0, 1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));
            Vehicle.AddWheel(new Wheel(
                                 new RaycastWheelShape(.375f, wheelGraphicRotation),
                                 new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(1.1f, 0, -1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));
giulioz
Posts: 5
Joined: Sun Sep 04, 2011 5:34 pm

Re: Arithmetic crash with veichle

Post by giulioz »

Thank you so much, now i didn't get the error but the veichle is static :(

Code: Select all

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using BEPUphysics.Vehicle;
using BEPUphysics.Entities.Prefabs;
using BEPUphysics;
using BEPUphysics.CollisionShapes;
using BEPUphysics.CollisionShapes.ConvexShapes;

namespace DrivingSim
{
    public class Tank
    {
        #region Fields


        // The XNA framework Model object that we are going to display.
        Model tankModel;


        // Shortcut references to the bones that we are going to animate.
        // We could just look these up inside the Draw method, but it is more
        // efficient to do the lookups while loading and cache the results.
        ModelBone leftBackWheelBone;
        ModelBone rightBackWheelBone;
        ModelBone leftFrontWheelBone;
        ModelBone rightFrontWheelBone;
        ModelBone leftSteerBone;
        ModelBone rightSteerBone;
        ModelBone turretBone;
        ModelBone cannonBone;
        ModelBone hatchBone;


        // Store the original transform matrix for each animating bone.
        Matrix leftBackWheelTransform;
        Matrix rightBackWheelTransform;
        Matrix leftFrontWheelTransform;
        Matrix rightFrontWheelTransform;
        Matrix leftSteerTransform;
        Matrix rightSteerTransform;
        Matrix turretTransform;
        Matrix cannonTransform;
        Matrix hatchTransform;


        // Array holding all the bone transform matrices for the entire model.
        // We could just allocate this locally inside the Draw method, but it
        // is more efficient to reuse a single array, as this avoids creating
        // unnecessary garbage.
        Matrix[] boneTransforms;


        // Current animation positions.
        float wheelRotationValue;
        float steerRotationValue;
        float turretRotationValue;
        float cannonRotationValue;
        float hatchRotationValue;

        
        // Fisica.
        Vehicle physics;
        public float BackwardSpeed = -13;
        public float ForwardSpeed = 30;
        public float MaximumTurnAngle = (float)Math.PI / 6;
        public float TurnSpeed = MathHelper.Pi;

        public Vector3 tankPos;
        public Quaternion tankRot;


        #endregion

        #region Properties


        /// <summary>
        /// Gets or sets the wheel rotation amount.
        /// </summary>
        public float WheelRotation
        {
            get { return wheelRotationValue; }
            set { wheelRotationValue = value; }
        }


        /// <summary>
        /// Gets or sets the steering rotation amount.
        /// </summary>
        public float SteerRotation
        {
            get { return steerRotationValue; }
            set { steerRotationValue = value; }
        }


        /// <summary>
        /// Gets or sets the turret rotation amount.
        /// </summary>
        public float TurretRotation
        {
            get { return turretRotationValue; }
            set { turretRotationValue = value; }
        }


        /// <summary>
        /// Gets or sets the cannon rotation amount.
        /// </summary>
        public float CannonRotation
        {
            get { return cannonRotationValue; }
            set { cannonRotationValue = value; }
        }


        /// <summary>
        /// Gets or sets the entry hatch rotation amount.
        /// </summary>
        public float HatchRotation
        {
            get { return hatchRotationValue; }
            set { hatchRotationValue = value; }
        }


        #endregion


        /// <summary>
        /// Loads the tank model.
        /// </summary>
        public void Load(ContentManager content, Space space)
        {
            // Load the tank model from the ContentManager.
            tankModel = content.Load<Model>("tank");

            // Look up shortcut references to the bones we are going to animate.
            leftBackWheelBone = tankModel.Bones["l_back_wheel_geo"];
            rightBackWheelBone = tankModel.Bones["r_back_wheel_geo"];
            leftFrontWheelBone = tankModel.Bones["l_front_wheel_geo"];
            rightFrontWheelBone = tankModel.Bones["r_front_wheel_geo"];
            leftSteerBone = tankModel.Bones["l_steer_geo"];
            rightSteerBone = tankModel.Bones["r_steer_geo"];
            turretBone = tankModel.Bones["turret_geo"];
            cannonBone = tankModel.Bones["canon_geo"];
            hatchBone = tankModel.Bones["hatch_geo"];

            // Store the original transform matrix for each animating bone.
            leftBackWheelTransform = leftBackWheelBone.Transform;
            rightBackWheelTransform = rightBackWheelBone.Transform;
            leftFrontWheelTransform = leftFrontWheelBone.Transform;
            rightFrontWheelTransform = rightFrontWheelBone.Transform;
            leftSteerTransform = leftSteerBone.Transform;
            rightSteerTransform = rightSteerBone.Transform;
            turretTransform = turretBone.Transform;
            cannonTransform = cannonBone.Transform;
            hatchTransform = hatchBone.Transform;

            // Allocate the transform matrix array.
            boneTransforms = new Matrix[tankModel.Bones.Count];

            // Inizializza la fisica.
            tankPos = new Vector3(0, 0, 0);
            tankRot = new Quaternion(0, 0, 0, 0);

            /*wheels[0] = new Wheel(new RaycastWheelShape(2, Matrix.Identity));
            wheels[1] = new Wheel(new RaycastWheelShape(2, Matrix.Identity));
            wheels[2] = new Wheel(new RaycastWheelShape(2, Matrix.Identity));
            wheels[3] = new Wheel(new RaycastWheelShape(2, Matrix.Identity));

            physics = new Vehicle(new Box(new BEPUphysics.EntityStateManagement.MotionState(), 5, 5, 10), wheels);
            space.Add(physics);*/

            var bodies = new List<CompoundShapeEntry>()
            {
                new CompoundShapeEntry(new BoxShape(2.5f, .75f, 4.5f), new Vector3(0, 0, 0), 60),
                new CompoundShapeEntry(new BoxShape(2.5f, .3f, 2f), new Vector3(0, .75f / 2 + .3f / 2, .5f), 1)
            };
            var body = new CompoundBody(bodies, 61);
            body.CollisionInformation.LocalPosition = new Vector3(0, .5f, 0);
            body.Position = (tankPos);
            physics = new Vehicle(body);

            #region RaycastWheelShapes

            Matrix wheelGraphicRotation = Matrix.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);
            physics.AddWheel(new Wheel(
                                 new RaycastWheelShape(.375f, wheelGraphicRotation),
                                 new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(-1.1f, 0, 1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));
            physics.AddWheel(new Wheel(
                                 new RaycastWheelShape(.375f, wheelGraphicRotation),
                                 new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(-1.1f, 0, -1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));
            physics.AddWheel(new Wheel(
                                 new RaycastWheelShape(.375f, wheelGraphicRotation),
                                 new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(1.1f, 0, 1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));
            physics.AddWheel(new Wheel(
                                 new RaycastWheelShape(.375f, wheelGraphicRotation),
                                 new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(1.1f, 0, -1.8f)),
                                 new WheelDrivingMotor(2.5f, 30000, 10000),
                                 new WheelBrake(1.5f, 2, .02f),
                                 new WheelSlidingFriction(4, 5)));

            #endregion


            foreach (Wheel wheel in physics.Wheels)
            {
                wheel.Shape.FreezeWheelsWhileBraking = true;
                wheel.Suspension.SolverSettings.MaximumIterations = 1;
                wheel.Brake.SolverSettings.MaximumIterations = 1;
                wheel.SlidingFriction.SolverSettings.MaximumIterations = 1;
                wheel.DrivingMotor.SolverSettings.MaximumIterations = 1;
            }

            space.Add(physics);
        }


        /// <summary>
        /// Draws the tank model, using the current animation settings.
        /// </summary>
        public void Draw(Matrix world, Matrix view, Matrix projection)
        {
            // Set the world matrix as the root transform of the model.
            tankModel.Root.Transform = world;

            // Calculate matrices based on the current animation position.
            Matrix wheelRotation = Matrix.CreateRotationX(wheelRotationValue);
            Matrix steerRotation = Matrix.CreateRotationY(steerRotationValue);
            Matrix turretRotation = Matrix.CreateRotationY(turretRotationValue);
            Matrix cannonRotation = Matrix.CreateRotationX(cannonRotationValue);
            Matrix hatchRotation = Matrix.CreateRotationX(hatchRotationValue);

            // Apply matrices to the relevant bones.
            leftBackWheelBone.Transform = wheelRotation * leftBackWheelTransform;
            rightBackWheelBone.Transform = wheelRotation * rightBackWheelTransform;
            leftFrontWheelBone.Transform = wheelRotation * leftFrontWheelTransform;
            rightFrontWheelBone.Transform = wheelRotation * rightFrontWheelTransform;
            leftSteerBone.Transform = steerRotation * leftSteerTransform;
            rightSteerBone.Transform = steerRotation * rightSteerTransform;
            turretBone.Transform = turretRotation * turretTransform;
            cannonBone.Transform = cannonRotation * cannonTransform;
            hatchBone.Transform = hatchRotation * hatchTransform;

            // Look up combined bone matrices for the entire model.
            tankModel.CopyAbsoluteBoneTransformsTo(boneTransforms);

            // Draw the model.
            foreach (ModelMesh mesh in tankModel.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.World = boneTransforms[mesh.ParentBone.Index];
                    effect.View = view;
                    effect.Projection = projection;

                    effect.EnableDefaultLighting();
                }

                mesh.Draw();
            }
        }

        public void Update(float dt, KeyboardState keyboardInput)
        {
            leftBackWheelBone.Transform = physics.Wheels[0].Shape.WorldTransform;
            rightBackWheelBone.Transform = physics.Wheels[1].Shape.WorldTransform;
            leftFrontWheelBone.Transform = physics.Wheels[2].Shape.WorldTransform;
            rightFrontWheelBone.Transform = physics.Wheels[3].Shape.WorldTransform;

            tankPos = physics.Body.Position;
            tankRot = physics.Body.Orientation;

            if (keyboardInput.IsKeyDown(Keys.E))
            {
                //Drive
                physics.Wheels[1].DrivingMotor.TargetSpeed = ForwardSpeed;
                physics.Wheels[3].DrivingMotor.TargetSpeed = ForwardSpeed;
            }
            else if (keyboardInput.IsKeyDown(Keys.D))
            {
                //Reverse
                physics.Wheels[1].DrivingMotor.TargetSpeed = BackwardSpeed;
                physics.Wheels[3].DrivingMotor.TargetSpeed = BackwardSpeed;
            }
            else
            {
                //Idle
                physics.Wheels[1].DrivingMotor.TargetSpeed = 0;
                physics.Wheels[3].DrivingMotor.TargetSpeed = 0;
            }
            if (keyboardInput.IsKeyDown(Keys.Space))
            {
                //Brake
                foreach (Wheel wheel in physics.Wheels)
                {
                    wheel.Brake.IsBraking = true;
                }
            }
            else
            {
                //Release brake
                foreach (Wheel wheel in physics.Wheels)
                {
                    wheel.Brake.IsBraking = false;
                }
            }
            //Use smooth steering; while held down, move towards maximum.
            //When not pressing any buttons, smoothly return to facing forward.
            float angle;
            bool steered = false;
            if (keyboardInput.IsKeyDown(Keys.S))
            {
                steered = true;
                angle = Math.Max(physics.Wheels[1].Shape.SteeringAngle - TurnSpeed * dt, -MaximumTurnAngle);
                physics.Wheels[1].Shape.SteeringAngle = angle;
                physics.Wheels[3].Shape.SteeringAngle = angle;
            }
            if (keyboardInput.IsKeyDown(Keys.F))
            {
                steered = true;
                angle = Math.Min(physics.Wheels[1].Shape.SteeringAngle + TurnSpeed * dt, MaximumTurnAngle);
                physics.Wheels[1].Shape.SteeringAngle = angle;
                physics.Wheels[3].Shape.SteeringAngle = angle;
            }
            if (!steered)
            {
                //Neither key was pressed, so de-steer.
                if (physics.Wheels[1].Shape.SteeringAngle > 0)
                {
                    angle = Math.Max(physics.Wheels[1].Shape.SteeringAngle - TurnSpeed * dt, 0);
                    physics.Wheels[1].Shape.SteeringAngle = angle;
                    physics.Wheels[3].Shape.SteeringAngle = angle;
                }
                else
                {
                    angle = Math.Min(physics.Wheels[1].Shape.SteeringAngle + TurnSpeed * dt, 0);
                    physics.Wheels[1].Shape.SteeringAngle = angle;
                    physics.Wheels[3].Shape.SteeringAngle = angle;
                }
            }
        }
    }
}
Sorry if I'm too noob!
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Arithmetic crash with veichle

Post by Norbo »

The vehicle's body is kinematic because no mass was provided in the constructor. Kinematic entities have essentially infinite mass, so no regular force can move them. Pass one more parameter for the mass in the vehicle's body's constructor.
hatef
Posts: 2
Joined: Sat Mar 03, 2012 3:16 pm

Re: Arithmetic crash with veichle

Post by hatef »

The vehicle's body is kinematic because no mass was provided in the constructor. Kinematic entities have essentially infinite mass, so no regular force can move them. Pass one more parameter for the mass in the vehicle's body's constructor.
Hi norbo,

Could you clarify what you mean by "the vehicle's body's constructor", my code looks like this

var bodies = new List<CompoundShapeEntry>()
{
new CompoundShapeEntry(new BoxShape(2.5f, .75f, 4.5f), new Vector3(0, 0, 0), 60),
new CompoundShapeEntry(new BoxShape(2.5f, .3f, 2f), new Vector3(0, .75f / 2 + .3f / 2, .5f), 1)
};
var body = new CompoundBody(bodies, 61);
body.CollisionInformation.LocalPosition = new Vector3(0, 1.2f, 0);
body.Position = (carPos);
//body.InverseMass = 61;
carPhysics = new Vehicle(body);


the only vehicle constructors i find are these two:

Vehicle(Entity) Constructs a vehicle.
Vehicle(Entity, IEnumerable<(Of <<'(Wheel>)>>)) Constructs a vehicle.

Am i missing something?

could you explain with an example?

Thank you so much for this engine, its amazing.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Arithmetic crash with veichle

Post by Norbo »

Sorry about that, I was looking at some apparently old/commented code.

That CompoundBody is given a mass in its constructor, so it will be dynamic. That is correct.

I don't see anything that would explain being 'static.' In what way is it static?
hatef
Posts: 2
Joined: Sat Mar 03, 2012 3:16 pm

Re: Arithmetic crash with veichle

Post by hatef »

Hi,

Thanks for your reply, it was actually a very big model with a very small vehicle attached so it wasnt moving very fast lol.

Thank you anyway.
Post Reply