/// <summary> /// <para>This function creates the virtual objects according to the distance. </para> /// If the distande from the user to the stored infrastructure is less than distance_threshold_max meters and more than distance_threshold_min meters, it created the V.O. /// When the distance is more than distance_threshold_max meters and less than distance_threshold_min meters, the V.O is disabled. /// </summary> public void SceneCreation() { if (objectList.Count() != 0) { //for each object in the stored objects list foreach (ServerObject objectInList in objectList) { //if opbject is not already created if (!objectInList.created.Equals("yes")) { float dist = 0f;; //traffic lights if (!objectInList.traffic_light_id.Equals(0)) { dist = locationScript.Location(objectInList.coordinatesX, objectInList.coordinatesY); } //espiras if (!objectInList.gis_espiras_id.Equals(0)) { dist = locationScript.Location(objectInList.gis_espiras_coordinatesX, objectInList.gis_espiras_coordinatesY); } //crosswalk if (!objectInList.gis_crosswalks_id.Equals(0)) { dist = locationScript.Location(objectInList.gis_crosswalk_coordinatesX, objectInList.gis_crosswalk_coordinatesY); } // create V.O if (dist >= distance_threshold_min && dist <= distance_threshold_max) { //set created as true objectInList.created = "yes"; //delaration of the cartesian variables float x = 0f; float y = 0f; float z = 0f; string name = ""; //traffic lights if (!objectInList.traffic_light_id.Equals(0)) { z = locationScript.LatitudeToZ(objectInList.coordinatesX); x = locationScript.LongitudeToX(objectInList.coordinatesY); //y = 3f; y = 0f; Debug.LogWarning("Server Connection [Creating V.O.]: Traffic Id: " + objectInList.traffic_light_id); //set gameObject name name = "TrafficLight" + objectInList.traffic_light_id; GameObject signalType; if (objectInList.traffic_light_id.Equals(5) || objectInList.traffic_light_id.Equals(6)) { signalType = infrastructure_TrafficLight_upper; } else { signalType = infrastructure_TrafficLight; } //create object GameObject trafficLight_gameObject = (GameObject)Instantiate(signalType, new Vector3(x, y, z), infraPos.rotation); int orientation = objectInList.signal_Orientation; Debug.Log("[Augmented Script]: Traffic Light Orientation: " + orientation); //rotate trafficLight_gameObject trafficLight_gameObject.transform.Rotate(0, orientation, 0); //add trafficLight_gameObject name trafficLight_gameObject.name = name; //// put GIS info on the suface of the object //titleObj = trafficLight_gameObject.GetComponentInChildren<Text>(); //titleObj.text = "Id: " + objectInList.traffic_light_id; // add the V.O. to scene trafficLight_gameObject.SetActive(true); //add to array trafficArray[objectInList.traffic_light_id] = trafficLight_gameObject; } //espiras if (!objectInList.gis_espiras_id.Equals(0)) { z = locationScript.LatitudeToZ(objectInList.gis_espiras_coordinatesX); x = locationScript.LongitudeToX(objectInList.gis_espiras_coordinatesY); Debug.LogWarning("Server Connection [Creating V.O.]: Espiras Id: " + objectInList.gis_espiras_id); name = "Espira" + objectInList.gis_espiras_id; //create object GameObject espira = (GameObject)Instantiate(infrastructure_Espira, new Vector3(x, y, z), infraPos.rotation); espira.name = name; // put GIS info on the suface of the object titleObj = espira.GetComponentInChildren <Text>(); titleObj.text = "Espiras\n\nId: " + objectInList.gis_espiras_id; // add the V.O. to scene espira.SetActive(true); //add to array espirasArray[objectInList.gis_espiras_id] = espira; } //crosswalk if (!objectInList.gis_crosswalks_id.Equals(0)) { z = locationScript.LatitudeToZ(objectInList.gis_crosswalk_coordinatesX); x = locationScript.LongitudeToX(objectInList.gis_crosswalk_coordinatesY); Debug.LogWarning("Server Connection [Creating V.O.]: Crosswalk Id: " + objectInList.gis_crosswalks_id); name = "Crosswalk" + objectInList.gis_crosswalks_id; //create object GameObject crosswalk = (GameObject)Instantiate(infrastructure_Crooswalk, new Vector3(x, y, z), infraPos.rotation); crosswalk.name = name; // put GIS info on the suface of the object titleObj = crosswalk.GetComponentInChildren <Text>(); titleObj.text = "Crosswalk\n\nId:" + objectInList.gis_crosswalks_id; // add the V.O. to scene crosswalk.SetActive(true); //add to array crosswalksArray[objectInList.gis_crosswalks_id] = crosswalk; } } else { //Debug.Log("Already created." + objectInList.traffic_light_id + objectInList.gis_espiras_id + objectInList.gis_crosswalks_id); } } //if gameobject already created else { float dist = 0f;; //traffic lights if (!objectInList.traffic_light_id.Equals(0)) { dist = locationScript.Location(objectInList.coordinatesX, objectInList.coordinatesY); //Debug.LogWarning("Server Connection [Already Created V.O.]: " + dist + " meters - Traffic Id: " + objectInList.traffic_light_id); } //espiras if (!objectInList.gis_espiras_id.Equals(0)) { dist = locationScript.Location(objectInList.gis_espiras_coordinatesX, objectInList.gis_espiras_coordinatesY); //Debug.LogWarning("Server Connection [Already Created V.O.]: " + dist + " meters - Espiras Id: " + objectInList.gis_espiras_id); } //crosswalk if (!objectInList.gis_crosswalks_id.Equals(0)) { dist = locationScript.Location(objectInList.gis_crosswalk_coordinatesX, objectInList.gis_crosswalk_coordinatesY); //Debug.LogWarning("Server Connection [Already Created V.O.]: " + dist + " meters - Crosswalk Id: " + objectInList.gis_crosswalks_id); } if (dist < distance_threshold_min || dist > distance_threshold_max) { if (!objectInList.traffic_light_id.Equals(0)) { Debug.LogWarning("Server Connection [Disabling V.O.]: " + dist + " meters - Traffic Id: " + objectInList.traffic_light_id); //destroy V.O. Destroy(trafficArray[objectInList.traffic_light_id]); //not created again objectInList.created = "no"; Debug.LogError("Traffic Light Id: " + objectInList.traffic_light_id + " destroyed"); } //espiras if (!objectInList.gis_espiras_id.Equals(0)) { Debug.LogWarning("Server Connection [Disabling V.O.]: " + dist + " meters - Espiras Id: " + objectInList.gis_espiras_id); //destroy V.O. Destroy(espirasArray[objectInList.gis_espiras_id]); //not created again objectInList.created = "no"; Debug.LogError("Espira Id: " + objectInList.gis_espiras_id + " destroyed"); } //crosswalk if (!objectInList.gis_crosswalks_id.Equals(0)) { Debug.LogWarning("Server Connection [Disabling V.O.]: " + dist + " meters - Crosswalk Id: " + objectInList.gis_crosswalks_id); //destroy V.O. Destroy(crosswalksArray[objectInList.gis_crosswalks_id]); //not created again objectInList.created = "no"; Debug.LogError("Crosswalk Id: " + objectInList.gis_crosswalks_id + " destroyed"); } } } } } }
/// <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"; } } }