00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <vamos/body/Engine.h>
00022 #include <vamos/geometry/Conversions.h>
00023 #include <iostream>
00024
00025
00026
00027
00028 Vamos_Body::
00029 Engine::Engine (double mass, const Vamos_Geometry::Three_Vector& position,
00030 double max_power,
00031 double peak_engine_rpm,
00032 double rpm_limit,
00033 double inertia,
00034 double idle_throttle,
00035 double start_speed,
00036 double stall_speed,
00037 double fuel_consumption)
00038 : Particle (mass, position),
00039 m_max_power (max_power),
00040 m_peak_engine_speed (Vamos_Geometry::rpm_to_rad_s (peak_engine_rpm)),
00041 m_engine_speed_limit (Vamos_Geometry::rpm_to_rad_s (rpm_limit)),
00042 m_inertia (inertia),
00043 m_idle_throttle (idle_throttle),
00044 m_start_speed (Vamos_Geometry::rpm_to_rad_s (start_speed)),
00045 m_stall_speed (Vamos_Geometry::rpm_to_rad_s (stall_speed)),
00046 m_fuel_consumption (fuel_consumption),
00047 m_rotational_speed (0.0),
00048 m_gas (0.0),
00049 m_drag (0.0),
00050 m_transmission_speed (0.0),
00051 m_out_of_gas (false),
00052 m_drive_torque (0.0),
00053 m_drive_impulse (0.0),
00054 m_engaged (false),
00055
00056 m_friction (m_max_power / pow (m_peak_engine_speed, 3))
00057 {
00058 }
00059
00060 void Vamos_Body::
00061 Engine::set_torque_curve (const std::vector <Vamos_Geometry::Two_Point>& torque_points)
00062 {
00063 m_torque_curve.clear ();
00064 m_torque_curve.load (torque_points);
00065 m_torque_curve.scale (Vamos_Geometry::rpm_to_rad_s (1.0));
00066
00067
00068 }
00069
00070
00071
00072
00073
00074
00075 void Vamos_Body::
00076 Engine::input (double gas, double drag, double transmission_speed,
00077 bool engaged)
00078 {
00079 m_gas = gas;
00080 m_drag = drag;
00081 m_transmission_speed = transmission_speed;
00082 m_engaged = engaged;
00083 }
00084
00085 void Vamos_Body::
00086 Engine::find_forces ()
00087 {
00088
00089 m_drive_torque = torque_map (m_gas, m_rotational_speed) - m_drag;
00090 m_torque = Vamos_Geometry::Three_Vector (-m_drive_torque, 0.0, 0.0);
00091 }
00092
00093 void Vamos_Body::
00094 Engine::propagate (double time)
00095 {
00096
00097
00098
00099 m_last_rotational_speed = m_rotational_speed;
00100
00101
00102
00103 if (m_engaged)
00104 {
00105 m_rotational_speed = m_transmission_speed;
00106 }
00107 else
00108 {
00109 m_rotational_speed += time * m_drive_torque / m_inertia;
00110 }
00111
00112
00113
00114 if (m_rotational_speed < m_stall_speed)
00115 {
00116 m_rotational_speed = 0.0;
00117 }
00118 }
00119
00120 void Vamos_Body::
00121 Engine::rewind ()
00122 {
00123 m_rotational_speed = m_last_rotational_speed;
00124 }
00125
00126
00127
00128 double Vamos_Body::
00129 Engine::torque_map (double gas, double rot_speed)
00130 {
00131 double idle = m_idle_throttle;
00132 if ((m_out_of_gas) || (m_rotational_speed < m_stall_speed))
00133 {
00134 gas = 0.0;
00135 idle = 0.0;
00136 }
00137 else if (gas < idle)
00138 {
00139 gas = idle;
00140 }
00141 m_gas = gas;
00142
00143 if (m_torque_curve.size () == 0)
00144 {
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 double factor = 1.0 / m_peak_engine_speed;
00159
00160 double torque = -m_max_power * factor * factor * factor
00161 * rot_speed * rot_speed;
00162
00163 if (m_rotational_speed < m_engine_speed_limit)
00164 {
00165 torque += m_max_power * factor * gas * (1.0 + factor * rot_speed);
00166 }
00167
00168 return torque;
00169
00170
00171
00172
00173 }
00174 else
00175 {
00176
00177 double torque = -m_friction * rot_speed * rot_speed * (1 - m_gas);
00178
00179
00180
00181
00182 if (m_rotational_speed < m_engine_speed_limit)
00183 {
00184
00185 double addtorque = m_gas * m_torque_curve.interpolate (rot_speed);
00186 if (addtorque > 0)
00187 torque += addtorque;
00188
00189 }
00190
00191
00192 return torque;
00193
00194
00195
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 }
00211
00212
00213
00214 void Vamos_Body::
00215 Engine::speed (double speed_in)
00216 {
00217 if (speed_in > m_stall_speed)
00218 {
00219 m_rotational_speed = speed_in;
00220 }
00221 else
00222 {
00223
00224 m_rotational_speed = 0.0;
00225 }
00226
00227 m_drive_impulse = m_inertia * (m_rotational_speed - m_last_rotational_speed);
00228 }