[go: up one dir, main page]

Menu

[588012]: / body / Engine.cc  Maximize  Restore  History

Download this file

176 lines (160 with data), 5.0 kB

  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// Engine.cc - an engine for the drivetrain.
//
// Copyright (C) 2001--2002 Sam Varner
//
// This file is part of Vamos Automotive Simulator.
//
// Vamos is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vamos is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vamos. If not, see <http://www.gnu.org/licenses/>.
#include "Engine.h"
#include "../geometry/Conversions.h"
#include <iostream>
using namespace Vamos_Geometry;
//* Class Engine
//** Constructor
Vamos_Body::
Engine::Engine (double mass, const Three_Vector& position,
double max_power,
double peak_engine_rpm,
double rpm_limit,
double inertia,
double idle_throttle,
double start_speed,
double stall_speed,
double fuel_consumption,
const Frame* parent)
: Particle (mass, position, parent),
m_max_power (max_power),
m_peak_engine_speed (rpm_to_rad_s (peak_engine_rpm)),
m_engine_speed_limit (rpm_to_rad_s (rpm_limit)),
m_inertia (inertia),
m_idle_throttle (idle_throttle),
m_start_speed (rpm_to_rad_s (start_speed)),
m_stall_speed (rpm_to_rad_s (stall_speed)),
m_fuel_consumption (fuel_consumption),
m_rotational_speed (0.0),
m_gas (0.0),
m_drag (0.0),
m_transmission_speed (0.0),
m_out_of_gas (false),
m_drive_torque (0.0),
m_drive_impulse (0.0),
m_engaged (false),
// See "Motor Vehicle Dynamics" Genta, Section 4.2.2
m_friction (m_max_power / pow (m_peak_engine_speed, 3))
{
}
void Vamos_Body::
Engine::set_torque_curve (const std::vector <Two_Vector>& torque_points)
{
m_torque_curve.clear ();
m_torque_curve.load (torque_points);
m_torque_curve.scale (rpm_to_rad_s (1.0));
}
// Handle the input parameters. GAS is the throttle position.
// TRANSMISSION_SPEED is the rotational speed of the transmission side
// of the clutch. DRAG is the torque due to friction when the clutch
// is not fully engaged. ENGAGED is true when the clutch is fully
// engaged, false otherwise.
void Vamos_Body::
Engine::input (double gas, double drag, double transmission_speed,
bool engaged)
{
m_gas = gas;
m_drag = drag;
m_transmission_speed = transmission_speed;
m_engaged = engaged;
}
void Vamos_Body::
Engine::find_forces ()
{
// Find the engine's torque with the current conditions.
m_drive_torque = torque_map (m_gas, m_rotational_speed) - m_drag;
set_torque (Three_Vector (-m_drive_torque, 0.0, 0.0));
}
double Vamos_Body::
Engine::power (double gas, double rotational_speed)
{
return rotational_speed * torque_map (gas, rotational_speed);
}
void Vamos_Body::
Engine::propagate (double time)
{
// The engine should change its own speed only when the clutch is
// disengaged. Otherwise, the engine speed is matched to the transmission,
// which changes speed due to the applied engine torque.
m_last_rotational_speed = m_rotational_speed;
// If the clutch is engaged, the engine speed is locked to the
// transmission speed.
if (m_engaged)
{
m_rotational_speed = m_transmission_speed;
}
else
{
m_rotational_speed += time * m_drive_torque / m_inertia;
}
// Keep engine speed from going negative when changing from forward to
// reverse (or vice versa) without using the clutch.
if (m_rotational_speed < m_stall_speed)
{
m_rotational_speed = 0.0;
}
}
void Vamos_Body::
Engine::rewind ()
{
m_rotational_speed = m_last_rotational_speed;
}
// Return the torque for a given throttle setting, GAS, and engine
// speed ROT_SPEED.
double Vamos_Body::
Engine::torque_map (double gas, double rot_speed)
{
if ((m_out_of_gas)
|| (m_rotational_speed < m_stall_speed)
|| (m_rotational_speed > m_engine_speed_limit))
m_gas = 0.0;
else
m_gas = std::max (gas, m_idle_throttle);
if (m_torque_curve.size () == 0)
{
// See "Motor Vehicle Dynamics" Genta, Section 4.2.2
return (m_max_power * m_gas * (1.0 + rot_speed / m_peak_engine_speed)
/ m_peak_engine_speed)
- m_friction * rot_speed * rot_speed;
}
else
{
// Interpolate between the drag curve and the torque curve.
return m_gas * m_torque_curve.interpolate (rot_speed)
- m_friction * rot_speed * rot_speed * (1.0 - m_gas);
}
}
// Set the engine speed to SPEED_IN and calculate the resulting
// impulse.
void Vamos_Body::
Engine::speed (double speed_in)
{
if (speed_in > m_stall_speed)
{
m_rotational_speed = speed_in;
}
else
{
// The engine stalled.
m_rotational_speed = 0.0;
}
// Record the change in angular momentum.
m_drive_impulse = m_inertia * (m_rotational_speed - m_last_rotational_speed);
}