Skip to content

Commit

Permalink
💡 Renamed confusing EngineClass attr getters.
Browse files Browse the repository at this point in the history
Changes:
* `getMaxRPM()` --> `getShiftDownRPM()` -- equivalent of `ACTORSIMATTR_ENGINE_SHIFT_DOWN_RPM`
* `getMinRPM()` --> `getShiftUpRPM()` -- equivalent of `ACTORSIMATTR_ENGINE_SHIFT_UP_RPM`

The 'example_actor_engineDiag.as' was updated:
* updated 'engine' tab to show new names
* completely removed the 'clutch' tab as it didn't make sense anymore - I got confused by the min/max RPM when writing it. This also fixes a division-by-zero script crash reported by Mike.
* fixed plot min/max values in the 'state' tab.
  • Loading branch information
ohlidalp committed Jan 25, 2025
1 parent 790cb00 commit bf459dc
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 103 deletions.
4 changes: 2 additions & 2 deletions doc/angelscript/Script2Game/EngineClass.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ class EngineSimClass

/// @name Definition; keyword 'engine'
/// @{
float getMinRPM() const; //!< Shift down RPM ('engine' attr #1)
float getMaxRPM() const; //!< Shift up RPM ('engine' attr #2)
float getShiftDownRPM() const; //!< Shift down RPM ('engine' attr #1)
float getShiftUpRPM() const; //!< Shift up RPM ('engine' attr #2)
float getEngineTorque() const; //!< Torque in N/m ('engine' attr #3)
float getDiffRatio() const; //!< Global gear ratio ('engine' attr #4)
float getGearRatio(int pos); //!< -1=R, 0=N, 1... ('engine' attrs #5[R],#6[N],#7[1]...)
Expand Down
79 changes: 13 additions & 66 deletions resources/scripts/example_actor_engineDiag.as
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
/// \title Engine + Clutch diag script
/// \title Engine tweak + Clutch diag script
/// \brief Shows config params and state of engine simulation
/// \author ohlidalp 2024-2025, see https://github.com/RigsOfRods/rigs-of-rods/pull/3177

// Window [X] button handler
#include "imgui_utils.as"
imgui_utils::CloseWindowPrompt closeBtnHandler;

// #region FrameStep - clutch calc
// #region Plots

vector2 cfgPlotSize(0.f, 45.f); // 0=autoresize
bool cfgUseGlobalGearForThresholdCalc = false; // by default 1st gear is used, which may be a bug.

// assume 60FPS = circa 3 sec
const int MAX_SAMPLES = 3*60;
array<float> clutchBuf(MAX_SAMPLES, 0.f);
array<float> rpmBuf(MAX_SAMPLES, 0.f);
array<float> clutchTorqueBuf(MAX_SAMPLES, 0.f);
array<float> calcGearboxSpinnerBuf(MAX_SAMPLES, 0.f);
array<float> calcClutchTorqueBuf(MAX_SAMPLES, 0.f);
array<float> calcForceThresholdBuf(MAX_SAMPLES, 0.f);
array<float> calcClutchTorqueClampedBuf(MAX_SAMPLES, 0.f);
array<float> calcClutchTorqueFinalBuf(MAX_SAMPLES, 0.f);

void updateFloatBuf(array<float>@ buf, float f)
{
Expand All @@ -34,21 +29,6 @@ void updateEnginePlotBuffers(EngineClass@ engine)
updateFloatBuf(rpmBuf, engine.getRPM());
updateFloatBuf(clutchTorqueBuf, engine.getTorque());

// Replicating the clutch torque calculation
float gearboxspinner = engine.getRPM() / engine.getGearRatio(engine.getGear());
updateFloatBuf(calcGearboxSpinnerBuf, gearboxspinner);

float clutchTorque = (gearboxspinner - engine.getWheelSpin()) * engine.getClutch() * engine.getClutchForce();
updateFloatBuf(calcClutchTorqueBuf, clutchTorque);

float forceThreshold = 1.5f * fmax(engine.getTorque(), engine.getEnginePower()) * fabs(engine.getGearRatio(cfgUseGlobalGearForThresholdCalc ? 0 : 1)); // gear 1=BUG? should probably be 0=global
updateFloatBuf(calcForceThresholdBuf, forceThreshold);

float clutchTorqueClamped = fclamp(clutchTorque, -forceThreshold, forceThreshold);
updateFloatBuf(calcClutchTorqueClampedBuf, clutchTorqueClamped);

float clutchTorqueFinal = clutchTorqueClamped * (1.f - fexp(-fabs(gearboxspinner - engine.getWheelSpin())));
updateFloatBuf(calcClutchTorqueFinalBuf, clutchTorqueFinal);
}

// #endregion
Expand Down Expand Up @@ -157,10 +137,10 @@ void drawEngineAttributesTab(BeamClass@ actor, EngineClass@ engine)

ImGui::Columns(2);

drawTableRow("getMinRPM", engine.getMinRPM());
drawTableRow("getShiftDownRPM", engine.getShiftDownRPM());
drawAttrInputRow(actor, ACTORSIMATTR_ENGINE_SHIFTDOWN_RPM, "SHIFTDOWN_RPM");
ImGui::Separator();
drawTableRow("getMaxRPM", engine.getMaxRPM());
drawTableRow("getShiftUpRPM", engine.getShiftUpRPM());
drawAttrInputRow(actor, ACTORSIMATTR_ENGINE_SHIFTUP_RPM, "SHIFTUP_RPM");
ImGui::Separator();
drawTableRow("getEngineTorque", engine.getEngineTorque());
Expand Down Expand Up @@ -243,9 +223,10 @@ void drawSimulationStateTab(EngineClass@ engine)
drawTableRow("getAcc", engine.getAcc());
drawTableRowPlot("getClutch (0.0 - 1.0)", clutchBuf, 0.f, 1.f);
drawTableRow("getCrankFactor", engine.getCrankFactor());
drawTableRowPlot("getRPM (min - max)", rpmBuf, engine.getMinRPM(), engine.getMaxRPM());
drawTableRow("getSmoke", engine.getSmoke());
drawTableRowPlot("getTorque (0 - clutchforce)", clutchTorqueBuf, 0.f, engine.getClutchForce());
drawTableRowPlot("getRPM (0 - 10000)", rpmBuf, 0.f, 10000.f);
drawTableRow("getSmoke", engine.getSmoke());
float clutchTorquePlotMax = engine.getEngineTorque() * engine.getGearRatio(1) * 2.5f; // magic
drawTableRowPlot("getTorque (0 - "+clutchTorquePlotMax+")", clutchTorqueBuf, 0.f, clutchTorquePlotMax);
drawTableRow("getTurboPSI", engine.getTurboPSI());
drawTableRow("getAutoMode", engine.getAutoMode());//SimGearboxMode
drawTableRow("getGear", engine.getGear());
Expand All @@ -265,35 +246,6 @@ void drawSimulationStateTab(EngineClass@ engine)
ImGui::Columns(1);
}
// #endregion

// #region Main window - clutch calc tab

void drawClutchCalcTab(EngineClass@ engine)
{

ImGui::TextDisabled('// Replicating the clutch torque calculation');
ImGui::SameLine();
ImGui::Checkbox("cfgUseGlobalGearForThresholdCalc (visual only)", cfgUseGlobalGearForThresholdCalc);
ImGui::Separator();

ImGui::TextDisabled('float gearboxspinner = engine.getRPM() / engine.getGearRatio(engine.getGear());');
float topGearRPM = engine.getMaxRPM() * engine.getGearRatio(engine.getNumGears() - 1);
plotFloatBuf(calcGearboxSpinnerBuf, 0.f, topGearRPM*0.5f);

ImGui::TextDisabled('float clutchTorque = (gearboxspinner - engine.getWheelSpin()) * engine.getClutch() * engine.getClutchForce();');
plotFloatBuf(calcClutchTorqueBuf, 0.f, 1000000);

ImGui::TextDisabled('float forceThreshold = 1.5f * fmax(engine.getTorque(), engine.getEnginePower()) * fabs(engine.getGearRatio(1)) // BUG? should probably be 0=global ');
plotFloatBuf(calcForceThresholdBuf, 0.f, 10*engine.getMaxRPM() * engine.getGearRatio(engine.getNumGears() - 1));

ImGui::TextDisabled('float clutchTorqueClamped = fclamp(clutchTorque, -forceThreshold, forceThreshold);');
plotFloatBuf(calcClutchTorqueClampedBuf, 100.f, topGearRPM*10);

ImGui::TextDisabled('float clutchTorqueFinal = clutchTorqueClamped * (1.f - fexp(-fabs(gearboxspinner - engine.getWheelSpin())));');
plotFloatBuf(calcClutchTorqueFinalBuf, 100.f, topGearRPM*10);
}

// #endregion

// #region Main window
void drawEngineDiagUI(BeamClass@ actor, EngineClass@ engine)
Expand All @@ -303,27 +255,22 @@ void drawEngineDiagUI(BeamClass@ actor, EngineClass@ engine)
if (ImGui::BeginTabItem('engine args'))
{
drawEngineAttributesTab(actor, engine);
ImGui::EndTabItem();
ImGui::EndTabItem();
}


if (ImGui::BeginTabItem("engoption args"))
{
drawEngoptionAttributesTab(actor, engine);
ImGui::EndTabItem();
ImGui::EndTabItem();
}

if (ImGui::BeginTabItem('state'))
{
drawSimulationStateTab(engine);
{ drawSimulationStateTab(engine);

ImGui::EndTabItem();
}

if (ImGui::BeginTabItem("calc"))
{
drawClutchCalcTab(engine);
ImGui::EndTabItem();
}
ImGui::EndTabBar();
}
}
Expand Down
6 changes: 3 additions & 3 deletions source/main/gameplay/CruiseControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ void Actor::UpdateCruiseControl(float dt)
else if (ar_engine->getGear() == 0) // out of gear
{
// Try to maintain the target rpm
float speed_range = (ar_engine->getMaxRPM() - ar_engine->getMinRPM()) / 50.0f;
float speed_range = (ar_engine->getShiftUpRPM() - ar_engine->getShiftDownRPM()) / 50.0f;
acc += ar_engine->getEngineInertia() * (cc_target_rpm - ar_engine->getRPM()) / speed_range;
}

Expand Down Expand Up @@ -105,7 +105,7 @@ void Actor::UpdateCruiseControl(float dt)
else if (ar_engine->getGear() == 0) // out of gear
{
cc_target_rpm *= pow(2.0f, dt / 5.0f);
cc_target_rpm = std::min(cc_target_rpm, ar_engine->getMaxRPM());
cc_target_rpm = std::min(cc_target_rpm, ar_engine->getShiftUpRPM());
}
}
if (App::GetInputEngine()->getEventBoolValue(EV_TRUCK_CRUISE_CONTROL_DECL))
Expand All @@ -118,7 +118,7 @@ void Actor::UpdateCruiseControl(float dt)
else if (ar_engine->getGear() == 0) // out of gear
{
cc_target_rpm *= pow(0.5f, dt / 5.0f);
cc_target_rpm = std::max(ar_engine->getMinRPM(), cc_target_rpm);
cc_target_rpm = std::max(ar_engine->getShiftDownRPM(), cc_target_rpm);
}
}
if (App::GetInputEngine()->getEventBoolValue(EV_TRUCK_CRUISE_CONTROL_READJUST))
Expand Down
38 changes: 19 additions & 19 deletions source/main/gameplay/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Engine::Engine(float _min_rpm, float _max_rpm, float torque, float reverse_gear,
, m_max_idle_mixture(0.1f)
, m_engine_max_rpm(std::abs(_max_rpm))
, m_min_idle_mixture(0.0f)
, m_engine_min_rpm(std::abs(_min_rpm))
, m_engine_shiftup_rpm(std::abs(_min_rpm))
, m_num_gears((int)forward_gears.size())
, m_post_shift_time(0.2f)
, m_post_shift_clock(0.0f)
Expand Down Expand Up @@ -101,7 +101,7 @@ Engine::Engine(float _min_rpm, float _max_rpm, float torque, float reverse_gear,
, m_antilag_min_rpm(3000)
, m_antilag_power_factor(170)
{
m_full_rpm_range = (m_engine_max_rpm - m_engine_min_rpm);
m_full_rpm_range = (m_engine_max_rpm - m_engine_shiftup_rpm);
m_one_third_rpm_range = m_full_rpm_range / 3.0f;
m_half_rpm_range = m_full_rpm_range / 2.0f;

Expand Down Expand Up @@ -578,25 +578,25 @@ void Engine::UpdateEngine(float dt, int doUpdate)
}

// auto clutch
float declutchRPM = m_engine_min_rpm * 0.75f + m_engine_stall_rpm * 0.25f;
float declutchRPM = m_engine_shiftup_rpm * 0.75f + m_engine_stall_rpm * 0.25f;
if (m_cur_gear == 0 || m_cur_engine_rpm < declutchRPM)
{
m_cur_clutch = 0.0f;
}
else if (m_cur_engine_rpm < m_engine_min_rpm && m_engine_min_rpm > declutchRPM)
else if (m_cur_engine_rpm < m_engine_shiftup_rpm && m_engine_shiftup_rpm > declutchRPM)
{
float clutch = (m_cur_engine_rpm - declutchRPM) / (m_engine_min_rpm - declutchRPM);
float clutch = (m_cur_engine_rpm - declutchRPM) / (m_engine_shiftup_rpm - declutchRPM);
m_cur_clutch = std::min(clutch * clutch, m_cur_clutch);
}
else if (!m_shift_val && m_cur_engine_rpm > m_engine_min_rpm && m_cur_clutch < 1.0f)
else if (!m_shift_val && m_cur_engine_rpm > m_engine_shiftup_rpm && m_cur_clutch < 1.0f)
{
float threshold = 1.5f * getEnginePower(m_cur_engine_rpm) * std::abs(m_gear_ratios[2]);
float gearboxspinner = m_cur_engine_rpm / m_gear_ratios[m_cur_gear + 1];
float clutchTorque = (gearboxspinner - m_cur_wheel_revolutions) * m_clutch_force;
float reTorque = Math::Clamp(clutchTorque, -threshold, +threshold) / m_gear_ratios[m_cur_gear + 1];

float range = (m_engine_max_rpm - m_engine_min_rpm) * 0.4f * sqrt(std::max(0.2f, acc));
float powerRatio = std::min((m_cur_engine_rpm - m_engine_min_rpm) / range, 1.0f);
float range = (m_engine_max_rpm - m_engine_shiftup_rpm) * 0.4f * sqrt(std::max(0.2f, acc));
float powerRatio = std::min((m_cur_engine_rpm - m_engine_shiftup_rpm) / range, 1.0f);
float engineTorque = getEnginePower() * std::min(m_cur_acc, 0.9f) * powerRatio;

float torqueDiff = std::min(engineTorque, std::abs(reTorque));
Expand Down Expand Up @@ -634,7 +634,7 @@ void Engine::UpdateEngine(float dt, int doUpdate)
shift(1);
}
}
else if (m_cur_gear > 1 && m_ref_wheel_revolutions * m_gear_ratios[m_cur_gear] < m_engine_max_rpm && (m_cur_engine_rpm < m_engine_min_rpm || (m_cur_engine_rpm < m_engine_min_rpm + m_shift_behaviour * m_half_rpm_range / 2.0f &&
else if (m_cur_gear > 1 && m_ref_wheel_revolutions * m_gear_ratios[m_cur_gear] < m_engine_max_rpm && (m_cur_engine_rpm < m_engine_shiftup_rpm || (m_cur_engine_rpm < m_engine_shiftup_rpm + m_shift_behaviour * m_half_rpm_range / 2.0f &&
getEnginePower(m_cur_wheel_revolutions * m_gear_ratios[m_cur_gear]) > getEnginePower(m_cur_wheel_revolutions * m_gear_ratios[m_cur_gear + 1]))))
{
shift(-1);
Expand Down Expand Up @@ -693,18 +693,18 @@ void Engine::UpdateEngine(float dt, int doUpdate)
newGear--;
}
}
else if (avgAcc50 > 0.6f && acc < 0.8f && acc > avgAcc50 + 0.1f && m_cur_engine_rpm < m_engine_min_rpm + m_half_rpm_range)
else if (avgAcc50 > 0.6f && acc < 0.8f && acc > avgAcc50 + 0.1f && m_cur_engine_rpm < m_engine_shiftup_rpm + m_half_rpm_range)
{
if (newGear > 1 && m_cur_wheel_revolutions * m_gear_ratios[newGear] < m_engine_min_rpm + m_half_rpm_range &&
if (newGear > 1 && m_cur_wheel_revolutions * m_gear_ratios[newGear] < m_engine_shiftup_rpm + m_half_rpm_range &&
getEnginePower(m_cur_wheel_revolutions * m_gear_ratios[newGear]) * m_gear_ratios[newGear] >
getEnginePower(m_cur_wheel_revolutions * m_gear_ratios[newGear + 1]) * m_gear_ratios[newGear + 1])
{
newGear--;
}
}
else if (avgAcc50 > 0.4f && acc < 0.8f && acc > avgAcc50 + 0.1f && m_cur_engine_rpm < m_engine_min_rpm + m_half_rpm_range)
else if (avgAcc50 > 0.4f && acc < 0.8f && acc > avgAcc50 + 0.1f && m_cur_engine_rpm < m_engine_shiftup_rpm + m_half_rpm_range)
{
if (newGear > 1 && m_cur_wheel_revolutions * m_gear_ratios[newGear] < m_engine_min_rpm + m_one_third_rpm_range &&
if (newGear > 1 && m_cur_wheel_revolutions * m_gear_ratios[newGear] < m_engine_shiftup_rpm + m_one_third_rpm_range &&
getEnginePower(m_cur_wheel_revolutions * m_gear_ratios[newGear]) * m_gear_ratios[newGear] >
getEnginePower(m_cur_wheel_revolutions * m_gear_ratios[newGear + 1]) * m_gear_ratios[newGear + 1])
{
Expand All @@ -714,23 +714,23 @@ void Engine::UpdateEngine(float dt, int doUpdate)
else if (m_cur_gear < (m_autoselect == TWO ? std::min(2, m_num_gears) : m_num_gears) &&
avgBrake200 < 0.2f && acc < std::min(avgAcc200 + 0.1f, 1.0f) && m_cur_engine_rpm > avgRPM200 - m_full_rpm_range / 20.0f)
{
if (avgAcc200 < 0.6f && avgAcc200 > 0.4f && m_cur_engine_rpm > m_engine_min_rpm + m_one_third_rpm_range && m_cur_engine_rpm < m_engine_max_rpm - m_one_third_rpm_range)
if (avgAcc200 < 0.6f && avgAcc200 > 0.4f && m_cur_engine_rpm > m_engine_shiftup_rpm + m_one_third_rpm_range && m_cur_engine_rpm < m_engine_max_rpm - m_one_third_rpm_range)
{
if (m_cur_wheel_revolutions * m_gear_ratios[newGear + 2] > m_engine_min_rpm + m_one_third_rpm_range)
if (m_cur_wheel_revolutions * m_gear_ratios[newGear + 2] > m_engine_shiftup_rpm + m_one_third_rpm_range)
{
newGear++;
}
}
else if (avgAcc200 < 0.4f && avgAcc200 > 0.2f && m_cur_engine_rpm > m_engine_min_rpm + m_one_third_rpm_range)
else if (avgAcc200 < 0.4f && avgAcc200 > 0.2f && m_cur_engine_rpm > m_engine_shiftup_rpm + m_one_third_rpm_range)
{
if (m_cur_wheel_revolutions * m_gear_ratios[newGear + 2] > m_engine_min_rpm + m_one_third_rpm_range / 2.0f)
if (m_cur_wheel_revolutions * m_gear_ratios[newGear + 2] > m_engine_shiftup_rpm + m_one_third_rpm_range / 2.0f)
{
newGear++;
}
}
else if (avgAcc200 < 0.2f && m_cur_engine_rpm > m_engine_min_rpm + m_one_third_rpm_range / 2.0f && m_cur_engine_rpm < m_engine_min_rpm + m_half_rpm_range)
else if (avgAcc200 < 0.2f && m_cur_engine_rpm > m_engine_shiftup_rpm + m_one_third_rpm_range / 2.0f && m_cur_engine_rpm < m_engine_shiftup_rpm + m_half_rpm_range)
{
if (m_cur_wheel_revolutions * m_gear_ratios[newGear + 2] > m_engine_min_rpm + m_one_third_rpm_range / 2.0f)
if (m_cur_wheel_revolutions * m_gear_ratios[newGear + 2] > m_engine_shiftup_rpm + m_one_third_rpm_range / 2.0f)
{
newGear++;
}
Expand Down
6 changes: 3 additions & 3 deletions source/main/gameplay/Engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ class Engine : public RefCountingObject<Engine>

/// @name Definition; keyword 'engine'
/// @{
float getMinRPM() const { return m_engine_min_rpm; } //!< Shift down RPM ('engine' attr #1)
float getMaxRPM() const { return m_engine_max_rpm; } //!< Shift up RPM ('engine' attr #2)
float getShiftDownRPM() const { return m_engine_shiftup_rpm; } //!< Shift down RPM ('engine' attr #1)
float getShiftUpRPM() const { return m_engine_max_rpm; } //!< Shift up RPM ('engine' attr #2)
float getEngineTorque() const { return m_engine_torque; } //!< Torque in N/m ('engine' attr #3)
float getDiffRatio() const { return m_diff_ratio; } //!< Global gear ratio ('engine' attr #4)
float getGearRatio(int pos); //!< -1=R, 0=N, 1... ('engine' attrs #5[R],#6[N],#7[1]...)
Expand Down Expand Up @@ -218,7 +218,7 @@ class Engine : public RefCountingObject<Engine>
float m_max_idle_mixture; //!< Maximum throttle to maintain the idle RPM ('engoption' attr #9)
float m_engine_inertia; //!< ('engoption' attr #1)
float m_engine_max_rpm; //!< Shift up RPM ('engine' attr #2)
float m_engine_min_rpm; //!< Shift down RPM ('engine' attr #1)
float m_engine_shiftup_rpm; //!< Shift down RPM ('engine' attr #1)
float m_engine_idle_rpm; //!< ('engoption' attr #8)
float m_engine_stall_rpm; //!< ('engoption' attr #7)
bool m_engine_is_priming; //!< Engine
Expand Down
2 changes: 1 addition & 1 deletion source/main/gfx/GfxActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1891,7 +1891,7 @@ void RoR::GfxActor::UpdateSimDataBuffer()
m_simbuf.simbuf_drive_ratio = m_actor->ar_engine->getDriveRatio();
m_simbuf.simbuf_clutch = m_actor->ar_engine->getClutch();
m_simbuf.simbuf_num_gears = m_actor->ar_engine->getNumGears();
m_simbuf.simbuf_engine_max_rpm = m_actor->ar_engine->getMaxRPM();
m_simbuf.simbuf_engine_max_rpm = m_actor->ar_engine->getShiftUpRPM();
m_simbuf.simbuf_engine_smoke = m_actor->ar_engine->getSmoke();
}
if (m_actor->m_num_wheel_diffs > 0)
Expand Down
Loading

0 comments on commit bf459dc

Please sign in to comment.