2. Realtà aumentata ed Azure, un binomio imbattibile
Alessio Iafrate
Microsoft MVP, Freelance
developer
Founder DotNetAbruzzo
3. A
G
E
N
D
A
Why is mobile AR relevant?
• By 2020, 100 million consumers will
shop in AR online and in-store,
according to Gartner, Inc.
DatafromSeptember2018by
https://pages.arm.com/arvr-report.html
4. A
G
E
N
D
A
Why does the cloud play a role here?
• The cloud provides the secure
storage and scalable
processing for a digital copy of
the real world which can be
accessed by any user at any
time on any device for shared
AR content.
12. A
G
E
N
D
A
Wayfinding
• Guiding the way through a
store following a spatial
grocery list
• Empowering people who are
blind or low vision with
spatial sound anchors
• Navigating large areas like
theme parks, museums,
festivals
24. A
G
E
N
D
A
Mobile
HoloLens
Client
Place notes in the real world
Persistent virtual content
Azure Spatial
Anchors
Azure
App Service
Azure
Cosmos DB
Sharing Service
iOS – Swift, ARKit, SceneKit
Android – Java, ARCore, SceneForm
SOLUTION ARCHITECTURE
25. A
G
E
N
D
A
API Key Concepts
• CloudSpatialAnchorSession
• Provides core services (Ex. Create, locate, update, delete CloudSpatialAnchor’s)
• Captures data about the environment
• CloudSpatialAnchor
• Links to the underlying AR platform Anchor (WorldAnchor on HoloLens, ARAnchor on iOS, Anchor on Android)
• Holds an ID, Expiration, and Properties (Dictionary<String, String>)
• CreateAnchorAsync(CloudSpatialAnchor anchor) { … }
• Save a CloudSpatialAnchor to Azure Spatial Anchors
• Returns the CloudSpatialAnchor with an ID assigned
• CreateWatcher(AnchorLocateCriteria criteria)
• Begins to watch for anchors that meet the specified criteria
• Returns located CloudSpatialAnchor’s through a delegate
• AnchorLocateCriteria
• Assign it an array of CloudSpatialAnchor IDs
27. A
G
E
N
D
A
Mobile
HoloLens
Client
Persistent virtual content
Azure Spatial
Anchors
Sharing
Service
1) Initialize session
2) Create anchor
3) Locate anchors
1. Save anchor
2. Get anchor ID back
3. Save anchor ID in database
4. Get IDs from database
5. Locate anchors by ID
6. Get anchors back
SOLUTION ARCHITECTURE
28. A
G
E
N
D
A
protected void init() {
// Set up ARCore & SceneForm.
this.sceneView = ...
Scene scene = ...
...
// Initialize the CloudSpatialAnchorSession.
this.spatialAnchorsSession = new CloudSpatialAnchorSession();
this.spatialAnchorsSession.Configuration.AccountKey = “xxxxxxxxx”;
this.spatialAnchorsSession.Configuration.AccountId = “xxxxxxxxx”;
...
// Give frames to the CloudSpatialAnchorSession.
scene.Update += (_, args) =>
{
// Pass frames to Spatial Anchors for processing.
this.spatialAnchorsSession?.ProcessFrame(this.sceneView.ArFrame);
};
// Add a callback that tells us how much information about the environment we have.
this.spatialAnchorsSession.OnSessionUpdated += (_, sessionUpdateArgs) =>{
this.sessionUpdated = sessionUpdateArgs.Args.Status.RecommendedForCreateProgress;
}
// Register handleTap() as a callback to be invoked when the user taps to place a sphere.
this.arFragment.TapArPlane += ArFragment_TapArPlane;
...
}
Initialize session
29. A
G
E
N
D
A
Private async void ArFragment_TapArPlane (HitResult hitResult, Plane plane, MotionEvent motionEvent) {
// Create the ARCore Anchor.
Anchor localAnchor = hitResult.createAnchor();
// Render a white sphere at the localAnchor position.
...
// Set the previously created ARCore Anchor as the localAnchor of the CloudSpatialAnchor.
CloudSpatialAnchor cloudAnchor = new CloudSpatialAnchor();
cloudAnchor.LocalAnchor=localAnchor;
// Prompt the user to input a note, set it as a property on the CloudSpatialAnchor.
...
// Wait until we have enough data about the environment
while (this.sessionUpdated < 1) { ... wait ... }
// Save the CloudSpatialAnchor to Azure Spatial Anchors.
this.spatialAnchorsSession.CreateAnchorAsync(cloudAnchor)
.ContinueWith(async cloudAnchorTask =>{
// Save CloudSpatialAnchor ID to the Sharing Service.
PostAnchor(cloudAnchor.getIdentifier());
}
});
Azure Spatial
Anchors
Sharing
Service
Create anchor
30. A
G
E
N
D
A
public void LocateAnchors(String[] identifiers) {
AnchorLocateCriteria criteria = new AnchorLocateCriteria();
criteria.setIdentifiers(identifiers);
this.spatialAnchorsSession.createWatcher(criteria);
}
String[] identifiers = GET https://<foo>.azurewebsites.net/api/anchors
LocateAnchors(identifiers); Azure Spatial
Anchors
Sharing
Service
Locate anchor
31. A
G
E
N
D
A
private void initializeSession() {
// Initialize the CloudSpatialAnchorSession.
this.cloudSession = new CloudSpatialAnchorSession();
...
this.cloudAnchorManager.OnAnchorLocated += CloudAnchorManager_OnAnchorLocated;
}
private void CloudAnchorManager_OnAnchorLocated(object sender, AnchorLocatedEventArgs args)
{
if (args.Args.Status == LocateAnchorStatus.Located) {
// Get the ARCore Anchor from the CloudSpatialAnchor.
Anchor localAnchor = args.Args.Anchor.LocalAnchor;
// Render object at the ARCore Anchor location.
...
}
});
Azure Spatial
Anchors
Locate anchor
33. A
G
E
N
D
A
Wayfinding
public void LocateAnchors(String[] identifiers) {
AnchorLocateCriteria criteria = new AnchorLocateCriteria();
criteria.setIdentifiers(identifiers);
cloudSession.createWatcher(criteria);
}
public void LocateNearbyAnchors(CloudSpatialAnchor anchor) {
NearAnchorCriteria nearAnchorCriteria = new NearAnchorCriteria();
nearAnchorCriteria.setSourceAnchor(anchor);
AnchorLocateCriteria criteria = new AnchorLocateCriteria();
criteria.setNearAnchor(nearAnchorCriteria);
cloudSession.createWatcher(criteria);
}
37. A
G
E
N
D
A
Placing anchors
Target interesting visual features
• Avoid blank surfaces or surfaces
without details.
Record from perspectives where
you want the next person to
discover from
• Think about those who will come
after you.
Why mobile AR when we have next gen AR devices like HL2
Gartner quote: By 2020, 100 million consumers will shop in AR online and in-store and 5G will play a huge role says Gartner. https://www.gartner.com/en/newsroom/press-releases/2019-04-01-gartner-says-100-million-consumers-will-shop-in-augme
Persistent content enabled by Anchors will play an important role here as well for advanced in-store experiences
26% active devices were able to use either ARKit + ARCore. September 2018 Now one third
Google I/O - 400mio devices
We all love the advanced features of HL but mobile AR is
Low entry, wide reach everyone has a smartphone
Why Azure?
Devices have their own, disconnected AR view of the world
Cloud brings it together
Virtual content persists and sharing across devices
Relies on device’s digital view of the world
How do devices view/see the world?
Abstract concept Examples and scenarios we see with our customers
HL since 2015 Dozens of apps / use cases
Due to NDA generalized use cases we see commonly
Own coord system for location in real-world
A common frame of reference to place digital content in the same physical location where it stays at the same position and orientation relative to the real-world environment.
Location in real-world ensures virtual content stays at the same pos/orient even if you move
Anchor is not the content, just a real-world location where content can be anchored
HoloLens, ARKit, ARCore and Magic Leap (PCF)
A common frame of reference to place digital content in the same physical location where it stays at the same position and orientation relative to the real-world environment.
What is a Cloud Spatial Anchor - Why Cloud?
Normalizes different devices anchors/mappings
Multiple users. sharing across devices with persistence
A common frame of reference for enabling multiple users to place digital content in the same physical location where it is persisted and can be seen on different devices at the same position and orientation relative to the real-world environment.
Persistence
Hot research topic, Startups as well as big players
ASA is the only implementation that provides persisted, x-plat, shared anchors
Paris later tech details
Here more examples: shared, x-plat + persistence
A common frame of reference for enabling multiple users to place digital content in the same physical location where it is persisted and can be seen on different devices at the same position and orientation relative to the real-world environment.
Real-time IoT sensor data on real-world equipment
Multi-user, cross-platform
Biz val:
Real-time insights into data
much faster than searching through pages of information on complex control room panels
Dynamic warehouse navigating for fulfilling a order
Biz val: Increased efficiency and less packaging errors
Photo from Wikipedia:
https://commons.wikimedia.org/wiki/File:Pantos_Logistics_-_Warehouse_picture.jpg
Enterprise is nice but there’s a ton of fun consumer use cases as well
Mobile AR market size
Festival navigation like Coachella https://twitter.com/rschu/status/1117339333969817600
Theme park navigation concept video used with permission: https://vimeo.com/319985238
“Sure, You can use it. At the moment it's a marker based/Arkit/Core combination, but love to see what Azure Spatial Anchors can do to further this concept”
Also: holographic characters in its amusement park for guests in line to hang out with them as they’re waiting to board the ride
Biz val: Engaging customers with innovative tech and improve their CX
Swiss 'gabarits’ / Baugespann / Profile
Show the form of a future construction with poles,
Architecture vis of building before they build to get citizens involved
Design reviews
Biz val: making tedious, laborious and time-intensive work into a natural, intuitive and more collaborative experience.
Better vis means better commitment;
reduce cost
First Photo from:
https://upload.wikimedia.org/wikipedia/commons/4/43/Sch%C3%B6nb%C3%BChlring_in_Luzern.jpg
Second photo by my friend Laurent Bugnion who lives in Siwtzerland
Location-based:
ASA screams games Multi-user, cross-platform
Scavenger hunt; Hide and seek games, social engaging
Biz val: Democratize AR game dev – now any developer can build the next Pokémon Go,
Fruit hunt dropped fruity anchors during last MVP Summit
Won’t slip on virtual banana
Talk about Azure Spatial Anchors, abbreviate to ASA
New Azure service lets you place spatial anchors and save them to the cloud
Before we begin, want to briefly touch on what a cloud spatial anchor is again – important for the rest of this talk
If you place a spatial anchor, you now have a reference between your device and a point the real world.
You can render a hologram there,
And when you want to share this point, you save it to ASA.
When the next person comes, they get that location, and they can see the hologram as well.
Share a position in the real world that can be persisted and can be seen on different devices.
Want to share a picture that I’m familiar with – the lobby of my building.
And this video is what Azure Spatial Anchors sees when it's looking at the lobby.
In green are feature points, which are distinguishing points in the real world. Your badge would be full of feature points because there are lots of high visual contrast.
In red are camera frames, which are the pictures we took with the camera from different points in space.
As you wave your phone around, we get more and more green feature points. When you place an anchor, it gets tied to those feature points. And when you look for an anchor, we use the feature points that we've collected to know where the anchor should be placed.
I want to note that all of this is done on the device, so no camera frames are leaving your device.
Building an app for collaboration in the real world
Building on that to do wayfinding
Finally, some UX best considerations
Support HL, iOS, Android. Can develop on Unity or write native apps.
All platforms are first class citizens. And our KPI matrix that considers all platforms, and their relationships to each other.
Today, we’re highlighting iOS Swift and Android Java. But you can also build for iOS and Android.
So the app we built is a collaborative experience. Like we saw in Rene's factory floor example, where they placed training guidance on a car being assembled, this app lets you leave notes on places of interest and then later retrieve them.
Before this demo, we placed a note on the table. When we start the app, we're going to locate it. We'll then place a new note that we can later retrieve.
Right now, they're collecting the camera frames and searching for anchors.
We found the note!
And now we'll place a note for the next person to come see.
If we restart the device, we can now see that we found the new anchor again!
I'm now going to give you a quick look at the architecture. We'll then look at some key concepts for the ASA API before coming back to it in more detail.
We have client code, Java and Swift in this case. It talks to two things.
ASA, which we use to save and locate anchors.
Next, an API. Using Azure App Service, we have an ASP.NET API that is connected to a CosmosDB backend. We use this to store information about our anchors which we need to retrieve them from Azure Spatial Anchors. Because it’s not really important what we use in the sharing service, I’m just going to call it the sharing service, and you can think of it as a database.
Now I'm going to look at some API key concepts, and then we'll revisit this diagram with a little more context.
CloudSpatialAnchorSession – you give the session camera frames (one note – you don’t need to do this on HoloLens because we have the map)
CreateAnchorAsync – no ID when you create, only when it’s been created you’ll get a callback with a CloudSpatialAnchor that has an ID assigned.
CreateWatcher
You get back a CloudSpatialAnchor, and it has a link to an underlying AR platform anchor. If you are on iOS, you will get back an ARAnchor, even if you are on a HoloLens. That’s one of the really cool things we do – you don’t have to do any math or conversions and you get to work with the anchor that is native to the platform you are on.
So if we look at the big picture, we see that when we create an anchor we are given back an ID.
And when we want to find an anchor, we need to tell ASA the ID of the anchor we want to find.
That is why we need a database – we store IDs in it.
I'm now going to give you a quick look at the architecture. We'll then look at some key concepts for the ASA API before coming back to it in more detail.
We have client code, Java and Swift in this case. It talks to two things.
ASA, which we use to save and locate anchors.
Next, an API. Using Azure App Service, we have an ASP.NET API that is connected to a CosmosDB backend. We use this to store information about our anchors which we need to retrieve them from Azure Spatial Anchors. Because it’s not really important what we use in the sharing service, I’m just going to call it the sharing service, and you can think of it as a database.
Now I'm going to look at some API key concepts, and then we'll revisit this diagram with a little more context.
The sharing service is a way for us to store IDs. You need to share IDs because different users at different times will want to look for an anchor.
I now
I’m elippsis in place of code to simplify things. In this case, sceneView and scene are Sceneform concepts. All this code it on GitHub, and I’d love it if you looked into it more there.
Then, we need to give the camera frames to ASA, so we add an update listener and call ProcessFrame.
If you’re not familiar with this sytax, a listener is similar-ish to a delegate or callback, in that it will get called by SceneForm whenever there is a new camera frame
So what this does it call session.processframe everytime there’s a new camera frame
On HoloLens you don't need to do this because we have the spatial map.
SessionUpdated
So we use sessionUpdated to tell us about how much environmental information we have, and whether it’s enough to save an anchor
Next, let’s create an anchor. To do so, we need to add a callback that will be invoked when you tap on the screen. TapArPlaneListener is a ARCore concept that lets us register a method to be called when you tap on a plane. Let’s write the handle tap method to place an anchor
First, we create the local anchor – creating this Anchor object is an ARCore concept, and we do it by using the HitResult, i.e. the place in the real world we tapped.
We’ll now add another listener that will get called when we locate an anchor.
Now that we’ve located an anchor, we can get its location. We get in back as an ARCore Anchor, even if it was created on HoloLens or iOS.
So that’s our app – I hope you can now initialize a session, create an anchor, and then locate anchors. All this code is on GitHub, and I’ll share the Url at the end of the session.
You’ve seen how to locate an anchor by ID. You initialize the criteria, set an array of IDs, and create a watcher.
But you can also locate anchors that are connected to, and nearby, an anchor you have already located.
We’ll write LocateNearbyAnchors to do so. It’s passed in a CloudSpatialAnchor that has already been located.
Then create NearAnchorCriteria, and set the anchor as the source anchor.
Then we’ll create the AnchorLocateCriteria we’ve seen before, but this time set the NearAnchor as the nearAnchorCriteria object. Let’s look at what this will do.
I want to first touch briefly on feature points again.
Well, first, you want to try to get feature points. A white wall will have less of those green dots, so it will be harder to locate an anchor that was placed without capturing many feature points.
Second, you want to consider the scenario, because it will lead your UX design.
Are you placing a note at the top of a hiking trail to tell people about the route?
If so, you'll want to make sure you capture from 360 so that the next person coming along doesn't need to be in the same place you were
Or are you displaying a data visualization on a conference room table?
Maybe you should encourage users to place the anchor sitting down, or in an accessible and central spot.
Are you leaving notes around a museum?
Maybe it doesn’t matter if the user captures a 360, and instead they should focus on the painting and panning around it.
When you’re finding anchors, I also encourage you to design based on the scenario. Internally, we’ve seen two patterns for finding anchors emerge.
One is the target scenario – where you’re able to show the user a picture of the area they should aim at.
Let’s give an example - If you were designing an app for a museum, you might have an admin mode, where only certain people get to place anchors. In that case, you might be able to get them to take a picture of each painting to help guide users to find the anchor later.
Another thing we’ve seen is the room scenario, where the anchor could be anywhere. An example of this is ap escape the room app we built, where anchors could be all over. In that case, you want to give UX that will encourage the user to pan all around.
So, with that, I want to say that we’re live! We launched at the end of February, and our team is so happy and thankful to be here. We’ve loved watching what people are building – and we hope to continue seeing Rene’s amazing videos, as well as all of yours!