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 53dad7a0 authored by Stefanos DOUMPOULAKIS's avatar Stefanos DOUMPOULAKIS
Browse files

Merge branch 'feature/CodeEU-270_low-motorized-primary-bus' into 'amdm2/develop'

implement feature to asses whether a simulation abort may be caused due to low motorization (primary bus simulation)

See merge request vecto/vecto!153
parents d0888cb4 9fda42da
Branches
Tags
No related merge requests found
Showing
with 398 additions and 81 deletions
......@@ -2,7 +2,9 @@
using System.IO;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Threading;
using VECTO3GUI2020.Properties;
using Application = System.Windows.Application;
using MessageBox = System.Windows.MessageBox;
namespace VECTO3GUI2020.Helper
......@@ -143,12 +145,22 @@ namespace VECTO3GUI2020.Helper
MessageBoxButton button,
MessageBoxImage icon)
{
return MessageBox.Show(messageBoxText, caption, button, icon);
var t = Application.Current.Dispatcher
.InvokeAsync(() => MessageBox.Show(messageBoxText, caption, button, icon)).Task;
t.Wait();
return t.Result;
//return MessageBox.Show(messageBoxText, caption, button, icon);
}
public MessageBoxResult ShowMessageBox(string messageBoxText, string caption)
{
return MessageBox.Show(messageBoxText, caption);
var t = Application.Current.Dispatcher
.InvokeAsync(() => MessageBox.Show(messageBoxText, caption)).Task;
t.Wait();
return t.Result;
//return MessageBox.Show(messageBoxText, caption);
}
......
......@@ -585,6 +585,10 @@ namespace VECTO3GUI2020.ViewModel.Implementation
Type = MessageType.ErrorMessage,
Message = ex.Message
});
DialogHelper.ShowErrorMessage(
$"ERROR running job {Path.GetFileName(jobEntry.DataSource.SourceFile)}: {ex.Message}", "Error");
status.Report($"Failed to initialize Simulation");
return;
}
}
foreach (var cycle in jobContainer.GetCycleTypes())
......
......@@ -1172,10 +1172,16 @@ namespace TUGraz.VectoCommon.InputData
IList<IResult> Results { get; }
}
public enum ResultStatus
{
Success,
Error,
PrimaryRunIgnored
}
public interface IResult
{
string ResultStatus { get; }
ResultStatus ResultStatus { get; }
VehicleClass VehicleGroup { get; }
......
......@@ -836,7 +836,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
_manufacturerResults = new ManufacturerResults(xmlDoc.SelectSingleNode("//*[local-name() = 'Results']"));
_vehicleLenght = xmlDoc.SelectSingleNode("//*[local-name() = 'VehicleLength']")?.InnerText.ToDouble().SI<Meter>();
_vehicleClass = VehicleClassHelper.Parse(xmlDoc.SelectSingleNode("//*[local-name() = 'VehicleGroup']").InnerText);
_vehicleClass = VehicleClassHelper.Parse(xmlDoc.SelectSingleNode("//*[local-name() = 'VehicleGroup']")?.InnerText);
_vehicleCode = xmlDoc.SelectSingleNode("//*[local-name() = 'VehicleCode']")?.InnerText.ParseEnum<VehicleCode>() ?? VehicleCode.NOT_APPLICABLE;
}
}
......@@ -849,7 +849,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
Results = new List<IResult>();
foreach (XmlNode node in resultNode.SelectNodes("./*[local-name() = 'Result' and @status='success']")) {
var entry = new Result {
ResultStatus = node.Attributes.GetNamedItem("status").InnerText,
ResultStatus = node.Attributes.GetNamedItem("status").InnerText.ParseEnum<ResultStatus>(),
Mission = node.SelectSingleNode("./*[local-name()='Mission']").InnerText.ParseEnum<MissionType>(),
SimulationParameter = GetSimulationParameter(node.SelectSingleNode("./*[local-name() = 'SimulationParameters' or local-name() = 'SimulationParametersCompletedVehicle']")),
EnergyConsumption = node.SelectSingleNode("./*[local-name()='Fuel' and FuelConsumption/@unit='MJ/km']")?
......
......@@ -2,6 +2,7 @@
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using TUGraz.VectoCommon.Exceptions;
using TUGraz.VectoCommon.InputData;
using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Resources;
......@@ -54,7 +55,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider
private IList<IResult> GetResult(XmlNode xmlNode)
{
var resultStatus = GetAttribute(xmlNode, XMLNames.Result_Status);
var resultStatus = GetAttribute(xmlNode, XMLNames.Result_Status).ParseEnum<ResultStatus>();
var vehicleGroup = GetString(XMLNames.Report_Results_PrimaryVehicleSubgroup, xmlNode);
var mission = GetString(XMLNames.Report_Result_Mission, xmlNode).ParseEnum<MissionType>();
var simulationNode = GetNode(XMLNames.Report_ResultEntry_SimulationParameters, xmlNode);
......@@ -66,9 +67,9 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider
var retVal = new List<IResult>();
foreach (XmlNode node in ovcModes) {
var ovcMode = GetAttribute(node, XMLNames.Results_Report_OVCModeAttr).ParseEnum<OvcHevMode>();
GetEnergyConsumption(node, out var ovcEnergyConsumption, out var ovcElectricEnergyConsumption);
GetEnergyConsumption(node, out var ovcEnergyConsumption, out var ovcElectricEnergyConsumption, out var ovcIgnoredPrimaryRun);
retVal.Add(new Result {
ResultStatus = resultStatus,
ResultStatus = ovcIgnoredPrimaryRun ? ResultStatus.PrimaryRunIgnored : resultStatus,
Mission = mission,
VehicleGroup = VehicleClassHelper.Parse(vehicleGroup),
SimulationParameter = simulationParams,
......@@ -82,10 +83,10 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider
return retVal;
}
GetEnergyConsumption(xmlNode, out var energyConsumption, out var electricEnergyConsumption);
GetEnergyConsumption(xmlNode, out var energyConsumption, out var electricEnergyConsumption, out var ignoredPrimaryRun);
return new List<IResult>() {
new Result {
ResultStatus = resultStatus,
ResultStatus = ignoredPrimaryRun ? ResultStatus.PrimaryRunIgnored : resultStatus,
Mission = mission,
VehicleGroup = VehicleClassHelper.Parse(vehicleGroup),
SimulationParameter = simulationParams,
......@@ -98,19 +99,37 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider
}
private void GetEnergyConsumption(XmlNode xmlNode, out Dictionary<FuelType, JoulePerMeter> energyConsumption,
out JoulePerMeter electricEnergyConsumption)
out JoulePerMeter electricEnergyConsumption, out bool ignoredPrimaryRun)
{
var ignoredPrimaryRunTmp = false;
energyConsumption = GetNodes(XMLNames.Report_Results_Fuel, xmlNode)
.Cast<XmlNode>().Select(x => new KeyValuePair<FuelType, JoulePerMeter>(
GetAttribute(x, XMLNames.Report_Results_Fuel_Type_Attr).ParseEnum<FuelType>(),
x.SelectSingleNode(
$".//*[local-name()='{XMLNames.Report_Result_EnergyConsumption}' and @unit='MJ/km']")?.InnerText
.ToDouble().SI(Unit.SI.Mega.Joule.Per.Kilo.Meter).Cast<JoulePerMeter>())).ToDictionary(x => x.Key, x => x.Value);
electricEnergyConsumption = GetNode(XMLNames.Report_ResultEntry_VIF_ElectricEnergyConsumption, xmlNode, required:false)?
.Cast<XmlNode>().Select(x => {
var fuelType = GetAttribute(x, XMLNames.Report_Results_Fuel_Type_Attr).ParseEnum<FuelType>();
var consumption = x.SelectSingleNode(
$".//*[local-name()='{XMLNames.Report_Result_EnergyConsumption}' and @unit='MJ/km']")
?.InnerText.ToDouble();
if (consumption.HasValue && double.IsNaN(consumption.Value)) {
ignoredPrimaryRunTmp = true;
return new KeyValuePair<FuelType, JoulePerMeter>(fuelType,
null);
}
return new KeyValuePair<FuelType, JoulePerMeter>(fuelType,
consumption?.SI(Unit.SI.Mega.Joule.Per.Kilo.Meter).Cast<JoulePerMeter>());
}).ToDictionary(x => x.Key, x => x.Value);
var electricEnergyConsumptionValue = GetNode(XMLNames.Report_ResultEntry_VIF_ElectricEnergyConsumption, xmlNode, required:false)?
.SelectSingleNode(
$".//*[local-name()='{XMLNames.Report_Result_EnergyConsumption}' and @unit='MJ/km']")?.InnerText?
.ToDouble().SI(Unit.SI.Mega.Joule.Per.Kilo.Meter).Cast<JoulePerMeter>();
.ToDouble();
if (electricEnergyConsumptionValue.HasValue && double.IsNaN(electricEnergyConsumptionValue.Value)) {
ignoredPrimaryRunTmp = true;
electricEnergyConsumption = null;
} else {
electricEnergyConsumption = electricEnergyConsumptionValue?.SI(Unit.SI.Mega.Joule.Per.Kilo.Meter)
.Cast<JoulePerMeter>();
}
ignoredPrimaryRun = ignoredPrimaryRunTmp;
}
......
......@@ -266,10 +266,11 @@ namespace TUGraz.VectoCore.InputData.Impl
public IList<IResult> Results { get; internal set; }
}
[DebuggerDisplay("{ResultStatus} | {VehicleGroup} {Mission} {OvcMode}")]
public class Result : IResult
{
public string ResultStatus { get; internal set; }
public ResultStatus ResultStatus { get; internal set; }
public VehicleClass VehicleGroup { get; internal set; }
public MissionType Mission { get; internal set; }
public ISimulationParameter SimulationParameter { get; internal set; }
......
......@@ -171,14 +171,20 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl.DeclarationMode.CompletedBusRun
var primaryResult = DataProvider.MultistageJobInputData.JobInputData.PrimaryVehicle.GetResult(
simulationRunData.Mission.BusParameter.BusGroup, simulationRunData.Mission.MissionType, fuelMode,
simulationRunData.VehicleData.Loading, ovcHevMode);
if (primaryResult == null || !primaryResult.ResultStatus.Equals("success")) {
if (primaryResult == null) {
throw new VectoException(
"Failed to find results in PrimaryVehicleReport for vehicle group: {0}, mission: {1}, fuel mode: '{2}', payload: {3}. Make sure PIF and completed vehicle data match!",
simulationRunData.Mission.BusParameter.BusGroup, simulationRunData.Mission.MissionType, fuelMode,
simulationRunData.VehicleData.Loading);
}
if (primaryResult.ResultStatus != "success") {
if (primaryResult.ResultStatus == ResultStatus.PrimaryRunIgnored) {
throw new VectoException(
"The vehicle group of the complete(d) vehicle falls into a primary vehicle sub-group for which no result could be calculated due to the criterion of insufficient powertrain power. mission: {1}, fuel mode: '{2}', payload: {3}.",
simulationRunData.Mission.BusParameter.BusGroup, simulationRunData.Mission.MissionType, fuelMode,
simulationRunData.VehicleData.Loading);
}
if (primaryResult.ResultStatus != ResultStatus.Success) {
throw new VectoException(
"Simulation results in PrimaryVehicleReport for vehicle group: {0}, mission: {1}, fuel mode: '{2}', payload: {3} not finished successfully.",
simulationRunData.Mission.BusParameter.BusGroup, simulationRunData.Mission.MissionType, fuelMode,
......
......@@ -10,6 +10,7 @@ using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter;
using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponents;
using TUGraz.VectoCore.Models.Declaration;
using TUGraz.VectoCore.Models.Declaration.IterativeRunStrategies;
using TUGraz.VectoCore.Models.Declaration.PostMortemAnalysisStrategy;
using TUGraz.VectoCore.Models.Simulation.Data;
using TUGraz.VectoCore.Models.Simulation.Impl;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
......@@ -115,7 +116,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl.DeclarationMode.PrimaryBusRunDa
Cycle = new DrivingCycleProxy(cycle, mission.MissionType.ToString()),
ExecutionMode = ExecutionMode.Declaration,
};
simulationRunData.PostMortemStrategy = new PrimaryBusPostMortemStrategy();
return simulationRunData;
}
......@@ -539,6 +540,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl.DeclarationMode.PrimaryBusRunDa
runData.ModFileSuffix += ovcMode == OvcHevMode.ChargeSustaining ? "CS" : "CD";
}
runData.OVCMode = ovcMode;
return runData;
}
......
......@@ -185,14 +185,19 @@ namespace TUGraz.VectoMockup.Simulation.RundataFactories
var primaryResult = InputDataProvider.JobInputData.PrimaryVehicle.GetResult(
simulationRunData.Mission.BusParameter.BusGroup, simulationRunData.Mission.MissionType, fuelMode,
simulationRunData.VehicleData.Loading, OvcHevMode.NotApplicable);
if (primaryResult == null || !primaryResult.ResultStatus.Equals("success")) {
if (primaryResult == null) {
throw new VectoException(
"Failed to find results in PrimaryVehicleReport for vehicle group: {0}, mission: {1}, fuel mode: '{2}', payload: {3}. Make sure PIF and completed vehicle data match!",
simulationRunData.Mission.BusParameter.BusGroup, simulationRunData.Mission.MissionType, fuelMode,
simulationRunData.VehicleData.Loading);
}
if (primaryResult.ResultStatus != "success") {
if (primaryResult.ResultStatus == ResultStatus.PrimaryRunIgnored) {
throw new VectoException(
"The vehicle group of the complete(d) vehicle falls into a primary vehicle sub-group for which no result could be calculated due to the criterion of insufficient powertrain power. mission: {1}, fuel mode: '{2}', payload: {3}.",
simulationRunData.Mission.BusParameter.BusGroup, simulationRunData.Mission.MissionType, fuelMode,
simulationRunData.VehicleData.Loading);
}
if (primaryResult.ResultStatus != ResultStatus.Success) {
throw new VectoException(
"Simulation results in PrimaryVehicleReport for vehicle group: {0}, mission: {1}, fuel mode: '{2}', payload: {3} not finished successfully.",
simulationRunData.Mission.BusParameter.BusGroup, simulationRunData.Mission.MissionType, fuelMode,
......
......@@ -1734,7 +1734,8 @@ namespace TUGraz.VectoCore.Models.Declaration
VehicleOperationLookup.VehicleOperationData vehicleOperation,
(double etaChgBatDepot, double etaChgBatInMission, double etaChtBatWeighted) chargingEfficiency)
{
if (cdResult.Status != VectoRun.Status.Success || csResult.Status != VectoRun.Status.Success) {
if (!cdResult.Status.IsOneOf(VectoRun.Status.Success, VectoRun.Status.PrimaryBusSimulationIgnore) ||
!csResult.Status.IsOneOf(VectoRun.Status.Success, VectoRun.Status.PrimaryBusSimulationIgnore)) {
return null;
}
var batteryData = cdResult.BatteryData;
......@@ -1787,6 +1788,7 @@ namespace TUGraz.VectoCore.Models.Declaration
.ToDictionary(x => x.Item1, x => x.Item2);
var retVal = new WeightedResult() {
Status = cdResult.Status == VectoRun.Status.PrimaryBusSimulationIgnore || csResult.Status == VectoRun.Status.PrimaryBusSimulationIgnore ? VectoRun.Status.PrimaryBusSimulationIgnore : VectoRun.Status.Success,
Distance = cdResult.Distance,
Payload = cdResult.Payload,
CargoVolume = cdResult.CargoVolume,
......@@ -1889,6 +1891,7 @@ namespace TUGraz.VectoCore.Models.Declaration
var fuels = entries.First().FuelData;
return new WeightedResult() {
Status = VectoRun.Status.Success,
AverageSpeed = null,
AverageDrivingSpeed = null,
Distance = entries.Sum(e => e.Distance * e.WeightingFactor),
......@@ -1924,6 +1927,7 @@ namespace TUGraz.VectoCore.Models.Declaration
var fuels = entries.First().ChargeDepletingResult.FuelData;
return new WeightedResult() {
Status = VectoRun.Status.Success,
AverageSpeed = null,
AverageDrivingSpeed = null,
Distance = entries.Sum(e => e.ChargeDepletingResult.Distance * e.ChargeDepletingResult.WeightingFactor),
......
......@@ -35,7 +35,4 @@ namespace TUGraz.VectoCore.Models.Declaration.IterativeRunStrategies
{
//IIterativeRunResult CreateIterativeResult(IModalDataContainer modData);
}
}
\ No newline at end of file
using System;
using TUGraz.VectoCore.Models.Simulation;
namespace TUGraz.VectoCore.Models.Declaration.PostMortemAnalysisStrategy
{
public interface IPostMortemAnalyzeStrategy
{
bool AbortSimulation(IVehicleContainer container, Exception exception);
}
public class DefaultPostMortemAnalyzeStrategy : IPostMortemAnalyzeStrategy
{
#region Implementation of IPostMortemAnalyzeStrategy
public bool AbortSimulation(IVehicleContainer container, Exception exception)
{
return true;
}
#endregion
}
}
\ No newline at end of file
using System;
using System.Linq;
using TUGraz.VectoCommon.Exceptions;
using TUGraz.VectoCommon.InputData;
using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Configuration;
using TUGraz.VectoCore.Models.Connector.Ports.Impl;
using TUGraz.VectoCore.Models.Simulation;
using TUGraz.VectoCore.Models.Simulation.Impl;
using TUGraz.VectoCore.Models.SimulationComponent.Impl;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Models.Declaration.PostMortemAnalysisStrategy
{
public class PrimaryBusPostMortemStrategy : IPostMortemAnalyzeStrategy
{
protected static readonly MeterPerSecond MinSpeed = 5.KMPHtoMeterPerSecond();
#region Implementation of IPostMortemAnalyzeStrategy
public bool AbortSimulation(IVehicleContainer container, Exception exception)
{
if (container.RunData.Mission.MissionType != MissionType.Interurban) {
// for now only consider interurban cycle
return true;
}
if (container.RunData.Loading != LoadingType.ReferenceLoad) {
// for now only consider reference load
return true;
}
if (!container.RunData.Mission.BusParameter.DoubleDecker) {
// for now only consider double decker buses
return true;
}
if (!container.DrivingCycleInfo.RoadGradient.IsGreater(0)) {
// road gradient must be greater than 0
return true;
}
if (container.VehicleInfo.VehicleSpeed.IsGreater(MinSpeed)) {
// vehicle has to be almost stopped
return true;
}
var maxGradability = GetMaxGradability(container);
if (maxGradability.IsSmaller(container.DrivingCycleInfo.RoadGradient)) {
// the vehicle cannot go this steep uphill passage...
return false;
}
return true;
}
protected virtual Radian GetMaxGradability(IVehicleContainer container)
{
var testContainer = new SimplePowertrainContainer(container.RunData);
switch (container.PowertrainInfo.VehicleArchitecutre) {
//case VectoSimulationJobType.ConventionalVehicle:
// PowertrainBuilder.BuildSimplePowertrain(container.RunData, testContainer);
// break;
//case VectoSimulationJobType.ParallelHybridVehicle:
//case VectoSimulationJobType.IHPC:
// PowertrainBuilder.BuildSimpleHybridPowertrain(container.RunData, testContainer);
// break;
//case VectoSimulationJobType.SerialHybridVehicle:
// PowertrainBuilder.BuildSimpleSerialHybridPowertrain(container.RunData, testContainer);
// break;
//case VectoSimulationJobType.IEPC_S:
// PowertrainBuilder.BuildSimpleIEPCHybridPowertrain(container.RunData, testContainer);
// break;
case VectoSimulationJobType.BatteryElectricVehicle:
case VectoSimulationJobType.IEPC_E:
PowertrainBuilder.BuildSimplePowertrainElectric(container.RunData, testContainer);
break;
default:
throw new VectoException($"unhandled powertrain architecture {container.PowertrainInfo.VehicleArchitecutre} to calculate gradability");
}
testContainer.UpdateComponents(container);
var maxSlope = SearchSlope(testContainer);
return maxSlope;
}
protected virtual Radian SearchSlope(SimplePowertrainContainer container)
{
var simulationInterval = Constants.SimulationSettings.TargetTimeInterval;
var absTime = 0.SI<Second>();
var gradient = 0.SI<Radian>();
var vehicle = container.VehiclePort;
var acceleration = DeclarationData.GearboxTCU.StartAcceleration * 0.5;
foreach (var motor in container.ElectricMotors.Values) {
if ((motor as ElectricMotor).Control is SimpleElectricMotorControl emCtl) {
emCtl.EmOff = false;
}
}
if (container.HasGearbox) {
var gbx = container.GearboxCtl as Gearbox;
gbx.Gear = gbx.ModelData.GearList.First();
}
vehicle.Initialize(0.KMPHtoMeterPerSecond(), gradient);
var initialResponse = vehicle.Request(absTime, simulationInterval, acceleration, gradient, true);
var delta = GetDelta(initialResponse as ResponseDryRun, container.VehicleArchitecutre);
try {
gradient = SearchAlgorithm.Search(
gradient, delta, 0.1.SI<Radian>(),
getYValue: response => GetDelta(response as ResponseDryRun, container.VehicleArchitecutre),
evaluateFunction: grad => vehicle.Request(absTime, simulationInterval, acceleration, grad, true),
criterion: response => GetDelta(response as ResponseDryRun, container.VehicleArchitecutre).Value(),
searcher: this);
} catch (VectoSearchAbortedException) {
return double.MaxValue.SI<Radian>();
}
return gradient;
}
private Watt GetDelta(ResponseDryRun response, VectoSimulationJobType vehicleArchitecutre)
{
//return response.DeltaFullLoad;
switch (vehicleArchitecutre) {
case VectoSimulationJobType.ConventionalVehicle:
case VectoSimulationJobType.ParallelHybridVehicle:
case VectoSimulationJobType.IHPC:
return response.DeltaFullLoad;
case VectoSimulationJobType.SerialHybridVehicle:
case VectoSimulationJobType.IEPC_S:
case VectoSimulationJobType.BatteryElectricVehicle:
case VectoSimulationJobType.IEPC_E:
return (response.ElectricMotor.TorqueRequest + response.ElectricMotor.MaxDriveTorque) * response.ElectricMotor.AvgDrivetrainSpeed;
default:
throw new VectoException($"unhandled powertrain architecture {vehicleArchitecutre} to calculate gradability");
}
}
#endregion
}
}
\ No newline at end of file
......@@ -48,6 +48,7 @@ using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponents;
using TUGraz.VectoCore.InputData.Reader.Impl;
using TUGraz.VectoCore.Models.Declaration;
using TUGraz.VectoCore.Models.Declaration.IterativeRunStrategies;
using TUGraz.VectoCore.Models.Declaration.PostMortemAnalysisStrategy;
using TUGraz.VectoCore.Models.Simulation.DataBus;
using TUGraz.VectoCore.Models.Simulation.Impl;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
......@@ -189,6 +190,9 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
[JsonIgnore]
public IIterativeRunStrategy IterativeRunStrategy { get; internal set; } = new DefaultIterativeStrategy();
[JsonIgnore]
public IPostMortemAnalyzeStrategy PostMortemStrategy { get; internal set; } = new DefaultPostMortemAnalyzeStrategy();
public NewtonMeter TorqueDriftLeftWheel { get; internal set; }
public NewtonMeter TorqueDriftRightWheel { get; internal set; }
......
......@@ -41,7 +41,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
{
public class DistanceRun : VectoRun
{
public DistanceRun(IVehicleContainer container, IFollowUpRunCreator followUpCreator) : base(container, followUpCreator) {}
public DistanceRun(IVehicleContainer container, IFollowUpRunCreator followUpCreator, IPostMortemAnalyzer postMortem) : base(container, followUpCreator, postMortem) {}
public DistanceRun(IVehicleContainer container) : base(container) {}
protected override IResponse DoSimulationStep()
{
......
using System;
using TUGraz.VectoCommon.Exceptions;
using TUGraz.VectoCore.Models.Declaration.PostMortemAnalysisStrategy;
namespace TUGraz.VectoCore.Models.Simulation.Impl
{
public interface IPostMortemAnalyzer
{
/**
* @returns true if the original exception shall be thrown
*/
bool AbortSimulation(IVehicleContainer container, Exception ex);
}
public class NoPostMortemAnalysis : IPostMortemAnalyzer
{
#region Implementation of IPostMortemAnalyzer
public bool AbortSimulation(IVehicleContainer container, Exception ex)
{
return true;
}
#endregion
}
public class DefaultPostMortemAnalyzer : IPostMortemAnalyzer
{
protected readonly IPostMortemAnalyzeStrategy _strategy;
public DefaultPostMortemAnalyzer(IPostMortemAnalyzeStrategy postMortemStrategy)
{
_strategy = postMortemStrategy;
}
#region Implementation of IPostMortemAnalyzer
public bool AbortSimulation(IVehicleContainer container, Exception ex)
{
if (!_strategy.AbortSimulation(container, ex)) {
//_strategy.M
container.RunStatus = VectoRun.Status.PrimaryBusSimulationIgnore;
return false;
}
return true;
}
#endregion
}
}
\ No newline at end of file
......@@ -268,7 +268,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl.SimulatorFactory
var container = PowertrainBuilder.Build(data, modData, sumWriter);
run = new DistanceRun(container, new FollowUpRunCreator(data.IterativeRunStrategy));
run = new DistanceRun(container, new FollowUpRunCreator(data.IterativeRunStrategy), new DefaultPostMortemAnalyzer(data.PostMortemStrategy));
break;
case CycleType.EngineOnly:
if ((data.SimulationType & SimulationType.EngineOnly) == 0) {
......
......@@ -38,6 +38,7 @@ using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Models.Connector.Ports;
using TUGraz.VectoCore.Models.Connector.Ports.Impl;
using TUGraz.VectoCore.Models.Declaration.PostMortemAnalysisStrategy;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Models.Simulation.Impl
......@@ -52,6 +53,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
protected Second dt = 1.SI<Second>();
private bool _cancelled;
private readonly IFollowUpRunCreator _followUpCreator;
private readonly IPostMortemAnalyzer _postMortemAnalyzer;
protected ISimulationOutPort CyclePort { get; set; }
[Required, ValidateObject]
......@@ -72,7 +74,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
public virtual double Progress => CyclePort.Progress * (PostProcessingDone ? 1.0 : 0.99) * (WritingResultsDone ? 1.0 : 0.99);
protected VectoRun(IVehicleContainer container, IFollowUpRunCreator followUpCreator = null)
protected VectoRun(IVehicleContainer container, IFollowUpRunCreator followUpCreator = null, IPostMortemAnalyzer postMortem = null)
{
Container = container;
RunIdentifier = Interlocked.Increment(ref _runIdCounter);
......@@ -81,6 +83,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
PostProcessingDone = false;
WritingResultsDone = false;
_followUpCreator = followUpCreator ?? new NoFollowUpRunCreator();
_postMortemAnalyzer = postMortem ?? new NoPostMortemAnalysis();
}
[DebuggerStepThrough]
public IVehicleContainer GetContainer() => Container;
......@@ -108,7 +112,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
Container.AbsTime = AbsTime;
Initialize();
IResponse response;
IResponse response = null;
var iterationCount = 0;
try {
......@@ -138,40 +142,63 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
PostProcessingDone = true;
} catch (VectoSimulationException vse) {
if (_postMortemAnalyzer?.AbortSimulation(Container, vse) ?? true) {
Log.Error("SIMULATION RUN ABORTED! ========================");
Log.Error(vse);
Container.RunStatus = Status.Aborted;
var ex = new VectoSimulationException("{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}, f_equiv:{9}",
var ex = new VectoSimulationException(
"{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}, f_equiv:{9}",
vse, AbsTime, Container.MileageCounter.Distance, dt, Container.VehicleInfo.VehicleSpeed,
TryCatch(() => Container.GearboxInfo.Gear), vse.Message, RunIdentifier, CycleName, RunSuffix, TryCatch(() => Container.RunData.HybridStrategyParameters?.EquivalenceFactor));
TryCatch(() => Container.GearboxInfo.Gear), vse.Message, RunIdentifier, CycleName, RunSuffix,
TryCatch(() => Container.RunData.HybridStrategyParameters?.EquivalenceFactor));
Container.FinishSimulationRun(ex);
throw ex;
}
} catch (VectoException ve) {
if (_postMortemAnalyzer?.AbortSimulation(Container, ve) ?? true) {
Log.Error("SIMULATION RUN ABORTED! ========================");
Log.Error(ve);
Container.RunStatus = Status.Aborted;
var ex = new VectoSimulationException("{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}, f_equiv:{9}",
var ex = new VectoSimulationException(
"{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}, f_equiv:{9}",
ve, AbsTime, Container.MileageCounter.Distance, dt, Container.VehicleInfo.VehicleSpeed,
TryCatch(() => Container.GearboxInfo.Gear), ve.Message, RunIdentifier, CycleName, RunSuffix, TryCatch(() => Container.RunData.HybridStrategyParameters?.EquivalenceFactor));
TryCatch(() => Container.GearboxInfo.Gear), ve.Message, RunIdentifier, CycleName, RunSuffix,
TryCatch(() => Container.RunData.HybridStrategyParameters?.EquivalenceFactor));
try {
Container.FinishSimulationRun(ex);
} catch (Exception ve2) {
ve = new VectoException("Multiple Exceptions occured.",
new AggregateException(ve, new VectoException("Exception during finishing Simulation.", ve2)));
new AggregateException(ve,
new VectoException("Exception during finishing Simulation.", ve2)));
throw ve;
}
throw ex;
}
} catch (Exception e) {
if (_postMortemAnalyzer?.AbortSimulation(Container, e) ?? true) {
Log.Error("SIMULATION RUN ABORTED! ========================");
Log.Error(e);
Container.RunStatus = Status.Aborted;
var ex = new VectoSimulationException("{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}, f_equiv:{9}",
var ex = new VectoSimulationException(
"{6} ({7} {8}) - absTime: {0}, distance: {1}, dt: {2}, v: {3}, Gear: {4} | {5}, f_equiv:{9}",
e, AbsTime, Container.MileageCounter.Distance, dt, Container.VehicleInfo.VehicleSpeed,
TryCatch(() => Container.GearboxInfo.Gear), e.Message, RunIdentifier, CycleName, RunSuffix, TryCatch(() => Container.RunData.HybridStrategyParameters?.EquivalenceFactor) ?? "-");
TryCatch(() => Container.GearboxInfo.Gear), e.Message, RunIdentifier, CycleName, RunSuffix,
TryCatch(() => Container.RunData.HybridStrategyParameters?.EquivalenceFactor) ?? "-");
Container.FinishSimulationRun(ex);
throw ex;
}
}
if (Container.RunStatus == Status.PrimaryBusSimulationIgnore) {
Container.FinishSimulationRun();
WritingResultsDone = true;
FinishedWithoutErrors = true;
IterationStatistics.FinishSimulation(RunName + CycleName + RunSuffix + RunIdentifier);
Log.Info("VectoJob finished.");
return;
}
if (CheckCyclePortProgress()) {
if (CyclePort.Progress < 1) {
......@@ -250,7 +277,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
Success,
Canceled,
Aborted,
REESSEmpty
REESSEmpty,
PrimaryBusSimulationIgnore
}
}
}
\ No newline at end of file
......@@ -143,6 +143,8 @@ namespace TUGraz.VectoCore.OutputData
public interface IWeightedResult
{
VectoRun.Status Status { get; }
MeterPerSecond AverageSpeed { get; }
MeterPerSecond AverageDrivingSpeed { get; }
......
using System.Collections.Generic;
using TUGraz.VectoCommon.BusAuxiliaries;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Models.Simulation.Impl;
namespace TUGraz.VectoCore.OutputData
{
......@@ -38,6 +39,7 @@ namespace TUGraz.VectoCore.OutputData
public IFuelProperties AuxHeaterFuel { get; set; }
public Kilogram ZEV_FuelConsumption_AuxHtr { get; set; }
public Kilogram ZEV_CO2 { get; set; }
public VectoRun.Status Status { get; set; }
#endregion
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment