void CustomVehicleControllerComponentEngine::Update (dFloat timestep)
{
	CustomVehicleControllerBodyStateChassis& chassis = m_controller->m_chassisState;
	CustomVehicleControllerComponentEngine::dGearBox* const gearBox = GetGearBox();

	gearBox->Update (timestep);

	int gear = gearBox->GetGear();

#ifdef  __TEST_VEHICLE_XXX__
if (gear > (CustomVehicleControllerComponentEngine::dGearBox::m_firstGear))
{
	gearBox->SetGear (CustomVehicleControllerComponentEngine::dGearBox::m_firstGear);
//	gearBox->SetGear (CustomVehicleControllerComponentEngine::dGearBox::m_reverseGear);
	gear = gearBox->GetGear();
}
#endif

	
	if (m_engineSwitch) {
		if (gear == CustomVehicleControllerComponentEngine::dGearBox::m_newtralGear) {
			dFloat param = dMax (GetParam(), 0.05f);
			m_engineToque = GetTorque (m_engineRPS) * param - m_engineIdleResistance1 * m_engineRPS - m_engineIdleResistance2 * m_engineRPS * m_engineRPS;
			dFloat alpha = m_engineIdleInvInertia * m_engineToque;
			m_engineRPS = dMin (dMax (m_engineRPS + alpha * timestep, 0.0f), m_radiansPerSecundsAtRedLine);
		} else {
			dFloat gearRatio = gearBox->GetGearRatio(gear);
			dFloat shaftOmega = m_differencial->GetShaftOmega();
			m_engineRPS = shaftOmega * gearRatio;
			dFloat torqueResistance = - m_engineInternalFriction * m_engineRPS;

			dFloat param = GetParam();
			dFloat nominalTorque = -GetTorque (dMax (-m_engineRPS, 0.0f)) * param;
			dFloat engineTorque = nominalTorque + torqueResistance;

			m_engineToque = m_engineToque + (engineTorque - m_engineToque) * timestep / m_clutchTorqueCouplingTime;
			dFloat shaftTorque = m_engineToque * gearRatio;
			m_differencial->ApplyTireTorque(shaftTorque, shaftOmega);
		}
	} else {
		m_engineRPS = m_engineRPS * 0.95f;
		if (m_engineRPS < 0.001f) {
			m_engineRPS = 0.0f;
		}
		m_engineToque = 0.0f;
	}

	dVector front (chassis.m_matrix.RotateVector(chassis.m_localFrame[0]));
	m_speedMPS = chassis.m_veloc % front;
}
Beispiel #2
0
/*****************************************************************************
 * Function - RunPeriodFlowCalculationTasks
 * DESCRIPTION:
 *
 *****************************************************************************/
void AdvancedFlowCtrl::RunPeriodFlowCalculationTasks()
{
  float pressure_in_pit = GetPressureInPit();
  float pressure_in_outlet = GetPressureInOutlet();

  // run pit flow calculation
  mpPitFlow->RunPitFlow(pressure_in_pit);

  AFC_RUN_PAR_UPDATE_STRUCT run_par_update_arguments;
  run_par_update_arguments.pressureIn = pressure_in_pit;
  run_par_update_arguments.pressureOut = pressure_in_outlet;

  for (int i = FIRST_PUMP; i <= LAST_PUMP; i++)
  {
    run_par_update_arguments.speed = GetSpeed(i);
    run_par_update_arguments.torque = GetTorque(i);
    run_par_update_arguments.pumpState = mPumpState[i];
    run_par_update_arguments.pumpRampUpPassed = (mAwaitPumpRampUpTime[i] <= 0);
    run_par_update_arguments.trainingState = mTrainingEnabledState[i];

    // run learn and parameter update
    UpdateFlowLearnControl((PUMP_TYPE) i);
    UpdateTrainingFrequency((PUMP_TYPE) i);
    mpParameterIdentifiers[i]->RunParUpdate(&run_par_update_arguments);
  }

  AFC_RUN_SYSTEM_FLOW_STRUCT run_system_flow_arguments;
  run_system_flow_arguments.pitArea = GetPitArea();
  run_system_flow_arguments.pressureIn = pressure_in_pit;
  run_system_flow_arguments.pressureOut = pressure_in_outlet;

  for (int i = FIRST_PUMP; i <= LAST_PUMP; i++)
  {
    run_system_flow_arguments.pump[i].speed = GetSpeed(i);
    run_system_flow_arguments.pump[i].torque = GetTorque(i);
    run_system_flow_arguments.pump[i].pumpState = mPumpState[i];
    run_system_flow_arguments.pump[i].pumpRampUpPassed = (mAwaitPumpRampUpTime[i] <= 0);

    t_calcvar* theta_Q = mpParameterIdentifiers[i]->GetPumpFlowParameters();

    for (int j = 0; j < FLOW_DIM; j++)
    {
      run_system_flow_arguments.pump[i].theta[j] = theta_Q[j];
    }
  }
  // run system flow calculation
  mpSystemFlow->RunSystemFlow(&run_system_flow_arguments);
}
Beispiel #3
0
void M3LoadX1::StepStatus()
{
	if (IsStateError())
		return;
	M3LoadX1EcStatus * ecs = (M3LoadX1EcStatus * )(ecc->GetStatus());
	tq_sense.Step(ecs->adc_torque());
	status.set_torque(tq_sense.GetTorque_mNm());
	status.set_torquedot(torquedot_df.Step(GetTorque()));
}
Beispiel #4
0
 void Ship::GetClientUpdateMessage(ClientShipUpdate& message) const
 {
     message.fired = false; //TODO: implement
     strcpy(message.name, GetName().c_str());
     Vector3f vec = GetForce();
     message.force[0] = vec[0];
     message.force[1] = vec[1];
     message.force[2] = vec[2];
     message.torque = GetTorque();
 }
