Code development platform for open source projects from the European Union institutions :large_blue_circle: EU Login authentication by SMS will be completely phased out by mid-2025. To see alternatives please check here

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

Merge pull request #456 in VECTO/vecto-sim from...

Merge pull request #456 in VECTO/vecto-sim from ~EMQUARIMA/vecto-sim:feature/VECTO-522-change-gear-ratio-for-torque-converter to develop

* commit '6a55bbb7':
  change torque converter threshold for 2nd gear to 1.85 (from 1.9)
parents a1a66170 6a55bbb7
No related branches found
No related tags found
No related merge requests found
......@@ -57,7 +57,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
}
var lookAheadData = new DriverData.LACData {
Enabled = DeclarationData.Driver.LookAhead.Enabled,
//Deceleration = DeclarationData.Driver.LookAhead.Deceleration,
//Deceleration = DeclarationData.Driver.LookAhead.Deceleration,
MinSpeed = DeclarationData.Driver.LookAhead.MinimumSpeed,
LookAheadDecisionFactor = new LACDecisionFactor(),
LookAheadDistanceFactor = DeclarationData.Driver.LookAhead.LookAheadDistanceFactor,
......
......@@ -177,7 +177,7 @@ namespace TUGraz.VectoCore.Models.Declaration
//public static readonly PerSecond TorqueConverterSpeedLimit = 1600.RPMtoRad();
public static double TorqueConverterSecondGearThreshold(VehicleCategory category)
{
return category.IsTruck() ? 1.8 : 1.9;
return category.IsTruck() ? 1.8 : 1.85;
}
public static readonly Second PowershiftShiftTime = 0.8.SI<Second>();
......
......@@ -29,79 +29,79 @@
* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
*/
using System;
using System.Collections.Generic;
using System.IO;
using TUGraz.VectoCommon.Utils;
namespace TUGraz.VectoCore.Models.Declaration
{
public enum LoadingType
{
FullLoading,
ReferenceLoad,
LowLoading,
EmptyLoading,
}
public class Mission
{
public MissionType MissionType;
public string CrossWindCorrectionParameters;
public double[] AxleWeightDistribution;
public Kilogram BodyCurbWeight;
public Stream CycleFile;
public List<MissionTrailer> Trailer;
public Kilogram MinLoad;
public Kilogram LowLoad;
public Kilogram RefLoad;
public Kilogram MaxLoad;
public CubicMeter TotalCargoVolume;
public Dictionary<LoadingType, Kilogram> Loadings
{
get {
return new Dictionary<LoadingType, Kilogram> {
{ LoadingType.LowLoading, LowLoad },
{ LoadingType.ReferenceLoad, RefLoad },
};
}
}
}
public class MissionTrailer
{
public TrailerType TrailerType;
public Kilogram TrailerCurbWeight;
public Kilogram TrailerGrossVehicleWeight;
public List<Wheels.Entry> TrailerWheels;
public double TrailerAxleWeightShare;
public SquareMeter DeltaCdA;
public CubicMeter CargoVolume;
}
public enum TrailerType
{
//None,
T1,
T2,
ST1,
Dolly
}
public static class TrailterTypeHelper
{
public static TrailerType Parse(string trailer)
{
if ("d".Equals(trailer, StringComparison.InvariantCultureIgnoreCase)) {
return TrailerType.Dolly;
}
return trailer.ParseEnum<TrailerType>();
}
}
using System;
using System.Collections.Generic;
using System.IO;
using TUGraz.VectoCommon.Utils;
namespace TUGraz.VectoCore.Models.Declaration
{
public enum LoadingType
{
FullLoading,
ReferenceLoad,
LowLoading,
EmptyLoading,
}
public class Mission
{
public MissionType MissionType;
public string CrossWindCorrectionParameters;
public double[] AxleWeightDistribution;
public Kilogram BodyCurbWeight;
public Stream CycleFile;
public List<MissionTrailer> Trailer;
public Kilogram MinLoad;
public Kilogram LowLoad;
public Kilogram RefLoad;
public Kilogram MaxLoad;
public CubicMeter TotalCargoVolume;
public Dictionary<LoadingType, Kilogram> Loadings
{
get {
return new Dictionary<LoadingType, Kilogram> {
{ LoadingType.LowLoading, LowLoad },
{ LoadingType.ReferenceLoad, RefLoad },
};
}
}
}
public class MissionTrailer
{
public TrailerType TrailerType;
public Kilogram TrailerCurbWeight;
public Kilogram TrailerGrossVehicleWeight;
public List<Wheels.Entry> TrailerWheels;
public double TrailerAxleWeightShare;
public SquareMeter DeltaCdA;
public CubicMeter CargoVolume;
}
public enum TrailerType
{
//None,
T1,
T2,
ST1,
Dolly
}
public static class TrailterTypeHelper
{
public static TrailerType Parse(string trailer)
{
if ("d".Equals(trailer, StringComparison.InvariantCultureIgnoreCase)) {
return TrailerType.Dolly;
}
return trailer.ParseEnum<TrailerType>();
}
}
}
\ No newline at end of file
......@@ -29,38 +29,38 @@
* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
*/
using System.IO;
using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
namespace TUGraz.VectoCore.Models.Declaration
{
public class Segment
{
public VehicleClass VehicleClass { get; internal set; }
public VehicleCategory VehicleCategory { get; set; }
public AxleConfiguration AxleConfiguration { get; set; }
public Kilogram GrossVehicleWeightMin { get; set; }
public Kilogram GrossVehicleWeightMax { get; set; }
public Kilogram GrossVehicleMassRating { get; set; }
public Stream AccelerationFile { get; internal set; }
public Mission[] Missions { get; internal set; }
public Meter VehicleHeight { get; internal set; }
public MeterPerSecond DesignSpeed { get; internal set; }
public SquareMeter CdADefault { get; internal set; }
public SquareMeter CdAConstruction { get; internal set; }
public Kilogram MunicipalBodyWeight { get; internal set; }
}
using System.IO;
using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
namespace TUGraz.VectoCore.Models.Declaration
{
public class Segment
{
public VehicleClass VehicleClass { get; internal set; }
public VehicleCategory VehicleCategory { get; set; }
public AxleConfiguration AxleConfiguration { get; set; }
public Kilogram GrossVehicleWeightMin { get; set; }
public Kilogram GrossVehicleWeightMax { get; set; }
public Kilogram GrossVehicleMassRating { get; set; }
public Stream AccelerationFile { get; internal set; }
public Mission[] Missions { get; internal set; }
public Meter VehicleHeight { get; internal set; }
public MeterPerSecond DesignSpeed { get; internal set; }
public SquareMeter CdADefault { get; internal set; }
public SquareMeter CdAConstruction { get; internal set; }
public Kilogram MunicipalBodyWeight { get; internal set; }
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -29,28 +29,28 @@
* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
*/
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using TUGraz.VectoCommon.Exceptions;
using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Configuration;
using TUGraz.VectoCore.Models.Declaration;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Models.SimulationComponent.Data
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using TUGraz.VectoCommon.Exceptions;
using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Configuration;
using TUGraz.VectoCore.Models.Declaration;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Models.SimulationComponent.Data
{
[CustomValidation(typeof(AirdragData), "ValidateAirDragData")]
public class AirdragData : SimulationComponentData
{
public CrossWindCorrectionMode CrossWindCorrectionMode { get; set; }
[Required, ValidateObject]
public ICrossWindCorrection CrossWindCorrectionCurve { get; internal set; }
public SquareMeter DeclaredAirdragArea { get; internal set; }
public class AirdragData : SimulationComponentData
{
public CrossWindCorrectionMode CrossWindCorrectionMode { get; set; }
[Required, ValidateObject]
public ICrossWindCorrection CrossWindCorrectionCurve { get; internal set; }
public SquareMeter DeclaredAirdragArea { get; internal set; }
// ReSharper disable once UnusedMember.Global -- used via Validation
public static ValidationResult ValidateAirDragData(AirdragData airDragData, ValidationContext validationContext)
......@@ -62,229 +62,229 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
return ValidationResult.Success;
}
}
/// <summary>
/// Data Class for the Vehicle
/// </summary>
[CustomValidation(typeof(VehicleData), "ValidateVehicleData")]
public class VehicleData : SimulationComponentData
{
public string VIN { get; internal set; }
public string LegislativeClass { get; internal set; }
public VehicleCategory VehicleCategory { get; internal set; }
public VehicleClass VehicleClass { get; internal set; }
public AxleConfiguration AxleConfiguration { get; internal set; }
public string ManufacturerAddress { get; internal set; }
[Required, ValidateObject] private List<Axle> _axleData;
private KilogramSquareMeter _wheelsInertia;
private double? _totalRollResistanceCoefficient;
private double? _rollResistanceCoefficientWithoutTrailer;
public List<Axle> AxleData
{
get { return _axleData; }
internal set {
_axleData = value;
_wheelsInertia = null;
_totalRollResistanceCoefficient = null;
}
}
/// <summary>
/// The Curb Weight of the vehicle
/// (+ Curb Weight of Standard-Body if it has one)
/// (+ Curb Weight of Trailer if it has one)
/// </summary>
[Required, SIRange(500, 40000, emsMission: false),
SIRange(0, 60000, emsMission: true)]
public Kilogram CurbWeight { get; internal set; }
/// <summary>
/// Curb Weight of Standard-Body (if it has one)
/// + Curb Weight of Trailer (if it has one)
/// </summary>
public Kilogram BodyAndTrailerWeight { get; internal set; }
[Required, SIRange(0, 40000, emsMission: false),
SIRange(0, 60000, emsMission: true)]
public Kilogram Loading { get; internal set; }
[SIRange(0, 500)]
public CubicMeter CargoVolume { get; internal set; }
/// <summary>
/// The Gross Vehicle Weight of the Vehicle.
/// </summary>
[Required,
SIRange(3500, 40000, ExecutionMode.Declaration, emsMission: false),
SIRange(0, 60000, ExecutionMode.Declaration, emsMission: true),
SIRange(0, 1000000, ExecutionMode.Engineering)]
public Kilogram GrossVehicleWeight { get; internal set; }
/// <summary>
/// The Gross Vehicle Weight of the Trailer (if the vehicle has one).
/// </summary>
[Required, SIRange(0, 40000, emsMission: false),
SIRange(0, 60000, emsMission: true)]
public Kilogram TrailerGrossVehicleWeight { get; internal set; }
[Required, SIRange(0.1, 0.7)]
public Meter DynamicTyreRadius { get; internal set; }
public KilogramSquareMeter WheelsInertia
{
get {
if (_wheelsInertia == null) {
ComputeRollResistanceAndReducedMassWheels();
}
return _wheelsInertia;
}
internal set { _wheelsInertia = value; }
}
//[Required, SIRange(0, 1E12)]
public double TotalRollResistanceCoefficient
{
get {
if (_totalRollResistanceCoefficient == null) {
ComputeRollResistanceAndReducedMassWheels();
}
return _totalRollResistanceCoefficient.GetValueOrDefault();
}
protected internal set { _totalRollResistanceCoefficient = value; }
}
public double RollResistanceCoefficientWithoutTrailer
{
get {
if (_rollResistanceCoefficientWithoutTrailer == null) {
ComputeRollResistanceAndReducedMassWheels();
}
return _rollResistanceCoefficientWithoutTrailer.GetValueOrDefault();
}
protected internal set { _rollResistanceCoefficientWithoutTrailer = value; }
}
public Kilogram TotalVehicleWeight
{
get {
var retVal = 0.0.SI<Kilogram>();
retVal += CurbWeight ?? 0.SI<Kilogram>();
retVal += BodyAndTrailerWeight ?? 0.SI<Kilogram>();
retVal += Loading ?? 0.SI<Kilogram>();
return retVal;
}
}
public Kilogram TotalCurbWeight
{
get { return (CurbWeight ?? 0.SI<Kilogram>()) + (BodyAndTrailerWeight ?? 0.SI<Kilogram>()); }
}
protected void ComputeRollResistanceAndReducedMassWheels()
{
if (TotalVehicleWeight == 0.SI<Kilogram>()) {
throw new VectoException("Total vehicle weight must be greater than 0! Set CurbWeight and Loading before!");
}
if (DynamicTyreRadius == null) {
throw new VectoException("Dynamic tyre radius must be set before axles!");
}
var g = Physics.GravityAccelleration;
var rrc = 0.0.SI<Scalar>();
var rrcVehicle = 0.0.SI<Scalar>();
var wheelsInertia = 0.0.SI<KilogramSquareMeter>();
var vehicleWeightShare = 0.0;
foreach (var axle in _axleData) {
if (axle.AxleWeightShare.IsEqual(0, 1e-12)) {
continue;
}
var nrWheels = axle.TwinTyres ? 4 : 2;
var baseValue = (axle.AxleWeightShare * TotalVehicleWeight * g / axle.TyreTestLoad / nrWheels).Value();
var rrcShare = axle.AxleWeightShare * axle.RollResistanceCoefficient *
Math.Pow(baseValue, Physics.RollResistanceExponent - 1);
if (axle.AxleType != AxleType.Trailer) {
rrcVehicle += rrcShare;
vehicleWeightShare += axle.AxleWeightShare;
}
rrc += rrcShare;
wheelsInertia += nrWheels * axle.Inertia;
}
RollResistanceCoefficientWithoutTrailer = rrcVehicle / vehicleWeightShare;
TotalRollResistanceCoefficient = rrc;
WheelsInertia = wheelsInertia;
}
// ReSharper disable once UnusedMember.Global -- used via Validation
public static ValidationResult ValidateVehicleData(VehicleData vehicleData, ValidationContext validationContext)
{
var mode = GetExecutionMode(validationContext);
var emsCycle = GetEmsMode(validationContext);
if (vehicleData.AxleData.Count < 1) {
return new ValidationResult("At least two axles need to be specified");
}
var weightShareSum = vehicleData.AxleData.Sum(axle => axle.AxleWeightShare);
if (!weightShareSum.IsEqual(1.0, 1E-10)) {
return new ValidationResult(
string.Format("Sum of axle weight share is not 1! sum: {0}, difference: {1}",
weightShareSum, 1 - weightShareSum));
}
for (var i = 0; i < vehicleData.AxleData.Count; i++) {
if (vehicleData.AxleData[i].TyreTestLoad.IsSmallerOrEqual(0)) {
return new ValidationResult(string.Format("Tyre test load (FzISO) for axle {0} must be greater than 0.", i));
}
}
if (vehicleData.TotalRollResistanceCoefficient <= 0) {
return
new ValidationResult(string.Format("Total rolling resistance must be greater than 0! {0}",
vehicleData.TotalRollResistanceCoefficient));
}
// total gvw is limited by max gvw (40t)
var gvwTotal = VectoMath.Min(vehicleData.GrossVehicleWeight + vehicleData.TrailerGrossVehicleWeight,
emsCycle
? Constants.SimulationSettings.MaximumGrossVehicleWeightEMS
: Constants.SimulationSettings.MaximumGrossVehicleWeight);
if (mode != ExecutionMode.Declaration) {
return ValidationResult.Success;
}
// vvvvvvv these checks apply only for declaration mode! vvvvvv
//if (vehicleData.AxleConfiguration.NumAxles() != vehicleData.AxleData.Count) {
// return
// new ValidationResult(
// string.Format("For a {0} type vehicle exactly {1} number of axles have to pe specified. Found {2}",
// vehicleData.AxleConfiguration.GetName(), vehicleData.AxleConfiguration.NumAxles(), vehicleData.AxleData.Count));
//}
if (vehicleData.TotalVehicleWeight > gvwTotal) {
return new ValidationResult(
string.Format("Total Vehicle Weight is greater than GrossVehicleWeight! Weight: {0}, GVW: {1}",
vehicleData.TotalVehicleWeight, gvwTotal));
}
var numDrivenAxles = vehicleData._axleData.Count(x => x.AxleType == AxleType.VehicleDriven);
if (numDrivenAxles != 1) {
return new ValidationResult("Exactly one axle has to be defined as driven!");
}
return ValidationResult.Success;
}
}
}
/// <summary>
/// Data Class for the Vehicle
/// </summary>
[CustomValidation(typeof(VehicleData), "ValidateVehicleData")]
public class VehicleData : SimulationComponentData
{
public string VIN { get; internal set; }
public string LegislativeClass { get; internal set; }
public VehicleCategory VehicleCategory { get; internal set; }
public VehicleClass VehicleClass { get; internal set; }
public AxleConfiguration AxleConfiguration { get; internal set; }
public string ManufacturerAddress { get; internal set; }
[Required, ValidateObject] private List<Axle> _axleData;
private KilogramSquareMeter _wheelsInertia;
private double? _totalRollResistanceCoefficient;
private double? _rollResistanceCoefficientWithoutTrailer;
public List<Axle> AxleData
{
get { return _axleData; }
internal set {
_axleData = value;
_wheelsInertia = null;
_totalRollResistanceCoefficient = null;
}
}
/// <summary>
/// The Curb Weight of the vehicle
/// (+ Curb Weight of Standard-Body if it has one)
/// (+ Curb Weight of Trailer if it has one)
/// </summary>
[Required, SIRange(500, 40000, emsMission: false),
SIRange(0, 60000, emsMission: true)]
public Kilogram CurbWeight { get; internal set; }
/// <summary>
/// Curb Weight of Standard-Body (if it has one)
/// + Curb Weight of Trailer (if it has one)
/// </summary>
public Kilogram BodyAndTrailerWeight { get; internal set; }
[Required, SIRange(0, 40000, emsMission: false),
SIRange(0, 60000, emsMission: true)]
public Kilogram Loading { get; internal set; }
[SIRange(0, 500)]
public CubicMeter CargoVolume { get; internal set; }
/// <summary>
/// The Gross Vehicle Weight of the Vehicle.
/// </summary>
[Required,
SIRange(3500, 40000, ExecutionMode.Declaration, emsMission: false),
SIRange(0, 60000, ExecutionMode.Declaration, emsMission: true),
SIRange(0, 1000000, ExecutionMode.Engineering)]
public Kilogram GrossVehicleWeight { get; internal set; }
/// <summary>
/// The Gross Vehicle Weight of the Trailer (if the vehicle has one).
/// </summary>
[Required, SIRange(0, 40000, emsMission: false),
SIRange(0, 60000, emsMission: true)]
public Kilogram TrailerGrossVehicleWeight { get; internal set; }
[Required, SIRange(0.1, 0.7)]
public Meter DynamicTyreRadius { get; internal set; }
public KilogramSquareMeter WheelsInertia
{
get {
if (_wheelsInertia == null) {
ComputeRollResistanceAndReducedMassWheels();
}
return _wheelsInertia;
}
internal set { _wheelsInertia = value; }
}
//[Required, SIRange(0, 1E12)]
public double TotalRollResistanceCoefficient
{
get {
if (_totalRollResistanceCoefficient == null) {
ComputeRollResistanceAndReducedMassWheels();
}
return _totalRollResistanceCoefficient.GetValueOrDefault();
}
protected internal set { _totalRollResistanceCoefficient = value; }
}
public double RollResistanceCoefficientWithoutTrailer
{
get {
if (_rollResistanceCoefficientWithoutTrailer == null) {
ComputeRollResistanceAndReducedMassWheels();
}
return _rollResistanceCoefficientWithoutTrailer.GetValueOrDefault();
}
protected internal set { _rollResistanceCoefficientWithoutTrailer = value; }
}
public Kilogram TotalVehicleWeight
{
get {
var retVal = 0.0.SI<Kilogram>();
retVal += CurbWeight ?? 0.SI<Kilogram>();
retVal += BodyAndTrailerWeight ?? 0.SI<Kilogram>();
retVal += Loading ?? 0.SI<Kilogram>();
return retVal;
}
}
public Kilogram TotalCurbWeight
{
get { return (CurbWeight ?? 0.SI<Kilogram>()) + (BodyAndTrailerWeight ?? 0.SI<Kilogram>()); }
}
protected void ComputeRollResistanceAndReducedMassWheels()
{
if (TotalVehicleWeight == 0.SI<Kilogram>()) {
throw new VectoException("Total vehicle weight must be greater than 0! Set CurbWeight and Loading before!");
}
if (DynamicTyreRadius == null) {
throw new VectoException("Dynamic tyre radius must be set before axles!");
}
var g = Physics.GravityAccelleration;
var rrc = 0.0.SI<Scalar>();
var rrcVehicle = 0.0.SI<Scalar>();
var wheelsInertia = 0.0.SI<KilogramSquareMeter>();
var vehicleWeightShare = 0.0;
foreach (var axle in _axleData) {
if (axle.AxleWeightShare.IsEqual(0, 1e-12)) {
continue;
}
var nrWheels = axle.TwinTyres ? 4 : 2;
var baseValue = (axle.AxleWeightShare * TotalVehicleWeight * g / axle.TyreTestLoad / nrWheels).Value();
var rrcShare = axle.AxleWeightShare * axle.RollResistanceCoefficient *
Math.Pow(baseValue, Physics.RollResistanceExponent - 1);
if (axle.AxleType != AxleType.Trailer) {
rrcVehicle += rrcShare;
vehicleWeightShare += axle.AxleWeightShare;
}
rrc += rrcShare;
wheelsInertia += nrWheels * axle.Inertia;
}
RollResistanceCoefficientWithoutTrailer = rrcVehicle / vehicleWeightShare;
TotalRollResistanceCoefficient = rrc;
WheelsInertia = wheelsInertia;
}
// ReSharper disable once UnusedMember.Global -- used via Validation
public static ValidationResult ValidateVehicleData(VehicleData vehicleData, ValidationContext validationContext)
{
var mode = GetExecutionMode(validationContext);
var emsCycle = GetEmsMode(validationContext);
if (vehicleData.AxleData.Count < 1) {
return new ValidationResult("At least two axles need to be specified");
}
var weightShareSum = vehicleData.AxleData.Sum(axle => axle.AxleWeightShare);
if (!weightShareSum.IsEqual(1.0, 1E-10)) {
return new ValidationResult(
string.Format("Sum of axle weight share is not 1! sum: {0}, difference: {1}",
weightShareSum, 1 - weightShareSum));
}
for (var i = 0; i < vehicleData.AxleData.Count; i++) {
if (vehicleData.AxleData[i].TyreTestLoad.IsSmallerOrEqual(0)) {
return new ValidationResult(string.Format("Tyre test load (FzISO) for axle {0} must be greater than 0.", i));
}
}
if (vehicleData.TotalRollResistanceCoefficient <= 0) {
return
new ValidationResult(string.Format("Total rolling resistance must be greater than 0! {0}",
vehicleData.TotalRollResistanceCoefficient));
}
// total gvw is limited by max gvw (40t)
var gvwTotal = VectoMath.Min(vehicleData.GrossVehicleWeight + vehicleData.TrailerGrossVehicleWeight,
emsCycle
? Constants.SimulationSettings.MaximumGrossVehicleWeightEMS
: Constants.SimulationSettings.MaximumGrossVehicleWeight);
if (mode != ExecutionMode.Declaration) {
return ValidationResult.Success;
}
// vvvvvvv these checks apply only for declaration mode! vvvvvv
//if (vehicleData.AxleConfiguration.NumAxles() != vehicleData.AxleData.Count) {
// return
// new ValidationResult(
// string.Format("For a {0} type vehicle exactly {1} number of axles have to pe specified. Found {2}",
// vehicleData.AxleConfiguration.GetName(), vehicleData.AxleConfiguration.NumAxles(), vehicleData.AxleData.Count));
//}
if (vehicleData.TotalVehicleWeight > gvwTotal) {
return new ValidationResult(
string.Format("Total Vehicle Weight is greater than GrossVehicleWeight! Weight: {0}, GVW: {1}",
vehicleData.TotalVehicleWeight, gvwTotal));
}
var numDrivenAxles = vehicleData._axleData.Count(x => x.AxleType == AxleType.VehicleDriven);
if (numDrivenAxles != 1) {
return new ValidationResult("Exactly one axle has to be defined as driven!");
}
return ValidationResult.Success;
}
}
}
\ No newline at end of file
......@@ -29,228 +29,228 @@
* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
*/
using System;
using TUGraz.VectoCommon.Exceptions;
using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Configuration;
using TUGraz.VectoCore.Models.Connector.Ports;
using TUGraz.VectoCore.Models.Simulation;
using TUGraz.VectoCore.Models.Simulation.Data;
using TUGraz.VectoCore.Models.Simulation.DataBus;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.OutputData;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
public class Vehicle : StatefulProviderComponent<Vehicle.VehicleState, IDriverDemandOutPort, IFvInPort, IFvOutPort>,
IVehicle, IMileageCounter, IFvInPort,
IDriverDemandOutPort
{
internal readonly VehicleData ModelData;
public readonly AirdragData AirdragData;
public Vehicle(IVehicleContainer container, VehicleData modelData, AirdragData airdrag) : base(container)
{
ModelData = modelData;
AirdragData = airdrag;
if (AirdragData.CrossWindCorrectionCurve != null) {
AirdragData.CrossWindCorrectionCurve.SetDataBus(container);
}
}
public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient)
{
PreviousState = new VehicleState {
Distance = DataBus.CycleStartDistance,
Velocity = vehicleSpeed,
RollingResistance = RollingResistance(roadGradient),
SlopeResistance = SlopeResistance(roadGradient),
AirDragResistance = AirDragResistance(vehicleSpeed, vehicleSpeed),
};
PreviousState.VehicleTractionForce = PreviousState.RollingResistance
+ PreviousState.AirDragResistance
+ PreviousState.SlopeResistance;
return NextComponent.Initialize(PreviousState.VehicleTractionForce, vehicleSpeed);
}
public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient, MeterPerSquareSecond startAcceleration)
{
//CurrentState.Velocity = vehicleSpeed + startAcceleration * Constants.SimulationSettings.TargetTimeInterval;
var vehicleAccelerationForce = DriverAcceleration(startAcceleration)
+ RollingResistance(roadGradient)
+
AirDragResistance(vehicleSpeed,
vehicleSpeed + startAcceleration * Constants.SimulationSettings.TargetTimeInterval)
+ SlopeResistance(roadGradient);
var retVal = NextComponent.Initialize(vehicleAccelerationForce, vehicleSpeed);
return retVal;
}
public IResponse Request(Second absTime, Second dt, MeterPerSquareSecond acceleration, Radian gradient,
bool dryRun = false)
{
Log.Debug("Vehicle: acceleration: {0}", acceleration);
CurrentState.SimulationInterval = dt;
CurrentState.Acceleration = acceleration;
CurrentState.Velocity = PreviousState.Velocity + acceleration * dt;
if (CurrentState.Velocity.IsEqual(0.SI<MeterPerSecond>(),
Constants.SimulationSettings.VehicleSpeedHaltTolerance)) {
CurrentState.Velocity = 0.SI<MeterPerSecond>();
}
CurrentState.Distance = PreviousState.Distance + PreviousState.Velocity * dt + acceleration * dt * dt / 2;
CurrentState.DriverAcceleration = DriverAcceleration(acceleration);
CurrentState.RollingResistance = RollingResistance(gradient);
try {
CurrentState.AirDragResistance = AirDragResistance(PreviousState.Velocity, CurrentState.Velocity);
} catch (VectoException ex) {
Log.Warn("Exception during calculation of AirDragResistance: absTime: {0}, dist: {1}, v: {2}. {3}", absTime,
CurrentState.Distance, CurrentState.Velocity, ex);
CurrentState.AirDragResistance = AirDragResistance(VectoMath.Max(0, PreviousState.Velocity),
VectoMath.Max(0, CurrentState.Velocity));
}
CurrentState.SlopeResistance = SlopeResistance(gradient);
// DriverAcceleration = vehicleTractionForce - RollingResistance - AirDragResistance - SlopeResistance
CurrentState.VehicleTractionForce = CurrentState.DriverAcceleration
+ CurrentState.RollingResistance
+ CurrentState.AirDragResistance
+ CurrentState.SlopeResistance;
var retval = NextComponent.Request(absTime, dt, CurrentState.VehicleTractionForce,
CurrentState.Velocity, dryRun);
return retval;
}
protected override void DoWriteModalResults(IModalDataContainer container)
{
var averageVelocity = (PreviousState.Velocity + CurrentState.Velocity) / 2.0;
container[ModalResultField.v_act] = averageVelocity;
container[ModalResultField.P_veh_inertia] = CurrentState.DriverAcceleration * averageVelocity;
container[ModalResultField.P_roll] = CurrentState.RollingResistance * averageVelocity;
container[ModalResultField.P_air] = CurrentState.AirDragResistance * averageVelocity;
container[ModalResultField.P_slope] = CurrentState.SlopeResistance * averageVelocity;
container[ModalResultField.P_trac] = CurrentState.VehicleTractionForce * averageVelocity;
// sanity check: is the vehicle in step with the cycle?
if (container[ModalResultField.dist] == DBNull.Value) {
Log.Warn("Distance field is not set!");
} else {
var distance = (SI)container[ModalResultField.dist];
if (!distance.IsEqual(CurrentState.Distance)) {
Log.Warn("Vehicle Distance diverges from Cycle by {0} [m]. Distance: {1}",
(distance - CurrentState.Distance).Value(), distance);
}
}
}
public Newton RollingResistance(Radian gradient)
{
var weight = ModelData.TotalVehicleWeight;
var gravity = Physics.GravityAccelleration;
var rollCoefficient = ModelData.TotalRollResistanceCoefficient;
var retVal = Math.Cos(gradient.Value()) * weight * gravity * rollCoefficient;
Log.Debug("RollingResistance: {0}", retVal);
return retVal;
}
protected internal Newton DriverAcceleration(MeterPerSquareSecond accelleration)
{
var retVal = ModelData.TotalVehicleWeight * accelleration;
Log.Debug("DriverAcceleration: {0}", retVal);
return retVal;
}
public Newton SlopeResistance(Radian gradient)
{
var retVal = ModelData.TotalVehicleWeight * Physics.GravityAccelleration * Math.Sin(gradient.Value());
Log.Debug("SlopeResistance: {0}", retVal);
return retVal;
}
public Newton AirDragResistance(MeterPerSecond previousVelocity, MeterPerSecond nextVelocity)
{
var vAverage = (previousVelocity + nextVelocity) / 2;
if (vAverage.IsEqual(0)) {
return 0.SI<Newton>();
}
var result = ComputeAirDragPowerLoss(previousVelocity, nextVelocity) / vAverage;
Log.Debug("AirDragResistance: {0}", result);
return result;
}
private Watt ComputeAirDragPowerLoss(MeterPerSecond v1, MeterPerSecond v2)
{
return AirdragData.CrossWindCorrectionCurve.AverageAirDragPowerLoss(v1, v2);
}
public Meter Distance
{
get { return PreviousState.Distance; }
}
public MeterPerSecond VehicleSpeed
{
get { return PreviousState.Velocity; }
}
public bool VehicleStopped
{
get { return PreviousState.Velocity.IsEqual(0.SI<MeterPerSecond>(), 0.01.SI<MeterPerSecond>()); }
}
public Kilogram VehicleMass
{
get { return ModelData.TotalCurbWeight; }
}
public Kilogram VehicleLoading
{
get { return ModelData.Loading; }
}
public Kilogram TotalMass
{
get { return ModelData.TotalVehicleWeight; }
}
public CubicMeter CargoVolume
{
get { return ModelData.CargoVolume; }
}
public class VehicleState
{
public Meter Distance = 0.SI<Meter>();
public Second SimulationInterval = 0.SI<Second>();
public Newton AirDragResistance = 0.SI<Newton>();
public Newton DriverAcceleration = 0.SI<Newton>();
public Newton RollingResistance = 0.SI<Newton>();
public Newton SlopeResistance = 0.SI<Newton>();
public Newton VehicleTractionForce = 0.SI<Newton>();
public MeterPerSecond Velocity = 0.SI<MeterPerSecond>();
public MeterPerSquareSecond Acceleration = 0.SI<MeterPerSquareSecond>();
public override string ToString()
{
return
string.Format(
"v: {0} a: {1}, dt: {2}, driver_acc: {3}, roll_res: {4}, slope_res: {5}, air_drag: {6}, traction force: {7}",
Velocity, Acceleration, SimulationInterval, DriverAcceleration, RollingResistance, SlopeResistance,
AirDragResistance,
VehicleTractionForce);
}
}
}
using System;
using TUGraz.VectoCommon.Exceptions;
using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Configuration;
using TUGraz.VectoCore.Models.Connector.Ports;
using TUGraz.VectoCore.Models.Simulation;
using TUGraz.VectoCore.Models.Simulation.Data;
using TUGraz.VectoCore.Models.Simulation.DataBus;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.OutputData;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
public class Vehicle : StatefulProviderComponent<Vehicle.VehicleState, IDriverDemandOutPort, IFvInPort, IFvOutPort>,
IVehicle, IMileageCounter, IFvInPort,
IDriverDemandOutPort
{
internal readonly VehicleData ModelData;
public readonly AirdragData AirdragData;
public Vehicle(IVehicleContainer container, VehicleData modelData, AirdragData airdrag) : base(container)
{
ModelData = modelData;
AirdragData = airdrag;
if (AirdragData.CrossWindCorrectionCurve != null) {
AirdragData.CrossWindCorrectionCurve.SetDataBus(container);
}
}
public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient)
{
PreviousState = new VehicleState {
Distance = DataBus.CycleStartDistance,
Velocity = vehicleSpeed,
RollingResistance = RollingResistance(roadGradient),
SlopeResistance = SlopeResistance(roadGradient),
AirDragResistance = AirDragResistance(vehicleSpeed, vehicleSpeed),
};
PreviousState.VehicleTractionForce = PreviousState.RollingResistance
+ PreviousState.AirDragResistance
+ PreviousState.SlopeResistance;
return NextComponent.Initialize(PreviousState.VehicleTractionForce, vehicleSpeed);
}
public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient, MeterPerSquareSecond startAcceleration)
{
//CurrentState.Velocity = vehicleSpeed + startAcceleration * Constants.SimulationSettings.TargetTimeInterval;
var vehicleAccelerationForce = DriverAcceleration(startAcceleration)
+ RollingResistance(roadGradient)
+
AirDragResistance(vehicleSpeed,
vehicleSpeed + startAcceleration * Constants.SimulationSettings.TargetTimeInterval)
+ SlopeResistance(roadGradient);
var retVal = NextComponent.Initialize(vehicleAccelerationForce, vehicleSpeed);
return retVal;
}
public IResponse Request(Second absTime, Second dt, MeterPerSquareSecond acceleration, Radian gradient,
bool dryRun = false)
{
Log.Debug("Vehicle: acceleration: {0}", acceleration);
CurrentState.SimulationInterval = dt;
CurrentState.Acceleration = acceleration;
CurrentState.Velocity = PreviousState.Velocity + acceleration * dt;
if (CurrentState.Velocity.IsEqual(0.SI<MeterPerSecond>(),
Constants.SimulationSettings.VehicleSpeedHaltTolerance)) {
CurrentState.Velocity = 0.SI<MeterPerSecond>();
}
CurrentState.Distance = PreviousState.Distance + PreviousState.Velocity * dt + acceleration * dt * dt / 2;
CurrentState.DriverAcceleration = DriverAcceleration(acceleration);
CurrentState.RollingResistance = RollingResistance(gradient);
try {
CurrentState.AirDragResistance = AirDragResistance(PreviousState.Velocity, CurrentState.Velocity);
} catch (VectoException ex) {
Log.Warn("Exception during calculation of AirDragResistance: absTime: {0}, dist: {1}, v: {2}. {3}", absTime,
CurrentState.Distance, CurrentState.Velocity, ex);
CurrentState.AirDragResistance = AirDragResistance(VectoMath.Max(0, PreviousState.Velocity),
VectoMath.Max(0, CurrentState.Velocity));
}
CurrentState.SlopeResistance = SlopeResistance(gradient);
// DriverAcceleration = vehicleTractionForce - RollingResistance - AirDragResistance - SlopeResistance
CurrentState.VehicleTractionForce = CurrentState.DriverAcceleration
+ CurrentState.RollingResistance
+ CurrentState.AirDragResistance
+ CurrentState.SlopeResistance;
var retval = NextComponent.Request(absTime, dt, CurrentState.VehicleTractionForce,
CurrentState.Velocity, dryRun);
return retval;
}
protected override void DoWriteModalResults(IModalDataContainer container)
{
var averageVelocity = (PreviousState.Velocity + CurrentState.Velocity) / 2.0;
container[ModalResultField.v_act] = averageVelocity;
container[ModalResultField.P_veh_inertia] = CurrentState.DriverAcceleration * averageVelocity;
container[ModalResultField.P_roll] = CurrentState.RollingResistance * averageVelocity;
container[ModalResultField.P_air] = CurrentState.AirDragResistance * averageVelocity;
container[ModalResultField.P_slope] = CurrentState.SlopeResistance * averageVelocity;
container[ModalResultField.P_trac] = CurrentState.VehicleTractionForce * averageVelocity;
// sanity check: is the vehicle in step with the cycle?
if (container[ModalResultField.dist] == DBNull.Value) {
Log.Warn("Distance field is not set!");
} else {
var distance = (SI)container[ModalResultField.dist];
if (!distance.IsEqual(CurrentState.Distance)) {
Log.Warn("Vehicle Distance diverges from Cycle by {0} [m]. Distance: {1}",
(distance - CurrentState.Distance).Value(), distance);
}
}
}
public Newton RollingResistance(Radian gradient)
{
var weight = ModelData.TotalVehicleWeight;
var gravity = Physics.GravityAccelleration;
var rollCoefficient = ModelData.TotalRollResistanceCoefficient;
var retVal = Math.Cos(gradient.Value()) * weight * gravity * rollCoefficient;
Log.Debug("RollingResistance: {0}", retVal);
return retVal;
}
protected internal Newton DriverAcceleration(MeterPerSquareSecond accelleration)
{
var retVal = ModelData.TotalVehicleWeight * accelleration;
Log.Debug("DriverAcceleration: {0}", retVal);
return retVal;
}
public Newton SlopeResistance(Radian gradient)
{
var retVal = ModelData.TotalVehicleWeight * Physics.GravityAccelleration * Math.Sin(gradient.Value());
Log.Debug("SlopeResistance: {0}", retVal);
return retVal;
}
public Newton AirDragResistance(MeterPerSecond previousVelocity, MeterPerSecond nextVelocity)
{
var vAverage = (previousVelocity + nextVelocity) / 2;
if (vAverage.IsEqual(0)) {
return 0.SI<Newton>();
}
var result = ComputeAirDragPowerLoss(previousVelocity, nextVelocity) / vAverage;
Log.Debug("AirDragResistance: {0}", result);
return result;
}
private Watt ComputeAirDragPowerLoss(MeterPerSecond v1, MeterPerSecond v2)
{
return AirdragData.CrossWindCorrectionCurve.AverageAirDragPowerLoss(v1, v2);
}
public Meter Distance
{
get { return PreviousState.Distance; }
}
public MeterPerSecond VehicleSpeed
{
get { return PreviousState.Velocity; }
}
public bool VehicleStopped
{
get { return PreviousState.Velocity.IsEqual(0.SI<MeterPerSecond>(), 0.01.SI<MeterPerSecond>()); }
}
public Kilogram VehicleMass
{
get { return ModelData.TotalCurbWeight; }
}
public Kilogram VehicleLoading
{
get { return ModelData.Loading; }
}
public Kilogram TotalMass
{
get { return ModelData.TotalVehicleWeight; }
}
public CubicMeter CargoVolume
{
get { return ModelData.CargoVolume; }
}
public class VehicleState
{
public Meter Distance = 0.SI<Meter>();
public Second SimulationInterval = 0.SI<Second>();
public Newton AirDragResistance = 0.SI<Newton>();
public Newton DriverAcceleration = 0.SI<Newton>();
public Newton RollingResistance = 0.SI<Newton>();
public Newton SlopeResistance = 0.SI<Newton>();
public Newton VehicleTractionForce = 0.SI<Newton>();
public MeterPerSecond Velocity = 0.SI<MeterPerSecond>();
public MeterPerSquareSecond Acceleration = 0.SI<MeterPerSquareSecond>();
public override string ToString()
{
return
string.Format(
"v: {0} a: {1}, dt: {2}, driver_acc: {3}, roll_res: {4}, slope_res: {5}, air_drag: {6}, traction force: {7}",
Velocity, Acceleration, SimulationInterval, DriverAcceleration, RollingResistance, SlopeResistance,
AirDragResistance,
VehicleTractionForce);
}
}
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment