Augmented/Virtual Reality with Horizontal Coordinates in iOS and Android

Augmented reality star maps
Augmented reality star maps

So, you want your mobile or tablet to know where in the world you’re pointing it for a virtual reality or augmented reality application?

To draw 3D geometry on the screen in OpenGL, you can use the rotation matrixes returned by the respective APIs (iOS/Android). The APIs will also give you roll, pitch and yaw angles for the device.

What’s not easy to do through the APIs is to get three angles that tell you in general where the device is pointing – that is, the direction in which the rear camera is pointing. You might want this information to capture the location of something in the real world, or to draw a virtual or augmented view of a world on the screen of the phone. The Fireballs in the Sky app (iOSAndroid) does both, allowing you to capture the start and end point of a “fireball” (meteor/ite) by pointing your phone at the sky, while drawing a HUD and stars on the phone  screen during the capture process, so you’re confident you’ve got the right part of the sky.

Azimuth and elevation
Azimuth and elevation

Roll, pitch and yaw tell you how the device sees itself – they are rotations around lines that go through the device (device axes). But in this case we want to know how the device sees the world – we need rotations around lines fixed in the real world (world axes). To know where the device is pointing, we actually want azimuthelevation and tilt, as shown.

Azimuth and elevation together are commonly known as a horizontal coordinate system.

Tilt angle
Tilt angle

The azimuth, elevation pair of angles gives you enough information to define a direction, and hence capture objects in the real world (assuming the distance to the object does not need to be specified). However, if you want to draw something on the screen of your device, you need to know whether the device is held in landscape orientation, portrait orientation, or somewhere in-between; thus a third angle – tilt – is required.

Azimuth is defined as the compass angle of the direction the device is pointing. Elevation is the angle above horizontal of the direction the device is pointing. Tilt is the angle the device is rotated around the direction in which it is pointing (the direction defined by azimuth and elevation angles).

We can get azimuth, elevation and tilt with the following approach:

  1. Define a world reference frame
  2. Obtain the device’s rotation matrix with respect to this frame
  3. Calculate the azimuth, elevation and tilt angles from the rotation matrix

It will really help to be familiar with the mathematical concept of a vector (three numbers defining a point or direction in 3D space), and be able to convert between radians and degrees, from here on in. Sample code may be published in future.

Define a World Reference Frame

World reference frame
World reference frame

We’re somewhere in the world, defined by latitudelongitude and altitude. We’ll define a reference frame with its origin at this point. For convenience, we’d like Z to point straight up into the sky, and X to point to true north. Therefore, Y points west (for a right-handed frame), as shown here. We define unit vectors ijk in the principal directions (or axes) X, Y, Z, and we’ll use them later.

