Esempio n. 1
0
void CARENGINEINFO::SetTorqueCurve(
	const btScalar redline,
	const std::vector<std::pair<btScalar, btScalar> > & torque)
{
	torque_curve.Clear();

	//this value accounts for the fact that the torque curves are usually measured
	// on a dyno, but we're interested in the actual crankshaft power
	const btScalar dyno_correction_factor = 1.0;//1.14;

	assert(torque.size() > 1);

	//ensure we have a smooth curve down to 0 RPM
	if (torque[0].first != 0) torque_curve.AddPoint(0,0);

	for (std::vector<std::pair<btScalar, btScalar> >::const_iterator i = torque.begin(); i != torque.end(); ++i)
	{
		torque_curve.AddPoint(i->first, i->second * dyno_correction_factor);
	}

	//ensure we have a smooth curve for over-revs
	torque_curve.AddPoint(torque[torque.size()-1].first + 10000, 0);

	//write out a debug torque curve file
	/*std::ofstream f("out.dat");
	for (btScalar i = 0; i < curve[curve.size()-1].first+1000; i+= 20) f << i << " " << torque_curve.Interpolate(i) << std::endl;*/
	//for (unsigned int i = 0; i < curve.size(); i++) f << curve[i].first << " " << curve[i].second << std::endl;

	//calculate engine friction
	btScalar max_power_angvel = redline*3.14153/30.0;
	btScalar max_power = torque_curve.Interpolate(redline) * max_power_angvel;
	friction = max_power / (max_power_angvel*max_power_angvel*max_power_angvel);

	//calculate idle throttle position
	for (idle = 0; idle < 1.0; idle += 0.01)
	{
		if (GetTorque(idle, start_rpm) > -GetFrictionTorque(start_rpm*3.141593/30.0, 1.0, idle))
		{
			//std::cout << "Found idle throttle: " << idle << ", " << GetTorqueCurve(idle, start_rpm) << ", " << friction_torque << std::endl;
			break;
		}
	}
}
Esempio n. 2
0
bool CarEngineInfo::Load(const PTree & cfg, std::ostream & error_output)
{
	std::vector<btScalar> pos(3, 0.0f);
	if (!cfg.get("displacement", displacement, error_output)) return false;
	if (!cfg.get("max-power", maxpower, error_output)) return false;
	if (!cfg.get("peak-engine-rpm", redline, error_output)) return false;
	if (!cfg.get("rpm-limit", rpm_limit, error_output)) return false;
	if (!cfg.get("inertia", inertia, error_output)) return false;
	if (!cfg.get("start-rpm", start_rpm, error_output)) return false;
	if (!cfg.get("stall-rpm", stall_rpm, error_output)) return false;
	if (!cfg.get("position", pos, error_output)) return false;
	if (!cfg.get("mass", mass, error_output)) return false;

	position.setValue(pos[0], pos[1], pos[2]);

	// fuel consumption
	btScalar fuel_heating_value = 4.5E7; // Ws/kg
	btScalar engine_efficiency = 0.35;
	cfg.get("fuel-heating-value", fuel_heating_value);
	cfg.get("efficiency", engine_efficiency);
	fuel_rate = 1 /	(engine_efficiency * fuel_heating_value);

	// nos parameters
	cfg.get("nos-mass", nos_mass);
	cfg.get("nos-boost", nos_boost);
	cfg.get("nos-ratio", nos_fuel_ratio);

	// friction (Heywood 1988 tfmep)
	friction[0] = btScalar(97000 / (4 * M_PI)) * displacement;
	friction[1] = btScalar(15000 / (4 * M_PI)) * displacement;
	friction[2] = btScalar(5000 / (4 * M_PI)) * displacement;
	std::vector<btScalar> f(3, 0);
	if (cfg.get("torque-friction", f))
	{
		friction[0] = f[0];
		friction[1] = f[1];
		friction[2] = f[2];
	}

	// torque
	int curve_num = 0;
	std::vector<btScalar> torque_point(2);
	std::string torque_str("torque-curve-00");
	std::vector<std::pair<btScalar, btScalar> > torque;
	while (cfg.get(torque_str, torque_point))
	{
		torque.push_back(std::pair<btScalar, btScalar>(torque_point[0], torque_point[1]));

		curve_num++;
		std::ostringstream s;
		s << "torque-curve-";
		s.width(2);
		s.fill('0');
		s << curve_num;
		torque_str = s.str();
	}
	if (torque.size() <= 1)
	{
		error_output << "You must define at least 2 torque curve points." << std::endl;
		return false;
	}

	// set torque curve
	torque_curve.Clear();
	if (torque[0].first > stall_rpm)
	{
		btScalar dx = torque[1].first - torque[0].first;
		btScalar dy = torque[1].second - torque[0].second;
		btScalar stall_torque = dy / dx * (stall_rpm - torque[0].first) + torque[0].second;
		torque_curve.AddPoint(stall_rpm,  stall_torque);

		error_output << "Torque curve begins above stall rpm.\n"
			<< "Extrapolating to " << stall_rpm << ", " << stall_torque << std::endl;
	}
	for (const auto & tp : torque)
	{
		torque_curve.AddPoint(tp.first, tp.second);
	}
	if (torque[torque.size() - 1].first < rpm_limit)
	{
		btScalar r = torque[torque.size() - 1].first + 10000.0f;
		btScalar t = 0.0f;
		torque_curve.AddPoint(r , t);

		error_output << "Torque curve ends below rpm limit.\n"
			<< "Extrapolating to " << r << ", " << t << std::endl;
	}

	// calculate idle throttle position
	for (idle_throttle = 0.0f; idle_throttle < 1.0f; idle_throttle += 0.01f)
	{
		if (GetTorque(idle_throttle, start_rpm) > -GetFrictionTorque(idle_throttle, start_rpm))
			break;
	}

	// calculate idle throttle slope
	btScalar stall_throttle;
	for (stall_throttle = idle_throttle; stall_throttle < 1.0f; stall_throttle += 0.01f)
	{
		if (GetTorque(stall_throttle, stall_rpm) > -GetFrictionTorque(stall_throttle, stall_rpm))
			break;
	}
	idle_throttle_slope = 1.5f * (idle_throttle - stall_throttle) / (start_rpm - stall_rpm);

	return true;
}