Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit 3d1c74e0 authored by Markus Quaritsch's avatar Markus Quaritsch
Browse files

moving mt shift strategy and amt shift strategy to separate files

parent dbdbf045
No related branches found
No related tags found
No related merge requests found
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Configuration;
using TUGraz.VectoCore.Models.Connector.Ports.Impl;
using TUGraz.VectoCore.Models.Simulation.DataBus;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
/// <summary>
/// AMTShiftStrategy implements the AMT Shifting Behaviour.
/// </summary>
public class AMTShiftStrategy : ShiftStrategy
{
/// <summary>
/// The previous gear before the disengagement. Used for GetGear() when skipGears is false.
/// </summary>
protected uint PreviousGear;
public uint NextGear { get; set; }
public AMTShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus)
{
PreviousGear = 1;
Data.EarlyShiftUp = true;
Data.SkipGears = true;
}
private bool SpeedTooLowForEngine(uint gear, PerSecond outAngularSpeed)
{
return (outAngularSpeed * Data.Gears[gear].Ratio).IsSmaller(DataBus.EngineIdleSpeed);
}
// original vecto2.2: (inAngularSpeed - IdleSpeed) / (RatedSpeed - IdleSpeed) >= 1.2
// = inAngularSpeed - IdleSpeed >= 1.2*(RatedSpeed - IdleSpeed)
// = inAngularSpeed >= 1.2*RatedSpeed - 0.2*IdleSpeed
private bool SpeedTooHighForEngine(uint gear, PerSecond outAngularSpeed)
{
return
(outAngularSpeed * Data.Gears[gear].Ratio).IsGreaterOrEqual(DataBus.EngineN95hSpeed);
}
public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
{
while (NextGear > 1 && SpeedTooLowForEngine(NextGear, outAngularVelocity)) {
NextGear--;
}
while (NextGear < Data.Gears.Count && SpeedTooHighForEngine(NextGear, outAngularVelocity)) {
NextGear++;
}
return NextGear;
}
public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
{
PreviousGear = Gearbox.Gear;
}
public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
{
if (DataBus.VehicleSpeed.IsEqual(0)) {
for (var gear = (uint)Data.Gears.Count; gear > 1; gear--) {
var inAngularSpeed = outEngineSpeed * Data.Gears[gear].Ratio;
var ratedSpeed = Data.Gears[gear].FullLoadCurve != null
? Data.Gears[gear].FullLoadCurve.RatedSpeed
: DataBus.EngineRatedSpeed;
if (inAngularSpeed > ratedSpeed || inAngularSpeed.IsEqual(0)) {
continue;
}
var response = Gearbox.Initialize(gear, outTorque, outEngineSpeed);
var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
var reserve = 1 - response.EnginePowerRequest / fullLoadPower;
var inTorque = response.ClutchPowerRequest / inAngularSpeed;
// if in shift curve and above idle speed and torque reserve is provided.
if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && inAngularSpeed > DataBus.EngineIdleSpeed &&
reserve >= Data.StartTorqueReserve) {
return gear;
}
}
return 1;
}
for (var gear = (uint)Data.Gears.Count; gear > 1; gear--) {
var response = Gearbox.Initialize(gear, outTorque, outEngineSpeed);
var inAngularSpeed = outEngineSpeed * Data.Gears[gear].Ratio;
var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
var reserve = 1 - response.EnginePowerRequest / fullLoadPower;
var inTorque = response.ClutchPowerRequest / inAngularSpeed;
// if in shift curve and torque reserve is provided: return the current gear
if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && !IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) &&
reserve >= Data.StartTorqueReserve) {
if ((inAngularSpeed - DataBus.EngineIdleSpeed) / (DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) <
Constants.SimulationSettings.ClutchClosingSpeedNorm && gear > 1) {
gear--;
}
return gear;
}
// if over the up shift curve: return the previous gear (even thou it did not provide the required torque reserve)
if (IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) && gear < Data.Gears.Count) {
return gear + 1;
}
}
// fallback: return first gear
return 1;
}
public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
{
// no shift when vehicle stands
if (DataBus.VehicleStopped) {
return false;
}
// emergency shift to not stall the engine ------------------------
NextGear = gear;
while (NextGear > 1 && SpeedTooLowForEngine(NextGear, outAngularVelocity)) {
NextGear--;
}
while (NextGear < Data.Gears.Count && SpeedTooHighForEngine(NextGear, outAngularVelocity)) {
NextGear++;
}
if (NextGear != gear) {
return true;
}
// normal shift when all requirements are fullfilled ------------------
var minimumShiftTimePassed = (lastShiftTime + Data.ShiftTime).IsSmallerOrEqual(absTime);
if (!minimumShiftTimePassed) {
return false;
}
NextGear = CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear);
if (NextGear != gear) {
return true;
}
NextGear = CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear);
if ((Data.Gears[NextGear].Ratio * outAngularVelocity - DataBus.EngineIdleSpeed) /
(DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) <
Constants.SimulationSettings.ClutchClosingSpeedNorm && NextGear > 1) {
NextGear--;
}
return (NextGear != gear);
}
protected virtual uint CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
{
return DoCheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
}
protected virtual uint CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
{
return DoCheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
}
protected virtual uint DoCheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
{
// upshift
while (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity)) {
currentGear++;
if (!Data.SkipGears) {
break;
}
var tmpGear = Gearbox.Gear;
Gearbox.Gear = currentGear;
var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
Gearbox.Gear = tmpGear;
inAngularVelocity = Data.Gears[currentGear].Ratio * outAngularVelocity;
inTorque = response.ClutchPowerRequest / inAngularVelocity;
}
// early up shift to higher gear ---------------------------------------
if (Data.EarlyShiftUp && currentGear < Data.Gears.Count) {
// try if next gear would provide enough torque reserve
var tryNextGear = currentGear + 1;
var tmpGear = Gearbox.Gear;
Gearbox.Gear = tryNextGear;
var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
Gearbox.Gear = tmpGear;
if (!(response is ResponseEngineSpeedTooLow)) {
inAngularVelocity = Data.Gears[tryNextGear].Ratio * outAngularVelocity;
inTorque = response.ClutchPowerRequest / inAngularVelocity;
// if next gear supplied enough power reserve: take it
// otherwise take
if (!IsBelowDownShiftCurve(tryNextGear, inTorque, inAngularVelocity)) {
var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
var reserve = 1 - response.EnginePowerRequest / fullLoadPower;
if (reserve >= Data.TorqueReserve) {
currentGear = tryNextGear;
}
}
}
}
return currentGear;
}
protected virtual uint DoCheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
{
// down shift
while (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity)) {
currentGear--;
if (!Data.SkipGears) {
break;
}
var tmpGear = Gearbox.Gear;
Gearbox.Gear = currentGear;
var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
Gearbox.Gear = tmpGear;
inAngularVelocity = Data.Gears[currentGear].Ratio * outAngularVelocity;
inTorque = response.ClutchPowerRequest / inAngularVelocity;
}
return currentGear;
}
}
}
\ No newline at end of file
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Models.Simulation.DataBus;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
public class MTShiftStrategy : AMTShiftStrategy
{
public MTShiftStrategy(GearboxData data, IDataBus bus) : base(data, bus)
{
Data.EarlyShiftUp = false;
Data.SkipGears = true;
}
protected override uint CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
{
// if the driver's intention is _not_ to accelerate or drive along then don't upshift
if (DataBus.DriverBehavior != DrivingBehavior.Accelerating && DataBus.DriverBehavior != DrivingBehavior.Driving) {
return currentGear;
}
if ((absTime - Gearbox.LastDownshift).IsSmaller(10.SI<Second>())) {
return currentGear;
}
var nextGear = DoCheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
if (nextGear == currentGear) {
return nextGear;
}
// estimate acceleration for selected gear
if (EstimateAccelerationForGear(nextGear, outAngularVelocity).IsSmaller(0.1.SI<MeterPerSquareSecond>())) {
// if less than 0.1 for next gear, don't shift
if (nextGear - currentGear == 1) {
return currentGear;
}
// if a gear is skipped but acceleration is less than 0.1, try for next gear. if acceleration is still below 0.1 don't shift!
if (nextGear > currentGear &&
EstimateAccelerationForGear(currentGear + 1, outAngularVelocity).IsSmaller(0.1.SI<MeterPerSquareSecond>())) {
return currentGear;
}
}
return nextGear;
}
protected override uint CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
{
if ((absTime - Gearbox.LastUpshift).IsSmaller(10.SI<Second>())) {
return currentGear;
}
return DoCheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
}
}
}
\ No newline at end of file
......@@ -33,8 +33,6 @@ using System;
using System.Drawing.Design;
using TUGraz.VectoCommon.Exceptions;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Configuration;
using TUGraz.VectoCore.Models.Connector.Ports.Impl;
using TUGraz.VectoCore.Models.Simulation.DataBus;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
......@@ -85,7 +83,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
var rollResistanceLoss = DataBus.RollingResistance(avgSlope) * DataBus.VehicleSpeed;
var gearboxLoss = Gearbox.ModelData.Gears[gear].LossMap.GetTorqueLoss(gbxAngularVelocityOut,
maxEnginePower / nextEngineSpeed * Gearbox.ModelData.Gears[gear].Ratio).Value * nextEngineSpeed;
//DataBus.GearboxLoss();
//DataBus.GearboxLoss();
var slopeLoss = DataBus.SlopeResistance(avgSlope) * DataBus.VehicleSpeed;
var axleLoss = DataBus.AxlegearLoss();
......@@ -140,295 +138,4 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return ShiftPolygon.IsRightOf(inEngineSpeed, inTorque, upSection);
}
}
//###############################################################################
//###############################################################################
//###############################################################################
/// <summary>
/// AMTShiftStrategy implements the AMT Shifting Behaviour.
/// </summary>
public class AMTShiftStrategy : ShiftStrategy
{
/// <summary>
/// The previous gear before the disengagement. Used for GetGear() when skipGears is false.
/// </summary>
protected uint PreviousGear;
public uint NextGear { get; set; }
public AMTShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus)
{
PreviousGear = 1;
Data.EarlyShiftUp = true;
Data.SkipGears = true;
}
private bool SpeedTooLowForEngine(uint gear, PerSecond outAngularSpeed)
{
return (outAngularSpeed * Data.Gears[gear].Ratio).IsSmaller(DataBus.EngineIdleSpeed);
}
// original vecto2.2: (inAngularSpeed - IdleSpeed) / (RatedSpeed - IdleSpeed) >= 1.2
// = inAngularSpeed - IdleSpeed >= 1.2*(RatedSpeed - IdleSpeed)
// = inAngularSpeed >= 1.2*RatedSpeed - 0.2*IdleSpeed
private bool SpeedTooHighForEngine(uint gear, PerSecond outAngularSpeed)
{
return
(outAngularSpeed * Data.Gears[gear].Ratio).IsGreaterOrEqual(DataBus.EngineN95hSpeed);
}
public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
{
while (NextGear > 1 && SpeedTooLowForEngine(NextGear, outAngularVelocity)) {
NextGear--;
}
while (NextGear < Data.Gears.Count && SpeedTooHighForEngine(NextGear, outAngularVelocity)) {
NextGear++;
}
return NextGear;
}
public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
{
PreviousGear = Gearbox.Gear;
}
public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
{
if (DataBus.VehicleSpeed.IsEqual(0)) {
for (var gear = (uint)Data.Gears.Count; gear > 1; gear--) {
var inAngularSpeed = outEngineSpeed * Data.Gears[gear].Ratio;
var ratedSpeed = Data.Gears[gear].FullLoadCurve != null
? Data.Gears[gear].FullLoadCurve.RatedSpeed
: DataBus.EngineRatedSpeed;
if (inAngularSpeed > ratedSpeed || inAngularSpeed.IsEqual(0)) {
continue;
}
var response = Gearbox.Initialize(gear, outTorque, outEngineSpeed);
var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
var reserve = 1 - response.EnginePowerRequest / fullLoadPower;
var inTorque = response.ClutchPowerRequest / inAngularSpeed;
// if in shift curve and above idle speed and torque reserve is provided.
if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && inAngularSpeed > DataBus.EngineIdleSpeed &&
reserve >= Data.StartTorqueReserve) {
return gear;
}
}
return 1;
}
for (var gear = (uint)Data.Gears.Count; gear > 1; gear--) {
var response = Gearbox.Initialize(gear, outTorque, outEngineSpeed);
var inAngularSpeed = outEngineSpeed * Data.Gears[gear].Ratio;
var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
var reserve = 1 - response.EnginePowerRequest / fullLoadPower;
var inTorque = response.ClutchPowerRequest / inAngularSpeed;
// if in shift curve and torque reserve is provided: return the current gear
if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && !IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) &&
reserve >= Data.StartTorqueReserve) {
if ((inAngularSpeed - DataBus.EngineIdleSpeed) / (DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) <
Constants.SimulationSettings.ClutchClosingSpeedNorm && gear > 1) {
gear--;
}
return gear;
}
// if over the up shift curve: return the previous gear (even thou it did not provide the required torque reserve)
if (IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) && gear < Data.Gears.Count) {
return gear + 1;
}
}
// fallback: return first gear
return 1;
}
public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
{
// no shift when vehicle stands
if (DataBus.VehicleStopped) {
return false;
}
// emergency shift to not stall the engine ------------------------
NextGear = gear;
while (NextGear > 1 && SpeedTooLowForEngine(NextGear, outAngularVelocity)) {
NextGear--;
}
while (NextGear < Data.Gears.Count && SpeedTooHighForEngine(NextGear, outAngularVelocity)) {
NextGear++;
}
if (NextGear != gear) {
return true;
}
// normal shift when all requirements are fullfilled ------------------
var minimumShiftTimePassed = (lastShiftTime + Data.ShiftTime).IsSmallerOrEqual(absTime);
if (!minimumShiftTimePassed) {
return false;
}
NextGear = CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear);
if (NextGear != gear) {
return true;
}
NextGear = CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear);
if ((Data.Gears[NextGear].Ratio * outAngularVelocity - DataBus.EngineIdleSpeed) /
(DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) <
Constants.SimulationSettings.ClutchClosingSpeedNorm && NextGear > 1) {
NextGear--;
}
return (NextGear != gear);
}
protected virtual uint CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
{
return DoCheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
}
protected virtual uint CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
{
return DoCheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
}
protected virtual uint DoCheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
{
// upshift
while (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity)) {
currentGear++;
if (!Data.SkipGears) {
break;
}
var tmpGear = Gearbox.Gear;
Gearbox.Gear = currentGear;
var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
Gearbox.Gear = tmpGear;
inAngularVelocity = Data.Gears[currentGear].Ratio * outAngularVelocity;
inTorque = response.ClutchPowerRequest / inAngularVelocity;
}
// early up shift to higher gear ---------------------------------------
if (Data.EarlyShiftUp && currentGear < Data.Gears.Count) {
// try if next gear would provide enough torque reserve
var tryNextGear = currentGear + 1;
var tmpGear = Gearbox.Gear;
Gearbox.Gear = tryNextGear;
var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
Gearbox.Gear = tmpGear;
if (!(response is ResponseEngineSpeedTooLow)) {
inAngularVelocity = Data.Gears[tryNextGear].Ratio * outAngularVelocity;
inTorque = response.ClutchPowerRequest / inAngularVelocity;
// if next gear supplied enough power reserve: take it
// otherwise take
if (!IsBelowDownShiftCurve(tryNextGear, inTorque, inAngularVelocity)) {
var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
var reserve = 1 - response.EnginePowerRequest / fullLoadPower;
if (reserve >= Data.TorqueReserve) {
currentGear = tryNextGear;
}
}
}
}
return currentGear;
}
protected virtual uint DoCheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
{
// down shift
while (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity)) {
currentGear--;
if (!Data.SkipGears) {
break;
}
var tmpGear = Gearbox.Gear;
Gearbox.Gear = currentGear;
var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
Gearbox.Gear = tmpGear;
inAngularVelocity = Data.Gears[currentGear].Ratio * outAngularVelocity;
inTorque = response.ClutchPowerRequest / inAngularVelocity;
}
return currentGear;
}
}
//###############################################################################
//###############################################################################
//###############################################################################
public class MTShiftStrategy : AMTShiftStrategy
{
public MTShiftStrategy(GearboxData data, IDataBus bus) : base(data, bus)
{
Data.EarlyShiftUp = false;
Data.SkipGears = true;
}
protected override uint CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
{
// if the driver's intention is _not_ to accelerate or drive along then don't upshift
if (DataBus.DriverBehavior != DrivingBehavior.Accelerating && DataBus.DriverBehavior != DrivingBehavior.Driving) {
return currentGear;
}
if ((absTime - Gearbox.LastDownshift).IsSmaller(10.SI<Second>())) {
return currentGear;
}
var nextGear = DoCheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
if (nextGear == currentGear) {
return nextGear;
}
// estimate acceleration for selected gear
if (EstimateAccelerationForGear(nextGear, outAngularVelocity).IsSmaller(0.1.SI<MeterPerSquareSecond>())) {
// if less than 0.1 for next gear, don't shift
if (nextGear - currentGear == 1) {
return currentGear;
}
// if a gear is skipped but acceleration is less than 0.1, try for next gear. if acceleration is still below 0.1 don't shift!
if (nextGear > currentGear &&
EstimateAccelerationForGear(currentGear + 1, outAngularVelocity).IsSmaller(0.1.SI<MeterPerSquareSecond>())) {
return currentGear;
}
}
return nextGear;
}
protected override uint CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
{
if ((absTime - Gearbox.LastUpshift).IsSmaller(10.SI<Second>())) {
return currentGear;
}
return DoCheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
}
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment