/// <summary> /// Coputes targets from the function and adds them to the collection /// </summary> /// <param name="function">Function containing targets</param> /// <param name="collection">Collection to be filled with targets</param> private void ComputeTargets(Function function, Values.ListValue collection) { if (function != null) { Graph graph = function.Graph; if (graph != null && graph.Segments.Count > 1) { double prevSpeed = Double.MaxValue; for (int i = 1; i < graph.Segments.Count; i++) { Graph.Segment s = graph.Segments[i]; Types.Structure structureType = (Types.Structure)EFSSystem.findType(OverallNameSpaceFinder.INSTANCE.findByName(EFSSystem.Dictionaries[0], "Kernel.SpeedAndDistanceMonitoring.TargetSupervision"), "Kernel.SpeedAndDistanceMonitoring.TargetSupervision.Target"); Values.StructureValue value = new Values.StructureValue(structureType, structureType.NameSpace); Variables.Variable speed = (Variables.Variable)DataDictionary.Generated.acceptor.getFactory().createVariable(); speed.Type = EFSSystem.findType(OverallNameSpaceFinder.INSTANCE.findByName(EFSSystem.Dictionaries[0], "Default.BaseTypes"), "Default.BaseTypes.Speed"); speed.Name = "Speed"; speed.Mode = Generated.acceptor.VariableModeEnumType.aInternal; speed.Default = "0.0"; speed.Enclosing = value; speed.Value = new Values.DoubleValue(EFSSystem.DoubleType, s.Val(s.Start)); value.set(speed); Variables.Variable location = (Variables.Variable)DataDictionary.Generated.acceptor.getFactory().createVariable(); location.Type = EFSSystem.findType(OverallNameSpaceFinder.INSTANCE.findByName(EFSSystem.Dictionaries[0], "Default.BaseTypes"), "Default.BaseTypes.Distance"); location.Name = "Location"; location.Mode = Generated.acceptor.VariableModeEnumType.aInternal; location.Default = "0.0"; location.Enclosing = value; location.Value = new Values.DoubleValue(EFSSystem.DoubleType, s.Start); value.set(location); Variables.Variable length = (Variables.Variable)DataDictionary.Generated.acceptor.getFactory().createVariable(); length.Type = EFSSystem.findType(OverallNameSpaceFinder.INSTANCE.findByName(EFSSystem.Dictionaries[0], "Default.BaseTypes"), "Default.BaseTypes.Length"); length.Name = "Length"; length.Mode = Generated.acceptor.VariableModeEnumType.aInternal; length.Default = "0.0"; length.Enclosing = value; length.Value = new Values.DoubleValue(EFSSystem.DoubleType, s.End); value.set(length); if (s.Val(s.Start) < prevSpeed) { collection.Val.Add(value); } prevSpeed = s.Val(s.Start); } } } }
/// <summary> /// Computes targets from the function and stores them in the collection /// </summary> /// <param name="function">Function containing targets</param> /// <param name="collection">Collection to be filled with targets</param> private void ComputeTargets(Function function, ListValue collection) { if (function != null) { Graph graph = function.Graph; if (graph != null) { for (int i = 0; i < graph.Segments.Count; i++) { Graph.Segment s = graph.Segments[i]; StructureValue value = CreateTarget(s.Start, s.End - s.Start, s.Evaluate(s.Start)); collection.Val.Add(value); } } } }
/// <summary> /// Coputes targets from the function and adds them to the collection /// </summary> /// <param name="function">Function containing targets</param> /// <param name="collection">Collection to be filled with targets</param> private void ComputeTargets(Function function, ListValue collection) { if (function != null) { Graph graph = function.Graph; if (graph != null && graph.Segments.Count > 1) { NameSpace defaultNameSpace = OverallNameSpaceFinder.INSTANCE.findByName(EFSSystem.Dictionaries[0], "Default"); Structure structureType = (Structure) EFSSystem.FindType( defaultNameSpace, "TargetStruct" ); double prevSpeed = graph.Segments[0].Evaluate(graph.Segments[0].Start); for (int i = 1; i < graph.Segments.Count; i++) { Graph.Segment s = graph.Segments[i]; StructureValue value = new StructureValue(structureType); Field speed = value.CreateField(value, "Speed", structureType); speed.Value = new DoubleValue(EFSSystem.DoubleType, s.Evaluate(s.Start)); Field location = value.CreateField(value, "Location", structureType); location.Value = new DoubleValue(EFSSystem.DoubleType, s.Start); Field length = value.CreateField(value, "Length", structureType); length.Value = SegmentLength(s.End); Enum targetType = (Enum)EFSSystem.FindType(defaultNameSpace, "TargetTypeEnum"); Field type = value.CreateField(value, "Type", structureType); type.Value = targetType.DefaultValue; // Only add the target for the current segment to the collection if it brings a reduction in permitted speed if (s.Evaluate(s.Start) < prevSpeed) { collection.Val.Add(value); } // But even if it is not added to the collection of targets, this segment is now the reference speed prevSpeed = s.Evaluate(s.Start); } } } }
/// <summary> /// Provides the graph of this function if it has been statically defined /// </summary> /// <param name="context">the context used to create the graph</param> /// <param name="parameter"></param> /// <param name="explain"></param> /// <returns></returns> public override Graph CreateGraph(InterpretationContext context, Parameter parameter, ExplanationPart explain) { Graph retVal = null; Graph mrspGraph = null; Function speedRestriction = context.FindOnStack(SpeedRestrictions).Value as Function; if (speedRestriction != null) { Parameter p = (Parameter) speedRestriction.FormalParameters[0]; int token = context.LocalScope.PushContext(); context.LocalScope.SetGraphParameter(p); mrspGraph = createGraphForValue(context, context.FindOnStack(SpeedRestrictions).Value, explain, p); context.LocalScope.PopContext(token); } if (mrspGraph != null) { Function deceleratorFactor = context.FindOnStack(DecelerationFactor).Value as Function; if (deceleratorFactor != null) { Surface decelerationSurface = deceleratorFactor.CreateSurface(context, explain); if (decelerationSurface != null) { FlatSpeedDistanceCurve mrspCurve = mrspGraph.FlatSpeedDistanceCurve(mrspGraph.ExpectedEndX()); AccelerationSpeedDistanceSurface accelerationSurface = decelerationSurface.createAccelerationSpeedDistanceSurface(double.MaxValue, double.MaxValue); QuadraticSpeedDistanceCurve brakingCurve = null; try { brakingCurve = EtcsBrakingCurveBuilder.Build_A_Safe_Backward(accelerationSurface, mrspCurve); } catch (Exception) { retVal = new Graph(); retVal.AddSegment(new Graph.Segment(0, double.MaxValue, new Graph.Segment.Curve(0, 0, 0))); } if (brakingCurve != null) { retVal = new Graph(); // TODO : Remove the distinction between linear curves and quadratic curves bool isLinear = true; for (int i = 0; i < brakingCurve.SegmentCount; i++) { QuadraticCurveSegment segment = brakingCurve[i]; if (segment.A.ToUnits() != 0.0 || segment.V0.ToUnits() != 0.0) { isLinear = false; break; } } for (int i = 0; i < brakingCurve.SegmentCount; i++) { QuadraticCurveSegment segment = brakingCurve[i]; Graph.Segment newSegment; if (isLinear) { newSegment = new Graph.Segment( segment.X.X0.ToUnits(), segment.X.X1.ToUnits(), new Graph.Segment.Curve(0.0, segment.V0.ToSubUnits(SiSpeed_SubUnits.KiloMeter_per_Hour), 0.0)); } else { newSegment = new Graph.Segment( segment.X.X0.ToUnits(), segment.X.X1.ToUnits(), new Graph.Segment.Curve( segment.A.ToSubUnits(SiAcceleration_SubUnits.Meter_per_SecondSquare), segment.V0.ToSubUnits(SiSpeed_SubUnits.KiloMeter_per_Hour), segment.D0.ToSubUnits(SiDistance_SubUnits.Meter) ) ); } retVal.AddSegment(newSegment); } } } else { DecelerationFactor.AddError("Cannot create surface for " + DecelerationFactor); } } else { DecelerationFactor.AddError("Cannot evaluate " + DecelerationFactor + " as a function"); } } else { SpeedRestrictions.AddError("Cannot create graph for " + SpeedRestrictions); } return retVal; }
/// <summary> /// Provides the graph of this function if it has been statically defined /// </summary> /// <param name="context">the context used to create the graph</param> /// <returns></returns> public override Graph createGraph(Interpreter.InterpretationContext context, Parameter parameter) { Graph retVal = null; Graph MRSPGraph = null; Function speedRestriction = context.findOnStack(SpeedRestrictions).Value as Function; if (speedRestriction != null) { Parameter p = (Parameter)speedRestriction.FormalParameters[0]; int token = context.LocalScope.PushContext(); context.LocalScope.setGraphParameter(p); MRSPGraph = createGraphForValue(context, context.findOnStack(SpeedRestrictions).Value, p); context.LocalScope.PopContext(token); } if (MRSPGraph != null) { Function deceleratorFactor = context.findOnStack(DecelerationFactor).Value as Function; if (deceleratorFactor != null) { Surface DecelerationSurface = deceleratorFactor.createSurface(context); if (DecelerationSurface != null) { FlatSpeedDistanceCurve MRSPCurve = MRSPGraph.FlatSpeedDistanceCurve(MRSPGraph.ExpectedEndX()); AccelerationSpeedDistanceSurface accelerationSurface = DecelerationSurface.createAccelerationSpeedDistanceSurface(double.MaxValue, double.MaxValue); QuadraticSpeedDistanceCurve BrakingCurve = null; try { BrakingCurve = EtcsBrakingCurveBuilder.Build_A_Safe_Backward(accelerationSurface, MRSPCurve); } catch (System.Exception e) { retVal = new Graph(); retVal.addSegment(new Graph.Segment(0, double.MaxValue, new Graph.Segment.Curve(0, 0, 0))); } if (BrakingCurve != null) { retVal = new Graph(); // TODO : Remove the distinction between linear curves and quadratic curves bool isLinear = true; for (int i = 0; i < BrakingCurve.SegmentCount; i++) { QuadraticCurveSegment segment = BrakingCurve[i]; if (segment.A.ToUnits() != 0.0 || segment.V0.ToUnits() != 0.0) { isLinear = false; break; } } for (int i = 0; i < BrakingCurve.SegmentCount; i++) { QuadraticCurveSegment segment = BrakingCurve[i]; Graph.Segment newSegment; if (isLinear) { newSegment = new Graph.Segment( segment.X.X0.ToUnits(), segment.X.X1.ToUnits(), new Graph.Segment.Curve(0.0, segment.V0.ToSubUnits(SiSpeed_SubUnits.KiloMeter_per_Hour), 0.0)); } else { newSegment = new Graph.Segment( segment.X.X0.ToUnits(), segment.X.X1.ToUnits(), new Graph.Segment.Curve( segment.A.ToSubUnits(SiAcceleration_SubUnits.Meter_per_SecondSquare), segment.V0.ToSubUnits(SiSpeed_SubUnits.KiloMeter_per_Hour), segment.D0.ToSubUnits(SiDistance_SubUnits.Meter) ) ); } retVal.addSegment(newSegment); } } } else { Log.Error("Cannot create surface for " + DecelerationFactor.ToString()); } } else { Log.Error("Cannot evaluate " + DecelerationFactor.ToString() + " as a function"); } } else { Log.Error("Cannot create graph for " + SpeedRestrictions.ToString()); } return(retVal); }
/// <summary> /// Creates a graph for the function /// </summary> /// <param name="context"></param> /// <param name="parameter"></param> /// <param name="explain"></param> /// <returns></returns> public override Graph CreateGraph(InterpretationContext context, Parameter parameter, ExplanationPart explain) { Graph retVal = new Graph(); StructureValue LocationStruct = context.FindOnStack(Target).Value as StructureValue; SiDistance location; SiSpeed speed; if (LocationStruct != null) { IVariable locationField = LocationStruct.Val["Location"] as IVariable; location = new SiDistance((locationField.Value as DoubleValue).Val); IVariable speedField = LocationStruct.Val["Speed"] as IVariable; speed = new SiSpeed((speedField.Value as DoubleValue).Val, SiSpeed_SubUnits.KiloMeter_per_Hour); Function decelerationFactor = context.FindOnStack(DecelerationFactor).Value as Function; if (decelerationFactor != null) { Surface DecelerationSurface = decelerationFactor.CreateSurface(context, explain); if (DecelerationSurface != null) { AccelerationSpeedDistanceSurface accelerationSurface = DecelerationSurface.createAccelerationSpeedDistanceSurface(double.MaxValue, double.MaxValue); QuadraticSpeedDistanceCurve BrakingCurve = null; try { BrakingCurve = EtcsBrakingCurveBuilder.Build_Deceleration_Curve(accelerationSurface, speed, location); } catch (Exception e) { retVal.AddSegment(new Graph.Segment(0, double.MaxValue, new Graph.Segment.Curve(0, 0, 0))); } SiSpeed finalSpeed = new SiSpeed(GetDoubleValue(context.FindOnStack(EndSpeed).Value), SiSpeed_SubUnits.KiloMeter_per_Hour); for (int i = 0; i < BrakingCurve.SegmentCount; i++) { QuadraticCurveSegment segment = BrakingCurve[i]; SiSpeed endSpeed = Max(finalSpeed, segment.Get(segment.X.X1)); SiDistance endDistance; if (endSpeed == finalSpeed) { // Ensures that a braking curve is calculated until the finalSpeed // but not further than the end of the curve segment SiSpeed tmp = Max(segment.Get(segment.X.X1), endSpeed - new SiSpeed(0.001)); endDistance = segment.IntersectAt(tmp); } else { endDistance = segment.X.X1; } Graph.Segment newSegment = new Graph.Segment( segment.X.X0.ToUnits(), endDistance.ToUnits(), new Graph.Segment.Curve( segment.A.ToSubUnits(SiAcceleration_SubUnits.Meter_per_SecondSquare), segment.V0.ToSubUnits(SiSpeed_SubUnits.KiloMeter_per_Hour), segment.D0.ToSubUnits(SiDistance_SubUnits.Meter) ) ); retVal.AddSegment(newSegment); if (endSpeed == finalSpeed) { break; } } } } } return(retVal); }
/// <summary> /// Creates a graph for the function /// </summary> /// <param name="context"></param> /// <param name="parameter"></param> /// <param name="explain"></param> /// <returns></returns> public override Graph CreateGraph(InterpretationContext context, Parameter parameter, ExplanationPart explain) { Graph retVal = new Graph(); StructureValue LocationStruct = context.FindOnStack(Target).Value as StructureValue; SiDistance location; SiSpeed speed; if (LocationStruct != null) { IVariable locationField = LocationStruct.Val["Location"] as IVariable; location = new SiDistance((locationField.Value as DoubleValue).Val); IVariable speedField = LocationStruct.Val["Speed"] as IVariable; speed = new SiSpeed((speedField.Value as DoubleValue).Val, SiSpeed_SubUnits.KiloMeter_per_Hour); Function decelerationFactor = context.FindOnStack(DecelerationFactor).Value as Function; if (decelerationFactor != null) { Surface DecelerationSurface = decelerationFactor.CreateSurface(context, explain); if (DecelerationSurface != null) { AccelerationSpeedDistanceSurface accelerationSurface = DecelerationSurface.createAccelerationSpeedDistanceSurface(double.MaxValue, double.MaxValue); QuadraticSpeedDistanceCurve BrakingCurve = null; try { BrakingCurve = EtcsBrakingCurveBuilder.Build_Deceleration_Curve(accelerationSurface, speed, location); } catch (Exception e) { retVal.AddSegment(new Graph.Segment(0, double.MaxValue, new Graph.Segment.Curve(0, 0, 0))); } SiSpeed finalSpeed = new SiSpeed(GetDoubleValue(context.FindOnStack(EndSpeed).Value), SiSpeed_SubUnits.KiloMeter_per_Hour); for (int i = 0; i < BrakingCurve.SegmentCount; i++) { QuadraticCurveSegment segment = BrakingCurve[i]; SiSpeed endSpeed = Max(finalSpeed, segment.Get(segment.X.X1)); SiDistance endDistance; if (endSpeed == finalSpeed) { // Ensures that a braking curve is calculated until the finalSpeed // but not further than the end of the curve segment SiSpeed tmp = Max(segment.Get(segment.X.X1), endSpeed - new SiSpeed(0.001)); endDistance = segment.IntersectAt(tmp); } else { endDistance = segment.X.X1; } Graph.Segment newSegment = new Graph.Segment( segment.X.X0.ToUnits(), endDistance.ToUnits(), new Graph.Segment.Curve( segment.A.ToSubUnits(SiAcceleration_SubUnits.Meter_per_SecondSquare), segment.V0.ToSubUnits(SiSpeed_SubUnits.KiloMeter_per_Hour), segment.D0.ToSubUnits(SiDistance_SubUnits.Meter) ) ); retVal.AddSegment(newSegment); if (endSpeed == finalSpeed) { break; } } } } } return retVal; }