static double ComputeSmoothness(List <HistoryItem> history) { // for every point in [3, length-3], generate quadratic function for points [t - 3, t + 3]. // Then compute squared error for point. double errSum = 0.0d; for (int i = 3; i < history.Count - 3; i++) { var timeRange = new Range(i - 3, i + 4, 1); var relevantPoints = history.GetRange(i - 3, 7); var t = (from n in timeRange select n).ToArray(); var fitFuncX = Fitters.GeneratePolynomialFitFunction( timeRange, (from point in relevantPoints select point.Value.X).ToList(), 2); var fitFuncY = Fitters.GeneratePolynomialFitFunction( timeRange, (from point in relevantPoints select point.Value.Y).ToList(), 2); var errX = fitFuncX(i); var errY = fitFuncY(i); errSum += errX + errY; // Return summed error. } return(errSum / history.Count); }
public Vector2D ComputeCommand(WorldState worldState, Vector2D baseCommand) { // Create a range for t values. var ts = new Range(0, Math.Min(HistoryLength, worldState.InputHistory.Count), 1); // Fit a function on input for x-axis. Func <double, double> funcX = Fitters.GeneratePolynomialFitFunction( ts, (from l in worldState.InputHistory.TakeLast(HistoryLength) select l.Value.X).ToList(), FitFunctionDegree ); // Fit a function on input fo y-axis. Func <double, double> funcY = Fitters.GeneratePolynomialFitFunction( ts, (from l in worldState.InputHistory.TakeLast(HistoryLength) select l.Value.Y).ToList(), FitFunctionDegree ); // Predict next value and return. double time = HistoryLength + 1; var ret = new Vector2D(funcX(time), funcY(time)); if (double.IsNaN(ret.X)) { ret.X = 0.0; } if (double.IsNaN(ret.Y)) { ret.Y = 0.0; } return(ret.GetNormalized()); }