public void ManagedUnmanagedConversion()
		{
			var engineData = new VehicleEngineData()
			{
				DampingRateFullThrottle = 1,
				DampingRateZeroThrottleClutchDisengaged = 2,
				DampingRateZeroThrottleClutchEngaged = 3,
				MaxOmega = 4,
				PeakTorque = 5
			};

			var conversion = VehicleEngineData.TestManagedUnmanagedConversion(engineData);

			Assert.AreEqual(1, conversion.DampingRateFullThrottle);
			Assert.AreEqual(2, conversion.DampingRateZeroThrottleClutchDisengaged);
			Assert.AreEqual(3, conversion.DampingRateZeroThrottleClutchEngaged);
			Assert.AreEqual(4, conversion.MaxOmega);
			Assert.AreEqual(5, conversion.PeakTorque);
		}
Beispiel #2
0
        public void ManagedUnmanagedConversion()
        {
            var engineData = new VehicleEngineData()
            {
                DampingRateFullThrottle = 1,
                DampingRateZeroThrottleClutchDisengaged = 2,
                DampingRateZeroThrottleClutchEngaged    = 3,
                MaxOmega   = 4,
                PeakTorque = 5
            };

            var conversion = VehicleEngineData.TestManagedUnmanagedConversion(engineData);

            Assert.AreEqual(1, conversion.DampingRateFullThrottle);
            Assert.AreEqual(2, conversion.DampingRateZeroThrottleClutchDisengaged);
            Assert.AreEqual(3, conversion.DampingRateZeroThrottleClutchEngaged);
            Assert.AreEqual(4, conversion.MaxOmega);
            Assert.AreEqual(5, conversion.PeakTorque);
        }
Beispiel #3
0
		private void CreateVehicle4WSimulationData(
			float chassisMass,
			ConvexMesh chassisConvexMesh,
			float wheelMass, 
			ConvexMesh[] wheelConvexMeshes, 
			Vector3[] wheelCentreOffsets,
			VehicleWheelsSimData wheelsData, 
			VehicleDriveSimData4W driveData, 
			VehicleChassisData chassisData)
		{
			const int TIRE_TYPE_SLICKS = 0;

			//Extract the chassis AABB dimensions from the chassis convex mesh.
			//Vector3 chassisDims = computeChassisAABBDimensions(chassisConvexMesh);
			Vector3 chassisDims = new Vector3(10, 10, 10);

			//The origin is at the center of the chassis mesh.
			//Set the center of mass to be below this point and a little towards the front.
			Vector3 chassisCMOffset = new Vector3(0.0f, -chassisDims.Y * 0.5f + 0.65f, 0.25f);

			//Now compute the chassis mass and moment of inertia.
			//Use the moment of inertia of a cuboid as an approximate value for the chassis moi.
			Vector3 chassisMOI = new Vector3
			(
				(chassisDims.Y * chassisDims.Y + chassisDims.Z * chassisDims.Z) * chassisMass / 12.0f,
				(chassisDims.X * chassisDims.X + chassisDims.Z * chassisDims.Z) * chassisMass / 12.0f,
				(chassisDims.X * chassisDims.X + chassisDims.Y * chassisDims.Y) * chassisMass / 12.0f
			);

			//A bit of tweaking here.  The car will have more responsive turning if we reduce the
			//y-component of the chassis moment of inertia.
			chassisMOI.Y *= 0.8f;

			//Let's set up the chassis data structure now.
			chassisData.Mass = chassisMass;
			chassisData.MomentOfInertia = chassisMOI;
			chassisData.CenterOfMassOffset = chassisCMOffset;

			//Work out the front/rear mass split from the cm offset.
			//This is a very approximate calculation with lots of assumptions.
			//massRear*zRear + massFront*zFront = mass*cm           (1)
			//massRear       + massFront        = mass                      (2)
			//Rearrange (2)
			//massFront = mass - massRear                                           (3)
			//Substitute (3) into (1)
			//massRear(zRear - zFront) + mass*zFront = mass*cm      (4)
			//Solve (4) for massRear
			//massRear = mass(cm - zFront)/(zRear-zFront)           (5)
			//Now we also have
			//zFront = (z-cm)/2                                                                     (6a)
			//zRear = (-z-cm)/2                                                                     (6b)
			//Substituting (6a-b) into (5) gives
			//massRear = 0.5*mass*(z-3cm)/z                                         (7)
			float massRear = 0.5f * chassisMass * (chassisDims.Z - 3 * chassisCMOffset.Z) / chassisDims.Z;
			float massFront = chassisMass - massRear;

			//Extract the wheel radius and width from the wheel convex meshes.
			float[] wheelWidths = new float[4];
			float[] wheelRadii = new float[4];
			//ComputeWheelWidthsAndRadii(wheelConvexMeshes, wheelWidths, wheelRadii);
			wheelWidths = new[] { 3f, 3, 3, 3 };
			wheelRadii = new[] { 1f, 1, 1, 1 };

			//Now compute the wheel masses and inertias components around the axle's axis.
			//http://en.wikipedia.org/wiki/List_of_moments_of_inertia
			float[] wheelMOIs = new float[4];
			for (int i = 0; i < 4; i++)
			{
				wheelMOIs[i] = 0.5f * wheelMass * wheelRadii[i] * wheelRadii[i];
			}
			//Let's set up the wheel data structures now with radius, mass, and moi.
			VehicleWheelData[] wheels = new VehicleWheelData[4]
			{
				new VehicleWheelData(),
				new VehicleWheelData(),
				new VehicleWheelData(),
				new VehicleWheelData()
			};
			for (int i = 0; i < 4; i++)
			{
				wheels[i].Radius = wheelRadii[i];
				wheels[i].Mass = wheelMass;
				wheels[i].MomentOfInertia = wheelMOIs[i];
				wheels[i].Width = wheelWidths[i];
			}
			//Disable the handbrake from the front wheels and enable for the rear wheels
			wheels[(int)VehicleWheelOrdering.FrontLeft].MaxHandBrakeTorque = 0.0f;
			wheels[(int)VehicleWheelOrdering.FrontRight].MaxHandBrakeTorque = 0.0f;
			wheels[(int)VehicleWheelOrdering.RearLeft].MaxHandBrakeTorque = 4000.0f;
			wheels[(int)VehicleWheelOrdering.RearRight].MaxHandBrakeTorque = 4000.0f;
			//Enable steering for the front wheels and disable for the front wheels.
			wheels[(int)VehicleWheelOrdering.FrontLeft].MaxSteer = (float)System.Math.PI * 0.3333f;
			wheels[(int)VehicleWheelOrdering.FrontRight].MaxSteer = (float)System.Math.PI * 0.3333f;
			wheels[(int)VehicleWheelOrdering.RearLeft].MaxSteer = 0.0f;
			wheels[(int)VehicleWheelOrdering.RearRight].MaxSteer = 0.0f;

			//Let's set up the tire data structures now.
			//Put slicks on the front tires and wets on the rear tires.
			VehicleTireData[] tires = new VehicleTireData[4]
			{
				new VehicleTireData(),
				new VehicleTireData(),
				new VehicleTireData(),
				new VehicleTireData()
			};
			tires[(int)VehicleWheelOrdering.FrontLeft].Type = TIRE_TYPE_SLICKS;
			tires[(int)VehicleWheelOrdering.FrontRight].Type = TIRE_TYPE_SLICKS;
			tires[(int)VehicleWheelOrdering.RearLeft].Type = TIRE_TYPE_SLICKS;
			tires[(int)VehicleWheelOrdering.RearRight].Type = TIRE_TYPE_SLICKS;

			//Let's set up the suspension data structures now.
			VehicleSuspensionData[] susps = new VehicleSuspensionData[4]
			{
				new VehicleSuspensionData(),
				new VehicleSuspensionData(),
				new VehicleSuspensionData(),
				new VehicleSuspensionData()
			};
			for (int i = 0; i < 4; i++)
			{
				susps[i].MaxCompression = 0.3f;
				susps[i].MaxDroop = 0.1f;
				susps[i].SpringStrength = 35000.0f;
				susps[i].SpringDamperRate = 4500.0f;
			}
			susps[(int)VehicleWheelOrdering.FrontLeft].SprungMass = massFront * 0.5f;
			susps[(int)VehicleWheelOrdering.FrontRight].SprungMass = massFront * 0.5f;
			susps[(int)VehicleWheelOrdering.RearLeft].SprungMass = massRear * 0.5f;
			susps[(int)VehicleWheelOrdering.RearRight].SprungMass = massRear * 0.5f;

			//We need to set up geometry data for the suspension, wheels, and tires.
			//We already know the wheel centers described as offsets from the rigid body centre of mass.
			//From here we can approximate application points for the tire and suspension forces.
			//Lets assume that the suspension travel directions are absolutely vertical.
			//Also assume that we apply the tire and suspension forces 30cm below the centre of mass.
			Vector3[] suspTravelDirections = new Vector3[] { new Vector3(0, -1, 0), new Vector3(0, -1, 0), new Vector3(0, -1, 0), new Vector3(0, -1, 0) };
			Vector3[] wheelCentreCMOffsets = new Vector3[4];
			Vector3[] suspForceAppCMOffsets = new Vector3[4];
			Vector3[] tireForceAppCMOffsets = new Vector3[4];
			for (int i = 0; i < 4; i++)
			{
				wheelCentreCMOffsets[i] = wheelCentreOffsets[i] - chassisCMOffset;
				suspForceAppCMOffsets[i] = new Vector3(wheelCentreCMOffsets[i].X, -0.3f, wheelCentreCMOffsets[i].Z);
				tireForceAppCMOffsets[i] = new Vector3(wheelCentreCMOffsets[i].X, -0.3f, wheelCentreCMOffsets[i].Z);
			}

			//Now add the wheel, tire and suspension data.
			for (int i = 0; i < 4; i++)
			{
				wheelsData.SetWheelData(i, wheels[i]);
				wheelsData.SetTireData(i, tires[i]);
				wheelsData.SetSuspensionData(i, susps[i]);
				wheelsData.SetSuspensionTravelDirection(i, suspTravelDirections[i]);
				wheelsData.SetWheelCentreOffset(i, wheelCentreCMOffsets[i]);
				wheelsData.SetSuspensionForceApplicationPointOffset(i, suspForceAppCMOffsets[i]);
				wheelsData.SetTireForceApplicationPointOffset(i, tireForceAppCMOffsets[i]);
			}

			//Now set up the differential, engine, gears, clutch, and ackermann steering.

			//Diff
			VehicleDifferential4WData diff = new VehicleDifferential4WData();
			diff.Type = VehicleDifferentialType.LimitedSlip4WheelDrive;
			driveData.SetDifferentialData(diff);

			//Engine
			VehicleEngineData engine = new VehicleEngineData()
			{
				PeakTorque = 500.0f,
				MaxOmega = 600.0f//approx 6000 rpm
			};
			driveData.SetEngineData(engine);

			//Gears
			VehicleGearsData gears = new VehicleGearsData()
			{
				SwitchTime = 0.5f
			};
			driveData.SetGearsData(gears);

			//Clutch
			VehicleClutchData clutch = new VehicleClutchData()
			{
				Strength = 10.0f
			};
			driveData.SetClutchData(clutch);

			//Ackermann steer accuracy
			var ackermann = new VehicleAckermannGeometryData()
			{
				Accuracy = 1.0f,
				AxleSeparation = wheelCentreOffsets[(int)VehicleWheelOrdering.FrontLeft].Z - wheelCentreOffsets[(int)VehicleWheelOrdering.RearLeft].Z,
				FrontWidth = wheelCentreOffsets[(int)VehicleWheelOrdering.FrontRight].X - wheelCentreOffsets[(int)VehicleWheelOrdering.FrontLeft].X,
				RearWidth = wheelCentreOffsets[(int)VehicleWheelOrdering.RearRight].X - wheelCentreOffsets[(int)VehicleWheelOrdering.RearLeft].X
			};
			driveData.SetAckermannGeometryData(ackermann);
		}
