Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
Differentials.cpp
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2005-2012 Pierre-Michel Ricordel
4 Copyright 2007-2012 Thomas Fischer
5
6 For more information, see http://www.rigsofrods.org/
7
8 Rigs of Rods is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 3, as
10 published by the Free Software Foundation.
11
12 Rigs of Rods is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#include "Application.h"
22#include "Differentials.h"
23#include "Language.h"
24
25using namespace RoR;
26
28{
29 if (m_available_diffs.size() > 1)
30 {
31 std::rotate(m_available_diffs.begin(), m_available_diffs.begin() + 1, m_available_diffs.end());
32 }
33}
34
36{
37 if (m_available_diffs.empty())
38 return;
39
40 switch (m_available_diffs[0])
41 {
42 case SPLIT_DIFF: this->CalcSeparateDiff(diff_data); return;
43 case OPEN_DIFF: this->CalcOpenDiff(diff_data); return;
44 case VISCOUS_DIFF: this->CalcViscousDiff(diff_data); return;
45 case LOCKED_DIFF: this->CalcLockedDiff(diff_data); return;
46 }
47}
48
50{
51 if (m_available_diffs.empty())
52 return _L("invalid");
53
54 switch (m_available_diffs[0])
55 {
56 case SPLIT_DIFF: return _L("Split");
57 case OPEN_DIFF: return _L("Open");
58 case VISCOUS_DIFF: return _L("Viscous");
59 case LOCKED_DIFF: return _L("Locked");
60 default: return _L("invalid");
61 }
62}
63
65{
66 diff_data.out_torque[0] = diff_data.out_torque[1] = diff_data.in_torque / 2.0f;
67}
68
70{
71 /* Open differential calculations *************************
72 * These calculation are surprisingly tricky
73 * the power ratio is based on normalizing the speed of the
74 * wheel. Normalizing is when the sum of all values equals
75 * one. more detail provided below
76 */
77
78 diff_data.out_torque[0] = diff_data.out_torque[1] = diff_data.in_torque;
79
80 // combined total velocity
81 const Ogre::Real sum_of_vel = fabs(diff_data.speed[0]) + fabs(diff_data.speed[1]);
82
83 // minimum velocity
84 const Ogre::Real min_of_vel = std::min(fabs(diff_data.speed[0]), fabs(diff_data.speed[1]));
85
86 // normalize the wheel speed, at a speed of 0 power is split evenly
87 const Ogre::Real power_ratio = min_of_vel > 1.0f ? fabs(diff_data.speed[0]) / sum_of_vel : 0.5f;
88
89 // Diff model taken from Torcs, ror needs to model reaction torque for this to work.
90 //DrTq0 = DrTq*0.5f + spiderTq;
91 //DrTq1 = DrTq*0.5f - spiderTq;
92
93 // get the final ratio based on the speed of the wheels
94 diff_data.out_torque[0] *= Ogre::Math::Clamp(0.0f + power_ratio, 0.1f, 0.9f);
95 diff_data.out_torque[1] *= Ogre::Math::Clamp(1.0f - power_ratio, 0.1f, 0.9f);
96}
97
99{
100 /* Viscous axle calculation ********************************
101 * Two wheels are joined together by a rotary viscous coupling.
102 * The viscous liquid counteracts speed differences in the
103 * coupling.
104 */
105
106 const Ogre::Real m_torsion_damp = 10000.0f;
107 const Ogre::Real delta_speed = diff_data.speed[0] - diff_data.speed[1];
108
109 diff_data.out_torque[0] = diff_data.out_torque[1] = diff_data.in_torque / 2.0f;
110
111 // damping
112 diff_data.out_torque[0] -= delta_speed * m_torsion_damp;
113
114 // damping
115 diff_data.out_torque[1] += delta_speed * m_torsion_damp;
116}
117
119{
120 /* Locked axle calculation ********************************
121 * This is straight forward, two wheels are joined together
122 * by a torsion spring. the torsion spring keeps the two
123 * wheels in the same orientation as when they were first
124 * locked.
125 */
126
127 // Torsion spring rate that holds axles together when locked
128 // keep as variable for now since this value will be user configurable
129 const Ogre::Real m_torsion_rate = 1000000.0f;
130 const Ogre::Real m_torsion_damp = m_torsion_rate / 100.0f;
131 const Ogre::Real delta_speed = diff_data.speed[0] - diff_data.speed[1];
132
133 diff_data.out_torque[0] = diff_data.out_torque[1] = diff_data.in_torque / 2.0f;
134
135 // derive how far wheels traveled relative to each during the last time step
136 diff_data.delta_rotation += delta_speed * diff_data.dt;
137
138 // torque cause by axle shafts
139 diff_data.out_torque[0] -= diff_data.delta_rotation * m_torsion_rate;
140 // damping
141 diff_data.out_torque[0] -= delta_speed * m_torsion_damp;
142
143 // torque cause by axle shafts
144 diff_data.out_torque[1] += diff_data.delta_rotation * m_torsion_rate;
145 // damping
146 diff_data.out_torque[1] += delta_speed * m_torsion_damp;
147}
Central state/object manager and communications hub.
#define _L
static void CalcLockedDiff(DifferentialData &diff_data)
ensures both wheels rotate at the the same speed
std::vector< DiffType > m_available_diffs
static void CalcSeparateDiff(DifferentialData &diff_data)
a differential that always splits the torque evenly, this is the original method
void CalcAxleTorque(DifferentialData &diff_data)
std::string GetDifferentialTypeName()
static void CalcOpenDiff(DifferentialData &diff_data)
more power goes to the faster spining wheel
static void CalcViscousDiff(DifferentialData &diff_data)
more power goes to the slower spining wheel
@ VISCOUS_DIFF
@ SPLIT_DIFF
@ OPEN_DIFF
@ LOCKED_DIFF