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