/// <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"; } } }