예제 #1
0
    /// <summary>
    /// Moving Window Algorithm to give us a more steady GPS signal
    /// </summary>
    private void Update()
    {
        // key inputs to move the camera
        if (Input.GetKey(KeyCode.RightArrow))
        {
            longitude += 0.000003f;
            //transform.position += new Vector3(0.4f, 0, 0);
        }
        if (Input.GetKey(KeyCode.UpArrow))
        {
            latitude += 0.000005f;
            //transform.position += new Vector3(0, 0, 0.4f);
        }

        if (Input.GetKey(KeyCode.LeftArrow))
        {
            longitude -= 0.000003f;
            //transform.position += new Vector3(-0.4f, 0, 0);
        }
        if (Input.GetKey(KeyCode.DownArrow))
        {
            latitude -= 0.000005f;
            //transform.position += new Vector3(0, 0, -0.4f);
        }

        // if GPS is enabled
        if (gpsEnabled)
        {
            //Moving Window algorithm
            //if it is the first GPS Readings
            if (firstWindowReadings)
            {
                // get the first readings
                lastWindowLatitude  = Input.location.lastData.latitude;
                lastWindowLongitude = Input.location.lastData.longitude;
                lastWindowTimestamp = Input.location.lastData.timestamp;

                //print
                utilsScript.WriteToFile("\n\n[GPS Script]: First GPS Readings (lat and long): " + lastWindowLatitude + " - " + lastWindowLongitude);

                //add values to list
                latitudeWindowList.Add(lastWindowLatitude);
                longitudeWindowList.Add(lastWindowLongitude);
                timestampsWindowList.Add(lastWindowTimestamp);

                //update counts and booleans
                windowGPScount++;
                firstValues++;
                firstWindowReadings = false;

                // update the Unity general latitude and longitude values
                latitude  = lastWindowLatitude;
                longitude = lastWindowLongitude;
            }
            //if it is not the first GPS Readings
            else
            {
                // get lat and long updated values
                float  newlatitude  = Input.location.lastData.latitude;
                float  newlongitude = Input.location.lastData.longitude;
                double newTimestamp = Input.location.lastData.timestamp;

                // calculate the difference between the coordinate to comparison
                float latdif  = Math.Abs(lastWindowLatitude - newlatitude);
                float longdif = Math.Abs(lastWindowLongitude - newlongitude);

                // if GPS reading changes verifies if the readings are good enough
                if (latdif > 0.00001f || longdif > 0.000001f)
                {
                    //calculates the distance between the last and the new GPS values
                    float dist = locationScript.DistanceWindow(lastWindowLatitude, lastWindowLongitude, newlatitude, newlongitude);

                    // if the distance if less than GPSmaxDifDistance meters it is a possible good value
                    if (dist < GPSmaxDifDistance)
                    {
                        //print
                        utilsScript.WriteToFile("\n\n\n[GPS Script]: new lat, long, and timestamp readings: " + newlatitude + " - " + newlongitude + " - " + newTimestamp);

                        //print
                        utilsScript.WriteToFile("\n[GPS Script]: Moving Window distance: " + dist + " meters");

                        // time diference between the two readings (seconds)
                        double deltaTime = newTimestamp - lastWindowTimestamp;

                        //print
                        utilsScript.WriteToFile("\n[GPS Script]: Moving Window delta time: " + deltaTime + " seconds");

                        //speed calculation (m/s)
                        float speed = dist / (float)deltaTime;

                        //print
                        utilsScript.WriteToFile("\n[GPS Script]: Moving Window speed: " + speed + " m/s");

                        if (speedWindowList.Count() > 1)
                        {
                            // calculates the acceleration (deltaVelocity / deltaTime)
                            accelerationValue = (speedWindowList.ElementAt(speedWindowList.Count() - 1) + speed) / (float)deltaTime;
                            utilsScript.WriteToFile("\n[GPS Script]: Acceleration Value: " + accelerationValue + " m/s^2");
                        }

                        ////////////////////////////    Moving Window Algorithm verifications   ////////////////////////////////

                        //if user is fixed at a position and there are more than initialisingIterations GPS readings
                        if (speed < minWindowSpeed && windowGPScount > initialisingIterations ||                  //speed is too low, so user is fixed
                            accelerationValue < minWindowAcceleration && windowGPScount > initialisingIterations) // acceleration is too low, so user is fixed
                        {
                            // same position, so no need to change the lastWindow's latitude and longitude values

                            //time average
                            double tmpTimestamp = (newTimestamp + lastWindowTimestamp) / 2f;
                            lastWindowTimestamp = tmpTimestamp;

                            //print
                            utilsScript.WriteToFile("\n[GPS Script]: I Think the User Stoped Here!");

                            // maintain the old position on Unity, so no need to change the latitude and longitude values
                        }
                        // if the speed value is greater than the max value and there are more than initialisingIterations GPS readings
                        else if (speed > maxWindowSpeed && windowGPScount > initialisingIterations)
                        {
                            utilsScript.WriteToFile("\n[GPS Script]: Speed is to High for a Normal Ambulation (3m/s)!");

                            // replace the last GPS reading for the average of the last and new GPS readings
                            RemoveLastGPSReadings(newlatitude, newlongitude, newTimestamp);
                        }
                        // if the acceleration value is greater than the max value and there are more than initialisingIterations GPS readings
                        else if (accelerationValue > maxWindowAcceleration && windowGPScount > initialisingIterations)
                        {
                            utilsScript.WriteToFile("\n[GPS Script]: Acceleration is to High for even a runner (Usain Bolt - 3.09m/s^2)!");

                            // the acceleration value is to high, discard the values
                            RemoveLastGPSReadings(newlatitude, newlongitude, newTimestamp);
                        }
                        // if everything ok with the GPS readings
                        else
                        {
                            //add distance value to the list
                            distanceWindowList.Add(dist);

                            //add speed value to list
                            speedWindowList.Add(speed);

                            // calculate the necessary averages of the moving window algorithm
                            CalculateAverageValues();

                            //update to the last GPS reading values
                            lastWindowLatitude  = newlatitude;
                            lastWindowLongitude = newlongitude;
                            lastWindowTimestamp = newTimestamp;

                            // add new values to arrays
                            latitudeWindowList.Add(newlatitude);
                            longitudeWindowList.Add(newlongitude);
                            timestampsWindowList.Add(newTimestamp);

                            //print
                            utilsScript.WriteToFile("\n[GPS Script]: Added the GPS reading as a good one!");

                            //update count
                            windowGPScount++;
                            firstValues++;

                            // update the Unity general latitude and longitude values
                            latitude  = lastWindowLatitude;
                            longitude = lastWindowLongitude;
                        } // end everything ok else
                    }     // end < distance if
                    // if the distance if more than the GPSmaxDifDistance meters discard the GPS reading
                    else
                    {
                        if (firstValues < 5)
                        {
                            // if it is the first 5 readings discard the last GPS readings and use the new ones
                            RemoveLastGPSReadingsFirstValues(newlatitude, newlongitude, newTimestamp);
                        }
                        // if not the first readings and the distance is greater than the GPSmaxDifDistance value
                        else
                        {
                            // discard the last GPS readings and use the average between the last and the new ones
                            RemoveLastGPSReadings(newlatitude, newlongitude, newTimestamp);
                        }// end else first values
                    }
                    //end else GPSmaxDistance
                } //end if difference lat and long
            }     //end firstreadings else



            ///////////////////////////////////////////////////////////////   move camera   ////////////////////////////

            XCamera = locationScript.LongitudeToX(longitude);
            ZCamera = locationScript.LatitudeToZ(latitude);

            if (firstCamera)
            {
                lastX = XCamera;
                lastZ = ZCamera;
                cameraContainer.transform.position = Vector3.Lerp(transform.position, new Vector3(XCamera, 0, ZCamera), Time.deltaTime * smooth);
                Debug.LogError("[GPS Script]: Camera started at (x - z): " + XCamera + " - " + ZCamera);
                firstCamera = false;
            }
            else
            {
                // calculate the difference between the new and last readings
                float difX = Mathf.Abs(XCamera - lastX);
                float difZ = Mathf.Abs(ZCamera - lastZ);

                // if it changes update the camera position in the virtual world
                if (difX > 0.1 || difZ > 0.1)
                {
                    cameraContainer.transform.position = Vector3.Lerp(transform.position, new Vector3(XCamera, 0, ZCamera), Time.deltaTime * smooth);
                    Debug.LogError("[GPS Script]: Camera moved to (x - z): " + XCamera + " - " + ZCamera);

                    //update last values
                    lastX = XCamera;
                    lastZ = ZCamera;
                }
            }


            /////////////////////////////////////////////////////////////////////////////////////////////////////

            //update text in camera
            coordinates.text = "Lat: " + Input.location.lastData.latitude.ToString() + "     Long: " + Input.location.lastData.longitude.ToString() +
                               "     Altitude: " + Input.location.lastData.altitude.ToString() + "     Ver.Accuracy: " + Input.location.lastData.verticalAccuracy.ToString() +
                               "\nHor.Accuracy: " + Input.location.lastData.horizontalAccuracy.ToString() + "     Timestamp: " + Input.location.lastData.timestamp.ToString();
            debugGPS.text = "Debug: GPS updated";

            //compass values updating
            //calculates the average of the 10 compass values
            if (!compassV)
            {
                if (compassCount > 9)
                {
                    compassV = true;
                    float sum = 0f;
                    for (int i = 0; i < compassValuesArray.Length; i++)
                    {
                        sum += compassValuesArray[i];
                    }
                    //North = 0 or 360 -- East = 90 -- South = 180 -- West = 270
                    float compassAverage = sum / compassValuesArray.Length;
                    Debug.LogWarning("[GPS Script]: compass average: " + compassAverage);
                    //rotate camera
                    cameraContainer.transform.Rotate(0, compassAverage, 0);
                }
                else
                {
                    //add compass values to array
                    compassValuesArray[compassCount] = Input.compass.trueHeading;
                    //Debug.LogWarning("[Server Connection]: last compass value: " + compassValuesArray[compassCount]);
                    compassCount++;
                }
            }
            else
            {
                //debugGPS.text = "Debug: User has not enabled GPS";
            }
        }
    }