Skip to content
This repository has been archived by the owner on Jun 14, 2021. It is now read-only.
/ fuse-motion Public archive

iOS accelerometer, gyroscope and magnetometer readings for Fuse

Notifications You must be signed in to change notification settings

AlexGustafsson/fuse-motion

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Motion - iOS accelerometer, gyroscope, magnetometer readings and more for Fuse

App preview

Motion is an easy to use integration of all iOS's sensors reflecting motion, made for Fuse. It enables easy creation of compasses, motion trackers, activity trackers and so on.

Quickstart

Install Motion

Right now a manual installation is required. Requires Fuse 0.30.0 or above.

Copy the following files to your project:

  • Motion.js
  • Motion.hh
  • Motion.mm
  • Motion.uno

Update your .unoproj to reflect the following changes:

"Packages": [
  "Fuse",
  "FuseJS",
  "Fuse.Scripting"
],
"Includes": [
  "Motion.hh:ObjCHeader:iOS",
  "Motion.mm:ObjCSource:iOS",
  "*"
],
"iOS": {
  "PList": {
    "NSMotionUsageDescription": "Motion access motivation"
  }
}

note, the user is only asked to allow motion usage when subscribing to activity

Implementing Motion

Subscribe to sensor updates:

<JavaScript>
  var Motion = require("Motion");
  Motion.Subscribe("accelerometer magnetometer gyroscope motion activity", 0.2);
</JavaScript>

Optional: Include Motion in your App's MainView.ux to export all measurements as observables:

<JavaScript File="MotionJS.js"/>

Table of contents

Quickstart
Using Motion
Examples
Contributing
Disclaimer

Using Motion

Note: API is due to change, stay updated. Until then, use the source, Luke.
The API is pretty final. If you've got any feedback, please make your voice heard.

Implementing observables

Include Motion in your App's MainView.ux:

<JavaScript File="MotionJS.js"/>

Access the values using the same names as the JS API. See the "values" example for all available values.

<Text Value="{magnetometer.magneticField.x}" FontSize="20"/>

Subscribing to updates

To save resources when they are not needed, subscription is used to only grab values from the device when needed. Subscribe only to the events you need and when you need them.

<JavaScript>
  //Global module with a static instance - can be used anywhere
  var Motion = require("Motion");

  //Subscribe to changes from all available sensors with an interval of 0.2 seconds
  Motion.Subscribe("accelerometer magnetometer gyroscope motion activity", 0.2);
</JavaScript>

To release resources when they are no longer needed, unsubscribe to updates whenever possible.

  //Unsubscribe to all changes
  Motion.Unsubscribe("accelerometer magnetometer gyroscope motion activity");

See the Apple webpage on selecting a proper interval.

Interval (s) Usage
0.1 - 0.05 Suitable for determining a device’s current orientation vector.
0.03 – 0.017 Suitable for games and other apps that use the accelerometer for real-time user input.
0.014 – 0.01 Suitable for apps that need to detect high-frequency motion. For example, you might use this interval to detect the user hitting the device or shaking it very quickly.

Listening for updates

To retrieve the actual values, events are used.

Note: In their current state, Fuse NativeEvents don't allow for more than one "listener". As such you can only subscribe to the events once. Subscribing again will override any previous subscriptions. Since Motion already listens to the updates in order to share the values to UX, listening for the updates will disable that feature.
Fuse 0.30.0 came with an overhauled event system. As such proper events are now implemented in Motion.

<JavaScript>
  Motion.on("accelerometerChanged", function(values){
    values = JSON.parse(values);

    if(!values.error)
      console.log("Accelerometer values:", values);
  });

  Motion.on("gyroscopeChanged", function(values){
    values = JSON.parse(values);

    if(!values.error)
      console.log("Gyroscope values:", values);
  });

  Motion.on("motionChanged", function(values){
    values = JSON.parse(values);

    if(!values.error)
      console.log("Motion values:", values);
  });

  Motion.on("magnetometerChanged", function(values){
    values = JSON.parse(values);

    if(!values.error)
      console.log("Magnetometer values:", values);
  });

  Motion.on("activityChanged", function(values){
    values = JSON.parse(values);

    if(!values.error)
      console.log("Activity values:", values);
  });
</JavaScript>

Accessing values directly in UX

Motion exposes several values directly to UX Markup.

Note: In their current state, Fuse NativeEvents don't allow for more than one "listener". As such you can only subscribe to the events once. Subscribing again will override any previous subscriptions. Since Motion already listens to the updates in order to share the values to UX, listening for the updates will disable this feature.
Fuse 0.30.0 came with an overhauled event system. As such proper events are now implemented in Motion.

The following values are exposed:

var accelerometer = Observable({
  acceleration: {x: 0, y: 0, z: 0}
}),
gyroscope = Observable({
  rotationRate: {x: 0, y: 0, z: 0}
}),
magnetometer = Observable({
  magneticField: {x: 0, y: 0, z: 0}
}),
motion = Observable({
  attitude: {yaw: 0, pitch: 0, roll: 0},
  rotationRate: {x: 0, y: 0, z: 0},
  gravity: {x: 0, y: 0, z: 0},
  magneticField: {accuracy: -1, x: 0, y: 0, z: 0},
  userAcceleration: {x: 0, y: 0, z: 0}
}),
activity = Observable({
  unknown: true,
  stationary: false,
  walking: false,
  running: false,
  automotive: false,
  cycling: false,
  confidence: "low"
});

If you are unsure how to use values exposed from javascript through Observables check out the Fuse documentation and this example.

Examples

Demo app

When built, this project will act as an app showcasing all the examples.

Displays all available values.

Uses the magnetometer to apply a gravity effect to a dropshadow.

Uses the accelerometer to detect when the phone is hit.

No more phone thumb from "swiping right"! Train your wrist by using the gyroscope to enable a swipe like feature.

Contributing

Any help with the project is more than welcome. This is my first take on Uno and Objective-C so some things might not be following best practices or be incorrectly implemented all together.

TODO:

Disclaimer

Although the project is very capable, it is not built with production in mind. Therefore there might be complications when trying to use Motion for large-scale projects meant for the public. Motion was created to easily integrate sensor readings on iOS and as such it might not promote best practices nor be performant.

Built with Fuse 0.30.0 (build 8529) and Xcode Version 8.1 (8B62), tested on iPhone 6 iOS 10.2 and 10.2.1. Tested with Fuse 1.1.0 (build 13808).