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

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

retartder: handle null requests

driver: limiting acceleration / deceleration
parent 99b469cd
No related branches found
No related tags found
No related merge requests found
......@@ -130,7 +130,7 @@ namespace TUGraz.VectoCore.Models.Declaration
{
public const bool Enabled = true;
public static MeterPerSquareSecond Deceleration = -0.5.SI<MeterPerSquareSecond>();
public static readonly MeterPerSquareSecond Deceleration = -0.5.SI<MeterPerSquareSecond>();
public static readonly MeterPerSecond MinimumSpeed = 50.KMPHtoMeterPerSecond();
}
......
......@@ -132,13 +132,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
// unhandled response (overload, delta > 0) - we need to search for a valid operating point..
operatingPoint = SearchOperatingPoint(absTime, ds, gradient, operatingPoint.Acceleration, response);
operatingPoint = LimitAccelerationByDriverModel(operatingPoint, false);
operatingPoint = LimitAccelerationByDriverModel(operatingPoint, LimitationMode.LimitDecelerationDriver);
Log.Debug("Found operating point for Drive/Accelerate. dt: {0}, acceleration: {1}",
CurrentState.dt, CurrentState.Acceleration);
retVal = NextComponent.Request(absTime, operatingPoint.SimulationInterval, operatingPoint.Acceleration, gradient);
retVal.Switch().
Case<ResponseUnderload>().
Case<ResponseGearShift>().
Case<ResponseSuccess>().
Default(r => {
throw new UnexpectedResponseException("DrivingAction Accelerate after SearchOperatingPoint.", r);
......@@ -163,7 +164,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
Log.Debug("DrivingAction Coast");
return CoastOrRollAction(absTime, ds, maxVelocity, gradient);
return CoastOrRollAction(absTime, ds, maxVelocity, gradient, false);
}
/// <summary>
......@@ -178,7 +179,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
Log.Debug("DrivingAction Roll");
var retVal = CoastOrRollAction(absTime, ds, maxVelocity, gradient);
var retVal = CoastOrRollAction(absTime, ds, maxVelocity, gradient, true);
retVal.Switch().
Case<ResponseGearShift>(() => {
throw new UnexpectedResponseException("DrivingAction Roll: Gearshift during Roll action.", retVal);
......@@ -193,6 +194,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
/// <param name="ds"></param>
/// <param name="maxVelocity"></param>
/// <param name="gradient"></param>
/// <param name="rollAction"></param>
/// <returns>
/// * ResponseSuccess
/// * ResponseDrivingCycleDistanceExceeded: vehicle is at low speed, coasting would lead to stop before ds is reached.
......@@ -201,7 +203,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
/// * ResponseGearShift: gearbox needs to shift gears, vehicle can not accelerate (traction interruption)
/// * ResponseFailTimeInterval:
/// </returns>
protected IResponse CoastOrRollAction(Second absTime, Meter ds, MeterPerSecond maxVelocity, Radian gradient)
protected IResponse CoastOrRollAction(Second absTime, Meter ds, MeterPerSecond maxVelocity, Radian gradient,
bool rollAction)
{
var operatingPoint = ComputeAcceleration(ds, DataBus.VehicleSpeed);
......@@ -228,7 +231,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
Log.Debug("Found operating point for coasting. dt: {0}, acceleration: {1}", operatingPoint.SimulationInterval,
operatingPoint.Acceleration);
operatingPoint = LimitAccelerationByDriverModel(operatingPoint, true);
operatingPoint = LimitAccelerationByDriverModel(operatingPoint,
rollAction ? LimitationMode.NoLimitation : LimitationMode.LimitDecelerationLookahead);
CurrentState.Acceleration = operatingPoint.Acceleration;
CurrentState.dt = operatingPoint.SimulationInterval;
......@@ -245,7 +249,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
retVal.Switch().
Case<ResponseSuccess>().
Case<ResponseUnderload>(). // driver limits acceleration, operating point may be below engine's drag load
Case<ResponseUnderload>(). // driver limits acceleration, operating point may be below engine's
//drag load resp. below 0
//Case<ResponseOverload>(). // driver limits acceleration, operating point may be above 0 (GBX), use brakes
Case<ResponseGearShift>().
Case<ResponseFailTimeInterval>(r => {
retVal = new ResponseDrivingCycleDistanceExceeded() {
......@@ -340,19 +346,33 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
///
/// </summary>
/// <param name="operatingPoint"></param>
/// <param name="limitByLookahead"></param>
/// <param name="limits"></param>
/// <returns></returns>
private OperatingPoint LimitAccelerationByDriverModel(OperatingPoint operatingPoint, bool limitByLookahead)
private OperatingPoint LimitAccelerationByDriverModel(OperatingPoint operatingPoint,
LimitationMode limits)
{
// todo: limit by driver model!
if (limitByLookahead && operatingPoint.Acceleration < DeclarationData.Driver.LookAhead.Deceleration) {
Log.Debug("Limiting coasting deceleration from {0} to {1}", CurrentState.Acceleration,
DeclarationData.Driver.LookAhead.Deceleration);
operatingPoint.Acceleration = DeclarationData.Driver.LookAhead.Deceleration;
var limitApplied = false;
var originalAcceleration = operatingPoint.Acceleration;
if (((limits & LimitationMode.LimitDecelerationLookahead) != 0) &&
operatingPoint.Acceleration < LookaheadDeceleration) {
operatingPoint.Acceleration = LookaheadDeceleration;
limitApplied = true;
}
var accelerationLimits = DriverData.AccelerationCurve.Lookup(DataBus.VehicleSpeed);
if (operatingPoint.Acceleration > accelerationLimits.Acceleration) {
operatingPoint.Acceleration = accelerationLimits.Acceleration;
limitApplied = true;
}
if (((limits & LimitationMode.LimitDecelerationDriver) != 0) &&
operatingPoint.Acceleration < accelerationLimits.Deceleration) {
operatingPoint.Acceleration = accelerationLimits.Deceleration;
limitApplied = true;
}
if (limitApplied) {
operatingPoint.SimulationInterval =
ComputeTimeInterval(operatingPoint.Acceleration, operatingPoint.SimulationDistance).SimulationInterval;
Log.Debug("Changed dt due to limited coasting deceleration. dt: {0}", CurrentState.dt);
Log.Debug("Limiting acceleration from {0} to {1}, dt: {2}", originalAcceleration,
operatingPoint.Acceleration, operatingPoint.SimulationInterval);
}
return operatingPoint;
}
......@@ -492,18 +512,22 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
searchInterval *= intervalFactor;
retVal.Acceleration += searchInterval * -delta.Sign();
if (retVal.Acceleration < (DriverData.AccelerationCurve.MaxDeceleration() - searchInterval)
if (retVal.Acceleration < (10 * DriverData.AccelerationCurve.MaxDeceleration() - searchInterval)
|| retVal.Acceleration > (DriverData.AccelerationCurve.MaxAcceleration() + searchInterval)) {
LogManager.EnableLogging();
Log.Warn("Operating Point outside driver acceleration limits: a: {0}", retVal.Acceleration);
LogManager.DisableLogging();
throw new VectoSimulationException(
"Could not find an operating point: operating point outside of driver acceleration limits.");
"Could not find an operating point: operating point outside of driver acceleration limits. a: {0}",
retVal.Acceleration);
}
// TODO: move to driving mode
// check for minimum acceleration, add some safety margin due to search
if (!coasting && retVal.Acceleration.Abs() < Constants.SimulationSettings.MinimumAcceleration / 5.0
&& searchInterval.Abs() < Constants.SimulationSettings.MinimumAcceleration / 20.0) {
throw new VectoSimulationException("Could not achieve minimum acceleration");
}
//if (!coasting && retVal.Acceleration.Abs() < Constants.SimulationSettings.MinimumAcceleration / 5.0
// && searchInterval.Abs() < Constants.SimulationSettings.MinimumAcceleration / 20.0) {
// throw new VectoSimulationException("Could not achieve minimum acceleration");
//}
var tmp = ComputeTimeInterval(retVal.Acceleration, ds);
retVal.SimulationInterval = tmp.SimulationInterval;
......@@ -701,5 +725,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public Meter SimulationDistance;
public Second SimulationInterval;
}
[Flags]
protected enum LimitationMode
{
NoLimitation = 0x0,
//LimitAccelerationDriver = 0x1,
LimitDecelerationDriver = 0x2,
LimitDecelerationLookahead = 0x4
}
}
}
\ No newline at end of file
......@@ -45,6 +45,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public IResponse Request(Second absTime, Second dt, NewtonMeter torque, PerSecond angularVelocity, bool dryRun = false)
{
if (angularVelocity == null) {
return NextComponent.Request(absTime, dt, torque, null, dryRun);
}
var retarderTorqueLoss = _lossMap.RetarderLoss(angularVelocity);
_retarderLoss = retarderTorqueLoss * angularVelocity;
......
......@@ -119,6 +119,30 @@ namespace TUGraz.VectoCore.Tests.Integration.DriverStrategy
CreatePowerTrain(cycle, "DriverStrategy_Accelerate_0_85_level.vmod").Run();
}
[TestMethod]
public void Accelerate_0_85_uphill_1()
{
var cycle = CreateCycleData(new[] {
// <s>,<v>,<grad>,<stop>
" 0, 0, 0, 2",
" 0, 85, 1, 0",
"1000, 85, 1, 0",
});
CreatePowerTrain(cycle, "DriverStrategy_Accelerate_0_85_uphill_1.vmod").Run();
}
[TestMethod]
public void Accelerate_0_85_uphill_2()
{
var cycle = CreateCycleData(new[] {
// <s>,<v>,<grad>,<stop>
" 0, 0, 0, 2",
" 0, 85, 2, 0",
"1000, 85, 2, 0",
});
CreatePowerTrain(cycle, "DriverStrategy_Accelerate_0_85_uphill_2.vmod").Run();
}
[TestMethod]
public void Accelerate_0_85_uphill_5()
{
......@@ -173,8 +197,8 @@ namespace TUGraz.VectoCore.Tests.Integration.DriverStrategy
var cycle = CreateCycleData(new[] {
// <s>,<v>,<grad>,<stop>
" 0, 0, 0, 2",
" 0, 85, 15, 0",
"1000, 85, 15, 0",
" 0, 85, 10, 0",
"1000, 85, 10, 0",
});
CreatePowerTrain(cycle, "DriverStrategy_Accelerate_0_85_uphill_15.vmod").Run();
}
......@@ -585,7 +609,7 @@ namespace TUGraz.VectoCore.Tests.Integration.DriverStrategy
tmp = Port.AddComponent(tmp, new Clutch(container, engineData));
var aux = new Auxiliary(container);
aux.AddConstant("", 500.SI<Watt>());
aux.AddConstant("", 0.SI<Watt>());
tmp = Port.AddComponent(tmp, aux);
......
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TUGraz.VectoCore.Configuration;
using TUGraz.VectoCore.Exceptions;
using TUGraz.VectoCore.FileIO.Reader.Impl;
using TUGraz.VectoCore.Models.Connector.Ports.Impl;
using TUGraz.VectoCore.Models.Simulation.Data;
using TUGraz.VectoCore.Models.Simulation.Impl;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
......@@ -194,6 +198,71 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
modalData.Finish();
}
[TestMethod]
public void EngineIdleJump()
{
var vehicleContainer = new VehicleContainer();
var gearbox = new MockGearbox(vehicleContainer);
var engineData = EngineeringModeSimulationDataReader.CreateEngineDataFromFile(CoachEngine);
var engine = new CombustionEngine(vehicleContainer, engineData);
var clutch = new Clutch(vehicleContainer, engineData);
var aux = new Auxiliary(vehicleContainer);
aux.AddConstant("", 5000.SI<Watt>());
gearbox.Gear = 1;
//gearbox.InPort().Connect(engine.OutPort());
gearbox.InPort().Connect(clutch.OutPort());
clutch.InPort().Connect(aux.OutPort());
aux.InPort().Connect(engine.OutPort());
// var expectedResults = VectoCSVFile.Read(TestContext.DataRow["ResultFile"].ToString());
var requestPort = gearbox.OutPort();
//vehicleContainer.DataWriter = new ModalDataWriter("engine_idle_test.csv");
var dataWriter = new MockModalDataWriter();
vehicleContainer.DataWriter = dataWriter;
var torque = 1200.SI<NewtonMeter>();
var angularVelocity = 800.RPMtoRad();
// initialize engine...
gearbox.Initialize(torque, angularVelocity);
var absTime = 0.SI<Second>();
var dt = Constants.SimulationSettings.TargetTimeInterval;
var response = requestPort.Request(absTime, dt, torque, angularVelocity);
Assert.IsInstanceOfType(response, typeof(ResponseSuccess));
vehicleContainer.CommitSimulationStep(absTime, dt);
var row = dataWriter.Data.Rows.Cast<DataRow>().Last();
Assert.AreEqual(105530.96491487339.SI<Watt>(), row[ModalResultField.Pe_eng.GetName()]);
Assert.AreEqual(5000.SI<Watt>(), row[ModalResultField.Paux.GetName()]);
Assert.AreEqual(800.RPMtoRad(), row[ModalResultField.n.GetName()]);
absTime += dt;
// actual test...
gearbox.Gear = 0;
torque = 0.SI<NewtonMeter>();
response = gearbox.Request(absTime, dt, torque, angularVelocity);
Assert.IsInstanceOfType(response, typeof(ResponseSuccess));
vehicleContainer.CommitSimulationStep(absTime, dt);
row = dataWriter.Data.Rows.Cast<DataRow>().Last();
Assert.AreEqual(5000.SI<Watt>(), row[ModalResultField.Pe_eng.GetName()]);
Assert.AreEqual(5000.SI<Watt>(), row[ModalResultField.Paux.GetName()]);
Assert.AreEqual(800.RPMtoRad(), row[ModalResultField.n.GetName()]);
}
[TestMethod, Ignore]
public void TestWriteToFile()
......
......@@ -53,8 +53,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
tmp = AddComponent(tmp, new Clutch(vehicleContainer, engineData));
AddComponent(tmp, engine);
var gbx = new MockGearbox(vehicleContainer);
gbx.Gear = 1;
var gbx = new MockGearbox(vehicleContainer) { Gear = 1 };
var driverPort = driver.OutPort();
......
......@@ -2,12 +2,13 @@
using TUGraz.VectoCore.Models.Connector.Ports;
using TUGraz.VectoCore.Models.Simulation;
using TUGraz.VectoCore.Models.Simulation.Data;
using TUGraz.VectoCore.Models.Simulation.DataBus;
using TUGraz.VectoCore.Models.SimulationComponent;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Tests.Utils
{
public class MockGearbox : VectoSimulationComponent, IGearbox, ITnInPort, ITnOutPort
public class MockGearbox : VectoSimulationComponent, IGearbox, ITnInPort, ITnOutPort, IClutchInfo
{
private ITnOutPort _outPort;
......@@ -33,11 +34,20 @@ namespace TUGraz.VectoCore.Tests.Utils
public IResponse Request(Second absTime, Second dt, NewtonMeter torque, PerSecond engineSpeed, bool dryRun = false)
{
if (_outPort != null) {
if (Gear > 0) {
return _outPort.Request(absTime, dt, torque, engineSpeed, dryRun);
}
return _outPort.Request(absTime, dt, 0.SI<NewtonMeter>(), null, dryRun);
}
throw new NotImplementedException();
}
public IResponse Initialize(NewtonMeter torque, PerSecond angularVelocity)
{
if (_outPort != null) {
return _outPort.Initialize(torque, angularVelocity);
}
throw new NotImplementedException();
}
......@@ -48,5 +58,10 @@ namespace TUGraz.VectoCore.Tests.Utils
}
protected override void DoCommitSimulationStep() {}
public bool ClutchClosed(Second absTime)
{
return true;
}
}
}
\ 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