Beispiel #4
0
        private void CreateVehicle4WSimulationData(
            float chassisMass,
            ConvexMesh chassisConvexMesh,
            float wheelMass,
            ConvexMesh[] wheelConvexMeshes,
            Vector3[] wheelCentreOffsets,
            VehicleWheelsSimData wheelsData,
            VehicleDriveSimData4W driveData,
            VehicleChassisData chassisData)
        {
            const int TIRE_TYPE_SLICKS = 0;

            //Extract the chassis AABB dimensions from the chassis convex mesh.
            //Vector3 chassisDims = computeChassisAABBDimensions(chassisConvexMesh);
            Vector3 chassisDims = new Vector3(10, 10, 10);

            //The origin is at the center of the chassis mesh.
            //Set the center of mass to be below this point and a little towards the front.
            Vector3 chassisCMOffset = new Vector3(0.0f, -chassisDims.Y * 0.5f + 0.65f, 0.25f);

            //Now compute the chassis mass and moment of inertia.
            //Use the moment of inertia of a cuboid as an approximate value for the chassis moi.
            Vector3 chassisMOI = new Vector3
                                 (
                (chassisDims.Y * chassisDims.Y + chassisDims.Z * chassisDims.Z) * chassisMass / 12.0f,
                (chassisDims.X * chassisDims.X + chassisDims.Z * chassisDims.Z) * chassisMass / 12.0f,
                (chassisDims.X * chassisDims.X + chassisDims.Y * chassisDims.Y) * chassisMass / 12.0f
                                 );

            //A bit of tweaking here.  The car will have more responsive turning if we reduce the
            //y-component of the chassis moment of inertia.
            chassisMOI.Y *= 0.8f;

            //Let's set up the chassis data structure now.
            chassisData.Mass               = chassisMass;
            chassisData.MomentOfInertia    = chassisMOI;
            chassisData.CenterOfMassOffset = chassisCMOffset;

            //Work out the front/rear mass split from the cm offset.
            //This is a very approximate calculation with lots of assumptions.
            //massRear*zRear + massFront*zFront = mass*cm           (1)
            //massRear       + massFront        = mass                      (2)
            //Rearrange (2)
            //massFront = mass - massRear                                           (3)
            //Substitute (3) into (1)
            //massRear(zRear - zFront) + mass*zFront = mass*cm      (4)
            //Solve (4) for massRear
            //massRear = mass(cm - zFront)/(zRear-zFront)           (5)
            //Now we also have
            //zFront = (z-cm)/2                                                                     (6a)
            //zRear = (-z-cm)/2                                                                     (6b)
            //Substituting (6a-b) into (5) gives
            //massRear = 0.5*mass*(z-3cm)/z                                         (7)
            float massRear  = 0.5f * chassisMass * (chassisDims.Z - 3 * chassisCMOffset.Z) / chassisDims.Z;
            float massFront = chassisMass - massRear;

            //Extract the wheel radius and width from the wheel convex meshes.
            float[] wheelWidths = new float[4];
            float[] wheelRadii  = new float[4];
            //ComputeWheelWidthsAndRadii(wheelConvexMeshes, wheelWidths, wheelRadii);
            wheelWidths = new[] { 3f, 3, 3, 3 };
            wheelRadii  = new[] { 1f, 1, 1, 1 };

            //Now compute the wheel masses and inertias components around the axle's axis.
            //http://en.wikipedia.org/wiki/List_of_moments_of_inertia
            float[] wheelMOIs = new float[4];
            for (int i = 0; i < 4; i++)
            {
                wheelMOIs[i] = 0.5f * wheelMass * wheelRadii[i] * wheelRadii[i];
            }
            //Let's set up the wheel data structures now with radius, mass, and moi.
            VehicleWheelData[] wheels = new VehicleWheelData[4]
            {
                new VehicleWheelData(),
                new VehicleWheelData(),
                new VehicleWheelData(),
                new VehicleWheelData()
            };
            for (int i = 0; i < 4; i++)
            {
                wheels[i].Radius          = wheelRadii[i];
                wheels[i].Mass            = wheelMass;
                wheels[i].MomentOfInertia = wheelMOIs[i];
                wheels[i].Width           = wheelWidths[i];
            }
            //Disable the handbrake from the front wheels and enable for the rear wheels
            wheels[(int)VehicleWheelOrdering.FrontLeftWheel].MaxHandBrakeTorque  = 0.0f;
            wheels[(int)VehicleWheelOrdering.FrontRightWheel].MaxHandBrakeTorque = 0.0f;
            wheels[(int)VehicleWheelOrdering.RearLeftWheel].MaxHandBrakeTorque   = 4000.0f;
            wheels[(int)VehicleWheelOrdering.RearRightWheel].MaxHandBrakeTorque  = 4000.0f;
            //Enable steering for the front wheels and disable for the front wheels.
            wheels[(int)VehicleWheelOrdering.FrontLeftWheel].MaxSteer  = (float)System.Math.PI * 0.3333f;
            wheels[(int)VehicleWheelOrdering.FrontRightWheel].MaxSteer = (float)System.Math.PI * 0.3333f;
            wheels[(int)VehicleWheelOrdering.RearLeftWheel].MaxSteer   = 0.0f;
            wheels[(int)VehicleWheelOrdering.RearRightWheel].MaxSteer  = 0.0f;

            //Let's set up the tire data structures now.
            //Put slicks on the front tires and wets on the rear tires.
            VehicleTireData[] tires = new VehicleTireData[4]
            {
                new VehicleTireData(),
                new VehicleTireData(),
                new VehicleTireData(),
                new VehicleTireData()
            };
            tires[(int)VehicleWheelOrdering.FrontLeftWheel].Type  = TIRE_TYPE_SLICKS;
            tires[(int)VehicleWheelOrdering.FrontRightWheel].Type = TIRE_TYPE_SLICKS;
            tires[(int)VehicleWheelOrdering.RearLeftWheel].Type   = TIRE_TYPE_SLICKS;
            tires[(int)VehicleWheelOrdering.RearRightWheel].Type  = TIRE_TYPE_SLICKS;

            //Let's set up the suspension data structures now.
            VehicleSuspensionData[] susps = new VehicleSuspensionData[4]
            {
                new VehicleSuspensionData(),
                new VehicleSuspensionData(),
                new VehicleSuspensionData(),
                new VehicleSuspensionData()
            };
            for (int i = 0; i < 4; i++)
            {
                susps[i].MaxCompression   = 0.3f;
                susps[i].MaxDroop         = 0.1f;
                susps[i].SpringStrength   = 35000.0f;
                susps[i].SpringDamperRate = 4500.0f;
            }
            susps[(int)VehicleWheelOrdering.FrontLeftWheel].SprungMass  = massFront * 0.5f;
            susps[(int)VehicleWheelOrdering.FrontRightWheel].SprungMass = massFront * 0.5f;
            susps[(int)VehicleWheelOrdering.RearLeftWheel].SprungMass   = massRear * 0.5f;
            susps[(int)VehicleWheelOrdering.RearRightWheel].SprungMass  = massRear * 0.5f;

            //We need to set up geometry data for the suspension, wheels, and tires.
            //We already know the wheel centers described as offsets from the rigid body centre of mass.
            //From here we can approximate application points for the tire and suspension forces.
            //Lets assume that the suspension travel directions are absolutely vertical.
            //Also assume that we apply the tire and suspension forces 30cm below the centre of mass.
            Vector3[] suspTravelDirections  = new Vector3[] { new Vector3(0, -1, 0), new Vector3(0, -1, 0), new Vector3(0, -1, 0), new Vector3(0, -1, 0) };
            Vector3[] wheelCentreCMOffsets  = new Vector3[4];
            Vector3[] suspForceAppCMOffsets = new Vector3[4];
            Vector3[] tireForceAppCMOffsets = new Vector3[4];
            for (int i = 0; i < 4; i++)
            {
                wheelCentreCMOffsets[i]  = wheelCentreOffsets[i] - chassisCMOffset;
                suspForceAppCMOffsets[i] = new Vector3(wheelCentreCMOffsets[i].X, -0.3f, wheelCentreCMOffsets[i].Z);
                tireForceAppCMOffsets[i] = new Vector3(wheelCentreCMOffsets[i].X, -0.3f, wheelCentreCMOffsets[i].Z);
            }

            //Now add the wheel, tire and suspension data.
            for (int i = 0; i < 4; i++)
            {
                wheelsData.SetWheelData(i, wheels[i]);
                wheelsData.SetTireData(i, tires[i]);
                wheelsData.SetSuspensionData(i, susps[i]);
                wheelsData.SetSuspensionTravelDirection(i, suspTravelDirections[i]);
                wheelsData.SetWheelCentreOffset(i, wheelCentreCMOffsets[i]);
                wheelsData.SetSuspensionForceApplicationPointOffset(i, suspForceAppCMOffsets[i]);
                wheelsData.SetTireForceApplicationPointOffset(i, tireForceAppCMOffsets[i]);
            }

            //Now set up the differential, engine, gears, clutch, and ackermann steering.

            //Diff
            VehicleDifferential4WData diff = new VehicleDifferential4WData();

            diff.Type = VehicleDifferentialType.LimitedSlip4WheelDrive;
            driveData.SetDifferentialData(diff);

            //Engine
            VehicleEngineData engine = new VehicleEngineData()
            {
                PeakTorque = 500.0f,
                MaxOmega   = 600.0f              //approx 6000 rpm
            };

            driveData.SetEngineData(engine);

            //Gears
            VehicleGearsData gears = new VehicleGearsData()
            {
                SwitchTime = 0.5f
            };

            driveData.SetGearsData(gears);

            //Clutch
            VehicleClutchData clutch = new VehicleClutchData()
            {
                Strength = 10.0f
            };

            driveData.SetClutchData(clutch);

            //Ackermann steer accuracy
            VehicleAckermannGeometryData ackermann = new VehicleAckermannGeometryData()
            {
                Accuracy       = 1.0f,
                AxleSeparation = wheelCentreOffsets[(int)VehicleWheelOrdering.FrontLeftWheel].Z - wheelCentreOffsets[(int)VehicleWheelOrdering.RearLeftWheel].Z,
                FrontWidth     = wheelCentreOffsets[(int)VehicleWheelOrdering.FrontRightWheel].X - wheelCentreOffsets[(int)VehicleWheelOrdering.FrontLeftWheel].X,
                RearWidth      = wheelCentreOffsets[(int)VehicleWheelOrdering.RearRightWheel].X - wheelCentreOffsets[(int)VehicleWheelOrdering.RearLeftWheel].X
            };

            driveData.SetAckermannGeometryData(ackermann);
        }