Problems with Object Placement after determining Location

Include the following details (edit as applicable):

  • Issue category: Unity Example Package
  • Device type & OS version: iOS / Other Ex. iPhone 8+ on iOS 13
  • Host machine & OS version: Mac
  • Issue Environment : Unity Remote / On Device / Dev Portal
  • Xcode version: 13
  • ARDK version: 2
  • Unity version: 2021

Description of the issue:

Hi there,
I am developing an app, where POI are downloaded from a database (for now typed in manually) and placed around a user at the correct lat/long by calculations from the users GPS coordinates and compass readings. So far, extracting all the necessairy positional parameters works fine, but I am having troubles placing objects (prefabs) AFTER I have determined the users coordinates.

I havent worked with Unity/C# before, so I might just struggle with that…

My problem:

IEnumerator Start() method handles GPS/compass extraction from mobile device
calls void Set_Points() methods with compass bearing and gps coordinates as parameters
Set_Points() transforms POI and user gps to a local coordinate system and places prefabs with Instantiate() method.

Packing the Set_Points() method into the Start() method didnt work either, I dont really understand the relevance of the IEnumerator, maybe thats why it wont work.

Somehow the script stops working after it gets the coordinates and I dont know why… If someone can help me out, I would really appreciate it!

For reference my code:

using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;

public class Place_Object_North_v02 : MonoBehaviour
{
public GameObject add_prefab;
public static float compass_reading;
public static double gnss_user;

// converts degrees to rad
public double Deg2Rad(double deg_angle)
{
    double rad_angle = deg_angle * Math.PI / 180;
    return rad_angle;
}

// converts radiants to degrees
public double Rad2Deg(double rad_angle)
{
    double deg_angle = rad_angle * 180 / Math.PI;
    return deg_angle;
}

public void Set_Points(double phi, double[] position)
{
    Debug.Log("Start extra function");
    //double phi = compass_reading; // degrees, angle between top of device to north pole
    double R = 6373.0 * 1000; // m
    //double[] position = gnss_user;

    
    //double[] position = { 48.150316, 14.584814 };
    //double[,] poi = new double[,] { {48.150316, 15},
    //                                    {48.149562, 14.60982},
    //                                    { 48.135173, 14.553694}};

    // LAT LON
    // 48.21388, 16.38112
    // 48,2139 16,38115
    //double[] position = { 48.2139, 16.38115 };

    double[,] poi = new double[,] { {position[0], position[1]},
                                    {48.21388, 16.38112},
                                    {48.21398, 16.38122},
                                    {48.21378, 16.38132},
                                    {48.21368, 16.38142}};
    var results = new List<double>();

    // iterate over all points and calculate different parameters
    for (int i = 0; i <= poi.Rank; i++)
    {

        double lat1 = Deg2Rad(position[0]), lon1 = Deg2Rad(position[1]);
        double lat2 = Deg2Rad(poi[i, 0]), lon2 = Deg2Rad(poi[i, 1]);

        double dlon = lon2 - lon1;
        double dlat = lat2 - lat1;

        double a = Math.Pow(Math.Sin(dlat / 2), 2) + Math.Cos(lat1) * Math.Cos(lat2) * Math.Pow(Math.Sin(dlon / 2), 2);
        double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));

        double angle = Rad2Deg(Math.Atan2(dlon, dlat));

        if (angle < 0)
        {
            angle += 360;
        }
        if (angle >= 360)
        {
            angle -= 360;
        }

        double distance = R * c;
        double dx = Rad2Deg(Math.Cos(angle)) * distance;
        double dy = Rad2Deg(Math.Sin(angle)) * distance;

        // calculation of angle between device and poi from northpole
        double theta = phi - angle;
        // coordinates of poi from device (z because of weird unity)
        double x = distance * Math.Cos(theta), z = distance * Math.Sin(theta);

        Debug.Log("POI" + " " + x + " " + "0" + " " + z);
        Instantiate(add_prefab, new Vector3((float)x, 0, (float)z), Quaternion.identity);
    }

}

// Start is called before the first frame update
IEnumerator Start()
{
    Debug.Log("Start script");
    Debug.Log("Accesing Location");

    // Check if the user has location service enabled.
    if (!Input.location.isEnabledByUser)
    {
        yield break;
    }

    // Start Compass before Location
    Input.compass.enabled = true;

    // Starts the location service.
    Input.location.Start();

    //GNSS
    // Waits until the location service initializes

    int maxWait = 5;
    while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0)
    {
        yield return new WaitForSeconds(1);
        maxWait--;
    }

    // If the service didn't initialize in 20 seconds this cancels location service use.
    if (maxWait < 1)
    {
        Debug.Log("Timed out");
        yield break;
    }

    if (maxWait == 20)
    {
        yield break;
    }

    // If the connection failed this cancels location service use.
    if (Input.location.status == LocationServiceStatus.Failed)
    {
        Debug.Log("Unable to determine device location");
        yield break;
    }
    else
    {
        // If the connection succeeded, this retrieves the device's current location and displays it in the Console window.
        Debug.Log("Location determined: " + Input.location.lastData.latitude + " " + Input.location.lastData.longitude);
    }

    // COMPASS
    Debug.Log("Input.compass.trueHeading = " + Input.compass.trueHeading);

    // assign variables
    gnss_user[0] = Input.location.lastData.latitude;
    gnss_user[1] = Input.location.lastData.longitude;
    compass_reading = Input.compass.trueHeading;

    Input.location.Stop();
    Set_Points(compass_reading, gnss_user);

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

    Debug.Log("Placing Balls");

}

}

Hi Josef,

I took a look at your question and code and noticed that you’re not using any ARDK libraries. Unfortunately, we only provide support for issues regarding our ARDK platform and for projects and code that attempt to integrate ARDK to create and manage AR sessions.

I would recommend reaching out for help on the Unity forums, and if at any point you find yourself attempting to integrate ARDK with your project and it’s not working, or if there is another part of your project that is using ARDK already and it’s not working, feel free to reach out to us by submitting a new topic.

Hi,
yeah I am aware that I am not using any ARDK tools, but as I have noticed here (Proper way to get compass heading - #13 by rob_link) the underlying ARDK methods can interfere with the basic Unity Codebase (or so it may seem).

This might just be a c#/Unity problem, but maybe someone else from the community had a similar experience and/or is more proficient in c# and can help me out

Hi Josef,

This has been addressed in version 2.1 of ARDK. I would recommend upgrading to it if possible. If that is not possible or if it did not resolve your issues please let me know.