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

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

Merge branch 'develop' of...

parents f18f37c1 8c2ae933
Branches
Tags
No related merge requests found
Showing
with 605 additions and 456 deletions
......@@ -110,7 +110,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
var gearbox = new CycleGearbox(container, data.GearboxData, data.EngineData.Inertia);
// PWheelCycle --> AxleGear --> CycleClutch --> Engine <-- Aux
var powertrain = new PWheelCycle(container, data.Cycle, data.AxleGearData.AxleGear.Ratio,
var powertrain = new PWheelCycle(container, data.Cycle, data.AxleGearData.AxleGear.Ratio, data.VehicleData,
gearbox.ModelData.Gears.ToDictionary(g => g.Key, g => g.Value.Ratio))
.AddComponent(new AxleGear(container, data.AxleGearData))
.AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null)
......@@ -235,7 +235,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
{
var conventionalAux = CreateAuxiliaries(data, container);
var busAux = new BusAuxiliariesAdapter(container, data.AdvancedAux.AdvancedAuxiliaryFilePath, data.Cycle.Name,
data.VehicleData.TotalVehicleWeight(), data.EngineData.ConsumptionMap, data.EngineData.IdleSpeed, conventionalAux);
data.VehicleData.TotalVehicleWeight, data.EngineData.ConsumptionMap, data.EngineData.IdleSpeed, conventionalAux);
return busAux;
}
......
......@@ -180,6 +180,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
if (k.IsEqual(0, 0.0001)) {
// constant torque: solve linear equation
// power = M * n_eng_avg
if (d.IsEqual(0, 0.0001)) {
return new List<PerSecond>();
}
return (power / d).ToEnumerable();
}
......
......@@ -126,24 +126,29 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
public CrossWindCorrectionMode CrossWindCorrectionMode { get; set; }
public Kilogram TotalVehicleWeight()
public Kilogram TotalVehicleWeight
{
get
{
var retVal = 0.0;
if (CurbWeight != null)
if (CurbWeight != null) {
retVal += CurbWeight.Value();
if (Loading != null)
}
if (Loading != null) {
retVal += Loading.Value();
}
return retVal.SI<Kilogram>();
}
}
public Kilogram TotalCurbWeight()
public Kilogram TotalCurbWeight
{
return CurbWeight ?? 0.SI<Kilogram>();
get { return CurbWeight ?? 0.SI<Kilogram>(); }
}
protected void ComputeRollResistanceAndReducedMassWheels()
{
if (TotalVehicleWeight() == 0.SI<Kilogram>()) {
if (TotalVehicleWeight == 0.SI<Kilogram>()) {
throw new VectoException("Total vehicle weight must be greater than 0! Set CurbWeight and Loading before!");
}
if (DynamicTyreRadius == null) {
......@@ -159,7 +164,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
continue;
}
var nrWheels = axle.TwinTyres ? 4 : 2;
var baseValue = (axle.AxleWeightShare * TotalVehicleWeight() * g / axle.TyreTestLoad / nrWheels).Value();
var baseValue = (axle.AxleWeightShare * TotalVehicleWeight * g / axle.TyreTestLoad / nrWheels).Value();
rrc += axle.AxleWeightShare * axle.RollResistanceCoefficient *
Math.Pow(baseValue, Physics.RollResistanceExponent - 1);
......@@ -211,10 +216,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
// vehicleData.AxleConfiguration.GetName(), vehicleData.AxleConfiguration.NumAxles(), vehicleData.AxleData.Count));
//}
if (vehicleData.TotalVehicleWeight() > gvwTotal) {
if (vehicleData.TotalVehicleWeight > gvwTotal) {
return new ValidationResult(
string.Format("Total Vehicle Weight is greater than GrossVehicleWeight! Weight: {0}, GVW: {1}",
vehicleData.TotalVehicleWeight(), gvwTotal));
vehicleData.TotalVehicleWeight, gvwTotal));
}
return ValidationResult.Success;
}
......
......@@ -117,7 +117,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public abstract GearInfo NextGear { get; }
public Second TractionInterruption
public virtual Second TractionInterruption
{
get { return ModelData.TractionInterruption; }
}
......
......@@ -500,6 +500,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
private Second _idleStart;
private Watt _lastEnginePower;
private PerSecond _engineTargetSpeed;
public ITnOutPort RequestPort { private get; set; }
......@@ -539,9 +540,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
if (!outTorque.IsEqual(0)) {
throw new VectoException("Torque has to be 0 for idle requests!");
}
var targetVelocity = _engine.PreviousState.EngineSpeed / _dataBus.GetGearData(_dataBus.Gear).Ratio *
if (_idleStart == null) {
_idleStart = absTime;
_engineTargetSpeed = _engine.PreviousState.EngineSpeed / _dataBus.GetGearData(_dataBus.Gear).Ratio *
_dataBus.GetGearData(_dataBus.NextGear.Gear).Ratio;
var velocitySlope = (targetVelocity - _engine.PreviousState.EngineSpeed) / _dataBus.TractionInterruption;
}
var velocitySlope = (_engineTargetSpeed - _engine.PreviousState.EngineSpeed) / (_dataBus.TractionInterruption - (absTime - _idleStart));
var nextAngularSpeed = (velocitySlope * dt + _engine.PreviousState.EngineSpeed);
if (nextAngularSpeed < _engine.ModelData.IdleSpeed) {
......
......@@ -48,6 +48,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
public class CycleGearbox : AbstractGearbox<CycleGearbox.CycleGearboxState>
{
/// <summary>
/// True if gearbox is disengaged (no gear is set).
/// </summary>
protected internal Second Disengaged = null;
protected bool? TorqueConverterActive;
protected internal readonly TorqueConverter TorqueConverter;
......@@ -130,9 +135,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
bool dryRun = false)
{
Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity);
Gear = DataBus.DriverBehavior == DrivingBehavior.Braking
? DataBus.CycleData.LeftSample.Gear
: DataBus.CycleData.RightSample.Gear;
var gear = GetGearFromCycle();
TorqueConverterActive = DataBus.DriverBehavior == DrivingBehavior.Braking
? DataBus.CycleData.LeftSample.TorqueConverterActive
......@@ -141,13 +144,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
if (TorqueConverter != null && TorqueConverterActive == null) {
throw new VectoSimulationException("Driving cycle does not contain information about TorqueConverter!");
}
if (Gear != 0 && !ModelData.Gears.ContainsKey(Gear)) {
throw new VectoSimulationException("Requested Gear {0} from driving cycle is not available", Gear);
if (gear != 0 && !ModelData.Gears.ContainsKey(gear)) {
throw new VectoSimulationException("Requested Gear {0} from driving cycle is not available", gear);
}
// mk 2016-11-30: added additional check for outAngularVelocity due to failing test: MeasuredSpeed_Gear_AT_PS_Run
// mq 2016-12-16: changed check to vehicle halted due to failing test: MeasuredSpeed_Gear_AT_*
var retVal = Gear == 0 || DataBus.DriverBehavior == DrivingBehavior.Halted
var retVal = gear == 0 || DataBus.DriverBehavior == DrivingBehavior.Halted
//|| (outAngularVelocity.IsSmallerOrEqual(0, 1) && outTorque.IsSmallerOrEqual(0, 1))
? RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun)
: RequestEngaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
......@@ -156,6 +159,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return retVal;
}
private uint GetGearFromCycle()
{
return DataBus.DriverBehavior == DrivingBehavior.Braking
? DataBus.CycleData.LeftSample.Gear
: DataBus.CycleData.RightSample.Gear;
}
/// <summary>
/// Handles requests when a gear is engaged
/// </summary>
......@@ -168,6 +178,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
private IResponse RequestEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
bool dryRun)
{
Disengaged = null;
Gear = GetGearFromCycle();
var torqueConverterLocked = TorqueConverterActive == null || !TorqueConverterActive.Value;
var effectiveRatio = ModelData.Gears[Gear].Ratio;
......@@ -270,6 +284,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
private IResponse RequestDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
bool dryRun)
{
if (Disengaged == null) {
Disengaged = absTime;
}
var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
if (dryRun) {
// if gearbox is disengaged the 0-line is the limit for drag and full load
......@@ -298,13 +316,49 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
};
}
CurrentState.SetState(0.SI<NewtonMeter>(), 0.SI<PerSecond>(), 0.SI<NewtonMeter>(), outAngularVelocity);
//var motoringSpeed = DataBus.EngineIdleSpeed;
//var disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), DataBus.EngineIdleSpeed);
//if (!(disengagedResponse is ResponseSuccess)) {
// motoringSpeed = DataBus.EngineSpeed;
// if (motoringSpeed.IsGreater(DataBus.EngineIdleSpeed)) {
// var first = (ResponseDryRun)NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed, true);
// try {
// motoringSpeed = SearchAlgorithm.Search(motoringSpeed, first.DeltaDragLoad,
// Constants.SimulationSettings.EngineIdlingSearchInterval,
// getYValue: result => ((ResponseDryRun)result).DeltaDragLoad,
// evaluateFunction: n => NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), n, true),
// criterion: result => ((ResponseDryRun)result).DeltaDragLoad.Value());
// } catch (VectoException) {
// Log.Warn("CycleGearbox could not find motoring speed for disengaged state.");
// }
// motoringSpeed = motoringSpeed.LimitTo(DataBus.EngineIdleSpeed, DataBus.EngineSpeed);
// }
// disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed);
//}
IResponse disengagedResponse;
if (GearboxType.AutomaticTransmission()) {
disengagedResponse = EngineIdleRequest(absTime, dt);
} else {
disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), null);
}
if (TorqueConverter != null) {
TorqueConverter.Locked(CurrentState.InTorque, disengagedResponse.EngineSpeed);
}
disengagedResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity;
CurrentState.SetState(0.SI<NewtonMeter>(), disengagedResponse.EngineSpeed, 0.SI<NewtonMeter>(), outAngularVelocity);
CurrentState.Gear = Gear;
var motoringSpeed = DataBus.EngineIdleSpeed;
return disengagedResponse;
}
private IResponse EngineIdleRequest(Second absTime, Second dt)
{
var disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), DataBus.EngineIdleSpeed);
if (!(disengagedResponse is ResponseSuccess)) {
motoringSpeed = DataBus.EngineSpeed;
if (disengagedResponse is ResponseSuccess) {
return disengagedResponse;
}
var motoringSpeed = DataBus.EngineSpeed;
if (motoringSpeed.IsGreater(DataBus.EngineIdleSpeed)) {
var first = (ResponseDryRun)NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed, true);
try {
......@@ -318,21 +372,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
}
motoringSpeed = motoringSpeed.LimitTo(DataBus.EngineIdleSpeed, DataBus.EngineSpeed);
}
disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed);
}
if (TorqueConverter != null) {
TorqueConverter.Locked(CurrentState.InTorque, motoringSpeed);
}
disengagedResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity;
return disengagedResponse;
}
protected override void DoWriteModalResults(IModalDataContainer container)
{
var avgInAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0;
container[ModalResultField.Gear] = Gear;
container[ModalResultField.Gear] = Disengaged != null ? 0 : Gear;
container[ModalResultField.P_gbx_loss] = CurrentState.TransmissionTorqueLoss * avgInAngularSpeed;
container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgInAngularSpeed;
container[ModalResultField.P_gbx_in] = CurrentState.InTorque * avgInAngularSpeed;
......@@ -372,7 +419,55 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
get
{
return new GearInfo(DataBus.CycleData.RightSample.Gear, !DataBus.CycleData.RightSample.TorqueConverterActive ?? true);
if (Disengaged == null) {
return new GearInfo(Gear, !TorqueConverterActive ?? true);
}
var future = DataBus.LookAhead(ModelData.TractionInterruption * 5);
var nextGear = 0u;
var torqueConverterLocked = true;
foreach (var entry in future) {
if (entry.VehicleTargetSpeed != null && entry.VehicleTargetSpeed.IsEqual(0)) {
// vehicle is stopped, no next gear, engine should go to idle
break;
}
if (entry.WheelAngularVelocity != null && entry.WheelAngularVelocity.IsEqual(0)) {
// vehicle is stopped, no next gear, engine should go to idle
break;
}
if (entry.Gear == 0) {
continue;
}
nextGear = entry.Gear;
torqueConverterLocked = !entry.TorqueConverterActive ?? false;
break;
}
return new GearInfo(nextGear, torqueConverterLocked);
}
}
public override Second TractionInterruption
{
get
{
if (Disengaged == null) {
return ModelData.TractionInterruption;
}
var future = DataBus.LookAhead(ModelData.TractionInterruption * 5);
foreach (var entry in future) {
if (entry.VehicleTargetSpeed != null && entry.VehicleTargetSpeed.IsEqual(0)) {
// vehicle is stopped, no next gear, engine should go to idle
break;
}
if (entry.WheelAngularVelocity != null && entry.WheelAngularVelocity.IsEqual(0)) {
// vehicle is stopped, no next gear, engine should go to idle
break;
}
if (entry.Gear == 0) {
continue;
}
return entry.Time - Disengaged;
}
return ModelData.TractionInterruption;
}
}
......
......@@ -484,76 +484,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
CycleStartDistance = startDistance;
}
public sealed class DrivingCycleEnumerator : IEnumerator<DrivingCycleData.DrivingCycleEntry>
{
private int _currentCycleIndex;
private readonly IDrivingCycleData _data;
public DrivingCycleEnumerator(IDrivingCycleData data)
{
_currentCycleIndex = 0;
_data = data;
LastEntry = false;
}
public DrivingCycleEnumerator Clone()
{
return new DrivingCycleEnumerator(_data) {
_currentCycleIndex = _currentCycleIndex,
LastEntry = LastEntry
};
}
public DrivingCycleData.DrivingCycleEntry Current
{
get { return LeftSample; }
}
public DrivingCycleData.DrivingCycleEntry Next
{
get { return RightSample; }
}
public DrivingCycleData.DrivingCycleEntry LeftSample
{
get { return _data.Entries[_currentCycleIndex]; }
}
public DrivingCycleData.DrivingCycleEntry RightSample
{
get { return _currentCycleIndex + 1 >= _data.Entries.Count ? null : _data.Entries[_currentCycleIndex + 1]; }
}
public bool LastEntry { get; private set; }
object System.Collections.IEnumerator.Current
{
get { return LeftSample; }
}
public bool MoveNext()
{
// cycleIndex has to be max. next to last (so that rightSample is still valid.
if (_currentCycleIndex >= _data.Entries.Count - 2) {
LastEntry = true;
return false;
}
_currentCycleIndex++;
if (_currentCycleIndex == _data.Entries.Count - 2) {
LastEntry = true;
}
return true;
}
public void Reset()
{
_currentCycleIndex = 0;
}
public void Dispose() {}
}
public sealed class DrivingCycleState
{
public DrivingCycleState Clone()
......
using System.Collections.Generic;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
public sealed class DrivingCycleEnumerator : IEnumerator<DrivingCycleData.DrivingCycleEntry>
{
private int _currentCycleIndex;
private readonly IDrivingCycleData _data;
public DrivingCycleEnumerator(IDrivingCycleData data)
{
_currentCycleIndex = 0;
_data = data;
LastEntry = false;
}
public DrivingCycleEnumerator Clone()
{
return new DrivingCycleEnumerator(_data) {
_currentCycleIndex = _currentCycleIndex,
LastEntry = LastEntry
};
}
public DrivingCycleData.DrivingCycleEntry Current
{
get { return LeftSample; }
}
public DrivingCycleData.DrivingCycleEntry Next
{
get { return RightSample; }
}
public DrivingCycleData.DrivingCycleEntry LeftSample
{
get { return _data.Entries[_currentCycleIndex]; }
}
public DrivingCycleData.DrivingCycleEntry RightSample
{
get { return _currentCycleIndex + 1 >= _data.Entries.Count ? null : _data.Entries[_currentCycleIndex + 1]; }
}
public bool LastEntry { get; private set; }
object System.Collections.IEnumerator.Current
{
get { return LeftSample; }
}
public bool MoveNext()
{
// cycleIndex has to be max. next to last (so that rightSample is still valid.
if (_currentCycleIndex >= _data.Entries.Count - 2) {
LastEntry = true;
return false;
}
_currentCycleIndex++;
if (_currentCycleIndex == _data.Entries.Count - 2) {
LastEntry = true;
}
return true;
}
public void Reset()
{
_currentCycleIndex = 0;
}
public void Dispose() {}
}
}
\ No newline at end of file
......@@ -72,8 +72,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
protected readonly IDrivingCycleData Data;
private bool _isInitializing;
protected IEnumerator<DrivingCycleData.DrivingCycleEntry> RightSample { get; set; }
protected IEnumerator<DrivingCycleData.DrivingCycleEntry> LeftSample { get; set; }
protected internal readonly DrivingCycleEnumerator CycleIterator;
protected Second AbsTime { get; set; }
......@@ -86,12 +85,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
: base(container)
{
Data = cycle;
LeftSample = Data.Entries.GetEnumerator();
LeftSample.MoveNext();
RightSample = Data.Entries.GetEnumerator();
RightSample.MoveNext();
RightSample.MoveNext();
CycleIterator = new DrivingCycleEnumerator(cycle);
PreviousState = new DrivingCycleState {
Distance = 0.SI<Meter>(),
......@@ -129,22 +123,22 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
var debug = new DebugData();
// cycle finished
if (RightSample.Current == null || LeftSample.Current == null) {
if (CycleIterator.LastEntry && absTime >= CycleIterator.RightSample.Time) {
return new ResponseCycleFinished { AbsTime = absTime, Source = this };
}
// interval exceeded
if (RightSample.Current != null && (absTime + dt).IsGreater(RightSample.Current.Time)) {
if (CycleIterator.RightSample != null && (absTime + dt).IsGreater(CycleIterator.RightSample.Time)) {
return new ResponseFailTimeInterval {
AbsTime = absTime,
Source = this,
DeltaT = RightSample.Current.Time - absTime
DeltaT = CycleIterator.RightSample.Time - absTime
};
}
// calc acceleration from speed diff vehicle to cycle
var deltaV = RightSample.Current.VehicleTargetSpeed - DataBus.VehicleSpeed;
var deltaT = RightSample.Current.Time - LeftSample.Current.Time;
var deltaV = CycleIterator.RightSample.VehicleTargetSpeed - DataBus.VehicleSpeed;
var deltaT = CycleIterator.RightSample.Time - CycleIterator.LeftSample.Time;
if (DataBus.VehicleSpeed.IsSmaller(0)) {
throw new VectoSimulationException("vehicle velocity is smaller than zero");
......@@ -155,7 +149,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
}
var acceleration = deltaV / deltaT;
var gradient = LeftSample.Current.RoadGradient;
var gradient = CycleIterator.LeftSample.RoadGradient;
DriverAcceleration = acceleration;
DriverBehavior = acceleration < 0
? DriverBehavior = DrivingBehavior.Braking
......@@ -242,21 +236,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
container[ModalResultField.dist] = CurrentState.Distance;
container[ModalResultField.simulationDistance] = CurrentState.SimulationDistance;
container[ModalResultField.v_targ] = LeftSample.Current.VehicleTargetSpeed;
container[ModalResultField.grad] = LeftSample.Current.RoadGradientPercent;
container[ModalResultField.altitude] = LeftSample.Current.Altitude;
container[ModalResultField.v_targ] = CycleIterator.LeftSample.VehicleTargetSpeed;
container[ModalResultField.grad] = CycleIterator.LeftSample.RoadGradientPercent;
container[ModalResultField.altitude] = CycleIterator.LeftSample.Altitude;
container[ModalResultField.acc] = CurrentState.Acceleration;
}
protected override void DoCommitSimulationStep()
{
if ((RightSample.Current == null) || AbsTime.IsGreaterOrEqual(RightSample.Current.Time)) {
RightSample.MoveNext();
LeftSample.MoveNext();
if ((CycleIterator.RightSample == null) || AbsTime.IsGreaterOrEqual(CycleIterator.RightSample.Time)) {
CycleIterator.MoveNext();
}
PreviousState = CurrentState;
CurrentState = CurrentState.Clone();
AdvanceState();
}
public string CycleName
......@@ -274,23 +265,23 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
get
{
return new CycleData {
AbsTime = LeftSample.Current.Time,
AbsTime = CycleIterator.LeftSample.Time,
AbsDistance = null,
LeftSample = LeftSample.Current,
RightSample = RightSample.Current,
LeftSample = CycleIterator.LeftSample,
RightSample = CycleIterator.RightSample,
};
}
}
public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance)
{
return new DrivingCycleData.DrivingCycleEntry(RightSample.Current);
return new DrivingCycleData.DrivingCycleEntry(CycleIterator.RightSample);
//throw new System.NotImplementedException();
}
public Meter Altitude
{
get { return LeftSample.Current.Altitude; }
get { return CycleIterator.LeftSample.Altitude; }
}
public Meter CycleStartDistance
......@@ -305,7 +296,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time)
{
throw new NotImplementedException();
var retVal = new List<DrivingCycleData.DrivingCycleEntry>();
var iterator = CycleIterator.Clone();
do {
retVal.Add(iterator.RightSample);
} while (iterator.MoveNext() && iterator.RightSample.Time < AbsTime + time);
return retVal;
}
public void FinishSimulation()
......@@ -315,7 +313,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public bool VehicleStopped
{
get { return !_isInitializing && LeftSample.Current.VehicleTargetSpeed.IsEqual(0); }
get { return !_isInitializing && CycleIterator.LeftSample.VehicleTargetSpeed.IsEqual(0); }
}
public DrivingBehavior DriverBehavior { get; internal set; }
......
......@@ -81,22 +81,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public void Reset()
{
LeftSample.Reset();
LeftSample.MoveNext();
RightSample.Reset();
RightSample.MoveNext();
RightSample.MoveNext();
CycleIterator.Reset();
IdleStart = null;
}
public Second GetNextCycleTime()
{
if (RightSample.Current == null)
if (CycleIterator.RightSample == null) {
return null;
}
return RightSample.Current.Time - LeftSample.Current.Time;
return CycleIterator.RightSample.Time - CycleIterator.LeftSample.Time;
}
protected override void DoWriteModalResults(IModalDataContainer container)
......
......@@ -44,21 +44,24 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
/// <summary>
/// Driving Cycle for the PWheel driving cycle.
/// </summary>
public class PWheelCycle : PowertrainDrivingCycle, IDriverInfo
public class PWheelCycle : PowertrainDrivingCycle, IDriverInfo, IVehicleInfo
{
private VehicleData _vehicleData;
/// <summary>
/// Initializes a new instance of the <see cref="PWheelCycle"/> class.
/// </summary>
/// <param name="container">The container.</param>
/// <param name="cycle">The cycle.</param>
/// <param name="axleRatio">The axle ratio.</param>
/// <param name="vehicleData"></param>
/// <param name="gearRatios"></param>
public PWheelCycle(IVehicleContainer container, IDrivingCycleData cycle, double axleRatio,
public PWheelCycle(IVehicleContainer container, IDrivingCycleData cycle, double axleRatio, VehicleData vehicleData,
IDictionary<uint, double> gearRatios) : base(container, cycle)
{
// just to ensure that null-gear has ratio 1
gearRatios[0] = 1;
_vehicleData = vehicleData;
foreach (var entry in Data.Entries) {
entry.WheelAngularVelocity = entry.AngularVelocity / (axleRatio * gearRatios[entry.Gear]);
entry.Torque = entry.PWheel / entry.WheelAngularVelocity;
......@@ -76,36 +79,68 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public override IResponse Request(Second absTime, Second dt)
{
if (RightSample.Current == null) {
if (CycleIterator.LastEntry && CycleIterator.RightSample.Time == absTime) {
return new ResponseCycleFinished { Source = this };
}
// interval exceeded
if ((absTime + dt).IsGreater(RightSample.Current.Time)) {
if (CycleIterator.RightSample != null && (absTime + dt).IsGreater(CycleIterator.RightSample.Time)) {
return new ResponseFailTimeInterval {
AbsTime = absTime,
Source = this,
DeltaT = RightSample.Current.Time - absTime
DeltaT = CycleIterator.RightSample.Time - absTime
};
}
return DoHandleRequest(absTime, dt, LeftSample.Current.WheelAngularVelocity);
return DoHandleRequest(absTime, dt, CycleIterator.LeftSample.WheelAngularVelocity);
}
protected override void DoWriteModalResults(IModalDataContainer container)
{
container[ModalResultField.P_wheel_in] = LeftSample.Current.PWheel;
container[ModalResultField.P_wheel_in] = CycleIterator.LeftSample.PWheel;
base.DoWriteModalResults(container);
}
#region IDriverInfo
public MeterPerSecond VehicleSpeed { get; private set; }
/// <summary>
/// True if the angularVelocity at the wheels is 0.
/// </summary>
public bool VehicleStopped
{
get { return false; }
get { return CycleIterator.LeftSample.WheelAngularVelocity.IsEqual(0); }
}
public Kilogram VehicleMass
{
get { return _vehicleData.TotalCurbWeight; }
}
public Kilogram VehicleLoading
{
get { return _vehicleData.Loading; }
}
public Kilogram TotalMass
{
get { return _vehicleData.TotalVehicleWeight; }
}
public Newton AirDragResistance(MeterPerSecond previousVelocity, MeterPerSecond nextVelocity)
{
throw new System.NotImplementedException();
}
public Newton RollingResistance(Radian gradient)
{
throw new System.NotImplementedException();
}
public Newton SlopeResistance(Radian gradient)
{
throw new System.NotImplementedException();
}
/// <summary>
......
......@@ -52,8 +52,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
IDrivingCycleInfo, ISimulationOutPort, ITnInProvider, ITnInPort
{
protected readonly IDrivingCycleData Data;
protected IEnumerator<DrivingCycleData.DrivingCycleEntry> RightSample { get; set; }
protected IEnumerator<DrivingCycleData.DrivingCycleEntry> LeftSample { get; set; }
protected internal readonly DrivingCycleEnumerator CycleIterator;
protected Second AbsTime { get; set; }
......@@ -65,12 +64,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public PowertrainDrivingCycle(IVehicleContainer container, IDrivingCycleData cycle) : base(container)
{
Data = cycle;
LeftSample = Data.Entries.GetEnumerator();
LeftSample.MoveNext();
RightSample = Data.Entries.GetEnumerator();
RightSample.MoveNext();
RightSample.MoveNext();
CycleIterator = new DrivingCycleEnumerator(Data);
AbsTime = 0.SI<Second>();
}
......@@ -94,20 +88,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public virtual IResponse Request(Second absTime, Second dt)
{
// cycle finished (no more entries in cycle)
if (LeftSample.Current == null) {
if (CycleIterator.LastEntry && CycleIterator.RightSample.Time == absTime) {
return new ResponseCycleFinished { Source = this };
}
// interval exceeded
if (RightSample.Current != null && (absTime + dt).IsGreater(RightSample.Current.Time)) {
if (CycleIterator.RightSample != null && (absTime + dt).IsGreater(CycleIterator.RightSample.Time)) {
return new ResponseFailTimeInterval {
AbsTime = absTime,
Source = this,
DeltaT = RightSample.Current.Time - absTime
DeltaT = CycleIterator.RightSample.Time - absTime
};
}
return DoHandleRequest(absTime, dt, LeftSample.Current.AngularVelocity);
return DoHandleRequest(absTime, dt, CycleIterator.LeftSample.AngularVelocity);
}
protected IResponse DoHandleRequest(Second absTime, Second dt, PerSecond angularVelocity)
......@@ -117,16 +111,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
IResponse response;
var responseCount = 0;
do {
response = NextComponent.Request(absTime, dt, LeftSample.Current.Torque, angularVelocity);
response = NextComponent.Request(absTime, dt, CycleIterator.LeftSample.Torque, angularVelocity);
CurrentState.InAngularVelocity = angularVelocity;
CurrentState.InTorque = LeftSample.Current.Torque;
CurrentState.InTorque = CycleIterator.LeftSample.Torque;
debug.Add(response);
response.Switch()
.Case<ResponseGearShift>(
() => response = NextComponent.Request(absTime, dt, LeftSample.Current.Torque, angularVelocity))
() => response = NextComponent.Request(absTime, dt, CycleIterator.LeftSample.Torque, angularVelocity))
.Case<ResponseUnderload>(r => {
var torqueInterval = -r.Delta / (angularVelocity.IsEqual(0) ? 10.RPMtoRad() : angularVelocity);
var torque = SearchAlgorithm.Search(LeftSample.Current.Torque, r.Delta, torqueInterval,
var torque = SearchAlgorithm.Search(CycleIterator.LeftSample.Torque, r.Delta, torqueInterval,
getYValue: result => ((ResponseDryRun)result).DeltaDragLoad,
evaluateFunction: t => NextComponent.Request(absTime, dt, t, angularVelocity, true),
criterion: y => ((ResponseDryRun)y).DeltaDragLoad.Value());
......@@ -136,9 +130,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
.Case<ResponseOverload>(r => {
angularVelocity = SearchAlgorithm.Search(angularVelocity, r.Delta, 50.RPMtoRad(),
getYValue: result => ((ResponseDryRun)result).DeltaFullLoad,
evaluateFunction: n => NextComponent.Request(absTime, dt, LeftSample.Current.Torque, n, true),
evaluateFunction: n => NextComponent.Request(absTime, dt, CycleIterator.LeftSample.Torque, n, true),
criterion: y => ((ResponseDryRun)y).DeltaFullLoad.Value());
response = NextComponent.Request(absTime, dt, LeftSample.Current.Torque, angularVelocity);
response = NextComponent.Request(absTime, dt, CycleIterator.LeftSample.Torque, angularVelocity);
CurrentState.InAngularVelocity = angularVelocity;
})
.Case<ResponseFailTimeInterval>(r => { dt = r.DeltaT; })
......@@ -171,10 +165,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
protected override void DoCommitSimulationStep()
{
if ((RightSample.Current == null) || AbsTime.IsGreaterOrEqual(RightSample.Current.Time)) {
RightSample.MoveNext();
LeftSample.MoveNext();
}
CycleIterator.MoveNext();
}
#endregion
......@@ -184,10 +175,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
get
{
return new CycleData {
AbsTime = LeftSample.Current.Time,
AbsTime = CycleIterator.LeftSample.Time,
AbsDistance = null,
LeftSample = LeftSample.Current,
RightSample = RightSample.Current,
LeftSample = CycleIterator.LeftSample,
RightSample = CycleIterator.RightSample,
};
}
}
......@@ -216,7 +207,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time)
{
throw new NotImplementedException();
var retVal = new List<DrivingCycleData.DrivingCycleEntry>();
var iterator = CycleIterator.Clone();
do {
retVal.Add(iterator.RightSample);
} while (iterator.MoveNext() && iterator.RightSample.Time < AbsTime + time);
return retVal;
}
public void FinishSimulation()
......
......@@ -142,7 +142,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public Newton RollingResistance(Radian gradient)
{
var weight = ModelData.TotalVehicleWeight();
var weight = ModelData.TotalVehicleWeight;
var gravity = Physics.GravityAccelleration;
var rollCoefficient = ModelData.TotalRollResistanceCoefficient;
......@@ -153,14 +153,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
protected internal Newton DriverAcceleration(MeterPerSquareSecond accelleration)
{
var retVal = ModelData.TotalVehicleWeight() * 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());
var retVal = ModelData.TotalVehicleWeight * Physics.GravityAccelleration * Math.Sin(gradient.Value());
Log.Debug("SlopeResistance: {0}", retVal);
return retVal;
}
......@@ -199,7 +199,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public Kilogram VehicleMass
{
get { return ModelData.TotalCurbWeight(); }
get { return ModelData.TotalCurbWeight; }
}
public Kilogram VehicleLoading
......@@ -209,7 +209,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public Kilogram TotalMass
{
get { return ModelData.TotalVehicleWeight(); }
get { return ModelData.TotalVehicleWeight; }
}
public class VehicleState
......
......@@ -152,6 +152,7 @@
<Compile Include="Models\SimulationComponent\Impl\AbstractGearbox.cs" />
<Compile Include="Models\SimulationComponent\Impl\ATGearbox.cs" />
<Compile Include="Models\SimulationComponent\Impl\ATShiftStrategy.cs" />
<Compile Include="Models\SimulationComponent\Impl\DrivingCycleEnumerator.cs" />
<Compile Include="Models\SimulationComponent\Impl\MeasuredSpeedDrivingCycle.cs" />
<Compile Include="Models\SimulationComponent\Impl\PTOCycleController.cs" />
<Compile Include="Models\SimulationComponent\Impl\PWheelCycle.cs" />
......
......@@ -99,7 +99,7 @@ namespace TUGraz.VectoCore.Tests.Integration
.AddComponent(engine);
var aux = new BusAuxiliariesAdapter(container, AdvancedAuxFile, "Coach",
vehicleData.TotalVehicleWeight(), engineData.ConsumptionMap, engineData.IdleSpeed);
vehicleData.TotalVehicleWeight, engineData.ConsumptionMap, engineData.IdleSpeed);
engine.Connect(aux.Port());
......
......@@ -410,6 +410,16 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
@"TestData\MeasuredSpeed\Results\MeasuredSpeedGear.vsum", @"TestData\MeasuredSpeed\MeasuredSpeedGear.vsum", true);
}
[TestMethod]
public void MeasuredSpeed_Gear_TractionInterruption_Run()
{
RunJob(@"TestData\MeasuredSpeed\MeasuredSpeedGear_TractionInterruption.vecto",
@"TestData\MeasuredSpeed\Results\MeasuredSpeedGear_TractionInterruption_MeasuredSpeed_Gear_Rural_TractionInterruption.vmod",
@"TestData\MeasuredSpeed\MeasuredSpeedGear_TractionInterruption_MeasuredSpeed_Gear_Rural_TractionInterruption.vmod",
@"TestData\MeasuredSpeed\Results\MeasuredSpeedGear_TractionInterruption.vsum",
@"TestData\MeasuredSpeed\MeasuredSpeedGear_TractionInterruption.vsum", true);
}
[TestMethod]
public void MeasuredSpeed_Gear_Aux_Run()
{
......
......@@ -74,7 +74,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
Gears = new Dictionary<uint, GearData> { { 1, new GearData { Ratio = 2.0 } }, { 2, new GearData { Ratio = 3.5 } } }
}, 0.SI<KilogramSquareMeter>());
var cycle = new PWheelCycle(container, drivingCycle, 2.3,
var cycle = new PWheelCycle(container, drivingCycle, 2.3, null,
gearbox.ModelData.Gears.ToDictionary(g => g.Key, g => g.Value.Ratio));
Assert.AreEqual(container.CycleData.LeftSample.Time, 1.SI<Second>());
......
time [s],n_eng_avg [1/min],T_eng_fcmap [Nm],Tq_full [Nm],Tq_drag [Nm],P_eng_fcmap [kW],P_eng_full [kW],P_eng_full_stat [kW],P_eng_drag [kW],P_eng_inertia [kW],P_eng_out [kW],P_clutch_loss [kW],P_clutch_out [kW],P_aux [kW],P_aux_cycle,FC-Map [g/h],FC-AUXc [g/h],FC-WHTCc [g/h],FC-AAUX [g/h],FC-Final [g/h]
0.5000,580.0000,15.3868,1139.3103,-148.5000,0.9346,69.1988,74.7678,-9.0195,0.9668,0.0000,,,0.0000,0.0000,1506.8291,1506.8291,1506.8291,1506.8291,1506.8291
0.5000,600.0000,0.0000,1101.3333,-148.0000,0.0000,69.1988,80.5504,-9.2991,0.0000,0.0000,,,0.0000,0.0000,1459.0000,1459.0000,1459.0000,1459.0000,1459.0000
1.5000,600.0000,0.0000,1101.3333,-148.0000,0.0000,69.1988,80.5504,-9.2991,0.0000,0.0000,,,0.0000,0.0000,1459.0000,1459.0000,1459.0000,1459.0000,1459.0000
2.5000,600.0000,0.0000,1101.3333,-148.0000,0.0000,69.1988,80.5504,-9.2991,0.0000,0.0000,,,0.0000,0.0000,1459.0000,1459.0000,1459.0000,1459.0000,1459.0000
3.5000,600.0000,0.0000,1101.3333,-148.0000,0.0000,69.1988,80.5504,-9.2991,0.0000,0.0000,,,0.0000,0.0000,1459.0000,1459.0000,1459.0000,1459.0000,1459.0000
......@@ -694,4 +694,3 @@
692.5000,1828.8550,419.6568,1757.6779,-269.3382,80.3715,336.6256,341.6938,-51.5829,4.5158,77.1577,,,0.0000,0.0000,18432.2375,18432.2375,18432.2375,18432.2375,18432.2375
693.5000,1879.2710,186.7066,1634.0959,-278.6651,36.7433,321.5848,326.0610,-54.8404,3.2561,33.8936,,,0.0000,0.0000,12627.1055,12627.1055,12627.1055,12627.1055,12627.1055
694.5000,1913.7100,282.6382,1544.5241,-285.0363,56.6416,309.5276,314.6095,-57.1222,2.1771,54.8685,,,0.0000,0.0000,15798.5513,15798.5513,15798.5513,15798.5513,15798.5513
695.5000,1632.2305,423.4192,1856.7600,-239.6734,72.3737,317.3700,349.2417,-40.9666,-40.1481,99.4356,,,0.0000,0.0000,15949.2211,15949.2211,15949.2211,15949.2211,15949.2211
time [s],n_eng_avg [1/min],T_eng_fcmap [Nm],Tq_full [Nm],Tq_drag [Nm],P_eng_fcmap [kW],P_eng_full [kW],P_eng_full_stat [kW],P_eng_drag [kW],P_eng_inertia [kW],P_eng_out [kW],P_clutch_loss [kW],P_clutch_out [kW],P_aux [kW],P_aux_cycle,FC-Map [g/h],FC-AUXc [g/h],FC-WHTCc [g/h],FC-AAUX [g/h],FC-Final [g/h]
0.5000,580.0000,15.3868,1139.3103,-148.5000,0.9346,69.1988,74.7678,-9.0195,0.9668,0.0000,,,0.0000,0.0000,1506.8291,1506.8291,1506.8291,1506.8291,1506.8291
0.5000,600.0000,0.0000,1101.3333,-148.0000,0.0000,69.1988,80.5504,-9.2991,0.0000,0.0000,,,0.0000,0.0000,1459.0000,1459.0000,1459.0000,1459.0000,1459.0000
1.5000,600.0000,0.0000,1101.3333,-148.0000,0.0000,69.1988,80.5504,-9.2991,0.0000,0.0000,,,0.0000,0.0000,1459.0000,1459.0000,1459.0000,1459.0000,1459.0000
2.5000,600.0000,0.0000,1101.3333,-148.0000,0.0000,69.1988,80.5504,-9.2991,0.0000,0.0000,,,0.0000,0.0000,1459.0000,1459.0000,1459.0000,1459.0000,1459.0000
3.5000,600.0000,0.0000,1101.3333,-148.0000,0.0000,69.1988,80.5504,-9.2991,0.0000,0.0000,,,0.0000,0.0000,1459.0000,1459.0000,1459.0000,1459.0000,1459.0000
......@@ -1005,4 +1005,3 @@
1003.5000,1747.2970,300.1032,1848.6197,-256.3581,54.9118,338.2540,350.4916,-46.9075,0.6887,54.3718,,,0.0000,0.0000,13995.8711,13995.8711,13995.8711,13995.8711,13995.8711
1004.5000,1756.4730,279.3416,1846.5955,-257.6886,51.3814,339.6580,350.4587,-47.3986,0.6510,50.8605,,,0.0000,0.0000,13517.1779,13517.1779,13517.1779,13517.1779,13517.1779
1005.5000,1767.0600,371.2643,1842.4875,-259.2237,68.7010,340.9451,350.3965,-47.9683,0.9043,68.0355,,,0.0000,0.0000,16168.5403,16168.5403,16168.5403,16168.5403,16168.5403
1006.5000,1782.7120,420.7529,1838.6908,-261.4932,78.5483,343.2563,350.2568,-48.8169,1.4133,77.5542,,,0.0000,0.0000,17735.7210,17735.7210,17735.7210,17735.7210,17735.7210
time [s],n_eng_avg [1/min],T_eng_fcmap [Nm],Tq_full [Nm],Tq_drag [Nm],P_eng_fcmap [kW],P_eng_full [kW],P_eng_full_stat [kW],P_eng_drag [kW],P_eng_inertia [kW],P_eng_out [kW],P_clutch_loss [kW],P_clutch_out [kW],P_aux [kW],P_aux_cycle,FC-Map [g/h],FC-AUXc [g/h],FC-WHTCc [g/h],FC-AAUX [g/h],FC-Final [g/h]
0.5000,580.0000,15.3868,1139.3103,-148.5000,0.9346,69.1988,74.7678,-9.0195,0.9668,0.0000,,,0.0000,0.0000,1506.8291,1506.8291,1506.8291,1506.8291,1506.8291
0.5000,600.0000,0.0000,1101.3333,-148.0000,0.0000,69.1988,80.5504,-9.2991,0.0000,0.0000,,,0.0000,0.0000,1459.0000,1459.0000,1459.0000,1459.0000,1459.0000
1.5000,600.0000,0.0000,1101.3333,-148.0000,0.0000,69.1988,80.5504,-9.2991,0.0000,0.0000,,,0.0000,0.0000,1459.0000,1459.0000,1459.0000,1459.0000,1459.0000
2.5000,600.0000,0.0000,1101.3333,-148.0000,0.0000,69.1988,80.5504,-9.2991,0.0000,0.0000,,,0.0000,0.0000,1459.0000,1459.0000,1459.0000,1459.0000,1459.0000
3.5000,600.0000,0.0000,1101.3333,-148.0000,0.0000,69.1988,80.5504,-9.2991,0.0000,0.0000,,,0.0000,0.0000,1459.0000,1459.0000,1459.0000,1459.0000,1459.0000
......@@ -165,4 +165,3 @@
163.5000,1304.2050,-130.9400,1839.3308,-191.5046,-17.8833,251.2085,314.1249,-26.1549,-2.9996,-14.5053,,,0.0000,0.0000,1284.6858,1284.6858,1284.6858,1284.6858,1284.6858
164.5000,1249.3625,-130.3151,1840.3154,-184.9235,-17.0495,240.7739,300.9158,-24.1941,-2.8371,-13.8406,,,0.0000,0.0000,1146.0132,1146.0132,1146.0132,1146.0132,1146.0132
165.5000,1202.9710,-127.2652,1840.5811,-179.3565,-16.0322,231.8669,289.7421,-22.5944,-1.9195,-13.8576,,,0.0000,0.0000,970.6337,970.6337,970.6337,970.6337,970.6337
166.5000,1174.7100,28.3827,1841.3623,-176.5975,3.4915,226.5158,282.9353,-21.7242,-0.8925,4.3569,,,0.0000,0.0000,3760.5779,3760.5779,3760.5779,3760.5779,3760.5779
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment