diff --git a/VECTO/GUI/GearboxForm.vb b/VECTO/GUI/GearboxForm.vb index ec30e800ba9b54d203e952b82495838c511e5f7e..06c79a488fb20073a9330b4c92cdc5c0c600bc9e 100644 --- a/VECTO/GUI/GearboxForm.vb +++ b/VECTO/GUI/GearboxForm.vb @@ -928,9 +928,10 @@ Public Class GearboxForm If _ gbx(i).SubItems(GearboxTbl.Ratio).Text <> "" AndAlso Double.TryParse(gbx(i).SubItems(GearboxTbl.Ratio).Text, value) _ Then + Dim maxSpeed As PerSecond = If(String.IsNullOrWhiteSpace(gbx(i).SubItems(GearboxTbl.MaxSpeed).Text), Nothing, gbx(i).SubItems(GearboxTbl.MaxSpeed).Text.ToDouble().RPMtoRad()) retVal.Add( New TransmissionInputData() _ - With {.Ratio = value}) + With {.Ratio = value, .MaxInputSpeed = maxSpeed}) End If Next diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs index d1215b3ed7871137a52891742a30613667ab6652..25b74b9bef713ecce1e6622284c721da5e8a4819 100644 --- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs +++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs @@ -1,34 +1,34 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2017 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - +/* +* This file is part of VECTO. +* +* Copyright © 2012-2017 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + using System.Collections.Generic; using System.Data; using System.Linq; @@ -253,8 +253,15 @@ namespace TUGraz.VectoCore.Models.Declaration var p3pExt = new Point((1.1 * p5.Y - edgeP6pP3p.OffsetXY) / edgeP6pP3p.SlopeXY, 1.1 * p5.Y); // ReSharper restore InconsistentNaming - upShift = IntersectShiftPolygon(new[] { p4, p7, p5 }, new[] { p2p, p6p, p3pExt }) - .Select(point => new ShiftPolygon.ShiftPolygonEntry(point.Y.SI<NewtonMeter>(), point.X.SI<PerSecond>())).ToList(); + var upShiftPts = IntersectTakeHigherShiftLine(new[] { p4, p7, p5 }, new[] { p2p, p6p, p3pExt }); + if (gears[gearIdx].MaxInputSpeed != null) { + var maxSpeed = gears[gearIdx].MaxInputSpeed.Value(); + upShiftPts = IntersectTakeLowerShiftLine(upShiftPts, + new[] { new Point(maxSpeed, 0), new Point(maxSpeed, upShiftPts.Max(pt => pt.Y)) }); + } + upShift = + upShiftPts.Select(point => new ShiftPolygon.ShiftPolygonEntry(point.Y.SI<NewtonMeter>(), point.X.SI<PerSecond>())) + .ToList(); upShift[0].Torque = maxDragTorque; return new ShiftPolygon(downShift, upShift); } @@ -300,20 +307,9 @@ namespace TUGraz.VectoCore.Models.Declaration return engineSpeed; } - internal static List<Point> IntersectShiftPolygon(Point[] orig, Point[] transformedDownshift) + internal static Point[] IntersectTakeHigherShiftLine(Point[] orig, Point[] transformedDownshift) { - var intersections = new List<Point>(); - // compute all intersection points between both line segments - // ReSharper disable once LoopCanBeConvertedToQuery - foreach (var origLine in orig.Pairwise(Edge.Create)) { - // ReSharper disable once LoopCanBeConvertedToQuery - foreach (var transformedLine in transformedDownshift.Pairwise(Edge.Create)) { - var isect = VectoMath.Intersect(origLine, transformedLine); - if (isect != null) { - intersections.Add(isect); - } - } - } + var intersections = Intersect(orig, transformedDownshift); // add all points (i.e. intersecting points and both line segments) to a single list var pointSet = new List<Point>(orig); @@ -349,14 +345,70 @@ namespace TUGraz.VectoCore.Models.Declaration } // order points first by x coordinate and the by Y coordinate ASC - return shiftPolygon.OrderBy(pt => pt.X).ThenBy(pt => pt.Y).ToList(); + return shiftPolygon.OrderBy(pt => pt.X).ThenBy(pt => pt.Y).ToArray(); + } + + internal static Point[] IntersectTakeLowerShiftLine(Point[] upShiftPts, Point[] upperLimit) + { + var intersections = Intersect(upShiftPts, upperLimit); + if (!intersections.Any()) { + return upShiftPts[0].X < upperLimit[0].X ? upShiftPts : upperLimit; + } + var pointSet = new List<Point>(upShiftPts); + pointSet.AddRange(upperLimit); + pointSet.AddRange(intersections); + pointSet.AddRange(ProjectPointsToLineSegments(upShiftPts, upperLimit, true)); + pointSet.AddRange(ProjectPointsToLineSegments(upperLimit, upShiftPts, true)); + + var shiftPolygon = new List<Point>(); + foreach (var yCoord in pointSet.Select(pt => pt.Y).Distinct().OrderBy(y => y).Reverse()) { + var yPoints = pointSet.Where(pt => pt.Y.IsEqual(yCoord)).ToList(); + shiftPolygon.Add(yPoints.MinBy(pt => pt.X)); + } + + // find and remove colinear points + var toRemove = new List<Point>(); + for (var i = 0; i < shiftPolygon.Count - 2; i++) { + var edge = new Edge(shiftPolygon[i], shiftPolygon[i + 2]); + if (edge.ContainsXY(shiftPolygon[i + 1])) { + toRemove.Add(shiftPolygon[i + 1]); + } + } + foreach (var point in toRemove) { + shiftPolygon.Remove(point); + } + + // order points first by x coordinate and the by Y coordinate ASC + return shiftPolygon.OrderBy(pt => pt.X).ThenBy(pt => pt.Y).ToArray(); + } + + private static Point[] Intersect(Point[] orig, Point[] transformedDownshift) + { + var intersections = new List<Point>(); + // compute all intersection points between both line segments + // ReSharper disable once LoopCanBeConvertedToQuery + foreach (var origLine in orig.Pairwise(Edge.Create)) { + // ReSharper disable once LoopCanBeConvertedToQuery + foreach (var transformedLine in transformedDownshift.Pairwise(Edge.Create)) { + var isect = VectoMath.Intersect(origLine, transformedLine); + if (isect != null) { + intersections.Add(isect); + } + } + } + return intersections.ToArray(); } - private static IEnumerable<Point> ProjectPointsToLineSegments(IEnumerable<Point> lineSegments, Point[] points) + private static IEnumerable<Point> ProjectPointsToLineSegments(IEnumerable<Point> lineSegments, Point[] points, + bool projectToVertical = false) { var pointSet = new List<Point>(); foreach (var segment in lineSegments.Pairwise(Edge.Create)) { if (segment.P1.X.IsEqual(segment.P2.X)) { + if (projectToVertical) { + pointSet.AddRange( + points.Select(point => new Point(segment.P1.X, point.Y)).Where(pt => pt.Y.IsBetween(segment.P1.Y, segment.P2.Y))); + } continue; } var k = segment.SlopeXY; @@ -406,11 +458,11 @@ namespace TUGraz.VectoCore.Models.Declaration var data = VectoCSVFile.ReadStream(RessourceHelper.ReadStream(resourceId), source: resourceId); var characteristicTorque = (from DataRow row in data.Rows select - new TorqueConverterEntry() { - SpeedRatio = row.ParseDouble(TorqueConverterDataReader.Fields.SpeedRatio), - Torque = row.ParseDouble(TorqueConverterDataReader.Fields.CharacteristicTorque).SI<NewtonMeter>(), - TorqueRatio = row.ParseDouble(TorqueConverterDataReader.Fields.TorqueRatio) - }).ToArray(); + new TorqueConverterEntry() { + SpeedRatio = row.ParseDouble(TorqueConverterDataReader.Fields.SpeedRatio), + Torque = row.ParseDouble(TorqueConverterDataReader.Fields.CharacteristicTorque).SI<NewtonMeter>(), + TorqueRatio = row.ParseDouble(TorqueConverterDataReader.Fields.TorqueRatio) + }).ToArray(); foreach (var torqueConverterEntry in characteristicTorque) { torqueConverterEntry.SpeedRatio = torqueConverterEntry.SpeedRatio * ratio; torqueConverterEntry.TorqueRatio = torqueConverterEntry.TorqueRatio / ratio; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index aa140f1360ec336a81fd0b1f0eba4ffdeffcfa56..4321fb273c867e832cbabb552e6afae6bf8311d9 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -1,34 +1,34 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2017 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - +/* +* This file is part of VECTO. +* +* Copyright © 2012-2017 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + using System; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Models; @@ -181,9 +181,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var avgEngineSpeed = (PreviousState.EngineSpeed + angularVelocity) / 2.0; - var engineSpeedLimit = GetEngineSpeedLimit(); + var engineSpeedLimit = GetEngineSpeedLimit(absTime); if (!dryRun && avgEngineSpeed.IsGreater(engineSpeedLimit, Constants.SimulationSettings.LineSearchTolerance)) { - return new ResponseEngineSpeedTooHigh() { DeltaEngineSpeed = avgEngineSpeed - engineSpeedLimit }; + return new ResponseEngineSpeedTooHigh() { + DeltaEngineSpeed = avgEngineSpeed - engineSpeedLimit, + Source = this, + EngineSpeed = angularVelocity + }; } var fullDragTorque = ModelData.FullLoadCurves[DataBus.Gear].DragLoadStationaryTorque(avgEngineSpeed); @@ -293,12 +297,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl }; } - protected virtual PerSecond GetEngineSpeedLimit() + protected virtual PerSecond GetEngineSpeedLimit(Second absTime) { - return DataBus.Gear == 0 + return DataBus.Gear == 0 || !DataBus.ClutchClosed(absTime) ? ModelData.FullLoadCurves[0].N95hSpeed - : VectoMath.Min(DataBus.GetGearData(DataBus.Gear).MaxSpeed, - ModelData.FullLoadCurves[0].N95hSpeed); + : VectoMath.Min(DataBus.GetGearData(DataBus.Gear).MaxSpeed, ModelData.FullLoadCurves[0].N95hSpeed); } public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs index 18f0703a596e6b8c0035f22334a71bfa8ee197cc..485e4be47eed6f39d59f07d33d94fb529f1ed29c 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs @@ -1,34 +1,34 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2017 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - +/* +* This file is part of VECTO. +* +* Copyright © 2012-2017 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + using System; using System.Collections.Generic; using System.Diagnostics; @@ -538,66 +538,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { IResponse response = null; if (DataBus.VehicleSpeed <= DriverStrategy.BrakeTrigger.NextTargetSpeed) { - if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) { - if (DataBus.VehicleSpeed.IsGreater(0)) { - response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); - } else { - if (RetryDistanceExceeded) { - response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient); - } else { - RetryDistanceExceeded = true; - return new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 }; - } - } - } else { - response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); - } - response.Switch(). - Case<ResponseGearShift>(() => { - response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); - response.Switch(). - Case<ResponseUnderload>(r => { - // under-load may happen if driver limits acceleration when rolling downhill - response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, - gradient, r); - }). - Case<ResponseSpeedLimitExceeded>(() => { - response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed, - gradient); - }); - }). - Case<ResponseSpeedLimitExceeded>(() => { - response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed, - gradient); - }). - Case<ResponseUnderload>(r => { - response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, - gradient, r); - response.Switch(). - Case<ResponseGearShift>(() => { - DataBus.BrakePower = 0.SI<Watt>(); - response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, - gradient, r); - }). - Case<ResponseOverload>(() => { - DataBus.BrakePower = 0.SI<Watt>(); - if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) { - if (DataBus.VehicleSpeed.IsGreater(0)) { - response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); - } else { - if (RetryDistanceExceeded) { - response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient); - } else { - RetryDistanceExceeded = true; - response = new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 }; - } - } - } else { - response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); - } - }); - }); - return response; + return HandleTargetspeedReached(absTime, ds, targetVelocity, gradient); } var currentDistance = DataBus.Distance; @@ -665,7 +606,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); } }). - Case<ResponseGearShift>(r => { response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); }); + Case<ResponseGearShift>(r => { response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); }). + Case<ResponseEngineSpeedTooHigh>(r => { + response = Driver.DrivingActionBrake(absTime, ds, targetVelocity, gradient, r); + }); // handle the SpeedLimitExceeded Response separately in case it occurs in one of the requests in the second try response.Switch(). Case<ResponseSpeedLimitExceeded>(() => { @@ -732,6 +676,76 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return response; } + private IResponse HandleTargetspeedReached(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient) + { + IResponse response; + if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) { + if (DataBus.VehicleSpeed.IsGreater(0)) { + response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); + } else { + if (RetryDistanceExceeded) { + response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient); + } else { + RetryDistanceExceeded = true; + return new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 }; + } + } + } else { + response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); + } + var i = 0; + do { + response.Switch(). + Case<ResponseGearShift>(() => { + response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); + response.Switch(). + Case<ResponseUnderload>(r => { + // under-load may happen if driver limits acceleration when rolling downhill + response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, + gradient, r); + }). + Case<ResponseSpeedLimitExceeded>(() => { + response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed, + gradient); + }); + }). + Case<ResponseSpeedLimitExceeded>(() => { + response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed, + gradient); + }). + Case<ResponseUnderload>(r => { + //response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, + // gradient, r); + response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed + r.Acceleration * r.SimulationInterval, + gradient, r); + response.Switch(). + Case<ResponseGearShift>(() => { + DataBus.BrakePower = 0.SI<Watt>(); + response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, + gradient, r); + }). + Case<ResponseOverload>(() => { + DataBus.BrakePower = 0.SI<Watt>(); + if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) { + if (DataBus.VehicleSpeed.IsGreater(0)) { + response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); + } else { + if (RetryDistanceExceeded) { + response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient); + } else { + RetryDistanceExceeded = true; + response = new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 }; + } + } + } else { + response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); + } + }); + }); + } while (!(response is ResponseSuccess) && i++ < 3); + return response; + } + protected override IResponse CheckRequestDoesNotExceedNextAction(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient, IResponse response, out Meter newds) { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineOnlyCombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineOnlyCombustionEngine.cs index b8c9ed793ac97afd9baa9e294946a6100185c502..908779388dfcfbbf3db50f4047c7edcea5b7d0d5 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineOnlyCombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineOnlyCombustionEngine.cs @@ -1,34 +1,34 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2017 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - +/* +* This file is part of VECTO. +* +* Copyright © 2012-2017 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.Connector.Ports.Impl; @@ -110,7 +110,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return requestedEngineTorque; } - protected override PerSecond GetEngineSpeedLimit() + protected override PerSecond GetEngineSpeedLimit(Second absTime) { return ModelData.FullLoadCurves[0].N95hSpeed; } diff --git a/VectoCore/VectoCore/Utils/VectoCSVFile.cs b/VectoCore/VectoCore/Utils/VectoCSVFile.cs index 3a0be33e6e4c4c2195ab1f7c16600c8004d65b3e..e904ab0adeb9f252dca49b16d2d47476c175298d 100644 --- a/VectoCore/VectoCore/Utils/VectoCSVFile.cs +++ b/VectoCore/VectoCore/Utils/VectoCSVFile.cs @@ -1,245 +1,249 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2017 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - -using Microsoft.VisualBasic.FileIO; -using System; -using System.Data; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Text.RegularExpressions; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; - -namespace TUGraz.VectoCore.Utils -{ - /// <summary> - /// Class for Reading and Writing VECTO CSV Files. - /// </summary> - /// <remarks> - /// The following format applies to all CSV (Comma-separated values) Input Files used in VECTO: - /// List DELIMITER: Comma "," - /// Decimal-Mark: Dot "." - /// Comments: "#" at the beginning of the comment line. Number and position of comment lines is not limited. - /// Header: One header line (not a comment line) at the beginning of the file. - /// All Combinations between max-format and min-format possible. Only "id"-field is used. - /// max: id (name) [unit], id (name) [unit], ... - /// min: id,id,... - /// </remarks> - public static class VectoCSVFile - { - private static readonly Regex HeaderFilter = new Regex(@"\[.*?\]|\<|\>", RegexOptions.Compiled); - private const string Delimiter = ","; - private const string Comment = "#"; - - /// <summary> - /// Reads a CSV file which is stored in Vecto-CSV-Format. - /// </summary> - /// <param name="fileName">the filename</param> - /// <param name="ignoreEmptyColumns">set true, if empty columns should be ignored. default: false.</param> - /// <param name="fullHeader">set true is column names should be preserved. Otherwise units are trimed away. default: false.</param> - /// <returns>A DataTable which represents the CSV File.</returns> - public static TableData Read(string fileName, bool ignoreEmptyColumns = false, bool fullHeader = false) - { - try { - using (var fs = new FileStream(fileName, FileMode.Open)) { - var retVal = new TableData(fileName); - ReadCSV(retVal, fs, ignoreEmptyColumns, fullHeader); - return retVal; - } - } catch (Exception e) { - LogManager.GetLogger(typeof(VectoCSVFile).FullName).Error(e); - throw new VectoException("Error reading file {0}: {1}", fileName, e.Message); - } - } - - /// <summary> - /// Reads a CSV file which is stored in Vecto-CSV-Format. - /// </summary> - /// <param name="stream">the stream to read</param> - /// <param name="ignoreEmptyColumns">set true, if empty columns should be ignored. default: false.</param> - /// <param name="fullHeader">set true is column names should be preserved. Otherwise units are trimed away. default: false.</param> - /// <param name="source"></param> - /// <returns>A DataTable which represents the CSV File.</returns> - public static TableData ReadStream(Stream stream, bool ignoreEmptyColumns = false, bool fullHeader = false, - string source = null) - { - var retVal = new TableData(source, DataSourceType.Embedded); - ReadCSV(retVal, stream, ignoreEmptyColumns, fullHeader); - return retVal; - } - - private static void ReadCSV(DataTable table, Stream stream, bool ignoreEmptyColumns, bool fullHeader) - { - var p = new TextFieldParser(stream) { - TextFieldType = FieldType.Delimited, - Delimiters = new[] { Delimiter }, - CommentTokens = new[] { Comment }, - HasFieldsEnclosedInQuotes = true, - TrimWhiteSpace = true - }; - - string[] colsWithoutComment = { }; - - try { - var fields = p.ReadFields(); - if (fields == null) { - throw new CSVReadException("CSV Read Error: File was empty."); - } - colsWithoutComment = fields - .Select(l => l.Contains(Comment) ? l.Substring(0, l.IndexOf(Comment, StringComparison.Ordinal)) : l) - .ToArray(); - } catch (ArgumentNullException) { - throw new CSVReadException("CSV Read Error: File was empty."); - } - - double tmp; - var columns = colsWithoutComment - .Select(l => fullHeader ? l : HeaderFilter.Replace(l, "")) - .Select(l => l.Trim()) - .Where(col => !double.TryParse(col, NumberStyles.Any, CultureInfo.InvariantCulture, out tmp)) - .Distinct() - .ToList(); - - var firstLineIsData = columns.Count == 0; - - if (firstLineIsData) { - LogManager.GetLogger(typeof(VectoCSVFile).FullName) - .Warn("No valid Data Header found. Interpreting the first line as data line."); - // set the validColumns to: {"0", "1", "2", "3", ...} for all columns in first line. - columns = colsWithoutComment.Select((_, i) => i.ToString()).ToList(); - } - - //var table = new DataTable(); - foreach (var col in columns) { - table.Columns.Add(col); - } - - if (p.EndOfData) { - return; - } - - var lineNumber = 1; - do { - string[] cells = { }; - if (firstLineIsData) { - cells = colsWithoutComment; - } else { - var fields = p.ReadFields(); - if (fields != null) { - cells = fields.Select(l => l.Contains(Comment) ? l.Substring(0, l.IndexOf(Comment, StringComparison.Ordinal)) : l) - .Select(s => s.Trim()) - .ToArray(); - } - } - firstLineIsData = false; - if (table.Columns.Count != cells.Length && !ignoreEmptyColumns) { - throw new CSVReadException( - string.Format("Line {0}: The number of values is not correct. Expected {1} Columns, Got {2} Columns", - lineNumber, table.Columns.Count, cells.Length)); - } - - try { - // ReSharper disable once CoVariantArrayConversion - table.Rows.Add(cells); - } catch (InvalidCastException e) { - throw new CSVReadException( - string.Format("Line {0}: The data format of a value is not correct. {1}", lineNumber, e.Message), e); - } - lineNumber++; - } while (!p.EndOfData); - } - - /// <summary> - /// Writes the datatable to the csv file. - /// Uses the column caption as header (with fallback to column name) for the csv header. - /// </summary> - /// <param name="fileName">Path to the file.</param> - /// <param name="table">The Datatable.</param> - /// <param name="addVersionHeader"></param> - public static void Write(string fileName, DataTable table, bool addVersionHeader = false) - { - using (var sw = new StreamWriter(new FileStream(fileName, FileMode.Create), Encoding.UTF8)) { - Write(sw, table, addVersionHeader); - } - } - - /// <summary> - /// writes the datatable to a csv file. - /// Uses the column caption as header (with fallback to column name) for the csv header. - /// <remarks>Note: the callee has to make suree to close the stream after use.</remarks> - /// </summary> - /// <param name="writer"></param> - /// <param name="table"></param> - /// <param name="addVersionHeader"></param> - public static void Write(StreamWriter writer, DataTable table, bool addVersionHeader = false) - { - if (writer == null) { - return; - } - if (addVersionHeader) { - var vectodll = Assembly.LoadFrom(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "VectoCore.dll")).GetName(); - writer.WriteLine("# VECTO {0} - {1}", vectodll.Version, DateTime.Now.ToString("dd.MM.yyyy HH:mm")); - } - var header = table.Columns.Cast<DataColumn>().Select(col => col.Caption ?? col.ColumnName); - writer.WriteLine(string.Join(Delimiter, header)); - - var columnFormatter = new Func<SI, string>[table.Columns.Count]; - for (var i = 0; i < table.Columns.Count; i++) { - var col = table.Columns[i]; - var decimals = (uint?)col.ExtendedProperties["decimals"]; - var outputFactor = (double?)col.ExtendedProperties["outputFactor"]; - var showUnit = (bool?)col.ExtendedProperties["showUnit"]; - - columnFormatter[i] = item => item.ToOutputFormat(decimals, outputFactor, showUnit); - } - - foreach (DataRow row in table.Rows) { - var items = row.ItemArray; - var formattedList = new string[items.Length]; - for (var i = 0; i < items.Length; i++) { - var si = items[i] as SI; - formattedList[i] = si != null - ? columnFormatter[i](si) - : formattedList[i] = string.Format(CultureInfo.InvariantCulture, "{0}", items[i]); - if (formattedList[i].Contains(Delimiter)) { - formattedList[i] = string.Format("\"{0}\"", formattedList[i]); - } - } - writer.WriteLine(string.Join(Delimiter, formattedList)); - } - } - } +/* +* This file is part of VECTO. +* +* Copyright © 2012-2017 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + +using Microsoft.VisualBasic.FileIO; +using System; +using System.Data; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCore.Utils +{ + /// <summary> + /// Class for Reading and Writing VECTO CSV Files. + /// </summary> + /// <remarks> + /// The following format applies to all CSV (Comma-separated values) Input Files used in VECTO: + /// List DELIMITER: Comma "," + /// Decimal-Mark: Dot "." + /// Comments: "#" at the beginning of the comment line. Number and position of comment lines is not limited. + /// Header: One header line (not a comment line) at the beginning of the file. + /// All Combinations between max-format and min-format possible. Only "id"-field is used. + /// max: id (name) [unit], id (name) [unit], ... + /// min: id,id,... + /// </remarks> + public static class VectoCSVFile + { + private static readonly Regex HeaderFilter = new Regex(@"\[.*?\]|\<|\>", RegexOptions.Compiled); + private const string Delimiter = ","; + private const string Comment = "#"; + + /// <summary> + /// Reads a CSV file which is stored in Vecto-CSV-Format. + /// </summary> + /// <param name="fileName">the filename</param> + /// <param name="ignoreEmptyColumns">set true, if empty columns should be ignored. default: false.</param> + /// <param name="fullHeader">set true is column names should be preserved. Otherwise units are trimed away. default: false.</param> + /// <returns>A DataTable which represents the CSV File.</returns> + public static TableData Read(string fileName, bool ignoreEmptyColumns = false, bool fullHeader = false) + { + try { + using (var fs = new FileStream(fileName, FileMode.Open)) { + var retVal = new TableData(fileName); + ReadCSV(retVal, fs, ignoreEmptyColumns, fullHeader); + return retVal; + } + } catch (Exception e) { + LogManager.GetLogger(typeof(VectoCSVFile).FullName).Error(e); + throw new VectoException("Error reading file {0}: {1}", fileName, e.Message); + } + } + + /// <summary> + /// Reads a CSV file which is stored in Vecto-CSV-Format. + /// </summary> + /// <param name="stream">the stream to read</param> + /// <param name="ignoreEmptyColumns">set true, if empty columns should be ignored. default: false.</param> + /// <param name="fullHeader">set true is column names should be preserved. Otherwise units are trimed away. default: false.</param> + /// <param name="source"></param> + /// <returns>A DataTable which represents the CSV File.</returns> + public static TableData ReadStream(Stream stream, bool ignoreEmptyColumns = false, bool fullHeader = false, + string source = null) + { + var retVal = new TableData(source, DataSourceType.Embedded); + ReadCSV(retVal, stream, ignoreEmptyColumns, fullHeader); + return retVal; + } + + private static void ReadCSV(DataTable table, Stream stream, bool ignoreEmptyColumns, bool fullHeader) + { + var p = new TextFieldParser(stream) { + TextFieldType = FieldType.Delimited, + Delimiters = new[] { Delimiter }, + CommentTokens = new[] { Comment }, + HasFieldsEnclosedInQuotes = true, + TrimWhiteSpace = true + }; + + string[] colsWithoutComment = { }; + + try { + var fields = p.ReadFields(); + if (fields == null) { + throw new CSVReadException("CSV Read Error: File was empty."); + } + colsWithoutComment = fields + .Select(l => l.Contains(Comment) ? l.Substring(0, l.IndexOf(Comment, StringComparison.Ordinal)) : l) + .ToArray(); + } catch (ArgumentNullException) { + throw new CSVReadException("CSV Read Error: File was empty."); + } + + double tmp; + var columns = colsWithoutComment + .Select(l => fullHeader ? l : HeaderFilter.Replace(l, "")) + .Select(l => l.Trim()) + .Where(col => !double.TryParse(col, NumberStyles.Any, CultureInfo.InvariantCulture, out tmp)) + .Distinct() + .ToList(); + + var firstLineIsData = columns.Count == 0; + + if (firstLineIsData) { + LogManager.GetLogger(typeof(VectoCSVFile).FullName) + .Warn("No valid Data Header found. Interpreting the first line as data line."); + // set the validColumns to: {"0", "1", "2", "3", ...} for all columns in first line. + columns = colsWithoutComment.Select((_, i) => i.ToString()).ToList(); + } + + //var table = new DataTable(); + foreach (var col in columns) { + table.Columns.Add(col); + } + + if (p.EndOfData) { + return; + } + + var lineNumber = 1; + do { + string[] cells = { }; + if (firstLineIsData) { + cells = colsWithoutComment; + } else { + var fields = p.ReadFields(); + if (fields != null) { + cells = fields.Select(l => l.Contains(Comment) ? l.Substring(0, l.IndexOf(Comment, StringComparison.Ordinal)) : l) + .Select(s => s.Trim()) + .ToArray(); + } + } + firstLineIsData = false; + if (table.Columns.Count != cells.Length && !ignoreEmptyColumns) { + throw new CSVReadException( + string.Format("Line {0}: The number of values is not correct. Expected {1} Columns, Got {2} Columns", + lineNumber, table.Columns.Count, cells.Length)); + } + + try { + // ReSharper disable once CoVariantArrayConversion + table.Rows.Add(cells); + } catch (InvalidCastException e) { + throw new CSVReadException( + string.Format("Line {0}: The data format of a value is not correct. {1}", lineNumber, e.Message), e); + } + lineNumber++; + } while (!p.EndOfData); + } + + /// <summary> + /// Writes the datatable to the csv file. + /// Uses the column caption as header (with fallback to column name) for the csv header. + /// </summary> + /// <param name="fileName">Path to the file.</param> + /// <param name="table">The Datatable.</param> + /// <param name="addVersionHeader"></param> + public static void Write(string fileName, DataTable table, bool addVersionHeader = false) + { + using (var sw = new StreamWriter(new FileStream(fileName, FileMode.Create), Encoding.UTF8)) { + Write(sw, table, addVersionHeader); + } + } + + /// <summary> + /// writes the datatable to a csv file. + /// Uses the column caption as header (with fallback to column name) for the csv header. + /// <remarks>Note: the callee has to make suree to close the stream after use.</remarks> + /// </summary> + /// <param name="writer"></param> + /// <param name="table"></param> + /// <param name="addVersionHeader"></param> + public static void Write(StreamWriter writer, DataTable table, bool addVersionHeader = false) + { + if (writer == null) { + return; + } + if (addVersionHeader) { + try { + var vectodll = Assembly.LoadFrom(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "VectoCore.dll")).GetName(); + writer.WriteLine("# VECTO {0} - {1}", vectodll.Version, DateTime.Now.ToString("dd.MM.yyyy HH:mm")); + } catch (Exception) { + writer.WriteLine("# VECTO {0} - {1}", "Unknown", DateTime.Now.ToString("dd.MM.yyyy HH:mm")); + } + } + var header = table.Columns.Cast<DataColumn>().Select(col => col.Caption ?? col.ColumnName); + writer.WriteLine(string.Join(Delimiter, header)); + + var columnFormatter = new Func<SI, string>[table.Columns.Count]; + for (var i = 0; i < table.Columns.Count; i++) { + var col = table.Columns[i]; + var decimals = (uint?)col.ExtendedProperties["decimals"]; + var outputFactor = (double?)col.ExtendedProperties["outputFactor"]; + var showUnit = (bool?)col.ExtendedProperties["showUnit"]; + + columnFormatter[i] = item => item.ToOutputFormat(decimals, outputFactor, showUnit); + } + + foreach (DataRow row in table.Rows) { + var items = row.ItemArray; + var formattedList = new string[items.Length]; + for (var i = 0; i < items.Length; i++) { + var si = items[i] as SI; + formattedList[i] = si != null + ? columnFormatter[i](si) + : formattedList[i] = string.Format(CultureInfo.InvariantCulture, "{0}", items[i]); + if (formattedList[i].Contains(Delimiter)) { + formattedList[i] = string.Format("\"{0}\"", formattedList[i]); + } + } + writer.WriteLine(string.Join(Delimiter, formattedList)); + } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Integration/FuelTypesTest.cs b/VectoCore/VectoCoreTest/Integration/FuelTypesTest.cs index 6c9246226a5ba9520e5729e62a10583df2316a04..e5ad5808e80bfa5589bd748d36f6603d706e6e71 100644 --- a/VectoCore/VectoCoreTest/Integration/FuelTypesTest.cs +++ b/VectoCore/VectoCoreTest/Integration/FuelTypesTest.cs @@ -1,34 +1,34 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2017 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - +/* +* This file is part of VECTO. +* +* Copyright © 2012-2017 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + using NUnit.Framework; using TUGraz.VectoCommon.Models; using TUGraz.VectoCore.InputData.FileIO.JSON; @@ -63,7 +63,7 @@ namespace TUGraz.VectoCore.Tests.Integration var jobContainer = new JobContainer(sumData); var inputData = JSONInputDataFactory.ReadJsonJob(jobName); - var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, inputData, fileWriter) { WriteModalResults = true }; + var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, inputData, fileWriter) { WriteModalResults = true, Validate = false}; jobContainer.AddRuns(runsFactory); diff --git a/VectoCore/VectoCoreTest/Integration/FullCycleDeclarationTest.cs b/VectoCore/VectoCoreTest/Integration/FullCycleDeclarationTest.cs index 023e422781c149971c0e53b213dc1a15d2d9b0a4..52eae98fd9dd02a00043d9c243c4a60d825dc2de 100644 --- a/VectoCore/VectoCoreTest/Integration/FullCycleDeclarationTest.cs +++ b/VectoCore/VectoCoreTest/Integration/FullCycleDeclarationTest.cs @@ -1,34 +1,34 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2017 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - +/* +* This file is part of VECTO. +* +* Copyright © 2012-2017 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + using System.Data; using System.IO; using System.Linq; @@ -168,7 +168,8 @@ namespace TUGraz.VectoCore.Tests.Integration var inputData = JSONInputDataFactory.ReadJsonJob(LongHaulTruckDeclarationJob); var fileWriter = new FileOutputWriter(LongHaulTruckDeclarationJob); var factory = new SimulatorFactory(ExecutionMode.Declaration, inputData, fileWriter) { - WriteModalResults = true + WriteModalResults = true, + Validate = false }; var sumData = new SummaryDataContainer(fileWriter); var jobContainer = new JobContainer(sumData); @@ -286,7 +287,8 @@ namespace TUGraz.VectoCore.Tests.Integration var inputData = JSONInputDataFactory.ReadJsonJob(DeliveryTruckDeclarationJob); var fileWriter = new FileOutputWriter(DeliveryTruckDeclarationJob); var factory = new SimulatorFactory(ExecutionMode.Declaration, inputData, fileWriter) { - WriteModalResults = true + WriteModalResults = true, + Validate = false }; var sumData = new SummaryDataContainer(fileWriter); var jobContainer = new JobContainer(sumData); @@ -317,7 +319,8 @@ namespace TUGraz.VectoCore.Tests.Integration var inputData = JSONInputDataFactory.ReadJsonJob(DeliveryTruck8GearDeclarationJob); var fileWriter = new FileOutputWriter(DeliveryTruck8GearDeclarationJob); var factory = new SimulatorFactory(ExecutionMode.Declaration, inputData, fileWriter) { - WriteModalResults = true + WriteModalResults = true, + Validate = false }; var sumData = new SummaryDataContainer(fileWriter); var jobContainer = new JobContainer(sumData); diff --git a/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs index 06f1dab82704d9366afac338afb9b3e5d27f2922..62b786714b8f31a3b7005e1325f9dd4f3eb4055d 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs @@ -1,34 +1,34 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2017 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - +/* +* This file is part of VECTO. +* +* Copyright © 2012-2017 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + using System; using System.Collections.Generic; using System.IO; @@ -74,9 +74,9 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration new Point(20, 20), }; - var result = DeclarationData.Gearbox.IntersectShiftPolygon(upShift, transformed); + var result = DeclarationData.Gearbox.IntersectTakeHigherShiftLine(upShift, transformed); - Assert.AreEqual(expected.Length, result.Count); + Assert.AreEqual(expected.Length, result.Length); foreach (var tuple in expected.Zip(result, Tuple.Create)) { Assert.AreEqual(tuple.Item1.X, tuple.Item2.X); @@ -105,18 +105,18 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration new Point(20, 15.6), }; - var result = DeclarationData.Gearbox.IntersectShiftPolygon(upShift, transformed); + var result = DeclarationData.Gearbox.IntersectTakeHigherShiftLine(upShift, transformed); - Assert.AreEqual(expected.Length, result.Count); + Assert.AreEqual(expected.Length, result.Length); foreach (var tuple in expected.Zip(result, Tuple.Create)) { Assert.AreEqual(tuple.Item1.X, tuple.Item2.X); Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y); } - result = DeclarationData.Gearbox.IntersectShiftPolygon(transformed, upShift); + result = DeclarationData.Gearbox.IntersectTakeHigherShiftLine(transformed, upShift); - Assert.AreEqual(expected.Length, result.Count); + Assert.AreEqual(expected.Length, result.Length); foreach (var tuple in expected.Zip(result, Tuple.Create)) { Assert.AreEqual(tuple.Item1.X, tuple.Item2.X); @@ -146,18 +146,18 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration new Point(20, 20), }; - var result = DeclarationData.Gearbox.IntersectShiftPolygon(upShift, transformed); + var result = DeclarationData.Gearbox.IntersectTakeHigherShiftLine(upShift, transformed); - Assert.AreEqual(expected.Length, result.Count); + Assert.AreEqual(expected.Length, result.Length); foreach (var tuple in expected.Zip(result, Tuple.Create)) { Assert.AreEqual(tuple.Item1.X, tuple.Item2.X); Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y); } - result = DeclarationData.Gearbox.IntersectShiftPolygon(transformed, upShift); + result = DeclarationData.Gearbox.IntersectTakeHigherShiftLine(transformed, upShift); - Assert.AreEqual(expected.Length, result.Count); + Assert.AreEqual(expected.Length, result.Length); foreach (var tuple in expected.Zip(result, Tuple.Create)) { Assert.AreEqual(tuple.Item1.X, tuple.Item2.X); @@ -187,18 +187,108 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration new Point(20, 16.8), }; - var result = DeclarationData.Gearbox.IntersectShiftPolygon(upShift, transformed); + var result = DeclarationData.Gearbox.IntersectTakeHigherShiftLine(upShift, transformed); - Assert.AreEqual(expected.Length, result.Count); + Assert.AreEqual(expected.Length, result.Length); foreach (var tuple in expected.Zip(result, Tuple.Create)) { Assert.AreEqual(tuple.Item1.X, tuple.Item2.X, 1e-3); Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y, 1e-3); } - result = DeclarationData.Gearbox.IntersectShiftPolygon(transformed, upShift); + result = DeclarationData.Gearbox.IntersectTakeHigherShiftLine(transformed, upShift); - Assert.AreEqual(expected.Length, result.Count); + Assert.AreEqual(expected.Length, result.Length); + + foreach (var tuple in expected.Zip(result, Tuple.Create)) { + Assert.AreEqual(tuple.Item1.X, tuple.Item2.X, 1e-3); + Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y, 1e-3); + } + } + + [TestCase] + public void LimitShiftlines1() + { + var upShift = new[] { + new Point(10, 0), + new Point(10, 10), + new Point(20, 20), + }; + + var limit = new[] { + new Point(8, 0), + new Point(8, 20) + }; + + var expected = new[] { + new Point(8, 0), + new Point(8, 20) + }; + + var result = DeclarationData.Gearbox.IntersectTakeLowerShiftLine(upShift, limit); + + Assert.AreEqual(expected.Length, result.Length); + + foreach (var tuple in expected.Zip(result, Tuple.Create)) { + Assert.AreEqual(tuple.Item1.X, tuple.Item2.X, 1e-3); + Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y, 1e-3); + } + } + + [TestCase] + public void LimitShiftlines2() + { + var upShift = new[] { + new Point(10, 0), + new Point(10, 10), + new Point(20, 20), + }; + + var limit = new[] { + new Point(15, 0), + new Point(15, 20) + }; + + var expected = new[] { + new Point(10, 0), + new Point(10, 10), + new Point(15, 15), + new Point(15, 20), + }; + + var result = DeclarationData.Gearbox.IntersectTakeLowerShiftLine(upShift, limit); + + Assert.AreEqual(expected.Length, result.Length); + + foreach (var tuple in expected.Zip(result, Tuple.Create)) { + Assert.AreEqual(tuple.Item1.X, tuple.Item2.X, 1e-3); + Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y, 1e-3); + } + } + + [TestCase] + public void LimitShiftlines3() + { + var upShift = new[] { + new Point(10, 0), + new Point(10, 10), + new Point(20, 20), + }; + + var limit = new[] { + new Point(25, 0), + new Point(25, 20) + }; + + var expected = new[] { + new Point(10, 0), + new Point(10, 10), + new Point(20, 20), + }; + + var result = DeclarationData.Gearbox.IntersectTakeLowerShiftLine(upShift, limit); + + Assert.AreEqual(expected.Length, result.Length); foreach (var tuple in expected.Zip(result, Tuple.Create)) { Assert.AreEqual(tuple.Item1.X, tuple.Item2.X, 1e-3); @@ -546,7 +636,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration shiftPolygons.Add( DeclarationData.Gearbox.ComputeShiftPolygon(gearboxData.Type, i, fullLoadCurves[(uint)(i + 1)], gearboxData.Gears, engineData, axlegearRatio, rdyn.SI<Meter>()) - ); + ); List<Point> tmp1, tmp2, tmp3; ComputShiftPolygonPoints(i, fullLoadCurves[(uint)(i + 1)], gearboxData.Gears, engineData, axlegearRatio, rdyn.SI<Meter>(), out tmp1, out tmp2, out tmp3); @@ -669,7 +759,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration var segment = Tuple.Create( new ShiftPolygon.ShiftPolygonEntry(550.SI<NewtonMeter>(), 685.RPMtoRad()), new ShiftPolygon.ShiftPolygonEntry(1200.SI<NewtonMeter>(), 1080.RPMtoRad()) - ); + ); Assert.AreEqual(result, ShiftPolygon.IsLeftOf(speed.RPMtoRad(), torque.SI<NewtonMeter>(), segment)); } diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/GearboxShiftLossesTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/GearboxShiftLossesTest.cs index e051d3be7415703b4a7266fcdfea6d3440f29640..b52ace952b4e0210be3d25aff2560fdd5bdc9f53 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponent/GearboxShiftLossesTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/GearboxShiftLossesTest.cs @@ -1,34 +1,34 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2017 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - +/* +* This file is part of VECTO. +* +* Copyright © 2012-2017 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + using System.Globalization; using NUnit.Framework; using TUGraz.VectoCommon.Models; @@ -93,6 +93,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var wheels = new Wheels(container, 0.5.SI<Meter>(), 9.5.SI<KilogramSquareMeter>()); var vehicle = new MockVehicle(container); + container.AbsTime = 100.SI<Second>(); var driver = new MockDriver(container); vehicle.MyVehicleSpeed = 10.KMPHtoMeterPerSecond(); driver.DriverBehavior = DrivingBehavior.Driving;