public EstimateResult getEstimate(SnifferWifiMeasurement currentMeasurement) { //Check ready state if (mCurrentBuilding == null) return null; //Maintain primary and secondary search space //Cf OfflineClientPocketPCUF if (secondarySearchSpace == null) { secondarySearchSpace = mCurrentBuilding.Vertices; // mGraph.getVertices(); } EstimateResult primaryEstimate = new EstimateResult(null, Double.MaxValue); EstimateResult secondaryEstimate = new EstimateResult(null, Double.MaxValue); BestCandidateSet = new BCS(5); //candidates are added in the compare methods below //measurement is compared with primary search space (adjacent vertices to previous estimated vertex) //and secondary search space (non-connected nodes or the full graph) if (prevBestEstimateVertex != null) { primaryEstimate = mPosAlgorithm.compare(prevBestEstimateVertex.adjacentVertices(), currentMeasurement); } secondaryEstimate = mPosAlgorithm.compare(secondarySearchSpace, currentMeasurement); //Changed to accomodate hyper, where we return null if online meas only has one mac //Vertex best = null; EstimateResult bestEstimate = null; if (primaryEstimate != null) bestEstimate = primaryEstimate; if (secondaryEstimate != null) { //The primary estimate may be overriden by a secondary if it is better for the second time in a row if (secondaryEstimate.getDistance() < primaryEstimate.getDistance()) { numSecondaryBest++; if (numSecondaryBest >= 2 || prevBestEstimateVertex == null) { numSecondaryBest = 0; bestEstimate = secondaryEstimate; //.getVertex(); } } else { numSecondaryBest = 0; } } prevBestEstimateVertex = bestEstimate.getVertex(); //Currently, the error estimate is also calculated in the compare methods, //but we override that logic here since this implementation considers the global //candidates - not just the local primary- or secondary candidates. //We throw in an extra 5 meters to account for movement double error = Math.Ceiling(BestCandidateSet.getMaxDistance()); // + 5; bestEstimate.setErrorEstimate(error); return bestEstimate; }
public EstimateResult compare(IEnumerable<Vertex> vertices, SnifferWifiMeasurement measurement) { measurement = getNStrongestAPMeasurement(measurement, 7); if (vertices == null || measurement == null) return null; bcs = WifiPosEngine.BestCandidateSet; //new BCS(5); //bcs.clear(); double curDist; //distance of current vertice in search space EstimateResult result = new EstimateResult(null, double.MaxValue); foreach (Vertex curVertex in vertices) //sammenlign med hver Vertex { foreach (SnifferWifiMeasurement curFP in curVertex.SnifferWifiMeasurements) //sammenlign med hvert fingerprint (usually only one - otherwise use more intelligent approach) { curDist = 0; foreach (String mac in measurement.getMACs()) //all APs in sample if (curFP.containsMac(mac)) curDist += Math.Pow((measurement.getAvgDbM(mac) - curFP.getAvgDbM(mac)), 2); else curDist += Math.Pow((measurement.getAvgDbM(mac) - MISSING_MAC_PENALTY), 2); curDist = Math.Sqrt(curDist); if (curDist < result.getDistance()) { result.setDistance(curDist); result.setVertex(curVertex); } bcs.add(curVertex, curDist); //add to best candidate set - which will take care of only using the best estimates. } } //The following only yields a local error estimate within the primary- or secondary //vertices and may thus not be appropriate result.setErrorEstimate(Math.Ceiling(bcs.getMaxDistance())); return result; }
//Public visibility so we can test it (directly) via unit tests public static SnifferWifiMeasurement getNStrongestAPMeasurement(SnifferWifiMeasurement measurement, int n) { if (measurement.getMACs().Count < n) return measurement; SortedDictionary<double, String> strongestAPs = new SortedDictionary<double, String>(); //Find the n strongest macs // foreach (String mac in measurement.getMACs()) //all APs in sample { double curMacVal = measurement.getAvgDbM(mac); while (strongestAPs.ContainsKey(curMacVal)) curMacVal += 0.0001; strongestAPs.Add(curMacVal, mac); //NB: TreeMap sorts members in ascending order! //Thus, we remove from the head to keep the strongest values if (strongestAPs.Count > n) strongestAPs.Remove(strongestAPs.First().Key); } //Create new measurement containing n strongest macs SnifferWifiMeasurement result = new SnifferWifiMeasurement(); foreach (double d in strongestAPs.Keys) { SnifferHistogram h = new SnifferHistogram(); h.Mac = strongestAPs[d]; h.value = (int)d; h.count = 1; result.SnifferHistograms.Add(h); //result.addValue(strongestAPs.get(d), (int)d); } return result; }