992 lines
45 KiB
C++
992 lines
45 KiB
C++
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions
|
|
// are met:
|
|
// * Redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
// * Redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution.
|
|
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
|
// contributors may be used to endorse or promote products derived
|
|
// from this software without specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
|
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
//
|
|
// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved.
|
|
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
|
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
|
|
|
#pragma once
|
|
|
|
/** \addtogroup vehicle2
|
|
@{
|
|
*/
|
|
|
|
#include "foundation/PxFoundation.h"
|
|
#include "common/PxCoreUtilityTypes.h"
|
|
|
|
#include "vehicle2/PxVehicleParams.h"
|
|
|
|
#include "vehicle2/commands/PxVehicleCommandParams.h"
|
|
|
|
#if !PX_DOXYGEN
|
|
namespace physx
|
|
{
|
|
namespace vehicle2
|
|
{
|
|
#endif
|
|
|
|
/**
|
|
\brief Distribute a throttle response to the wheels of a direct drive vehicle.
|
|
\note The drive torque applied to each wheel on the ith axle is throttleCommand * maxResponse * wheelResponseMultipliers[i].
|
|
\note A typical use case is to set maxResponse to be the vehicle's maximum achievable drive torque
|
|
that occurs when the steer command is equal to 1.0. The array wheelResponseMultipliers[i] would then be used
|
|
to specify the maximum achievable drive torque per wheel as a fractional multiplier of the vehicle's maximum achievable steer angle.
|
|
*/
|
|
struct PxVehicleDirectDriveThrottleCommandResponseParams : public PxVehicleCommandResponseParams
|
|
{
|
|
PX_FORCE_INLINE PxVehicleDirectDriveThrottleCommandResponseParams transformAndScale(
|
|
const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const
|
|
{
|
|
PX_UNUSED(srcFrame);
|
|
PX_UNUSED(trgFrame);
|
|
PxVehicleDirectDriveThrottleCommandResponseParams r = *this;
|
|
const PxReal scale = trgScale.scale/srcScale.scale;
|
|
r.maxResponse *= (scale*scale); //Max response is a torque!
|
|
return r;
|
|
}
|
|
|
|
PX_FORCE_INLINE bool isValid(const PxVehicleAxleDescription& axleDesc) const
|
|
{
|
|
PX_CHECK_AND_RETURN_VAL(PxIsFinite(maxResponse), "PxVehicleDirectDriveThrottleCommandResponseParams.maxResponse must be a finite value", false);
|
|
for (PxU32 i = 0; i < axleDesc.nbWheels; i++)
|
|
{
|
|
PX_CHECK_AND_RETURN_VAL(PxIsFinite(wheelResponseMultipliers[axleDesc.wheelIdsInAxleOrder[i]]), "PxVehicleDirectDriveThrottleCommandResponseParams.wheelResponseMultipliers[i] must be a finite value", false);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
/**
|
|
\brief Specifies the maximum clutch strength that occurs when the clutch pedal is fully disengaged and the clutch is fully engaged.
|
|
*/
|
|
struct PxVehicleClutchCommandResponseParams
|
|
{
|
|
/**
|
|
\brief Strength of clutch.
|
|
|
|
\note The clutch is the mechanism that couples the engine to the wheels.
|
|
A stronger clutch more strongly couples the engine to the wheels, while a
|
|
clutch of strength zero completely decouples the engine from the wheels.
|
|
Stronger clutches more quickly bring the wheels and engine into equilibrium, while weaker
|
|
clutches take longer, resulting in periods of clutch slip and delays in power transmission
|
|
from the engine to the wheels.
|
|
The torque generated by the clutch is proportional to the clutch strength and
|
|
the velocity difference between the engine's rotational speed and the rotational speed of the
|
|
driven wheels after accounting for the gear ratio.
|
|
The torque at the clutch is applied negatively to the engine and positively to the driven wheels.
|
|
|
|
<b>Range:</b> [0,inf)<br>
|
|
<b>Unit:</b> torque * time = mass * (length^2) / time
|
|
*/
|
|
PxReal maxResponse;
|
|
|
|
PX_FORCE_INLINE PxVehicleClutchCommandResponseParams transformAndScale(
|
|
const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const
|
|
{
|
|
PX_UNUSED(srcFrame);
|
|
PX_UNUSED(trgFrame);
|
|
const PxReal scale = trgScale.scale/srcScale.scale;
|
|
PxVehicleClutchCommandResponseParams r = *this;
|
|
r.maxResponse *= (scale*scale);
|
|
return r;
|
|
}
|
|
|
|
PX_FORCE_INLINE bool isValid() const
|
|
{
|
|
PX_CHECK_AND_RETURN_VAL(maxResponse >= 0.0f, "PxVehicleClutchCommandResponseParams.maxResponse must be greater than or equal to zero", false);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
/**
|
|
\brief Choose between a potentially more expensive but more accurate solution to the clutch model or a potentially cheaper but less accurate solution.
|
|
@see PxVehicleClutchParams
|
|
*/
|
|
struct PxVehicleClutchAccuracyMode
|
|
{
|
|
enum Enum
|
|
{
|
|
eESTIMATE = 0,
|
|
eBEST_POSSIBLE
|
|
};
|
|
};
|
|
|
|
/**
|
|
\brief The clutch connects two plates together. One plate rotates with the speed of the engine. The second plate rotates with a weighted average of all
|
|
wheels connected to the differential after accounting for the gear ratio. The difference in rotation speeds generates a restoring torque applied to engine and wheels
|
|
that aims to reduce the difference in rotational speed. The restoring torque is proportional to the clutch strength and the clutch pedal position.
|
|
*/
|
|
struct PxVehicleClutchParams
|
|
{
|
|
public:
|
|
|
|
/**
|
|
\brief The engine and wheel rotation speeds that are coupled through the clutch can be updated by choosing
|
|
one of two modes: eESTIMATE and eBEST_POSSIBLE.
|
|
|
|
\note If eESTIMATE is chosen the vehicle sdk will update the wheel and engine rotation speeds
|
|
with estimated values to the implemented clutch model.
|
|
|
|
\note If eBEST_POSSIBLE is chosen the vehicle sdk will compute the best possible
|
|
solution (within floating point tolerance) to the implemented clutch model.
|
|
This is the recommended mode.
|
|
|
|
\note The clutch model remains the same if either eESTIMATE or eBEST_POSSIBLE is chosen but the accuracy and
|
|
computational cost of the solution to the model can be tuned as required.
|
|
*/
|
|
PxVehicleClutchAccuracyMode::Enum accuracyMode;
|
|
|
|
/**
|
|
\brief Tune the mathematical accuracy and computational cost of the computed estimate to the wheel and
|
|
engine rotation speeds if eESTIMATE is chosen.
|
|
|
|
\note As estimateIterations increases the computational cost of the clutch also increases and the solution
|
|
approaches the solution that would be computed if eBEST_POSSIBLE was chosen instead.
|
|
|
|
\note This has no effect if eBEST_POSSIBLE is chosen as the accuracy mode.
|
|
|
|
\note A value of zero is not allowed if eESTIMATE is chosen as the accuracy mode.
|
|
*/
|
|
PxU32 estimateIterations;
|
|
|
|
PX_FORCE_INLINE PxVehicleClutchParams transformAndScale(
|
|
const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const
|
|
{
|
|
PX_UNUSED(srcFrame);
|
|
PX_UNUSED(trgFrame);
|
|
PX_UNUSED(srcScale);
|
|
PX_UNUSED(trgScale);
|
|
return *this;
|
|
}
|
|
|
|
PX_FORCE_INLINE bool isValid() const
|
|
{
|
|
PX_CHECK_AND_RETURN_VAL((PxVehicleClutchAccuracyMode::eBEST_POSSIBLE == accuracyMode) || ((PxVehicleClutchAccuracyMode::eESTIMATE == accuracyMode) && (estimateIterations > 0)), "PxVehicleClutchParams.estimateIterations must be greater than zero if PxVehicleClutchAccuracyMode::eESTIMATE is selected", false);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
struct PxVehicleEngineParams
|
|
{
|
|
/**
|
|
\brief Maximum supported number of points in the #torqueCurve graph.
|
|
*/
|
|
enum
|
|
{
|
|
eMAX_NB_ENGINE_TORQUE_CURVE_ENTRIES = 8
|
|
};
|
|
|
|
/**
|
|
\brief Graph of normalized torque (torque/#peakTorque) against normalized engine speed ( engineRotationSpeed / #maxOmega ).
|
|
|
|
\note The normalized engine speed is the x-axis of the graph, while the normalized torque is the y-axis of the graph.
|
|
*/
|
|
PxVehicleFixedSizeLookupTable<PxReal, eMAX_NB_ENGINE_TORQUE_CURVE_ENTRIES> torqueCurve;
|
|
|
|
/**
|
|
\brief Moment of inertia of the engine around the axis of rotation.
|
|
|
|
<b>Range:</b> (0, inf)<br>
|
|
<b>Unit:</b> mass * (length^2)
|
|
*/
|
|
PxReal moi;
|
|
|
|
/**
|
|
\brief Maximum torque available to apply to the engine when the accelerator pedal is at maximum.
|
|
|
|
\note The torque available is the value of the accelerator pedal (in range [0, 1]) multiplied by the normalized torque as computed from #torqueCurve multiplied by #peakTorque.
|
|
|
|
<b>Range:</b> [0, inf)<br>
|
|
<b>Unit:</b> mass * (length^2) / (time^2)
|
|
*/
|
|
PxReal peakTorque;
|
|
|
|
/**
|
|
\brief Minimum rotation speed of the engine.
|
|
|
|
<b>Range:</b> [0, inf)<br>
|
|
<b>Unit:</b> radians / time
|
|
*/
|
|
PxReal idleOmega;
|
|
|
|
/**
|
|
\brief Maximum rotation speed of the engine.
|
|
|
|
<b>Range:</b> [0, inf)<br>
|
|
<b>Unit:</b> radians / time
|
|
*/
|
|
PxReal maxOmega;
|
|
|
|
/**
|
|
\brief Damping rate of engine when full throttle is applied.
|
|
|
|
\note If the clutch is engaged (any gear except neutral) then the damping rate applied at run-time is an interpolation
|
|
between #dampingRateZeroThrottleClutchEngaged and #dampingRateFullThrottle:
|
|
#dampingRateZeroThrottleClutchEngaged + (#dampingRateFullThrottle-#dampingRateZeroThrottleClutchEngaged)*acceleratorPedal;
|
|
|
|
\note If the clutch is disengaged (in neutral gear) the damping rate applied at run-time is an interpolation
|
|
between #dampingRateZeroThrottleClutchDisengaged and #dampingRateFullThrottle:
|
|
#dampingRateZeroThrottleClutchDisengaged + (#dampingRateFullThrottle-#dampingRateZeroThrottleClutchDisengaged)*acceleratorPedal;
|
|
|
|
<b>Range:</b> [0, inf)<br>
|
|
<b>Unit:</b> torque * time = mass * (length^2) / time
|
|
*/
|
|
PxReal dampingRateFullThrottle;
|
|
|
|
/**
|
|
\brief Damping rate of engine when no throttle is applied and with engaged clutch.
|
|
|
|
\note If the clutch is engaged (any gear except neutral) then the damping rate applied at run-time is an interpolation
|
|
between #dampingRateZeroThrottleClutchEngaged and #dampingRateFullThrottle:
|
|
#dampingRateZeroThrottleClutchEngaged + (#dampingRateFullThrottle-#dampingRateZeroThrottleClutchEngaged)*acceleratorPedal;
|
|
|
|
\note If the clutch is disengaged (in neutral gear) the damping rate applied at run-time is an interpolation
|
|
between #dampingRateZeroThrottleClutchDisengaged and #dampingRateFullThrottle:
|
|
#dampingRateZeroThrottleClutchDisengaged + (#dampingRateFullThrottle-#dampingRateZeroThrottleClutchDisengaged)*acceleratorPedal;
|
|
|
|
<b>Range:</b> [0, inf)<br>
|
|
<b>Unit:</b> torque * time = mass * (length^2) / time
|
|
*/
|
|
PxReal dampingRateZeroThrottleClutchEngaged;
|
|
|
|
/**
|
|
\brief Damping rate of engine when no throttle is applied and with disengaged clutch.
|
|
|
|
\note If the clutch is engaged (any gear except neutral) then the damping rate applied at run-time is an interpolation
|
|
between #dampingRateZeroThrottleClutchEngaged and #dampingRateFullThrottle:
|
|
#dampingRateZeroThrottleClutchEngaged + (#dampingRateFullThrottle-#dampingRateZeroThrottleClutchEngaged)*acceleratorPedal;
|
|
|
|
\note If the clutch is disengaged (in neutral gear) the damping rate applied at run-time is an interpolation
|
|
between #dampingRateZeroThrottleClutchDisengaged and #dampingRateFullThrottle:
|
|
#dampingRateZeroThrottleClutchDisengaged + (#dampingRateFullThrottle-#dampingRateZeroThrottleClutchDisengaged)*acceleratorPedal;
|
|
|
|
<b>Range:</b> [0, inf)<br>
|
|
<b>Unit:</b> torque * time = mass * (length^2) / time
|
|
*/
|
|
PxReal dampingRateZeroThrottleClutchDisengaged;
|
|
|
|
PX_FORCE_INLINE PxVehicleEngineParams transformAndScale(
|
|
const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const
|
|
{
|
|
PX_UNUSED(srcFrame);
|
|
PX_UNUSED(trgFrame);
|
|
PxVehicleEngineParams r = *this;
|
|
const PxReal scale = trgScale.scale/srcScale.scale;
|
|
r.moi *= (scale*scale);
|
|
r.peakTorque *= (scale*scale);
|
|
r.dampingRateFullThrottle *= (scale*scale);
|
|
r.dampingRateZeroThrottleClutchDisengaged *= (scale*scale);
|
|
r.dampingRateZeroThrottleClutchEngaged *= (scale*scale);
|
|
return r;
|
|
}
|
|
|
|
PX_FORCE_INLINE bool isValid() const
|
|
{
|
|
PX_CHECK_AND_RETURN_VAL(moi > 0.0f, "PxVehicleEngineParams.moi must be greater than zero", false);
|
|
PX_CHECK_AND_RETURN_VAL(peakTorque >= 0.0f, "PxVehicleEngineParams.peakTorque must be greater than or equal to zero", false);
|
|
PX_CHECK_AND_RETURN_VAL(torqueCurve.isValid(), "PxVehicleEngineParams.torqueCurve is invalid", false);
|
|
PX_CHECK_AND_RETURN_VAL(maxOmega >= 0.0f, "PxVehicleEngineParams.maxOmega must be greater than or equal to zero", false);
|
|
PX_CHECK_AND_RETURN_VAL(idleOmega >= 0.0f, "PxVehicleEngineParams.idleOmega must be greater or equal to zero", false);
|
|
PX_CHECK_AND_RETURN_VAL(dampingRateFullThrottle >= 0.0f, "PxVehicleEngineParams.dampingRateFullThrottle must be greater than or equal to zero", false);
|
|
PX_CHECK_AND_RETURN_VAL(dampingRateZeroThrottleClutchEngaged >= 0.0f, "PxVehicleEngineParams.dampingRateZeroThrottleClutchEngaged must be greater than or equal to zero", false);
|
|
PX_CHECK_AND_RETURN_VAL(dampingRateZeroThrottleClutchDisengaged >= 0.0f, "PxVehicleEngineParams.dampingRateZeroThrottleClutchDisengaged must be greater than or equal to zero", false)
|
|
return true;
|
|
}
|
|
};
|
|
|
|
struct PxVehicleGearboxParams
|
|
{
|
|
public:
|
|
|
|
/**
|
|
\brief The gear that denotes neutral gear
|
|
*/
|
|
PxU32 neutralGear;
|
|
|
|
/**
|
|
\brief Maximum supported number of gears, including reverse and neutral.
|
|
*/
|
|
enum Enum
|
|
{
|
|
eMAX_NB_GEARS = 32
|
|
};
|
|
|
|
/**
|
|
\brief Gear ratios
|
|
|
|
The ratio for reverse gears must be negative, the ratio for the neutral gear
|
|
has to be 0 and the ratio for forward gears must be positive.
|
|
*/
|
|
PxReal ratios[eMAX_NB_GEARS];
|
|
|
|
/**
|
|
\brief Gear ratio applied is #ratios[currentGear]*#finalRatio
|
|
|
|
<b>Range:</b> (0, inf)<br>
|
|
*/
|
|
PxReal finalRatio;
|
|
|
|
/**
|
|
\brief Number of gears (including reverse and neutral).
|
|
|
|
<b>Range:</b> [1, eMAX_NB_GEARS]<br>
|
|
*/
|
|
PxU32 nbRatios;
|
|
|
|
/**
|
|
\brief Time it takes to switch gear.
|
|
|
|
<b>Range:</b> [0, inf)<br>
|
|
<b>Unit:</b> time
|
|
*/
|
|
PxReal switchTime;
|
|
|
|
PX_FORCE_INLINE PxVehicleGearboxParams transformAndScale(
|
|
const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const
|
|
{
|
|
PX_UNUSED(srcFrame);
|
|
PX_UNUSED(trgFrame);
|
|
PX_UNUSED(srcScale);
|
|
PX_UNUSED(trgScale);
|
|
return *this;
|
|
}
|
|
|
|
PX_FORCE_INLINE bool isValid() const
|
|
{
|
|
PX_CHECK_AND_RETURN_VAL(finalRatio > 0, "PxVehicleGearboxParams.finalRatio must be greater than zero", false);
|
|
PX_CHECK_AND_RETURN_VAL(nbRatios >= 1, "PxVehicleGearboxParams.nbRatios must be greater than zero", false);
|
|
PX_CHECK_AND_RETURN_VAL(nbRatios <= eMAX_NB_GEARS, "PxVehicleGearboxParams.nbRatios must be less than or equal to eMAX_NB_GEARS", false);
|
|
PX_CHECK_AND_RETURN_VAL(neutralGear < nbRatios, "PxVehicleGearboxParams.neutralGear must be less than PxVehicleGearboxParams.nbRatios", false);
|
|
PX_CHECK_AND_RETURN_VAL(switchTime >= 0.0f, "PxVehicleGearboxParams.switchTime must be greater than or equal to zero", false);
|
|
for(PxU32 i = 0; i < neutralGear; i++)
|
|
{
|
|
PX_CHECK_AND_RETURN_VAL(ratios[i] < 0.0f, "Reverse gear ratios must be less than zero", false);
|
|
}
|
|
{
|
|
PX_CHECK_AND_RETURN_VAL(ratios[neutralGear] == 0.0f, "Neutral gear ratio must be equal to zero", false);
|
|
}
|
|
for (PxU32 i = neutralGear + 1; i < nbRatios; i++)
|
|
{
|
|
PX_CHECK_AND_RETURN_VAL(ratios[i] > 0.0f, "Forward gear ratios must be greater than zero", false);
|
|
}
|
|
for (PxU32 i = neutralGear + 2; i < nbRatios; i++)
|
|
{
|
|
PX_CHECK_AND_RETURN_VAL(ratios[i] < ratios[i - 1], "Forward gear ratios must be a descending sequence of gear ratios", false);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
struct PxVehicleAutoboxParams
|
|
{
|
|
public:
|
|
|
|
/**
|
|
\brief Value of ( engineRotationSpeed /maxEngineRevs ) that is high enough to increment gear.
|
|
|
|
\note When ( engineRotationSpeed / #PxVehicleEngineParams::maxOmega ) > upRatios[currentGear] the autobox will begin
|
|
a transition to currentGear+1 unless currentGear is the highest possible gear or neutral or reverse.
|
|
|
|
<b>Range:</b> [0, 1]<br>
|
|
*/
|
|
PxReal upRatios[PxVehicleGearboxParams::eMAX_NB_GEARS];
|
|
|
|
/**
|
|
\brief Value of engineRevs/maxEngineRevs that is low enough to decrement gear.
|
|
|
|
\note When ( engineRotationSpeed / #PxVehicleEngineParams::maxOmega) < downRatios[currentGear] the autobox will begin
|
|
a transition to currentGear-1 unless currentGear is first gear or neutral or reverse.
|
|
|
|
<b>Range:</b> [0, 1]<br>
|
|
*/
|
|
PxReal downRatios[PxVehicleGearboxParams::eMAX_NB_GEARS];
|
|
|
|
/**
|
|
\brief Set the latency time of the autobox.
|
|
|
|
\note Latency time is the minimum time that must pass between each gear change that is initiated by the autobox.
|
|
The auto-box will only attempt to initiate another gear change up or down if the simulation time that has passed since the most recent
|
|
automated gear change is greater than the specified latency.
|
|
|
|
<b>Range:</b> [0, inf)<br>
|
|
<b>Unit:</b> time
|
|
*/
|
|
PxReal latency;
|
|
|
|
PX_FORCE_INLINE PxVehicleAutoboxParams transformAndScale(
|
|
const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const
|
|
{
|
|
PX_UNUSED(srcFrame);
|
|
PX_UNUSED(trgFrame);
|
|
PX_UNUSED(srcScale);
|
|
PX_UNUSED(trgScale);
|
|
return *this;
|
|
}
|
|
|
|
PX_FORCE_INLINE bool isValid(const PxVehicleGearboxParams& gearboxParams) const
|
|
{
|
|
if (!gearboxParams.isValid())
|
|
return false;
|
|
|
|
for (PxU32 i = gearboxParams.neutralGear + 1; i < gearboxParams.nbRatios-1; i++)
|
|
{
|
|
PX_CHECK_AND_RETURN_VAL(upRatios[i] >= 0.0f, "PxVehicleAutoboxParams.upRatios must be greater than or equal to zero", false);
|
|
}
|
|
for (PxU32 i = gearboxParams.neutralGear + 2; i < gearboxParams.nbRatios; i++)
|
|
{
|
|
PX_CHECK_AND_RETURN_VAL(downRatios[i] >= 0.0f, "PxVehicleAutoboxParams.downRatios must be greater than or equal to zero", false);
|
|
}
|
|
PX_CHECK_AND_RETURN_VAL(latency >= 0.0f, "PxVehicleAutoboxParams.latency must be greater than or equal to zero", false);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
/**
|
|
@deprecated
|
|
*/
|
|
struct PX_DEPRECATED PxVehicleFourWheelDriveDifferentialLegacyParams
|
|
{
|
|
public:
|
|
|
|
enum Enum
|
|
{
|
|
eDIFF_TYPE_LS_4WD, //limited slip differential for car with 4 driven wheels
|
|
eDIFF_TYPE_LS_FRONTWD, //limited slip differential for car with front-wheel drive
|
|
eDIFF_TYPE_LS_REARWD, //limited slip differential for car with rear-wheel drive
|
|
eMAX_NB_DIFF_TYPES
|
|
};
|
|
|
|
/**
|
|
\brief The two front wheels are specified by the array frontWheelIds.
|
|
\note The states eDIFF_TYPE_LS_4WD, eDIFF_TYPE_LS_FRONTWD require knowledge of the front wheels
|
|
to allow torque splits between front and rear axles as well as torque splits across the front axle.
|
|
\note frontWheelIds[0] should specify the wheel on the front axle that is negatively placed on the lateral axis.
|
|
\note frontWheelIds[1] should specify the wheel on the front axle that is positively placed on the lateral axis.
|
|
\note If #frontNegPosSplit > 0.5, more torque will be delivered to the wheel specified by frontWheelIds[0] than to the wheel
|
|
specified by frontWheelIds[1]. The converse is true if #frontNegPosSplit < 0.5.
|
|
*/
|
|
PxU32 frontWheelIds[2];
|
|
|
|
|
|
/**
|
|
\brief The two rear wheels are specified by the array rearWheelIds.
|
|
\note The states eDIFF_TYPE_LS_4WD, eDIFF_TYPE_LS_REARWD require knowledge of the rear wheels
|
|
to allow torque splits between front and rear axles as well as torque splits across the rear axle.
|
|
\note rearWheelIds[0] should specify the wheel on the rear axle that is negatively placed on the lateral axis.
|
|
\note rearWheelIds[1] should specify the wheel on the rear axle that is positively placed on the lateral axis.
|
|
\note If #rearNegPosSplit > 0.5, more torque will be delivered to the wheel specified by rearWheelIds[0] than to the wheel
|
|
specified by rearWheelIds[1]. The converse is true if #rearNegPosSplit < 0.5.
|
|
*/
|
|
PxU32 rearWheelIds[2];
|
|
|
|
/**
|
|
\brief Ratio of torque split between front and rear wheels (>0.5 means more front, <0.5 means more to rear).
|
|
|
|
\note Only applied to DIFF_TYPE_LS_4WD
|
|
|
|
<b>Range:</b> [0, 1]<br>
|
|
*/
|
|
PxReal frontRearSplit;
|
|
|
|
/**
|
|
\brief Ratio of torque split between front-negative and front-positive wheels (>0.5 means more to #frontWheelIds[0], <0.5 means more to #frontWheelIds[1]).
|
|
|
|
\note Only applied to DIFF_TYPE_LS_4WD and DIFF_TYPE_LS_FRONTWD
|
|
|
|
<b>Range:</b> [0, 1]<br>
|
|
*/
|
|
PxReal frontNegPosSplit;
|
|
|
|
/**
|
|
\brief Ratio of torque split between rear-negative wheel and rear-positive wheels (>0.5 means more to #rearWheelIds[0], <0.5 means more to #rearWheelIds[1]).
|
|
|
|
\note Only applied to DIFF_TYPE_LS_4WD and eDIFF_TYPE_LS_REARWD
|
|
|
|
<b>Range:</b> [0, 1]<br>
|
|
*/
|
|
PxReal rearNegPosSplit;
|
|
|
|
/**
|
|
\brief Maximum allowed ratio of average front wheel rotation speed and rear wheel rotation speeds.
|
|
The differential will divert more torque to the slower wheels when the bias is exceeded.
|
|
|
|
\note Only applied to DIFF_TYPE_LS_4WD
|
|
|
|
<b>Range:</b> [1, inf)<br>
|
|
*/
|
|
PxReal centerBias;
|
|
|
|
/**
|
|
\brief Maximum allowed ratio of front-left and front-right wheel rotation speeds.
|
|
The differential will divert more torque to the slower wheel when the bias is exceeded.
|
|
|
|
\note Only applied to DIFF_TYPE_LS_4WD and DIFF_TYPE_LS_FRONTWD
|
|
|
|
<b>Range:</b> [1, inf)<br>
|
|
*/
|
|
PxReal frontBias;
|
|
|
|
/**
|
|
\brief Maximum allowed ratio of rear-left and rear-right wheel rotation speeds.
|
|
The differential will divert more torque to the slower wheel when the bias is exceeded.
|
|
|
|
\note Only applied to DIFF_TYPE_LS_4WD and DIFF_TYPE_LS_REARWD
|
|
|
|
<b>Range:</b> [1, inf)<br>
|
|
*/
|
|
PxReal rearBias;
|
|
|
|
/**
|
|
\brief Type of differential.
|
|
|
|
<b>Range:</b> [DIFF_TYPE_LS_4WD, eDIFF_TYPE_LS_REARWD]<br>
|
|
*/
|
|
Enum type;
|
|
|
|
PX_FORCE_INLINE PxVehicleFourWheelDriveDifferentialLegacyParams transformAndScale(
|
|
const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const
|
|
{
|
|
PX_UNUSED(srcFrame);
|
|
PX_UNUSED(trgFrame);
|
|
PX_UNUSED(srcScale);
|
|
PX_UNUSED(trgScale);
|
|
return *this;
|
|
}
|
|
|
|
PX_FORCE_INLINE bool isValid(const PxVehicleAxleDescription& axleDesc) const
|
|
{
|
|
PX_UNUSED(axleDesc);
|
|
PX_CHECK_AND_RETURN_VAL((axleDesc.getAxle(frontWheelIds[0]) != 0xffffffff) && (axleDesc.getAxle(frontWheelIds[0])== axleDesc.getAxle(frontWheelIds[1])), "frontWheelIds[0] and frontWheelIds[1] must reference wheels on the same axle", false);
|
|
PX_CHECK_AND_RETURN_VAL((axleDesc.getAxle(rearWheelIds[0]) != 0xffffffff) && (axleDesc.getAxle(rearWheelIds[0]) == axleDesc.getAxle(rearWheelIds[1])), "rearWheelIds[0] and rearWheelIds[1] must reference wheels on the same axle", false);
|
|
PX_CHECK_AND_RETURN_VAL(frontRearSplit <= 1.0f && frontRearSplit >= 0.0f, "PxVehicleLegacyFourWheelDriveDifferentialParams.frontRearSplit must be in range [0,1]", false);
|
|
PX_CHECK_AND_RETURN_VAL(frontNegPosSplit <= 1.0f && frontNegPosSplit >= 0.0f, "PxVehicleLegacyFourWheelDriveDifferentialParams.frontNegPosSplit must be in range [0,1]", false);
|
|
PX_CHECK_AND_RETURN_VAL(rearNegPosSplit <= 1.0f && rearNegPosSplit >= 0.0f, "PxVehicleLegacyFourWheelDriveDifferentialParams.rearNegPosSplit must be in range [0,1]", false);
|
|
PX_CHECK_AND_RETURN_VAL(centerBias >= 1.0f, "PxVehicleLegacyFourWheelDriveDifferentialParams.centerBias must be greater than or equal to 1.0f", false);
|
|
PX_CHECK_AND_RETURN_VAL(frontBias >= 1.0f, "PxVehicleLegacyFourWheelDriveDifferentialParams.frontBias must be greater than or equal to 1.0f", false);
|
|
PX_CHECK_AND_RETURN_VAL(rearBias >= 1.0f, "PxVehicleLegacyFourWheelDriveDifferentialParams.rearBias must be greater than or equal to 1.0f", false);
|
|
PX_CHECK_AND_RETURN_VAL(type < PxVehicleFourWheelDriveDifferentialLegacyParams::eMAX_NB_DIFF_TYPES, "PxVehicleLegacyFourWheelDriveDifferentialParams.type has illegal value", false);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
/**
|
|
\brief PxVehicleMultiWheelDriveDifferentialParams specifies the wheels that are to receive drive torque from the differential
|
|
and the division of torque between the wheels that are connected to the differential.
|
|
*/
|
|
struct PxVehicleMultiWheelDriveDifferentialParams
|
|
{
|
|
/**
|
|
\brief torqueRatios describes the fraction of torque delivered to each wheel through the differential.
|
|
\note Wheels not connected to the differential must receive zero torque.
|
|
\note Wheels connected to the differential may receive a non-zero torque.
|
|
\note The sum of the absolute of the ratios of all wheels must equal to 1.0.
|
|
\note A negative torque ratio simulates a wheel with negative gearing applied.
|
|
|
|
<b>Range:</b> [1, -1]<br>
|
|
*/
|
|
PxReal torqueRatios[PxVehicleLimits::eMAX_NB_WHEELS];
|
|
|
|
/**
|
|
\brief aveWheelSpeedRatios describes the contribution of each wheel to the average wheel speed measured at the clutch.
|
|
\note Wheels not connected to the differential do not contribute to the average wheel speed measured at the clutch.
|
|
\note Wheels connected to the differential may delivere a non-zero contribution to the average wheel speed measured at the clutch.
|
|
\note The sum of all ratios of all wheels must equal to 1.0.
|
|
|
|
<b>Range:</b> [0, 1]<br>
|
|
*/
|
|
PxReal aveWheelSpeedRatios[PxVehicleLimits::eMAX_NB_WHEELS];
|
|
|
|
|
|
PX_FORCE_INLINE void setToDefault()
|
|
{
|
|
PxMemZero(this, sizeof(PxVehicleMultiWheelDriveDifferentialParams));
|
|
}
|
|
|
|
PX_FORCE_INLINE PxVehicleMultiWheelDriveDifferentialParams transformAndScale(
|
|
const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const
|
|
{
|
|
PX_UNUSED(srcFrame);
|
|
PX_UNUSED(trgFrame);
|
|
PX_UNUSED(srcScale);
|
|
PX_UNUSED(trgScale);
|
|
return *this;
|
|
}
|
|
|
|
PX_FORCE_INLINE bool isValid(const PxVehicleAxleDescription& axleDesc) const
|
|
{
|
|
if (!axleDesc.isValid())
|
|
return false;
|
|
PxReal aveWheelSpeedSum = 0.0f;
|
|
PxReal torqueRatioSum = 0.0f;
|
|
for (PxU32 i = 0; i < axleDesc.nbWheels; i++)
|
|
{
|
|
const PxU32 wheelId = axleDesc.wheelIdsInAxleOrder[i];
|
|
PX_CHECK_AND_RETURN_VAL(PxAbs(torqueRatios[wheelId]) <= 1.0f, "PxVehicleMultiWheelDriveDifferentialParams.torqueRatios[i] must be in range [-1, 1] for all wheels connected to the differential", false);
|
|
PX_CHECK_AND_RETURN_VAL(aveWheelSpeedRatios[wheelId] >= 0.0f && aveWheelSpeedRatios[wheelId] <= 1.0f, "PxVehicleMultiWheelDriveDifferentialParams.aveWheelSpeedRatios[i] must be in range [0, 1] for all wheels connected to the differential", false);
|
|
aveWheelSpeedSum += aveWheelSpeedRatios[wheelId];
|
|
torqueRatioSum += PxAbs(torqueRatios[wheelId]);
|
|
}
|
|
PX_CHECK_AND_RETURN_VAL(aveWheelSpeedSum >= 0.99f && aveWheelSpeedSum <= 1.01f, "Sum of PxVehicleMultiWheelDriveDifferentialParams.aveWheelSpeedRatios[i] must be 1.0.", false);
|
|
PX_CHECK_AND_RETURN_VAL(torqueRatioSum >= 0.99f && torqueRatioSum <= 1.01f, "Sum of PxVehicleMultiWheelDriveDifferentialParams.torqueRatios[i] must be 1.0.", false);
|
|
PX_UNUSED(aveWheelSpeedSum);
|
|
PX_UNUSED(torqueRatioSum);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
/**
|
|
\brief A special value that indicates instantaneous resolution of a slip that exceeds a differential bias.
|
|
*/
|
|
#define PX_VEHICLE_FOUR_WHEEL_DIFFERENTIAL_MAXIMUM_STRENGTH PX_MAX_F32
|
|
|
|
/**
|
|
\brief PxVehicleFourWheelDriveDifferentialParams specifies the wheels that are to receive drive torque from the differential
|
|
and the division of torque between the wheels that are connected to the differential. Additionally, it specifies the biases
|
|
and strength of a limited slip differential that operates on two wheels specified as front wheels and two wheels specified
|
|
as rear wheels.
|
|
*/
|
|
struct PxVehicleFourWheelDriveDifferentialParams : public PxVehicleMultiWheelDriveDifferentialParams
|
|
{
|
|
/**
|
|
\brief The ids of the two wheels considered by the differential to be the front pair.
|
|
\note When the ratio of the rotational speeds of the front wheels exceeds frontBias, drive torque is diverted so
|
|
that the ratio approaches the value specified by frontTarget. When the bias is not breached, the drive torque
|
|
is specified by the corresponding entries in PxVehicleMultiWheelDriveDifferentialParams::torqueRatios.
|
|
*/
|
|
PxU32 frontWheelIds[2];
|
|
|
|
/**
|
|
\brief The ids of the two wheels considered by the differential to be the rear pair.
|
|
\note When the ratio of the rotational speeds of the rear wheels exceeds rearBias, drive torque is diverted so
|
|
that the ratio approaches the value specified by rearTarget. When the bias is not breached, the drive torque
|
|
is specified by the corresponding entries in PxVehicleMultiWheelDriveDifferentialParams::torqueRatios.
|
|
*/
|
|
PxU32 rearWheelIds[2];
|
|
|
|
/**
|
|
\brief The parameter frontBias specifies the maximum angular speed ratio of the two front wheels specified by frontWheelIds[2].
|
|
\note If frontBias has value 0.0, the differential will not try to enforce any relationship between the rotational speeds of the two front wheels.
|
|
\note If frontBias has value 0.0, the torque split between the front wheels is specified by the array torqueRatios.
|
|
\note frontBias must have value 0.0 (deactivated limited slip) or be greater than 1.0 (activated limited slip) or be equal to 1.0 (locked axle).
|
|
\note If frontBias has value greater than or equal to 1.0 then the array frontWheelIds must be specified and the corresponding entries of
|
|
the isConnected[] array must be set true.
|
|
\note If frontBias has value greater than or equal to 1.0 then frontTarget must also be specified.
|
|
\note A locked axle may be achieved by setting frontBias and frontTarget to 1.0.
|
|
\note A limited slip differential may be achieved by setting frontBias > 1.0 and frontBias > frontTarget > 1.0.
|
|
*/
|
|
PxReal frontBias;
|
|
|
|
/**
|
|
\brief The parameter frontTarget specifies the target rotational speed ratio of the two front wheels in the event that the ratio exceeds frontBias and frontBias
|
|
is configured for an activated limited slip or locked axle.
|
|
\note frontTarget must be less than frontBias and greater than 1.0 to implement a limited slip differential.
|
|
\note Set frontTarget and frontBias to 1.0 to implement a locked axle.
|
|
*/
|
|
PxReal frontTarget;
|
|
|
|
/**
|
|
\brief The parameter rearBias specifies the maximum angular speed ratio of the two rear wheels specified by rearWheelIds[2].
|
|
\note If rearBias has value 0.0, the differential will not try to enforce any relationship between the rotational speeds of the two rear wheels.
|
|
\note If rearBias has value 0.0, the torque split between the rear wheels is specified by the array torqueRatios.
|
|
\note rearBias must have value 0.0 (deactivated limited slip) or be greater than 1.0 (activated limited slip) or be equal to 1.0 (locked axle).
|
|
\note If rearBias has value greater than or equal to 1.0 then the array rearWheelIds must be specified and the corresponding entries of
|
|
the isConnected[] array must be set true.
|
|
\note If rearBias has value greater than or equal to 1.0 then rearTarget must also be specified.
|
|
\note A locked axle may be achieved by setting rearBias and rearTarget to 1.0.
|
|
\note A limited slip differential may be achieved by setting rearBias > 1.0 and rearBias > rearTarget > 1.0
|
|
*/
|
|
PxReal rearBias;
|
|
|
|
/**
|
|
\brief The parameter rearTarget specifies the target rotational speed ratio of the two rear wheels in the event that the ratio exceeds rearBias and rearBias
|
|
is configured for an activated limited slip or locked axle.
|
|
\note rearTarget must be less than rearBias and greater than 1.0 to implement a limited slip differential.
|
|
\note Set rearTarget and rearBias to 1.0 to implement a locked axle.
|
|
*/
|
|
PxReal rearTarget;
|
|
|
|
/**
|
|
\brief The parameter centerBias specifies the maximum angular speed ratio of the sum of the two front wheels and the sum of the two rear wheels,
|
|
as specified by frontWheelIds[2] and rearWheelIds[2].
|
|
\note If centerBias has value 0.0, the differential will not try to enforce any relationship between the rotational speeds of the front and rear wheels.
|
|
\note If centerBias has value 0.0, the torque split between the front and rear rear wheels is specified by the array torqueRatios.
|
|
\note centerBias must have value 0.0 (deactivated limited slip) or be greater than 1.0 (activated limited slip) or be equal to 1.0 (locked).
|
|
\note If centerBias has value greater than or equal to 1.0 then the arrays frontWheelIds and rearWheelIds must be specified and the corresponding entries of
|
|
the isConnected[] array must be set true.
|
|
\note If centerBias has value greater than or equal to 1.0 then centerTarget must also be specified.
|
|
\note A locked front/rear differential may be achieved by setting centerBias and centerTarget to 1.0.
|
|
\note A limited slip differential may be achieved by setting centerBias > 1.0 and centerBias > centerTarget > 1.0
|
|
*/
|
|
PxReal centerBias;
|
|
|
|
/**
|
|
\brief The parameter centerTarget specifies the target rotational speed ratio of the sum of the two front wheels and the sum of the two rear wheels
|
|
in the event that the ratio exceeds centerBias and centerBias is configured for an activated limited slip.
|
|
\note centerTarget must be less than centerBias and greater than 1.0 to implement a limited slip differential.
|
|
\note Set centerTarget and centerBias to 1.0 to implement a locked differential.
|
|
*/
|
|
PxReal centerTarget;
|
|
|
|
/**
|
|
\brief The parameter rate specifies how quickly the ratio of rotational speeds approaches the target rotational speed ratio.
|
|
\note strength must be in range [0,PX_VEHICLE_FOUR_WHEEL_DIFF_MAXIMUM_STRENGTH].
|
|
\note The ratio of rotational speeds is decremented each update by rate*dt until the ratio is equal to the target ratio.
|
|
\note A value of 0 will result in a deactivated limited slip.
|
|
\note A value of PX_VEHICLE_FOUR_WHEEL_DIFF_MAXIMUM_STRENGTH will result in instantaneous correction of the rotational speed ratios.
|
|
*/
|
|
PxReal rate;
|
|
|
|
|
|
PX_FORCE_INLINE void setToDefault()
|
|
{
|
|
PxVehicleMultiWheelDriveDifferentialParams::setToDefault();
|
|
frontBias = 0.0f;
|
|
rearBias = 0.0f;
|
|
centerBias = 0.0f;
|
|
}
|
|
|
|
PX_FORCE_INLINE bool isValid(const PxVehicleAxleDescription& axleDesc) const
|
|
{
|
|
if (!PxVehicleMultiWheelDriveDifferentialParams::isValid(axleDesc))
|
|
return false;
|
|
|
|
PX_CHECK_AND_RETURN_VAL((0.0f == centerBias) ||
|
|
(centerBias > 1.0f &&
|
|
frontWheelIds[0] < axleDesc.nbWheels && frontWheelIds[1] < axleDesc.nbWheels &&
|
|
rearWheelIds[0] < axleDesc.nbWheels && rearWheelIds[1] < axleDesc.nbWheels),
|
|
"PxVehicleFourWheelDriveDifferentialParams:: centreBias is enabled but the frontWheelIds and rearWheelIds are not configured correctly.", false);
|
|
PX_CHECK_AND_RETURN_VAL((0.0f == centerBias) ||
|
|
(centerBias > 1.0f &&
|
|
frontWheelIds[0] != frontWheelIds[1] && frontWheelIds[0] != rearWheelIds[0] && frontWheelIds[0] != rearWheelIds[1] &&
|
|
frontWheelIds[1] != rearWheelIds[0] && frontWheelIds[1] != rearWheelIds[1] &&
|
|
rearWheelIds[0] != rearWheelIds[1]),
|
|
"PxVehicleFourWheelDriveDifferentialParams:: centreBias is enabled but the frontWheelIds and rearWheelIds are not configured correctly.", false);
|
|
PX_CHECK_AND_RETURN_VAL((0.0f == centerBias) ||
|
|
(centerBias > 1.0f &&
|
|
torqueRatios[frontWheelIds[0]] != 0.0f && torqueRatios[frontWheelIds[1]] != 0.0f && torqueRatios[rearWheelIds[0]] != 0.0f && torqueRatios[rearWheelIds[1]] != 0.0f),
|
|
"PxVehicleFourWheelDriveDifferentialParams:: centreBias is enabled but the front and rear wheels are not connected.", false);
|
|
|
|
PX_CHECK_AND_RETURN_VAL((0.0f == rearBias) ||
|
|
(rearBias > 1.0f && rearWheelIds[0] < axleDesc.nbWheels && rearWheelIds[1] < axleDesc.nbWheels),
|
|
"PxVehicleFourWheelDriveDifferentialParams:: rearBias is enabled but the rearWheelIds are not configured correctly.", false);
|
|
PX_CHECK_AND_RETURN_VAL((0.0f == rearBias) ||
|
|
(rearBias > 1.0f && rearWheelIds[0] != rearWheelIds[1]),
|
|
"PxVehicleFourWheelDriveDifferentialParams:: rearBias is enabled but the rearWheelIds are not configured correctly.", false);
|
|
PX_CHECK_AND_RETURN_VAL((0.0f == centerBias) ||
|
|
(rearBias > 1.0f && torqueRatios[rearWheelIds[0]] != 0.0f && torqueRatios[rearWheelIds[1]] != 0.0f),
|
|
"PxVehicleFourWheelDriveDifferentialParams:: rearBias is enabled but the rear wheels are not connected.", false);
|
|
|
|
PX_CHECK_AND_RETURN_VAL((0.0f == frontBias) ||
|
|
(frontBias > 1.0f && frontWheelIds[0] < axleDesc.nbWheels && frontWheelIds[1] < axleDesc.nbWheels),
|
|
"PxVehicleFourWheelDriveDifferentialParams:: frontBias is enabled but the frontWheelIds are not configured correctly.", false);
|
|
PX_CHECK_AND_RETURN_VAL((0.0f == frontBias) ||
|
|
(frontBias > 1.0f && frontWheelIds[0] != frontWheelIds[1]),
|
|
"PxVehicleFourWheelDriveDifferentialParams:: frontBias is enabled but the frontWheelIds are not configured correctly.", false);
|
|
PX_CHECK_AND_RETURN_VAL((0.0f == frontBias) ||
|
|
(frontBias > 1.0f && torqueRatios[frontWheelIds[0]] != 0.0f && frontWheelIds[frontWheelIds[1]]),
|
|
"PxVehicleFourWheelDriveDifferentialParams:: frontBias is enabled but the front wheels are not connected.", false);
|
|
|
|
PX_CHECK_AND_RETURN_VAL(((0.0f == frontBias) && (0.0f == rearBias) && (0.0f == centerBias)) || (rate >= 0.0f),
|
|
"PxVehicleFourWheelDriveDifferentialParams:: strength must be greater than or equal to zero", false);
|
|
|
|
PX_CHECK_AND_RETURN_VAL((0.0f == frontBias) || ((1.0f == frontTarget && 1.0f == rearTarget) || (frontTarget > 1.0f && frontTarget < frontBias)),
|
|
"PxVehicleFourWheelDriveDifferentialParams: frontBias is enabled but frontTarget not in range (1.0f, frontBias)", false);
|
|
PX_CHECK_AND_RETURN_VAL((0.0f == rearBias) || ((1.0f == rearTarget && 1.0f == rearBias) || (rearTarget > 1.0f && rearTarget < rearBias)),
|
|
"PxVehicleFourWheelDriveDifferentialParams: rearBias is enabled but rearTarget not in range (1.0f, rearBias)", false);
|
|
PX_CHECK_AND_RETURN_VAL((0.0f == centerBias) || ((1.0f == centerTarget && 1.0f == centerBias) || (centerTarget > 1.0f && centerTarget < centerBias)),
|
|
"PxVehicleFourWheelDriveDifferentialParams: centerBias is enabled but centerTarget not in range (1.0f, centerBias)", false);
|
|
|
|
return true;
|
|
}
|
|
|
|
PX_FORCE_INLINE PxVehicleFourWheelDriveDifferentialParams transformAndScale(
|
|
const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const
|
|
{
|
|
PX_UNUSED(srcFrame);
|
|
PX_UNUSED(trgFrame);
|
|
PX_UNUSED(srcScale);
|
|
PX_UNUSED(trgScale);
|
|
PxVehicleFourWheelDriveDifferentialParams r = *this;
|
|
static_cast<PxVehicleMultiWheelDriveDifferentialParams&>(r) = PxVehicleMultiWheelDriveDifferentialParams::transformAndScale(srcFrame, trgFrame, srcScale, trgScale);
|
|
return r;
|
|
}
|
|
};
|
|
|
|
/**
|
|
\brief A description of a tank differential.
|
|
\note The wheels on a tank may be connected to the differential or not connected to the differential.
|
|
\note The wheels on a tank track may be connected to a tank track or not connected to a tank track.
|
|
\note Wheels connected to the differential but not to a tank track receive the torque split specified by the
|
|
corresponding elements of PxVehicleMultiWheelDriveDifferentialParams::torqueRatios[].
|
|
\note Wheels connected to a tank track but not to the differential receive no torque from the engine.
|
|
\note Wheels connected to a tank track and to the differential receive the torque split specified by the
|
|
corresponding elements of PxVehicleMultiWheelDriveDifferentialParams::torqueRatios[] multiplied by the corresponding
|
|
thrust controller value. If the thrust controller has a negative value, the wheels will receive a torque that is negative
|
|
with respect to the gearing ratio.
|
|
\note The wheels in each tank track have a constraint applied to them to enforce the rule that they all have the same longitudinal speed
|
|
at the contact point between the wheel and the tank track.
|
|
*/
|
|
struct PxVehicleTankDriveDifferentialParams : public PxVehicleMultiWheelDriveDifferentialParams
|
|
{
|
|
PX_FORCE_INLINE void setToDefault()
|
|
{
|
|
PxVehicleMultiWheelDriveDifferentialParams::setToDefault();
|
|
nbTracks = 0;
|
|
nbWheelsInTracks = 0;
|
|
}
|
|
|
|
/**
|
|
\brief Add a tank track by specifying the number of wheels along the track track and an array of wheel ids specifying each wheel in the tank track.
|
|
\param[in] nbWheelsInTrackToAdd is the number of wheels in the track to be added.
|
|
\param[in] wheelIdsInTrackToAdd is an array of wheel ids specifying all the wheels in the track to be added.
|
|
\param[in] thrustControllerIndex specifies the index of the thrust controller that will be used to control the tank track.
|
|
*/
|
|
void addTankTrack(const PxU32 nbWheelsInTrackToAdd, const PxU32* const wheelIdsInTrackToAdd, const PxU32 thrustControllerIndex)
|
|
{
|
|
PX_ASSERT((nbWheelsInTracks + nbWheelsInTrackToAdd) < PxVehicleLimits::eMAX_NB_WHEELS);
|
|
PX_ASSERT(nbTracks < PxVehicleLimits::eMAX_NB_WHEELS);
|
|
PX_ASSERT(thrustControllerIndex < 2);
|
|
nbWheelsPerTrack[nbTracks] = nbWheelsInTrackToAdd;
|
|
thrustIdPerTrack[nbTracks] = thrustControllerIndex;
|
|
trackToWheelIds[nbTracks] = nbWheelsInTracks;
|
|
for (PxU32 i = 0; i < nbWheelsInTrackToAdd; i++)
|
|
{
|
|
wheelIdsInTrackOrder[nbWheelsInTracks + i] = wheelIdsInTrackToAdd[i];
|
|
}
|
|
nbWheelsInTracks += nbWheelsInTrackToAdd;
|
|
nbTracks++;
|
|
}
|
|
|
|
/**
|
|
\brief Return the number of tracks.
|
|
\return The number of tracks.
|
|
@see getNbWheelsInTrack()
|
|
*/
|
|
PX_FORCE_INLINE PxU32 getNbTracks() const
|
|
{
|
|
return nbTracks;
|
|
}
|
|
|
|
/**
|
|
\brief Return the number of wheels in the ith track.
|
|
\param[in] i specifies the track to be queried for its wheel count.
|
|
\return The number of wheels in the specified track.
|
|
@see getWheelInTrack()
|
|
*/
|
|
PX_FORCE_INLINE PxU32 getNbWheelsInTrack(const PxU32 i) const
|
|
{
|
|
return nbWheelsPerTrack[i];
|
|
}
|
|
|
|
/**
|
|
\brief Return the array of all wheels in the ith track.
|
|
\param[in] i specifies the track to be queried for its wheels.
|
|
\return The array of wheels in the specified track.
|
|
*/
|
|
PX_FORCE_INLINE const PxU32* getWheelsInTrack(const PxU32 i) const
|
|
{
|
|
return (wheelIdsInTrackOrder + trackToWheelIds[i]);
|
|
}
|
|
|
|
/**
|
|
\brief Return the wheel id of the jth wheel in the ith track.
|
|
\param[in] j specifies that the wheel id to be returned is the jth wheel in the list of wheels on the specified track.
|
|
\param[in] i specifies the track to be queried.
|
|
\return The wheel id of the jth wheel in the ith track.
|
|
@see getNbWheelsInTrack()
|
|
*/
|
|
PX_FORCE_INLINE PxU32 getWheelInTrack(const PxU32 j, const PxU32 i) const
|
|
{
|
|
return wheelIdsInTrackOrder[trackToWheelIds[i] + j];
|
|
}
|
|
|
|
/**
|
|
\brief Return the index of the thrust controller that will control a specified track.
|
|
\param[in] i specifies the track to be queried for its thrust controller index
|
|
\return The index of the thrust controller that will control the ith track.
|
|
*/
|
|
PX_FORCE_INLINE PxU32 getThrustControllerIndex(const PxU32 i) const
|
|
{
|
|
return thrustIdPerTrack[i];
|
|
}
|
|
|
|
PX_FORCE_INLINE PxVehicleTankDriveDifferentialParams transformAndScale(
|
|
const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const
|
|
{
|
|
PX_UNUSED(srcFrame);
|
|
PX_UNUSED(trgFrame);
|
|
PX_UNUSED(srcScale);
|
|
PX_UNUSED(trgScale);
|
|
PxVehicleTankDriveDifferentialParams r = *this;
|
|
static_cast<PxVehicleMultiWheelDriveDifferentialParams&>(r) = PxVehicleMultiWheelDriveDifferentialParams::transformAndScale(srcFrame, trgFrame, srcScale, trgScale);
|
|
return r;
|
|
}
|
|
|
|
PX_FORCE_INLINE bool isValid(const PxVehicleAxleDescription& axleDesc) const
|
|
{
|
|
if (!PxVehicleMultiWheelDriveDifferentialParams::isValid(axleDesc))
|
|
return false;
|
|
|
|
PX_CHECK_AND_RETURN_VAL(nbTracks <= PxVehicleLimits::eMAX_NB_WHEELS, "PxVehicleTankDriveDifferentialParams.nbTracks must not exceed PxVehicleLimits::eMAX_NB_WHEELS", false);
|
|
PX_CHECK_AND_RETURN_VAL(nbWheelsInTracks <= PxVehicleLimits::eMAX_NB_WHEELS, "PxVehicleTankDriveDifferentialParams.nbWheelsInTracks must not exceed PxVehicleLimits::eMAX_NB_WHEELS", false);
|
|
for (PxU32 i = 0; i < nbTracks; i++)
|
|
{
|
|
PX_CHECK_AND_RETURN_VAL(thrustIdPerTrack[i] < 2, "PxVehicleTankDriveDifferentialParams.thrustId must be less than 2", false);
|
|
PX_CHECK_AND_RETURN_VAL(getNbWheelsInTrack(i) >= 2, "PxVehicleTankDriveDifferentialParams.nbWheelsPerTrack must be greater than or equal to 2", false);
|
|
}
|
|
|
|
for (PxU32 i = 0; i < axleDesc.nbWheels; i++)
|
|
{
|
|
const PxU32 wheelId = axleDesc.wheelIdsInAxleOrder[i];
|
|
PxU32 count = 0;
|
|
for (PxU32 j = 0; j < nbWheelsInTracks; j++)
|
|
{
|
|
if (wheelIdsInTrackOrder[j] == wheelId)
|
|
count++;
|
|
}
|
|
PX_CHECK_AND_RETURN_VAL(count <= 1, "PxVehicleTankDriveDifferentialParams - a wheel cannot be in more than one tank track", false);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
PxU32 nbTracks; //!< The number of tracks
|
|
PxU32 thrustIdPerTrack[PxVehicleLimits::eMAX_NB_WHEELS]; //!< The id of the thrust that will control the track. Must have value 0 or 1.
|
|
PxU32 nbWheelsPerTrack[PxVehicleLimits::eMAX_NB_WHEELS]; //!< The number of wheels in each track
|
|
PxU32 trackToWheelIds[PxVehicleLimits::eMAX_NB_WHEELS]; //!< The list of wheel ids for the ith tank track begins at wheelIdsInTrackOrder[trackToWheelIds[i]]
|
|
|
|
PxU32 wheelIdsInTrackOrder[PxVehicleLimits::eMAX_NB_WHEELS];//!< The list of all wheel ids in all tracks
|
|
PxU32 nbWheelsInTracks; //!< The number of wheels in all tracks.
|
|
};
|
|
|
|
|
|
#if !PX_DOXYGEN
|
|
} // namespace vehicle2
|
|
} // namespace physx
|
|
#endif
|
|
|
|
/** @} */
|
|
|