/// <summary> /// Compute the position given the receivings /// </summary> internal static Position triangulate(List <Packet.Reception> receivings, DateTime receptiontime) { Position p = new Position(Vector2D.Zero, receivings[0].ReceivingStation.location.room); Vector2D accumulator = new Vector2D(Vector2D.Zero); p.positionDate = receptiontime; String tag = ""; if (receivings.Count() > 2) { double minrssi = 0; double avgrssi = 0; double vote = 0; foreach (Packet.Reception pr in receivings) { tag += (Environment.NewLine + pr.RSSI + " " + pr.ReceivingStation.NameMAC); minrssi = pr.RSSI < minrssi ? pr.RSSI : minrssi; avgrssi += pr.RSSI; double weight = Math.Pow(Math.E, (pr.RSSI + 25) / 10); accumulator = accumulator.Add(pr.ReceivingStation.location.MultiplyScalar(weight)); vote += weight; } avgrssi /= receivings.Count(); accumulator = accumulator.DivideScalar(vote).Clip(Vector2D.Zero, p.room.size); tag += Environment.NewLine + "avg: " + accumulator.X + " " + accumulator.Y; if (avgrssi < -105 || (avgrssi < -90 && minrssi < -70)) { p = new Position(0, 0, Room.externRoom); } else { if (receivings.Count() == 3) { Vector2D tr = triangulate_circles(receivings); if (tr != null) { //tag += Environment.NewLine + "tri: " + tr.X + " " + tr.Y; accumulator = accumulator.MultiplyScalar(0.87).Add(tr.Clip(Vector2D.Zero, p.room.size).MultiplyScalar(0.13)); } } p._Import(accumulator); } } else { p.uncertainity = UNCERTAIN_POSITION + 1; } p.tag = tag; return(p); }