\[ \newcommand{\vect}[1]{\mathbf{#1}}
\vect{i} = \left[1,0,0\right], \vect{j} = \left[0,1,0\right], \vect{k} = \left[0,0,1\right]\]

Obtain Device Rotation Matrix

Device rotation with respect to world frame
Device rotation with respect to world frame

What we want eventually is an rotation matrix that is made up of the components of the device axes abc, (also unit vectors) with reference to the world frame we defined. This matrix will allow us to convert a direction in the device frame into a direction in the world frame, and vice versa. This gives us all the information we need to derive azimuth, elevation and tilt angles.

We’ll describe the device axes as:

  • is “screen right”, the direction from the centre to the right of the screen with the device in portrait
  • is “screen top”, the direction from the centre to the top of the screen with the device in portrait
  • c is “screen normal”, the direction straight out of the screen (at right angles to the screen, towards the viewer’s eye)

We can write each device axis as a vector sum of the components in each of the principal world frame directions, or we can use the shorthand of a list of numbers:

\[\vect{a} = a_i\vect{i}+a_j\vect{j}+a_k\vect{k} = \left[a_i,a_j,a_k\right]\]

The rotation matrix then has the form:

\[\mathbf{A} = \left[\begin{array}{ccc}
a_i & b_i & c_i \\
a_j & b_j & c_j \\
a_k & b_k & c_k \end{array}\right]\]

To get a matrix of this form in iOS, just use reference CMAttitudeReferenceFrameXTrueNorthZVertical and get the rotation matrix. However, the returned matrix will be the transpose of the matrix above, so you will need to transpose the result of the API call.

In Android, you will need to correct for magnetic declination and a default frame that uses Y as magnetic north, and therefore X as east. Both corrections are rotations about the Z axis. The matrix will similarly be transposed.

Calculate View Angles

Device elevation angle
Device elevation angle

We can calculate the view angles with some vector maths. The easiest angle is elevation, so let’s start there. We find the angle that the screen normal (c) makes with the vertical (k) using the dot product cosine relationship.

\[-\vect{c} \cdot \vect{k} = \cos\left(\frac{\pi}{2}-e\right)\]
\[e = \frac{\pi}{2} – \arccos\left(-\vect{c} \cdot \vect{k}\right)\]

Elevation is in the range [-90, 90]. Note also from the definitions above that such dot products can be extracted directly from the rotation matrix, as we can write:

\[\vect{c} \cdot \vect{k} = c_k \]

Device azimuth angle
Device azimuth angle

Next, we calculate azimuth, for which we need the horizontal projection (cH) of the screen normal (c). We use Pythagoras’ theorem to calculate cH:

\[1 = c_H^2 + c_V^2\]
\[c_H = \sqrt{1 – c_k^2}\]

We then define a vector cP in the direction of c, such that the horizontal projection of this vector is always equal to 1, so we can use this horizontal projection to calculate angles with the horizontal vectors i & j.

\[\vect{c}_P = \frac{\vect{c}}{c_H}\]

Horizontal projection of device screen normal
Horizontal projection of device screen normal

We then calculate the angle the horizontal projection of the screen normal (cP) makes with the north axis (i). We get the magnitude of this angle from this dot product with i, and we get the direction (E or W of north) from the dot product with the west axis (j).

\[\cos{\alpha} = -\vect{c}_P \cdot \vect{i} = \frac{-\vect{c} \cdot \vect{i}}{c_H}\]
\[\alpha’ = \arccos\left(-\frac{c_i}{c_H}\right)\]
\[\newcommand{\sgn}{\text{sgn}}
\alpha = \sgn\left({c_j}\right) \times \alpha’\]

Note that because we’ve only used screen normal direction up until now, we don’t care how the phone is tilted between portrait and landscape.

Device tilt angle
Device tilt angle

Last, we calculate tilt. For this calculation we also need to ensure the projection of the screen right vector aP onto the vertical axis (k) is always equal to 1. As above, we divide a by cH.

\[\vect{a}_P = \frac{\vect{a}}{c_H}\]

We take the angle between aP and the world frame vertical axis k.

\[\cos{\tau} = -\vect{a}_P \cdot \vect{k} = \frac{-\vect{a} \cdot \vect{k}}{c_H}\]
\[\tau’ = \arccos\left(-\frac{a_k}{c_H}\right)\]
\[\tau = \sgn\left({b_k}\right) \times \tau’\]

Note that as the elevation gets closer to +/-90, both the azimuth value and the tilt value will become less accurate because the horizontal projection of the screen normal approaches zero, and the vertical projection of the screen right direction approaches zero. How to handle elevation +/-90 is left as an exercise to the reader.

Sample Code

Sample code may be available in future. However, these calculations have been verified in iOS and Android.

Telling Stories for a Change

Sometimes, in a professional setting, we can see a need for change, we can even provide evidence, but we can’t get other people to see it like we do. There’s one time, however, in a social setting, when most people will agree on the need for change: at the climax of a movie when the hero faces a difficult choice between growing or taking the easy way out.  Can we use techniques from movie-making to be more effective change-makers?

The Story Spline

The Story Spline summarises the classical narrative structure. Most stories have a hero. The story starts by introducing us to that hero, their passions and fears, and their world, which may at first be unremarkable. However, at some point (typically 12 minutes into a feature film), their world is changed dramatically. Then, they encounter more and more insurmountable hurdles to return to normality. Finally, they are faced by their fears and a choice: turn their back on everything they’ve learned and return to their comfortable world (boo), or take a risk and make themselves and the world a better place (yay). The story doesn’t end there; hard work remains to be done and there may be more surprises. However, when the choice is made, we know whether it’s right or wrong.

The Story Spline format parallels what we use in agile software development for user stories, elevator pitches, etc. It looks like this:

ONCE UPON A TIME … (“Exposition”)
AND EVERY DAY …
UNTIL ONE DAY … (“Inciting Incident”)
AND BECAUSE OF THAT (or AND THEN) … (“Progressive Complications”)
AND BECAUSE OF THAT (or AND THEN) …

UNTIL FINALLY … (“Crisis/Climax”)
AND SINCE THAT DAY … (“Resolution”)
THE MORAL OF THE STORY IS … (“Theme”)

You could try filling this out for your favourite film.

Putting it to Use

But how do we use this to affect change in a professional setting? Here, I use consulting language, but you could be doing this internally.

  1. Cast the client as the hero
  2. Establish the “theme”. Write THE MORAL OF THE STORY IS …
  3. Decide what CHOICE you want the client to make
    1. Note that this is the “crisis” moment (UNTIL FINALLY)
    2. It’s the present moment for you and your client
    3. So everything prior to this is in the past
  4. Prepare “resolution” actions (may be simple, or may be an approach to discover)
  5. Decide on your “inciting incident”
    1. This splits the past up into the distant past and the recent past
    2. For an explicit change initiative, this is probably the start of the initiative
  6. Frame the distant past in opposition to the right choice
  7. Write the ONCE UPON A TIME … AND EVERY DAY … with that framing
  8. Write the “progressive complications” that have delayed the choice until now
  9. Write the UNTIL FINALLY …
    1. This is NOT phrased as you need to make a choice X
    2. This is phrased as we are at a crisis, and the choices remain implied

Now put this Story Spline on index cards. That keeps each point short, and aids in presentation. Put some blu-tack on the back and make sure they’re in order!

When you meet with the client, tell them you’re going to review the state of the engagement before seeking to make a decision about future direction. Now, start telling the story (and tell it like a story, don’t be shy! throw the phrase “classical narrative structure” in there if you want to establish your serious credentials), sticking the index cards on the wall (or laying them on a table) as you go. This will help prompt you and keep you on track, and serve as a physical reminder of what’s been agreed so far. It’s important to seek the client’s agreement on each card as you stick it up. If they don’t agree, put it to one side (if it’s a disposable progressive complication), or engage in a dialogue about what that card should say. Presuming you reach agreement, and it doesn’t fundamentally break the story, continue in this fashion.

When you get to the crisis, the client should be prepared to recognise the “right” choice, so try to let them reach that choice themselves, and be prepared to support it. Offer ideas and be prepared with actions to implement them. The more it feels like the client’s choice, the better.

If you get the outcome you want, reassure them with THE MORAL OF THE STORY. You may not get that outcome. No guarantees. If you can’t agree on the back-story, you may want to take a recess and come back to it to improve your chances of getting the “right” outcome.

An Example

I have used this technique when consulting – see discussion of effectiveness below, but I’ll use a made-up example here:

Storytelling for change example
Storytelling for change example

THE MORAL OF THE STORY IS that sometimes you have to be prepared to cut your losses and go back to the drawing board.

Note that it takes a bit of work to condense a complex situation into a few lines (I could probably have done this example better!), and each card would carry a lot of context for you and the client, which might not be discernible to the outside observer.

Effectiveness

While I’ve only used this once, it very quickly enabled everyone to get on the same page. The novelty of the approach got people’s attention, and the meeting was clearly focussed on resolving the decision at the climax. However, if I’d failed to get agreement on the back-story, we could have been in trouble. Let me know your experiences and thoughts.

Leave Product Development to the Dummies

This is the talk I gave at Agile Australia 2013 about the role of simulation in product development. Check out a PDF of the slides with brief notes.

Description

"Dummies" talk at Agile Australia

Stop testing on humans! Auto manufacturers have greatly reduced the harm once caused by inadvertently crash-testing production cars with real people. Now, simulation ensures every new car endures thousands of virtual crashes before even a dummy sets foot inside. Can we do the same for software product delivery?

Simulation can deliver faster feedback than real-world trials, for less cost. Simulation supports agility, improves quality and shortens development cycles. Designers and manufacturers of physical products found this out a long time ago. By contrast, in Agile software development, we aim to ship small increments of real software to real people and use their feedback to guide product development. But what if that’s not possible? (And can we still benefit from simulation even when it is?)

The goal of trials remains the same: get a good product to market as quickly as possible (or pivot or kill a bad product as quickly as possible). However, if you have to wait for access to human subjects or real software, or if it’s too costly to scale to the breadth and depth of real-world trials required to optimise design and minimise risk, consider simulation.

Learn why simulation was chosen for the design of call centre services (and compare this with crash testing cars), how a simulator was developed, and what benefits the approach brought. You’ll leave equipped to decide whether simulation is appropriate for your next innovation project, and with some resources to get you started.

Discover:

  • How and when to use simulation to improve agility
  • The anatomy of a simulator
  • A lean, risk-based approach to developing and validating a simulator
  • Techniques for effectively visualising and communicating simulations
  • Implementing simulated designs in the real world

Visualising Net Promoter Score

Net Promoter Score™ (NPS) is a popular method for evaluating customer loyalty. It has its own promoters and detractors, but it is widely used. If you are using it, or plan to, these visual tools might help you understand better what an NPS value means.

Reverse Engineering NPS

So you have an NPS value. Can you use it to draw a picture of your customers? An NPS value purports to tell you about your customer base – how do customers who are likely to recommend your brand (promoters) stack up against those who are likely to trash it (detractors)?

Try it out for yourself. Set the NPS value (from -100 to +100) by clicking/tapping the NPS slider and see the distribution of promoters and detractors. Note you can also explore the effect of the assumed number of neutrals, something a single NPS figure doesn’t tell you.

The visualisation was produced with Processing/Processing.js. See the source code . If it’s not all visible on a small screen, try the visualisation alone.

Tufte might argue the dimensionality of the visualisation (basically 2D, though it’s really 1D wrapped around again and again) exceeds that of the data (1D proportion of promoters, neutrals and detractors). However, I thought 1,000 customers was a good number to use in this context, and wrapping was the only way to compactly show all those customers. Leave your thoughts in the comments, or adapt the source, if you’ do things differently.

Don’t Ever Use Average Satisfaction Score

Satisfaction Scores (“Sat Scores”) are the raw data collected from customers. It’s tempting to reason about NPS with the average of these sat scores because it’s easier to calculate in Excel™ than NPS. If you are tempted, just remember: you may look like an ASS if you use Average Sat Score. Why is Average Sat Score flawed? See below.

NPS is not Average Satisfaction Score
NPS is not Average Sat Score

Average Sat Score doesn’t care about the distribution of responses, whereas NPS is all about the distribution. The same Average Sat Score of 7 applies to customer response sets with NPS values of -50, +40, -100, or “undefined”. NPS is designed to magnify outliers (promoters and detractors) rather than collapse them towards the centre, which is what the Average Sat Score does. Whether NPS works or not is another question entirely.

The Maths of NPS

The visuals above are based on the standard definition of NPS. We have N customer responses Ri (for i = 1 to N) to a feedback question, such as “Rate on a scale from 0 to 10 how likely you are to recommend us”. The number of promoters P is the number of responses Ri > 8. The number of detractors D is the number of responses Ri < 7. The remaining responses are “neutral”.

\[NPS = \frac{N-D}{N+D}\times{100}\]