/******************************************************************************************************/ protected void Emit_Quadratic_Segment(StreamWriter swd, QuadraticCurveSegment aSegment, SiSpeed v_offset, SiDistance d_offset) { SiDistance d0 = aSegment.X.X0; SiDistance d1 = aSegment.X.X1; Emit_d_V(swd, d0 + d_offset, aSegment.Get(d0) + v_offset); if (d1 - d0 > SiDistance.One) { SiDistance delta = SiDistance.One; SiDistance d = d0 + delta; do { Emit_d_V(swd, d + d_offset, aSegment.Get(d) + v_offset); d += delta; } while (d < d1); } Emit_d_V(swd, d1 + d_offset, aSegment.Get(d1) + v_offset); }
/// <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); }