1 | // |
2 | // Redistribution and use in source and binary forms, with or without |
3 | // modification, are permitted provided that the following conditions |
4 | // are met: |
5 | // * Redistributions of source code must retain the above copyright |
6 | // notice, this list of conditions and the following disclaimer. |
7 | // * Redistributions in binary form must reproduce the above copyright |
8 | // notice, this list of conditions and the following disclaimer in the |
9 | // documentation and/or other materials provided with the distribution. |
10 | // * Neither the name of NVIDIA CORPORATION nor the names of its |
11 | // contributors may be used to endorse or promote products derived |
12 | // from this software without specific prior written permission. |
13 | // |
14 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY |
15 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
16 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
17 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
18 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
20 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
21 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
22 | // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
24 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | // |
26 | // Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved. |
27 | // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. |
28 | // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. |
29 | |
30 | #ifndef PX_VEHICLE_CORE_COMPONENTS_H |
31 | #define PX_VEHICLE_CORE_COMPONENTS_H |
32 | /** \addtogroup vehicle |
33 | @{ |
34 | */ |
35 | |
36 | #include "foundation/PxMemory.h" |
37 | #include "foundation/PxVec3.h" |
38 | #include "common/PxCoreUtilityTypes.h" |
39 | #include "vehicle/PxVehicleSDK.h" |
40 | #include "common/PxTypeInfo.h" |
41 | |
42 | #if !PX_DOXYGEN |
43 | namespace physx |
44 | { |
45 | #endif |
46 | |
47 | class PxVehicleChassisData |
48 | { |
49 | public: |
50 | |
51 | friend class PxVehicleDriveSimData4W; |
52 | |
53 | PxVehicleChassisData() |
54 | : mMOI(PxVec3(0,0,0)), |
55 | mMass(1500), |
56 | mCMOffset(PxVec3(0,0,0)) |
57 | { |
58 | } |
59 | |
60 | /** |
61 | \brief Moment of inertia of vehicle rigid body actor. |
62 | |
63 | \note Specified in kilograms metres-squared (kg m^2). |
64 | */ |
65 | PxVec3 mMOI; |
66 | |
67 | /** |
68 | \brief Mass of vehicle rigid body actor. |
69 | |
70 | \note Specified in kilograms (kg). |
71 | */ |
72 | PxReal mMass; |
73 | |
74 | /** |
75 | \brief Center of mass offset of vehicle rigid body actor. |
76 | |
77 | \note Specified in metres (m). |
78 | */ |
79 | PxVec3 mCMOffset; |
80 | |
81 | private: |
82 | |
83 | PxReal pad; |
84 | |
85 | bool isValid() const; |
86 | }; |
87 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleChassisData)& 0x0f)); |
88 | |
89 | class PxVehicleEngineData |
90 | { |
91 | public: |
92 | |
93 | friend class PxVehicleDriveSimData; |
94 | |
95 | enum |
96 | { |
97 | eMAX_NB_ENGINE_TORQUE_CURVE_ENTRIES = 8 |
98 | }; |
99 | |
100 | PxVehicleEngineData() |
101 | : mMOI(1.0f), |
102 | mPeakTorque(500.0f), |
103 | mMaxOmega(600.0f), |
104 | mDampingRateFullThrottle(0.15f), |
105 | mDampingRateZeroThrottleClutchEngaged(2.0f), |
106 | mDampingRateZeroThrottleClutchDisengaged(0.35f) |
107 | { |
108 | mTorqueCurve.addPair(x: 0.0f, y: 0.8f); |
109 | mTorqueCurve.addPair(x: 0.33f, y: 1.0f); |
110 | mTorqueCurve.addPair(x: 1.0f, y: 0.8f); |
111 | |
112 | mRecipMOI=1.0f/mMOI; |
113 | mRecipMaxOmega=1.0f/mMaxOmega; |
114 | } |
115 | |
116 | /** |
117 | \brief Graph of normalized torque (torque/mPeakTorque) against normalized engine speed ( engineRotationSpeed / mMaxOmega ). |
118 | |
119 | \note The normalized engine speed is the x-axis of the graph, while the normalized torque is the y-axis of the graph. |
120 | */ |
121 | PxFixedSizeLookupTable<eMAX_NB_ENGINE_TORQUE_CURVE_ENTRIES> mTorqueCurve; |
122 | |
123 | /** |
124 | \brief Moment of inertia of the engine around the axis of rotation. |
125 | |
126 | \note Specified in kilograms metres-squared (kg m^2) |
127 | */ |
128 | PxReal mMOI; |
129 | |
130 | /** |
131 | \brief Maximum torque available to apply to the engine when the accelerator pedal is at maximum. |
132 | |
133 | \note The torque available is the value of the accelerator pedal (in range [0, 1]) multiplied by the normalized torque as computed from mTorqueCurve multiplied by mPeakTorque. |
134 | |
135 | \note Specified in kilograms metres-squared per second-squared (kg m^2 s^-2). |
136 | |
137 | <b>Range:</b> [0, PX_MAX_F32)<br> |
138 | */ |
139 | PxReal mPeakTorque; |
140 | |
141 | /** |
142 | \brief Maximum rotation speed of the engine. |
143 | |
144 | \note Specified in radians per second (s^-1). |
145 | |
146 | <b>Range:</b> [0, PX_MAX_F32)<br> |
147 | */ |
148 | PxReal mMaxOmega; |
149 | |
150 | /** |
151 | \brief Damping rate of engine when full throttle is applied. |
152 | |
153 | \note If the clutch is engaged (any gear except neutral) then the damping rate applied at run-time is an interpolation |
154 | between mDampingRateZeroThrottleClutchEngaged and mDampingRateFullThrottle: |
155 | mDampingRateZeroThrottleClutchEngaged + (mDampingRateFullThrottle-mDampingRateZeroThrottleClutchEngaged)*acceleratorPedal; |
156 | |
157 | \note If the clutch is disengaged (in neutral gear) the damping rate applied at run-time is an interpolation |
158 | between mDampingRateZeroThrottleClutchDisengaged and mDampingRateFullThrottle: |
159 | mDampingRateZeroThrottleClutchDisengaged + (mDampingRateFullThrottle-mDampingRateZeroThrottleClutchDisengaged)*acceleratorPedal; |
160 | |
161 | \note Specified in kilograms metres-squared per second (kg m^2 s^-1). |
162 | |
163 | <b>Range:</b> [0, PX_MAX_F32)<br> |
164 | */ |
165 | PxReal mDampingRateFullThrottle; |
166 | |
167 | |
168 | /** |
169 | \brief Damping rate of engine when full throttle is applied. |
170 | |
171 | \note If the clutch is engaged (any gear except neutral) then the damping rate applied at run-time is an interpolation |
172 | between mDampingRateZeroThrottleClutchEngaged and mDampingRateFullThrottle: |
173 | mDampingRateZeroThrottleClutchEngaged + (mDampingRateFullThrottle-mDampingRateZeroThrottleClutchEngaged)*acceleratorPedal; |
174 | |
175 | \note If the clutch is disengaged (in neutral gear) the damping rate applied at run-time is an interpolation |
176 | between mDampingRateZeroThrottleClutchDisengaged and mDampingRateFullThrottle: |
177 | mDampingRateZeroThrottleClutchDisengaged + (mDampingRateFullThrottle-mDampingRateZeroThrottleClutchDisengaged)*acceleratorPedal; |
178 | |
179 | \note Specified in kilograms metres-squared per second (kg m^2 s^-1). |
180 | |
181 | <b>Range:</b> [0, PX_MAX_F32)<br> |
182 | */ |
183 | PxReal mDampingRateZeroThrottleClutchEngaged; |
184 | |
185 | /** |
186 | \brief Damping rate of engine when full throttle is applied. |
187 | |
188 | \note If the clutch is engaged (any gear except neutral) then the damping rate applied at run-time is an interpolation |
189 | between mDampingRateZeroThrottleClutchEngaged and mDampingRateFullThrottle: |
190 | mDampingRateZeroThrottleClutchEngaged + (mDampingRateFullThrottle-mDampingRateZeroThrottleClutchEngaged)*acceleratorPedal; |
191 | |
192 | \note If the clutch is disengaged (in neutral gear) the damping rate applied at run-time is an interpolation |
193 | between mDampingRateZeroThrottleClutchDisengaged and mDampingRateFullThrottle: |
194 | mDampingRateZeroThrottleClutchDisengaged + (mDampingRateFullThrottle-mDampingRateZeroThrottleClutchDisengaged)*acceleratorPedal; |
195 | |
196 | \note Specified in kilograms metres-squared per second (kg m^2 s^-1). |
197 | |
198 | <b>Range:</b> [0, PX_MAX_F32)<br> |
199 | */ |
200 | PxReal mDampingRateZeroThrottleClutchDisengaged; |
201 | |
202 | /** |
203 | \brief Return value of mRecipMOI(=1.0f/mMOI) that is automatically set by PxVehicleDriveSimData::setEngineData |
204 | */ |
205 | PX_FORCE_INLINE PxReal getRecipMOI() const {return mRecipMOI;} |
206 | |
207 | /** |
208 | \brief Return value of mRecipMaxOmega( = 1.0f / mMaxOmega ) that is automatically set by PxVehicleDriveSimData::setEngineData |
209 | */ |
210 | PX_FORCE_INLINE PxReal getRecipMaxOmega() const {return mRecipMaxOmega;} |
211 | |
212 | private: |
213 | |
214 | /** |
215 | \brief Reciprocal of the engine moment of inertia. |
216 | |
217 | \note Not necessary to set this value because it is set by PxVehicleDriveSimData::setEngineData |
218 | |
219 | <b>Range:</b> [0, PX_MAX_F32)<br> |
220 | */ |
221 | PxReal mRecipMOI; |
222 | |
223 | /** |
224 | \brief Reciprocal of the maximum rotation speed of the engine. |
225 | |
226 | \note Not necessary to set this value because it is set by PxVehicleDriveSimData::setEngineData |
227 | |
228 | <b>Range:</b> [0, PX_MAX_F32)<br> |
229 | */ |
230 | PxReal mRecipMaxOmega; |
231 | |
232 | bool isValid() const; |
233 | |
234 | |
235 | //serialization |
236 | public: |
237 | PxVehicleEngineData(const PxEMPTY) : mTorqueCurve(PxEmpty) {} |
238 | //~serialization |
239 | }; |
240 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleEngineData)& 0x0f)); |
241 | |
242 | class PxVehicleGearsData |
243 | { |
244 | public: |
245 | |
246 | friend class PxVehicleDriveSimData; |
247 | |
248 | enum Enum |
249 | { |
250 | eREVERSE=0, |
251 | eNEUTRAL, |
252 | eFIRST, |
253 | eSECOND, |
254 | eTHIRD, |
255 | eFOURTH, |
256 | eFIFTH, |
257 | eSIXTH, |
258 | eSEVENTH, |
259 | eEIGHTH, |
260 | eNINTH, |
261 | eTENTH, |
262 | eELEVENTH, |
263 | eTWELFTH, |
264 | eTHIRTEENTH, |
265 | eFOURTEENTH, |
266 | eFIFTEENTH, |
267 | eSIXTEENTH, |
268 | eSEVENTEENTH, |
269 | eEIGHTEENTH, |
270 | eNINETEENTH, |
271 | eTWENTIETH, |
272 | eTWENTYFIRST, |
273 | eTWENTYSECOND, |
274 | eTWENTYTHIRD, |
275 | eTWENTYFOURTH, |
276 | eTWENTYFIFTH, |
277 | eTWENTYSIXTH, |
278 | eTWENTYSEVENTH, |
279 | eTWENTYEIGHTH, |
280 | eTWENTYNINTH, |
281 | eTHIRTIETH, |
282 | eGEARSRATIO_COUNT |
283 | }; |
284 | |
285 | PxVehicleGearsData() |
286 | : mFinalRatio(4.0f), |
287 | mNbRatios(7), |
288 | mSwitchTime(0.5f) |
289 | { |
290 | mRatios[PxVehicleGearsData::eREVERSE]=-4.0f; |
291 | mRatios[PxVehicleGearsData::eNEUTRAL]=0.0f; |
292 | mRatios[PxVehicleGearsData::eFIRST]=4.0f; |
293 | mRatios[PxVehicleGearsData::eSECOND]=2.0f; |
294 | mRatios[PxVehicleGearsData::eTHIRD]=1.5f; |
295 | mRatios[PxVehicleGearsData::eFOURTH]=1.1f; |
296 | mRatios[PxVehicleGearsData::eFIFTH]=1.0f; |
297 | |
298 | for(PxU32 i = PxVehicleGearsData::eSIXTH; i < PxVehicleGearsData::eGEARSRATIO_COUNT; ++i) |
299 | mRatios[i]=0.f; |
300 | } |
301 | |
302 | /** |
303 | \brief Gear ratios |
304 | |
305 | <b>Range:</b> [0, PX_MAX_F32)<br> |
306 | */ |
307 | PxReal mRatios[PxVehicleGearsData::eGEARSRATIO_COUNT]; |
308 | |
309 | /** |
310 | \brief Gear ratio applied is mRatios[currentGear]*finalRatio |
311 | |
312 | <b>Range:</b> [0, PX_MAX_F32)<br> |
313 | */ |
314 | PxReal mFinalRatio; |
315 | |
316 | /** |
317 | \brief Number of gears (including reverse and neutral). |
318 | |
319 | <b>Range:</b> (0, MAX_NB_GEAR_RATIOS)<br> |
320 | */ |
321 | PxU32 mNbRatios; |
322 | |
323 | /** |
324 | \brief Time it takes to switch gear. |
325 | |
326 | \note Specified in seconds (s). |
327 | |
328 | <b>Range:</b> [0, PX_MAX_F32)<br> |
329 | */ |
330 | PxReal mSwitchTime; |
331 | |
332 | private: |
333 | |
334 | PxReal mPad; |
335 | |
336 | bool isValid() const; |
337 | |
338 | //serialization |
339 | public: |
340 | PxVehicleGearsData(const PxEMPTY) {} |
341 | PxReal getGearRatio(PxVehicleGearsData::Enum a) const {return mRatios[a];} |
342 | void setGearRatio(PxVehicleGearsData::Enum a, PxReal ratio) { mRatios[a] = ratio;} |
343 | //~serialization |
344 | }; |
345 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleGearsData)& 0x0f)); |
346 | |
347 | class PxVehicleAutoBoxData |
348 | { |
349 | public: |
350 | |
351 | friend class PxVehicleDriveSimData; |
352 | |
353 | PxVehicleAutoBoxData() |
354 | { |
355 | for(PxU32 i=0;i<PxVehicleGearsData::eGEARSRATIO_COUNT;i++) |
356 | { |
357 | mUpRatios[i]=0.65f; |
358 | mDownRatios[i]=0.50f; |
359 | } |
360 | //Not sure how important this is but we want to kick out of neutral very quickly. |
361 | mUpRatios[PxVehicleGearsData::eNEUTRAL]=0.15f; |
362 | //Set the latency time in an unused element of one of the arrays. |
363 | mDownRatios[PxVehicleGearsData::eREVERSE]=2.0f; |
364 | } |
365 | |
366 | /** |
367 | \brief Value of ( engineRotationSpeed / PxVehicleEngineData::mMaxOmega ) that is high enough to increment gear. |
368 | |
369 | \note When ( engineRotationSpeed / PxVehicleEngineData::mMaxOmega ) > mUpRatios[currentGear] the autobox will begin |
370 | a transition to currentGear+1 unless currentGear is the highest possible gear or neutral or reverse. |
371 | |
372 | <b>Range:</b> [0, 1]<br> |
373 | */ |
374 | PxReal mUpRatios[PxVehicleGearsData::eGEARSRATIO_COUNT]; |
375 | |
376 | /** |
377 | \brief Value of engineRevs/maxEngineRevs that is low enough to decrement gear. |
378 | |
379 | \note When ( engineRotationSpeed / PxVehicleEngineData::mMaxOmega ) < mDownRatios[currentGear] the autobox will begin |
380 | a transition to currentGear-1 unless currentGear is first gear or neutral or reverse. |
381 | |
382 | <b>Range:</b> [0, 1]<br> |
383 | */ |
384 | PxReal mDownRatios[PxVehicleGearsData::eGEARSRATIO_COUNT]; |
385 | |
386 | /** |
387 | \brief Set the latency time of the autobox. |
388 | |
389 | \note Latency time is the minimum time that must pass between each gear change that is initiated by the autobox. |
390 | 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 |
391 | automated gear change is greater than the specified latency. |
392 | |
393 | \note Specified in seconds (s). |
394 | |
395 | @see getLatency |
396 | */ |
397 | void setLatency(const PxReal latency) |
398 | { |
399 | mDownRatios[PxVehicleGearsData::eREVERSE]=latency; |
400 | } |
401 | |
402 | /** |
403 | \brief Get the latency time of the autobox. |
404 | |
405 | \note Specified in seconds (s). |
406 | |
407 | @see setLatency |
408 | */ |
409 | PxReal getLatency() const |
410 | { |
411 | return mDownRatios[PxVehicleGearsData::eREVERSE]; |
412 | } |
413 | |
414 | private: |
415 | bool isValid() const; |
416 | |
417 | //serialization |
418 | public: |
419 | PxVehicleAutoBoxData(const PxEMPTY) {} |
420 | |
421 | PxReal getUpRatios(PxVehicleGearsData::Enum a) const {return mUpRatios[a];} |
422 | void setUpRatios(PxVehicleGearsData::Enum a, PxReal ratio) { mUpRatios[a] = ratio;} |
423 | |
424 | PxReal getDownRatios(PxVehicleGearsData::Enum a) const {return mDownRatios[a];} |
425 | void setDownRatios(PxVehicleGearsData::Enum a, PxReal ratio) { mDownRatios[a] = ratio;} |
426 | //~serialization |
427 | }; |
428 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleAutoBoxData)& 0x0f)); |
429 | |
430 | class PxVehicleDifferential4WData |
431 | { |
432 | public: |
433 | |
434 | friend class PxVehicleDriveSimData4W; |
435 | |
436 | enum Enum |
437 | { |
438 | eDIFF_TYPE_LS_4WD, //limited slip differential for car with 4 driven wheels |
439 | eDIFF_TYPE_LS_FRONTWD, //limited slip differential for car with front-wheel drive |
440 | eDIFF_TYPE_LS_REARWD, //limited slip differential for car with rear-wheel drive |
441 | eDIFF_TYPE_OPEN_4WD, //open differential for car with 4 driven wheels |
442 | eDIFF_TYPE_OPEN_FRONTWD, //open differential for car with front-wheel drive |
443 | eDIFF_TYPE_OPEN_REARWD, //open differential for car with rear-wheel drive |
444 | eMAX_NB_DIFF_TYPES |
445 | }; |
446 | |
447 | PxVehicleDifferential4WData() |
448 | : mFrontRearSplit(0.45f), |
449 | mFrontLeftRightSplit(0.5f), |
450 | mRearLeftRightSplit(0.5f), |
451 | mCentreBias(1.3f), |
452 | mFrontBias(1.3f), |
453 | mRearBias(1.3f), |
454 | mType(PxVehicleDifferential4WData::eDIFF_TYPE_LS_4WD) |
455 | { |
456 | } |
457 | |
458 | /** |
459 | \brief Ratio of torque split between front and rear (>0.5 means more to front, <0.5 means more to rear). |
460 | |
461 | \note Only applied to DIFF_TYPE_LS_4WD and eDIFF_TYPE_OPEN_4WD |
462 | |
463 | <b>Range:</b> [0, 1]<br> |
464 | */ |
465 | PxReal mFrontRearSplit; |
466 | |
467 | /** |
468 | \brief Ratio of torque split between front-left and front-right (>0.5 means more to front-left, <0.5 means more to front-right). |
469 | |
470 | \note Only applied to DIFF_TYPE_LS_4WD and eDIFF_TYPE_OPEN_4WD and eDIFF_TYPE_LS_FRONTWD |
471 | |
472 | <b>Range:</b> [0, 1]<br> |
473 | */ |
474 | PxReal mFrontLeftRightSplit; |
475 | |
476 | /** |
477 | \brief Ratio of torque split between rear-left and rear-right (>0.5 means more to rear-left, <0.5 means more to rear-right). |
478 | |
479 | \note Only applied to DIFF_TYPE_LS_4WD and eDIFF_TYPE_OPEN_4WD and eDIFF_TYPE_LS_REARWD |
480 | |
481 | <b>Range:</b> [0, 1]<br> |
482 | */ |
483 | PxReal mRearLeftRightSplit; |
484 | |
485 | /** |
486 | \brief Maximum allowed ratio of average front wheel rotation speed and rear wheel rotation speeds |
487 | The differential will divert more torque to the slower wheels when the bias is exceeded. |
488 | |
489 | \note Only applied to DIFF_TYPE_LS_4WD |
490 | |
491 | <b>Range:</b> [1, PX_MAX_F32)<br> |
492 | */ |
493 | PxReal mCentreBias; |
494 | |
495 | /** |
496 | \brief Maximum allowed ratio of front-left and front-right wheel rotation speeds. |
497 | The differential will divert more torque to the slower wheel when the bias is exceeded. |
498 | |
499 | \note Only applied to DIFF_TYPE_LS_4WD and DIFF_TYPE_LS_FRONTWD |
500 | |
501 | <b>Range:</b> [1, PX_MAX_F32)<br> |
502 | */ |
503 | PxReal mFrontBias; |
504 | |
505 | /** |
506 | \brief Maximum allowed ratio of rear-left and rear-right wheel rotation speeds. |
507 | The differential will divert more torque to the slower wheel when the bias is exceeded. |
508 | |
509 | \note Only applied to DIFF_TYPE_LS_4WD and DIFF_TYPE_LS_REARWD |
510 | |
511 | <b>Range:</b> [1, PX_MAX_F32)<br> |
512 | */ |
513 | PxReal mRearBias; |
514 | |
515 | /** |
516 | \brief Type of differential. |
517 | |
518 | <b>Range:</b> [DIFF_TYPE_LS_4WD, DIFF_TYPE_OPEN_FRONTWD]<br> |
519 | */ |
520 | PxVehicleDifferential4WData::Enum mType; |
521 | |
522 | private: |
523 | |
524 | PxReal mPad[1]; |
525 | |
526 | bool isValid() const; |
527 | |
528 | //serialization |
529 | public: |
530 | PxVehicleDifferential4WData(const PxEMPTY) {} |
531 | //~serialization |
532 | }; |
533 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDifferential4WData)& 0x0f)); |
534 | |
535 | class PxVehicleDifferentialNWData |
536 | { |
537 | public: |
538 | |
539 | friend class PxVehicleDriveSimDataNW; |
540 | friend class PxVehicleUpdate; |
541 | |
542 | PxVehicleDifferentialNWData() |
543 | { |
544 | PxMemSet(dest: mBitmapBuffer, c: 0, count: sizeof(PxU32) * (((PX_MAX_NB_WHEELS + 31) & ~31) >> 5)); |
545 | mNbDrivenWheels=0; |
546 | mInvNbDrivenWheels=0.0f; |
547 | } |
548 | |
549 | /** |
550 | \brief Set a specific wheel to be driven or non-driven by the differential. |
551 | |
552 | \note The available drive torque will be split equally between all driven wheels. |
553 | Zero torque will be applied to non-driven wheels. |
554 | The default state of each wheel is to be uncoupled to the differential. |
555 | */ |
556 | void setDrivenWheel(const PxU32 wheelId, const bool drivenState); |
557 | |
558 | /** |
559 | \brief Test if a specific wheel has been configured as a driven or non-driven wheel. |
560 | */ |
561 | bool getIsDrivenWheel(const PxU32 wheelId) const; |
562 | |
563 | private: |
564 | |
565 | PxU32 mBitmapBuffer[((PX_MAX_NB_WHEELS + 31) & ~31) >> 5]; |
566 | PxU32 mNbDrivenWheels; |
567 | PxReal mInvNbDrivenWheels; |
568 | PxU32 mPad; |
569 | |
570 | bool isValid() const; |
571 | |
572 | //serialization |
573 | public: |
574 | PxVehicleDifferentialNWData(const PxEMPTY) {} |
575 | PxU32 getDrivenWheelStatus() const; |
576 | void setDrivenWheelStatus(PxU32 status); |
577 | //~serialization |
578 | }; |
579 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDifferentialNWData)& 0x0f)); |
580 | |
581 | |
582 | class PxVehicleAckermannGeometryData |
583 | { |
584 | public: |
585 | |
586 | friend class PxVehicleDriveSimData4W; |
587 | |
588 | PxVehicleAckermannGeometryData() |
589 | : mAccuracy(1.0f), |
590 | mFrontWidth(0.0f), //Must be filled out |
591 | mRearWidth(0.0f), //Must be filled out |
592 | mAxleSeparation(0.0f) //Must be filled out |
593 | { |
594 | } |
595 | |
596 | /** |
597 | \brief Accuracy of Ackermann steer calculation. |
598 | |
599 | \note Accuracy with value 0.0 results in no Ackermann steer-correction, while |
600 | accuracy with value 1.0 results in perfect Ackermann steer-correction. |
601 | |
602 | \note Perfect Ackermann steer correction modifies the steer angles applied to the front-left and |
603 | front-right wheels so that the perpendiculars to the wheels' longitudinal directions cross the |
604 | extended vector of the rear axle at the same point. It is also applied to any steer angle applied |
605 | to the rear wheels but instead using the extended vector of the front axle. |
606 | |
607 | \note In general, more steer correction produces better cornering behavior. |
608 | |
609 | <b>Range:</b> [0, 1]<br> |
610 | */ |
611 | PxReal mAccuracy; |
612 | |
613 | /** |
614 | \brief Distance between center-point of the two front wheels. |
615 | |
616 | \note Specified in metres (m). |
617 | |
618 | <b>Range:</b> [0, PX_MAX_F32)<br> |
619 | */ |
620 | PxReal mFrontWidth; |
621 | |
622 | /** |
623 | \brief Distance between center-point of the two rear wheels. |
624 | |
625 | \note Specified in metres (m). |
626 | |
627 | <b>Range:</b> [0, PX_MAX_F32)<br> |
628 | */ |
629 | PxReal mRearWidth; |
630 | |
631 | /** |
632 | \brief Distance between center of front axle and center of rear axle. |
633 | |
634 | \note Specified in metres (m). |
635 | |
636 | <b>Range:</b> [0, PX_MAX_F32)<br> |
637 | */ |
638 | PxReal mAxleSeparation; |
639 | |
640 | private: |
641 | |
642 | bool isValid() const; |
643 | |
644 | //serialization |
645 | public: |
646 | PxVehicleAckermannGeometryData(const PxEMPTY) {} |
647 | //~serialization |
648 | }; |
649 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleAckermannGeometryData)& 0x0f)); |
650 | |
651 | /** |
652 | \brief Choose between a potentially more expensive but more accurate solution to the clutch model or a potentially cheaper but less accurate solution. |
653 | @see PxVehicleClutchData |
654 | */ |
655 | struct PxVehicleClutchAccuracyMode |
656 | { |
657 | enum Enum |
658 | { |
659 | eESTIMATE = 0, |
660 | eBEST_POSSIBLE |
661 | }; |
662 | }; |
663 | |
664 | class PxVehicleClutchData |
665 | { |
666 | public: |
667 | |
668 | friend class PxVehicleDriveSimData; |
669 | |
670 | PxVehicleClutchData() |
671 | : mStrength(10.0f), |
672 | mAccuracyMode(PxVehicleClutchAccuracyMode::eBEST_POSSIBLE), |
673 | mEstimateIterations(5) |
674 | { |
675 | } |
676 | |
677 | /** |
678 | \brief Strength of clutch. |
679 | |
680 | \note The clutch is the mechanism that couples the engine to the wheels. |
681 | A stronger clutch more strongly couples the engine to the wheels, while a |
682 | clutch of strength zero completely decouples the engine from the wheels. |
683 | Stronger clutches more quickly bring the wheels and engine into equilibrium, while weaker |
684 | clutches take longer, resulting in periods of clutch slip and delays in power transmission |
685 | from the engine to the wheels. |
686 | The torque generated by the clutch is proportional to the clutch strength and |
687 | the velocity difference between the engine's rotational speed and the rotational speed of the |
688 | driven wheels after accounting for the gear ratio. |
689 | The torque at the clutch is applied negatively to the engine and positively to the driven wheels. |
690 | |
691 | \note Specified in kilograms metres-squared per second (kg m^2 s^-1) |
692 | |
693 | <b>Range:</b> [0,PX_MAX_F32)<br> |
694 | */ |
695 | PxReal mStrength; |
696 | |
697 | /** |
698 | \brief The engine and wheel rotation speeds that are coupled through the clutch can be updated by choosing |
699 | one of two modes: eESTIMATE and eBEST_POSSIBLE. |
700 | |
701 | \note If eESTIMATE is chosen the vehicle sdk will update the wheel and engine rotation speeds |
702 | with estimated values to the implemented clutch model. |
703 | |
704 | \note If eBEST_POSSIBLE is chosen the vehicle sdk will compute the best possible |
705 | solution (within floating point tolerance) to the implemented clutch model. |
706 | This is the recommended mode. |
707 | |
708 | \note The clutch model remains the same if either eESTIMATE or eBEST_POSSIBLE is chosen but the accuracy and |
709 | computational cost of the solution to the model can be tuned as required. |
710 | */ |
711 | PxVehicleClutchAccuracyMode::Enum mAccuracyMode; |
712 | |
713 | /** |
714 | \brief Tune the mathematical accuracy and computational cost of the computed estimate to the wheel and |
715 | engine rotation speeds if eESTIMATE is chosen. |
716 | |
717 | \note As mEstimateIterations increases the computational cost of the clutch also increases and the solution |
718 | approaches the solution that would be computed if eBEST_POSSIBLE was chosen instead. |
719 | |
720 | \note This has no effect if eBEST_POSSIBLE is chosen as the accuracy mode. |
721 | |
722 | \note A value of zero is not allowed if eESTIMATE is chosen as the accuracy mode. |
723 | */ |
724 | PxU32 mEstimateIterations; |
725 | |
726 | private: |
727 | |
728 | PxU8 mPad[4]; |
729 | |
730 | bool isValid() const; |
731 | |
732 | //serialization |
733 | public: |
734 | PxVehicleClutchData(const PxEMPTY) {} |
735 | //~serialization |
736 | }; |
737 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleClutchData)& 0x0f)); |
738 | |
739 | |
740 | /** |
741 | \brief Tire load variation can be strongly dependent on the time-step so it is a good idea to filter it |
742 | to give less jerky handling behavior. |
743 | |
744 | \note The x-axis of the graph is normalized tire load, while the y-axis is the filtered normalized tire load. |
745 | |
746 | \note The normalized load is the force acting downwards on the tire divided by the force experienced by the tire when the car is at rest on the ground. |
747 | |
748 | \note The rest load is approximately the product of the value of gravitational acceleration and PxVehicleSuspensionData::mSprungMass. |
749 | |
750 | \note The minimum possible normalized load is zero. |
751 | |
752 | \note There are two points on the graph: (mMinNormalisedLoad, mMinNormalisedFilteredLoad) and (mMaxNormalisedLoad, mMaxFilteredNormalisedLoad). |
753 | |
754 | \note Normalized loads less than mMinNormalisedLoad have filtered normalized load = mMinNormalisedFilteredLoad. |
755 | |
756 | \note Normalized loads greater than mMaxNormalisedLoad have filtered normalized load = mMaxFilteredNormalisedLoad. |
757 | |
758 | \note Normalized loads in-between are linearly interpolated between mMinNormalisedFilteredLoad and mMaxFilteredNormalisedLoad. |
759 | |
760 | \note The tire load applied as input to the tire force computation is the filtered normalized load multiplied by the rest load. |
761 | */ |
762 | class PxVehicleTireLoadFilterData |
763 | { |
764 | public: |
765 | |
766 | friend class PxVehicleWheelsSimData; |
767 | |
768 | PxVehicleTireLoadFilterData() |
769 | : mMinNormalisedLoad(0), |
770 | mMinFilteredNormalisedLoad(0.2308f), |
771 | mMaxNormalisedLoad(3.0f), |
772 | mMaxFilteredNormalisedLoad(3.0f) |
773 | { |
774 | mDenominator=1.0f/(mMaxNormalisedLoad - mMinNormalisedLoad); |
775 | } |
776 | |
777 | /** |
778 | \brief Graph point (mMinNormalisedLoad,mMinFilteredNormalisedLoad) |
779 | */ |
780 | PxReal mMinNormalisedLoad; |
781 | |
782 | /** |
783 | \brief Graph point (mMinNormalisedLoad,mMinFilteredNormalisedLoad) |
784 | */ |
785 | PxReal mMinFilteredNormalisedLoad; |
786 | |
787 | /** |
788 | \brief Graph point (mMaxNormalisedLoad,mMaxFilteredNormalisedLoad) |
789 | */ |
790 | PxReal mMaxNormalisedLoad; |
791 | |
792 | /** |
793 | \brief Graph point (mMaxNormalisedLoad,mMaxFilteredNormalisedLoad) |
794 | */ |
795 | PxReal mMaxFilteredNormalisedLoad; |
796 | |
797 | PX_FORCE_INLINE PxReal getDenominator() const {return mDenominator;} |
798 | |
799 | private: |
800 | |
801 | /** |
802 | \brief Not necessary to set this value. |
803 | */ |
804 | //1.0f/(mMaxNormalisedLoad-mMinNormalisedLoad) for quick calculations |
805 | PxReal mDenominator; |
806 | |
807 | PxU32 mPad[3]; |
808 | |
809 | bool isValid() const; |
810 | |
811 | //serialization |
812 | public: |
813 | PxVehicleTireLoadFilterData(const PxEMPTY) {} |
814 | //~serialization |
815 | }; |
816 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleTireLoadFilterData)& 0x0f)); |
817 | |
818 | class PxVehicleWheelData |
819 | { |
820 | public: |
821 | |
822 | friend class PxVehicleWheels4SimData; |
823 | |
824 | PxVehicleWheelData() |
825 | : mRadius(0.0f), //Must be filled out |
826 | mWidth(0.0f), |
827 | mMass(20.0f), |
828 | mMOI(0.0f), //Must be filled out |
829 | mDampingRate(0.25f), |
830 | mMaxBrakeTorque(1500.0f), |
831 | mMaxHandBrakeTorque(0.0f), |
832 | mMaxSteer(0.0f), |
833 | mToeAngle(0.0f), |
834 | mRecipRadius(0.0f), //Must be filled out |
835 | mRecipMOI(0.0f) //Must be filled out |
836 | { |
837 | } |
838 | |
839 | /** |
840 | \brief Radius of unit that includes metal wheel plus rubber tire. |
841 | |
842 | \note Specified in metres (m). |
843 | |
844 | <b>Range:</b> [0, PX_MAX_F32)<br> |
845 | */ |
846 | PxReal mRadius; |
847 | |
848 | /** |
849 | \brief Maximum width of unit that includes wheel plus tire. |
850 | |
851 | \note Specified in metres (m). |
852 | |
853 | <b>Range:</b> [0, PX_MAX_F32)<br> |
854 | */ |
855 | PxReal mWidth; |
856 | |
857 | /** |
858 | \brief Mass of unit that includes wheel plus tire. |
859 | |
860 | \note Specified in kilograms (kg). |
861 | |
862 | <b>Range:</b> [0, PX_MAX_F32)<br> |
863 | */ |
864 | PxReal mMass; |
865 | |
866 | /** |
867 | \brief Moment of inertia of unit that includes wheel plus tire about the rolling axis. |
868 | |
869 | \note Specified in kilograms metres-squared (kg m^2). |
870 | |
871 | <b>Range:</b> [0, PX_MAX_F32)<br> |
872 | */ |
873 | PxReal mMOI; |
874 | |
875 | /** |
876 | \brief Damping rate applied to wheel. |
877 | |
878 | \note Specified in kilograms metres-squared per second (kg m^2 s^-1). |
879 | |
880 | <b>Range:</b> [0, PX_MAX_F32)<br> |
881 | */ |
882 | PxReal mDampingRate; |
883 | |
884 | /** |
885 | \brief Max brake torque that can be applied to wheel. |
886 | |
887 | \note Specified in kilograms metres-squared per second-squared (kg m^2 s^-2) |
888 | |
889 | <b>Range:</b> [0, PX_MAX_F32)<br> |
890 | */ |
891 | PxReal mMaxBrakeTorque; |
892 | |
893 | /** |
894 | \brief Max handbrake torque that can be applied to wheel. |
895 | |
896 | \note Specified in kilograms metres-squared per second-squared (kg m^2 s^-2) |
897 | |
898 | <b>Range:</b> [0, PX_MAX_F32)<br> |
899 | */ |
900 | PxReal mMaxHandBrakeTorque; |
901 | |
902 | /** |
903 | \brief Max steer angle that can be achieved by the wheel. |
904 | |
905 | \note Specified in radians. |
906 | |
907 | <b>Range:</b> [0, PX_MAX_F32)<br> |
908 | */ |
909 | PxReal mMaxSteer; |
910 | |
911 | /** |
912 | \brief Wheel toe angle. This value is ignored by PxVehicleDriveTank and PxVehicleNoDrive. |
913 | |
914 | \note Specified in radians. |
915 | |
916 | <b>Range:</b> [0, Pi/2]<br> |
917 | */ |
918 | PxReal mToeAngle;//in radians |
919 | |
920 | /** |
921 | \brief Return value equal to 1.0f/mRadius |
922 | |
923 | @see PxVehicleWheelsSimData::setWheelData |
924 | */ |
925 | PX_FORCE_INLINE PxReal getRecipRadius() const {return mRecipRadius;} |
926 | |
927 | /** |
928 | \brief Return value equal to 1.0f/mRecipMOI |
929 | |
930 | @see PxVehicleWheelsSimData::setWheelData |
931 | */ |
932 | PX_FORCE_INLINE PxReal getRecipMOI() const {return mRecipMOI;} |
933 | |
934 | private: |
935 | |
936 | /** |
937 | \brief Reciprocal of radius of unit that includes metal wheel plus rubber tire. |
938 | |
939 | \note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setWheelData |
940 | |
941 | <b>Range:</b> [0, PX_MAX_F32)<br> |
942 | */ |
943 | PxReal mRecipRadius; |
944 | |
945 | /** |
946 | \brief Reciprocal of moment of inertia of unit that includes wheel plus tire about single allowed axis of rotation. |
947 | |
948 | \note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setWheelData |
949 | |
950 | <b>Range:</b> [0, PX_MAX_F32)<br> |
951 | */ |
952 | PxReal mRecipMOI; |
953 | |
954 | PxReal mPad[1]; |
955 | |
956 | bool isValid() const; |
957 | }; |
958 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleWheelData)& 0x0f)); |
959 | |
960 | class PxVehicleSuspensionData |
961 | { |
962 | public: |
963 | |
964 | friend class PxVehicleWheels4SimData; |
965 | |
966 | PxVehicleSuspensionData() |
967 | : mSpringStrength(0.0f), |
968 | mSpringDamperRate(0.0f), |
969 | mMaxCompression(0.3f), |
970 | mMaxDroop(0.1f), |
971 | mSprungMass(0.0f), |
972 | mCamberAtRest(0.0f), |
973 | mCamberAtMaxCompression(0.0f), |
974 | mCamberAtMaxDroop(0.0f), |
975 | mRecipMaxCompression(1.0f), |
976 | mRecipMaxDroop(1.0f) |
977 | { |
978 | } |
979 | |
980 | /** |
981 | \brief Spring strength of suspension unit. |
982 | |
983 | \note Specified in kilograms per second-squared (kg s^-2). |
984 | |
985 | <b>Range:</b> [0, PX_MAX_F32)<br> |
986 | */ |
987 | PxReal mSpringStrength; |
988 | |
989 | /** |
990 | \brief Spring damper rate of suspension unit. |
991 | |
992 | \note Specified in kilograms per second (kg s^-1). |
993 | |
994 | <b>Range:</b> [0, PX_MAX_F32)<br> |
995 | */ |
996 | PxReal mSpringDamperRate; |
997 | |
998 | /** |
999 | \brief Maximum compression allowed by suspension spring. |
1000 | |
1001 | \note Specified in metres (m). |
1002 | |
1003 | <b>Range:</b> [0, PX_MAX_F32)<br> |
1004 | */ |
1005 | PxReal mMaxCompression; |
1006 | |
1007 | /** |
1008 | \brief Maximum elongation allowed by suspension spring. |
1009 | |
1010 | \note Specified in metres (m). |
1011 | |
1012 | <b>Range:</b> [0, PX_MAX_F32)<br> |
1013 | */ |
1014 | PxReal mMaxDroop; |
1015 | |
1016 | /** |
1017 | \brief Mass of vehicle that is supported by suspension spring. |
1018 | |
1019 | \note Specified in kilograms (kg). |
1020 | |
1021 | \note Each suspension is guaranteed to generate an upwards force of |gravity|*mSprungMass along the suspension direction when the wheel is perfectly |
1022 | at rest and sitting at the rest pose defined by the wheel centre offset. |
1023 | |
1024 | \note The sum of the sprung masses of all suspensions of a vehicle should match the mass of the PxRigidDynamic associated with the vehicle. |
1025 | When this condition is satisfied for a vehicle on a horizontal plane the wheels of the vehicle are guaranteed to sit at the rest pose |
1026 | defined by the wheel centre offset. The mass matching condition is not enforced. |
1027 | |
1028 | \note As the wheel compresses or elongates along the suspension direction the force generated by the spring is |
1029 | F = |gravity|*mSprungMass + deltaX*mSpringStrength + deltaXDot*mSpringDamperRate |
1030 | where deltaX is the deviation from the defined rest pose and deltaXDot is the velocity of the sprung mass along the suspension direction. |
1031 | In practice, deltaXDot is computed by comparing the current and previous deviation from the rest pose and dividing the difference |
1032 | by the simulation timestep. |
1033 | |
1034 | \note If a single suspension spring is hanging in the air and generates zero force the remaining springs of the vehicle will necessarily |
1035 | sit in a compressed configuration. In summary, the sum of the remaining suspension forces cannot balance the downwards gravitational force |
1036 | acting on the vehicle without extra force arising from the deltaX*mSpringStrength force term. |
1037 | |
1038 | \note Theoretically, a suspension spring should generate zero force at maximum elongation and increase linearly as the suspension approaches the rest pose. |
1039 | PxVehicleSuspensionData will only enforce this physical law if the spring is configured so that |gravity|*mSprungMass == mMaxDroop*mSpringStrength. |
1040 | To help decouple vehicle handling from visual wheel positioning this condition is not enforced. |
1041 | In practice, the value of |gravity|*mSprungMass + deltaX*mSpringStrength is clamped at zero to ensure it never falls negative. |
1042 | |
1043 | @see PxVehicleComputeSprungMasses, PxVehicleWheelsSimData::setWheelCentreOffset, PxVehicleSuspensionData::mSpringStrength, PxVehicleSuspensionData::mSpringDamperRate, PxVehicleSuspensionData::mMaxDroop |
1044 | |
1045 | <b>Range:</b> [0, PX_MAX_F32)<br> |
1046 | */ |
1047 | PxReal mSprungMass; |
1048 | |
1049 | /** |
1050 | \brief Camber angle (in radians) of wheel when the suspension is at its rest position. |
1051 | |
1052 | \note Specified in radians. |
1053 | |
1054 | <b>Range:</b> [-pi/2, pi/2]<br> |
1055 | |
1056 | */ |
1057 | PxReal mCamberAtRest; |
1058 | |
1059 | /** |
1060 | \brief Camber angle (in radians) of wheel when the suspension is at maximum compression. |
1061 | |
1062 | \note For compressed suspensions the camber angle is a linear interpolation of |
1063 | mCamberAngleAtRest and mCamberAtMaxCompression |
1064 | |
1065 | \note Specified in radians. |
1066 | |
1067 | <b>Range:</b> [-pi/2, pi/2]<br> |
1068 | */ |
1069 | PxReal mCamberAtMaxCompression; |
1070 | |
1071 | /** |
1072 | \brief Camber angle (in radians) of wheel when the suspension is at maximum droop. |
1073 | |
1074 | \note For extended suspensions the camber angle is linearly interpolation of |
1075 | mCamberAngleAtRest and mCamberAtMaxDroop |
1076 | |
1077 | \note Specified in radians. |
1078 | |
1079 | <b>Range:</b> [-pi/2, pi/2]<br> |
1080 | */ |
1081 | PxReal mCamberAtMaxDroop; |
1082 | |
1083 | /** |
1084 | \brief Reciprocal of maximum compression. |
1085 | |
1086 | \note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setSuspensionData |
1087 | |
1088 | <b>Range:</b> [0, PX_MAX_F32)<br> |
1089 | */ |
1090 | PX_FORCE_INLINE PxReal getRecipMaxCompression() const {return mRecipMaxCompression;} |
1091 | |
1092 | /** |
1093 | \brief Reciprocal of maximum droop. |
1094 | |
1095 | \note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setSuspensionData |
1096 | |
1097 | <b>Range:</b> [0, PX_MAX_F32)<br> |
1098 | */ |
1099 | PX_FORCE_INLINE PxReal getRecipMaxDroop() const {return mRecipMaxDroop;} |
1100 | |
1101 | /** |
1102 | \brief Set a new sprung mass for the suspension and modify the spring strength so that the natural frequency |
1103 | of the spring is preserved. |
1104 | \param[in] newSprungMass is the new mass that the suspension spring will support. |
1105 | */ |
1106 | void setMassAndPreserveNaturalFrequency(const PxReal newSprungMass) |
1107 | { |
1108 | const PxF32 oldStrength = mSpringStrength; |
1109 | const PxF32 oldSprungMass = mSprungMass; |
1110 | const PxF32 newStrength = oldStrength * (newSprungMass / oldSprungMass); |
1111 | mSpringStrength = newStrength; |
1112 | mSprungMass = newSprungMass; |
1113 | } |
1114 | |
1115 | private: |
1116 | |
1117 | /** |
1118 | \brief Cached value of 1.0f/mMaxCompression |
1119 | |
1120 | \note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setSuspensionData |
1121 | */ |
1122 | PxReal mRecipMaxCompression; |
1123 | |
1124 | /** |
1125 | \brief Cached value of 1.0f/mMaxDroop |
1126 | |
1127 | \note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setSuspensionData |
1128 | */ |
1129 | PxReal mRecipMaxDroop; |
1130 | |
1131 | //padding |
1132 | PxReal mPad[2]; |
1133 | |
1134 | bool isValid() const; |
1135 | }; |
1136 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleSuspensionData)& 0x0f)); |
1137 | |
1138 | class PxVehicleAntiRollBarData |
1139 | { |
1140 | public: |
1141 | |
1142 | friend class PxVehicleWheelsSimData; |
1143 | |
1144 | PxVehicleAntiRollBarData() |
1145 | : mWheel0(0xffffffff), |
1146 | mWheel1(0xffffffff), |
1147 | mStiffness(0.0f) |
1148 | { |
1149 | } |
1150 | |
1151 | /* |
1152 | \brief The anti-roll bar connects two wheels with indices mWheel0 and mWheel1 |
1153 | */ |
1154 | PxU32 mWheel0; |
1155 | |
1156 | /* |
1157 | \brief The anti-roll bar connects two wheels with indices mWheel0 and mWheel1 |
1158 | */ |
1159 | PxU32 mWheel1; |
1160 | |
1161 | /* |
1162 | \brief The stiffness of the anti-roll bar. |
1163 | |
1164 | \note Specified in kilograms per second-squared (kg s^-2). |
1165 | |
1166 | <b>Range:</b> [0, PX_MAX_F32)<br> |
1167 | */ |
1168 | PxF32 mStiffness; |
1169 | |
1170 | private: |
1171 | |
1172 | PxF32 mPad[1]; |
1173 | |
1174 | bool isValid() const; |
1175 | }; |
1176 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleAntiRollBarData)& 0x0f)); |
1177 | |
1178 | class PxVehicleTireData |
1179 | { |
1180 | public: |
1181 | friend class PxVehicleWheels4SimData; |
1182 | |
1183 | PxVehicleTireData() |
1184 | : mLatStiffX(2.0f), |
1185 | mLatStiffY(0.3125f*(180.0f / PxPi)), |
1186 | mLongitudinalStiffnessPerUnitGravity(1000.0f), |
1187 | mCamberStiffnessPerUnitGravity(0.1f*(180.0f / PxPi)), |
1188 | mType(0) |
1189 | { |
1190 | mFrictionVsSlipGraph[0][0]=0.0f; |
1191 | mFrictionVsSlipGraph[0][1]=1.0f; |
1192 | mFrictionVsSlipGraph[1][0]=0.1f; |
1193 | mFrictionVsSlipGraph[1][1]=1.0f; |
1194 | mFrictionVsSlipGraph[2][0]=1.0f; |
1195 | mFrictionVsSlipGraph[2][1]=1.0f; |
1196 | |
1197 | mRecipLongitudinalStiffnessPerUnitGravity=1.0f/mLongitudinalStiffnessPerUnitGravity; |
1198 | |
1199 | mFrictionVsSlipGraphRecipx1Minusx0=1.0f/(mFrictionVsSlipGraph[1][0]-mFrictionVsSlipGraph[0][0]); |
1200 | mFrictionVsSlipGraphRecipx2Minusx1=1.0f/(mFrictionVsSlipGraph[2][0]-mFrictionVsSlipGraph[1][0]); |
1201 | } |
1202 | |
1203 | /** |
1204 | \brief Tire lateral stiffness is a graph of tire load that has linear behavior near zero load and |
1205 | flattens at large loads. mLatStiffX describes the minimum normalized load (load/restLoad) that gives a |
1206 | flat lateral stiffness response to load. |
1207 | |
1208 | <b>Range:</b> [0, PX_MAX_F32)<br> |
1209 | */ |
1210 | PxReal mLatStiffX; |
1211 | |
1212 | /** |
1213 | \brief Tire lateral stiffness is a graph of tire load that has linear behavior near zero load and |
1214 | flattens at large loads. mLatStiffY describes the maximum possible value of lateralStiffness/restLoad that occurs |
1215 | when (load/restLoad)>= mLatStiffX. |
1216 | |
1217 | \note If load/restLoad is greater than mLatStiffX then the lateral stiffness is mLatStiffY*restLoad. |
1218 | |
1219 | \note If load/restLoad is less than mLatStiffX then the lateral stiffness is mLastStiffY*(load/mLatStiffX) |
1220 | |
1221 | \note Lateral force can be approximated as lateralStiffness * lateralSlip. |
1222 | |
1223 | \note Specified in per radian. |
1224 | |
1225 | <b>Range:</b> [0, PX_MAX_F32)<br> |
1226 | */ |
1227 | PxReal mLatStiffY; |
1228 | |
1229 | /** |
1230 | \brief Tire Longitudinal stiffness per unit gravitational acceleration. |
1231 | |
1232 | \note Longitudinal stiffness of the tire is calculated as gravitationalAcceleration*mLongitudinalStiffnessPerUnitGravity. |
1233 | |
1234 | \note Longitudinal force can be approximated as gravitationalAcceleration*mLongitudinalStiffnessPerUnitGravity*longitudinalSlip. |
1235 | |
1236 | \note Specified in kilograms per radian. |
1237 | |
1238 | <b>Range:</b> [0, PX_MAX_F32)<br> |
1239 | */ |
1240 | PxReal mLongitudinalStiffnessPerUnitGravity; |
1241 | |
1242 | /** |
1243 | \brief tire Tire camber stiffness per unity gravitational acceleration. |
1244 | |
1245 | \note Camber stiffness of the tire is calculated as gravitationalAcceleration*mCamberStiffnessPerUnitGravity |
1246 | |
1247 | \note Camber force can be approximated as gravitationalAcceleration*mCamberStiffnessPerUnitGravity*camberAngle. |
1248 | |
1249 | \note Specified in kilograms per radian. |
1250 | |
1251 | <b>Range:</b> [0, PX_MAX_F32)<br> |
1252 | */ |
1253 | PxReal mCamberStiffnessPerUnitGravity; |
1254 | |
1255 | /** |
1256 | \brief Graph of friction vs longitudinal slip with 3 points. |
1257 | |
1258 | \note mFrictionVsSlipGraph[0][0] is always zero. |
1259 | |
1260 | \note mFrictionVsSlipGraph[0][1] is the friction available at zero longitudinal slip. |
1261 | |
1262 | \note mFrictionVsSlipGraph[1][0] is the value of longitudinal slip with maximum friction. |
1263 | |
1264 | \note mFrictionVsSlipGraph[1][1] is the maximum friction. |
1265 | |
1266 | \note mFrictionVsSlipGraph[2][0] is the end point of the graph. |
1267 | |
1268 | \note mFrictionVsSlipGraph[2][1] is the value of friction for slips greater than mFrictionVsSlipGraph[2][0]. |
1269 | |
1270 | \note The friction value computed from the friction vs longitudinal slip graph is used to scale the friction |
1271 | value for the combination of material and tire type (PxVehicleDrivableSurfaceToTireFrictionPairs). |
1272 | |
1273 | \note mFrictionVsSlipGraph[2][0] > mFrictionVsSlipGraph[1][0] > mFrictionVsSlipGraph[0][0] |
1274 | |
1275 | \note mFrictionVsSlipGraph[1][1] is typically greater than mFrictionVsSlipGraph[0][1] |
1276 | |
1277 | \note mFrictionVsSlipGraph[2][1] is typically smaller than mFrictionVsSlipGraph[1][1] |
1278 | |
1279 | \note longitudinal slips > mFrictionVsSlipGraph[2][0] use friction multiplier mFrictionVsSlipGraph[2][1] |
1280 | |
1281 | \note The final friction value used by the tire model is the value returned by PxVehicleDrivableSurfaceToTireFrictionPairs |
1282 | multiplied by the value computed from mFrictionVsSlipGraph. |
1283 | |
1284 | @see PxVehicleDrivableSurfaceToTireFrictionPairs, PxVehicleComputeTireForce |
1285 | |
1286 | <b>Range:</b> [0, PX_MAX_F32)<br> |
1287 | */ |
1288 | PxReal mFrictionVsSlipGraph[3][2]; |
1289 | |
1290 | /** |
1291 | \brief Tire type denoting slicks, wets, snow, winter, summer, all-terrain, mud etc. |
1292 | |
1293 | @see PxVehicleDrivableSurfaceToTireFrictionPairs |
1294 | |
1295 | <b>Range:</b> [0, PX_MAX_F32)<br> |
1296 | */ |
1297 | PxU32 mType; |
1298 | |
1299 | /** |
1300 | \brief Return Cached value of 1.0/mLongitudinalStiffnessPerUnitGravity |
1301 | |
1302 | @see PxVehicleWheelsSimData::setTireData |
1303 | */ |
1304 | PX_FORCE_INLINE PxReal getRecipLongitudinalStiffnessPerUnitGravity() const {return mRecipLongitudinalStiffnessPerUnitGravity;} |
1305 | |
1306 | /** |
1307 | \brief Return Cached value of 1.0f/(mFrictionVsSlipGraph[1][0]-mFrictionVsSlipGraph[0][0]) |
1308 | |
1309 | @see PxVehicleWheelsSimData::setTireData |
1310 | */ |
1311 | PX_FORCE_INLINE PxReal getFrictionVsSlipGraphRecipx1Minusx0() const {return mFrictionVsSlipGraphRecipx1Minusx0;} |
1312 | |
1313 | /** |
1314 | \brief Return Cached value of 1.0f/(mFrictionVsSlipGraph[2][0]-mFrictionVsSlipGraph[1][0]) |
1315 | |
1316 | @see PxVehicleWheelsSimData::setTireData |
1317 | */ |
1318 | PX_FORCE_INLINE PxReal getFrictionVsSlipGraphRecipx2Minusx1() const {return mFrictionVsSlipGraphRecipx2Minusx1;} |
1319 | |
1320 | private: |
1321 | |
1322 | /** |
1323 | \brief Cached value of 1.0/mLongitudinalStiffnessPerUnitGravity. |
1324 | |
1325 | \note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setTireData |
1326 | |
1327 | @see PxVehicleWheelsSimData::setTireData |
1328 | */ |
1329 | PxReal mRecipLongitudinalStiffnessPerUnitGravity; |
1330 | |
1331 | /** |
1332 | \brief Cached value of 1.0f/(mFrictionVsSlipGraph[1][0]-mFrictionVsSlipGraph[0][0]) |
1333 | |
1334 | \note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setTireData |
1335 | |
1336 | @see PxVehicleWheelsSimData::setTireData |
1337 | */ |
1338 | PxReal mFrictionVsSlipGraphRecipx1Minusx0; |
1339 | |
1340 | /** |
1341 | \brief Cached value of 1.0f/(mFrictionVsSlipGraph[2][0]-mFrictionVsSlipGraph[1][0]) |
1342 | |
1343 | \note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setTireData |
1344 | |
1345 | @see PxVehicleWheelsSimData::setTireData |
1346 | */ |
1347 | PxReal mFrictionVsSlipGraphRecipx2Minusx1; |
1348 | |
1349 | PxReal mPad[2]; |
1350 | |
1351 | bool isValid() const; |
1352 | }; |
1353 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleTireData)& 0x0f)); |
1354 | #if !PX_DOXYGEN |
1355 | } // namespace physx |
1356 | #endif |
1357 | |
1358 | /** @} */ |
1359 | #endif //PX_VEHICLE_CORE_COMPONENTS_H |
1360 | |