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