Beispiel #5
0
void CARENGINE::DebugPrint(std::ostream & out) const
{
	out << "---Engine---" << "\n";
	out << "Throttle position: " << throttle_position << "\n";
	out << "Combustion torque: " << combustion_torque << "\n";
	out << "Clutch torque: " << -clutch_torque << "\n";
	out << "Friction torque: " << friction_torque << "\n";
	out << "Total torque: " << GetTorque() << "\n";
	out << "RPM: " << GetRPM() << "\n";
	out << "Rev limit exceeded: " << rev_limit_exceeded << "\n";
	out << "Running: " << !stalled << "\n";
}
Beispiel #6
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;
		}
	}
}
Beispiel #7
0
void M3Joint::StepCommand()
{
	if (!act || IsStateSafeOp())
		return;
	
	if (IsVersion(IQ) && !ctrl_simple)
		return;
	
	
	if(IsStateError())
	{
		if (IsVersion(IQ))
		ctrl_simple->SetDesiredControlMode(CTRL_MODE_OFF);
		else
		act->SetDesiredControlMode(ACTUATOR_MODE_OFF);
		
		return;
	}
	
	/*tmp_cnt++;
	if (tmp_cnt == 100)
	{
	M3_DEBUG("th_in: %f\n", command.q_desired());
	

	}*/
	
	
	
	if (command.ctrl_mode() == JOINT_MODE_THETA && command.smoothing_mode() == SMOOTHING_MODE_MIN_JERK)
	{
	command.set_ctrl_mode(JOINT_MODE_THETA_MJ);
		
	}
	
	if (command.ctrl_mode() == JOINT_MODE_THETA_GC && command.smoothing_mode() == SMOOTHING_MODE_MIN_JERK)
	{
	command.set_ctrl_mode(JOINT_MODE_THETA_GC_MJ);	  
	}
	
	//Avoid pops
	if (command.ctrl_mode()!=mode_last)
	{
		q_on_slew.Reset(0.0);
		tq_on_slew.Reset(0.0);
		pwm_on_slew.Reset(0.0);
		q_slew.Reset(GetThetaDeg());
		jerk_joint.Startup(GetTimestamp(), GetThetaDeg());
		if (IsVersion(IQ)) 
		tq_switch=GetTorque()*1000;  // TODO: Make GetTorque nNm again
		else
		tq_switch=GetTorque(); 
		q_switch=GetThetaDeg();
		pwm_switch=GetPwmCmd();
		if (IsVersion(IQ)) { 
		ctrl_simple->ResetIntegrators();
		}
	}
	if (IsVersion(IQ)) { 
	if (!act->IsMotorPowerSlewedOn())
	ctrl_simple->ResetIntegrators();	 
	}
	
	
	if (IsVersion(IQ)) { 
	
		ctrl_simple->SetDesiredControlMode(CTRL_MODE_OFF);
		
		switch(command.ctrl_mode())
		{
			
			case JOINT_MODE_THETA:
			case JOINT_MODE_THETA_MJ:
			{
				if (!IsEncoderCalibrated())
				{
				// M3_INFO("Not calib %s\n",GetName().c_str());
				break;
				}
				CalcThetaDesiredSmooth();
				mReal des=trans->GetThetaDesActuatorDeg();
				StepBrake(des,trans->GetThetaActuatorDeg());
				//Do PID in actuator space so result is direct PWM
				//ctrl_simple->SetDesiredControlMode(CTRL_MODE_THETA);
				ctrl_simple->SetDesiredControlMode(CTRL_MODE_THETA);
				ctrl_simple->SetDesiredTheta(DEG2RAD(des));
								
				break;
			}
			case JOINT_MODE_THETA_GC:
			case JOINT_MODE_THETA_GC_MJ:
			case JOINT_MODE_POSE:
			{
				if (!IsEncoderCalibrated())
				break;
				mReal stiffness,gravity,tq_des;
				CalcThetaDesiredSmooth();
				mReal des=trans->GetThetaDesJointDeg();
				StepBrake(des,trans->GetThetaJointDeg());
				//Do PID in joint space
				if (command.ctrl_mode() == JOINT_MODE_POSE)
				{
				tq_des =pid_theta_gc.Step(trans->GetThetaJointDeg(),
						trans->GetThetaDotJointDeg(),
						des,
						0.0,
						0.0,
						param.kq_d_pose(),
						0.0,
						0.0);
				} else {
				tq_des =pid_theta_gc.Step(trans->GetThetaJointDeg(),
						trans->GetThetaDotJointDeg(),
						des,
						param.kq_p(),
						param.kq_i(),
						param.kq_d(),
						param.kq_i_limit(),
						param.kq_i_range());
				}
				/*if (pnt_cnt%200==0) {		
					M3_DEBUG("actuator: %s\n", GetName().c_str());
					M3_DEBUG("tq_des: %f\n",tq_des);
					M3_DEBUG("th: %f -> %f  thdot: %f\n",trans->GetThetaJointDeg(),des,trans->GetThetaDotJointDeg());
					M3_DEBUG("des: %f\n\n",des);
				}*/
				stiffness=CLAMP(command.q_stiffness(),0.0,1.0);
				gravity=GetTorqueGravity()*param.kq_g();
				//Ramp in from torque at switch-over point
				mReal tq_on, tq_out;
				tq_on=tq_on_slew.Step(1.0,1.0/MODE_TQ_ON_SLEW_TIME); 
				//tq_on = 1.0;
				tq_out=tq_on*(stiffness*tq_des-gravity)+(1.0-tq_on)*tq_switch;
				//tq_out = tq_switch;
				//tq_out = stiffness*tq_des-gravity;
				//Send out
				trans->SetTorqueDesJoint(tq_out/1000.0);	//TODO: convert back to mNm	
				
				ctrl_simple->SetDesiredControlMode(CTRL_MODE_TORQUE);
				ctrl_simple->SetDesiredTorque(trans->GetTorqueDesActuator());
				
				break;
			}
			case JOINT_MODE_TORQUE_GC:			
			{
			if (!IsEncoderCalibrated())
				break;
				mReal tq_on, tq_out,gravity;
				mReal tq_des=command.tq_desired();
				StepBrake(tq_des,trans->GetTorqueJoint());
				gravity=GetTorqueGravity()*param.kq_g();
				//Ramp in from torque at switch-over point
				tq_on=tq_on_slew.Step(1.0,1.0/MODE_TQ_ON_SLEW_TIME);
				tq_out=tq_on*(tq_des-gravity)+(1.0-tq_on)*tq_switch;
				//Send out
				/*if (pnt_cnt%200==0) {		
					M3_DEBUG("actuator: %s tq_gravity: %f\n", GetName().c_str(),gravity);
					M3_DEBUG("tq_des: %f tqout_des: %f\n",tq_des,tq_out);
				}*/
				trans->SetTorqueDesJoint(tq_out/1000.0);				
				
				ctrl_simple->SetDesiredControlMode(CTRL_MODE_TORQUE);
				ctrl_simple->SetDesiredTorque(trans->GetTorqueDesActuator());
				
				break;
			}
			
			case JOINT_MODE_THETADOT_GC:			
			{
				if (!IsEncoderCalibrated())
				break;
				mReal stiffness,gravity,tq_des;
				//CalcThetaDesiredSmooth();
				trans->SetThetaDotDesJointDeg(command.qdot_desired());
				mReal des=trans->GetThetaDotDesJointDeg();
				//StepBrake(des,trans->GetThetaDotJointDeg());
				tq_des =pid_thetadot_gc.Step(trans->GetThetaDotJointDeg(),
						trans->GetThetaDotDotJointDeg(),
						des,
						param.kqdot_p(),
						param.kqdot_i(),
						param.kqdot_d(),
						param.kqdot_i_limit(),
						param.kqdot_i_range());
				StepBrake(tq_des,trans->GetTorqueJoint());
				stiffness=CLAMP(command.q_stiffness(),0.0,1.0);
				gravity=GetTorqueGravity()*param.kq_g();
				//Ramp in from torque at switch-over point
				mReal tq_on, tq_out;
				tq_on=tq_on_slew.Step(1.0,1.0/MODE_TQ_ON_SLEW_TIME); 
				tq_out=tq_on*(stiffness*tq_des-gravity)+(1.0-tq_on)*tq_switch;
				//tq_out = tq_switch;
				//tq_out = stiffness*tq_des-gravity;
				//Send out
				/*if (pnt_cnt%200==0) {		
					M3_DEBUG("actuator: %s\n", GetName().c_str());
					M3_DEBUG("tq_des: %f tqout_des: %f v: %f\n",tq_des,tq_out,trans->GetThetaDotJointDeg());
					M3_DEBUG("des: %f Tjoint: %f desac: %f\n\n",des,trans->GetTorqueJoint(),trans->GetTorqueDesActuator());
				}*/
				trans->SetTorqueDesJoint(tq_out/1000.0);	//TODO: convert back to mNm	
				
				ctrl_simple->SetDesiredControlMode(CTRL_MODE_TORQUE);
				ctrl_simple->SetDesiredTorque(trans->GetTorqueDesActuator());
				
				break;
			}

			case JOINT_MODE_THETADOT:			
			{
				if (!IsEncoderCalibrated())
				break;
				mReal stiffness,gravity,tq_des;
				//CalcThetaDesiredSmooth();
				trans->SetThetaDotDesJointDeg(command.qdot_desired());
				mReal des=trans->GetThetaDotDesJointDeg();
				//StepBrake(des,trans->GetThetaDotJointDeg());
				tq_des =pid_thetadot_gc.Step(trans->GetThetaDotJointDeg(),
						trans->GetThetaDotDotJointDeg(),
						des,
						param.kqdot_p(),
						param.kqdot_i(),
						param.kqdot_d(),
						param.kqdot_i_limit(),
						param.kqdot_i_range());
				StepBrake(tq_des,trans->GetTorqueJoint());
				stiffness=CLAMP(command.q_stiffness(),0.0,1.0);
				//Ramp in from torque at switch-over point
				mReal tq_on, tq_out;
				tq_on=tq_on_slew.Step(1.0,1.0/MODE_TQ_ON_SLEW_TIME); 
				tq_out=tq_on*(stiffness*tq_des)+(1.0-tq_on)*tq_switch;
				//Send out
				/*if (pnt_cnt%200==0) {		
					M3_DEBUG("actuator: %s\n", GetName().c_str());
					M3_DEBUG("tq_des: %f tqout_des: %f v: %f\n",tq_des,tq_out,trans->GetThetaDotJointDeg());
					M3_DEBUG("des: %f Tjoint: %f desac: %f\n\n",des,trans->GetTorqueJoint(),trans->GetTorqueDesActuator());
				}*/
				trans->SetTorqueDesJoint(tq_out/1000.0);	//TODO: convert back to mNm	
				
				ctrl_simple->SetDesiredControlMode(CTRL_MODE_TORQUE);
				ctrl_simple->SetDesiredTorque(trans->GetTorqueDesActuator());
				
				break;
			}
			case JOINT_MODE_TORQUE:
			{		  
				mReal tq_on,tq_out;
				//Ramp in from torque at switch-over point
				mReal tq_des=command.tq_desired();
				StepBrake(tq_des,trans->GetTorqueJoint());
				tq_on=tq_on_slew.Step(1.0,1.0/MODE_TQ_ON_SLEW_TIME);
				tq_out=tq_on*tq_des+(1.0-tq_on)*tq_switch;
				//Send out
				trans->SetTorqueDesJoint(tq_out/1000.0);
				
				ctrl_simple->SetDesiredControlMode(CTRL_MODE_TORQUE);
				ctrl_simple->SetDesiredTorque(trans->GetTorqueDesActuator());
								
				break;
			}
			case JOINT_MODE_TORQUE_GRAV_MODEL:
			{
				if (!IsEncoderCalibrated())
				break;
				
				mReal tq_des;				
								
				//Do PID in torque grav model space
				
				tq_des =pid_tq_grav_model.Step(GetTorqueGravity(),
						trans->GetThetaDotJointDeg(),
						-command.tq_desired(),
						param.kq_p_tq_gm(),
						param.kq_i_tq_gm(),
						param.kq_d_tq_gm(),
						param.kq_i_limit_tq_gm(),
						param.kq_i_range_tq_gm());
				
				
				
				//Ramp in from torque at switch-over point
				mReal tq_on, tq_out;
				tq_on=tq_on_slew.Step(1.0,1.0/MODE_TQ_ON_SLEW_TIME); 
				//tq_on = 1.0;
				tq_out=tq_on*(tq_des)+(1.0-tq_on)*tq_switch;				
				//Send out
				trans->SetTorqueDesJoint(tq_out/1000.0);	//TODO: convert back to mNm	
				
				ctrl_simple->SetDesiredControlMode(CTRL_MODE_CURRENT);
				ctrl_simple->SetDesiredTorque(trans->GetTorqueDesActuator());
				
				/*if (tmp_cnt++ == 1000)
				{
				M3_DEBUG("------------------------\n");
				M3_DEBUG("%s\n", GetName().c_str());
				M3_DEBUG("tq_gc: %f\n", GetTorqueGravity());
				//M3_DEBUG("tq_dot: %f\n", -trans->GetTorqueDotJoint());				    
				M3_DEBUG("tq_des: %f\n", tq_des);
				M3_DEBUG("tq_on: %f\n", tq_on);
				//M3_DEBUG("tq_switch: %f\n", tq_switch);
				M3_DEBUG("tq_out: %f\n", tq_out);				    
				M3_DEBUG("tq_act: %f\n", trans->GetTorqueDesActuator());
				tmp_cnt = 0;
				}*/
				
				break;
			}
			case JOINT_MODE_OFF:
			case JOINT_MODE_PWM:
			default:
				ctrl_simple->SetDesiredControlMode(CTRL_MODE_OFF);
				//act->SetDesiredControlMode(ACTUATOR_MODE_OFF);
				mReal des; //dummy
				StepBrake(des,0);
				break;	
		};
	} else { // Legacy, no supported on BMW,MAX2 versions 2.0
	
//		act->SetDesiredControlMode(ACTUATOR_MODE_OFF);//default
		
		switch(command.ctrl_mode())
		{
			case JOINT_MODE_PWM:
			{
				//Ramp in from pwm at switch-over point
				mReal pwm_des=command.pwm_desired();
				StepBrake(pwm_des,0);			
				//StepBrake(pwm_des,command.pwm_cmd());			
				
				mReal pwm_on, pwm_out;
				pwm_on=pwm_on_slew.Step(1.0,1.0/MODE_PWM_ON_SLEW_TIME);
				pwm_out=pwm_on*pwm_des+(1.0-pwm_on)*pwm_switch;
				//Send out
				act->SetDesiredControlMode(ACTUATOR_MODE_PWM);
				if (disable_pwm_ramp)
				act->SetDesiredPwm(command.pwm_desired());
				else
				act->SetDesiredPwm((int)pwm_out);;
				break;
			}
			case JOINT_MODE_THETA:
			case JOINT_MODE_THETA_MJ:
			{
				
				
					
				if (!IsEncoderCalibrated())
				{
//					M3_INFO("Not calib %s\n",GetName().c_str());
					break;
				}
				
				CalcThetaDesiredSmooth();
				mReal des=trans->GetThetaDesActuatorDeg();
				StepBrake(des,trans->GetThetaActuatorDeg());
				//Do PID in actuator space so result is direct PWM
				mReal pwm =pid_theta.Step(trans->GetThetaActuatorDeg(),
							trans->GetThetaDotActuatorDeg(),
							des,
							param.kt_p(),
							param.kt_i(),
							param.kt_d(),
							param.kt_i_limit(),
							param.kt_i_range());
				act->SetDesiredControlMode(ACTUATOR_MODE_PWM);
				//Ramp in from pwm at switch-over point
				mReal pwm_on, pwm_out;
				pwm_on=pwm_on_slew.Step(1.0,1.0/MODE_PWM_ON_SLEW_TIME);
				pwm_out=pwm_on*pwm+(1.0-pwm_on)*pwm_switch;
				act->SetDesiredPwm((int)pwm_out);
				/*if (tmp_cnt++%100==0)
				{
					M3_INFO("des %3.2f sen: %3.2f pid: %3.2f out: %3.2f\n",des,trans->GetThetaActuatorDeg(),
						pwm,pwm_out);
				}*/
				break;
			}
			case JOINT_MODE_THETA_GC:
			case JOINT_MODE_THETA_GC_MJ:
			{
				if (!IsEncoderCalibrated())
				break;
				mReal stiffness,gravity,tq_des;
				CalcThetaDesiredSmooth();
				mReal des=trans->GetThetaDesJointDeg();
				StepBrake(des,trans->GetThetaJointDeg());
				//Do PID in joint space
				tq_des =pid_theta_gc.Step(trans->GetThetaJointDeg(),
						trans->GetThetaDotJointDeg(),
						des,
						param.kq_p(),
						param.kq_i(),
						param.kq_d(),
						param.kq_i_limit(),
						param.kq_i_range());
				stiffness=CLAMP(command.q_stiffness(),0.0,1.0);
				gravity=GetTorqueGravity()*param.kq_g();
				//Ramp in from torque at switch-over point
				mReal tq_on, tq_out;
				tq_on=tq_on_slew.Step(1.0,1.0/MODE_TQ_ON_SLEW_TIME);
				tq_out=tq_on*(stiffness*tq_des-gravity)+(1.0-tq_on)*tq_switch;
				//Send out
				
				trans->SetTorqueDesJoint(tq_out);
				act->SetDesiredControlMode(ACTUATOR_MODE_TORQUE);
				act->SetDesiredTorque(trans->GetTorqueDesActuator());
				break;
			}
			case JOINT_MODE_TORQUE_GC:			
			{
			if (!IsEncoderCalibrated())
				break;
				mReal tq_on, tq_out,gravity;
				mReal tq_des=command.tq_desired();
				StepBrake(tq_des,trans->GetTorqueJoint());
				gravity=GetTorqueGravity()*param.kq_g();
				//Ramp in from torque at switch-over point
				tq_on=tq_on_slew.Step(1.0,1.0/MODE_TQ_ON_SLEW_TIME);
				tq_out=tq_on*(tq_des-gravity)+(1.0-tq_on)*tq_switch;
				//Send out
				trans->SetTorqueDesJoint(tq_out);
				act->SetDesiredControlMode(ACTUATOR_MODE_TORQUE);

				act->SetDesiredTorque(trans->GetTorqueDesActuator());
				break;
			}
			case JOINT_MODE_TORQUE:
			{		  
				mReal tq_on,tq_out;
				//Ramp in from torque at switch-over point
				mReal tq_des=command.tq_desired();
				
				StepBrake(tq_des,trans->GetTorqueJoint());
				tq_on=tq_on_slew.Step(1.0,1.0/MODE_TQ_ON_SLEW_TIME);
				tq_out=tq_on*tq_des+(1.0-tq_on)*tq_switch;
				//Send out
				trans->SetTorqueDesJoint(tq_out);
				act->SetDesiredControlMode(ACTUATOR_MODE_TORQUE);
				act->SetDesiredTorque(trans->GetTorqueDesActuator());			
				
				/*if (tmp_cnt++ == 100)
				{
				M3_DEBUG("tq_des: %f\n", tq_des);
				M3_DEBUG("tq_on: %f\n", tq_on);
				M3_DEBUG("tq_switch: %f\n", tq_switch);
				M3_DEBUG("tq_out: %f\n", tq_out);				    
				M3_DEBUG("tq_act: %f\n", trans->GetTorqueDesActuator());
				tmp_cnt = 0;
				}*/
				break;
			}
			case JOINT_MODE_OFF:
			default:
				act->SetDesiredControlMode(ACTUATOR_MODE_OFF);
				mReal des; //dummy
				StepBrake(des,0);
				break;
		};
	}
	
	mode_last=(int)command.ctrl_mode();
	
	/*if (tmp_cnt == 100)
	{
	M3_DEBUG("tq_out: %f\n", ((M3ActuatorCommand*)act->GetCommand())->tq_desired() );
	
	tmp_cnt = 0;
	}*/
	
}
void CustomVehicleControllerComponentEngine::InitEngineTorqueCurve (dFloat vehicleSpeed,
	dFloat idleTorque, dFloat rpsAtIdleTorque, 
	dFloat peakTorque, dFloat rpsAtPeakTorque, 
	dFloat peakHorsePower, dFloat rpsAtPeakHorsePower, 
	dFloat torqueAtRedLine, dFloat rpsAtRedLineTorque)
{
	int oldGear = m_gearBox->GetGear();
	m_gearBox->SetGear(m_gearBox->GetGearCount() - 1);

	ConvertToMetricSystem (vehicleSpeed, idleTorque, rpsAtIdleTorque, peakTorque, rpsAtPeakTorque, peakHorsePower, rpsAtPeakHorsePower, torqueAtRedLine, rpsAtRedLineTorque);
	SetTopSpeed (vehicleSpeed, rpsAtPeakHorsePower);				  	   

	dFloat torqueAtPeakPower = peakHorsePower / rpsAtPeakHorsePower;
	dAssert (rpsAtIdleTorque > 0.0f);
	dAssert (rpsAtIdleTorque < rpsAtPeakTorque);
	dAssert (rpsAtPeakTorque < rpsAtPeakHorsePower);
	dAssert (rpsAtPeakHorsePower < rpsAtRedLineTorque);

	dAssert (idleTorque > 0.0f);
	//dAssert (idleTorque < peakTorque);
	dAssert (peakTorque > torqueAtPeakPower);
	dAssert (torqueAtPeakPower > torqueAtRedLine);
	dAssert (torqueAtRedLine > 0.0f);
	dAssert (peakTorque * rpsAtPeakTorque < peakHorsePower);

	dFloat rpsTable[5];
	dFloat torqueTable[5];

	rpsTable[0] = 0.0f;
	rpsTable[1] = rpsAtIdleTorque;
	rpsTable[2] = rpsAtPeakTorque;
	rpsTable[3] = rpsAtPeakHorsePower;
	rpsTable[4] = rpsAtRedLineTorque;

	torqueTable[0] = idleTorque;
	torqueTable[1] = idleTorque;
	torqueTable[2] = peakTorque;
	torqueTable[3] = torqueAtPeakPower;
	torqueTable[4] = torqueAtRedLine;

	const int count = sizeof (rpsTable) / sizeof (rpsTable[0]);
	for (int i = 0; i < count; i ++) {
		rpsTable[i] /= m_crownGearRatio;
		torqueTable[i] *= m_crownGearRatio * 1.0f;
	}
	m_torqueCurve.InitalizeCurve (sizeof (rpsTable)/sizeof (rpsTable[0]), rpsTable, torqueTable);

	m_radiansPerSecundsAtIdleTorque = rpsTable[1];
	m_radiansPerSecundsAtPeakPower = rpsTable[3];
	m_radiansPerSecundsAtRedLine = rpsTable[4];
	m_engineInternalFriction = torqueTable[2] / (m_radiansPerSecundsAtRedLine * 4.0f);

	m_engineIdleResistance1 = torqueTable[2] / (m_radiansPerSecundsAtRedLine * 2.0f);
	dFloat W = 0.5f * (rpsTable[3] + rpsTable[4]);
	dFloat T = GetTorque (W);
	m_engineIdleResistance2 = (T - W * m_engineIdleResistance1) / (W * W);
	if (m_engineIdleResistance2 < 1.0e-4f) {
		m_engineIdleResistance2 =  1.0e-4f;
	}

	m_gearBox->SetOptimalShiftLimits (rpsTable[2] /rpsTable[4], rpsTable[3] / rpsTable[4]);
	m_gearBox->SetGear(oldGear);
}
Beispiel #9
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;
}