In een tooltje wil ik de g-krachten visualiseren van een voertuig. De relevante data die ik tot mijn beschikking heb, zijn de coördinaten, de tijdsduur tussen het vastleggen van de coördinaten, de snelheden van het object zelf en de rotatiesnelheden van het object.
Mijn huidige manier om dit voor elkaar te krijgen is door 3 punten te pakken, daartussen de hoek van te pakken. Zodoende heb ik de hoeksnelheid van het object, dit vermenigvuldigd met de absolute snelheid zorgt ervoor dat ik de versnelling in ms^2 heb. (ω·v)
Echter zorgt deze manier voor erg veel ruis in mijn data. Het gemiddelde van al die punten geeft wel een degelijk resultaat, maar ik heb toch het idee dat ik niet de goede data gebruik, of dat er ergens een fout zit.
Helper-functies:
Buiten ω·v zou ik niet echt weten welke data van toepassing is. De rotatiesnelheid van het voertuig zelf (om de eigen as) kan ik niet gebruiken - dan zouden de nummers bij een slip niet kloppen. Kan iemand helpen?
Mijn huidige manier om dit voor elkaar te krijgen is door 3 punten te pakken, daartussen de hoek van te pakken. Zodoende heb ik de hoeksnelheid van het object, dit vermenigvuldigd met de absolute snelheid zorgt ervoor dat ik de versnelling in ms^2 heb. (ω·v)
Echter zorgt deze manier voor erg veel ruis in mijn data. Het gemiddelde van al die punten geeft wel een degelijk resultaat, maar ik heb toch het idee dat ik niet de goede data gebruik, of dat er ergens een fout zit.
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| // Vector3: Heeft een .x, .y en .z. // De x-as is in de breedte van het voertuig, rechts positief // De y-as is in de lengte van het voertuig, vooruit positief // Functies volledig met hoofdletters komen uit de applicatie. // std::vector<Vector3> LastCoords(3); void onTick() { Vector3 accel = g_vehData.mAcceleration; Vector3 absPos = ENTITY::GET_ENTITY_COORDS(g_playerVehicle, true); LastCoords.push_back(absPos); while (LastCoords.size() > 3) { LastCoords.erase(LastCoords.begin()); } float worldSpeed = Length(g_vehData.mVelocity); float worldRotVel = GetAngleBetween(LastCoords[1] - LastCoords[0], LastCoords[2] - LastCoords[1]) / MISC::GET_FRAME_TIME(); if (isnan(worldRotVel)) { worldRotVel = PrevRotVel; } PrevRotVel = worldRotVel; float GForceX = (accel.x + worldSpeed * worldRotVel) / 9.81f; float GForceY = accel.y / 9.81f; UI::ShowText(locX + 0.100f, locY - 0.075f, 0.5f, fmt::format("LAT: {:.2f} g", GForceX)); UI::ShowText(locX + 0.100f, locY + 0.025f, 0.5f, fmt::format("LON: {:.2f} g", GForceY)); } |
Helper-functies:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| template <typename Vector3T> auto Dot(Vector3T a, Vector3T b) { return a.x * b.x + a.y * b.y + a.z * b.z; } template <typename Vector3T> Vector3T Cross(Vector3T left, Vector3T right) { Vector3T result{}; result.x = left.y * right.z - left.z * right.y; result.y = left.z * right.x - left.x * right.z; result.z = left.x * right.y - left.y * right.x; return result; } template <typename Vector3T> auto GetAngleBetween(Vector3T a, Vector3T b) { Vector3T normal{}; normal.z = static_cast < decltype(a.x) >(1.0); auto angle = acos(Dot(a, b) / (Length(a) * Length(b))); if (Dot(normal, Cross(a, b)) < 0.0) angle = -angle; return angle; } |
Buiten ω·v zou ik niet echt weten welke data van toepassing is. De rotatiesnelheid van het voertuig zelf (om de eigen as) kan ik niet gebruiken - dan zouden de nummers bij een slip niet kloppen. Kan iemand helpen?