Пример #1
0
        /// <summary>
        /// Creates the surface for the Acceleration based on speed and distance (A(V,d))
        /// </summary>
        /// <returns></returns>
        public AccelerationSpeedDistanceSurface createAccelerationSpeedDistanceSurface(double expectedEndX, double expectedEndY)
        {
            AccelerationSpeedDistanceSurface retVal = new AccelerationSpeedDistanceSurface();

            foreach (Segment segment in Segments)
            {
                Graph graph = segment.Graph;
                FlatAccelerationSpeedCurve acc = graph.FlatAccelerationSpeedCurve(expectedEndY);
                for (int i = 0; i < acc.SegmentCount; i++)
                {
                    double start = segment.Start;
                    double end   = segment.End;
                    if (end == double.MaxValue)
                    {
                        end = expectedEndX;
                    }

                    ConstantCurveSegment <SiSpeed, SiAcceleration> seg = acc[i];
                    SurfaceTile tile = new SurfaceTile(
                        new SiDistance(start, SiDistance_SubUnits.Meter),
                        new SiDistance(end, SiDistance_SubUnits.Meter),
                        seg.X.X0,
                        seg.X.X1,
                        seg.Y
                        );
                    retVal.Tiles.Add(tile);
                }
            }

            return(retVal);
        }
Пример #2
0
        /// <summary>
        /// Creates the picture associated to this graph
        /// </summary>
        /// <param name="name"></param>
        /// <returns>the corresponding bitmap</returns>
        public Bitmap Display()
        {
            Bitmap retVal = null;

            SpeedDistanceCurvePlotter display = new SpeedDistanceCurvePlotter();
            String name = null;

            /// Computes the expected end to display
            double expectedEndX = 0;
            Dictionary <Function, Graph> graphs = new Dictionary <Function, Graph>();

            foreach (Function function in Functions)
            {
                InterpretationContext context = new InterpretationContext(function);
                if (function.FormalParameters.Count == 1)
                {
                    Parameter parameter = (Parameter)function.FormalParameters[0];
                    Graph     graph     = function.createGraph(context, parameter);
                    if (graph != null)
                    {
                        expectedEndX = Math.Max(expectedEndX, graph.ExpectedEndX());
                        graphs.Add(function, graph);
                    }
                }
            }

            double expectedEndY = 0;
            Dictionary <Function, Surface> surfaces = new Dictionary <Function, Surface>();

            foreach (Function function in Functions)
            {
                InterpretationContext context = new InterpretationContext(function);
                if (function.FormalParameters.Count == 2)
                {
                    Surface surface = function.createSurface(context);
                    if (surface != null)
                    {
                        expectedEndX = Math.Max(expectedEndX, surface.ExpectedEndX());
                        expectedEndY = Math.Max(expectedEndY, surface.ExpectedEndY());
                        surfaces.Add(function, surface);
                    }
                }
            }

            // Don't display surfaces that are too big
            if (setMaximumYValueCheckBox.Checked)
            {
                try
                {
                    int maxY = Int32.Parse(maximumYValueTextBox.Text);
                    expectedEndY = Math.Min(expectedEndY, maxY);
                }
                catch (Exception)
                {
                }
            }
            expectedEndY = Math.Min(600, expectedEndY);

            int i = 0;

            /// Creates the graphs
            foreach (KeyValuePair <Function, Graph> pair in graphs)
            {
                Function function = pair.Key;
                Graph    graph    = pair.Value;

                if (graph != null)
                {
                    if (graph.IsFlat())
                    {
                        FlatSpeedDistanceCurve curve = graph.FlatSpeedDistanceCurve(expectedEndX);
                        display.AddCurve(curve, function.FullName, COLORS[i % COLORS.Length]);
                    }
                    else
                    {
                        QuadraticSpeedDistanceCurve curve = graph.QuadraticSpeedDistanceCurve(expectedEndX);
                        display.AddCurve(curve, function.FullName, COLORS[i % COLORS.Length]);
                    }

                    if (name == null)
                    {
                        name = function.Name;
                    }
                }
                i += 1;
            }

            /// Creates the surfaces
            foreach (KeyValuePair <Function, Surface> pair in surfaces)
            {
                Function function = pair.Key;
                Surface  surface  = pair.Value;

                if (surface != null)
                {
                    AccelerationSpeedDistanceSurface curve = surface.createAccelerationSpeedDistanceSurface(expectedEndX, expectedEndY);
                    display.AddCurve(curve, function.FullName);
                    if (name == null)
                    {
                        name = function.Name;
                    }
                }
            }

            if (name != null)
            {
                display.GnuPlot_Home_Path = Path.GetDirectoryName(Application.ExecutablePath) + "\\gnuplot\\bin";
                string outputDir = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData) + "\\ERTMSFormalSpecs";
                System.IO.Directory.CreateDirectory(outputDir);
                display.Output_Path          = outputDir;
                display.Base_Name            = "EFSPicture_" + name;
                display.ImageWidth           = 1200;
                display.ImageHeight          = 600;
                display.EraseTemporaryFiles  = false;
                display.ShowColouredSegments = false;

                if (setMinimumValueCheckBox.Checked)
                {
                    try
                    {
                        double val = double.Parse(minimumValueTextBox.Text);
                        display.Min_X = new SiDistance(val, SiDistance_SubUnits.Meter);
                    }
                    catch (Exception)
                    {
                    }
                }

                if (setMaximumValueCheckBox.Checked)
                {
                    try
                    {
                        double val = double.Parse(maximumValueTextBox.Text);
                        display.Max_X = new SiDistance(val, SiDistance_SubUnits.Meter);
                    }
                    catch (Exception)
                    {
                    }
                }

                if (display.Plot())
                {
                    // Sometimes, a handle is still open on the corresponding file which forbids opening the stream on it
                    // Wait a bit until the handle is no more open
                    System.IO.FileStream stream = null;

                    System.DateTime start = System.DateTime.Now;
                    while (stream == null && System.DateTime.Now - start < new TimeSpan(0, 0, 5))
                    {
                        try
                        {
                            stream = new System.IO.FileStream(display.ImageFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
                        }
                        catch (Exception)
                        {
                            System.Threading.Thread.Sleep(100);
                        }
                    }

                    if (stream != null)
                    {
                        try
                        {
                            retVal = new Bitmap(stream);
                        }
                        catch (Exception)
                        {
                        }
                        finally
                        {
                            stream.Close();
                            // System.IO.File.Delete(display.ImageFileName);
                        }
                    }
                }
            }

            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);
        }