1 /***************************************************************************
2 carengine.cpp - Engine + drivetrain of a car
3 -------------------
4 begin : di mrt 8 2005
5 copyright : (C) 2005 by CJP
6 email : cornware-cjp@users.sourceforge.net
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include <cmath>
19
20 #include "carengine.h"
21
CCarEngine()22 CCarEngine::CCarEngine()
23 {
24 m_Gear = 1;
25 m_MainAxisM = 0.0;
26 m_MainAxisW = 0.0;
27 m_Gas = 0.0;
28 }
29
~CCarEngine()30 CCarEngine::~CCarEngine(){
31 }
32
update(float dt,float w1,float w2,float w3,float w4)33 void CCarEngine::update(float dt, float w1, float w2, float w3, float w4)
34 {
35 float currentW = 0.5 * m_FrontTraction * (w1 + w2) + 0.5 * m_RearTraction * (w3 + w4);
36 float factor = exp(-100.0*dt);
37 m_MainAxisW = factor * m_MainAxisW + (1.0-factor) * currentW;
38
39 float MEngine = getEngineM(m_MainAxisW * getGearRatio());
40
41 //fprintf(stderr, "%.f\t%.f\n", m_MainAxisW * getGearRatio(), MEngine);
42
43 MEngine *= m_Gas;
44
45 m_MainAxisM = MEngine * getGearRatio();
46 }
47
getWheelM(unsigned int wheelnr)48 float CCarEngine::getWheelM(unsigned int wheelnr)
49 {
50 if(wheelnr == 0 || wheelnr == 1)
51 return 0.5 * m_FrontTraction * m_MainAxisM;
52
53 if(wheelnr == 2 || wheelnr == 3)
54 return 0.5 * m_RearTraction * m_MainAxisM;
55
56 return 0.0;
57 }
58
getGearRatio(int gear)59 float CCarEngine::getGearRatio(int gear)
60 {
61 if(gear < 0) gear = m_Gear;
62 return m_DifferentialRatio * m_GearRatios[gear];
63 }
64
getEngineM(float wengine)65 float CCarEngine::getEngineM(float wengine)
66 {
67 //Piecewise fit through several points
68
69 float Mengine = 0.0;
70
71 if(wengine < 0.0)
72 {
73 //negative RPMs
74 //TODO: make something more realistic
75 Mengine = m_M0;
76 }
77 else if(wengine < m_w_Mmax)
78 {
79 float wrel = (wengine-m_w_Mmax)/m_w_Mmax;
80 Mengine = m_Mmax - (m_Mmax - m_M0) * wrel*wrel;
81 }
82 else if(wengine < m_w_Pmax)
83 {
84 float dw = m_w_Pmax-m_w_Mmax;
85 float wrel = (wengine-m_w_Mmax)/dw;
86
87 float A = (3 + dw/m_w_Pmax) * m_Pmax / m_w_Pmax - 3*m_Mmax;
88 float B = (2 + dw/m_w_Pmax) * m_Pmax / m_w_Pmax - 2*m_Mmax;
89 Mengine = m_Mmax + A *wrel*wrel - B*wrel*wrel*wrel;
90 }
91 else
92 {
93 float wrel = (wengine - m_w_Pmax) / (m_w_Zero - m_w_Pmax);
94 Mengine = (m_Pmax / m_w_Pmax) * (1.0 - wrel*wrel);
95
96 if(Mengine < -0.1 * m_Mmax) Mengine = -0.1*m_Mmax;
97 }
98
99 return Mengine;
100 }
101