/// <summary> /// Instantiating a record from a list of shifts /// </summary> /// <param name="xShift">X shifts.</param> /// <param name="yShift">Y shifts.</param> public ForwardReachResult(MotionShift xShift, MotionShift yShift) { FirstShiftRecordNum = new int?[] { xShift.GetPhaseShiftPoint(0), yShift.GetPhaseShiftPoint(0) }; SecondShiftRecordNum = new int?[] { xShift.GetPhaseShiftPoint(1), yShift.GetPhaseShiftPoint(1) }; ThirdShiftRecordNum = new int?[] { xShift.GetPhaseShiftPoint(2), yShift.GetPhaseShiftPoint(2) }; }
/// <summary> /// Analyze the specified input and parameters. /// </summary> /// <returns>The analyze.</returns> /// <param name="inputs">Input.</param> /// <param name="parameters">Parameters.</param> public IEnumerable <ICsvWritable> Analyze(IEnumerable <SensorReading> inputs, IEnumerable <Parameter> parameters) { var results = new List <ForwardReachResult>(); // parse out parameters var accelParam = parameters.FirstOrDefault(x => x.Field.Equals(CommandParameters.Acceleration)); var accelXParam = parameters.FirstOrDefault(x => x.Field.Equals(CommandParameters.AccelX)); var accelYParam = parameters.FirstOrDefault(x => x.Field.Equals(CommandParameters.AccelY)); if (accelParam == null || accelXParam == null || accelYParam == null) { return(null); } // parse out clause values var windowSize = int.Parse(accelParam.GetClauseValue(CommandParameters.Window)); var margin = int.Parse(accelParam.GetClauseValue(CommandParameters.Margin)); var accelXThreshold = decimal.Parse(accelXParam.GetClauseValue(CommandParameters.Threshold)); var accelYThreshold = decimal.Parse(accelYParam.GetClauseValue(CommandParameters.Threshold)); // iterate through input records with a single-record sliding window var currentInputs = new List <SensorReading>(); foreach (var input in inputs) { // add new inputs to the collection until it is full if (currentInputs.Count() < windowSize) { currentInputs.Add(input); } // once it is full, check for reach behavior match if (currentInputs.Count() == windowSize) { // convert raw accel-x vals into motion shift obj var xShift = new MotionShift { Axis = Constants.BAT.Axes.X }; xShift.SetPhases(currentInputs); // convert raw accel-y vals into motion shift obj var yShift = new MotionShift { Axis = Constants.BAT.Axes.Y }; yShift.SetPhases(currentInputs); // determine if shifts meet "forward reach" behavior expectations var isForwardReachOnX = xShift.IsForwardReach(accelXThreshold); var isForwardReachOnY = yShift.IsForwardReach(accelYThreshold); var shiftsAreWithinMargins = xShift.WithinMargins(yShift, margin); if (isForwardReachOnX && isForwardReachOnY && shiftsAreWithinMargins) { var newResult = new ForwardReachResult(xShift, yShift); if (!results.Any(x => x.Matches(newResult))) { results.Add(newResult); } // if match found, shift current input collection // by one half window size and continue for (int i = 0; i < (windowSize / 2); i++) { currentInputs.RemoveAt(i); } continue; } // if no match found, remove the first record and go again currentInputs.RemoveAt(0); } } return(results.Distinct()); }