Example #1
0
        public static void DoMotionWithAir(TrainPacket packet)
        {
            if (packet.P > 0 && packet.Velocity < 0.005)
            {
                packet.Velocity = 0.005;
            }

            if (packet.R > 1)
            {
                double MaxP = 4.0;
                double OutP = MaxP / Math.Pow(20.0, Math.E / 2.0) * Math.Pow((double)packet.P, Math.E / 2.0);
                packet.nextVelocity = Dynamics.LocoMotions.CalcVelocityUpWithAir(Math.Abs(packet.Velocity), 0.1, 1.0, OutP, DT);

                if (packet.Velocity < packet.nextVelocity)
                {
                    packet.Velocity = packet.nextVelocity;
                }
            }

            if (packet.R < 10)
            {
                double B = Math.Abs(packet.Velocity) < minV ? 2.0 : 1.0;
                packet.Velocity = Dynamics.LocoMotions.CalcVelocityDownWithAir(Math.Abs(packet.Velocity), 0.1, 1.0, B, 1.0, packet.R / 10.0, DT);
                if (packet.Velocity < 0.005)
                {
                    packet.Velocity = 0;
                }
            }
        }
Example #2
0
        public static void DoMotionWithSlip(TrainPacket packet, double maxV)
        {
            double minV = 0.02;

            if (packet.P > 0 && packet.Velocity < minV)
            {
                packet.Velocity = minV;
            }

            double p = packet.P / 20.0, r = 1.0 - (packet.R - 1.0) / 9.0;

            packet.nextVelocity = Dynamics.LocoMotions.CalcVelocityWithSlip(Math.Abs(packet.Velocity), p, r, maxV, 0.05);

            if ((packet.R > 1 && packet.Velocity < packet.nextVelocity) || packet.R < 10)
            {
                packet.Velocity = packet.nextVelocity;
            }

            if (packet.Velocity < minV)
            {
                packet.Velocity = 0;
            }
            if (packet.Velocity > maxV)
            {
                packet.Velocity = maxV;
            }
        }
Example #3
0
        private void BtnCalc_Click(object sender, EventArgs e)
        {
            g.Clear(BoxGraph.BackColor);

            if (!Parse(BoxV, out double v))
            {
                return;
            }
            if (!Parse(BoxP, out int p))
            {
                return;
            }
            if (!Parse(BoxR, out int r))
            {
                return;
            }
            if (!Parse(BoxLim, out double lim))
            {
                return;
            }
            bool high   = BoxHigh.Checked;
            bool unlock = BoxUnlock.Checked;
            bool euler  = BoxEuler.Checked;
            bool slip   = BoxSlip.Checked;

            r = 10 - r; r = r < 1 ? 1 : (r > 10 ? 10 : r);

            TrainPacket packet = new TrainPacket(p, r, 1);

            packet.SetVelocity(v);

            if (v < lim)
            {
                if (p == 0 || r == 1)
                {
                    return;
                }
                Calc(() => packet.Velocity < lim, packet, lim, high, unlock, euler, slip);
            }
            else if (v > lim)
            {
                if (r == 10)
                {
                    packet.R = 1;
                }
                Calc(() => packet.Velocity > lim, packet, lim, high, unlock, euler, slip);
            }

            ShowCode(p, r, lim, high);
        }
Example #4
0
        private void Calc(State state, TrainPacket packet, double lim, bool high, bool unlock, bool euler, bool slip)
        {
            new Task(() =>
            {
                double dist        = 0;
                List <double> vels = new List <double>();

                BtnCalc.Invoke(new Action(() => BtnCalc.Enabled   = false));
                BtnClear.Invoke(new Action(() => BtnClear.Enabled = false));
                while (state.Invoke())
                {
                    if (euler)
                    {
                        if (slip)
                        {
                            if (high)
                            {
                                if (unlock)
                                {
                                    TrainController.DoMotionWithSlip(packet, 8.0);
                                }
                                else
                                {
                                    TrainController.DoMotionWithSlip(packet, 5.0);
                                }
                            }
                            else
                            {
                                TrainController.DoMotionWithSlip(packet, 3.5);
                            }
                        }
                        else
                        {
                            if (high)
                            {
                                if (unlock)
                                {
                                    TrainController.DoMotionWithEuler(packet, 8.0);
                                }
                                else
                                {
                                    TrainController.DoMotionWithEuler(packet, 5.0);
                                }
                            }
                            else
                            {
                                TrainController.DoMotionWithEuler(packet, 3.5);
                            }
                        }
                    }
                    else
                    {
                        if (high)
                        {
                            if (unlock)
                            {
                                TrainController.DoMotionWithAirHighEx(packet);
                            }
                            else
                            {
                                TrainController.DoMotionWithAirHigh(packet);
                            }
                        }
                        else
                        {
                            TrainController.DoMotionWithAir(packet);
                        }
                    }

                    dist += packet.Velocity; vels.Add(packet.Velocity);
                    if (dist > MAX)
                    {
                        BoxDist.Invoke(new Action(() => BoxDist.Text      = "NULL"));
                        BtnCalc.Invoke(new Action(() => BtnCalc.Enabled   = true));
                        BtnClear.Invoke(new Action(() => BtnClear.Enabled = true));
                        return;
                    }
                }
                BtnCalc.Invoke(new Action(() => BtnCalc.Enabled   = true));
                BtnClear.Invoke(new Action(() => BtnClear.Enabled = true));

                BoxDist.Invoke(new Action(() => BoxDist.Text = dist.ToString("F1")));

                double max   = Max(vels);
                double step  = (double)BoxGraph.Width / (double)vels.Count;
                double scale = (double)BoxGraph.Height / max;

                for (int i = 0; i < vels.Count - 1; i++)
                {
                    g.DrawLine(
                        Pens.Black,
                        (float)(i * step), (float)((double)BoxGraph.Height - vels[i] * scale),
                        (float)((i + 1) * step), (float)((double)BoxGraph.Height - vels[i + 1] * scale)
                        );
                }

                vels.Clear();
            }).Start();
        }