示例#1
0
        public Coordinates calculatePosition()
        {
            BeaconInfo [] beaconsOrdered = new BeaconInfo[4];

            //busca las 4 distancias menores, calcula distancia cada 3 beacons y hace promedio.
            var top4DistancesKeys = distances.Values;

            int pos = 0;

            foreach (string beaconKey in top4DistancesKeys)
            {
                beaconsOrdered[pos++] = (BeaconInfo)beacons[beaconKey];
                System.Console.WriteLine(Tag + " Beacon used: " + beaconKey + " distancia: " + beaconsOrdered[pos - 1].distance);
                if (pos > 4)
                {
                    break;
                }
            }

            // sumo coordenadas temporales
            Coordinates coord = new Coordinates();
            int         total = 0;

            for (int i = 0; i < 4; i++)
            {
                Coordinates tmp = calculateDistanceTrilateration(beaconsOrdered[i % 4], beaconsOrdered[(i + 1) % 4], beaconsOrdered[(i + 2) % 4]);
                if (!Double.IsNaN(tmp.x) && !Double.IsNaN(tmp.y))
                {
                    coord.x += tmp.x;
                    coord.y += tmp.y;
                    total++;
                }
            }

            //hago promedio
            if (total > 0)
            {
                coord.x /= total;
                coord.y /= total;
            }             // si no hay temporales devuelvo NaN
            else
            {
                coord.x = Double.NaN;
                coord.y = Double.NaN;
            }

            System.Console.WriteLine(Tag + "Posicion calculada: (" + coord.x + ", " + coord.y + ")");
            return(coord);
        }
示例#2
0
        public BeaconInfo updateBeacon(NSUuid uuid, NSNumber major, NSNumber minor, double distance)
        {
            System.Console.WriteLine(Tag + "add beacon");

            String     key        = major + ":" + minor;
            BeaconInfo beaconInfo = null;

            // si existe, actualizo
            if (beacons.Contains(key))
            {
                beaconInfo = (BeaconInfo)beacons[key];

                // saco distancia vieja
                if (distances.ContainsValue(key))
                {
                    distances.Remove(beaconInfo.distance);
                }

                beaconInfo.addDistance(distance);
            }             //sino, agrego
            else
            {
                beaconInfo       = new BeaconInfo();
                beaconInfo.uuid  = uuid.AsString();
                beaconInfo.major = major;
                beaconInfo.minor = minor;
                beaconInfo.addDistance(distance);

                beacons.Add(key, beaconInfo);
            }

            //actualizo distancias
            try {
                distances.Add(beaconInfo.distance, key);
            } catch (ArgumentException e) {
                //TODO que hacemos? le sumamos un cm y la dibujamos?
                System.Console.WriteLine(Tag + "add beacon -> clave duplicada en distancias");
                System.Console.WriteLine(Tag + e.Message);
            }
            return(beaconInfo);
        }
示例#3
0
        private Coordinates calculateDistanceTrilateration(BeaconInfo beaconA, BeaconInfo beaconB, BeaconInfo beaconC)
        {
            if (beaconA == null || beaconB == null || beaconC == null)
            {
                return(new Coordinates(Double.NaN, Double.NaN));
            }

            double latA = beaconA.position.x;
            double lonA = beaconA.position.y;
            double disA = beaconA.distance;

            double latB = beaconB.position.x;
            double lonB = beaconB.position.y;
            double disB = beaconB.distance;

            double latC = beaconC.position.x;
            double lonC = beaconC.position.y;
            double disC = beaconC.distance;

            double[] P1 = { lonA, latA, 0 };
            double[] P2 = { lonB, latB, 0 };
            double[] P3 = { lonC, latC, 0 };

            double[] ex   = { 0, 0, 0 };
            double   P2P1 = 0;

            for (int i = 0; i < 3; i++)
            {
                P2P1 += Math.Pow(P2[i] - P1[i], 2);
            }

            for (int i = 0; i < 3; i++)
            {
                ex[i] = (P2[i] - P1[i]) / Math.Sqrt(P2P1);
            }

            double[] p3p1 = { 0, 0, 0 };
            for (int i = 0; i < 3; i++)
            {
                p3p1[i] = P3[i] - P1[i];
            }

            double ivar = 0;

            for (int i = 0; i < 3; i++)
            {
                ivar += (ex[i] * p3p1[i]);
            }

            double p3p1i = 0;

            for (int i = 0; i < 3; i++)
            {
                p3p1i += Math.Pow(P3[i] - P1[i] - ex[i] * ivar, 2);
            }

            double[] ey = { 0, 0, 0 };
            for (int i = 0; i < 3; i++)
            {
                ey[i] = (P3[i] - P1[i] - ex[i] * ivar) / Math.Sqrt(p3p1i);
            }

            double[] ez = { 0, 0, 0 };
            // if 2-dimensional vector then ez = 0

            double d = Math.Sqrt(P2P1);

            double jvar = 0;

            for (int i = 0; i < 3; i++)
            {
                jvar += (ey[i] * p3p1[i]);
            }

            // from wikipedia
            // plug and chug using above values
            double x = (Math.Pow(disA, 2) - Math.Pow(disB, 2) + Math.Pow(d, 2)) / (2 * d);
            double y = ((Math.Pow(disA, 2) - Math.Pow(disC, 2) + Math.Pow(ivar, 2) + Math.Pow(jvar, 2)) / (2 * jvar)) - ((ivar / jvar) * x);

            // only one case shown here
            double z = Math.Sqrt(Math.Pow(disA, 2) - Math.Pow(x, 2) - Math.Pow(y, 2));

            if (Double.IsNaN(z))
            {
                z = 0;
            }

            // triPt is an array with ECEF x,y,z of trilateration point
            // triPt = P1 + x*ex + y*ey + z*ez
            double[] triPt = { 0, 0, 0 };

            for (int i = 0; i < 3; i++)
            {
                triPt[i] = P1[i] + ex[i] * x + ey[i] * y + ez[i] * z;
            }

            // convert back to lat/long from ECEF
            // convert to degrees
            double xPhone = triPt[0];
            double yPhone = triPt[1];

            System.Console.WriteLine(Tag + " Trilateration - x= " + xPhone + " y=" + yPhone);

            return(new Coordinates(xPhone, yPhone));
        }