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

Skip to content
Snippets Groups Projects
Commit d2f5d20f authored by Michael KRISPER's avatar Michael KRISPER
Browse files

Merge remote-tracking branch...

Merge remote-tracking branch 'quaritsch/feature/VECTO-125-comparison-of-vecto2.2-and-vecto3' into feature/VECTO-124-pdf-report
parents 7d0e4dea ce4bc3fe
No related branches found
No related tags found
No related merge requests found
......@@ -17,7 +17,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
public class DefaultDriverStrategy : LoggingObject, IDriverStrategy
{
protected DrivingBehaviorEntry NextDrivingAction;
protected internal DrivingBehaviorEntry NextDrivingAction;
public enum DrivingMode
{
......@@ -75,58 +75,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
var retVal = DrivingModes[CurrentDrivingMode].Request(absTime, ds, targetVelocity, gradient);
if (NextDrivingAction == null || !(retVal is ResponseSuccess)) {
return retVal;
}
// if we accelerate in the current simulation interval the ActionDistance of the next action
// changes and we might pass the ActionDistance - check again...
if (retVal.Acceleration <= 0) {
return retVal;
}
// if the speed at the end of the simulation interval is below the next target speed
// we are fine (no need to brake right now)
var v2 = Driver.DataBus.VehicleSpeed + retVal.Acceleration * retVal.SimulationInterval;
if (v2 <= NextDrivingAction.NextTargetSpeed) {
return retVal;
}
Meter newds;
switch (NextDrivingAction.Action) {
case DrivingBehavior.Coasting:
var coastingDistance = Formulas.DecelerationDistance(v2, NextDrivingAction.NextTargetSpeed,
Driver.DriverData.LookAheadCoasting.Deceleration);
// if the distance at the end of the simulation interval is smaller than the new ActionDistance
// we are safe - go ahead...
if ((Driver.DataBus.Distance + ds).IsSmallerOrEqual(NextDrivingAction.TriggerDistance - coastingDistance,
Constants.SimulationSettings.DriverActionDistanceTolerance)) {
return retVal;
}
newds = EstimateAccelerationDistanceBeforeBrake(retVal, NextDrivingAction);
break;
case DrivingBehavior.Braking:
var brakingDistance = Driver.DriverData.AccelerationCurve.ComputeAccelerationDistance(v2,
NextDrivingAction.NextTargetSpeed);
if ((Driver.DataBus.Distance + ds).IsSmaller(NextDrivingAction.TriggerDistance - brakingDistance)) {
return retVal;
}
newds = (NextDrivingAction.TriggerDistance - brakingDistance) - Driver.DataBus.Distance;
break;
default:
return retVal;
}
if (newds.IsEqual(0, 1e-3) || ds.IsEqual(newds, 1e-3.SI<Meter>())) {
return retVal;
}
Log.Debug("Exceeding next ActionDistance at {0}. Reducing max Distance to {1}", NextDrivingAction.ActionDistance,
newds);
return new ResponseDrivingCycleDistanceExceeded() {
Source = this,
MaxDistance = newds,
};
return retVal;
}
private void UpdateDrivingAction(Meter currentDistance)
......@@ -186,28 +135,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public DrivingBehavior DriverBehavior { get; internal set; }
private Meter EstimateAccelerationDistanceBeforeBrake(IResponse retVal, DrivingBehaviorEntry nextAction)
{
// estimate the distance to drive when accelerating with the current acceleration (taken from retVal) and then
// coasting with the dirver's LookaheadDeceleration.
// TriggerDistance - CurrentDistance = s_accelerate + s_lookahead
// s_coast(dt) = - (currentSpeed + a * dt + nextTargetSpeed) * (nextTargetSpeed - (currentSpeed + a * dt)) / (2 * a_lookahead)
// s_acc(dt) = currentSpeed * dt + a / 2 * dt^2
// => solve for dt, compute ds = currentSpeed * dt + a / 2 * dt^2
var dtList = VectoMath.QuadraticEquationSolver(
(retVal.Acceleration / 2 -
retVal.Acceleration * retVal.Acceleration / 2 / Driver.DriverData.LookAheadCoasting.Deceleration).Value(),
(Driver.DataBus.VehicleSpeed -
Driver.DataBus.VehicleSpeed * retVal.Acceleration / Driver.DriverData.LookAheadCoasting.Deceleration).Value(),
(nextAction.NextTargetSpeed * nextAction.NextTargetSpeed / 2 / Driver.DriverData.LookAheadCoasting.Deceleration -
Driver.DataBus.VehicleSpeed * Driver.DataBus.VehicleSpeed / 2 / Driver.DriverData.LookAheadCoasting.Deceleration -
(nextAction.TriggerDistance - Driver.DataBus.Distance)).Value());
dtList.Sort();
var dt = dtList.First(x => x > 0).SI<Second>();
var newds = Driver.DataBus.VehicleSpeed * dt + retVal.Acceleration / 2 * dt * dt;
return newds;
}
protected DrivingBehaviorEntry GetNextDrivingAction(Meter minDistance)
{
var currentSpeed = Driver.DataBus.VehicleSpeed;
......@@ -285,20 +212,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public abstract class AbstractDriverMode : LoggingObject, IDriverMode
{
private DefaultDriverStrategy _driverStrategy;
private IDriverActions _driver;
private DriverData _driverData;
private IDataBus _dataBus;
public DefaultDriverStrategy DriverStrategy
{
get { return _driverStrategy; }
set { _driverStrategy = value; }
}
public DefaultDriverStrategy DriverStrategy { get; set; }
protected IDriverActions Driver
{
get { return _driver ?? (_driver = _driverStrategy.Driver); }
get { return _driver ?? (_driver = DriverStrategy.Driver); }
}
protected DriverData DriverData
......@@ -311,15 +233,78 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
get { return _dataBus ?? (_dataBus = Driver.DataBus); }
}
public abstract IResponse Request(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient);
public IResponse Request(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient)
{
var response = DoHandleRequest(absTime, ds, targetVelocity, gradient);
if (DriverStrategy.NextDrivingAction == null || !(response is ResponseSuccess)) {
return response;
}
// if we accelerate in the current simulation interval the ActionDistance of the next action
// changes and we might pass the ActionDistance - check again...
if (response.Acceleration <= 0) {
return response;
}
// if the speed at the end of the simulation interval is below the next target speed
// we are fine (no need to brake right now)
var v2 = Driver.DataBus.VehicleSpeed + response.Acceleration * response.SimulationInterval;
if (v2 <= DriverStrategy.NextDrivingAction.NextTargetSpeed) {
return response;
}
Meter newds;
response = CheckRequestDoesNotExceedNextAction(absTime, ds, targetVelocity, gradient, response, out newds);
if (newds.IsEqual(0, 1e-3) || ds.IsEqual(newds, 1e-3.SI<Meter>())) {
return response;
}
Log.Debug("Exceeding next ActionDistance at {0}. Reducing max Distance to {1}",
DriverStrategy.NextDrivingAction.ActionDistance,
newds);
return new ResponseDrivingCycleDistanceExceeded() {
Source = this,
MaxDistance = newds,
};
}
protected abstract IResponse DoHandleRequest(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient);
protected abstract IResponse CheckRequestDoesNotExceedNextAction(Second absTime, Meter ds,
MeterPerSecond targetVelocity, Radian gradient, IResponse response, out Meter newSimulationDistance);
public abstract void ResetMode();
protected Meter EstimateAccelerationDistanceBeforeBrake(IResponse retVal, DrivingBehaviorEntry nextAction)
{
// estimate the distance to drive when accelerating with the current acceleration (taken from retVal) and then
// coasting with the dirver's LookaheadDeceleration.
// TriggerDistance - CurrentDistance = s_accelerate + s_lookahead
// s_coast(dt) = - (currentSpeed + a * dt + nextTargetSpeed) * (nextTargetSpeed - (currentSpeed + a * dt)) / (2 * a_lookahead)
// s_acc(dt) = currentSpeed * dt + a / 2 * dt^2
// => solve for dt, compute ds = currentSpeed * dt + a / 2 * dt^2
var dtList = VectoMath.QuadraticEquationSolver(
(retVal.Acceleration / 2 -
retVal.Acceleration * retVal.Acceleration / 2 / Driver.DriverData.LookAheadCoasting.Deceleration).Value(),
(Driver.DataBus.VehicleSpeed -
Driver.DataBus.VehicleSpeed * retVal.Acceleration / Driver.DriverData.LookAheadCoasting.Deceleration).Value(),
(nextAction.NextTargetSpeed * nextAction.NextTargetSpeed / 2 / Driver.DriverData.LookAheadCoasting.Deceleration -
Driver.DataBus.VehicleSpeed * Driver.DataBus.VehicleSpeed / 2 / Driver.DriverData.LookAheadCoasting.Deceleration -
(nextAction.TriggerDistance - Driver.DataBus.Distance)).Value());
dtList.Sort();
var dt = dtList.First(x => x > 0).SI<Second>();
var newds = Driver.DataBus.VehicleSpeed * dt + retVal.Acceleration / 2 * dt * dt;
return newds;
}
}
//=====================================
public class DriverModeDrive : AbstractDriverMode
{
public override IResponse Request(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient)
protected override IResponse DoHandleRequest(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient)
{
IResponse response = null;
......@@ -371,6 +356,42 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return response;
}
protected override IResponse CheckRequestDoesNotExceedNextAction(Second absTime, Meter ds,
MeterPerSecond targetVelocity, Radian gradient, IResponse response, out Meter newds)
{
var nextAction = DriverStrategy.NextDrivingAction;
newds = ds;
if (nextAction == null) {
return response;
}
var v2 = Driver.DataBus.VehicleSpeed + response.Acceleration * response.SimulationInterval;
switch (DriverStrategy.NextDrivingAction.Action) {
case DrivingBehavior.Coasting:
var coastingDistance = Formulas.DecelerationDistance(v2, nextAction.NextTargetSpeed,
Driver.DriverData.LookAheadCoasting.Deceleration);
// if the distance at the end of the simulation interval is smaller than the new ActionDistance
// we are safe - go ahead...
if ((Driver.DataBus.Distance + ds).IsSmallerOrEqual(nextAction.TriggerDistance - coastingDistance,
Constants.SimulationSettings.DriverActionDistanceTolerance)) {
return response;
}
newds = EstimateAccelerationDistanceBeforeBrake(response, nextAction);
break;
case DrivingBehavior.Braking:
var brakingDistance = Driver.DriverData.AccelerationCurve.ComputeAccelerationDistance(v2,
nextAction.NextTargetSpeed);
if ((Driver.DataBus.Distance + ds).IsSmaller(nextAction.TriggerDistance - brakingDistance)) {
return response;
}
newds = (nextAction.TriggerDistance - brakingDistance) - Driver.DataBus.Distance;
break;
default:
return response;
}
return null;
}
public override void ResetMode() {}
}
......@@ -386,7 +407,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
protected BrakingPhase Phase;
public override IResponse Request(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient)
protected override IResponse DoHandleRequest(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient)
{
IResponse response = null;
if (DataBus.VehicleSpeed <= DriverStrategy.BrakeTrigger.NextTargetSpeed) {
......@@ -498,6 +519,31 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return response;
}
protected override IResponse CheckRequestDoesNotExceedNextAction(Second absTime, Meter ds,
MeterPerSecond targetVelocity, Radian gradient, IResponse response, out Meter newds)
{
var nextAction = DriverStrategy.NextDrivingAction;
newds = ds;
if (nextAction == null) {
return response;
}
switch (nextAction.Action) {
case DrivingBehavior.Coasting:
var v2 = Driver.DataBus.VehicleSpeed + response.Acceleration * response.SimulationInterval;
var brakingDistance = Driver.DriverData.AccelerationCurve.ComputeAccelerationDistance(v2,
nextAction.NextTargetSpeed);
if ((Driver.DataBus.Distance + ds).IsSmaller(nextAction.TriggerDistance - brakingDistance)) {
return response;
}
newds = (nextAction.TriggerDistance - brakingDistance) - Driver.DataBus.Distance;
break;
default:
return response;
}
return null;
}
public override void ResetMode()
{
Phase = BrakingPhase.Coast;
......
......@@ -334,6 +334,21 @@ namespace TUGraz.VectoCore.Tests.Integration.DriverStrategy
@"..\..\TestData\Integration\DriverStrategy\Vecto2.2\40t Truck\40t_Long_Haul_Truck_Cycle_Decelerate_80_0_uphill_3.vmod");
}
[TestMethod]
public void Truck_Decelerate_80_0_SlopeChangeDuringCoast()
{
var data = new string[] {
// <s>,<v>,<grad>,<stop>
" 0, 60, -1.15, 0",
" 70, 60, -1.85, 0",
"300, 0, -1.85, 2",
};
var cycle = SimpleDrivingCycles.CreateCycleData(data);
Truck40tPowerTrain.CreateEngineeringRun(cycle, "Truck_DriverStrategy_Decelerate_80_0_SlopeChangeDuringCoast.vmod")
.Run();
}
[TestMethod, Ignore]
public void Truck_Decelerate_80_0_uphill_5()
{
......
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