Code development platform for open source projects from the European Union institutions :large_blue_circle: EU Login authentication by SMS has been phased out. To see alternatives please check here

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

Merge branch 'feature/VECTO-112-simple-shifting-strategy' of...

Merge branch 'feature/VECTO-112-simple-shifting-strategy' of https://webgate.ec.europa.eu/CITnet/stash/scm/~emkrispmi/vecto-sim into feature/VECTO-121-driver-strategy-allow-overspeed

Conflicts:
	VectoCore/Models/SimulationComponent/Impl/Driver.cs
parents a2e8d2a0 ef38745f
No related branches found
No related tags found
No related merge requests found
......@@ -11,6 +11,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
/// <summary>
/// Checks if a shift operation is required.
/// </summary>
/// <param name="absTime">The abs time.</param>
/// <param name="dt">The dt.</param>
/// <param name="outTorque">The out torque.</param>
/// <param name="outAngularVelocity">The out angular velocity.</param>
/// <param name="inTorque">The in torque.</param>
/// <param name="inAngularVelocity">The in angular velocity.</param>
/// <param name="gear">The current gear.</param>
/// <param name="lastShiftTime">The last shift time.</param>
/// <returns><c>true</c> if a shift is required, <c>false</c> otherwise.</returns>
bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime);
......@@ -20,9 +29,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
/// <param name="absTime">The abs time.</param>
/// <param name="dt">The dt.</param>
/// <param name="torque">The torque.</param>
/// <param name="outEngineSpeed">The angular speed.</param>
/// <returns></returns>
uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outEngineSpeed);
/// <param name="outAngularVelocity">The angular speed.</param>
/// <returns>The initial gear.</returns>
uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity);
/// <summary>
/// Engages a gear.
......@@ -31,7 +40,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
/// <param name="dt">The dt.</param>
/// <param name="outTorque">The out torque.</param>
/// <param name="outEngineSpeed">The out engine speed.</param>
/// <returns></returns>
/// <returns>The gear to take.</returns>
uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed);
/// <summary>
......
......@@ -474,7 +474,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
debug.Add(new { brakingPower = 0.SI<Watt>(), searchInterval, delta = origDelta, operatingPoint });
var breakingPower = searchInterval * -origDelta.Sign();
var brakePower = searchInterval * -origDelta.Sign();
// double the searchInterval until a good interval was found
var intervalFactor = 1.0;
......@@ -482,7 +482,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
//ResponseDryRun response;
do {
operatingPoint = ComputeTimeInterval(operatingPoint.Acceleration, ds);
DataBus.BreakPower = breakingPower;
DataBus.BreakPower = brakePower;
var response =
(ResponseDryRun)
NextComponent.Request(absTime, operatingPoint.SimulationInterval, operatingPoint.Acceleration, gradient, true);
......@@ -494,7 +494,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return operatingPoint;
}
debug.Add(new { breakingPower, searchInterval, delta, operatingPoint });
debug.Add(new { brakePower, searchInterval, delta, operatingPoint });
// check if a correct searchInterval was found (when the delta changed signs, we stepped through the 0-point)
// from then on the searchInterval can be bisected.
......@@ -504,7 +504,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
}
searchInterval *= intervalFactor;
breakingPower += searchInterval * -delta.Sign();
brakePower += searchInterval * -delta.Sign();
} while (retryCount++ < Constants.SimulationSettings.DriverSearchLoopThreshold);
LogManager.EnableLogging();
......
using System.Diagnostics;
using System.Dynamic;
using TUGraz.VectoCore.Configuration;
using TUGraz.VectoCore.Exceptions;
using TUGraz.VectoCore.Models.Connector.Ports;
......@@ -249,10 +248,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
};
}
//if (DataBus.VehicleSpeed.IsEqual(0)) {
// Gear = _strategy.Engage(torque, angularVelocity, Data.SkipGears);
//}
var response = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), null);
response.GearboxPowerRequest = outTorque * outAngularVelocity;
......@@ -268,27 +263,27 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
/// <item><term>else</term><description>Response from NextComponent.</description></item>
/// </list>
/// </returns>
private IResponse RequestGearEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed,
private IResponse RequestGearEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
bool dryRun)
{
// Set a Gear if no gear was set and engineSpeed is not zero
if (_disengaged && !outEngineSpeed.IsEqual(0)) {
if (_disengaged && !outAngularVelocity.IsEqual(0)) {
_disengaged = false;
if (DataBus.VehicleStopped) {
Gear = _strategy.InitGear(absTime, dt, outTorque, outEngineSpeed);
Gear = _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity);
} else {
Gear = _strategy.Engage(absTime, dt, outTorque, outEngineSpeed);
Gear = _strategy.Engage(absTime, dt, outTorque, outAngularVelocity);
}
Log.Debug("Gearbox engaged gear {0}", Gear);
}
var inEngineSpeed = outEngineSpeed * Data.Gears[Gear].Ratio;
var inTorque = (outEngineSpeed.IsEqual(0))
var inEngineSpeed = outAngularVelocity * Data.Gears[Gear].Ratio;
var inTorque = (outAngularVelocity.IsEqual(0))
? outTorque / Data.Gears[Gear].Ratio
: Data.Gears[Gear].LossMap.GearboxInTorque(inEngineSpeed, outTorque);
_powerLoss = inTorque * inEngineSpeed - outTorque * outEngineSpeed;
_powerLoss = inTorque * inEngineSpeed - outTorque * outAngularVelocity;
if (!inEngineSpeed.IsEqual(0)) {
_powerLossInertia = Formulas.InertiaPower(inEngineSpeed, _previousInAngularSpeed, Data.Inertia, dt);
......@@ -299,32 +294,36 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
if (dryRun) {
var dryRunResponse = NextComponent.Request(absTime, dt, inTorque, inEngineSpeed, true);
dryRunResponse.GearboxPowerRequest = outTorque * outEngineSpeed;
dryRunResponse.GearboxPowerRequest = outTorque * outAngularVelocity;
return dryRunResponse;
}
if (!inEngineSpeed.IsEqual(0)) {
if (_strategy.ShiftRequired(absTime, dt, outTorque, outEngineSpeed, inTorque, inEngineSpeed, Gear,
_shiftTime + Data.TractionInterruption)) {
var shiftAllowed = !inEngineSpeed.IsEqual(0) && !DataBus.VehicleSpeed.IsEqual(0);
if (shiftAllowed) {
var shiftRequired = _strategy.ShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque, inEngineSpeed,
Gear, _shiftTime + Data.TractionInterruption);
if (shiftRequired) {
_shiftTime = absTime + Data.TractionInterruption;
Log.Debug("Gearbox is shifting. absTime: {0}, dt: {1}, shiftTime: {2}, out: ({3}, {4}), in: ({5}, {6})", absTime,
dt, _shiftTime, outTorque, outEngineSpeed, inTorque, inEngineSpeed);
dt, _shiftTime, outTorque, outAngularVelocity, inTorque, inEngineSpeed);
_disengaged = true;
_strategy.Disengage(absTime, dt, outTorque, outEngineSpeed);
_strategy.Disengage(absTime, dt, outTorque, outAngularVelocity);
Log.Info("Gearbox disengaged");
return new ResponseGearShift {
Source = this,
SimulationInterval = Data.TractionInterruption,
GearboxPowerRequest = outTorque * outEngineSpeed
GearboxPowerRequest = outTorque * outAngularVelocity
};
}
}
var response = NextComponent.Request(absTime, dt, inTorque, inEngineSpeed);
response.GearboxPowerRequest = outTorque * outEngineSpeed;
response.GearboxPowerRequest = outTorque * outAngularVelocity;
_previousInAngularSpeed = inEngineSpeed;
return response;
......@@ -345,7 +344,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
protected override void DoWriteModalResults(IModalDataWriter writer)
{
writer[ModalResultField.Gear] = _disengaged ? 0 : Gear;
writer[ModalResultField.Gear] = _disengaged || DataBus.VehicleStopped ? 0 : Gear;
writer[ModalResultField.PlossGB] = _powerLoss;
writer[ModalResultField.PaGB] = _powerLossInertia;
}
......
using System;
using TUGraz.VectoCore.Exceptions;
using TUGraz.VectoCore.Models.Connector.Ports.Impl;
using TUGraz.VectoCore.Models.Simulation.DataBus;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
......@@ -8,9 +7,13 @@ using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
/// <summary>
/// Class ShiftStrategy is a base class for shift strategies. Implements some helper methods for checking the shift curves.
/// </summary>
public abstract class ShiftStrategy : IShiftStrategy
{
protected IDataBus DataBus;
protected GearboxData Data;
protected ShiftStrategy(GearboxData data, IDataBus dataBus)
......@@ -20,17 +23,23 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
}
public abstract uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed);
public abstract void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed);
public abstract bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularSpeed, uint gear, Second lastShiftTime);
public abstract uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed);
public Gearbox Gearbox { get; set; }
/// <summary>
/// Tests if the operating point is below the down-shift curve (=outside of shift curve).
/// </summary>
/// <param name="gear">The gear.</param>
/// <param name="inTorque">The in torque.</param>
/// <param name="inEngineSpeed">The in engine speed.</param>
/// <returns><c>true</c> if the operating point is below the down-shift curv; otherwise, <c>false</c>.</returns>
protected virtual bool IsBelowDownShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
{
if (gear <= 1) {
......@@ -38,12 +47,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
}
var downSection = Data.Gears[gear].ShiftPolygon.Downshift.GetSection(entry => entry.AngularSpeed < inEngineSpeed);
if (downSection.Item2.AngularSpeed < inEngineSpeed) {
return false;
}
return IsOnLeftSide(inEngineSpeed, inTorque, downSection.Item1, downSection.Item2);
}
/// <summary>
/// Tests if the gearbox is above the up-shift curve (=outside of shift curve).
/// Tests if the operating point is above the up-shift curve (=outside of shift curve).
/// </summary>
/// <param name="gear">The gear.</param>
/// <param name="inTorque">The in torque.</param>
/// <param name="inEngineSpeed">The in engine speed.</param>
/// <returns><c>true</c> if the operating point is above the up-shift curve; otherwise, <c>false</c>.</returns>
protected virtual bool IsAboveUpShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
{
if (gear >= Data.Gears.Count) {
......@@ -51,16 +68,24 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
}
var upSection = Data.Gears[gear].ShiftPolygon.Upshift.GetSection(entry => entry.AngularSpeed < inEngineSpeed);
if (upSection.Item2.AngularSpeed < inEngineSpeed) {
return true;
}
return IsOnRightSide(inEngineSpeed, inTorque, upSection.Item1, upSection.Item2);
}
/// <summary>
/// Tests if current power request is left or right of the shiftpolygon segment
/// Tests if current power request is on the left side of the shiftpolygon segment
/// </summary>
/// <remarks>
/// Computes a simplified cross product for the vectors: from-->X, from-->to and checks
/// if the z-component is positive (which means that X was on the right side of from-->to).
/// </remarks>
/// <param name="angularSpeed">The angular speed.</param>
/// <param name="torque">The torque.</param>
/// <param name="from">From.</param>
/// <param name="to">To.</param>
/// <returns><c>true</c> if current power request is on the left side of the shiftpolygon segment; otherwise, <c>false</c>.</returns>
/// <remarks>Computes a simplified cross product for the vectors: from--X, from--to and checks
/// if the z-component is positive (which means that X was on the right side of from--to).</remarks>
private static bool IsOnLeftSide(PerSecond angularSpeed, NewtonMeter torque, ShiftPolygon.ShiftPolygonEntry from,
ShiftPolygon.ShiftPolygonEntry to)
{
......@@ -71,12 +96,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
}
/// <summary>
/// Tests if current power request is left or right of the shiftpolygon segment
/// Tests if current power request is on the left side of the shiftpolygon segment
/// </summary>
/// <remarks>
/// Computes a simplified cross product for the vectors: from-->X, from-->to and checks
/// if the z-component is negative (which means that X was on the left side of from-->to).
/// </remarks>
/// <param name="angularSpeed">The angular speed.</param>
/// <param name="torque">The torque.</param>
/// <param name="from">From.</param>
/// <param name="to">To.</param>
/// <returns><c>true</c> if current power request is on the left side of the shiftpolygon segment; otherwise, <c>false</c>.</returns>
/// <remarks>Computes a simplified cross product for the vectors: from--X, from--to and checks
/// if the z-component is negative (which means that X was on the left side of from--to).</remarks>
private static bool IsOnRightSide(PerSecond angularSpeed, NewtonMeter torque, ShiftPolygon.ShiftPolygonEntry from,
ShiftPolygon.ShiftPolygonEntry to)
{
......@@ -87,6 +115,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
}
}
/// <summary>
/// AMTShiftStrategy implements the AMT Shifting Behaviour.
/// </summary>
public class AMTShiftStrategy : ShiftStrategy
{
/// <summary>
......@@ -99,54 +130,32 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
PreviousGear = 1;
}
private uint GetGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularSpeed, bool skipGears,
double torqueReserve)
{
// maxGear ratio must not result in a angularSpeed below idle-speed
var maxGear = (uint)(skipGears ? Data.Gears.Count : Math.Min(PreviousGear + 1, Data.Gears.Count));
var minGear = skipGears ? 1 : Math.Max(PreviousGear - 1, 1);
while (outAngularSpeed * Data.Gears[maxGear].Ratio < DataBus.EngineIdleSpeed && maxGear > minGear) {
maxGear--;
private bool SpeedTooLowForEngine(uint gear, PerSecond outAngularSpeed)
{
return (outAngularSpeed * Data.Gears[NextGear].Ratio).IsSmaller(DataBus.EngineIdleSpeed);
}
// minGear ratio must not result in an angularSpeed above ratedspeed-range * 1.2
while ((outAngularSpeed * Data.Gears[minGear].Ratio - DataBus.EngineIdleSpeed) /
(DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) >= 1.2 && minGear < maxGear) {
minGear++;
// 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[NextGear].Ratio).IsGreaterOrEqual(1.2 * DataBus.EngineRatedSpeed -
0.2 * DataBus.EngineIdleSpeed);
}
// loop only runs from maxGear to minGear+1 because minGear is returned afterwards anyway.
for (var gear = maxGear; gear > minGear; gear--) {
Gearbox.Gear = gear;
var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularSpeed, true);
var currentPower = response.EnginePowerRequest;
var fullLoadPower = currentPower - response.DeltaFullLoad;
var reserve = 1 - (currentPower / fullLoadPower).Cast<Scalar>();
var inAngularSpeed = outAngularSpeed * Data.Gears[gear].Ratio;
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 >= torqueReserve) {
return gear;
}
// if over the up shift curve: return the previous gear (although it did not provide the required torque reserve)
if (IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) && gear < maxGear) {
return gear + 1;
}
public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
{
while (NextGear > 1 && SpeedTooLowForEngine(NextGear, outAngularVelocity)) {
NextGear--;
}
return minGear;
while (NextGear < Data.Gears.Count && SpeedTooHighForEngine(NextGear, outAngularVelocity)) {
NextGear++;
}
public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
{
return GetGear(absTime, dt, outTorque, outEngineSpeed, Data.SkipGears, Data.TorqueReserve);
return NextGear;
}
public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
......@@ -154,58 +163,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
PreviousGear = Gearbox.Gear;
}
public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
{
if (DataBus.VehicleStopped) {
return false;
}
var minimumShiftTimePassed = (lastShiftTime + Data.ShiftTime).IsSmallerOrEqual(absTime);
if (!minimumShiftTimePassed) {
return false;
}
var speedTooLowForEngine = inAngularVelocity < DataBus.EngineIdleSpeed;
var speedToHighForEngine = (inAngularVelocity * Data.Gears[gear].Ratio - DataBus.EngineIdleSpeed) /
(DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) >= 1.2;
// if angularSpeed is too high or too low to operate the engine, a shift is needed, regardless of shiftTime
if (gear > 1 && speedTooLowForEngine || gear < Data.Gears.Count && speedToHighForEngine) {
return true;
}
// todo: simulate traction interruption power request change after shift
// and only shift if simulated power request still fullfills the shift conditions.
if (IsBelowDownShiftCurve(gear, inTorque, inAngularVelocity) ||
IsAboveUpShiftCurve(gear, inTorque, inAngularVelocity)) {
return true;
}
if (Data.EarlyShiftUp && gear < Data.Gears.Count) {
// try if next gear would provide enough torque reserve
var nextGear = gear + 1;
//todo: is initialize correct? shouldnt it be a dry run request? but gear has to be set in advance
var response = Gearbox.Initialize(nextGear, outTorque, outAngularVelocity);
var nextAngularVelocity = Data.Gears[nextGear].Ratio * outAngularVelocity;
if (!IsBelowDownShiftCurve(nextGear, response.ClutchPowerRequest / nextAngularVelocity, nextAngularVelocity)) {
var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
var reserve = 1 - (response.EnginePowerRequest / fullLoadPower).Cast<Scalar>();
if (reserve >= Data.TorqueReserve) {
return true;
}
}
}
return false;
}
public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
{
if (DataBus.VehicleSpeed.IsEqual(0)) {
......@@ -254,6 +211,98 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
// 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).IsSmaller(absTime);
if (!minimumShiftTimePassed) {
return false;
}
// down shift
while (IsBelowDownShiftCurve(NextGear, inTorque, inAngularVelocity)) {
NextGear--;
if (!Data.SkipGears) {
break;
}
var tmpGear = Gearbox.Gear;
Gearbox.Gear = NextGear;
var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
Gearbox.Gear = tmpGear;
inAngularVelocity = Data.Gears[NextGear].Ratio * outAngularVelocity;
inTorque = response.ClutchPowerRequest / inAngularVelocity;
}
if (NextGear != gear) {
return true;
}
// upshift
while (IsAboveUpShiftCurve(NextGear, inTorque, inAngularVelocity)) {
NextGear++;
if (!Data.SkipGears) {
break;
}
var tmpGear = Gearbox.Gear;
Gearbox.Gear = NextGear;
var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
Gearbox.Gear = tmpGear;
inAngularVelocity = Data.Gears[NextGear].Ratio * outAngularVelocity;
inTorque = response.ClutchPowerRequest / inAngularVelocity;
}
// early up shift to higher gear ---------------------------------------
if (Data.EarlyShiftUp && NextGear < Data.Gears.Count) {
// try if next gear would provide enough torque reserve
var tryNextGear = NextGear + 1;
var tmpGear = Gearbox.Gear;
Gearbox.Gear = tryNextGear;
var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
Gearbox.Gear = tmpGear;
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).Cast<Scalar>();
if (reserve >= Data.TorqueReserve) {
NextGear = tryNextGear;
}
}
}
return (NextGear != gear);
}
public uint NextGear { get; set; }
}
//TODO Implement MTShiftStrategy
......@@ -263,12 +312,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
......@@ -278,10 +327,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
throw new NotImplementedException();
}
public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
}
......@@ -292,12 +340,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
......@@ -307,10 +355,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
throw new NotImplementedException();
}
public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
}
......@@ -319,7 +366,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
public CustomShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus) {}
public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
NewtonMeter inTorque,
PerSecond inAngularSpeed, uint gear, Second lastShiftTime)
......
......@@ -925,6 +925,7 @@ namespace TUGraz.VectoCore.Utils
/// Returns the numerical sign of the SI.
/// </summary>
/// <returns>-1 if si &lt; 0. 0 if si==0, 1 if si &gt; 0.</returns>
[DebuggerHidden]
public int Sign()
{
return Math.Sign(Val);
......
......@@ -104,7 +104,7 @@ namespace TUGraz.VectoCore.Tests.Integration
TorqueReserve = 0.2,
StartTorqueReserve = 0.2,
SkipGears = true,
EarlyShiftUp = false,
EarlyShiftUp = true,
};
}
......
......@@ -61,7 +61,7 @@ namespace TUGraz.VectoCore.Tests.Utils
.Select(v => v.Field<string>(ModalResultField.v_targ.GetName()))
.Select(v => string.IsNullOrWhiteSpace(v) ? "0" : v);
values += string.Format("|{0}|{1}", string.Join(",", x), string.Join(",", y3));
values += string.Format("|{0}|{1}|0|0", string.Join(",", x), string.Join(",", y3));
}
values = values.Replace("NaN", "0");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment