Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Hololens2 XRSDK WorldAnchors

Discussion in 'AR' started by jdcart, Sep 25, 2020.

  1. jdcart

    jdcart

    Joined:
    Jun 24, 2015
    Posts:
    15
    It looks like WorldAnchors don't work at all when using the XRSDK.

    What is the replacement to WorldAnchor, WorldAnchorStore, etc. in the XRSDK for the Hololens 2?
     
  2. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
  3. jdcart

    jdcart

    Joined:
    Jun 24, 2015
    Posts:
    15
    I see, I wish this had better documentation. I have a few questions related to the HL2 using MRTK:

    1. Do I have to use the SubsystemManager and call Create() on the XRReferencePointSubsystemDescriptors, or is there one already available (Perhaps already created by MRTK) that I can somehow use? If there is an existing one, how can I get it?

    2. For this line "AnchorData data = Marshal.PtrToStructure<AnchorData>(rp.nativePtr);" Under what namespace is AnchorData defined? If it's not defined, how should it be defined?

    Thanks for pointing me in the right direction.
     
  4. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    For 1: No, assuming that the platform you are running on supports Anchors, and your VS app manifest is setup to declare "Spatial Perception" you should just be able to query for and use the subsystem using the current loader. I actually use a helper class I created for simplifying this:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.XR.Management;
    3.  
    4. struct Subsystem<T> where T : class, ISubsystem
    5. {
    6.     private static System.Object s_lock = new System.Object();
    7.  
    8.     private static T s_subsystem = null;
    9.  
    10.     public static T Instance
    11.     {
    12.         get
    13.         {
    14.             if (s_subsystem == null)
    15.             {
    16.                 lock (s_lock)
    17.                 {
    18.                     if (s_subsystem == null)
    19.                     {
    20.                         s_subsystem = XRGeneralSettings.Instance?.Manager?.activeLoader?.GetLoadedSubsystem<T>() ?? null;
    21.                     }
    22.                 }
    23.             }
    24.  
    25.             return s_subsystem;
    26.         }
    27.     }
    28.  
    29.     public static void Release()
    30.     {
    31.         s_subsystem = null;
    32.     }
    33. }
    34.  
    and you use it like so:

    Code (CSharp):
    1. public class Foo
    2. {
    3.     private static SomeSubsystem SomeSubsystem => Subsystem<SomeSubsystem>.Instance;
    4.  
    5.     void SomeFunction()
    6.     {
    7.         SomeSubsystem?.SomeFunctpon();
    8.     }
    9. }
    10.  
    For 2:
    Code (CSharp):
    1. [StructLayout(LayoutKind.Sequential)]
    2. struct AnchorData
    3. {
    4.     public int version;
    5.  
    6.     [MarshalAs(UnmanagedType.IUnknown)]
    7.     public System.Object spatialAnchor;
    8. }
    9.  
    For any documentation you feel is missing or needs more info, please file bugs for that.
     
    Ramjid likes this.
  5. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    Caveat: I typed a bunch of that in by hand so might be some errors.
     
  6. jdcart

    jdcart

    Joined:
    Jun 24, 2015
    Posts:
    15
    I guess my comment about the documentation is more related to the removal of the high level WorldAnchor system that was available with Legacy VR and the fact that there is no clear replacement for it.

    All these things that you are pointing me to are definitely lower level than what was available in the past. You need to have a better understanding about the platform and how all those systems get created with the new plugin system. I'm just learning about all those things thanks to you.

    Thanks again. This is very helpful!
     
  7. Ramjid

    Ramjid

    Joined:
    Nov 27, 2017
    Posts:
    6
    @joejo : I'm facing almost the same problem as jdcart - I'm working on my first Hololens2 project using the new XR SDK and just learned in this thread that it doesn't support the old worldAnchors.

    I've read the documentation you linked and your code examples, but coming from an art background to Unity development I must admit I'm still pretty clueless on how to actually make it work.

    I believe I understand your helper class, but when using it to create "XRAnchorSubsystem" it is apparently not a valid option. It appears that I'm using an older version of AR Subsystems (2.1.2) which doesn't yet have that class, but I can't figure out if I'm supposed to manually update AR Subsystems somehow or if it's maybe just depending on which Unity version I'm using (2020.1.6f1). Or maybe it is related to which version of Windows XR Plugin I'm running (3.3.1) ?

    And once I've made it that far and successfully initialize the subsystem, how do I actually use/access it to create/destroy anchors or attach/detach objects to these anchors? The Windows XR Plugin documentation you linked says "Successful initialization and start of the subsystem allows the user to Add anchors, Remove anchors and Query for all known anchors" but doesn't explain how to do it. So do I just use the the functions referenced in the Unity documentation on XRAnchors? But what's the whole Windows XR Plugin part doing then?

    You see, I'm a bit... lost :) Could you maybe expand your explanation for a more "entry-level" audience or give me a few additional pointers on where to look for beginner-level clues on this subject?
     
  8. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    First, if you aren't finding XRAnchorSystem then the version of ARSubsystems you have is older and probably still declares it as XRReferencePointSubsystem. But since you are using Windows MR XR Plugin version 3 then you should be using the version of ARSubsystems verified for that version, which I believe is version 3. That should get you over your first hurdle.

    Secondly, documentation for the anchor subsystem can be found here: https://docs.unity3d.com/Packages/c...Engine.XR.ARSubsystems.XRAnchorSubsystem.html.

    Third, you really shouldn't be managing the lifecycles yourself unless you absolutely need to. That's what XR Plug-in Management is for. It will create, start, stop and destroy any and all subsystems setup for your device when you enable it in the management UI. For sure XRAnchorSubsystem is one of those and should be started for you. If that is failing, then you need to enable Spatial Perception in the app manifest. You can do that one of two ways, depending on if you've generated your VS project already or not.

    If you haven't, you can enable it in the Player Settings->Publishing Settings->Capabilities and then select "Spatial Perception".

    If you have, you have to enable it in Visual Studio:
    General overview of packaging: https://docs.microsoft.com/en-us/windows/uwp/packaging/
    Editing App Manifest in VS: https://docs.microsoft.com/en-us/windows/msix/package/packaging-uwp-apps#configure-your-project
    Capabilities: https://docs.microsoft.com/en-us/windows/uwp/packaging/app-capability-declarations
     
  9. jdcart

    jdcart

    Joined:
    Jun 24, 2015
    Posts:
    15
    I just got the anchors working yesterday. You are going to definitely need to use the helper class, and the second code snippet to be able to access the subsystem and work with the anchors. I come from an art background as well, so I see why it can be confusing but it's actually straightforward enough.

    In my particular case I'm using Unity 2019.4, I'm worried that you will have more problems with Unity 2020 using MRTK, I don't think they are there yet with the support of that Unity version-- as a first step, if you can, I'd recommend going back to 2019.4.

    I'm using:
    - Unity 2019.4.1
    - Windows XR Plugin 2.4.1 preview1: I'm using this one because it has some extension functions to persist the anchors.
    - XR Plugin Management 3.2.15

    To attach an anchor you would do something like this:

    Code (CSharp):
    1.  
    2. public void AttachAnchor()
    3.     {
    4.         //Create new pose from the game object's transform that we want to attach.
    5.         Pose p = new Pose(transform.position, transform.rotation);
    6.  
    7.         XRReferencePoint rp;
    8.  
    9.         //Try to add a reference point at the location at which the object was placed
    10.         if (RpSubsystem.TryAddReferencePoint(p, out rp))
    11.         {
    12.             //At this point do whatever you need to do with the XRReferencePoint. In my case I get the TrackableID, you'll see why later...
    13.             AnchorID = rp.TrackableId;
    14.         }
    15.     }
    16.  
    When you call AttachAnchor, you haven't actually created a relationship between the anchor and the game object, so in order for you to handle the updates, you need to create a function that handles that (This is what actually locks the object in place). I placed mine in Update():

    Code (CSharp):
    1.  
    2.  
    3. private void GetAnchorChanges()
    4.     {
    5.         TrackableChanges<XRReferencePoint>? currentRps = RpSubsystem?.GetChanges(Unity.Collections.Allocator.Temp) ?? null;
    6.  
    7.             if (currentRps != null && currentRps?.updated.Length > 0)
    8.             {
    9.                 //Update all the game objects based on the updated reference points
    10.                 foreach (XRReferencePoint rp in currentRps?.updated)
    11.                 {
    12.                     //This is what locks the object in place. This is why I stored the TrackableId when I created the anchor
    13.                     if (rp.trackableId == AnchorID)
    14.                     {
    15.                         transform.position = rp.pose.position;
    16.                         transform.rotation = rp.pose.rotation;
    17.                     }
    18.                 }
    19.         }
    20.     }
    To remove:

    Code (CSharp):
    1.  
    2.     public void RemoveAnchor()
    3.     {
    4.         if (RpSubsystem.TryRemoveReferencePoint(AnchorID))
    5.         {
    6.             //At this point the object shouldn't be anchored anymore
    7.         }
    8.     }
    9.  
    Hopefully that helps.
     
    Last edited: Oct 1, 2020
    HaydenLeeteUC and Ramjid like this.
  10. mdurand

    mdurand

    Joined:
    Aug 1, 2016
    Posts:
    45
    Please see the AR Foundation sample scene named Anchors.unity - which supports the XRAnchorSubsystem on HoloLens and HoloLens 2.

    https://github.com/Unity-Technologies/arfoundation-samples

    AR Foundation makes interacting with the XRAnchorSubsystem very easy and represents each anchor as components on separate GameObjects.

    https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@4.1/manual/anchor-manager.html

    Please make sure that the branch of AR Foundation samples you checkout matches the version of the AR Foundation and XR Plugin that you wish to use. Note that in AR Foundation package version 2.1.x the XRAnchorSubsystem was known as XRReferencePointSubsystem.

    -Mike
     
    Ramjid likes this.
  11. Ramjid

    Ramjid

    Joined:
    Nov 27, 2017
    Posts:
    6
    @joejo and @mdurand : Thanks for your pointers, after installing AR Foundations it automatically installed a more recent AR Subsystems package. I'm taking a look at AR Foundation's anchor manager as we speak, but the whole AR Foundation package seems pretty promising already.

    @jdcart : Thanks a lot for your explanation, that's exactly the kind of "practical" help I had hoped for! I guess as a designer first (and due to my lack of in-depth programming knowledge), my approach to coding is mostly based around trial and error - by now I can write basic game/interaction logic just fine, but I've still mostly no clue about the underlying code architecture or the higher-level programming concepts. I'm trying to learn as much as I can, but always kind of "on-the-fly" as I try to solve a particular problem :)

    As for Unity 2020.1: There's no real need to use 2020.1 for me and I'm not that far into my project, so switching back to 2019.4 shouldn't be an issue if I can't get it to work in this version.